CA-226900: Do not allow selection of individual pool members when installing a hotfix

This change does not apply to supplemental packs, as we should be able to install supp packs to individual hosts in a pool.
Also, if the wizard is installing an update from disk and we cannot match it in updates.xml, then we will continue to allow host selection, because we can't tell whether it is a supp pack or a hotfix.

Plus fixing the bug where the "Select All" button is enabled even when all the selectable servers/pools are selected

Signed-off-by: Mihaela Stoica <mihaela.stoica@citrix.com>
This commit is contained in:
Mihaela Stoica 2017-01-11 11:32:57 +00:00
parent cd5db23cdb
commit b418a8a170

View File

@ -57,6 +57,8 @@ namespace XenAdmin.Wizards.PatchingWizard
private const int CHECKED = 1;
private const int INDETERMINATE = 2;
private bool poolSelectionOnly;
public XenServerPatchAlert SelectedUpdateAlert { private get; set; }
public XenServerPatchAlert FileFromDiskAlert { private get; set; }
@ -93,6 +95,7 @@ namespace XenAdmin.Wizards.PatchingWizard
base.PageLoaded(direction);
try
{
poolSelectionOnly = IsInAutomaticMode || SelectedUpdateAlert != null || FileFromDiskAlert != null;
label1.Text = IsInAutomaticMode ? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_AUTOMATED_MODE : Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_DEFAULT;
// catch selected servers, in order to restore selection after the dataGrid is reloaded
@ -100,58 +103,26 @@ namespace XenAdmin.Wizards.PatchingWizard
dataGridViewHosts.Rows.Clear();
if (IsInAutomaticMode)
{
//hides expand column
dataGridViewHosts.Columns[0].Visible = false;
}
else
{
dataGridViewHosts.Columns[0].Visible = true;
}
List<IXenConnection> xenConnections = ConnectionsManager.XenConnectionsCopy;
xenConnections.Sort();
foreach (IXenConnection xenConnection in xenConnections)
{
if (IsInAutomaticMode)
// add pools, their members and standalone hosts
Pool pool = Helpers.GetPool(xenConnection);
bool hasPool = pool != null;
if (hasPool)
{
if (!xenConnection.IsConnected)
continue;
var pool = Helpers.GetPoolOfOne(xenConnection);
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(pool));
Host master = pool.Connection.Resolve(pool.master);
int index = -1;
if (Helpers.GetPool(xenConnection) != null) //pools
{
index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(pool));
}
else //standalone hosts
{
index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(master, false));
}
EnabledRow(master, SelectedUpdateType, index);
}
else
{
Pool pool = Helpers.GetPool(xenConnection);
bool hasPool = pool != null;
if (hasPool)
{
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(pool));
Host master = pool.Connection.Resolve(pool.master);
EnabledRow(master, SelectedUpdateType, index);
}
Host[] hosts = xenConnection.Cache.Hosts;
Array.Sort(hosts);
foreach (Host host in hosts)
{
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(host, hasPool));
EnabledRow(host, SelectedUpdateType, index);
}
Host[] hosts = xenConnection.Cache.Hosts;
Array.Sort(hosts);
foreach (Host host in hosts)
{
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(host, hasPool, !poolSelectionOnly));
EnabledRow(host, SelectedUpdateType, index);
}
}
@ -238,14 +209,14 @@ namespace XenAdmin.Wizards.PatchingWizard
return;
}
List<Host> selectedHosts = null;
List<Host> applicableHosts = null;
if (SelectedUpdateAlert != null)
{
selectedHosts = SelectedUpdateAlert.DistinctHosts;
applicableHosts = SelectedUpdateAlert.DistinctHosts;
}
else if (FileFromDiskAlert != null)
{
selectedHosts = FileFromDiskAlert.DistinctHosts;
applicableHosts = FileFromDiskAlert.DistinctHosts;
}
if (!host.CanApplyHotfixes && (Helpers.ElyOrGreater(host) || type != UpdateType.ISO))
@ -259,7 +230,7 @@ namespace XenAdmin.Wizards.PatchingWizard
{
case UpdateType.NewRetail:
case UpdateType.Existing:
disableNotApplicableHosts(row, selectedHosts, host);
disableNotApplicableHosts(row, applicableHosts, host);
break;
case UpdateType.ISO:
if (!host.CanInstallSuppPack && !Helpers.ElyOrGreater(host)) //from Ely, iso does not mean supplemental pack
@ -267,17 +238,23 @@ namespace XenAdmin.Wizards.PatchingWizard
row.Enabled = false;
row.Cells[3].ToolTipText = Messages.PATCHINGWIZARD_SELECTSERVERPAGE_CANNOT_INSTALL_SUPP_PACKS;
}
if (selectedHosts != null)
if (applicableHosts != null)
{
disableNotApplicableHosts(row, selectedHosts, host);
disableNotApplicableHosts(row, applicableHosts, host);
}
break;
}
}
private void disableNotApplicableHosts(PatchingHostsDataGridViewRow row, List<Host> selectedHosts, Host host)
private void disableNotApplicableHosts(PatchingHostsDataGridViewRow row, List<Host> applicableHosts, Host host)
{
if (selectedHosts != null && !selectedHosts.Contains(host))
if (applicableHosts == null)
return;
if (poolSelectionOnly && row.IsPoolOrStandaloneHost && host.Connection.Cache.Hosts.Any(applicableHosts.Contains))
return;
if (!applicableHosts.Contains(host))
{
string patchUuidFromAlert = null;
if (SelectedUpdateAlert != null && SelectedUpdateAlert.Patch != null)
@ -378,7 +355,7 @@ namespace XenAdmin.Wizards.PatchingWizard
foreach (PatchingHostsDataGridViewRow row in dataGridViewHosts.Rows)
{
if ((int)row.Cells[POOL_CHECKBOX_COL].Value > UNCHECKED && ((row.Tag is Host && !row.HasPool) || row.Tag is Pool))
if ((int)row.Cells[POOL_CHECKBOX_COL].Value > UNCHECKED && row.IsPoolOrStandaloneHost)
{
IXenConnection connection = ((IXenObject) row.Tag).Connection;
if (connection == null || !connection.IsConnected)
@ -407,7 +384,7 @@ namespace XenAdmin.Wizards.PatchingWizard
foreach (PatchingHostsDataGridViewRow row in dataGridViewHosts.Rows)
{
if ((row.Tag is Host && !row.HasPool) || row.Tag is Pool)
if (row.IsPoolOrStandaloneHost && row.Enabled)
{
int val = (int)row.Cells[POOL_CHECKBOX_COL].Value;
if (val > UNCHECKED)
@ -449,7 +426,7 @@ namespace XenAdmin.Wizards.PatchingWizard
{
get
{
if (IsInAutomaticMode)
if (poolSelectionOnly)
{
return SelectedPools.SelectMany(p => p.Connection.Cache.Hosts).ToList();
}
@ -504,7 +481,7 @@ namespace XenAdmin.Wizards.PatchingWizard
{
foreach (PatchingHostsDataGridViewRow row in dataGridViewHosts.Rows)
{
if (row.Enabled && row.Tag != null && row.Tag is Host)
if (row.IsSelectableHost)
{
var host = (Host) row.Tag;
if (selectedServers.Contains(host))
@ -513,6 +490,17 @@ namespace XenAdmin.Wizards.PatchingWizard
? POOL_ICON_HOST_CHECKBOX_COL
: POOL_CHECKBOX_COL);
}
else if (poolSelectionOnly && row.IsSelectablePool)
{
// select the pools of the selected servers
var pool = (Pool) row.Tag;;
foreach (var host in pool.Connection.Cache.Hosts)
{
if (selectedServers.Contains(host))
dataGridViewHosts.CheckBoxChange(row.Index, POOL_CHECKBOX_COL);
break;
}
}
}
}
}
@ -539,14 +527,14 @@ namespace XenAdmin.Wizards.PatchingWizard
{
foreach (PatchingHostsDataGridViewRow row in dataGridViewHosts.Rows)
{
if (row.Tag is Host)
if (row.IsSelectableHost)
{
if (row.HasPool && (int)row.Cells[POOL_ICON_HOST_CHECKBOX_COL].Value != value)
dataGridViewHosts.CheckBoxChange(row.Index, POOL_ICON_HOST_CHECKBOX_COL);
else if ((int)row.Cells[POOL_CHECKBOX_COL].Value != value)
dataGridViewHosts.CheckBoxChange(row.Index, POOL_CHECKBOX_COL);
}
if (IsInAutomaticMode && row.Tag is Pool)
else if (row.IsSelectablePool && (int)row.Cells[POOL_CHECKBOX_COL].Value != value)
{
dataGridViewHosts.CheckBoxChange(row.Index, POOL_CHECKBOX_COL);
}
@ -584,7 +572,7 @@ namespace XenAdmin.Wizards.PatchingWizard
e.PaintBackground(e.ClipBounds, true);
e.Handled = true;
}
else if (row.HasPool && !row.Enabled && e.ColumnIndex == POOL_ICON_HOST_CHECKBOX_COL)
else if (row.HasPool && !row.IsSelectableHost && e.ColumnIndex == POOL_ICON_HOST_CHECKBOX_COL)
{
e.PaintBackground(e.ClipBounds, true);
e.Handled = true;
@ -792,15 +780,18 @@ namespace XenAdmin.Wizards.PatchingWizard
private DataGridViewCell _poolIconHostCheckCell;
private DataGridViewTextBoxCell _versionCell;
private readonly bool _showHostCheckBox = true;
public PatchingHostsDataGridViewRow(Pool pool)
: base(pool)
{
SetupCells();
}
public PatchingHostsDataGridViewRow(Host host, bool hasPool)
public PatchingHostsDataGridViewRow(Host host, bool hasPool, bool showHostCheckBox = true)
: base(host, hasPool)
{
_showHostCheckBox = showHostCheckBox;
SetupCells();
}
@ -825,29 +816,41 @@ namespace XenAdmin.Wizards.PatchingWizard
public int CheckValue
{
get {
return Tag is Pool || (Tag is Host && !_hasPool)
return IsPoolOrStandaloneHost
? (int) Cells[POOL_CHECKBOX_COL].Value
: (int) Cells[POOL_ICON_HOST_CHECKBOX_COL].Value;
}
}
public bool IsPoolOrStandaloneHost
{
get { return IsAPoolRow || (IsAHostRow && !HasPool); }
}
public bool IsSelectableHost
{
get { return IsAHostRow && Enabled && (_showHostCheckBox || !HasPool); }
}
public bool IsSelectablePool
{
get { return IsAPoolRow && Enabled; }
}
private void SetupCells()
{
_poolCheckBoxCell = new DataGridViewCheckBoxCell { ThreeState = true };
_expansionCell = new DataGridViewImageCell();
if (Tag is Pool || (Tag is Host && !_hasPool))
_poolIconHostCheckCell = new DataGridViewIconCell();
if (IsPoolOrStandaloneHost)
_poolIconHostCheckCell = new DataGridViewIconCell();
else
_poolIconHostCheckCell = new DataGridViewCheckBoxCell();
_nameCell = new DataGridViewNameCell();
_versionCell = new DataGridViewTextBoxCell();
Cells.AddRange(new[] { _expansionCell, _poolCheckBoxCell, _poolIconHostCheckCell, _nameCell, _versionCell });
this.UpdateDetails();
@ -867,12 +870,12 @@ namespace XenAdmin.Wizards.PatchingWizard
}
else if (Tag is Host)
{
Host host = (Host)Tag;
Host host = (Host) Tag;
_poolCheckBoxCell.Value = 0;
_expansionCell.Value = Resources.tree_plus;
if (_hasPool)
_poolIconHostCheckCell.Value = 0;
else
else
_poolIconHostCheckCell.Value = Images.GetImage16For(host);
_nameCell.Value = host;
_versionCell.Value = host.ProductVersionTextShort;