@@ -178,26 +178,38 @@ let recover ~__context ~self ~session_to ~force =
178178 assert_can_be_recovered ~__context ~self ~session_to ;
179179 let vms = Db.VM_appliance. get_VMs ~__context ~self in
180180 let recovered_vms = Xapi_dr. recover_vms ~__context ~vms ~session_to ~force in
181- (* Recreate the VM appliance object. *)
181+ (* Deal with the VM appliance object. *)
182182 let old_appliance = Db.VM_appliance. get_record ~__context ~self in
183183 Server_helpers. exec_with_new_task ~session_id: session_to " Recreating VM appliance object"
184184 (fun __context_to ->
185- let new_appliance = create ~__context:__context_to
186- ~name_label: old_appliance.API. vM_appliance_name_label
187- ~name_description: old_appliance.API. vM_appliance_name_description in
185+ let recovered_appliance = try
186+ (* If an appliance with the same UUID exists, remove all VMs from the appliance and update its name_label/name_description. *)
187+ let existing_appliance = Db.VM_appliance. get_by_uuid ~__context:__context_to ~uuid: old_appliance.API. vM_appliance_uuid in
188+ debug " An appliance with UUID %s already exists - reusing it." old_appliance.API. vM_appliance_uuid;
189+ let vms = Db.VM_appliance. get_VMs ~__context:__context_to ~self: existing_appliance in
190+ List. iter
191+ (fun vm -> Db.VM. set_appliance ~__context:__context_to ~self: vm ~value: Ref. null)
192+ vms;
193+ Db.VM_appliance. set_name_label ~__context:__context_to ~self: existing_appliance ~value: old_appliance.API. vM_appliance_name_label;
194+ Db.VM_appliance. set_name_description ~__context:__context_to ~self: existing_appliance ~value: old_appliance.API. vM_appliance_name_description;
195+ existing_appliance
196+ with Db_exn. Read_missing_uuid ("VM_appliance" , _ , _ ) ->
197+ (* If no appliance with the same UUID exists, create a new one from the old appliance's data. *)
198+ debug " No appliance with UUID %s exists - creating a new one." old_appliance.API. vM_appliance_uuid;
199+ begin
200+ let new_appliance = create ~__context:__context_to
201+ ~name_label: old_appliance.API. vM_appliance_name_label
202+ ~name_description: old_appliance.API. vM_appliance_name_description in
203+ Db.VM_appliance. set_uuid ~__context:__context_to
204+ ~self: new_appliance
205+ ~value: old_appliance.API. vM_appliance_uuid;
206+ new_appliance
207+ end
208+ in
188209 (* Add all the non-template VMs to the appliance. *)
189210 List. iter
190211 (fun vm ->
191212 if not (Db.VM. get_is_a_template ~__context:__context_to ~self: vm) then
192- Db.VM. set_appliance ~__context:__context_to ~self: vm ~value: new_appliance )
213+ Db.VM. set_appliance ~__context:__context_to ~self: vm ~value: recovered_appliance )
193214 recovered_vms;
194- update_allowed_operations ~__context:__context_to ~self: new_appliance;
195- try
196- Db.VM_appliance. set_uuid ~__context:__context_to
197- ~self: new_appliance
198- ~value: old_appliance.API. vM_appliance_uuid
199- with Db_exn. Uniqueness_constraint_violation (_ , _ , _ ) ->
200- (* Fail silently if the appliance's uuid already exists. *)
201- debug
202- " Could not give VM appliance the uuid %s as a VM appliance with this uuid already exists."
203- old_appliance.API. vM_appliance_uuid)
215+ update_allowed_operations ~__context:__context_to ~self: recovered_appliance)
0 commit comments