From db041099ef1c39b8bc9c948678f99a5eb4cbe1dd Mon Sep 17 00:00:00 2001 From: Konstantina Chremmou Date: Wed, 6 May 2020 16:43:08 +0100 Subject: [PATCH] CA-339271: Improved action description. Also: Added cancelling ability to MoveVM action; made some simplifications. Signed-off-by: Konstantina Chremmou --- .../Actions/VDI/MigrateVirtualDiskAction.cs | 24 +-- XenModel/Actions/VDI/MoveVirtualDiskAction.cs | 6 +- XenModel/Actions/VM/VMMoveAction.cs | 138 ++++++++++-------- XenModel/Messages.Designer.cs | 30 ++-- XenModel/Messages.resx | 14 +- 5 files changed, 104 insertions(+), 108 deletions(-) diff --git a/XenModel/Actions/VDI/MigrateVirtualDiskAction.cs b/XenModel/Actions/VDI/MigrateVirtualDiskAction.cs index 27a3b8eb8..5cbd1654f 100644 --- a/XenModel/Actions/VDI/MigrateVirtualDiskAction.cs +++ b/XenModel/Actions/VDI/MigrateVirtualDiskAction.cs @@ -44,7 +44,7 @@ namespace XenAdmin.Actions private readonly VDI vdi; public MigrateVirtualDiskAction(IXenConnection connection, VDI vdi, SR sr) - : base(connection, string.Format(Messages.ACTION_MOVING_VDI_TITLE, Helpers.GetName(vdi), Helpers.GetName(sr))) + : base(connection, string.Format(Messages.ACTION_MOVING_VDI_TO_SR, Helpers.GetName(vdi), Helpers.GetName(sr))) { Description = Messages.ACTION_PREPARING; this.vdi = vdi; @@ -53,24 +53,10 @@ namespace XenAdmin.Actions protected override void Run() { - try - { - Title = Description = string.Format(Messages.ACTION_MOVING_VDI_STATUS, Helpers.GetName(vdi)); - RelatedTask = VDI.async_pool_migrate(Session, vdi.opaque_ref, SR.opaque_ref, new Dictionary()); - PollToCompletion(); - } - catch (CancelledException) - { - Description = string.Format(Messages.ACTION_VM_MIGRATE_CANCELLED, vdi.Name()); - throw; - } - catch (Failure boo) - { - Description = boo.Message; - throw; - } - - Description = Messages.ACTION_VM_MIGRATED; + Description = string.Format(Messages.ACTION_MOVING_VDI, Helpers.GetName(vdi)); + RelatedTask = VDI.async_pool_migrate(Session, vdi.opaque_ref, SR.opaque_ref, new Dictionary()); + PollToCompletion(); + Description = Messages.MOVED; } } } diff --git a/XenModel/Actions/VDI/MoveVirtualDiskAction.cs b/XenModel/Actions/VDI/MoveVirtualDiskAction.cs index 161167b2f..a64d70677 100644 --- a/XenModel/Actions/VDI/MoveVirtualDiskAction.cs +++ b/XenModel/Actions/VDI/MoveVirtualDiskAction.cs @@ -47,7 +47,7 @@ namespace XenAdmin.Actions private VDI vdi; public MoveVirtualDiskAction(IXenConnection connection, XenAPI.VDI vdi, SR sr) - : base(connection, string.Format(Messages.ACTION_MOVING_VDI_TITLE, Helpers.GetName(vdi), Helpers.GetName(sr))) + : base(connection, string.Format(Messages.ACTION_MOVING_VDI_TO_SR, Helpers.GetName(vdi), Helpers.GetName(sr))) { this.vdi = vdi; SR = sr; @@ -63,7 +63,7 @@ namespace XenAdmin.Actions protected override void Run() { - Description = string.Format(Messages.ACTION_MOVING_VDI_STATUS, Helpers.GetName(vdi)); + Description = string.Format(Messages.ACTION_MOVING_VDI, Helpers.GetName(vdi)); PercentComplete = 10; log.DebugFormat("Moving VDI '{0}'", Helpers.GetName(vdi)); RelatedTask = VDI.async_copy(Session, vdi.opaque_ref, SR.opaque_ref); @@ -126,7 +126,7 @@ namespace XenAdmin.Actions Connection.WaitForCache(VBD.create(Session, newVbd)); PercentComplete = 100; - Description = Messages.COMPLETED; + Description = Messages.MOVED; log.DebugFormat("Moved VDI '{0}'", Helpers.GetName(vdi)); } diff --git a/XenModel/Actions/VM/VMMoveAction.cs b/XenModel/Actions/VM/VMMoveAction.cs index 2d4d5a906..5472eefe7 100644 --- a/XenModel/Actions/VM/VMMoveAction.cs +++ b/XenModel/Actions/VM/VMMoveAction.cs @@ -40,20 +40,21 @@ namespace XenAdmin.Actions.VMActions { public class VMMoveAction : AsyncAction { - public Dictionary StorageMapping; + private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private Dictionary _storageMapping; public VMMoveAction(VM vm, Dictionary storageMapping, Host host) - : base(vm.Connection, Messages.ACTION_VM_MOVING) + : base(vm.Connection, string.Format(Messages.ACTION_VM_MOVING, vm.Name())) { - this.Description = Messages.ACTION_PREPARING; this.VM = vm; this.Host = host; this.Pool = Helpers.GetPool(vm.Connection); if (vm.is_a_template) this.Template = vm; - StorageMapping = storageMapping; - SR = StorageMapping.Values.FirstOrDefault(); + _storageMapping = storageMapping; + SR = _storageMapping.Values.FirstOrDefault(); PopulateApiMethodsToRoleCheck(); } @@ -61,7 +62,6 @@ namespace XenAdmin.Actions.VMActions public VMMoveAction(VM vm, SR sr, Host host, string namelabel) : base(vm.Connection, string.Format(Messages.ACTION_VM_MOVING_TITLE, vm.Name(), namelabel, sr.NameWithoutHost())) { - this.Description = Messages.ACTION_PREPARING; this.VM = vm; this.Host = host; this.Pool = Helpers.GetPool(vm.Connection); @@ -70,11 +70,12 @@ namespace XenAdmin.Actions.VMActions this.Template = vm; // create a storage map where all VDIs are mapped to the same SR - StorageMapping = new Dictionary(); - var vbds = vm.Connection.ResolveAll(vm.VBDs); - foreach (var vbd in vbds) + _storageMapping = new Dictionary(); + foreach (var vbdRef in vm.VBDs) { - StorageMapping.Add(vbd.VDI.opaque_ref, sr); + var vbd = vm.Connection.Resolve(vbdRef); + if (vbd != null) + _storageMapping.Add(vbd.VDI.opaque_ref, sr); } PopulateApiMethodsToRoleCheck(); @@ -95,68 +96,77 @@ namespace XenAdmin.Actions.VMActions protected override void Run() { - this.Description = Messages.ACTION_VM_MOVING; - try + Description = Messages.ACTION_PREPARING; + + // move the progress bar above 0, it's more reassuring to see than a blank bar as we copy the first disk + PercentComplete += 10; + int halfstep = 90 / (VM.VBDs.Count * 2); + + var exceptions = new List(); + + foreach (var vbdRef in VM.VBDs) { - var vbds = Connection.ResolveAll(VM.VBDs); - int halfstep = (int)(90/(vbds.Count * 2)); - // move the progress bar above 0, it's more reassuring to see than a blank bar as we copy the first disk - PercentComplete += 10; - Exception exn = null; + if (Cancelling) + throw new CancelledException(); - foreach (VBD oldVBD in vbds) + var oldVBD = Connection.Resolve(vbdRef); + + if (oldVBD == null || !oldVBD.GetIsOwner()) + continue; + + if (_storageMapping == null || + !_storageMapping.TryGetValue(oldVBD.VDI.opaque_ref, out SR sr) || sr == null) + continue; + + var curVdi = Connection.Resolve(oldVBD.VDI); + if (curVdi == null) + continue; + + if (curVdi.SR.opaque_ref == sr.opaque_ref) + continue; + + Description = string.Format(Messages.ACTION_MOVING_VDI_TO_SR, + Helpers.GetName(curVdi), Helpers.GetName(sr)); + + RelatedTask = VDI.async_copy(Session, oldVBD.VDI.opaque_ref, sr.opaque_ref); + PollToCompletion(PercentComplete, PercentComplete + halfstep); + var newVDI = Connection.WaitForCache(new XenRef(Result)); + + var newVBD = new VBD { - if (!oldVBD.GetIsOwner()) - continue; + userdevice = oldVBD.userdevice, + bootable = oldVBD.bootable, + mode = oldVBD.mode, + type = oldVBD.type, + unpluggable = oldVBD.unpluggable, + other_config = oldVBD.other_config, + VDI = new XenRef(newVDI.opaque_ref), + VM = new XenRef(VM.opaque_ref) + }; + newVBD.SetIsOwner(oldVBD.GetIsOwner()); - var curVdi = Connection.Resolve(oldVBD.VDI); - if (curVdi == null) - continue; - - if (StorageMapping == null || !StorageMapping.ContainsKey(oldVBD.VDI.opaque_ref)) - continue; - - SR sr = StorageMapping[oldVBD.VDI.opaque_ref]; - if (sr == null || curVdi.SR.opaque_ref == sr.opaque_ref) - continue; - - RelatedTask = XenAPI.VDI.async_copy(Session, oldVBD.VDI.opaque_ref, sr.opaque_ref); - PollToCompletion(PercentComplete, PercentComplete + halfstep); - var newVDI = Connection.WaitForCache(new XenRef(Result)); - - var newVBD = new VBD - { - userdevice = oldVBD.userdevice, - bootable = oldVBD.bootable, - mode = oldVBD.mode, - type = oldVBD.type, - unpluggable = oldVBD.unpluggable, - other_config = oldVBD.other_config, - VDI = new XenRef(newVDI.opaque_ref), - VM = new XenRef(VM.opaque_ref) - }; - newVBD.SetIsOwner(oldVBD.GetIsOwner()); - - VBD vbd = oldVBD; - BestEffort(ref exn, () => VDI.destroy(Session, vbd.VDI.opaque_ref)); - Connection.WaitForCache(VBD.create(Session, newVBD)); - - PercentComplete += halfstep; + try + { + VDI.destroy(Session, oldVBD.VDI.opaque_ref); + } + catch (Exception e) + { + log.ErrorFormat("Failed to destroy old VDI {0}", oldVBD.VDI.opaque_ref); + exceptions.Add(e); } - if (SR != null) - VM.set_suspend_SR(Session, VM.opaque_ref, SR.opaque_ref); + Connection.WaitForCache(VBD.create(Session, newVBD)); - if (exn != null) - throw exn; + PercentComplete += halfstep; + } - } - catch (CancelledException) - { - this.Description = string.Format(Messages.MOVE_CANCELLED, VM.Name()); - throw; - } - this.Description = Messages.MOVED; + if (SR != null) + VM.set_suspend_SR(Session, VM.opaque_ref, SR.opaque_ref); + + if (exceptions.Count > 0) + throw new Exception(Messages.ACTION_VM_MOVING_VDI_DESTROY_FAILURE); + + Description = Messages.MOVED; } } } diff --git a/XenModel/Messages.Designer.cs b/XenModel/Messages.Designer.cs index 33481e81c..c6752ee11 100755 --- a/XenModel/Messages.Designer.cs +++ b/XenModel/Messages.Designer.cs @@ -1566,18 +1566,18 @@ namespace XenAdmin { /// /// Looks up a localized string similar to Moving virtual disk '{0}'.... /// - public static string ACTION_MOVING_VDI_STATUS { + public static string ACTION_MOVING_VDI { get { - return ResourceManager.GetString("ACTION_MOVING_VDI_STATUS", resourceCulture); + return ResourceManager.GetString("ACTION_MOVING_VDI", resourceCulture); } } /// /// Looks up a localized string similar to Moving Virtual Disk '{0}' to SR '{1}'. /// - public static string ACTION_MOVING_VDI_TITLE { + public static string ACTION_MOVING_VDI_TO_SR { get { - return ResourceManager.GetString("ACTION_MOVING_VDI_TITLE", resourceCulture); + return ResourceManager.GetString("ACTION_MOVING_VDI_TO_SR", resourceCulture); } } @@ -3193,7 +3193,7 @@ namespace XenAdmin { } /// - /// Looks up a localized string similar to Moving VM to new storage.... + /// Looks up a localized string similar to Moving VM '{0}' to new storage. /// public static string ACTION_VM_MOVING { get { @@ -3210,6 +3210,15 @@ namespace XenAdmin { } } + /// + /// Looks up a localized string similar to Failed to finalize moving VM '{0}' to new storage. Please see logs for details.. + /// + public static string ACTION_VM_MOVING_VDI_DESTROY_FAILURE { + get { + return ResourceManager.GetString("ACTION_VM_MOVING_VDI_DESTROY_FAILURE", resourceCulture); + } + } + /// /// Looks up a localized string similar to Rebooted. /// @@ -24523,15 +24532,6 @@ namespace XenAdmin { } } - /// - /// Looks up a localized string similar to Moving {0} canceled. - /// - public static string MOVE_CANCELLED { - get { - return ResourceManager.GetString("MOVE_CANCELLED", resourceCulture); - } - } - /// /// Looks up a localized string similar to Move object '{0}' to folder '{1}'.... /// @@ -24578,7 +24578,7 @@ namespace XenAdmin { } /// - /// Looks up a localized string similar to Moved. + /// Looks up a localized string similar to Move completed.. /// public static string MOVED { get { diff --git a/XenModel/Messages.resx b/XenModel/Messages.resx index 587945138..2c6d9c2ab 100755 --- a/XenModel/Messages.resx +++ b/XenModel/Messages.resx @@ -618,10 +618,10 @@ Started migrating virtual disks - + Moving virtual disk '{0}'... - + Moving Virtual Disk '{0}' to SR '{1}' @@ -1183,11 +1183,14 @@ Migrating VM '{0}' - Moving VM to new storage... + Moving VM '{0}' to new storage Moving VM '{0}' to '{1}' on SR '{2}' + + Failed to finalize moving VM '{0}' to new storage. Please see logs for details. + Rebooted @@ -8522,10 +8525,7 @@ Do you want to continue? More info... - Moved - - - Moving {0} canceled + Move completed. Move selected objects to folder '{0}'...