From 531496a46e0ba0ccdd0af3a270b21d357d22ff97 Mon Sep 17 00:00:00 2001 From: Mihaela Stoica Date: Wed, 30 Mar 2016 11:37:09 +0100 Subject: [PATCH] CA-205118: RPU Wizard Fails Due to Host CPU Incompatibility Error Added a Precheck to the RPU wizard, to check if the hosts in the pool have different CPU feature sets (using the old feature check for pre-Dundee pools) and display an error, offering to shut down all VMs. Signed-off-by: Mihaela Stoica --- .../Checks/AssertCanEvacuateUpgradeCheck.cs | 30 ++++ .../PoolProblem/CPUIncompatibilityProblem.cs | 144 ++++++++++++++++++ XenAdmin/XenAdmin.csproj | 1 + XenModel/Messages.Designer.cs | 38 ++++- XenModel/Messages.resx | 12 ++ 5 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 XenAdmin/Diagnostics/Problems/PoolProblem/CPUIncompatibilityProblem.cs diff --git a/XenAdmin/Diagnostics/Checks/AssertCanEvacuateUpgradeCheck.cs b/XenAdmin/Diagnostics/Checks/AssertCanEvacuateUpgradeCheck.cs index bdd687780..703df0344 100644 --- a/XenAdmin/Diagnostics/Checks/AssertCanEvacuateUpgradeCheck.cs +++ b/XenAdmin/Diagnostics/Checks/AssertCanEvacuateUpgradeCheck.cs @@ -35,6 +35,7 @@ using XenAdmin.Core; using XenAdmin.Diagnostics.Problems; using XenAdmin.Diagnostics.Problems.HostProblem; using XenAdmin.Diagnostics.Problems.VMProblem; +using XenAdmin.Diagnostics.Problems.PoolProblem; using XenAPI; namespace XenAdmin.Diagnostics.Checks @@ -51,6 +52,15 @@ namespace XenAdmin.Diagnostics.Checks if (!Host.IsLive) return new HostNotLiveWarning(this, Host); + // check if the pool has incompatible CPUs + Pool pool = Helpers.GetPoolOfOne(Host.Connection); + if (pool != null && PoolHasCpuIncompatibilityProblem(pool)) + { + if (Host.IsMaster()) + return new CPUIncompatibilityProblem(this, pool); + return new CPUCIncompatibilityWarning(this, pool, Host); + } + //vCPU configuration check foreach (var vm in Host.Connection.Cache.VMs.Where(vm => vm.is_a_real_vm)) { @@ -60,5 +70,25 @@ namespace XenAdmin.Diagnostics.Checks return base.RunCheck(); } + + private bool PoolHasCpuIncompatibilityProblem(Pool pool) + { + if (pool == null) + return false; + + if (!pool.Connection.Cache.VMs.Any(vm => vm.is_a_real_vm && vm.power_state != vm_power_state.Halted)) + return false; + + foreach (var host1 in pool.Connection.Cache.Hosts) + { + foreach (var host2 in pool.Connection.Cache.Hosts.Where(h => h.uuid != host1.uuid)) + { + if (!PoolJoinRules.CompatibleCPUs(host1, host2, false)) + return true; + } + } + return false; + + } } } \ No newline at end of file diff --git a/XenAdmin/Diagnostics/Problems/PoolProblem/CPUIncompatibilityProblem.cs b/XenAdmin/Diagnostics/Problems/PoolProblem/CPUIncompatibilityProblem.cs new file mode 100644 index 000000000..4b166640e --- /dev/null +++ b/XenAdmin/Diagnostics/Problems/PoolProblem/CPUIncompatibilityProblem.cs @@ -0,0 +1,144 @@ +/* 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; +using XenAdmin.Diagnostics.Checks; +using XenAPI; +using XenAdmin.Actions; +using System.Collections.Generic; +using XenAdmin.Actions.VMActions; +using XenAdmin.Commands; +using System.Linq; + + +namespace XenAdmin.Diagnostics.Problems.PoolProblem +{ + class CPUIncompatibilityProblem : PoolProblem + { + private Dictionary> vmsOnHosts = new Dictionary>(); + + public CPUIncompatibilityProblem(Check check, Pool pool) + : base(check, pool) + { + foreach (var vm in pool.Connection.Cache.VMs.Where(vm => vm.is_a_real_vm && vm.power_state != vm_power_state.Halted)) + { + vmsOnHosts.Add(vm, vm.resident_on); + } + } + + protected override AsyncAction CreateAction(out bool cancelled) + { + cancelled = false; + var actions = new List(); + foreach (var vm in vmsOnHosts.Keys) + { + if (vm.power_state == vm_power_state.Halted) + continue; + if (vm.allowed_operations.Contains(vm_operations.clean_shutdown)) + actions.Add(new VMCleanShutdown(vm)); + else + actions.Add(new VMHardShutdown(vm)); + } + if (actions.Count > 0) + return new MultipleAction(Pool.Connection, Messages.ACTION_VMS_SHUTTING_DOWN_TITLE, + Messages.ACTION_VMS_SHUTTING_DOWN_TITLE, Messages.ACTION_SHUT_DOWN, actions, true, false, true); + return null; + } + + public override AsyncAction UnwindChanges() + { + + var actions = new List(); + foreach (var vmOnHost in vmsOnHosts) + { + var vm = vmOnHost.Key; + + // check if the vm is still in the cache and is halted + if (vm.Connection.Resolve(new XenRef(vm.opaque_ref)) == null || vm.power_state != vm_power_state.Halted) + continue; + + var startOn = vm.Connection.Resolve(vmOnHost.Value); + + if (startOn != null) + actions.Add(new VMStartOnAction(vm, startOn, VMOperationCommand.WarningDialogHAInvalidConfig, VMOperationCommand.StartDiagnosisForm)); + else + actions.Add(new VMStartAction(vm, VMOperationCommand.WarningDialogHAInvalidConfig, VMOperationCommand.StartDiagnosisForm)); + } + + if (actions.Count > 0) + return new MultipleAction(Pool.Connection, Messages.ACTION_VMS_STARTING_ON_TITLE, + Messages.ACTION_VMS_STARTING_ON_TITLE, Messages.ACTION_VM_STARTED, actions, true, false, true); + return null; + } + + public override string Description + { + get + { + return String.Format(Messages.UPGRADEWIZARD_PROBLEM_INCOMPATIBLE_CPUS, Pool); + } + } + + public override string HelpMessage + { + get + { + return Messages.UPGRADEWIZARD_PROBLEM_INCOMPATIBLE_CPUS_HELPMESSAGE; + } + } + } + + class CPUCIncompatibilityWarning : Warning + { + private readonly Pool pool; + private readonly Host host; + + public CPUCIncompatibilityWarning(Check check, Pool pool, Host host) + : base(check) + { + this.pool = pool; + this.host = host; + } + + public override string Title + { + get { return Check.Description; } + } + + public override string Description + { + get + { + return string.Format(Messages.UPGRADEWIZARD_WARNING_INCOMPATIBLE_CPUS, host, pool); + } + } + } +} diff --git a/XenAdmin/XenAdmin.csproj b/XenAdmin/XenAdmin.csproj index e902947d6..b513d4dfa 100644 --- a/XenAdmin/XenAdmin.csproj +++ b/XenAdmin/XenAdmin.csproj @@ -212,6 +212,7 @@ + diff --git a/XenModel/Messages.Designer.cs b/XenModel/Messages.Designer.cs index f1ca6ab88..779313feb 100755 --- a/XenModel/Messages.Designer.cs +++ b/XenModel/Messages.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34209 +// Runtime Version:4.0.30319.18444 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -3147,6 +3147,15 @@ namespace XenAdmin { } } + /// + /// Looks up a localized string similar to Shutting Down VMs. + /// + public static string ACTION_VMS_SHUTTING_DOWN_TITLE { + get { + return ResourceManager.GetString("ACTION_VMS_SHUTTING_DOWN_TITLE", resourceCulture); + } + } + /// /// Looks up a localized string similar to Starting VMs. /// @@ -32985,6 +32994,24 @@ namespace XenAdmin { } } + /// + /// Looks up a localized string similar to Hosts in pool '{0}' have incompatible CPUs. + /// + public static string UPGRADEWIZARD_PROBLEM_INCOMPATIBLE_CPUS { + get { + return ResourceManager.GetString("UPGRADEWIZARD_PROBLEM_INCOMPATIBLE_CPUS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shut down all VMs. + /// + public static string UPGRADEWIZARD_PROBLEM_INCOMPATIBLE_CPUS_HELPMESSAGE { + get { + return ResourceManager.GetString("UPGRADEWIZARD_PROBLEM_INCOMPATIBLE_CPUS_HELPMESSAGE", resourceCulture); + } + } + /// /// Looks up a localized string similar to VM '{0}' has invalid vCPU settings.. /// @@ -33012,6 +33039,15 @@ namespace XenAdmin { } } + /// + /// Looks up a localized string similar to {0}: Check skipped because hosts in pool '{1}' have incompatible CPUs. + /// + public static string UPGRADEWIZARD_WARNING_INCOMPATIBLE_CPUS { + get { + return ResourceManager.GetString("UPGRADEWIZARD_WARNING_INCOMPATIBLE_CPUS", resourceCulture); + } + } + /// /// Looks up a localized string similar to Upgrading. /// diff --git a/XenModel/Messages.resx b/XenModel/Messages.resx index 0cccdd847..d01835dc4 100755 --- a/XenModel/Messages.resx +++ b/XenModel/Messages.resx @@ -1011,6 +1011,9 @@ Resuming VMs + + Shutting Down VMs + Starting VMs @@ -11404,6 +11407,12 @@ Note that if RBAC is enabled, only updates which you have privileges to dismiss Problems encountered when perfoming upgrade prechecks. + + Hosts in pool '{0}' have incompatible CPUs + + + Shut down all VMs + VM '{0}' has invalid vCPU settings. @@ -11413,6 +11422,9 @@ Note that if RBAC is enabled, only updates which you have privileges to dismiss Select the servers you wish to upgrade. + + {0}: Check skipped because hosts in pool '{1}' have incompatible CPUs + Upgrade host {0}