From 9b1a3315f03dab6277c20693cedeba47dfd296ff Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Thu, 3 Nov 2016 15:35:25 +0000 Subject: [PATCH 1/2] [CA-226897] Resume on Server option won't automatically resume the VM The resume on server uses the CrossPoolMigrateCommand to implement the migration of the VM to the desired host. Before this change that command had no support for resuming a VM after migrating it, so the VM was not resumed. With this change, the CrossPoolMigrateWizard can take an optional (default false) parameter to restart the VM after migration. When this is true, the migrate action becomes a MultipleAction, first migrating and then restarting the VM. Signed-off-by: Callum McIntyre --- .../Controls/VMOperationToolStripMenuItem.cs | 9 +++-- XenAdmin/Commands/CrossPoolMigrateCommand.cs | 9 ++--- .../CrossPoolMigrateWizard.cs | 33 +++++++++++++++++-- .../Actions/VM/VMCrossPoolMigrateAction.cs | 2 +- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs b/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs index 924fa737f..b52b0339c 100644 --- a/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs +++ b/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs @@ -56,7 +56,9 @@ namespace XenAdmin.Commands private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private readonly vm_operations _operation; - public VMOperationToolStripMenuItem(Command command, bool inContextMenu, vm_operations operation) + private readonly bool _resumeAfter; + + protected VMOperationToolStripMenuItem(Command command, bool inContextMenu, vm_operations operation) : base(command, inContextMenu) { if (operation != vm_operations.start_on && operation != vm_operations.resume_on && operation != vm_operations.pool_migrate) @@ -64,6 +66,9 @@ namespace XenAdmin.Commands throw new ArgumentException("Invalid operation", "operation"); } + if (operation.Equals(vm_operations.resume_on)) + _resumeAfter = true; + _operation = operation; base.DropDownItems.Add(new ToolStripMenuItem()); } @@ -195,7 +200,7 @@ namespace XenAdmin.Commands if (host != null) { VMOperationCommand cmd = new VMOperationHostCommand(Command.MainWindowCommandInterface, selection, delegate { return host; }, host.Name.EscapeAmpersands(), _operation, session); - VMOperationCommand cpmCmd = new CrossPoolMigrateCommand(Command.MainWindowCommandInterface, selection, host); + VMOperationCommand cpmCmd = new CrossPoolMigrateCommand(Command.MainWindowCommandInterface, selection, host, _resumeAfter); VMOperationToolStripMenuSubItem tempItem = item; Program.Invoke(Program.MainWindow, delegate diff --git a/XenAdmin/Commands/CrossPoolMigrateCommand.cs b/XenAdmin/Commands/CrossPoolMigrateCommand.cs index ac108edb8..d0ab5aa68 100644 --- a/XenAdmin/Commands/CrossPoolMigrateCommand.cs +++ b/XenAdmin/Commands/CrossPoolMigrateCommand.cs @@ -47,16 +47,18 @@ namespace XenAdmin.Commands { internal class CrossPoolMigrateCommand : VMOperationCommand { + private bool _resumeAfter; public CrossPoolMigrateCommand(IMainWindow mainWindow, IEnumerable selection) : base(mainWindow, selection) { } protected Host preSelectedHost = null; - public CrossPoolMigrateCommand(IMainWindow mainWindow, IEnumerable selection, Host preSelectedHost) + public CrossPoolMigrateCommand(IMainWindow mainWindow, IEnumerable selection, Host preSelectedHost, bool resumeAfter=false) : base(mainWindow, selection) { this.preSelectedHost = preSelectedHost; + _resumeAfter = resumeAfter; } public override string MenuText @@ -81,10 +83,9 @@ namespace XenAdmin.Commands } else { - MainWindowCommandInterface.ShowPerConnectionWizard(con, - new CrossPoolMigrateWizard(con, selection, preSelectedHost, WizardMode.Migrate)); + var wizard = new CrossPoolMigrateWizard(con, selection, preSelectedHost, WizardMode.Migrate, _resumeAfter); + MainWindowCommandInterface.ShowPerConnectionWizard(con, wizard); } - } protected override Host GetHost(VM vm) diff --git a/XenAdmin/Wizards/CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs b/XenAdmin/Wizards/CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs index 9dd83ae3b..cfa2ac344 100644 --- a/XenAdmin/Wizards/CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs +++ b/XenAdmin/Wizards/CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using XenAdmin.Actions; using XenAdmin.Actions.VMActions; using XenAdmin.Commands; using XenAdmin.Controls; @@ -68,13 +69,17 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard private WizardMode wizardMode; - public CrossPoolMigrateWizard(IXenConnection con, IEnumerable selection, Host targetHostPreSelection, WizardMode mode) + private bool _resumeAfterMigrate; + + // Note that resumeAfter is currently only implemented for Migrate mode, used for resume on server functionality + public CrossPoolMigrateWizard(IXenConnection con, IEnumerable selection, Host targetHostPreSelection, WizardMode mode, bool resumeAfterMigrate=false) : base(con) { InitializeComponent(); hostPreSelection = targetHostPreSelection; wizardMode = mode; InitialiseWizard(selection); + _resumeAfterMigrate = resumeAfterMigrate; } @@ -239,8 +244,30 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard if (wizardMode == WizardMode.Move && IsIntraPoolMove(pair)) new VMMoveAction(vm, pair.Value.Storage, target).RunAsync(); - else - new VMCrossPoolMigrateAction(vm, target, SelectedTransferNetwork, pair.Value, wizardMode == WizardMode.Copy).RunAsync(); + else + { + var isCopy = wizardMode == WizardMode.Copy; + + if (_resumeAfterMigrate) + { + var title = VMCrossPoolMigrateAction.GetTitle(vm, target, isCopy); + var startDescription = isCopy ? Messages.ACTION_VM_COPYING: Messages.ACTION_VM_MIGRATING; + var endDescription = isCopy ? Messages.ACTION_VM_COPIED: Messages.ACTION_VM_MIGRATED; + + var actions = new List() + { + new VMCrossPoolMigrateAction(vm, target, SelectedTransferNetwork, pair.Value, isCopy), + new ResumeAndStartVMsAction(vm.Connection, target, new List{vm}, new List(), null, null) + }; + + new MultipleAction(vm.Connection, title, startDescription, endDescription, + actions, false, false, true).RunAsync(); + } + else + { + new VMCrossPoolMigrateAction(vm, target, SelectedTransferNetwork, pair.Value, isCopy).RunAsync(); + } + } } base.FinishWizard(); diff --git a/XenModel/Actions/VM/VMCrossPoolMigrateAction.cs b/XenModel/Actions/VM/VMCrossPoolMigrateAction.cs index 630cb3593..beb47bbe8 100644 --- a/XenModel/Actions/VM/VMCrossPoolMigrateAction.cs +++ b/XenModel/Actions/VM/VMCrossPoolMigrateAction.cs @@ -77,7 +77,7 @@ namespace XenAdmin.Actions.VMActions } - private static string GetTitle(VM vm, Host toHost, bool copy) + public static string GetTitle(VM vm, Host toHost, bool copy) { if (copy) return string.Format(Messages.ACTION_VM_CROSS_POOL_COPY_TITLE, vm.Name, toHost.Name); From 6a096ebf07c512cca8d59245fdbdddd0d8786ff0 Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Tue, 8 Nov 2016 16:05:51 +0000 Subject: [PATCH 2/2] [CA-226897] Move the VMCrossPoolMigrateAction to be a variable outside the block, and added SuppressHistory to the MultipleAction. --- .../CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/XenAdmin/Wizards/CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs b/XenAdmin/Wizards/CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs index cfa2ac344..8ac9cc912 100644 --- a/XenAdmin/Wizards/CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs +++ b/XenAdmin/Wizards/CrossPoolMigrateWizard/CrossPoolMigrateWizard.cs @@ -247,6 +247,8 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard else { var isCopy = wizardMode == WizardMode.Copy; + var migrateAction = + new VMCrossPoolMigrateAction(vm, target, SelectedTransferNetwork, pair.Value, isCopy); if (_resumeAfterMigrate) { @@ -256,16 +258,16 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard var actions = new List() { - new VMCrossPoolMigrateAction(vm, target, SelectedTransferNetwork, pair.Value, isCopy), + migrateAction, new ResumeAndStartVMsAction(vm.Connection, target, new List{vm}, new List(), null, null) }; new MultipleAction(vm.Connection, title, startDescription, endDescription, - actions, false, false, true).RunAsync(); + actions, true, false, true).RunAsync(); } else { - new VMCrossPoolMigrateAction(vm, target, SelectedTransferNetwork, pair.Value, isCopy).RunAsync(); + migrateAction.RunAsync(); } } }