Skip to content

Commit 28fc8c3

Browse files
authored
Merge pull request xapi-project#3144 from jonludlam/CA-260352
CA-260352: Fix upgrade from 1.14-ppx to 1.30
2 parents a28d4c0 + a0fefee commit 28fc8c3

File tree

5 files changed

+86
-15
lines changed

5 files changed

+86
-15
lines changed

ocaml/client_records/records.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ let pool_update_record rpc session_id update =
10321032
make_field ~name:"installation-size" ~get:(fun () -> Int64.to_string (x ()).API.pool_update_installation_size) ();
10331033
make_field ~name:"hosts" ~get:(fun () -> String.concat ", " (get_hosts ())) ~get_set:get_hosts ();
10341034
make_field ~name:"after-apply-guidance" ~get:(fun () -> String.concat ", " (after_apply_guidance ())) ~get_set:after_apply_guidance ();
1035-
make_field ~name:"enforce-homogeneity" ~get:(fun () -> string_of_bool (x ()).API.pool_update_enforce_homogeneity) ();
1035+
make_field ~name:"enforce-homogeneity" ~get:(fun () -> string_of_bool (Client.Pool_update.get_enforce_homogeneity rpc session_id !_ref)) ();
10361036
]}
10371037

10381038
let host_cpu_record rpc session_id host_cpu =

ocaml/idl/datamodel.ml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4098,6 +4098,17 @@ let pool_update_resync_host = call
40984098
~allowed_roles:_R_POOL_OP
40994099
()
41004100

4101+
let pool_update_get_enforce_homogeneity = call
4102+
~name:"get_enforce_homogeneity"
4103+
~hide_from_docs:true
4104+
~doc:"Get the value of the field 'enforce_homogeneity'"
4105+
~in_oss_since:None
4106+
~in_product_since:rel_honolulu
4107+
~params:[ Ref _pool_update, "self", "The update to be queried"]
4108+
~allowed_roles:_R_POOL_OP
4109+
~result:(Bool, "The value of the field")
4110+
()
4111+
41014112
let pool_update =
41024113
create_obj ~in_db:true
41034114
~in_product_since:rel_ely
@@ -4122,6 +4133,7 @@ let pool_update =
41224133
pool_update_attach;
41234134
pool_update_detach;
41244135
pool_update_resync_host;
4136+
pool_update_get_enforce_homogeneity;
41254137
]
41264138
~contents:
41274139
[ uid ~in_oss_since:None _pool_update;
@@ -4132,13 +4144,6 @@ let pool_update =
41324144
field ~in_product_since:rel_ely ~default_value:(Some (VSet [])) ~in_oss_since:None ~qualifier:StaticRO ~ty:(Set pool_update_after_apply_guidance) "after_apply_guidance" "What the client should do after this update has been applied.";
41334145
field ~in_oss_since:None ~qualifier:StaticRO ~ty:(Ref _vdi) "vdi" "VDI the update was uploaded to";
41344146
field ~in_product_since:rel_ely ~in_oss_since:None ~qualifier:DynamicRO ~ty:(Set (Ref _host)) "hosts" "The hosts that have applied this update.";
4135-
field ~in_product_since:rel_honolulu
4136-
~default_value:(Some (VBool false))
4137-
~in_oss_since:None
4138-
~qualifier:StaticRO
4139-
~ty:Bool
4140-
"enforce_homogeneity"
4141-
"Flag - if true, all hosts in a pool must apply this update";
41424147
]
41434148
()
41444149

ocaml/xapi/message_forwarding.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3949,6 +3949,7 @@ module Forward = functor(Local: Custom_actions.CUSTOM_ACTIONS) -> struct
39493949
do_op_on ~local_fn ~__context ~host
39503950
(fun session_id rpc -> Client.Pool_update.resync_host rpc session_id host)
39513951

3952+
let get_enforce_homogeneity = Local.Pool_update.get_enforce_homogeneity
39523953
end
39533954
module VGPU_type = struct end
39543955
module LVHD = struct end

ocaml/xapi/xapi_pool.ml

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,30 @@ let pre_join_checks ~__context ~rpc ~session_id ~force =
144144
in
145145

146146
let assert_homogeneous_updates () =
147+
(* If we can't find the 'enforce_homogeneity' key, we'll default to it being true. However,
148+
let's make an override in case something has gone seriously wrong *)
149+
let default_update_enforcement =
150+
let pool = List.hd (Client.Pool.get_all rpc session_id) in
151+
let remote_pool_other_config = Client.Pool.get_other_config rpc session_id pool in
152+
try bool_of_string (List.assoc "default_update_enforcement" remote_pool_other_config) with _ -> true
153+
in
154+
let safe_get_enforce_homogeneity rpc session_id self =
155+
try
156+
Client.Pool_update.get_enforce_homogeneity rpc session_id self
157+
with e ->
158+
error "error locating an update's enforce_homogeneity flag. Update ref: '%s' Exception: '%s'"
159+
(Ref.string_of self)
160+
(Printexc.to_string e);
161+
default_update_enforcement
162+
in
147163
let module S = Helpers.StringSet in
148164
let local_host = Helpers.get_localhost ~__context in
149165
let local_uuid = Db.Host.get_uuid ~__context ~self:local_host in
150166
let updates_on ~rpc ~session_id host =
151167
Client.Host.get_updates ~rpc ~session_id ~self:host
152-
|> List.map (fun self -> Client.Pool_update.get_record ~rpc ~session_id ~self)
153-
|> List.filter (fun upd -> upd.API.pool_update_enforce_homogeneity = true)
154-
|> List.map (fun upd -> upd.API.pool_update_uuid)
168+
|> List.map (fun self -> (self,Client.Pool_update.get_record ~rpc ~session_id ~self))
169+
|> List.filter (fun (self,upd) -> safe_get_enforce_homogeneity rpc session_id self = true)
170+
|> List.map (fun (_,upd) -> upd.API.pool_update_uuid)
155171
|> S.of_list in
156172
let local_updates =
157173
Helpers.call_api_functions ~__context (fun rpc session_id ->

ocaml/xapi/xapi_pool_update.ml

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,52 @@ let patch_uuid_of_update_uuid uuid =
348348
modify 4; modify 5; modify 6; modify 7;
349349
Uuid.uuid_of_int_array arr |> Uuid.string_of_uuid
350350

351+
352+
module EnforceHomogeneityWorkaround = struct
353+
(* Enforce homogeneity horrendous hack *)
354+
355+
(* We're doing this because we can't put new keys in the database and then upgrade to the
356+
released version of 7.2 that doesn't understand the database keys. So we stash them in
357+
other_config. Unforunately pool_update doesn't contain other_config, but pool patch
358+
does. So we'll stick it in there. Eughrghghg. *)
359+
let __enforce_homogeneity_key = "enforce_homogeneity"
360+
361+
(* Retreive the pool_patch object associated with a pool_update. This is very
362+
similar to the function 'pool_patch_of_update' in xapi_pool_patch.ml, but
363+
because we might be talking about a different pool we need to only use the
364+
public API, not the internal Db calls that that function uses. Also, because
365+
the pool_update field of the pool_patch record is not exposed in the API, we
366+
have to use the above patch_uuid_of_update_uuid function... *)
367+
let pool_patch_of_update rpc session_id ref =
368+
let update_uuid = Client.Pool_update.get_uuid rpc session_id ref in
369+
let patch_uuid = patch_uuid_of_update_uuid update_uuid in
370+
try
371+
Client.Pool_patch.get_by_uuid rpc session_id patch_uuid
372+
with e ->
373+
error "Invalid state: Expected invariant - 1 pool_patch per pool_update. Got %s"
374+
(Printexc.to_string e);
375+
raise Api_errors.(Server_error (internal_error, ["Invalid state"]))
376+
377+
(* Note that this function will purposefully raise exceptions if there's any
378+
problem figuring out the value of 'enforce_homogeneity'. It's up to the
379+
caller to decide what to do in this case *)
380+
let get_enforce_homogeneity rpc session_id ~self =
381+
let pool_patch_ref = pool_patch_of_update rpc session_id self in
382+
Client.Pool_patch.get_other_config rpc session_id pool_patch_ref
383+
|> List.assoc __enforce_homogeneity_key
384+
|> bool_of_string
385+
386+
let set_enforce_homogeneity rpc session_id ~self ~value =
387+
let pool_patch_ref = pool_patch_of_update rpc session_id self in
388+
Client.Pool_patch.remove_from_other_config rpc session_id pool_patch_ref __enforce_homogeneity_key;
389+
Client.Pool_patch.add_to_other_config rpc session_id pool_patch_ref __enforce_homogeneity_key (string_of_bool value)
390+
391+
end
392+
393+
let get_enforce_homogeneity ~__context ~self =
394+
Helpers.call_api_functions ~__context (fun rpc session_id ->
395+
EnforceHomogeneityWorkaround.get_enforce_homogeneity rpc session_id self)
396+
351397
let create_update_record ~__context ~update ~update_info ~vdi =
352398
let patch_ref = Ref.make () in
353399
ignore(Db.Pool_patch.create ~__context
@@ -360,7 +406,7 @@ let create_update_record ~__context ~update ~update_info ~vdi =
360406
~pool_applied:false
361407
~after_apply_guidance:update_info.after_apply_guidance
362408
~pool_update:update
363-
~other_config:[]);
409+
~other_config:[EnforceHomogeneityWorkaround.__enforce_homogeneity_key,string_of_bool update_info.enforce_homogeneity]);
364410
Db.Pool_update.create ~__context
365411
~ref:update
366412
~uuid:update_info.uuid
@@ -371,7 +417,6 @@ let create_update_record ~__context ~update ~update_info ~vdi =
371417
~key:update_info.key
372418
~after_apply_guidance:update_info.after_apply_guidance
373419
~vdi:vdi
374-
~enforce_homogeneity:update_info.enforce_homogeneity
375420

376421
let introduce ~__context ~vdi =
377422
ignore(Unixext.mkdir_safe Xapi_globs.host_update_dir 0o755);
@@ -462,8 +507,12 @@ let resync_host ~__context ~host =
462507
| Some self ->
463508
(* re-interpret the enforce_homogeneity flag CP-258536 *)
464509
debug "pool_update.resync_host: update %s exists - updating it" update_uuid;
465-
Db.Pool_update.set_enforce_homogeneity ~__context ~self
466-
~value:update_info.enforce_homogeneity
510+
begin try
511+
Helpers.call_api_functions ~__context (fun rpc session_id ->
512+
EnforceHomogeneityWorkaround.set_enforce_homogeneity rpc session_id self update_info.enforce_homogeneity)
513+
with e ->
514+
error "Failed to set enforce_homogeneity: %s" (Printexc.to_string e)
515+
end
467516
| None ->
468517
let update = Ref.make () in
469518
debug "pool_update.resync_host: update %s not in database - creating it" update_uuid;

0 commit comments

Comments
 (0)