From 8f6c345c66203071321fa661339b6e0539ddacc8 Mon Sep 17 00:00:00 2001 From: Mihaela Stoica Date: Tue, 13 Jun 2017 13:12:01 +0100 Subject: [PATCH 1/2] CA-249858: XenCenter gives different messages for migrate VM at different screens when pool connected with vm-operator user Expose the reasons why a cross pool migration command cannot execute. Signed-off-by: Mihaela Stoica --- .../Controls/VMOperationToolStripMenuItem.cs | 4 +- XenAdmin/Commands/CrossPoolMigrateCommand.cs | 45 +++++++++++++++++-- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs b/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs index 2cb9ddac0..bb23cb42d 100644 --- a/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs +++ b/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs @@ -200,13 +200,13 @@ 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, _resumeAfter); + CrossPoolMigrateCommand cpmCmd = new CrossPoolMigrateCommand(Command.MainWindowCommandInterface, selection, host, _resumeAfter); VMOperationToolStripMenuSubItem tempItem = item; Program.Invoke(Program.MainWindow, delegate { bool oldMigrateCmdCanRun = cmd.CanExecute(); - if (_operation == vm_operations.start_on || !oldMigrateCmdCanRun && !cpmCmd.CanExecute()) + if (_operation == vm_operations.start_on || (!oldMigrateCmdCanRun && !cpmCmd.CanExecute() && string.IsNullOrEmpty(cpmCmd.CantExecuteReason))) tempItem.Command = cmd; else tempItem.Command = oldMigrateCmdCanRun ? cmd : cpmCmd; diff --git a/XenAdmin/Commands/CrossPoolMigrateCommand.cs b/XenAdmin/Commands/CrossPoolMigrateCommand.cs index c0ef1d53e..1104f6d91 100644 --- a/XenAdmin/Commands/CrossPoolMigrateCommand.cs +++ b/XenAdmin/Commands/CrossPoolMigrateCommand.cs @@ -63,7 +63,16 @@ namespace XenAdmin.Commands public override string MenuText { - get { return preSelectedHost == null ? Messages.HOST_MENU_CPM_TEXT : preSelectedHost.Name.EscapeAmpersands(); } + get + { + if (preSelectedHost == null) + return Messages.HOST_MENU_CPM_TEXT; + + var cantExecuteReason = CantExecuteReason; + return string.IsNullOrEmpty(cantExecuteReason) + ? preSelectedHost.Name.EscapeAmpersands() + : string.Format(Messages.MAINWINDOW_CONTEXT_REASON, preSelectedHost.Name.EscapeAmpersands(), cantExecuteReason.TrimEnd('\n', '\r')); + } } public override string ContextMenuText { get { return Messages.HOST_MENU_CPM_TEXT; } } @@ -100,18 +109,31 @@ namespace XenAdmin.Commands dlg.ShowDialog(parent); } + private readonly Dictionary cantExecuteReasons = new Dictionary(); + protected override bool CanExecute(VM vm) { - return CanExecute(vm, preSelectedHost); + if (preSelectedHost == null) + return CanExecute(vm, preSelectedHost); + + var filter = new CrossPoolMigrateCanMigrateFilter(preSelectedHost, new List {vm}, WizardMode.Migrate); + var canExecute = CanExecute(vm, preSelectedHost, filter); + if (string.IsNullOrEmpty(filter.Reason)) + cantExecuteReasons.Remove(vm); + else + cantExecuteReasons[vm] = filter.Reason; + return canExecute; } - public static bool CanExecute(VM vm, Host preselectedHost) + public static bool CanExecute(VM vm, Host preselectedHost, CrossPoolMigrateCanMigrateFilter filter = null) { bool failureFound = false; if (preselectedHost != null) { - failureFound = new CrossPoolMigrateCanMigrateFilter(preselectedHost, new List {vm}, WizardMode.Migrate).FailureFound; + failureFound = filter == null + ? new CrossPoolMigrateCanMigrateFilter(preselectedHost, new List {vm}, WizardMode.Migrate).FailureFound + : filter.FailureFound; } return !failureFound && @@ -121,5 +143,20 @@ namespace XenAdmin.Commands vm.SRs.ToList().All(sr=> sr != null && !sr.HBALunPerVDI) && (preselectedHost == null || vm.Connection.Resolve(vm.resident_on) != preselectedHost); //Not the same as the pre-selected host } + + public string CantExecuteReason + { + get + { + if (cantExecuteReasons.Count == GetSelection().Count) // none can execute + { + var uniqueReasons = cantExecuteReasons.Values.Distinct().ToList(); + + if (uniqueReasons.Count == 1) + return uniqueReasons[0]; + } + return null; + } + } } } From a79e156cf59448333ba61f937b0e6b77779ae264 Mon Sep 17 00:00:00 2001 From: Mihaela Stoica Date: Tue, 13 Jun 2017 16:47:43 +0100 Subject: [PATCH 2/2] CA-249858: Moved the Trim call Signed-off-by: Mihaela Stoica --- XenAdmin/Commands/CrossPoolMigrateCommand.cs | 2 +- .../Filters/CrossPoolMigrateCanMigrateFilter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/XenAdmin/Commands/CrossPoolMigrateCommand.cs b/XenAdmin/Commands/CrossPoolMigrateCommand.cs index 1104f6d91..10322780c 100644 --- a/XenAdmin/Commands/CrossPoolMigrateCommand.cs +++ b/XenAdmin/Commands/CrossPoolMigrateCommand.cs @@ -71,7 +71,7 @@ namespace XenAdmin.Commands var cantExecuteReason = CantExecuteReason; return string.IsNullOrEmpty(cantExecuteReason) ? preSelectedHost.Name.EscapeAmpersands() - : string.Format(Messages.MAINWINDOW_CONTEXT_REASON, preSelectedHost.Name.EscapeAmpersands(), cantExecuteReason.TrimEnd('\n', '\r')); + : string.Format(Messages.MAINWINDOW_CONTEXT_REASON, preSelectedHost.Name.EscapeAmpersands(), cantExecuteReason); } } diff --git a/XenAdmin/Wizards/CrossPoolMigrateWizard/Filters/CrossPoolMigrateCanMigrateFilter.cs b/XenAdmin/Wizards/CrossPoolMigrateWizard/Filters/CrossPoolMigrateCanMigrateFilter.cs index 99bd3e5bf..e89d262bb 100644 --- a/XenAdmin/Wizards/CrossPoolMigrateWizard/Filters/CrossPoolMigrateCanMigrateFilter.cs +++ b/XenAdmin/Wizards/CrossPoolMigrateWizard/Filters/CrossPoolMigrateCanMigrateFilter.cs @@ -107,7 +107,7 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters catch (Failure failure) { if (failure.ErrorDescription.Count > 0 && failure.ErrorDescription[0] == Failure.RBAC_PERMISSION_DENIED) - disableReason = failure.Message.Split('\n')[0]; // we want the first line only + disableReason = failure.Message.Split('\n')[0].TrimEnd('\r'); // we want the first line only else disableReason = failure.Message;