mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2025-01-20 15:29:26 +01:00
CA-309758: Optimisations to the way we assert if Vms can be migrated to a destination pool in the Cross Pool Migrate wizard
- When asserting if a VM can be migrated to a pool we don't have to check all the hosts in the pool at this point, we can enable the pool when we find the first host where migration is possible; we will check the rest of the hosts only if that pool is selected. - If the destination pool is older than the source, then we don't need to do any server calls because we know that migration to an older host is not allowed. Signed-off-by: Mihaela Stoica <mihaela.stoica@citrix.com>
This commit is contained in:
parent
0df39a9d83
commit
4abe4ddb30
@ -32,7 +32,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using XenAdmin.Commands;
|
using XenAdmin.Commands;
|
||||||
using XenAdmin.Core;
|
using XenAdmin.Core;
|
||||||
using XenAdmin.Wizards.GenericPages;
|
using XenAdmin.Wizards.GenericPages;
|
||||||
@ -69,135 +68,150 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
|
|||||||
canceled = true;
|
canceled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool FailureFound
|
public override bool FailureFoundFor(IXenObject itemToFilterOn)
|
||||||
{
|
{
|
||||||
get
|
Pool targetPool;
|
||||||
|
List<Host> targets = CollateHosts(itemToFilterOn, out targetPool);
|
||||||
|
|
||||||
|
foreach (VM vm in preSelectedVMs)
|
||||||
{
|
{
|
||||||
log.InfoFormat("Asserting can migrate to {0}...", ItemToFilterOn);
|
log.InfoFormat("Asserting can migrate VM {0} to {1}...", vm.Name(), itemToFilterOn);
|
||||||
|
bool vmIsMigratable = false;
|
||||||
Pool targetPool;
|
|
||||||
List<Host> targets = CollateHosts(out targetPool);
|
|
||||||
var excludedHosts = new List<string>();
|
|
||||||
|
|
||||||
foreach (Host host in targets)
|
foreach (Host host in targets)
|
||||||
{
|
{
|
||||||
var targetSrs = host.Connection.Cache.SRs.Where(sr => sr.SupportsStorageMigration()).ToList();
|
if (canceled)
|
||||||
var targetNetwork = GetANetwork(host);
|
return false;
|
||||||
|
|
||||||
foreach (VM vm in preSelectedVMs)
|
// obtain the cache data for a vm
|
||||||
|
IDictionary<string, string> vmCache;
|
||||||
|
lock (cacheLock)
|
||||||
{
|
{
|
||||||
if (canceled)
|
if (!cache.ContainsKey(vm.opaque_ref))
|
||||||
return excludedHosts.Count == targets.Count;
|
{
|
||||||
|
cache.Add(vm.opaque_ref, new Dictionary<string, string>());
|
||||||
|
}
|
||||||
|
vmCache = cache[vm.opaque_ref];
|
||||||
|
}
|
||||||
|
|
||||||
// obtain the cache data for a vm
|
try
|
||||||
IDictionary<string, string> vmCache;
|
{
|
||||||
|
//CA-220218: for intra-pool motion of halted VMs we do a move, so no need to assert we can migrate
|
||||||
|
Pool vmPool = Helpers.GetPoolOfOne(vm.Connection);
|
||||||
|
if (_wizardMode == WizardMode.Move && vmPool != null && targetPool != null && vmPool.opaque_ref == targetPool.opaque_ref)
|
||||||
|
{
|
||||||
|
// vm is migratable, no need to itearate through all the pool members
|
||||||
|
vmIsMigratable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Skip the resident host as there's a filter for it and
|
||||||
|
//if not then you could exclude intrapool migration
|
||||||
|
//CA-205799: do not offer the host the VM is currently on
|
||||||
|
Host homeHost = vm.Home();
|
||||||
|
if (homeHost != null && homeHost.opaque_ref == host.opaque_ref)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (vmCache.ContainsKey(host.opaque_ref))
|
||||||
|
{
|
||||||
|
disableReason = vmCache[host.opaque_ref];
|
||||||
|
if (string.IsNullOrEmpty(disableReason))
|
||||||
|
{
|
||||||
|
// vm is migratable to at least one host in the pool, no need to itearate through all the pool members
|
||||||
|
vmIsMigratable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if pool_migrate can be done, then we will allow it in the wizard, even if storage migration is not allowed (i.e. users can use the wizard to live-migrate a VM inside the pool)
|
||||||
|
if (_wizardMode == WizardMode.Migrate && vmPool != null && targetPool != null && vmPool.opaque_ref == targetPool.opaque_ref)
|
||||||
|
{
|
||||||
|
var reason = VMOperationHostCommand.GetVmCannotBootOnHostReason(vm, host, vm.Connection.Session, vm_operations.pool_migrate);
|
||||||
|
if (string.IsNullOrEmpty(reason))
|
||||||
|
{
|
||||||
|
lock (cacheLock)
|
||||||
|
{
|
||||||
|
vmCache.Add(host.opaque_ref, reason);
|
||||||
|
}
|
||||||
|
// vm is migratable to at least one host in the pool, no need to itearate through all the pool members
|
||||||
|
vmIsMigratable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if the destination host is older than the source host
|
||||||
|
var destinationVersion = Helpers.HostPlatformVersion(host);
|
||||||
|
var sourceVersion = Helpers.HostPlatformVersion(vm.Home() ?? Helpers.GetMaster(vmPool));
|
||||||
|
if (Helpers.productVersionCompare(destinationVersion, sourceVersion) < 0)
|
||||||
|
{
|
||||||
|
throw new Failure(Messages.OLDER_THAN_CURRENT_SERVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
PIF managementPif = host.Connection.Cache.PIFs.First(p => p.management);
|
||||||
|
XenAPI.Network managementNetwork = host.Connection.Cache.Resolve(managementPif.network);
|
||||||
|
|
||||||
|
Session session = host.Connection.DuplicateSession();
|
||||||
|
Dictionary<string, string> receiveMapping = Host.migrate_receive(session, host.opaque_ref, managementNetwork.opaque_ref, new Dictionary<string, string>());
|
||||||
|
|
||||||
|
var targetSrs = host.Connection.Cache.SRs.Where(sr => sr.SupportsStorageMigration()).ToList();
|
||||||
|
var targetNetwork = GetANetwork(host);
|
||||||
|
|
||||||
|
VM.assert_can_migrate(vm.Connection.Session,
|
||||||
|
vm.opaque_ref,
|
||||||
|
receiveMapping,
|
||||||
|
true,
|
||||||
|
GetVdiMap(vm, targetSrs),
|
||||||
|
vm.Connection == host.Connection ? new Dictionary<XenRef<VIF>, XenRef<XenAPI.Network>>() : GetVifMap(vm, targetNetwork),
|
||||||
|
new Dictionary<string, string>());
|
||||||
lock (cacheLock)
|
lock (cacheLock)
|
||||||
{
|
{
|
||||||
if (!cache.ContainsKey(vm.opaque_ref))
|
vmCache.Add(host.opaque_ref, string.Empty);
|
||||||
{
|
|
||||||
cache.Add(vm.opaque_ref, new Dictionary<string, string>());
|
|
||||||
}
|
|
||||||
vmCache = cache[vm.opaque_ref];
|
|
||||||
}
|
}
|
||||||
|
// vm is migratable to at least one host in the pool, no need to itearate through all the pool members
|
||||||
|
vmIsMigratable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Failure failure)
|
||||||
|
{
|
||||||
|
if (failure.ErrorDescription.Count > 0 && failure.ErrorDescription[0] == Failure.RBAC_PERMISSION_DENIED)
|
||||||
|
disableReason = failure.Message.Split('\n')[0].TrimEnd('\r'); // we want the first line only
|
||||||
|
else
|
||||||
|
disableReason = failure.Message;
|
||||||
|
|
||||||
try
|
lock (cacheLock)
|
||||||
{
|
{
|
||||||
//CA-220218: for intra-pool motion of halted VMs we do a move, so no need to assert we can migrate
|
vmCache.Add(host.opaque_ref, disableReason.Clone().ToString());
|
||||||
Pool vmPool = Helpers.GetPoolOfOne(vm.Connection);
|
|
||||||
if (_wizardMode == WizardMode.Move && vmPool != null && targetPool != null && vmPool.opaque_ref == targetPool.opaque_ref)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//Skip the resident host as there's a filter for it and
|
|
||||||
//if not then you could exclude intrapool migration
|
|
||||||
//CA-205799: do not offer the host the VM is currently on
|
|
||||||
Host homeHost = vm.Home();
|
|
||||||
if (homeHost != null && homeHost.opaque_ref == host.opaque_ref)
|
|
||||||
{
|
|
||||||
if (!excludedHosts.Contains(host.opaque_ref))
|
|
||||||
excludedHosts.Add(host.opaque_ref);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vmCache.ContainsKey(host.opaque_ref))
|
|
||||||
{
|
|
||||||
disableReason = vmCache[host.opaque_ref];
|
|
||||||
if (!string.IsNullOrEmpty(disableReason) && !excludedHosts.Contains(host.opaque_ref))
|
|
||||||
{
|
|
||||||
excludedHosts.Add(host.opaque_ref);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if pool_migrate can be done, then we will allow it in the wizard, even if storage migration is not allowed (i.e. users can use the wizard to live-migrate a VM inside the pool)
|
|
||||||
if (_wizardMode == WizardMode.Migrate && vmPool != null && targetPool != null && vmPool.opaque_ref == targetPool.opaque_ref)
|
|
||||||
{
|
|
||||||
var reason = VMOperationHostCommand.GetVmCannotBootOnHostReason(vm, host, vm.Connection.Session, vm_operations.pool_migrate);
|
|
||||||
if (string.IsNullOrEmpty(reason))
|
|
||||||
{
|
|
||||||
lock (cacheLock)
|
|
||||||
{
|
|
||||||
vmCache.Add(host.opaque_ref, reason);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PIF managementPif = host.Connection.Cache.PIFs.First(p => p.management);
|
|
||||||
XenAPI.Network network = host.Connection.Cache.Resolve(managementPif.network);
|
|
||||||
|
|
||||||
Session session = host.Connection.DuplicateSession();
|
|
||||||
Dictionary<string, string> receiveMapping = Host.migrate_receive(session, host.opaque_ref, network.opaque_ref, new Dictionary<string, string>());
|
|
||||||
VM.assert_can_migrate(vm.Connection.Session,
|
|
||||||
vm.opaque_ref,
|
|
||||||
receiveMapping,
|
|
||||||
true,
|
|
||||||
GetVdiMap(vm, targetSrs),
|
|
||||||
vm.Connection == host.Connection ? new Dictionary<XenRef<VIF>, XenRef<XenAPI.Network>>() : GetVifMap(vm, targetNetwork),
|
|
||||||
new Dictionary<string, string>());
|
|
||||||
lock (cacheLock)
|
|
||||||
{
|
|
||||||
vmCache.Add(host.opaque_ref, string.Empty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Failure failure)
|
|
||||||
{
|
|
||||||
if (failure.ErrorDescription.Count > 0 && failure.ErrorDescription[0] == Failure.RBAC_PERMISSION_DENIED)
|
|
||||||
disableReason = failure.Message.Split('\n')[0].TrimEnd('\r'); // we want the first line only
|
|
||||||
else
|
|
||||||
disableReason = failure.Message;
|
|
||||||
|
|
||||||
lock (cacheLock)
|
log.ErrorFormat("VM: {0}, Host: {1} - Reason: {2};", vm.Name(), host.Name(), failure.Message);
|
||||||
{
|
|
||||||
vmCache.Add(host.opaque_ref, disableReason.Clone().ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
log.ErrorFormat("VM: {0}, Host: {1} - Reason: {2};", vm.opaque_ref, host.opaque_ref, failure.Message);
|
vmIsMigratable = false;
|
||||||
|
|
||||||
if (!excludedHosts.Contains(host.opaque_ref))
|
|
||||||
excludedHosts.Add(host.opaque_ref);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return excludedHosts.Count == targets.Count;
|
// if at least one VM is not migratable to the target pool, then there is no point checking the remaining VMs
|
||||||
|
if (!vmIsMigratable)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Host> CollateHosts(out Pool thePool)
|
private List<Host> CollateHosts(IXenObject itemToFilterOn, out Pool thePool)
|
||||||
{
|
{
|
||||||
thePool = null;
|
thePool = null;
|
||||||
|
|
||||||
List<Host> target = new List<Host>();
|
List<Host> target = new List<Host>();
|
||||||
if (ItemToFilterOn is Host)
|
if (itemToFilterOn is Host)
|
||||||
{
|
{
|
||||||
target.Add(ItemToFilterOn as Host);
|
target.Add(itemToFilterOn as Host);
|
||||||
thePool = Helpers.GetPoolOfOne(ItemToFilterOn.Connection);
|
thePool = Helpers.GetPoolOfOne(itemToFilterOn.Connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ItemToFilterOn is Pool)
|
if (itemToFilterOn is Pool)
|
||||||
{
|
{
|
||||||
Pool pool = ItemToFilterOn as Pool;
|
Pool pool = itemToFilterOn as Pool;
|
||||||
target.AddRange(pool.Connection.Cache.Hosts);
|
target.AddRange(pool.Connection.Cache.Hosts);
|
||||||
|
target.Sort();
|
||||||
thePool = pool;
|
thePool = pool;
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
|
@ -49,31 +49,29 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
|
|||||||
this.preSelectedVMs = preSelectedVMs;
|
this.preSelectedVMs = preSelectedVMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool FailureFound
|
public override bool FailureFoundFor(IXenObject itemToFilterOn)
|
||||||
{
|
{
|
||||||
get
|
var residentHosts = from VM vm in preSelectedVMs
|
||||||
|
let home = vm.Home()
|
||||||
|
where home != null
|
||||||
|
select home;
|
||||||
|
|
||||||
|
|
||||||
|
if (itemToFilterOn is Host)
|
||||||
|
return residentHosts.Any(h => h == itemToFilterOn);
|
||||||
|
|
||||||
|
Pool tempPool = itemToFilterOn as Pool;
|
||||||
|
if (tempPool != null)
|
||||||
{
|
{
|
||||||
var residentHosts = from VM vm in preSelectedVMs
|
if (tempPool.Connection.Cache.Hosts.Length > 1)
|
||||||
let home = vm.Home()
|
return false;
|
||||||
where home != null
|
|
||||||
select home;
|
|
||||||
|
|
||||||
if (ItemToFilterOn is Host)
|
//Pool with one host (or less)
|
||||||
return residentHosts.Any(h => h == ItemToFilterOn);
|
Host master = tempPool.Connection.Resolve(tempPool.master);
|
||||||
|
return residentHosts.Any(h => h == master);
|
||||||
Pool tempPool = ItemToFilterOn as Pool;
|
|
||||||
if (tempPool != null)
|
|
||||||
{
|
|
||||||
if (tempPool.Connection.Cache.Hosts.Length > 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//Pool with one host (or less)
|
|
||||||
Host master = tempPool.Connection.Resolve(tempPool.master);
|
|
||||||
return residentHosts.Any(h => h == master);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Reason
|
public override string Reason
|
||||||
|
@ -50,21 +50,18 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
|
|||||||
this.preSelectedVMs = preSelectedVMs;
|
this.preSelectedVMs = preSelectedVMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool FailureFound
|
public override bool FailureFoundFor(IXenObject itemToFilterOn)
|
||||||
{
|
{
|
||||||
get
|
bool targetWlb = false;
|
||||||
{
|
|
||||||
bool targetWlb = false;
|
|
||||||
|
|
||||||
if(ItemToFilterOn != null)
|
if(itemToFilterOn != null)
|
||||||
targetWlb = Helpers.CrossPoolMigrationRestrictedWithWlb(ItemToFilterOn.Connection);
|
targetWlb = Helpers.CrossPoolMigrationRestrictedWithWlb(itemToFilterOn.Connection);
|
||||||
|
|
||||||
bool sourceWlb = preSelectedVMs.Any(vm => Helpers.CrossPoolMigrationRestrictedWithWlb(vm.Connection));
|
bool sourceWlb = preSelectedVMs.Any(vm => Helpers.CrossPoolMigrationRestrictedWithWlb(vm.Connection));
|
||||||
|
|
||||||
reason = targetWlb ? Messages.CPM_WLB_ENABLED_ON_HOST_FAILURE_REASON : Messages.CPM_WLB_ENABLED_ON_VM_FAILURE_REASON;
|
reason = targetWlb ? Messages.CPM_WLB_ENABLED_ON_HOST_FAILURE_REASON : Messages.CPM_WLB_ENABLED_ON_VM_FAILURE_REASON;
|
||||||
|
|
||||||
return targetWlb || sourceWlb;
|
return targetWlb || sourceWlb;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string reason = Messages.UNKNOWN;
|
private string reason = Messages.UNKNOWN;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
using XenAdmin.Controls;
|
using XenAdmin.Controls;
|
||||||
using XenAPI;
|
using XenAPI;
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ namespace XenAdmin.Wizards.GenericPages
|
|||||||
/// Event raised when the reason is updated
|
/// Event raised when the reason is updated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<DelayLoadingOptionComboBoxItem> ReasonUpdated;
|
public event Action<DelayLoadingOptionComboBoxItem> ReasonUpdated;
|
||||||
|
public Object ParentComboBox;
|
||||||
private string failureReason;
|
private string failureReason;
|
||||||
private IXenObject xenObject;
|
private IXenObject xenObject;
|
||||||
private const int DEFAULT_RETRIES = 10;
|
private const int DEFAULT_RETRIES = 10;
|
||||||
|
@ -41,21 +41,19 @@ namespace XenAdmin.Wizards.GenericPages
|
|||||||
if (!(itemToFilterOn is Host) && !(itemToFilterOn is Pool))
|
if (!(itemToFilterOn is Host) && !(itemToFilterOn is Pool))
|
||||||
throw new ArgumentException("Target should be host or pool");
|
throw new ArgumentException("Target should be host or pool");
|
||||||
|
|
||||||
ItemToFilterOn = itemToFilterOn;
|
baseItemToFilterOn = itemToFilterOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base item that should be used to filter on
|
/// Base item that should be used to filter on
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IXenObject ItemToFilterOn { get; set; }
|
private IXenObject baseItemToFilterOn { get; set; }
|
||||||
public abstract bool FailureFound { get; }
|
//public abstract bool FailureFound { get; }
|
||||||
public abstract string Reason { get; }
|
public abstract string Reason { get; }
|
||||||
|
|
||||||
public bool FailureFoundFor(IXenObject xenObject)
|
public abstract bool FailureFoundFor(IXenObject xenObject);
|
||||||
{
|
|
||||||
ItemToFilterOn = xenObject;
|
public bool FailureFound => FailureFoundFor(baseItemToFilterOn);
|
||||||
return FailureFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Cancel() { }
|
public virtual void Cancel() { }
|
||||||
}
|
}
|
||||||
|
@ -409,13 +409,13 @@ namespace XenAdmin.Wizards.GenericPages
|
|||||||
foreach (var host in sortedHosts)
|
foreach (var host in sortedHosts)
|
||||||
{
|
{
|
||||||
var item = new DelayLoadingOptionComboBoxItem(host, homeserverFilters);
|
var item = new DelayLoadingOptionComboBoxItem(host, homeserverFilters);
|
||||||
item.LoadSync();
|
|
||||||
cb.Items.Add(item);
|
cb.Items.Add(item);
|
||||||
if (item.Enabled && ((m_selectedObject != null && m_selectedObject.opaque_ref == host.opaque_ref) ||
|
item.ParentComboBox = cb;
|
||||||
(target.Item.opaque_ref == host.opaque_ref)))
|
item.PreferAsSelectedItem = m_selectedObject != null && m_selectedObject.opaque_ref == host.opaque_ref ||
|
||||||
cb.Value = item;
|
target.Item.opaque_ref == host.opaque_ref;
|
||||||
|
item.ReasonUpdated += DelayLoadedGridComboBoxItem_ReasonChanged;
|
||||||
|
item.LoadAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetComboBoxPreSelection(cb);
|
SetComboBoxPreSelection(cb);
|
||||||
@ -524,7 +524,34 @@ namespace XenAdmin.Wizards.GenericPages
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PropertyChanged(object sender, PropertyChangedEventArgs e)
|
private void DelayLoadedGridComboBoxItem_ReasonChanged(DelayLoadingOptionComboBoxItem item)
|
||||||
|
{
|
||||||
|
if (item == null)
|
||||||
|
throw new NullReferenceException("Trying to update delay loaded reason but failed to extract reason");
|
||||||
|
|
||||||
|
var cb = item.ParentComboBox as DataGridViewEnableableComboBoxCell;
|
||||||
|
if (cb == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(this, () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var selectedValue = cb.Value;
|
||||||
|
cb.DataGridView.RefreshEdit();
|
||||||
|
if (item.Enabled && item.PreferAsSelectedItem)
|
||||||
|
cb.Value = item;
|
||||||
|
else
|
||||||
|
cb.Value = selectedValue;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
item.ReasonUpdated -= DelayLoadedGridComboBoxItem_ReasonChanged;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PropertyName == "name_label" || e.PropertyName == "metrics" ||
|
if (e.PropertyName == "name_label" || e.PropertyName == "metrics" ||
|
||||||
e.PropertyName == "enabled" || e.PropertyName == "live" || e.PropertyName == "patches")
|
e.PropertyName == "enabled" || e.PropertyName == "live" || e.PropertyName == "patches")
|
||||||
|
@ -47,37 +47,34 @@ namespace XenAdmin.Wizards.ImportWizard.Filters
|
|||||||
{
|
{
|
||||||
_hardwarePlatformSettings = hardwarePlatformSettings;
|
_hardwarePlatformSettings = hardwarePlatformSettings;
|
||||||
|
|
||||||
if (ItemToFilterOn is Host host)
|
if (itemAddedToComboBox is Host host)
|
||||||
_hosts.Add(host);
|
_hosts.Add(host);
|
||||||
|
|
||||||
if (ItemToFilterOn is Pool pool)
|
if (itemAddedToComboBox is Pool pool)
|
||||||
_hosts.AddRange(pool.Connection.Cache.Hosts);
|
_hosts.AddRange(pool.Connection.Cache.Hosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool FailureFound
|
public override bool FailureFoundFor(IXenObject itemToFilterOn)
|
||||||
{
|
{
|
||||||
get
|
foreach (var setting in _hardwarePlatformSettings)
|
||||||
{
|
{
|
||||||
foreach (var setting in _hardwarePlatformSettings)
|
long hardwarePlatformVersion;
|
||||||
|
if (!long.TryParse(setting.Value.Value, out hardwarePlatformVersion))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_hosts.Count > 0)
|
||||||
{
|
{
|
||||||
long hardwarePlatformVersion;
|
if (_hosts.Any(h => !h.virtual_hardware_platform_versions.Contains(hardwarePlatformVersion)))
|
||||||
if (!long.TryParse(setting.Value.Value, out hardwarePlatformVersion))
|
return true;
|
||||||
continue;
|
}
|
||||||
|
else
|
||||||
if (_hosts.Count > 0)
|
{
|
||||||
{
|
if (hardwarePlatformVersion > 0)
|
||||||
if (_hosts.Any(h => !h.virtual_hardware_platform_versions.Contains(hardwarePlatformVersion)))
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hardwarePlatformVersion > 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Reason => Messages.CPM_FAILURE_REASON_HARDWARE_PLATFORM;
|
public override string Reason => Messages.CPM_FAILURE_REASON_HARDWARE_PLATFORM;
|
||||||
|
Loading…
Reference in New Issue
Block a user