mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2025-01-20 07:19:18 +01:00
Merge pull request #722 from MihaelaStoica/CP-14641
CP-14641: Add warnings on pool join if the pool and the joining host have different CPU features
This commit is contained in:
commit
9380134c9e
@ -126,7 +126,7 @@ namespace XenAdmin.Commands
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get permission for any fix-ups: 1) Licensing free hosts; 2) CPU masking 3) Ad configuration
|
// Get permission for any fix-ups: 1) Licensing free hosts; 2) CPU masking 3) Ad configuration 4) CPU feature levelling (Dundee or higher only)
|
||||||
// (We already know that these things are fixable because we have been through CanJoinPool() above).
|
// (We already know that these things are fixable because we have been through CanJoinPool() above).
|
||||||
if (!HelpersGUI.GetPermissionFor(_hosts, host => PoolJoinRules.FreeHostPaidMaster(host, master, false),
|
if (!HelpersGUI.GetPermissionFor(_hosts, host => PoolJoinRules.FreeHostPaidMaster(host, master, false),
|
||||||
Messages.ADD_HOST_TO_POOL_LICENSE_MESSAGE, Messages.ADD_HOST_TO_POOL_LICENSE_MESSAGE_MULTIPLE, true, "PoolJoinRelicensing")
|
Messages.ADD_HOST_TO_POOL_LICENSE_MESSAGE, Messages.ADD_HOST_TO_POOL_LICENSE_MESSAGE_MULTIPLE, true, "PoolJoinRelicensing")
|
||||||
@ -136,8 +136,8 @@ namespace XenAdmin.Commands
|
|||||||
||
|
||
|
||||||
!HelpersGUI.GetPermissionFor(_hosts, host => !PoolJoinRules.CompatibleAdConfig(host, master, false),
|
!HelpersGUI.GetPermissionFor(_hosts, host => !PoolJoinRules.CompatibleAdConfig(host, master, false),
|
||||||
Messages.ADD_HOST_TO_POOL_AD_MESSAGE, Messages.ADD_HOST_TO_POOL_AD_MESSAGE_MULTIPLE, true, "PoolJoinAdConfiguring")
|
Messages.ADD_HOST_TO_POOL_AD_MESSAGE, Messages.ADD_HOST_TO_POOL_AD_MESSAGE_MULTIPLE, true, "PoolJoinAdConfiguring")
|
||||||
)
|
||
|
||||||
|
!HelpersGUI.GetPermissionForCpuFeatureLevelling(_hosts, _pool))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,12 @@ namespace XenAdmin.Commands
|
|||||||
return Messages.MIGRATION_NOT_ALLOWED_NO_SHARED_STORAGE;
|
return Messages.MIGRATION_NOT_ALLOWED_NO_SHARED_STORAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (targetHost != draggedVMHome && VMOperationHostCommand.VmCpuFeaturesIncompatibleWithHost(targetHost, draggedVM))
|
||||||
|
{
|
||||||
|
// target host does not offer some of the CPU features that the VM currently sees
|
||||||
|
return Messages.MIGRATION_NOT_ALLOWED_CPU_FEATURES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,6 +131,12 @@ namespace XenAdmin.Commands
|
|||||||
|
|
||||||
if (draggedVM.allowed_operations == null || !draggedVM.allowed_operations.Contains(vm_operations.migrate_send))
|
if (draggedVM.allowed_operations == null || !draggedVM.allowed_operations.Contains(vm_operations.migrate_send))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (VMOperationHostCommand.VmCpuFeaturesIncompatibleWithHost(targetHost, draggedVM))
|
||||||
|
{
|
||||||
|
// target host does not offer some of the CPU features that the VM currently sees
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -95,6 +95,12 @@ namespace XenAdmin.Commands
|
|||||||
return Messages.MIGRATION_NOT_ALLOWED_NO_SHARED_STORAGE;
|
return Messages.MIGRATION_NOT_ALLOWED_NO_SHARED_STORAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (targetHost != draggedVMHome && VMOperationHostCommand.VmCpuFeaturesIncompatibleWithHost(targetHost, draggedVM))
|
||||||
|
{
|
||||||
|
// target host does not offer some of the CPU features that the VM currently sees
|
||||||
|
return Messages.MIGRATION_NOT_ALLOWED_CPU_FEATURES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,6 +180,12 @@ namespace XenAdmin.Commands
|
|||||||
// dragged VM must currently be shown below a host
|
// dragged VM must currently be shown below a host
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (VMOperationHostCommand.VmCpuFeaturesIncompatibleWithHost(targetHost, draggedVM))
|
||||||
|
{
|
||||||
|
// target host does not offer some of the CPU features that the VM currently sees
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -66,7 +66,7 @@ namespace XenAdmin.Commands
|
|||||||
{
|
{
|
||||||
VM vm = (VM)item.XenObject;
|
VM vm = (VM)item.XenObject;
|
||||||
|
|
||||||
string reason = GetVmCannotBootOnHostReason(vm, GetHost(vm), session);
|
string reason = GetVmCannotBootOnHostReason(vm, GetHost(vm), session, operation);
|
||||||
_cantBootReasons[vm] = reason;
|
_cantBootReasons[vm] = reason;
|
||||||
|
|
||||||
if (reason == null)
|
if (reason == null)
|
||||||
@ -117,7 +117,7 @@ namespace XenAdmin.Commands
|
|||||||
return vm != null && _cantBootReasons.ContainsKey(vm) && _cantBootReasons[vm] == null;
|
return vm != null && _cantBootReasons.ContainsKey(vm) && _cantBootReasons[vm] == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetVmCannotBootOnHostReason(VM vm, Host host, Session session)
|
private static string GetVmCannotBootOnHostReason(VM vm, Host host, Session session, vm_operations operation)
|
||||||
{
|
{
|
||||||
Host residentHost = vm.Connection.Resolve(vm.resident_on);
|
Host residentHost = vm.Connection.Resolve(vm.resident_on);
|
||||||
|
|
||||||
@ -134,6 +134,11 @@ namespace XenAdmin.Commands
|
|||||||
if (vm.power_state == vm_power_state.Running && residentHost != null && host.opaque_ref == residentHost.opaque_ref)
|
if (vm.power_state == vm_power_state.Running && residentHost != null && host.opaque_ref == residentHost.opaque_ref)
|
||||||
return Messages.HOST_MENU_CURRENT_SERVER;
|
return Messages.HOST_MENU_CURRENT_SERVER;
|
||||||
|
|
||||||
|
if ((operation == vm_operations.pool_migrate || operation == vm_operations.resume_on) && VmCpuFeaturesIncompatibleWithHost(host, vm))
|
||||||
|
{
|
||||||
|
return FriendlyErrorNames.VM_INCOMPATIBLE_WITH_THIS_HOST;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
VM.assert_can_boot_here(session, vm.opaque_ref, host.opaque_ref);
|
VM.assert_can_boot_here(session, vm.opaque_ref, host.opaque_ref);
|
||||||
@ -177,5 +182,31 @@ namespace XenAdmin.Commands
|
|||||||
|
|
||||||
return base.GetCantExecuteReasonCore(item);
|
return base.GetCantExecuteReasonCore(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool VmCpuFeaturesIncompatibleWithHost(Host targetHost, VM vm)
|
||||||
|
{
|
||||||
|
// check the CPU feature compatibility for Dundee and higher hosts
|
||||||
|
if (!Helpers.DundeeOrGreater(targetHost))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// only for running or suspended VMs
|
||||||
|
if (vm.power_state != vm_power_state.Running && vm.power_state != vm_power_state.Suspended)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (vm.last_boot_CPU_flags == null || !vm.last_boot_CPU_flags.ContainsKey("vendor") || !vm.last_boot_CPU_flags.ContainsKey("features")
|
||||||
|
|| targetHost.cpu_info == null || !targetHost.cpu_info.ContainsKey("vendor"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (vm.last_boot_CPU_flags["vendor"] != targetHost.cpu_info["vendor"])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (vm.IsHVM && targetHost.cpu_info.ContainsKey("features_hvm"))
|
||||||
|
return PoolJoinRules.FewerFeatures(targetHost.cpu_info["features_hvm"], vm.last_boot_CPU_flags["features"]);
|
||||||
|
|
||||||
|
if (!vm.IsHVM && targetHost.cpu_info.ContainsKey("features_pv"))
|
||||||
|
return PoolJoinRules.FewerFeatures(targetHost.cpu_info["features_pv"], vm.last_boot_CPU_flags["features"]);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ using XenAdmin.Dialogs;
|
|||||||
using XenAdmin.Network;
|
using XenAdmin.Network;
|
||||||
using XenAdmin.XenSearch;
|
using XenAdmin.XenSearch;
|
||||||
using XenAPI;
|
using XenAPI;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace XenAdmin.Core
|
namespace XenAdmin.Core
|
||||||
{
|
{
|
||||||
@ -95,8 +96,9 @@ namespace XenAdmin.Core
|
|||||||
/// <param name="msg_multiple">Dialog message when more than one item needs action. {0} will be substituted for a list of the items.</param>
|
/// <param name="msg_multiple">Dialog message when more than one item needs action. {0} will be substituted for a list of the items.</param>
|
||||||
/// <param name="defaultYes">Whether the default button should be Proceed (as opposed to Cancel)</param>
|
/// <param name="defaultYes">Whether the default button should be Proceed (as opposed to Cancel)</param>
|
||||||
/// <param name="helpName">Help ID for the dialog</param>
|
/// <param name="helpName">Help ID for the dialog</param>
|
||||||
|
/// <param name="icon">Severity icon for the dialog</param>
|
||||||
/// <returns>Whether permission was obtained (also true if no items needed action)</returns>
|
/// <returns>Whether permission was obtained (also true if no items needed action)</returns>
|
||||||
public static bool GetPermissionFor<T>(List<T> items, Predicate<T> pred, string msg_single, string msg_multiple, bool defaultYes, string helpName)
|
public static bool GetPermissionFor<T>(List<T> items, Predicate<T> pred, string msg_single, string msg_multiple, bool defaultYes, string helpName, Icon icon = null)
|
||||||
{
|
{
|
||||||
if (Program.RunInAutomatedTestMode)
|
if (Program.RunInAutomatedTestMode)
|
||||||
return true;
|
return true;
|
||||||
@ -111,7 +113,7 @@ namespace XenAdmin.Core
|
|||||||
msg = string.Format(msg_multiple, string.Join("\n", itemsToFixup.ConvertAll(item => item.ToString()).ToArray()));
|
msg = string.Format(msg_multiple, string.Join("\n", itemsToFixup.ConvertAll(item => item.ToString()).ToArray()));
|
||||||
|
|
||||||
ThreeButtonDialog dlg = new ThreeButtonDialog(
|
ThreeButtonDialog dlg = new ThreeButtonDialog(
|
||||||
new ThreeButtonDialog.Details(SystemIcons.Exclamation, msg),
|
new ThreeButtonDialog.Details(icon ?? SystemIcons.Exclamation, msg),
|
||||||
helpName,
|
helpName,
|
||||||
new ThreeButtonDialog.TBDButton(Messages.PROCEED, DialogResult.Yes),
|
new ThreeButtonDialog.TBDButton(Messages.PROCEED, DialogResult.Yes),
|
||||||
new ThreeButtonDialog.TBDButton(Messages.CANCEL, DialogResult.No));
|
new ThreeButtonDialog.TBDButton(Messages.CANCEL, DialogResult.No));
|
||||||
@ -570,5 +572,27 @@ namespace XenAdmin.Core
|
|||||||
Messages.DATEFORMAT_DMY_HMS, true)
|
Messages.DATEFORMAT_DMY_HMS, true)
|
||||||
: search.Name;
|
: search.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool GetPermissionForCpuFeatureLevelling(List<Host> hosts, Pool pool)
|
||||||
|
{
|
||||||
|
if (hosts == null || pool == null || !Helpers.DundeeOrGreater(pool.Connection))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
List<Host> hostsWithFewerFeatures = hosts.Where(host => PoolJoinRules.HostHasFewerFeatures(host, pool)).ToList();
|
||||||
|
List<Host> hostsWithMoreFeatures = hosts.Where(host => PoolJoinRules.HostHasMoreFeatures(host, pool)).ToList();
|
||||||
|
|
||||||
|
if (hostsWithFewerFeatures.Count > 0 && hostsWithMoreFeatures.Count > 0)
|
||||||
|
{
|
||||||
|
return GetPermissionFor(hostsWithFewerFeatures.Union(hostsWithMoreFeatures).ToList(), host => true,
|
||||||
|
Messages.ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_AND_HOST_MESSAGE, Messages.ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_AND_HOST_MESSAGE_MULTIPLE, true, "PoolJoinCpuMasking");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostsWithFewerFeatures.Count > 0)
|
||||||
|
return GetPermissionFor(hostsWithFewerFeatures, host => true,
|
||||||
|
Messages.ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_MESSAGE, Messages.ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_MESSAGE_MULTIPLE, true, "PoolJoinCpuMasking");
|
||||||
|
|
||||||
|
return GetPermissionFor(hostsWithMoreFeatures, host => true,
|
||||||
|
Messages.ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_HOST_MESSAGE, Messages.ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_HOST_MESSAGE_MULTIPLE, true, "PoolJoinCpuMasking", SystemIcons.Information);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,9 @@ namespace XenAdmin.Dialogs
|
|||||||
Messages.NEW_POOL_CPU_MASKING_MESSAGE, Messages.NEW_POOL_CPU_MASKING_MESSAGE_MULTIPLE, true, "PoolJoinCpuMasking")
|
Messages.NEW_POOL_CPU_MASKING_MESSAGE, Messages.NEW_POOL_CPU_MASKING_MESSAGE_MULTIPLE, true, "PoolJoinCpuMasking")
|
||||||
||
|
||
|
||||||
!HelpersGUI.GetPermissionFor(slaves, host => !PoolJoinRules.CompatibleAdConfig(host, master, false),
|
!HelpersGUI.GetPermissionFor(slaves, host => !PoolJoinRules.CompatibleAdConfig(host, master, false),
|
||||||
Messages.NEW_POOL_AD_MESSAGE, Messages.NEW_POOL_AD_MESSAGE_MULTIPLE, true, "PoolJoinAdConfiguring"))
|
Messages.NEW_POOL_AD_MESSAGE, Messages.NEW_POOL_AD_MESSAGE_MULTIPLE, true, "PoolJoinAdConfiguring")
|
||||||
|
||
|
||||||
|
!HelpersGUI.GetPermissionForCpuFeatureLevelling(slaves, Helpers.GetPoolOfOne(master.Connection)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
127
XenAdminTests/UnitTests/CPUFeaturesTest.cs
Normal file
127
XenAdminTests/UnitTests/CPUFeaturesTest.cs
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/* 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 System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using XenAdmin.Core;
|
||||||
|
|
||||||
|
namespace XenAdminTests.UnitTests
|
||||||
|
{
|
||||||
|
[TestFixture, Category(TestCategories.Unit)]
|
||||||
|
public class CPUFeaturesTest
|
||||||
|
{
|
||||||
|
const string cpu1 = "000ce3bd-bfebfbff-00000001-20100800";
|
||||||
|
const string cpu2 = "040ce3bd-bfebfbff-00000001-20100800";
|
||||||
|
const string cpu3 = "040ce33d-bfebfbff-00000001-20100801";
|
||||||
|
const string cpu4 = "000ce3bd-bfebfbff-00000001";
|
||||||
|
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public void SetupResults()
|
||||||
|
{
|
||||||
|
// A cpu does not have less features than itself
|
||||||
|
Expect(cpu1, cpu1, false);
|
||||||
|
Expect(cpu2, cpu2, false);
|
||||||
|
Expect(cpu3, cpu3, false);
|
||||||
|
Expect(cpu4, cpu4, false);
|
||||||
|
|
||||||
|
// cpu1 has less features than cpu2 and cpu3
|
||||||
|
Expect(cpu1, cpu2, true);
|
||||||
|
Expect(cpu1, cpu3, true);
|
||||||
|
Expect(cpu1, cpu4, false);
|
||||||
|
|
||||||
|
// cpu2 has less features than cpu3 (and some extra ones)
|
||||||
|
Expect(cpu2, cpu1, false);
|
||||||
|
Expect(cpu2, cpu3, true);
|
||||||
|
Expect(cpu2, cpu4, false);
|
||||||
|
|
||||||
|
// cpu3 is missing one feature (and has some extra ones)
|
||||||
|
Expect(cpu3, cpu1, true);
|
||||||
|
Expect(cpu3, cpu2, true);
|
||||||
|
Expect(cpu3, cpu4, true);
|
||||||
|
|
||||||
|
// cpu4 has less features than all because is missing the last set
|
||||||
|
Expect(cpu4, cpu1, true);
|
||||||
|
Expect(cpu4, cpu2, true);
|
||||||
|
Expect(cpu4, cpu3, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<Config, bool> expectedResults = new Dictionary<Config, bool>();
|
||||||
|
private class Config
|
||||||
|
{
|
||||||
|
string featureSet1, featureSet2;
|
||||||
|
public Config(string featureSet1, string featureSet2)
|
||||||
|
{
|
||||||
|
this.featureSet1 = featureSet1;
|
||||||
|
this.featureSet2 = featureSet2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
Config other = obj as Config;
|
||||||
|
if (other == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return
|
||||||
|
this.featureSet1 == other.featureSet1 &&
|
||||||
|
this.featureSet2 == other.featureSet2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return featureSet1.GetHashCode() * featureSet2.GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Expect(string featureSet1, string featureSet2, bool expected_result)
|
||||||
|
{
|
||||||
|
expectedResults[new Config(featureSet1, featureSet2)] = expected_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool Expected(string featureSet1, string featureSet2)
|
||||||
|
{
|
||||||
|
return expectedResults[new Config(featureSet1, featureSet2)];
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Run(
|
||||||
|
[Values(cpu1, cpu2, cpu3, cpu4)] string featureSet1,
|
||||||
|
[Values(cpu1, cpu2, cpu3, cpu4)] string featureSet2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
System.Console.WriteLine("Asserting {0} < {1}", featureSet1, featureSet2);
|
||||||
|
Assert.AreEqual(
|
||||||
|
Expected(featureSet1, featureSet2),
|
||||||
|
PoolJoinRules.FewerFeatures(featureSet1, featureSet2), string.Format("Assertion failed on {0} < {1}", featureSet1, featureSet2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -67,6 +67,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="HealthCheckTests\CredentialTests.cs" />
|
<Compile Include="HealthCheckTests\CredentialTests.cs" />
|
||||||
<Compile Include="HealthCheckTests\RequestUploadTaskTests.cs" />
|
<Compile Include="HealthCheckTests\RequestUploadTaskTests.cs" />
|
||||||
|
<Compile Include="UnitTests\CPUFeaturesTest.cs" />
|
||||||
<Compile Include="UnitTests\SubnetworkMaskValidatorTest.cs" />
|
<Compile Include="UnitTests\SubnetworkMaskValidatorTest.cs" />
|
||||||
<Compile Include="UnitTests\ExceptionSerializationTest.cs" />
|
<Compile Include="UnitTests\ExceptionSerializationTest.cs" />
|
||||||
<Compile Include="XenModelTests\ActionTests\ActionTest.cs" />
|
<Compile Include="XenModelTests\ActionTests\ActionTest.cs" />
|
||||||
|
93
XenModel/Messages.Designer.cs
generated
93
XenModel/Messages.Designer.cs
generated
@ -3802,6 +3802,90 @@ namespace XenAdmin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to You are attempting to add the server '{0}' to a pool that is using older CPUs.
|
||||||
|
///
|
||||||
|
///VMs running in the pool will only use the CPU features common to all the servers in the pool.
|
||||||
|
///
|
||||||
|
///Do you want to do this?.
|
||||||
|
/// </summary>
|
||||||
|
public static string ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_HOST_MESSAGE {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_HOST_MESSAGE", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to You are attempting to add the following servers to a pool that is using older CPUs.
|
||||||
|
///
|
||||||
|
///{0}
|
||||||
|
///
|
||||||
|
///VMs running in the pool will only use the CPU features common to all the servers in the pool.
|
||||||
|
///
|
||||||
|
///Do you want to do this?.
|
||||||
|
/// </summary>
|
||||||
|
public static string ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_HOST_MESSAGE_MULTIPLE {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_HOST_MESSAGE_MULTIPLE", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to You are attempting to add the server '{0}' to a pool that is using different CPUs.
|
||||||
|
///
|
||||||
|
///VMs starting on the pool in future will only use the reduced set of CPU features common to all the servers in the pool. VMs already running in the pool will not be able to migrate to the new server until they are restarted.
|
||||||
|
///
|
||||||
|
///Do you want to do this?.
|
||||||
|
/// </summary>
|
||||||
|
public static string ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_AND_HOST_MESSAGE {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_AND_HOST_MESSAGE", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to You are attempting to add the following servers to a pool that is using different CPUs.
|
||||||
|
///
|
||||||
|
///{0}
|
||||||
|
///
|
||||||
|
///VMs starting on the pool in future will only use the reduced set of CPU features common to all the servers in the pool. VMs already running in the pool will not be able to migrate to the new servers until they are restarted.
|
||||||
|
///
|
||||||
|
///Do you want to do this?.
|
||||||
|
/// </summary>
|
||||||
|
public static string ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_AND_HOST_MESSAGE_MULTIPLE {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_AND_HOST_MESSAGE_MULTIPLE", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to You are attempting to add the server '{0}' to a pool that is using newer CPUs.
|
||||||
|
///
|
||||||
|
///VMs starting on the pool in future will only use the reduced set of CPU features common to all the servers in the pool. VMs already running in the pool will not be able to migrate to the new server until they are restarted.
|
||||||
|
///
|
||||||
|
///Do you want to do this?.
|
||||||
|
/// </summary>
|
||||||
|
public static string ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_MESSAGE {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_MESSAGE", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to You are attempting to add the following servers to a pool that is using newer CPUs.
|
||||||
|
///
|
||||||
|
///{0}
|
||||||
|
///
|
||||||
|
///VMs starting on the pool in future will only use the reduced set of CPU features common to all the servers in the pool. VMs already running in the pool will not be able to migrate to the new servers until they are restarted.
|
||||||
|
///
|
||||||
|
///Do you want to do this?.
|
||||||
|
/// </summary>
|
||||||
|
public static string ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_MESSAGE_MULTIPLE {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_MESSAGE_MULTIPLE", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to You are attempting to add the server '{0}' to a pool that is using older CPUs.
|
/// Looks up a localized string similar to You are attempting to add the server '{0}' to a pool that is using older CPUs.
|
||||||
///
|
///
|
||||||
@ -21625,6 +21709,15 @@ namespace XenAdmin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to This VM may not migrate because the destination host does not have some of the CPU features that the VM is currently using.
|
||||||
|
/// </summary>
|
||||||
|
public static string MIGRATION_NOT_ALLOWED_CPU_FEATURES {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MIGRATION_NOT_ALLOWED_CPU_FEATURES", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to This VM may not migrate because it has a dedicated GPU.
|
/// Looks up a localized string similar to This VM may not migrate because it has a dedicated GPU.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1255,6 +1255,54 @@ Do you want to enable AD authentication on your server and join it to the same d
|
|||||||
{0}
|
{0}
|
||||||
|
|
||||||
All pool members must use the same authentication method. Do you want to enable AD authentication on these servers and join them to the same domain as the pool?</value>
|
All pool members must use the same authentication method. Do you want to enable AD authentication on these servers and join them to the same domain as the pool?</value>
|
||||||
|
</data>
|
||||||
|
<data name="ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_HOST_MESSAGE" xml:space="preserve">
|
||||||
|
<value>You are attempting to add the server '{0}' to a pool that is using older CPUs.
|
||||||
|
|
||||||
|
VMs running in the pool will only use the CPU features common to all the servers in the pool.
|
||||||
|
|
||||||
|
Do you want to do this?</value>
|
||||||
|
</data>
|
||||||
|
<data name="ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_HOST_MESSAGE_MULTIPLE" xml:space="preserve">
|
||||||
|
<value>You are attempting to add the following servers to a pool that is using older CPUs.
|
||||||
|
|
||||||
|
{0}
|
||||||
|
|
||||||
|
VMs running in the pool will only use the CPU features common to all the servers in the pool.
|
||||||
|
|
||||||
|
Do you want to do this?</value>
|
||||||
|
</data>
|
||||||
|
<data name="ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_AND_HOST_MESSAGE" xml:space="preserve">
|
||||||
|
<value>You are attempting to add the server '{0}' to a pool that is using different CPUs.
|
||||||
|
|
||||||
|
VMs starting on the pool in future will only use the reduced set of CPU features common to all the servers in the pool. VMs already running in the pool will not be able to migrate to the new server until they are restarted.
|
||||||
|
|
||||||
|
Do you want to do this?</value>
|
||||||
|
</data>
|
||||||
|
<data name="ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_AND_HOST_MESSAGE_MULTIPLE" xml:space="preserve">
|
||||||
|
<value>You are attempting to add the following servers to a pool that is using different CPUs.
|
||||||
|
|
||||||
|
{0}
|
||||||
|
|
||||||
|
VMs starting on the pool in future will only use the reduced set of CPU features common to all the servers in the pool. VMs already running in the pool will not be able to migrate to the new servers until they are restarted.
|
||||||
|
|
||||||
|
Do you want to do this?</value>
|
||||||
|
</data>
|
||||||
|
<data name="ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_MESSAGE" xml:space="preserve">
|
||||||
|
<value>You are attempting to add the server '{0}' to a pool that is using newer CPUs.
|
||||||
|
|
||||||
|
VMs starting on the pool in future will only use the reduced set of CPU features common to all the servers in the pool. VMs already running in the pool will not be able to migrate to the new server until they are restarted.
|
||||||
|
|
||||||
|
Do you want to do this?</value>
|
||||||
|
</data>
|
||||||
|
<data name="ADD_HOST_TO_POOL_CPU_DOWN_LEVEL_POOL_MESSAGE_MULTIPLE" xml:space="preserve">
|
||||||
|
<value>You are attempting to add the following servers to a pool that is using newer CPUs.
|
||||||
|
|
||||||
|
{0}
|
||||||
|
|
||||||
|
VMs starting on the pool in future will only use the reduced set of CPU features common to all the servers in the pool. VMs already running in the pool will not be able to migrate to the new servers until they are restarted.
|
||||||
|
|
||||||
|
Do you want to do this?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ADD_HOST_TO_POOL_CPU_MASKING_MESSAGE" xml:space="preserve">
|
<data name="ADD_HOST_TO_POOL_CPU_MASKING_MESSAGE" xml:space="preserve">
|
||||||
<value>You are attempting to add the server '{0}' to a pool that is using older CPUs.
|
<value>You are attempting to add the server '{0}' to a pool that is using older CPUs.
|
||||||
@ -7520,6 +7568,9 @@ To learn more about the XenServer Live VDI Migration feature or to start a XenSe
|
|||||||
<data name="MIGRATION_NOT_ALLOWED" xml:space="preserve">
|
<data name="MIGRATION_NOT_ALLOWED" xml:space="preserve">
|
||||||
<value>This VM may not migrate at the moment</value>
|
<value>This VM may not migrate at the moment</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MIGRATION_NOT_ALLOWED_CPU_FEATURES" xml:space="preserve">
|
||||||
|
<value>This VM may not migrate because the destination host does not have some of the CPU features that the VM is currently using</value>
|
||||||
|
</data>
|
||||||
<data name="MIGRATION_NOT_ALLOWED_GPU" xml:space="preserve">
|
<data name="MIGRATION_NOT_ALLOWED_GPU" xml:space="preserve">
|
||||||
<value>This VM may not migrate because it has a dedicated GPU</value>
|
<value>This VM may not migrate because it has a dedicated GPU</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -533,5 +533,85 @@ namespace XenAdmin.Core
|
|||||||
|
|
||||||
return badPacks;
|
return badPacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the host that joins the pool has a more extensive feature set than the pool (as long as the CPU vendor is common)
|
||||||
|
/// In this case the host will transparently be down-levelled to the pool level (without needing reboots)
|
||||||
|
/// </summary>
|
||||||
|
public static bool HostHasMoreFeatures(Host slave, Pool pool)
|
||||||
|
{
|
||||||
|
if (slave == null || pool == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Dictionary<string, string> slave_cpu_info = slave.cpu_info;
|
||||||
|
Dictionary<string, string> pool_cpu_info = pool.cpu_info;
|
||||||
|
if (!Helper.AreEqual2(slave_cpu_info, null) && !Helper.AreEqual2(pool_cpu_info, null))
|
||||||
|
{
|
||||||
|
// if pool has less features than slave, then slave will be down-levelled
|
||||||
|
return FewerFeatures(pool_cpu_info, slave_cpu_info);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the host that joins the pool has a less extensive feature set than the pool (as long as the CPU vendor is common)
|
||||||
|
/// In this case the pool is transparently down-levelled to the new host's level (without needing reboots)
|
||||||
|
/// </summary>
|
||||||
|
public static bool HostHasFewerFeatures(Host slave, Pool pool)
|
||||||
|
{
|
||||||
|
if (slave == null || pool == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Dictionary<string, string> slave_cpu_info = slave.cpu_info;
|
||||||
|
Dictionary<string, string> pool_cpu_info = pool.cpu_info;
|
||||||
|
if (!Helper.AreEqual2(slave_cpu_info, null) && !Helper.AreEqual2(pool_cpu_info, null))
|
||||||
|
{
|
||||||
|
// if slave has less features than pool, then pool will be down-levelled
|
||||||
|
return FewerFeatures(slave_cpu_info, pool_cpu_info);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether first CPU has fewer features than the second.
|
||||||
|
/// It returns true if the first feature set is less than the second one in at least one bit
|
||||||
|
/// </summary>
|
||||||
|
public static bool FewerFeatures(Dictionary<string, string> cpu_infoA, Dictionary<string, string> cpu_infoB)
|
||||||
|
{
|
||||||
|
if (cpu_infoA.ContainsKey("features_hvm") && cpu_infoB.ContainsKey("features_hvm") &&
|
||||||
|
FewerFeatures(cpu_infoA["features_hvm"], cpu_infoB["features_hvm"]))
|
||||||
|
return true;
|
||||||
|
if (cpu_infoA.ContainsKey("features_pv") && cpu_infoB.ContainsKey("features_pv") &&
|
||||||
|
FewerFeatures(cpu_infoA["features_pv"], cpu_infoB["features_pv"]))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FewerFeatures(string featureSetA, string featureSetB)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(featureSetA) || string.IsNullOrEmpty(featureSetB))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string stringA = featureSetA.Replace(" ", "");
|
||||||
|
stringA = stringA.Replace("-", "");
|
||||||
|
string stringB = featureSetB.Replace(" ", "");
|
||||||
|
stringB = stringB.Replace("-", "");
|
||||||
|
|
||||||
|
if (stringA.Length < stringB.Length)
|
||||||
|
stringA = stringA.PadRight(stringB.Length, '0');
|
||||||
|
if (stringB.Length < stringA.Length)
|
||||||
|
stringB = stringB.PadRight(stringA.Length, '0');
|
||||||
|
|
||||||
|
for (int i = 0; i < stringA.Length / 8; ++i)
|
||||||
|
{
|
||||||
|
uint intA = Convert.ToUInt32(stringA.Substring(8 * i, 8), 16);
|
||||||
|
uint intB = Convert.ToUInt32(stringB.Substring(8 * i, 8), 16);
|
||||||
|
|
||||||
|
if ((intA & intB) != intB)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
XenModel/XenAPI/FriendlyErrorNames.Designer.cs
generated
2
XenModel/XenAPI/FriendlyErrorNames.Designer.cs
generated
@ -4917,7 +4917,7 @@ namespace XenAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to The VM is incompatible with the CPU features of this host..
|
/// Looks up a localized string similar to The host does not have some of the CPU features that the VM is currently using.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string VM_INCOMPATIBLE_WITH_THIS_HOST {
|
public static string VM_INCOMPATIBLE_WITH_THIS_HOST {
|
||||||
get {
|
get {
|
||||||
|
@ -1749,7 +1749,7 @@ Authorized Roles: {1}</value>
|
|||||||
<value>HVM not supported</value>
|
<value>HVM not supported</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="VM_INCOMPATIBLE_WITH_THIS_HOST" xml:space="preserve">
|
<data name="VM_INCOMPATIBLE_WITH_THIS_HOST" xml:space="preserve">
|
||||||
<value>The VM is incompatible with the CPU features of this host.</value>
|
<value>The host does not have some of the CPU features that the VM is currently using</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="VM_IS_PART_OF_AN_APPLIANCE" xml:space="preserve">
|
<data name="VM_IS_PART_OF_AN_APPLIANCE" xml:space="preserve">
|
||||||
<value>The VM cannot be recovered on its own as it is part of a VM appliance.</value>
|
<value>The VM cannot be recovered on its own as it is part of a VM appliance.</value>
|
||||||
|
@ -78,7 +78,8 @@ namespace XenAPI
|
|||||||
List<XenRef<VDI>> metadata_VDIs,
|
List<XenRef<VDI>> metadata_VDIs,
|
||||||
string ha_cluster_stack,
|
string ha_cluster_stack,
|
||||||
List<pool_allowed_operations> allowed_operations,
|
List<pool_allowed_operations> allowed_operations,
|
||||||
Dictionary<string, pool_allowed_operations> current_operations)
|
Dictionary<string, pool_allowed_operations> current_operations,
|
||||||
|
Dictionary<string, string> cpu_info)
|
||||||
{
|
{
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.name_label = name_label;
|
this.name_label = name_label;
|
||||||
@ -111,6 +112,7 @@ namespace XenAPI
|
|||||||
this.ha_cluster_stack = ha_cluster_stack;
|
this.ha_cluster_stack = ha_cluster_stack;
|
||||||
this.allowed_operations = allowed_operations;
|
this.allowed_operations = allowed_operations;
|
||||||
this.current_operations = current_operations;
|
this.current_operations = current_operations;
|
||||||
|
this.cpu_info = cpu_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -155,6 +157,7 @@ namespace XenAPI
|
|||||||
ha_cluster_stack = update.ha_cluster_stack;
|
ha_cluster_stack = update.ha_cluster_stack;
|
||||||
allowed_operations = update.allowed_operations;
|
allowed_operations = update.allowed_operations;
|
||||||
current_operations = update.current_operations;
|
current_operations = update.current_operations;
|
||||||
|
cpu_info = update.cpu_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UpdateFromProxy(Proxy_Pool proxy)
|
internal void UpdateFromProxy(Proxy_Pool proxy)
|
||||||
@ -190,6 +193,7 @@ namespace XenAPI
|
|||||||
ha_cluster_stack = proxy.ha_cluster_stack == null ? null : (string)proxy.ha_cluster_stack;
|
ha_cluster_stack = proxy.ha_cluster_stack == null ? null : (string)proxy.ha_cluster_stack;
|
||||||
allowed_operations = proxy.allowed_operations == null ? null : Helper.StringArrayToEnumList<pool_allowed_operations>(proxy.allowed_operations);
|
allowed_operations = proxy.allowed_operations == null ? null : Helper.StringArrayToEnumList<pool_allowed_operations>(proxy.allowed_operations);
|
||||||
current_operations = proxy.current_operations == null ? null : Maps.convert_from_proxy_string_pool_allowed_operations(proxy.current_operations);
|
current_operations = proxy.current_operations == null ? null : Maps.convert_from_proxy_string_pool_allowed_operations(proxy.current_operations);
|
||||||
|
cpu_info = proxy.cpu_info == null ? null : Maps.convert_from_proxy_string_string(proxy.cpu_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Proxy_Pool ToProxy()
|
public Proxy_Pool ToProxy()
|
||||||
@ -226,6 +230,7 @@ namespace XenAPI
|
|||||||
result_.ha_cluster_stack = (ha_cluster_stack != null) ? ha_cluster_stack : "";
|
result_.ha_cluster_stack = (ha_cluster_stack != null) ? ha_cluster_stack : "";
|
||||||
result_.allowed_operations = (allowed_operations != null) ? Helper.ObjectListToStringArray(allowed_operations) : new string[] {};
|
result_.allowed_operations = (allowed_operations != null) ? Helper.ObjectListToStringArray(allowed_operations) : new string[] {};
|
||||||
result_.current_operations = Maps.convert_to_proxy_string_pool_allowed_operations(current_operations);
|
result_.current_operations = Maps.convert_to_proxy_string_pool_allowed_operations(current_operations);
|
||||||
|
result_.cpu_info = Maps.convert_to_proxy_string_string(cpu_info);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +271,7 @@ namespace XenAPI
|
|||||||
ha_cluster_stack = Marshalling.ParseString(table, "ha_cluster_stack");
|
ha_cluster_stack = Marshalling.ParseString(table, "ha_cluster_stack");
|
||||||
allowed_operations = Helper.StringArrayToEnumList<pool_allowed_operations>(Marshalling.ParseStringArray(table, "allowed_operations"));
|
allowed_operations = Helper.StringArrayToEnumList<pool_allowed_operations>(Marshalling.ParseStringArray(table, "allowed_operations"));
|
||||||
current_operations = Maps.convert_from_proxy_string_pool_allowed_operations(Marshalling.ParseHashTable(table, "current_operations"));
|
current_operations = Maps.convert_from_proxy_string_pool_allowed_operations(Marshalling.ParseHashTable(table, "current_operations"));
|
||||||
|
cpu_info = Maps.convert_from_proxy_string_string(Marshalling.ParseHashTable(table, "cpu_info"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeepEquals(Pool other, bool ignoreCurrentOperations)
|
public bool DeepEquals(Pool other, bool ignoreCurrentOperations)
|
||||||
@ -307,7 +313,8 @@ namespace XenAPI
|
|||||||
Helper.AreEqual2(this._restrictions, other._restrictions) &&
|
Helper.AreEqual2(this._restrictions, other._restrictions) &&
|
||||||
Helper.AreEqual2(this._metadata_VDIs, other._metadata_VDIs) &&
|
Helper.AreEqual2(this._metadata_VDIs, other._metadata_VDIs) &&
|
||||||
Helper.AreEqual2(this._ha_cluster_stack, other._ha_cluster_stack) &&
|
Helper.AreEqual2(this._ha_cluster_stack, other._ha_cluster_stack) &&
|
||||||
Helper.AreEqual2(this._allowed_operations, other._allowed_operations);
|
Helper.AreEqual2(this._allowed_operations, other._allowed_operations) &&
|
||||||
|
Helper.AreEqual2(this._cpu_info, other._cpu_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string SaveChanges(Session session, string opaqueRef, Pool server)
|
public override string SaveChanges(Session session, string opaqueRef, Pool server)
|
||||||
@ -734,6 +741,17 @@ namespace XenAPI
|
|||||||
return Maps.convert_from_proxy_string_pool_allowed_operations(session.proxy.pool_get_current_operations(session.uuid, (_pool != null) ? _pool : "").parse());
|
return Maps.convert_from_proxy_string_pool_allowed_operations(session.proxy.pool_get_current_operations(session.uuid, (_pool != null) ? _pool : "").parse());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the cpu_info field of the given pool.
|
||||||
|
/// First published in XenServer Dundee.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">The session</param>
|
||||||
|
/// <param name="_pool">The opaque_ref of the given pool</param>
|
||||||
|
public static Dictionary<string, string> get_cpu_info(Session session, string _pool)
|
||||||
|
{
|
||||||
|
return Maps.convert_from_proxy_string_string(session.proxy.pool_get_cpu_info(session.uuid, (_pool != null) ? _pool : "").parse());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the name_label field of the given pool.
|
/// Set the name_label field of the given pool.
|
||||||
/// First published in XenServer 4.0.
|
/// First published in XenServer 4.0.
|
||||||
@ -2524,5 +2542,24 @@ namespace XenAPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private Dictionary<string, pool_allowed_operations> _current_operations;
|
private Dictionary<string, pool_allowed_operations> _current_operations;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Details about the physical CPUs on the pool
|
||||||
|
/// First published in XenServer Dundee.
|
||||||
|
/// </summary>
|
||||||
|
public virtual Dictionary<string, string> cpu_info
|
||||||
|
{
|
||||||
|
get { return _cpu_info; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!Helper.AreEqual(value, _cpu_info))
|
||||||
|
{
|
||||||
|
_cpu_info = value;
|
||||||
|
Changed = true;
|
||||||
|
NotifyPropertyChanged("cpu_info");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Dictionary<string, string> _cpu_info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -576,6 +576,10 @@ namespace XenAPI
|
|||||||
Response<Object>
|
Response<Object>
|
||||||
pool_get_current_operations(string session, string _pool);
|
pool_get_current_operations(string session, string _pool);
|
||||||
|
|
||||||
|
[XmlRpcMethod("pool.get_cpu_info")]
|
||||||
|
Response<Object>
|
||||||
|
pool_get_cpu_info(string session, string _pool);
|
||||||
|
|
||||||
[XmlRpcMethod("pool.set_name_label")]
|
[XmlRpcMethod("pool.set_name_label")]
|
||||||
Response<string>
|
Response<string>
|
||||||
pool_set_name_label(string session, string _pool, string _name_label);
|
pool_set_name_label(string session, string _pool, string _name_label);
|
||||||
@ -6836,6 +6840,7 @@ namespace XenAPI
|
|||||||
public string ha_cluster_stack;
|
public string ha_cluster_stack;
|
||||||
public string [] allowed_operations;
|
public string [] allowed_operations;
|
||||||
public Object current_operations;
|
public Object current_operations;
|
||||||
|
public Object cpu_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
[XmlRpcMissingMapping(MappingAction.Ignore)]
|
[XmlRpcMissingMapping(MappingAction.Ignore)]
|
||||||
|
Loading…
Reference in New Issue
Block a user