diff --git a/XenAdmin/Commands/CopyTemplateCommand.cs b/XenAdmin/Commands/CopyTemplateCommand.cs deleted file mode 100644 index e234b8d5ed..0000000000 --- a/XenAdmin/Commands/CopyTemplateCommand.cs +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright (c) Citrix Systems, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -using System.Collections.Generic; -using System.Linq; -using XenAdmin.Actions; -using XenAdmin.Actions.VMActions; -using XenAdmin.Core; -using XenAdmin.Dialogs; -using XenAPI; - -namespace XenAdmin.Commands -{ - /// - /// Launches the Copy-Template dialog for the specified VM. - /// - internal class CopyTemplateCommand : Command - { - /// - /// Initializes a new instance of this Command. The parameter-less constructor is required in the derived - /// class if it is to be attached to a ToolStrip menu item or button. It should not be used in any other scenario. - /// - public CopyTemplateCommand() - { - } - - public CopyTemplateCommand(IMainWindow mainWindow, IEnumerable selection) - : base(mainWindow, selection) - { - } - - private bool CheckRbacPermissions(VM vm, RbacMethodList methodList, string warningMessage) - { - if (vm.Connection.Session.IsLocalSuperuser) - return true; - - var currentRoles = vm.Connection.Session.Roles; - var validRoles = Role.ValidRoleList(methodList, vm.Connection); - - if (currentRoles.Any(currentRole => validRoles.Contains(currentRole))) - return true; - - currentRoles.Sort(); - - using (var dlg = new ErrorDialog(string.Format(warningMessage, currentRoles[0].FriendlyName()))) - dlg.ShowDialog(Parent); - - return false; - } - - protected override void RunCore(SelectedItemCollection selection) - { - var template = (VM)selection[0].XenObject; - - if (CrossPoolCopyTemplateCommand.CanRun(template, null)) - { - new CrossPoolCopyTemplateCommand(MainWindowCommandInterface, selection).Run(); - } - else - { - var rbac = new RbacMethodList(); - rbac.AddRange(SrRefreshAction.StaticRBACDependencies); - rbac.AddRange(VMCopyAction.StaticRBACDependencies); - rbac.AddRange(VMCloneAction.StaticRBACDependencies); - - if (CheckRbacPermissions(template, rbac, Messages.RBAC_INTRA_POOL_COPY_TEMPLATE_BLOCKED)) - new CopyVMDialog(template).ShowPerXenObject(template, Program.MainWindow); - } - } - - protected override bool CanRunCore(SelectedItemCollection selection) - { - return selection.ContainsOneItemOfType() && selection.AtLeastOneXenObjectCan(CanRun); - } - - private static bool CanRun(VM vm) - { - if (vm != null && vm.is_a_template && !vm.is_a_snapshot && !vm.Locked && vm.allowed_operations != null && !vm.InternalTemplate()) - { - if (CrossPoolCopyTemplateCommand.CanRun(vm, null)) - return true; - if (vm.allowed_operations.Contains(vm_operations.clone) || vm.allowed_operations.Contains(vm_operations.copy)) - return true; - } - return false; - } - - public override string MenuText => Messages.MAINWINDOW_COPY_TEMPLATE; - } -} diff --git a/XenAdmin/Commands/CopyVMCommand.cs b/XenAdmin/Commands/CopyVMCommand.cs index ce9f3bc4b3..1e06b43bfb 100644 --- a/XenAdmin/Commands/CopyVMCommand.cs +++ b/XenAdmin/Commands/CopyVMCommand.cs @@ -35,77 +35,132 @@ using XenAdmin.Actions.VMActions; using XenAdmin.Core; using XenAdmin.Dialogs; +using XenAdmin.Network; +using XenAdmin.Wizards.CrossPoolMigrateWizard; using XenAPI; namespace XenAdmin.Commands { - /// - /// Launches the Copy-VM dialog for the selected VM. - /// - internal class CopyVMCommand : Command + internal abstract class CopyVmTemplateCommandBase : Command { - /// - /// Initializes a new instance of this Command. The parameter-less constructor is required in the derived - /// class if it is to be attached to a ToolStrip menu item or button. It should not be used in any other scenario. - /// - public CopyVMCommand() + protected CopyVmTemplateCommandBase() { } - public CopyVMCommand(IMainWindow mainWindow, IEnumerable selection) + protected CopyVmTemplateCommandBase(IMainWindow mainWindow, IEnumerable selection) : base(mainWindow, selection) { } - private bool CheckRbacPermissions(VM vm, RbacMethodList methodList, string warningMessage) + protected override bool CanRunCore(SelectedItemCollection selection) + { + return selection.ContainsOneItemOfType() && selection.AtLeastOneXenObjectCan(CanRun); + } + + protected override void RunCore(SelectedItemCollection selection) { - if (vm.Connection.Session.IsLocalSuperuser) + var vm = (VM)selection[0].XenObject; + + if (CanLaunchMigrateWizard(vm)) + { + MainWindowCommandInterface.ShowPerConnectionWizard(vm.Connection, + new CrossPoolMigrateWizard(vm.Connection, selection, null, WizardMode.Copy)); + return; + } + + if (CheckRbacPermissions(vm.Connection)) + new CopyVMDialog(vm).ShowPerXenObject(vm, Program.MainWindow); + } + + private bool CheckRbacPermissions(IXenConnection connection) + { + if (connection.Session.IsLocalSuperuser) return true; - var currentRoles = vm.Connection.Session.Roles; - var validRoles = Role.ValidRoleList(methodList, vm.Connection); + var methodList = new RbacMethodList(); + methodList.AddRange(SrRefreshAction.StaticRBACDependencies); + methodList.AddRange(VMCopyAction.StaticRBACDependencies); + methodList.AddRange(VMCloneAction.StaticRBACDependencies); + + var currentRoles = connection.Session.Roles; + var validRoles = Role.ValidRoleList(methodList, connection); if (currentRoles.Any(currentRole => validRoles.Contains(currentRole))) return true; currentRoles.Sort(); - using (var dlg = new ErrorDialog(string.Format(warningMessage, currentRoles[0].FriendlyName()))) + using (var dlg = new ErrorDialog(string.Format(RbacMessage, currentRoles[0].FriendlyName()))) dlg.ShowDialog(Parent); return false; } - protected override void RunCore(SelectedItemCollection selection) - { - var vm = (VM)selection[0].XenObject; + protected abstract string RbacMessage { get; } + protected abstract bool CanRun(VM vm); + protected abstract bool CanLaunchMigrateWizard(VM vm); + } - if (CrossPoolCopyVMCommand.CanRun(vm, null)) - { - new CrossPoolCopyVMCommand(MainWindowCommandInterface, selection).Run(); - } - else - { - var rbac = new RbacMethodList(); - rbac.AddRange(SrRefreshAction.StaticRBACDependencies); - rbac.AddRange(VMCopyAction.StaticRBACDependencies); - rbac.AddRange(VMCloneAction.StaticRBACDependencies); - if (CheckRbacPermissions(vm, rbac, Messages.RBAC_INTRA_POOL_COPY_VM_BLOCKED)) - new CopyVMDialog(vm).ShowPerXenObject(vm, Program.MainWindow); - } + internal class CopyVMCommand : CopyVmTemplateCommandBase + { + public CopyVMCommand() + { } - protected override bool CanRunCore(SelectedItemCollection selection) + public CopyVMCommand(IMainWindow mainWindow, IEnumerable selection) + : base(mainWindow, selection) { - return selection.ContainsOneItemOfType() && selection.AtLeastOneXenObjectCan(CanRun); } - private static bool CanRun(VM vm) + protected override bool CanRun(VM vm) + { + if (vm == null || vm.is_a_template || vm.Locked || vm.allowed_operations == null) + return false; + + if (CanLaunchMigrateWizard(vm)) + return true; + + return vm.allowed_operations.Contains(vm_operations.export) && vm.power_state != vm_power_state.Suspended; + } + + protected override bool CanLaunchMigrateWizard(VM vm) { - return vm != null && (CrossPoolCopyVMCommand.CanRun(vm, null) || vm.CanBeCopied()); + return vm.power_state == vm_power_state.Halted && CrossPoolMigrateCommand.CanRun(vm, null); } public override string MenuText => Messages.MAINWINDOW_COPY_VM; + protected override string RbacMessage => Messages.RBAC_INTRA_POOL_COPY_VM_BLOCKED; + } + + + internal class CopyTemplateCommand : CopyVmTemplateCommandBase + { + public CopyTemplateCommand() + { + } + + public CopyTemplateCommand(IMainWindow mainWindow, IEnumerable selection) + : base(mainWindow, selection) + { + } + + protected override bool CanRun(VM vm) + { + if (vm == null || !vm.is_a_template || vm.is_a_snapshot || vm.Locked || vm.allowed_operations == null || vm.InternalTemplate()) return false; + + if (CanLaunchMigrateWizard(vm)) + return true; + + return vm.allowed_operations.Contains(vm_operations.clone) || vm.allowed_operations.Contains(vm_operations.copy); + } + + protected override bool CanLaunchMigrateWizard(VM vm) + { + return !vm.DefaultTemplate() && CrossPoolMigrateCommand.CanRun(vm, null); + } + + public override string MenuText => Messages.MAINWINDOW_COPY_TEMPLATE; + protected override string RbacMessage => Messages.RBAC_INTRA_POOL_COPY_TEMPLATE_BLOCKED; } } diff --git a/XenAdmin/XenAdmin.csproj b/XenAdmin/XenAdmin.csproj index 606126f5df..9936cfe275 100755 --- a/XenAdmin/XenAdmin.csproj +++ b/XenAdmin/XenAdmin.csproj @@ -3360,7 +3360,6 @@ - diff --git a/XenModel/XenAPI-Extensions/VM.cs b/XenModel/XenAPI-Extensions/VM.cs index a4d2fdebb8..1571c71dab 100644 --- a/XenModel/XenAPI-Extensions/VM.cs +++ b/XenModel/XenAPI-Extensions/VM.cs @@ -1639,18 +1639,6 @@ public bool CanBeMoved() return false; } - /// - /// Whether the VM can be copied inside the pool (vm.copy) - /// - public bool CanBeCopied() - { - if (!is_a_template && !Locked && allowed_operations != null && allowed_operations.Contains(vm_operations.export) && power_state != vm_power_state.Suspended) - { - return true; - } - return false; - } - /// /// Returns whether this is a Windows VM by checking the distro value in the /// guest_metrics before falling back to the viridian flag. The result may not be