Add new MenuItem to Force Migrate a VM

This commit is contained in:
Alexander Schulz 2018-07-16 23:06:58 +02:00
parent 2f33754792
commit 70f61c0cd7
15 changed files with 81 additions and 53 deletions

View File

@ -59,10 +59,15 @@ namespace XenAdmin.Commands
{ {
if (selection.ToList().All(item => !Helpers.CrossPoolMigrationRestrictedWithWlb(item.Connection))) if (selection.ToList().All(item => !Helpers.CrossPoolMigrationRestrictedWithWlb(item.Connection)))
{ {
VMOperationCommand cmd = new CrossPoolMigrateCommand(Command.MainWindowCommandInterface, selection);
DropDownItems.Add(new ToolStripSeparator()); DropDownItems.Add(new ToolStripSeparator());
VMOperationCommand cmd = new CrossPoolMigrateCommand(Command.MainWindowCommandInterface, selection, false);
VMOperationToolStripMenuSubItem lastItem = new VMOperationToolStripMenuSubItem(cmd); VMOperationToolStripMenuSubItem lastItem = new VMOperationToolStripMenuSubItem(cmd);
DropDownItems.Add(lastItem); DropDownItems.Add(lastItem);
VMOperationCommand cmdForce = new CrossPoolMigrateCommand(Command.MainWindowCommandInterface, selection, true);
VMOperationToolStripMenuSubItem lastItemForce = new VMOperationToolStripMenuSubItem(cmdForce);
DropDownItems.Add(lastItemForce);
} }
} }

View File

@ -299,8 +299,8 @@ namespace XenAdmin.Commands
else else
{ {
var cpmCmd = isHomeServer var cpmCmd = isHomeServer
? new CrossPoolMigrateToHomeCommand(menu.Command.MainWindowCommandInterface, selection, host) ? new CrossPoolMigrateToHomeCommand(menu.Command.MainWindowCommandInterface, selection, host, false)
: new CrossPoolMigrateCommand(menu.Command.MainWindowCommandInterface, selection, host, menu._resumeAfter); : new CrossPoolMigrateCommand(menu.Command.MainWindowCommandInterface, selection, host, false, menu._resumeAfter);
var crossPoolMigrateCmdCanRun = cpmCmd.CanExecute(); var crossPoolMigrateCmdCanRun = cpmCmd.CanExecute();
if (Stopped) if (Stopped)

View File

@ -66,7 +66,7 @@ namespace XenAdmin.Commands
{ {
VM template = (VM)selection[0].XenObject; VM template = (VM)selection[0].XenObject;
if (CrossPoolCopyTemplateCommand.CanExecute(template, null)) if (CrossPoolCopyTemplateCommand.CanExecute(template, null, false))
new CrossPoolCopyTemplateCommand(MainWindowCommandInterface, selection).Execute(); new CrossPoolCopyTemplateCommand(MainWindowCommandInterface, selection).Execute();
else else
MainWindowCommandInterface.ShowPerXenModelObjectWizard(template, new CopyVMDialog(template)); MainWindowCommandInterface.ShowPerXenModelObjectWizard(template, new CopyVMDialog(template));
@ -81,7 +81,7 @@ namespace XenAdmin.Commands
{ {
if (vm != null && vm.is_a_template && !vm.is_a_snapshot && !vm.Locked && vm.allowed_operations != null && !vm.InternalTemplate()) if (vm != null && vm.is_a_template && !vm.is_a_snapshot && !vm.Locked && vm.allowed_operations != null && !vm.InternalTemplate())
{ {
if (CrossPoolCopyTemplateCommand.CanExecute(vm, null)) if (CrossPoolCopyTemplateCommand.CanExecute(vm, null, false))
return true; return true;
if (vm.allowed_operations.Contains(vm_operations.clone) || vm.allowed_operations.Contains(vm_operations.copy)) if (vm.allowed_operations.Contains(vm_operations.clone) || vm.allowed_operations.Contains(vm_operations.copy))
return true; return true;

View File

@ -66,7 +66,7 @@ namespace XenAdmin.Commands
{ {
VM vm = (VM)selection[0].XenObject; VM vm = (VM)selection[0].XenObject;
if (CrossPoolCopyVMCommand.CanExecute(vm, null)) if (CrossPoolCopyVMCommand.CanExecute(vm, null, false))
new CrossPoolCopyVMCommand(MainWindowCommandInterface, selection).Execute(); new CrossPoolCopyVMCommand(MainWindowCommandInterface, selection).Execute();
else else
MainWindowCommandInterface.ShowPerXenModelObjectWizard(vm, new CopyVMDialog(vm)); MainWindowCommandInterface.ShowPerXenModelObjectWizard(vm, new CopyVMDialog(vm));
@ -79,7 +79,7 @@ namespace XenAdmin.Commands
private static bool CanExecute(VM vm) private static bool CanExecute(VM vm)
{ {
return vm != null && (CrossPoolCopyVMCommand.CanExecute(vm, null) || vm.CanBeCopied()); return vm != null && (CrossPoolCopyVMCommand.CanExecute(vm, null, false) || vm.CanBeCopied());
} }
public override string MenuText public override string MenuText

View File

@ -40,11 +40,11 @@ namespace XenAdmin.Commands
internal class CrossPoolCopyVMCommand : CrossPoolMigrateCommand internal class CrossPoolCopyVMCommand : CrossPoolMigrateCommand
{ {
public CrossPoolCopyVMCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection) public CrossPoolCopyVMCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection)
: this(mainWindow, selection, null) : this(mainWindow, selection, null, false)
{ } { }
public CrossPoolCopyVMCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost) public CrossPoolCopyVMCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost, bool force)
: base(mainWindow, selection, preSelectedHost) : base(mainWindow, selection, preSelectedHost, force)
{ {
} }
@ -58,31 +58,31 @@ namespace XenAdmin.Commands
var con = selection.GetConnectionOfFirstItem(); var con = selection.GetConnectionOfFirstItem();
MainWindowCommandInterface.ShowPerConnectionWizard(con, MainWindowCommandInterface.ShowPerConnectionWizard(con,
new CrossPoolMigrateWizard(con, selection, preSelectedHost, WizardMode.Copy)); new CrossPoolMigrateWizard(con, selection, preSelectedHost, WizardMode.Copy, false));
} }
protected override bool CanExecute(VM vm) protected override bool CanExecute(VM vm)
{ {
return CanExecute(vm, preSelectedHost); return CanExecute(vm, preSelectedHost, _force);
} }
public static bool CanExecute(VM vm, Host preSelectedHost) public static bool CanExecute(VM vm, Host preSelectedHost, bool force)
{ {
if (vm == null || vm.is_a_template || vm.Locked || vm.power_state != vm_power_state.Halted) if (vm == null || vm.is_a_template || vm.Locked || vm.power_state != vm_power_state.Halted)
return false; return false;
return CrossPoolMigrateCommand.CanExecute(vm, preSelectedHost); return CrossPoolMigrateCommand.CanExecute(vm, preSelectedHost, force);
} }
} }
internal class CrossPoolCopyTemplateCommand : CrossPoolCopyVMCommand internal class CrossPoolCopyTemplateCommand : CrossPoolCopyVMCommand
{ {
public CrossPoolCopyTemplateCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection) public CrossPoolCopyTemplateCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection)
: this(mainWindow, selection, null) : this(mainWindow, selection, null, false)
{ } { }
public CrossPoolCopyTemplateCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost) public CrossPoolCopyTemplateCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost, bool force)
: base(mainWindow, selection, preSelectedHost) : base(mainWindow, selection, preSelectedHost, force)
{ {
} }
@ -91,12 +91,12 @@ namespace XenAdmin.Commands
get { return Messages.MAINWINDOW_COPY_TEMPLATE; } get { return Messages.MAINWINDOW_COPY_TEMPLATE; }
} }
public new static bool CanExecute(VM vm, Host preSelectedHost) public new static bool CanExecute(VM vm, Host preSelectedHost, bool force)
{ {
if (vm == null || !vm.is_a_template || vm.DefaultTemplate() || vm.Locked) if (vm == null || !vm.is_a_template || vm.DefaultTemplate() || vm.Locked)
return false; return false;
return CrossPoolMigrateCommand.CanExecute(vm, preSelectedHost); return CrossPoolMigrateCommand.CanExecute(vm, preSelectedHost, force);
} }
} }
} }

View File

@ -48,17 +48,21 @@ namespace XenAdmin.Commands
internal class CrossPoolMigrateCommand : VMOperationCommand internal class CrossPoolMigrateCommand : VMOperationCommand
{ {
private bool _resumeAfter; private bool _resumeAfter;
internal bool _force = false;
public CrossPoolMigrateCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection) public CrossPoolMigrateCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, bool force)
: base(mainWindow, selection) : base(mainWindow, selection)
{ } {
_force = force;
}
protected Host preSelectedHost = null; protected Host preSelectedHost = null;
public CrossPoolMigrateCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost, bool resumeAfter=false) public CrossPoolMigrateCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost, bool force, bool resumeAfter=false)
: base(mainWindow, selection) : base(mainWindow, selection)
{ {
this.preSelectedHost = preSelectedHost; this.preSelectedHost = preSelectedHost;
_resumeAfter = resumeAfter; _resumeAfter = resumeAfter;
_force = force;
} }
public override string MenuText public override string MenuText
@ -66,7 +70,11 @@ namespace XenAdmin.Commands
get get
{ {
if (preSelectedHost == null) if (preSelectedHost == null)
{
if (_force)
return "Force " + Messages.HOST_MENU_CPM_TEXT;
return Messages.HOST_MENU_CPM_TEXT; return Messages.HOST_MENU_CPM_TEXT;
}
var cantExecuteReason = CantExecuteReason; var cantExecuteReason = CantExecuteReason;
return string.IsNullOrEmpty(cantExecuteReason) return string.IsNullOrEmpty(cantExecuteReason)
@ -92,7 +100,7 @@ namespace XenAdmin.Commands
} }
else else
{ {
var wizard = new CrossPoolMigrateWizard(con, selection, preSelectedHost, WizardMode.Migrate, _resumeAfter); var wizard = new CrossPoolMigrateWizard(con, selection, preSelectedHost, WizardMode.Migrate, _force, _resumeAfter);
MainWindowCommandInterface.ShowPerConnectionWizard(con, wizard); MainWindowCommandInterface.ShowPerConnectionWizard(con, wizard);
} }
} }
@ -114,10 +122,10 @@ namespace XenAdmin.Commands
protected override bool CanExecute(VM vm) protected override bool CanExecute(VM vm)
{ {
if (preSelectedHost == null) if (preSelectedHost == null)
return CanExecute(vm, preSelectedHost); return CanExecute(vm, preSelectedHost, _force);
var filter = new CrossPoolMigrateCanMigrateFilter(preSelectedHost, new List<VM> {vm}, WizardMode.Migrate); var filter = new CrossPoolMigrateCanMigrateFilter(preSelectedHost, new List<VM> {vm}, WizardMode.Migrate, _force);
var canExecute = CanExecute(vm, preSelectedHost, filter); var canExecute = CanExecute(vm, preSelectedHost, _force, filter);
if (string.IsNullOrEmpty(filter.Reason)) if (string.IsNullOrEmpty(filter.Reason))
cantExecuteReasons.Remove(vm); cantExecuteReasons.Remove(vm);
else else
@ -125,14 +133,14 @@ namespace XenAdmin.Commands
return canExecute; return canExecute;
} }
public static bool CanExecute(VM vm, Host preselectedHost, CrossPoolMigrateCanMigrateFilter filter = null) public static bool CanExecute(VM vm, Host preselectedHost, bool force, CrossPoolMigrateCanMigrateFilter filter = null)
{ {
bool failureFound = false; bool failureFound = false;
if (preselectedHost != null) if (preselectedHost != null)
{ {
failureFound = filter == null failureFound = filter == null
? new CrossPoolMigrateCanMigrateFilter(preselectedHost, new List<VM> {vm}, WizardMode.Migrate).FailureFound ? new CrossPoolMigrateCanMigrateFilter(preselectedHost, new List<VM> {vm}, WizardMode.Migrate, force).FailureFound
: filter.FailureFound; : filter.FailureFound;
} }

View File

@ -42,8 +42,8 @@ namespace XenAdmin.Commands
/// </summary> /// </summary>
internal class CrossPoolMigrateToHomeCommand : CrossPoolMigrateCommand internal class CrossPoolMigrateToHomeCommand : CrossPoolMigrateCommand
{ {
public CrossPoolMigrateToHomeCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost) public CrossPoolMigrateToHomeCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost, bool force)
: base(mainWindow, selection, preSelectedHost) : base(mainWindow, selection, preSelectedHost, force)
{ {
} }

View File

@ -40,11 +40,11 @@ namespace XenAdmin.Commands
internal class CrossPoolMoveVMCommand : CrossPoolMigrateCommand internal class CrossPoolMoveVMCommand : CrossPoolMigrateCommand
{ {
public CrossPoolMoveVMCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection) public CrossPoolMoveVMCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection)
: this(mainWindow, selection, null) : this(mainWindow, selection, null, false)
{ } { }
public CrossPoolMoveVMCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost) public CrossPoolMoveVMCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection, Host preSelectedHost, bool force)
: base(mainWindow, selection, preSelectedHost) : base(mainWindow, selection, preSelectedHost, force)
{ {
} }
@ -64,22 +64,22 @@ namespace XenAdmin.Commands
else else
{ {
MainWindowCommandInterface.ShowPerConnectionWizard(con, MainWindowCommandInterface.ShowPerConnectionWizard(con,
new CrossPoolMigrateWizard(con, selection, preSelectedHost, GetWizardMode(selection))); new CrossPoolMigrateWizard(con, selection, preSelectedHost, GetWizardMode(selection), _force));
} }
} }
protected override bool CanExecute(VM vm) protected override bool CanExecute(VM vm)
{ {
return CanExecute(vm, preSelectedHost); return CanExecute(vm, preSelectedHost, _force);
} }
public static bool CanExecute(VM vm, Host preSelectedHost) public static bool CanExecute(VM vm, Host preSelectedHost, bool force)
{ {
if (vm == null || vm.is_a_template || vm.Locked || vm.power_state == vm_power_state.Running) if (vm == null || vm.is_a_template || vm.Locked || vm.power_state == vm_power_state.Running)
return false; return false;
return CrossPoolMigrateCommand.CanExecute(vm, preSelectedHost); return CrossPoolMigrateCommand.CanExecute(vm, preSelectedHost, force);
} }
public static WizardMode GetWizardMode(SelectedItemCollection selection) public static WizardMode GetWizardMode(SelectedItemCollection selection)

View File

@ -180,7 +180,7 @@ namespace XenAdmin.Commands
List<SelectedItem> selectedItems = new List<SelectedItem>(); List<SelectedItem> selectedItems = new List<SelectedItem>();
draggedVMs.ForEach(vm => selectedItems.Add(new SelectedItem(vm))); draggedVMs.ForEach(vm => selectedItems.Add(new SelectedItem(vm)));
new CrossPoolMoveVMCommand(MainWindowCommandInterface, selectedItems, targetHost) new CrossPoolMoveVMCommand(MainWindowCommandInterface, selectedItems, targetHost, false)
.Execute(); .Execute();
} }
} }

View File

@ -230,7 +230,7 @@ namespace XenAdmin.Commands
{ {
List<SelectedItem> selectedItems = new List<SelectedItem>(); List<SelectedItem> selectedItems = new List<SelectedItem>();
draggedVMs.ForEach(vm => selectedItems.Add(new SelectedItem(vm))); draggedVMs.ForEach(vm => selectedItems.Add(new SelectedItem(vm)));
new CrossPoolMigrateCommand(MainWindowCommandInterface, selectedItems, targetHost).Execute(); new CrossPoolMigrateCommand(MainWindowCommandInterface, selectedItems, targetHost, false).Execute();
return; return;
} }
} }

View File

@ -95,7 +95,7 @@ namespace XenAdmin.Commands
private static bool CanExecute(VM vm) private static bool CanExecute(VM vm)
{ {
return vm != null && (CrossPoolMoveVMCommand.CanExecute(vm, null) || vm.CanBeMoved()); return vm != null && (CrossPoolMoveVMCommand.CanExecute(vm, null, false) || vm.CanBeMoved());
} }
public override string MenuText public override string MenuText

View File

@ -43,6 +43,8 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
{ {
private List<VM> selectedVMs; private List<VM> selectedVMs;
private WizardMode wizardMode; private WizardMode wizardMode;
private bool force = false;
// A 2-level cache to store the result of CrossPoolMigrateCanMigrateFilter. // A 2-level cache to store the result of CrossPoolMigrateCanMigrateFilter.
// Cache structure is like: <vm-ref, <host-ref, fault-reason>>. // Cache structure is like: <vm-ref, <host-ref, fault-reason>>.
private IDictionary<string, IDictionary<string, string>> migrateFilterCache = private IDictionary<string, IDictionary<string, string>> migrateFilterCache =
@ -50,14 +52,15 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
public CrossPoolMigrateDestinationPage() public CrossPoolMigrateDestinationPage()
: this(null, WizardMode.Migrate, null) : this(null, WizardMode.Migrate, null, false)
{ {
} }
public CrossPoolMigrateDestinationPage(List<VM> selectedVMs, WizardMode wizardMode, List<IXenConnection> ignoredConnections) public CrossPoolMigrateDestinationPage(List<VM> selectedVMs, WizardMode wizardMode, List<IXenConnection> ignoredConnections, bool force)
{ {
this.selectedVMs = selectedVMs; this.selectedVMs = selectedVMs;
this.wizardMode = wizardMode; this.wizardMode = wizardMode;
this.force = force;
this.ignoredConnections = ignoredConnections ?? new List<IXenConnection>(); this.ignoredConnections = ignoredConnections ?? new List<IXenConnection>();
InitializeText(); InitializeText();
@ -134,7 +137,7 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
var filters = new List<ReasoningFilter> var filters = new List<ReasoningFilter>
{ {
new ResidentHostIsSameAsSelectionFilter(xenItem, selectedVMs), new ResidentHostIsSameAsSelectionFilter(xenItem, selectedVMs),
new CrossPoolMigrateCanMigrateFilter(xenItem, selectedVMs, wizardMode, migrateFilterCache), new CrossPoolMigrateCanMigrateFilter(xenItem, selectedVMs, wizardMode, force, migrateFilterCache),
new WlbEnabledFilter(xenItem, selectedVMs) new WlbEnabledFilter(xenItem, selectedVMs)
}; };
return new DelayLoadingOptionComboBoxItem(xenItem, filters); return new DelayLoadingOptionComboBoxItem(xenItem, filters);
@ -151,7 +154,7 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
vmList.Add(selectedVMs.Find(vm => vm.opaque_ref == opaqueRef)); vmList.Add(selectedVMs.Find(vm => vm.opaque_ref == opaqueRef));
filters.Add(new ResidentHostIsSameAsSelectionFilter(selectedItem.Item, vmList)); filters.Add(new ResidentHostIsSameAsSelectionFilter(selectedItem.Item, vmList));
filters.Add(new CrossPoolMigrateCanMigrateFilter(selectedItem.Item, vmList, wizardMode, migrateFilterCache)); filters.Add(new CrossPoolMigrateCanMigrateFilter(selectedItem.Item, vmList, wizardMode, force, migrateFilterCache));
filters.Add(new WlbEnabledFilter(selectedItem.Item, vmList)); filters.Add(new WlbEnabledFilter(selectedItem.Item, vmList));
} }

View File

@ -69,15 +69,17 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
private WizardMode wizardMode; private WizardMode wizardMode;
private bool _force;
private bool _resumeAfterMigrate; private bool _resumeAfterMigrate;
// Note that resumeAfter is currently only implemented for Migrate mode, used for resume on server functionality // Note that resumeAfter is currently only implemented for Migrate mode, used for resume on server functionality
public CrossPoolMigrateWizard(IXenConnection con, SelectedItemCollection selection, Host targetHostPreSelection, WizardMode mode, bool resumeAfterMigrate = false) public CrossPoolMigrateWizard(IXenConnection con, SelectedItemCollection selection, Host targetHostPreSelection, WizardMode mode, bool force, bool resumeAfterMigrate = false)
: base(con) : base(con)
{ {
InitializeComponent(); InitializeComponent();
hostPreSelection = targetHostPreSelection; hostPreSelection = targetHostPreSelection;
wizardMode = mode; wizardMode = mode;
_force = force;
InitialiseWizard(selection); InitialiseWizard(selection);
_resumeAfterMigrate = resumeAfterMigrate; _resumeAfterMigrate = resumeAfterMigrate;
} }
@ -184,7 +186,7 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
UpdateWindowTitle(); UpdateWindowTitle();
m_pageDestination = new CrossPoolMigrateDestinationPage(vmsFromSelection, m_pageDestination = new CrossPoolMigrateDestinationPage(vmsFromSelection,
wizardMode, GetSourceConnectionsForSelection(selection)) wizardMode, GetSourceConnectionsForSelection(selection), _force)
{ {
VmMappings = m_vmMappings, VmMappings = m_vmMappings,
Connection = selection.GetConnectionOfFirstItem() Connection = selection.GetConnectionOfFirstItem()
@ -271,14 +273,14 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
} }
} }
if (moveStorage) if (moveStorage)
new VMMoveAction(vm, pair.Value.Storage, target).RunAsync(); new VMMoveAction(vm, pair.Value.Storage, target).RunAsync();
} }
else else
{ {
var isCopy = wizardMode == WizardMode.Copy; var isCopy = wizardMode == WizardMode.Copy;
AsyncAction migrateAction; AsyncAction migrateAction;
if (isCopy || IsStorageMotion(pair)) if (isCopy || IsStorageMotion(pair))
migrateAction = new VMCrossPoolMigrateAction(vm, target, SelectedTransferNetwork, pair.Value, isCopy); migrateAction = new VMCrossPoolMigrateAction(vm, target, SelectedTransferNetwork, pair.Value, isCopy, _force);
else else
migrateAction = new VMMigrateAction(vm, target); migrateAction = new VMMigrateAction(vm, target);
@ -340,6 +342,11 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
: wizardMode == WizardMode.Move : wizardMode == WizardMode.Move
? Messages.MOVE_VM_WIZARD_TITLE ? Messages.MOVE_VM_WIZARD_TITLE
: IsCopyTemplate() ? Messages.COPY_TEMPLATE_WIZARD_TITLE : Messages.COPY_VM_WIZARD_TITLE; : IsCopyTemplate() ? Messages.COPY_TEMPLATE_WIZARD_TITLE : Messages.COPY_VM_WIZARD_TITLE;
if (_force)
{
Text = "Force " + Text;
}
} }
protected override void UpdateWizardContent(XenTabPage page) protected override void UpdateWizardContent(XenTabPage page)

View File

@ -48,9 +48,10 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
private readonly List<VM> preSelectedVMs; private readonly List<VM> preSelectedVMs;
private IDictionary<string, IDictionary<string, string>> cache; private IDictionary<string, IDictionary<string, string>> cache;
private bool canceled = false; private bool canceled = false;
private readonly bool force = false;
private static readonly Object cacheLock = new Object(); private static readonly Object cacheLock = new Object();
public CrossPoolMigrateCanMigrateFilter(IXenObject itemAddedToComboBox, List<VM> preSelectedVMs, WizardMode wizardMode, IDictionary<string, IDictionary<string, string>> cache = null) public CrossPoolMigrateCanMigrateFilter(IXenObject itemAddedToComboBox, List<VM> preSelectedVMs, WizardMode wizardMode, bool force, IDictionary<string, IDictionary<string, string>> cache = null)
: base(itemAddedToComboBox) : base(itemAddedToComboBox)
{ {
_wizardMode = wizardMode; _wizardMode = wizardMode;
@ -59,6 +60,8 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
else else
this.cache = cache; this.cache = cache;
this.force = force;
if (preSelectedVMs == null) if (preSelectedVMs == null)
throw new ArgumentNullException("Pre-selected VMs are null"); throw new ArgumentNullException("Pre-selected VMs are null");
this.preSelectedVMs = preSelectedVMs; this.preSelectedVMs = preSelectedVMs;
@ -147,14 +150,16 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
Session session = host.Connection.DuplicateSession(); Session session = host.Connection.DuplicateSession();
Dictionary<string, string> receiveMapping = Host.migrate_receive(session, host.opaque_ref, network.opaque_ref, new Dictionary<string, string>()); Dictionary<string, string> receiveMapping = Host.migrate_receive(session, host.opaque_ref, network.opaque_ref, new Dictionary<string, string>());
Dictionary<string, string> options = new Dictionary<string, string>();
if (force)
options.Add("force", "true");
VM.assert_can_migrate(vm.Connection.Session, VM.assert_can_migrate(vm.Connection.Session,
vm.opaque_ref, vm.opaque_ref,
receiveMapping, receiveMapping,
true, true,
GetVdiMap(vm, targetSrs), GetVdiMap(vm, targetSrs),
vm.Connection == host.Connection ? new Dictionary<XenRef<VIF>, XenRef<XenAPI.Network>>() : GetVifMap(vm, targetNetwork), vm.Connection == host.Connection ? new Dictionary<XenRef<VIF>, XenRef<XenAPI.Network>>() : GetVifMap(vm, targetNetwork),
//TODO: Implement force=true as general option options);
new Dictionary<string, string>(){{ "force", "true" }});
lock (cacheLock) lock (cacheLock)
{ {
vmCache.Add(host.opaque_ref, string.Empty); vmCache.Add(host.opaque_ref, string.Empty);

View File

@ -52,7 +52,7 @@ namespace XenAdmin.Actions.VMActions
/// <param name="mapping">the storage and networking mappings</param> /// <param name="mapping">the storage and networking mappings</param>
/// <param name="copy">weather this should be a cross-pool copy (true) or migrate (false) operation</param> /// <param name="copy">weather this should be a cross-pool copy (true) or migrate (false) operation</param>
/// <param name="force">weather this should be forced</param> /// <param name="force">weather this should be forced</param>
public VMCrossPoolMigrateAction(VM vm, Host destinationHost, XenAPI.Network transferNetwork, VmMapping mapping, bool copy, bool force=true) public VMCrossPoolMigrateAction(VM vm, Host destinationHost, XenAPI.Network transferNetwork, VmMapping mapping, bool copy, bool force)
: base(vm.Connection, GetTitle(vm, destinationHost, copy)) : base(vm.Connection, GetTitle(vm, destinationHost, copy))
{ {
Session = vm.Connection.Session; Session = vm.Connection.Session;