/* 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; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using XenAdmin.Controls; using XenAdmin.Controls.DataGridViewEx; using XenAdmin.Core; using XenAdmin.Network; using XenAdmin.Properties; using System.Linq; using XenAdmin.Wizards.RollingUpgradeWizard.Sorting; using XenAPI; using XenAdmin.Dialogs; namespace XenAdmin.Wizards.RollingUpgradeWizard { public partial class RollingUpgradeWizardSelectPool : XenTabPage { private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public RollingUpgradeWizardSelectPool() { InitializeComponent(); this.dataGridView1.CheckBoxClicked += DataGridRowClicked; this.Dock = DockStyle.Fill; } public override string Text { get { return Messages.SELECT_POOL; } } public override string PageTitle { get { return Messages.SELECT_POOL; } } public override string HelpID { get { return "Selectpool"; } } public override void PageLeave(PageLoadedDirection direction, ref bool cancel) { if (direction == PageLoadedDirection.Forward) { if (!AllSelectedHostsConnected()) { dataGridView1.Invalidate(); cancel = true; return; } foreach (var selectedMaster in SelectedMasters) { if (!(selectedMaster.Connection.Session.IsLocalSuperuser || selectedMaster.Connection.Session.Roles.Any(role => role.name_label == Role.MR_ROLE_POOL_ADMIN))) { using (var dlg = new ThreeButtonDialog( new ThreeButtonDialog.Details(SystemIcons.Warning, string.Format(Messages.RBAC_UPGRADE_WIZARD_MESSAGE, selectedMaster.Connection.Username, selectedMaster.Name), Messages.ROLLING_POOL_UPGRADE))) { dlg.ShowDialog(this); } DeselectMaster(selectedMaster); cancel = true; return; } } } base.PageLeave(direction, ref cancel); } private bool AllSelectedHostsConnected() { var disconnectedServerNames = new List(); foreach (UpgradeDataGridViewRow row in dataGridView1.Rows) { if (row.Checked == CheckState.Checked && ((row.Tag is Host && !row.HasPool) || row.Tag is Pool)) { IXenConnection connection = ((IXenObject)row.Tag).Connection; if (connection == null || !connection.IsConnected) disconnectedServerNames.Add(((IXenObject)row.Tag).Name); } } if (disconnectedServerNames.Count > 0) { using (var dlg = new ThreeButtonDialog( new ThreeButtonDialog.Details(SystemIcons.Warning, string.Format(Messages.ROLLING_UPGRADE_DISCONNECTED_SERVER, Helpers.StringifyList(disconnectedServerNames)), Messages.ROLLING_POOL_UPGRADE))) { dlg.ShowDialog(this); } return false; } return true; } private void DeselectMaster(Host master) { foreach (UpgradeDataGridViewRow row in dataGridView1.Rows) { if (row.Tag is Host && row.Tag == master) { row.Checked = CheckState.Unchecked; } else if (row.Tag is Pool && ((Pool)(row.Tag)).master.opaque_ref == master.opaque_ref) { row.Checked = CheckState.Unchecked; } } } private static bool IsNotAnUpgradeableVersion(Host host) { return false; // currently, all supported versions are upgradable } public IList SelectedMasters { get { List hosts = new List(); foreach (UpgradeDataGridViewRow row in dataGridView1.Rows) { if (row.Tag is Host) { if (!row.HasPool && ((int)row.Cells[1].Value) == 1) hosts.Add((Host)row.Tag); } else if (row.Tag is Pool && ((int)row.Cells[1].Value) == 1) { Pool pool = ((Pool)(row.Tag)); Host host = pool.Connection.Resolve(pool.master); hosts.Add(host); } } return hosts; } } public override void PageLoaded(PageLoadedDirection direction) { base.PageLoaded(direction); BuildServerList(); } private void BuildServerList() { IList masters = SelectedMasters; dataGridView1.Rows.Clear(); List xenConnections = ConnectionsManager.XenConnectionsCopy; xenConnections.Sort(); foreach (IXenConnection xenConnection in xenConnections) { Pool pool = Helpers.GetPool(xenConnection); Pool poolOfOne = Helpers.GetPoolOfOne(xenConnection); bool hasPool = true; if (pool != null) { int index = dataGridView1.Rows.Add(new UpgradeDataGridViewRow(pool)); if ((IsNotAnUpgradeableVersion(pool.SmallerVersionHost) && !pool.RollingUpgrade) || pool.IsUpgradeForbidden) ((DataGridViewExRow)dataGridView1.Rows[index]).Enabled = false; else if (masters.Contains(pool.Connection.Resolve(pool.master))) dataGridView1.CheckBoxChange(index, 1); } else { hasPool = false; } Host[] hosts = xenConnection.Cache.Hosts; Array.Sort(hosts); foreach (Host host in hosts) { int index = dataGridView1.Rows.Add(new UpgradeDataGridViewRow(host, hasPool)); if (IsNotAnUpgradeableVersion(host) || (poolOfOne != null && poolOfOne.IsUpgradeForbidden)) ((DataGridViewExRow)dataGridView1.Rows[index]).Enabled = false; else if (!hasPool && masters.Contains(host)) dataGridView1.CheckBoxChange(index, 1); } } foreach (DataGridViewRow row in dataGridView1.Rows) { dataGridView1.ExpandCollapseClicked(row.Index); } } public override bool EnableNext() { bool clearAllButtonEnabled = false; bool selectAllButtonEnabled = false; foreach (UpgradeDataGridViewRow row in dataGridView1.Rows) { if ((row.Tag is Host && !row.HasPool) || row.Tag is Pool) { int val = (int)row.Cells[1].Value; if (val > 0) clearAllButtonEnabled = true; else selectAllButtonEnabled = true; } } buttonClearAll.Enabled = clearAllButtonEnabled; buttonSelectAll.Enabled = selectAllButtonEnabled; return clearAllButtonEnabled; } private class UpgradeDataGridView : PoolHostDataGridViewOneCheckbox { public UpgradeDataGridView(){} public UpgradeDataGridView(IContainer container) : base(container){} protected override void SortAdditionalColumns() { UpgradeDataGridViewRow firstRow = Rows[0] as UpgradeDataGridViewRow; if (firstRow == null) return; if (columnToBeSortedIndex == firstRow.DescriptionCellIndex) { SortAndRebuildTree(new UpgradeDataGridViewDescriptionSorter(direction)); } if (columnToBeSortedIndex == firstRow.VersionCellIndex) { SortAndRebuildTree(new UpgradeDataGridViewVersionSorter(direction)); } } } public class UpgradeDataGridViewRow : PoolHostDataGridViewOneCheckboxRow { private DataGridViewTextBoxCell _description; private DataGridViewTextBoxCell _version; public UpgradeDataGridViewRow(Pool pool) : base(pool) { } public UpgradeDataGridViewRow(Host host, bool hasPool) : base(host, hasPool) { } public int DescriptionCellIndex { get { return Cells.IndexOf(_description); } } public int VersionCellIndex { get { return Cells.IndexOf(_version); } } public string DescriptionText { get { return (string) Cells[DescriptionCellIndex].Value; } } public string VersionText { get { return (string)Cells[VersionCellIndex].Value; } } protected override void SetupAdditionalDetailsColumns() { _description = new DataGridViewTextBoxCell(); _version = new DataGridViewTextBoxCell(); Cells.Add(_description); Cells.Add(_version); } protected override void UpdateAdditionalDetailsForPool(Pool pool, Host master) { _description.Value = pool.Description; _version.Value = pool.SmallerVersionHost.ProductVersionTextShort; } protected override void UpdateAdditionalDetailsForHost( Host host ) { _description.Value = host.Description; _version.Value = host.ProductVersionTextShort; } } private void buttonSelectAll_Click(object sender, EventArgs e) { foreach (UpgradeDataGridViewRow row in dataGridView1.Rows) { var checkrow = row.Cells[1] as DataGridViewCheckBoxCell; if (row.Enabled) checkrow.Value = 1; } OnPageUpdated(); } private void buttonClearAll_Click(object sender, EventArgs e) { foreach (DataGridViewRow row in dataGridView1.Rows) { var checkrow = row.Cells[1] as DataGridViewCheckBoxCell; checkrow.Value = 0; } OnPageUpdated(); } private void DataGridRowClicked(object sender, EventArgs e) { OnPageUpdated(); } } }