Skip to content

Commit

Permalink
Implement VM_appliance.recover
Browse files Browse the repository at this point in the history
This method recovers all the VMs in the appliance, then tries to
recreate the appliance object. If an appliance with the same UUID
exists, the error is caught and the recovered appliance will have a new
UUID.

Signed-off-by: John Else <john.else@citrix.com>
  • Loading branch information
johnelse committed Mar 23, 2011
1 parent 120e94d commit c812222
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 1 deletion.
11 changes: 11 additions & 0 deletions ocaml/idl/datamodel.ml
Expand Up @@ -6546,6 +6546,16 @@ let vm_appliance =
~doc:"Assert whether all SRs required to recover this VM appliance are available."
~allowed_roles:_R_READ_ONLY
() in
let vm_appliance_recover = call
~name:"recover"
~in_product_since:rel_boston
~params:[Ref _vm_appliance, "self", "The VM appliance to recover";
Ref _session, "session_to", "The session to which the VM appliance is to be recovered.";
Bool, "force", "Whether the VMs should replace newer versions of themselves."]
~errs:[Api_errors.vm_requires_sr]
~doc:"Recover the VM appliance"
~allowed_roles:_R_READ_ONLY
() in
create_obj ~in_db:true ~in_product_since:rel_boston ~in_oss_since:None ~internal_deprecated_since:None ~persist:PersistEverything ~gen_constructor_destructor:true ~name:_vm_appliance ~descr:"VM appliance"
~gen_events:true
~doccomments:[]
Expand All @@ -6555,6 +6565,7 @@ let vm_appliance =
vm_appliance_clean_shutdown;
vm_appliance_hard_shutdown;
vm_appliance_assert_can_be_recovered;
vm_appliance_recover;
]
~contents:([
uid _vm_appliance;
Expand Down
4 changes: 4 additions & 0 deletions ocaml/xapi/message_forwarding.ml
Expand Up @@ -586,6 +586,10 @@ module Forward = functor(Local: Custom_actions.CUSTOM_ACTIONS) -> struct
let assert_can_be_recovered ~__context ~self ~session_to =
info "VM_appliance.assert_can_be_recovered: VM_appliance = '%s'" (vm_appliance_uuid ~__context self);
Local.VM_appliance.assert_can_be_recovered ~__context ~self ~session_to

let recover ~__context ~self ~session_to ~force =
info "VM_appliance.recover: VM_appliance = '%s'" (vm_appliance_uuid ~__context self);
Local.VM_appliance.recover ~__context ~self ~session_to ~force
end
module DR_task = Local.DR_task
(* module Alert = Local.Alert *)
Expand Down
1 change: 1 addition & 0 deletions ocaml/xapi/xapi_dr.ml
Expand Up @@ -38,6 +38,7 @@ let recover_vms ~__context ~vms ~session_to ~force =
in
try
Import.complete_import ~__context:__context_to vmrefs;
vmrefs
with e ->
if force then
debug "%s" "VM recovery failed - not cleaning up as action was forced."
Expand Down
2 changes: 1 addition & 1 deletion ocaml/xapi/xapi_vm.ml
Expand Up @@ -1292,4 +1292,4 @@ let recover ~__context ~self ~session_to ~force =
(* Check the VM SRs are available. *)
assert_can_be_recovered ~__context ~self ~session_to;
(* Attempt to recover the VM. *)
Xapi_dr.recover_vms ~__context ~vms:[self] ~session_to ~force
ignore (Xapi_dr.recover_vms ~__context ~vms:[self] ~session_to ~force)
24 changes: 24 additions & 0 deletions ocaml/xapi/xapi_vm_appliance.ml
Expand Up @@ -175,3 +175,27 @@ let assert_can_be_recovered ~__context ~self ~session_to =
List.iter
(fun vm -> Xapi_vm_helpers.assert_can_be_recovered ~__context ~self:vm ~session_to)
vms

let recover ~__context ~self ~session_to ~force =
assert_can_be_recovered ~__context ~self ~session_to;
let vms = Db.VM_appliance.get_VMs ~__context ~self in
let recovered_vms = Xapi_dr.recover_vms ~__context ~vms ~session_to ~force in
(* Recreate the VM appliance object. *)
let old_appliance = Db.VM_appliance.get_record ~__context ~self in
Server_helpers.exec_with_new_task ~session_id:session_to "Recreating VM appliance object"
(fun __context_to ->
let new_appliance = create ~__context:__context_to
~name_label:old_appliance.API.vM_appliance_name_label
~name_description:old_appliance.API.vM_appliance_name_description in
List.iter
(fun vm -> Db.VM.set_appliance ~__context:__context_to ~self:vm ~value:new_appliance)
recovered_vms;
try
Db.VM_appliance.set_uuid ~__context:__context_to
~self:new_appliance
~value:old_appliance.API.vM_appliance_uuid
with Db_exn.Uniqueness_constraint_violation(_, _, _) ->
(* Fail silently if the appliance's uuid already exists. *)
debug
"Could not give VM appliance the uuid %s as a VM appliance with this uuid already exists."
old_appliance.API.vM_appliance_uuid)
2 changes: 2 additions & 0 deletions ocaml/xapi/xapi_vm_appliance.mli
Expand Up @@ -17,3 +17,5 @@ val hard_shutdown :

val assert_can_be_recovered :
__context:Context.t -> self:[ `VM_appliance ] Ref.t -> session_to:[ `session ] Ref.t -> unit
val recover :
__context:Context.t -> self:[ `VM_appliance ] Ref.t -> session_to:[ `session ] Ref.t -> force:bool -> unit

0 comments on commit c812222

Please sign in to comment.