diff --git a/Branding/Branding.resx b/Branding/Branding.resx index 6c38eff7d1..77fbebc146 100644 --- a/Branding/Branding.resx +++ b/Branding/Branding.resx @@ -182,6 +182,9 @@ 8.2 + + 8.2.1 + [BRANDING_PRODUCT_VERSION_TEXT] diff --git a/XenAdmin/Actions/GUIActions/ExternalPluginAction.cs b/XenAdmin/Actions/GUIActions/ExternalPluginAction.cs index 3f9582c94e..79e4c66d33 100644 --- a/XenAdmin/Actions/GUIActions/ExternalPluginAction.cs +++ b/XenAdmin/Actions/GUIActions/ExternalPluginAction.cs @@ -246,11 +246,11 @@ void _extAppProcess_OutputDataReceived(object sender, DataReceivedEventArgs e) } // Returns a set of params which relate to the object you have selected in the treeview - private List RetrieveParams(IXenObject obj) + private IEnumerable RetrieveParams(IXenObject obj) { - IXenConnection connection = obj.Connection; - Host coordinator = connection != null ? Helpers.GetCoordinator(connection) : null; // get coordinator asserts connection is not null - string coordinatorAddress = EmptyParameter; + var connection = obj?.Connection; + var coordinator = connection != null ? Helpers.GetCoordinator(connection) : null; // get coordinator asserts connection is not null + var coordinatorAddress = EmptyParameter; if (coordinator != null) { @@ -258,9 +258,9 @@ private List RetrieveParams(IXenObject obj) WriteTrustedCertificates(coordinator.Connection); } - string sessionRef = connection.Session != null ? connection.Session.opaque_ref : EmptyParameter; - string objCls = obj != null ? obj.GetType().Name : EmptyParameter; - string objUuid = obj != null && connection.Session != null ? Helpers.GetUuid(obj) : EmptyParameter; + var sessionRef = connection?.Session != null ? connection.Session.opaque_ref : EmptyParameter; + var objCls = obj != null ? obj.GetType().Name : EmptyParameter; + var objUuid = connection?.Session != null ? Helpers.GetUuid(obj) : EmptyParameter; return new List(new string[] { coordinatorAddress, sessionRef, objCls, objUuid }); } diff --git a/XenAdmin/Actions/GUIActions/Wlb/WlbOptimizePoolAction.cs b/XenAdmin/Actions/GUIActions/Wlb/WlbOptimizePoolAction.cs index 9509738803..a4c51b7826 100644 --- a/XenAdmin/Actions/GUIActions/Wlb/WlbOptimizePoolAction.cs +++ b/XenAdmin/Actions/GUIActions/Wlb/WlbOptimizePoolAction.cs @@ -55,13 +55,8 @@ class WlbOptimizePoolAction : AsyncAction public WlbOptimizePoolAction(Pool pool, Dictionary vmOptLst, string optId) : base(pool.Connection, string.Format(Messages.WLB_OPTIMIZING_POOL, Helpers.GetName(pool).Ellipsise(50))) { - if (pool == null) - throw new ArgumentNullException("pool"); - if (vmOptLst == null) - throw new ArgumentNullException("vmOptLst"); - - this.Pool = pool; - this.vmOptList = vmOptLst; + Pool = pool; + vmOptList = vmOptLst ?? throw new ArgumentNullException("vmOptLst"); this.optId = optId; #region RBAC Dependencies diff --git a/XenAdmin/Commands/ChangeControlDomainMemoryCommand.cs b/XenAdmin/Commands/ChangeControlDomainMemoryCommand.cs index c5b3ad38c2..df40022e6b 100644 --- a/XenAdmin/Commands/ChangeControlDomainMemoryCommand.cs +++ b/XenAdmin/Commands/ChangeControlDomainMemoryCommand.cs @@ -58,7 +58,10 @@ public ChangeControlDomainMemoryCommand(IMainWindow mainWindow, IEnumerable()) - { - return false; - } - IXenConnection connection = null; - bool atLeastOneCanRun = false; - foreach (SelectedItem item in selection) + var atLeastOneCanRun = false; + foreach (var item in selection) { - VM vm = (VM)item.XenObject; - + if (!(item.XenObject is VM vm)) + return false; + // all VMs must be on the same connection if (connection != null && vm.Connection != connection) { return false; } + connection = vm.Connection; if (CanRun(item)) { diff --git a/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs b/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs index 600e6350c7..9e4874214d 100644 --- a/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs +++ b/XenAdmin/Commands/Controls/VMOperationToolStripMenuItem.cs @@ -33,12 +33,11 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Forms; +using XenAdmin.Actions.Wlb; using XenAdmin.Controls; -using XenAPI; using XenAdmin.Core; -using XenAdmin.Actions; -using XenAdmin.Actions.Wlb; using XenAdmin.Network; +using XenAPI; namespace XenAdmin.Commands @@ -112,7 +111,7 @@ protected override void OnDropDownOpening(EventArgs e) // Adds the migrate wizard button, do this before the enable checks on the other items AddAdditionalMenuItems(selection); - + UpdateHostList(); } @@ -163,11 +162,13 @@ private void UpdateHostList() if (Helpers.WlbEnabled(connection)) { var vms = selection.AsXenObjects(); + if (vms == null || vms.Count == 0) + return; + var retrieveVmRecommendationsAction = new WlbRetrieveVmRecommendationsAction(connection, vms); retrieveVmRecommendationsAction.Completed += delegate { - if (Stopped || retrieveVmRecommendationsAction.Cancelled || - !retrieveVmRecommendationsAction.Succeeded) + if (Stopped || retrieveVmRecommendationsAction.Cancelled || !retrieveVmRecommendationsAction.Succeeded) return; var recommendations = new WlbRecommendations(vms, retrieveVmRecommendationsAction.Recommendations); @@ -244,7 +245,7 @@ private void EnableAppropriateHostsNoWlb() var firstItem = DropDownItems[0] as VMOperationToolStripMenuSubItem; if (firstItem == null) return; - + // API calls could happen in CanRun(), which take time to wait. So a Producer-Consumer-Queue with size 25 is used here to : // 1. Make API calls for different menu items happen in parallel; // 2. Limit the count of concurrent threads (now it's 25). @@ -254,7 +255,7 @@ private void EnableAppropriateHostsNoWlb() var connection = selection[0].Connection; var session = connection.DuplicateSession(); - var affinityHost = connection.Resolve(((VM) selection[0].XenObject).affinity); + var affinityHost = connection.Resolve(((VM)selection[0].XenObject).affinity); EnqueueHostMenuItem(this, session, affinityHost, firstItem, true); @@ -279,7 +280,7 @@ private void EnqueueHostMenuItem(VMOperationToolStripMenuItem menu, Session sess workerQueueWithoutWlb.EnqueueItem(() => { var selection = menu.Command.GetSelection(); - var cmd = isHomeServer + var cmd = isHomeServer ? new VMOperationHomeServerCommand(menu.Command.MainWindowCommandInterface, selection, menu._operation, session) : new VMOperationHostCommand(menu.Command.MainWindowCommandInterface, selection, delegate { return host; }, host.Name().EscapeAmpersands(), menu._operation, session); @@ -321,7 +322,7 @@ private void EnqueueHostMenuItem(VMOperationToolStripMenuItem menu, Session sess } }); } - + #endregion /// diff --git a/XenAdmin/Commands/Controls/WlbRecommendations.cs b/XenAdmin/Commands/Controls/WlbRecommendations.cs index 435794d235..257af1b4ec 100644 --- a/XenAdmin/Commands/Controls/WlbRecommendations.cs +++ b/XenAdmin/Commands/Controls/WlbRecommendations.cs @@ -54,8 +54,6 @@ internal class WlbRecommendations /// public WlbRecommendations(List vms, Dictionary, string[]>> recommendations) { - Util.ThrowIfEnumerableParameterNullOrEmpty(vms, "vms"); - _vms = new ReadOnlyCollection(vms); _recommendations = recommendations; _isError = recommendations == null; diff --git a/XenAdmin/Commands/DragDropMigrateVMCommand.cs b/XenAdmin/Commands/DragDropMigrateVMCommand.cs index a7422f6a75..0885958756 100644 --- a/XenAdmin/Commands/DragDropMigrateVMCommand.cs +++ b/XenAdmin/Commands/DragDropMigrateVMCommand.cs @@ -140,7 +140,7 @@ protected override bool CanRunCore() if(!LiveMigrateAllowedInVersion(targetHost, draggedVM)) { - Pool targetPool = targetHost == null ? null : Helpers.GetPool(targetHost.Connection); + Pool targetPool = Helpers.GetPool(targetHost.Connection); if(targetPool == null) return false; diff --git a/XenAdmin/Commands/EnableTlsVerificationCommand.cs b/XenAdmin/Commands/EnableTlsVerificationCommand.cs index 895d3d4da5..31999d7efe 100644 --- a/XenAdmin/Commands/EnableTlsVerificationCommand.cs +++ b/XenAdmin/Commands/EnableTlsVerificationCommand.cs @@ -111,7 +111,8 @@ protected override bool CanRunCore(SelectedItemCollection selection) !pool.current_operations.Values.Contains(pool_allowed_operations.ha_enable) && !pool.current_operations.Values.Contains(pool_allowed_operations.ha_disable) && !pool.current_operations.Values.Contains(pool_allowed_operations.cluster_create) && - !pool.current_operations.Values.Contains(pool_allowed_operations.designate_new_master); + !pool.current_operations.Values.Contains(pool_allowed_operations.designate_new_master) && + !pool.RollingUpgrade(); } protected override string GetCantRunReasonCore(IXenObject item) @@ -134,6 +135,9 @@ protected override string GetCantRunReasonCore(IXenObject item) if (pool.current_operations.Values.Contains(pool_allowed_operations.designate_new_master)) return Messages.ENABLE_TLS_VERIFICATION_NEW_COORDINATOR; + + if (pool.RollingUpgrade()) + return Messages.ENABLE_TLS_VERIFICATION_RPU; } return base.GetCantRunReasonCore(item); diff --git a/XenAdmin/Commands/ImPortCommand.cs b/XenAdmin/Commands/ImPortCommand.cs index 9ef720f978..178c997ffb 100644 --- a/XenAdmin/Commands/ImPortCommand.cs +++ b/XenAdmin/Commands/ImPortCommand.cs @@ -49,14 +49,14 @@ public ImportCommand(IMainWindow mainWindow,Pool pool) : base(mainWindow, pool) { } - public override string MenuText { get { return Messages.HOST_MENU_IMPORT_VM_TEXT; } } - - public override string ContextMenuText{get{return Messages.HOST_MENU_IMPORT_VM_TEXT;}} + public override string MenuText => Messages.HOST_MENU_IMPORT_VM_TEXT; + + public override string ContextMenuText => Messages.HOST_MENU_IMPORT_VM_TEXT; protected override void RunCore(SelectedItemCollection selection) { var con = selection.GetConnectionOfFirstItem(); - MainWindowCommandInterface.ShowPerConnectionWizard(con, new ImportWizard(con, selection.FirstAsXenObject, null, false)); + MainWindowCommandInterface.ShowPerConnectionWizard(con, new ImportWizard(con, selection.FirstAsXenObject, null)); } } } diff --git a/XenAdmin/Commands/RepairSRCommand.cs b/XenAdmin/Commands/RepairSRCommand.cs index 8b61ee2a70..77efee06fd 100644 --- a/XenAdmin/Commands/RepairSRCommand.cs +++ b/XenAdmin/Commands/RepairSRCommand.cs @@ -78,7 +78,10 @@ protected override void RunCore(SelectedItemCollection selection) dlg.ShowDialog(Parent); } - new RepairSRDialog(srList).Show(Parent); + if (srList.Count != 0) + { + new RepairSRDialog(srList).Show(Parent); + } } protected override bool CanRunCore(SelectedItemCollection selection) diff --git a/XenAdmin/ConsoleView/VNCGraphicsClient.cs b/XenAdmin/ConsoleView/VNCGraphicsClient.cs index 3c231e2ede..fa3a87ea95 100644 --- a/XenAdmin/ConsoleView/VNCGraphicsClient.cs +++ b/XenAdmin/ConsoleView/VNCGraphicsClient.cs @@ -1497,7 +1497,7 @@ private void SetupScaling() if (this.Size.Height >= (displayBorder ? this.DesktopSize.Height + BORDER_PADDING + BORDER_PADDING : DesktopSize.Height)) { - this.dy = (this.Size.Height - this.DesktopSize.Height) / 2; + this.dy = ((float) this.Size.Height - this.DesktopSize.Height) / 2; } else { @@ -1515,7 +1515,7 @@ private void SetupScaling() if (this.Size.Width >= (displayBorder ? this.DesktopSize.Width + BORDER_PADDING + BORDER_PADDING : DesktopSize.Width)) { - this.dx = (this.Size.Width - this.DesktopSize.Width) / 2; + this.dx = ((float) this.Size.Width - this.DesktopSize.Width) / 2; } else { diff --git a/XenAdmin/ConsoleView/VNCTabView.cs b/XenAdmin/ConsoleView/VNCTabView.cs index df4bb563bd..45af1cba35 100644 --- a/XenAdmin/ConsoleView/VNCTabView.cs +++ b/XenAdmin/ConsoleView/VNCTabView.cs @@ -711,18 +711,10 @@ private void hideTopBarContents() } else if (source.power_state == vm_power_state.Paused) { - if (source.allowed_operations.Contains(vm_operations.unpause)) - { - //EnablePowerStateLabel(Messages.CONSOLE_POWER_STATE_PAUSED_UNPAUSE); - // CA-12637: Pause/UnPause is not supported in the GUI. Comment out - // the EnablePowerStateLabel because it gives the appearance that we - // support unpause via the GUI. - DisablePowerStateLabel(Messages.CONSOLE_POWER_STATE_PAUSED); - } - else - { - DisablePowerStateLabel(Messages.CONSOLE_POWER_STATE_PAUSED); - } + // CA-12637: Pause/UnPause is not supported in the GUI. Comment out + // the EnablePowerStateLabel because it gives the impression that we + // support unpause via the GUI. + DisablePowerStateLabel(Messages.CONSOLE_POWER_STATE_PAUSED); } else if (source.power_state == vm_power_state.Suspended) { diff --git a/XenAdmin/Controls/Ballooning/HostMemoryControls.cs b/XenAdmin/Controls/Ballooning/HostMemoryControls.cs index 501301d4e9..07e7c3bf01 100644 --- a/XenAdmin/Controls/Ballooning/HostMemoryControls.cs +++ b/XenAdmin/Controls/Ballooning/HostMemoryControls.cs @@ -127,6 +127,9 @@ void vm_metrics_PropertyChanged(object sender, PropertyChangedEventArgs e) private void valueControlDomain_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { + if (host == null) + return; + using (var dlg = new ControlDomainMemoryDialog(host)) dlg.ShowDialog(Program.MainWindow); } diff --git a/XenAdmin/Controls/ConsolePanel.cs b/XenAdmin/Controls/ConsolePanel.cs index 10faf287e1..cf3ea73238 100644 --- a/XenAdmin/Controls/ConsolePanel.cs +++ b/XenAdmin/Controls/ConsolePanel.cs @@ -310,10 +310,9 @@ public void StartCloseVNCTimer(VNCView vncView) // find the pair in vncViews and start timer on the vm var views = vncViews.Where(kvp => kvp.Value == vncView).ToList(); - foreach (var kvp in views) + if (views.Count > 0) { - StartCloseVNCTimer(kvp.Key); - break; + StartCloseVNCTimer(views.First().Key); } } diff --git a/XenAdmin/Controls/CustomDataGraph/DataKey.cs b/XenAdmin/Controls/CustomDataGraph/DataKey.cs index f9622b2c62..633a0b702c 100644 --- a/XenAdmin/Controls/CustomDataGraph/DataKey.cs +++ b/XenAdmin/Controls/CustomDataGraph/DataKey.cs @@ -300,11 +300,7 @@ public DataRange YRange { get { - foreach (DataSet s in Sets.Values) - { - return s.CustomYRange; - } - return null; + return Sets.Values.Select(s => s.CustomYRange).FirstOrDefault(); } } diff --git a/XenAdmin/Controls/CustomDataGraph/DataSet.cs b/XenAdmin/Controls/CustomDataGraph/DataSet.cs index abc039a29c..113209e0cd 100644 --- a/XenAdmin/Controls/CustomDataGraph/DataSet.cs +++ b/XenAdmin/Controls/CustomDataGraph/DataSet.cs @@ -482,19 +482,15 @@ private void InsertPoint(int index, DataPoint dataPoint) public override bool Equals(object obj) { - if(!(obj is DataSet)) - return base.Equals(obj); - - DataSet other = (DataSet)obj; + if (!(obj is DataSet other)) + return false; return Id == other.Id; } public override int GetHashCode() { - if (string.IsNullOrEmpty(Id)) - return base.GetHashCode(); - return Id.GetHashCode(); + return string.IsNullOrEmpty(Id) ? 0 : Id.GetHashCode(); } internal void InsertPointCollection(List list) diff --git a/XenAdmin/Controls/CustomGridView/GridRow.cs b/XenAdmin/Controls/CustomGridView/GridRow.cs index 78c38d3ce2..f0e1ef7c3a 100644 --- a/XenAdmin/Controls/CustomGridView/GridRow.cs +++ b/XenAdmin/Controls/CustomGridView/GridRow.cs @@ -38,8 +38,8 @@ namespace XenAdmin.Controls.CustomGridView { public class GridRow : IComparable { - public readonly Dictionary Items = new Dictionary(); - public readonly List Rows = new List(); + public Dictionary Items = new Dictionary(); + public List Rows = new List(); public static Image ExpandedImage = Images.StaticImages.expanded_triangle; public static Image ShrunkenImage = Images.StaticImages.contracted_triangle; @@ -678,14 +678,14 @@ internal void RestoreExpandedState(List expandedState) public override bool Equals(object obj) { - if(!(obj is GridRow)) - return base.Equals(obj); - return OpaqueRef == ((GridRow)obj).OpaqueRef; + if (!(obj is GridRow row)) + return false; + return OpaqueRef == row.OpaqueRef; } public override int GetHashCode() { - return base.GetHashCode(); + return (OpaqueRef != null ? OpaqueRef.GetHashCode() : 0); } } diff --git a/XenAdmin/Controls/DataGridViewEx/PoolHostDataGridViewOneCheckboxRow.cs b/XenAdmin/Controls/DataGridViewEx/PoolHostDataGridViewOneCheckboxRow.cs index 9b1ccbbef7..0770e1d34d 100644 --- a/XenAdmin/Controls/DataGridViewEx/PoolHostDataGridViewOneCheckboxRow.cs +++ b/XenAdmin/Controls/DataGridViewEx/PoolHostDataGridViewOneCheckboxRow.cs @@ -90,7 +90,9 @@ protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle } } } - + + private readonly IXenObject _xenObject; + /// /// If the row is either a pool row or else a stanadlone host row /// @@ -128,7 +130,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return base.GetHashCode(); + return _xenObject?.GetHashCode() ?? 0; } public CheckState Checked @@ -143,11 +145,10 @@ public CheckState Checked } } - protected PoolHostDataGridViewOneCheckboxRow(){} - protected PoolHostDataGridViewOneCheckboxRow(Pool pool) : base(pool) { + _xenObject = pool; SetupCells(); } @@ -159,6 +160,7 @@ protected PoolHostDataGridViewOneCheckboxRow(Pool pool) protected PoolHostDataGridViewOneCheckboxRow(Host host, bool hasPool) : base(host, hasPool) { + _xenObject = host; SetupCells(); } diff --git a/XenAdmin/Controls/FilterLocationToolStripDropDownButton.cs b/XenAdmin/Controls/FilterLocationToolStripDropDownButton.cs index 1eef0ca0ad..aad9997fcb 100644 --- a/XenAdmin/Controls/FilterLocationToolStripDropDownButton.cs +++ b/XenAdmin/Controls/FilterLocationToolStripDropDownButton.cs @@ -32,6 +32,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using System.Windows.Forms; using XenAdmin.Core; using XenAdmin.Network; @@ -119,18 +120,18 @@ public void BuildFilterList() DeregisterEvents(); RegisterEvents(); - foreach (IXenConnection c in ConnectionsManager.XenConnectionsCopy) + foreach (var c in ConnectionsManager.XenConnectionsCopy) { - Pool p = Helpers.GetPool(c); + var p = Helpers.GetPool(c); if (p == null)// Stand alone host { - foreach (Host h in c.Cache.Hosts) + if (c.Cache.Hosts.Length > 0) { - var item = GenerateFilterItem(h, h.uuid); - item.Checked = HostCheckStates.ContainsKey(h.uuid); + var host = c.Cache.Hosts.First(); + var item = GenerateFilterItem(host, host.uuid); + item.Checked = HostCheckStates.ContainsKey(host.uuid); DropDownItems.Add(item); - break; } } else diff --git a/XenAdmin/Controls/FlickerFreeListBox.cs b/XenAdmin/Controls/FlickerFreeListBox.cs index 693ea129c7..7fcdf68695 100644 --- a/XenAdmin/Controls/FlickerFreeListBox.cs +++ b/XenAdmin/Controls/FlickerFreeListBox.cs @@ -33,7 +33,6 @@ using System.Windows.Forms; using System.Drawing; using System.Runtime.InteropServices; -using XenAdmin.Core; using XenCenterLib; namespace XenAdmin.Controls @@ -62,8 +61,8 @@ public FlickerFreeListBox() /// The handle of the horizontal scrollbar of this ListBox /// private IntPtr _hScrollbarHandle = IntPtr.Zero; - public WndProcCancelDelegate CancelWndProc = new WndProcCancelDelegate(delegate(Message msg) { return false; }); + public Func CancelWndProc = msg => false; protected override void WndProc(ref Message msg) { @@ -92,7 +91,7 @@ protected override void WndProc(ref Message msg) base.Invalidate(); } - if(!CancelWndProc(msg)) + if (!CancelWndProc(msg)) base.WndProc(ref msg); } @@ -118,18 +117,12 @@ protected override void OnMouseWheel(MouseEventArgs e) base.OnMouseWheel(e); } - private ContextMenuStrip _contextMenuStrip = null; + private ContextMenuStrip _contextMenuStrip; public override ContextMenuStrip ContextMenuStrip { - get - { - return _contextMenuStrip; - } - set - { - _contextMenuStrip = value; - } + get => _contextMenuStrip; + set => _contextMenuStrip = value; } protected override void OnKeyUp(KeyEventArgs e) @@ -233,115 +226,6 @@ protected override void OnSelectedIndexChanged(EventArgs e) Refresh(); } - public const int RIGHT_PADDING = 5; - - public void WilkieSpecial(Image icon, string text, string extraText, Color extraTextColor, Font extraTextFont, DrawItemEventArgs e) - { - Graphics g = e.Graphics; - - WSPaintBG(e, this); - - // This is the rect where we want to put the text pair - Rectangle bounds = new Rectangle(e.Bounds.Height, e.Bounds.Y, e.Bounds.Width - e.Bounds.Height - RIGHT_PADDING, e.Bounds.Height); - - String display; - Size s = WSDrawTextPair(this, text, extraText, extraTextColor, extraTextFont, e, bounds, true, out display); - - WSDrawSelectRect(e, bounds.Height + s.Width); - - WSDrawLeftImage(icon, e); - - // And the text - Drawing.DrawText(g, display, e.Font, - bounds, e.ForeColor, e.BackColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter); - } - - private static void WSDrawSelectRect(DrawItemEventArgs e, int width) - { - Graphics g = e.Graphics; - - Rectangle selectionRectangle = new Rectangle(e.Bounds.Location, e.Bounds.Size); - selectionRectangle.Width = width; - - using (SolidBrush backBrush = new SolidBrush(e.BackColor)) - { - g.FillRectangle(backBrush, selectionRectangle); - } - } - - private static Color GetBackColorFor(Control control) - { - return !control.Enabled ? SystemColors.Control : control.BackColor; - } - - private static void WSDrawLeftImage(Image icon, DrawItemEventArgs e) - { - Graphics g = e.Graphics; - - g.DrawImage(icon, e.Bounds.Left + 1, e.Bounds.Top + 1, e.Bounds.Height - 2, e.Bounds.Height - 2); - } - - private static Size WSDrawTextPair(Control control, String text, String extraText, Color extraTextColor, Font extraTextFont, DrawItemEventArgs e, Rectangle bounds, bool ShowSelectOnExtraText, out String display) - { - Graphics g = e.Graphics; - g.TextRenderingHint = Drawing.TextRenderingHint; - - display = text; - Size s = Drawing.MeasureText(g, display, e.Font, - bounds.Size, TextFormatFlags.Right | TextFormatFlags.VerticalCenter); - - if (extraText == null) - return s; - - // We're going to have the extra text take precedent over the text, - // so shrink the text and put ellipses on until it measures up - - Size t = Drawing.MeasureText(g, extraText, extraTextFont, - bounds.Size, TextFormatFlags.Right | TextFormatFlags.VerticalCenter); - - int trim = text.Length; - - while (s.Width + t.Width + 10 > bounds.Width && trim > 0) - { - trim--; - - display = text.Ellipsise(trim); - - s = Drawing.MeasureText(g, display, e.Font, - bounds.Size, TextFormatFlags.Right | TextFormatFlags.VerticalCenter); - } - - Color backColor = ShowSelectOnExtraText && control.Focused && e.State == DrawItemState.Selected - ? Color.LightGray - : GetBackColorFor(control); - - if (ShowSelectOnExtraText) - { - Rectangle greySelectionRectangle = new Rectangle(bounds.Width - t.Width + bounds.X, bounds.Y + 2, t.Width, t.Height); - - using (SolidBrush brush = new SolidBrush(backColor)) - { - g.FillRectangle(brush, greySelectionRectangle); - } - } - - Drawing.DrawText(g, extraText, extraTextFont, - bounds, extraTextColor, backColor, TextFormatFlags.Right | TextFormatFlags.VerticalCenter); - - return s; - } - - private static void WSPaintBG(DrawItemEventArgs e, Control control) - { - Graphics g = e.Graphics; - Color color = GetBackColorFor(control); - - using (SolidBrush backBrush = new SolidBrush(color)) - { - g.FillRectangle(backBrush, e.Bounds); - } - } - protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); @@ -354,6 +238,4 @@ protected override void OnLostFocus(EventArgs e) this.Refresh(); } } - - public delegate bool WndProcCancelDelegate(Message msg); } diff --git a/XenAdmin/Controls/LunPerVdiPicker.cs b/XenAdmin/Controls/LunPerVdiPicker.cs index 3e3ca3c66f..8b7c704804 100644 --- a/XenAdmin/Controls/LunPerVdiPicker.cs +++ b/XenAdmin/Controls/LunPerVdiPicker.cs @@ -271,7 +271,6 @@ protected void ConstructCells() cbLUN.Items.Add(new LunComboBoxItem(vdi) { AdditionalConstraints = LunConstraints }); } - cbLUN.Items.OfType().OrderBy(i=>i.Enabled); Cells.AddRange(tbVDI, cbLUN, tbSR); Debug.Assert(cbLUN.Items.Count == Sr.VDIs.Count, "Not all combobox items were converted"); } diff --git a/XenAdmin/Controls/NetworkingTab/NetworkList.cs b/XenAdmin/Controls/NetworkingTab/NetworkList.cs index 62dc98a5dd..0a358ce04d 100644 --- a/XenAdmin/Controls/NetworkingTab/NetworkList.cs +++ b/XenAdmin/Controls/NetworkingTab/NetworkList.cs @@ -305,8 +305,6 @@ public void BuildList() } NetworksGridView.Rows.AddRange(vifRowsToAdd.ToArray()); - bool selected = true; - if (selectedVIF != null) { foreach (VifRow row in NetworksGridView.Rows) @@ -319,11 +317,6 @@ public void BuildList() } } } - - if (!selected && NetworksGridView.Rows.Count > 0) - { - NetworksGridView.Rows[0].Selected = true; - } } else if (XenObject is Host || XenObject is Pool) { diff --git a/XenAdmin/Controls/SectionHeaderLabel.cs b/XenAdmin/Controls/SectionHeaderLabel.cs index 492d303951..533c6973a7 100644 --- a/XenAdmin/Controls/SectionHeaderLabel.cs +++ b/XenAdmin/Controls/SectionHeaderLabel.cs @@ -300,7 +300,7 @@ private float GetLineVerticalLocation() } case VerticalAlignment.Middle: { - Y = (this.Height - this.Padding.Vertical) / 2; + Y = ((float) this.Height - this.Padding.Vertical) / 2; break; } case VerticalAlignment.Bottom: diff --git a/XenAdmin/Controls/SnapshotTreeView.cs b/XenAdmin/Controls/SnapshotTreeView.cs index 122e0a5d08..4ac183d0cd 100644 --- a/XenAdmin/Controls/SnapshotTreeView.cs +++ b/XenAdmin/Controls/SnapshotTreeView.cs @@ -336,17 +336,6 @@ private void PositionSnapshots(SnapshotIcon icon, int x, int y) [DllImport("user32.dll")] internal static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref Win32.POINT pt); - - - public override Size GetPreferredSize(Size proposedSize) - { - if (root == null && Parent != null) - { - return DefaultSize; - } - return new Size(root.SubtreeWidth, root.SubtreeHeight); - } - #endregion #region Drawing diff --git a/XenAdmin/Controls/SrPicker.cs b/XenAdmin/Controls/SrPicker.cs index 9917e5a3e2..35bbb58459 100644 --- a/XenAdmin/Controls/SrPicker.cs +++ b/XenAdmin/Controls/SrPicker.cs @@ -137,12 +137,8 @@ protected override void OnPaint(PaintEventArgs e) if (_scanCount > 0) return; - - Program.Invoke(this, () => - { - Invalidate(); - Rebuild(items, preselectedSR); - }); + + Program.Invoke(this, () => Rebuild(items, preselectedSR)); }; action.RunAsync(); } @@ -177,6 +173,7 @@ private List GetSrPickerItems() private void Rebuild(List items = null, SR preselectedSr = null) { Program.AssertOnEventThread(); + Invalidate(); SR selectedSr = preselectedSr ?? SR; var theItems = items ?? GetSrPickerItems(); @@ -213,12 +210,18 @@ public void UpdateDiskSize(long diskSize) private void Server_PropertyChanged(object sender, PropertyChangedEventArgs e) { + if (_scanCount > 0) + return; + if (e.PropertyName == "name_label" || e.PropertyName == "PBDs" || e.PropertyName == "physical_utilisation" || e.PropertyName == "currently_attached" || e.PropertyName == "default_SR") Program.Invoke(this, () => Rebuild()); } private void SR_CollectionChanged(object sender, CollectionChangeEventArgs e) { + if (_scanCount > 0) + return; + Program.Invoke(this, () => Rebuild()); } diff --git a/XenAdmin/Controls/TreeViews/FlickerFreeTreeView.cs b/XenAdmin/Controls/TreeViews/FlickerFreeTreeView.cs index 0e2f355d0a..75219a7db2 100644 --- a/XenAdmin/Controls/TreeViews/FlickerFreeTreeView.cs +++ b/XenAdmin/Controls/TreeViews/FlickerFreeTreeView.cs @@ -33,6 +33,7 @@ using System.Windows.Forms; using XenAdmin.Core; using System.Collections.Generic; +using System.Linq; using XenAdmin.Network; using XenAdmin.XenSearch; using XenCenterLib; @@ -157,7 +158,7 @@ public new void EndUpdate() { VirtualTreeNode.PersistenceInfo info = new VirtualTreeNode.PersistenceInfo(node); - if (!_persistedSelectionInfo.Contains(info)) + if (_persistedSelectionInfo != null && !_persistedSelectionInfo.Contains(info)) { // selection is different to old one. So fire an event. @@ -203,11 +204,9 @@ private void RestoreSelection() if (newSelectedNodes.Count == 0) { - foreach (VirtualTreeNode.PersistenceInfo info in _persistedSelectionInfo) + if (_persistedSelectionInfo.Count > 0) { - // Finally, just select one of the parents - TryToSelectNode(newSelectedNodes, ClosestMatch(info.Path)); - break; + TryToSelectNode(newSelectedNodes, ClosestMatch(_persistedSelectionInfo.First().Path)); } } diff --git a/XenAdmin/Controls/Wlb/WlbOptimizePool.cs b/XenAdmin/Controls/Wlb/WlbOptimizePool.cs index f1bfa4817d..a15360d9ee 100644 --- a/XenAdmin/Controls/Wlb/WlbOptimizePool.cs +++ b/XenAdmin/Controls/Wlb/WlbOptimizePool.cs @@ -422,7 +422,7 @@ private ListViewItem FindItemFromVM(VM vm) /// EventArgs private void ButtonApply_Click(object sender, EventArgs e) { - if (this._pool == null) + if (_pool == null || _vmOptList == null) return; applyButton.Enabled = false; diff --git a/XenAdmin/Controls/XenSearch/QueryElement.cs b/XenAdmin/Controls/XenSearch/QueryElement.cs index 1bbd50e592..74be953d8a 100644 --- a/XenAdmin/Controls/XenSearch/QueryElement.cs +++ b/XenAdmin/Controls/XenSearch/QueryElement.cs @@ -1080,7 +1080,7 @@ internal StringPropertyQueryType(int group, ObjectTypes appliesTo, PropertyNames public class ExtraComboEntry { - public StringPropertyQuery.PropertyQueryType type; + public readonly StringPropertyQuery.PropertyQueryType type; public ExtraComboEntry(StringPropertyQuery.PropertyQueryType type) { this.type = type; @@ -1121,7 +1121,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return base.GetHashCode(); + return (int) type; } } @@ -1327,7 +1327,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return base.GetHashCode(); + return (int) type; } } @@ -2498,7 +2498,7 @@ public override void FromQuery(QueryFilter query, QueryElement queryElement) if (intQuery == null) return; - queryElement.numericUpDown.Value = intQuery.query / multiplier; + queryElement.numericUpDown.Value = (decimal) intQuery.query / multiplier; } } diff --git a/XenAdmin/Controls/XenSearch/ResourceSelectButton.cs b/XenAdmin/Controls/XenSearch/ResourceSelectButton.cs index 74210b6195..af4df4ccc3 100644 --- a/XenAdmin/Controls/XenSearch/ResourceSelectButton.cs +++ b/XenAdmin/Controls/XenSearch/ResourceSelectButton.cs @@ -139,11 +139,8 @@ public void FinishedInThisGroup(bool defaultExpand) public void Populate(Search search) { ClearItems(); - if (search != null && search.Query != null) - scope = search.Query.QueryScope; - else - scope = null; - search.PopulateAdapters(this); + scope = search?.Query?.QueryScope; + search?.PopulateAdapters(this); } } } \ No newline at end of file diff --git a/XenAdmin/Core/ActionBaseExtensions.cs b/XenAdmin/Core/ActionBaseExtensions.cs index c76ae8d868..1a1a263c0a 100644 --- a/XenAdmin/Core/ActionBaseExtensions.cs +++ b/XenAdmin/Core/ActionBaseExtensions.cs @@ -59,7 +59,10 @@ internal static Image GetImage(this ActionBase action) internal static string GetDetails(this ActionBase action) { var sb = new StringBuilder(GetTitle(action)); - sb.Append("\n").Append(GetDescription(action)); + + var description = GetDescription(action); + if (!string.IsNullOrEmpty(description)) + sb.Append("\n").Append(description); string timeString = GetTimeElapsed(action); if (!string.IsNullOrEmpty(timeString)) diff --git a/XenAdmin/Diagnostics/Checks/PVGuestsCheck.cs b/XenAdmin/Diagnostics/Checks/PVGuestsCheck.cs index 2969af6957..3422b0555a 100644 --- a/XenAdmin/Diagnostics/Checks/PVGuestsCheck.cs +++ b/XenAdmin/Diagnostics/Checks/PVGuestsCheck.cs @@ -43,41 +43,30 @@ namespace XenAdmin.Diagnostics.Checks class PVGuestsCheck : HostPostLivenessCheck { private readonly Pool _pool; - private readonly bool _upgrade; private readonly bool _manualUpgrade; private readonly Dictionary _installMethodConfig; - public PVGuestsCheck(Host coordinator, bool upgrade, bool manualUpgrade = false, Dictionary installMethodConfig = null) + public PVGuestsCheck(Host coordinator, bool manualUpgrade = false, Dictionary installMethodConfig = null) : base(coordinator) { _pool = Helpers.GetPoolOfOne(Host?.Connection); - _upgrade = upgrade; _manualUpgrade = manualUpgrade; _installMethodConfig = installMethodConfig; } public override bool CanRun() { - if (Helpers.QuebecOrGreater(Host)) + if (Helpers.YangtzeOrGreater(Host)) return false; if (_pool == null || !_pool.Connection.Cache.VMs.Any(vm => vm.IsPvVm())) return false; - if (!_upgrade && !Helpers.NaplesOrGreater(Host)) - return false; - return true; } protected override Problem RunHostCheck() { - //update case - if (!_upgrade) - return new PoolHasPVGuestWarningUrl(this, _pool); - - //upgrade case - if (!_manualUpgrade) { var hotfix = HotfixFactory.Hotfix(Host); @@ -95,6 +84,9 @@ protected override Problem RunHostCheck() if (string.IsNullOrEmpty(upgradePlatformVersion)) return new PoolHasPVGuestWarningUrl(this, _pool); + if (Helpers.YangtzeOrGreater(upgradePlatformVersion)) + return new PoolHasPVGuestProblem(this, _pool); + if (Helpers.QuebecOrGreater(upgradePlatformVersion)) return new PoolHasPVGuestWarningUrl(this, _pool); diff --git a/XenAdmin/Diagnostics/Problems/PoolProblem/PoolHasPVGuestWarningUrl.cs b/XenAdmin/Diagnostics/Problems/PoolProblem/PoolHasPVGuestWarningUrl.cs index 1ae4f6322c..b75a3e8d24 100644 --- a/XenAdmin/Diagnostics/Problems/PoolProblem/PoolHasPVGuestWarningUrl.cs +++ b/XenAdmin/Diagnostics/Problems/PoolProblem/PoolHasPVGuestWarningUrl.cs @@ -57,4 +57,27 @@ public PoolHasPVGuestWarningUrl(Check check, Pool pool) public override string HelpMessage => LinkText; public override string LinkText => Messages.LEARN_MORE; } + + + class PoolHasPVGuestProblem : ProblemWithInformationUrl + { + private readonly Pool _pool; + + public PoolHasPVGuestProblem(Check check, Pool pool) + : base(check) + { + _pool = pool; + } + + private string PVGuestCheckUrl => string.Format(InvisibleMessages.PV_GUESTS_CHECK_URL); + public override Uri UriToLaunch => new Uri(PVGuestCheckUrl); + public override string Title => Description; + + public override string Description => + string.Format(Messages.POOL_HAS_PV_GUEST_WARNING, _pool.Name(), + string.Format(Messages.STRING_SPACE_STRING, BrandManager.ProductBrand, BrandManager.ProductVersion81)); + + public override string HelpMessage => LinkText; + public override string LinkText => Messages.LEARN_MORE; + } } diff --git a/XenAdmin/Dialogs/ActionProgressDialog.cs b/XenAdmin/Dialogs/ActionProgressDialog.cs index ca71e25b40..973cfdfe39 100644 --- a/XenAdmin/Dialogs/ActionProgressDialog.cs +++ b/XenAdmin/Dialogs/ActionProgressDialog.cs @@ -124,7 +124,9 @@ private void UpdateSubActionStatusLabel() var multipleAction = action as MultipleAction; labelSubActionStatus.Visible = multipleAction != null && multipleAction.ShowSubActionsDetails; if (labelSubActionStatus.Visible) - UpdateLabel(labelSubActionStatus, multipleAction.SubActionDescription, multipleAction.SubActionTitle); + { + UpdateLabel(labelSubActionStatus, multipleAction?.SubActionDescription, multipleAction?.SubActionTitle); + } } private void action_Completed(ActionBase sender) diff --git a/XenAdmin/Dialogs/AddServerDialog.cs b/XenAdmin/Dialogs/AddServerDialog.cs index 34a99bc2a4..dc72c5b788 100644 --- a/XenAdmin/Dialogs/AddServerDialog.cs +++ b/XenAdmin/Dialogs/AddServerDialog.cs @@ -137,7 +137,9 @@ private void UpdateText() ServerNameComboBox.Enabled = true; AddButton.Text = Messages.ADD; } - if (_changedPass && connection.Password == null) + else if (!_changedPass) + return; + else if (connection.Password == null) { Text = Messages.CONNECT_TO_SERVER; labelInstructions.Text = Messages.CONNECT_TO_SERVER_BLURB; @@ -145,7 +147,7 @@ private void UpdateText() ServerNameComboBox.Enabled = false; AddButton.Text = Messages.CONNECT; } - else if (_changedPass && connection.ExpectPasswordIsCorrect) + else if (connection.ExpectPasswordIsCorrect) { // This situation should be rare, it normally comes from logging in a new session after an existing one has been made // We now use duplicate sessions instead most of the time which don't log in again. @@ -155,7 +157,7 @@ private void UpdateText() ServerNameComboBox.Enabled = false; AddButton.Text = Messages.OK; } - else if (_changedPass) // the password probably hasnt actually changed but we do know the user has typed it in wrong + else // the password probably hasn't actually changed but we do know the user has typed it in wrong { Text = Messages.CONNECT_TO_SERVER; labelInstructions.Text = string.Format(Messages.ERROR_CONNECTING_BLURB, BrandManager.BrandConsole); @@ -163,6 +165,7 @@ private void UpdateText() ServerNameComboBox.Enabled = false; AddButton.Text = Messages.CONNECT; } + } private void AddButton_Click(object sender, EventArgs e) @@ -200,7 +203,7 @@ private void ConnectToServer(IXenConnection conn, string hostname, int port, str { if (conn == null) { - conn = new XenConnection {fromDialog = true}; + conn = new XenConnection { fromDialog = true }; conn.CachePopulated += conn_CachePopulated; } else if (!_changedPass) diff --git a/XenAdmin/Dialogs/ControlDomainMemoryDialog.cs b/XenAdmin/Dialogs/ControlDomainMemoryDialog.cs index 4522324ce1..090ff451f3 100644 --- a/XenAdmin/Dialogs/ControlDomainMemoryDialog.cs +++ b/XenAdmin/Dialogs/ControlDomainMemoryDialog.cs @@ -50,8 +50,6 @@ public partial class ControlDomainMemoryDialog : XenDialogBase public ControlDomainMemoryDialog(Host host) : base(host.Connection) { - if (host == null) throw new ArgumentNullException("host"); - InitializeComponent(); this.host = host; this.host.PropertyChanged += Server_PropertyChanged; diff --git a/XenAdmin/Dialogs/LicenseManager/LicenseStatus.cs b/XenAdmin/Dialogs/LicenseManager/LicenseStatus.cs index a946477b34..8772390ca6 100644 --- a/XenAdmin/Dialogs/LicenseManager/LicenseStatus.cs +++ b/XenAdmin/Dialogs/LicenseManager/LicenseStatus.cs @@ -207,15 +207,15 @@ internal static bool PoolIsMixedFreeAndExpiring(IXenObject xenObject) if (freeCount == 0 || freeCount < xenObject.Connection.Cache.Hosts.Length) return false; - var expiryGroups = from Host h in xenObject.Connection.Cache.Hosts + var expiryGroups = (from Host h in xenObject.Connection.Cache.Hosts let exp = h.LicenseExpiryUTC() group h by exp into g - select new { ExpiryDate = g.Key, Hosts = g }; + select new { ExpiryDate = g.Key, Hosts = g }).ToList(); - if(expiryGroups.Count() > 1) + if (expiryGroups.Count > 1) { - expiryGroups.OrderBy(g => g.ExpiryDate); + expiryGroups = expiryGroups.OrderBy(g => g.ExpiryDate).ToList(); if ((expiryGroups.ElementAt(1).ExpiryDate - expiryGroups.ElementAt(0).ExpiryDate).TotalDays > 30) return true; } diff --git a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs index fd47ff9fb0..2bf0b09925 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs +++ b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs @@ -120,7 +120,7 @@ public void Build() log.Warn("Could not unprotect internet proxy password.", e); } - ConnectionTimeoutNud.Value = Properties.Settings.Default.ConnectionTimeout / 1000; + ConnectionTimeoutNud.Value = (decimal) Properties.Settings.Default.ConnectionTimeout / 1000; eventsDisabled = false; } diff --git a/XenAdmin/Dialogs/RepairSRDialog.cs b/XenAdmin/Dialogs/RepairSRDialog.cs index 1a03738558..46ce465337 100644 --- a/XenAdmin/Dialogs/RepairSRDialog.cs +++ b/XenAdmin/Dialogs/RepairSRDialog.cs @@ -75,7 +75,6 @@ public RepairSRDialog(SR sr, bool runAction = true) /// public RepairSRDialog(IEnumerable srs, bool runAction = true) { - Util.ThrowIfEnumerableParameterNullOrEmpty(srs, "srs"); this.runAction = runAction; BoldFont = new Font(Font, FontStyle.Bold); List srList = new List(srs); diff --git a/XenAdmin/Dialogs/VMDialogs/MoveVMDialog.cs b/XenAdmin/Dialogs/VMDialogs/MoveVMDialog.cs index 491644534f..27c0daebe6 100644 --- a/XenAdmin/Dialogs/VMDialogs/MoveVMDialog.cs +++ b/XenAdmin/Dialogs/VMDialogs/MoveVMDialog.cs @@ -78,7 +78,7 @@ private void srPicker1_DoubleClickOnRow(object sender, EventArgs e) private void buttonMove_Click(object sender, EventArgs e) { - var action = new VMMoveAction(vm, srPicker1.SR, vm.GetStorageHost(false), vm.Name()); + var action = new VMMoveAction(vm, srPicker1.SR, vm.GetStorageHost(false)); action.RunAsync(); Close(); } diff --git a/XenAdmin/Dialogs/Wlb/WlbReportSubscriptionDialog.cs b/XenAdmin/Dialogs/Wlb/WlbReportSubscriptionDialog.cs index bab414af23..b6096072be 100644 --- a/XenAdmin/Dialogs/Wlb/WlbReportSubscriptionDialog.cs +++ b/XenAdmin/Dialogs/Wlb/WlbReportSubscriptionDialog.cs @@ -378,8 +378,8 @@ private void SaveSubscription() Dictionary rps = new Dictionary(); foreach(string key in this._rpParams.Keys) { - if (String.Compare(key, WlbReportSubscription.REPORT_NAME, true) == 0) - _subscription.ReportName = this._rpParams[WlbReportSubscription.REPORT_NAME]; + if (String.Compare(key, WlbReportSubscription.REPORT_NAME_KEY, true) == 0) + _subscription.ReportName = this._rpParams[WlbReportSubscription.REPORT_NAME_KEY]; else { //Get start date range diff --git a/XenAdmin/GroupingTag.cs b/XenAdmin/GroupingTag.cs index f7866490ba..5bb67ac11f 100644 --- a/XenAdmin/GroupingTag.cs +++ b/XenAdmin/GroupingTag.cs @@ -37,7 +37,7 @@ public class GroupingTag { internal Grouping Grouping; internal object Parent; - internal object Group; + internal readonly object Group; /// /// @@ -55,8 +55,7 @@ internal GroupingTag(Grouping grouping, object parent, object group) public override bool Equals(object obj) { - GroupingTag other = obj as GroupingTag; - return other != null && Grouping.Equals(other.Grouping) && Group.Equals(other.Group); + return obj is GroupingTag other && Grouping.Equals(other.Grouping) && Group.Equals(other.Group); } public override int GetHashCode() diff --git a/XenAdmin/MainWindow.cs b/XenAdmin/MainWindow.cs index ad918e5a7e..11ff50d229 100755 --- a/XenAdmin/MainWindow.cs +++ b/XenAdmin/MainWindow.cs @@ -2706,7 +2706,7 @@ private void OpenGlobalImportWizard(string param) { HelpersGUI.BringFormToFront(this); Host hostAncestor = SelectionManager.Selection.Count == 1 ? SelectionManager.Selection[0].HostAncestor : null; - new ImportWizard(SelectionManager.Selection.GetConnectionOfFirstItem(), hostAncestor, param, false).Show(); + new ImportWizard(SelectionManager.Selection.GetConnectionOfFirstItem(), hostAncestor, param).Show(); } #region XenSearch diff --git a/XenAdmin/Plugins/Features/MenuItemFeature.cs b/XenAdmin/Plugins/Features/MenuItemFeature.cs index b85cc06a82..4c215b65fa 100644 --- a/XenAdmin/Plugins/Features/MenuItemFeature.cs +++ b/XenAdmin/Plugins/Features/MenuItemFeature.cs @@ -85,8 +85,9 @@ public MenuItemFeature(ResourceManager resourceManager, XmlNode node, PluginDesc ContextMenu = Helpers.GetEnumXmlAttribute(node, ATT_CONTEXT_MENU, GetContextMenuFromMenu(Menu)); Serialized = Helpers.GetEnumXmlAttribute(node, ATT_SERIALIZED, PluginSerializationLevel.none); - foreach (XmlNode child in node.ChildNodes) - { + if (node.ChildNodes.Count > 0) + { + var child = node.ChildNodes[0]; switch (child.Name) { case TYPE_SHELL: @@ -99,7 +100,6 @@ public MenuItemFeature(ResourceManager resourceManager, XmlNode node, PluginDesc ShellCmd = new XenServerPowershellCmd(child, paramsFromXML(child)); break; } - return; } } diff --git a/XenAdmin/SettingsPanels/PerfmonAlertEditPage.cs b/XenAdmin/SettingsPanels/PerfmonAlertEditPage.cs index 0a2615e306..78ef3dce0f 100644 --- a/XenAdmin/SettingsPanels/PerfmonAlertEditPage.cs +++ b/XenAdmin/SettingsPanels/PerfmonAlertEditPage.cs @@ -230,7 +230,7 @@ public void SetXenObjects(IXenObject orig, IXenObject clone) Host host = (Host)_XenObject; Host_metrics metrics = host.Connection.Resolve(host.metrics); if (metrics != null) - nudMemoryUsage.Maximum = metrics.memory_total / (1024 * 1024); + nudMemoryUsage.Maximum = (decimal) metrics.memory_total / (1024 * 1024); } Repopulate(); diff --git a/XenAdmin/TabPages/PvsPage.cs b/XenAdmin/TabPages/PvsPage.cs index 875ef86267..d7eee2122c 100644 --- a/XenAdmin/TabPages/PvsPage.cs +++ b/XenAdmin/TabPages/PvsPage.cs @@ -231,17 +231,17 @@ private void RegisterVmEventHandlers(VM vm, PVS_proxy pvsProxy) { vm.PropertyChanged -= VmPropertyChanged; vm.PropertyChanged += VmPropertyChanged; - if (pvsProxy != null) - { - pvsProxy.PropertyChanged -= PvsProxyPropertyChanged; - pvsProxy.PropertyChanged += PvsProxyPropertyChanged; - PVS_site pvsSite = pvsProxy == null ? null : Connection.Resolve(pvsProxy.site); - if (pvsSite != null) - { - pvsSite.PropertyChanged -= PvsSitePropertyChanged; - pvsSite.PropertyChanged += PvsSitePropertyChanged; - } - } + + if (pvsProxy == null) + return; + pvsProxy.PropertyChanged -= PvsProxyPropertyChanged; + pvsProxy.PropertyChanged += PvsProxyPropertyChanged; + + var pvsSite = Connection.Resolve(pvsProxy.site); + if (pvsSite == null) + return; + pvsSite.PropertyChanged -= PvsSitePropertyChanged; + pvsSite.PropertyChanged += PvsSitePropertyChanged; } private void UnregisterVmEventHandlers() diff --git a/XenAdmin/VNC/KeySet.cs b/XenAdmin/VNC/KeySet.cs deleted file mode 100644 index 90bcef4ff7..0000000000 --- a/XenAdmin/VNC/KeySet.cs +++ /dev/null @@ -1,161 +0,0 @@ -/* 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.Windows.Forms; - -namespace DotNetVnc -{ - public class KeySet : IEquatable - { - List keys; - - public IList Keys - { - get - { - return keys.AsReadOnly(); - } - } - - public KeySet() - { - this.keys = new List(); - } - - public KeySet(List keys) - { - this.keys = new List(); - - foreach (Keys key in keys) - { - if (!this.keys.Contains(key)) - { - this.keys.Add(key); - } - } - - this.keys.Sort(); - } - - public KeySet(params Keys[] keys) - { - this.keys = new List(); - - foreach (Keys key in keys) - { - if (!this.keys.Contains(key)) - { - this.keys.Add(key); - } - } - - this.keys.Sort(); - } - - public KeySet Add(Keys _key) - { - List newKeys = new List(); - - foreach(Keys key in this.keys) - { - newKeys.Add(key); - } - - if (!newKeys.Contains(_key)) - newKeys.Add(_key); - - return new KeySet(newKeys); - } - - public KeySet Remove(Keys _key) - { - List newKeys = new List(); - - foreach (Keys key in this.keys) - { - if (key != _key) - { - newKeys.Add(key); - } - } - - return new KeySet(newKeys); - } - - public bool Equals(KeySet keySet) - { - foreach (Keys key in keySet.Keys) - { - if (!keys.Contains(key)) - { - return false; - } - } - - foreach (Keys key in this.keys) - { - if (!keySet.Keys.Contains(key)) - { - return false; - } - } - - return true; - } - - public override int GetHashCode() - { - if (this.keys.Count > 0) - { - return (int)this.keys[0]; - } - else - { - return 0; - } - } - - public override String ToString() - { - String result = ""; - - foreach (Keys key in this.keys) - { - result += key; - result += " "; - } - - return result; - } - } -} diff --git a/XenAdmin/Wizards/BugToolWizardFiles/BugToolPageDestination.cs b/XenAdmin/Wizards/BugToolWizardFiles/BugToolPageDestination.cs index 91b4ba9b49..03f8b497fc 100644 --- a/XenAdmin/Wizards/BugToolWizardFiles/BugToolPageDestination.cs +++ b/XenAdmin/Wizards/BugToolWizardFiles/BugToolPageDestination.cs @@ -38,6 +38,7 @@ using XenAdmin.Core; using XenAdmin.Dialogs; using XenCenterLib; +using XenModel; using Registry = XenAdmin.Core.Registry; @@ -206,9 +207,9 @@ private bool CheckPathValid(out string error) if (String.IsNullOrEmpty(name)) return false; - if (!PathValidator.IsFileNameValid(name)) + if (!PathValidator.IsFileNameValid(name, out string invalidNameMsg)) { - error = Messages.BUGTOOL_PAGE_DESTINATION_INVALID_NAME; + error = $"{Messages.BUGTOOL_PAGE_DESTINATION_INVALID_NAME} {invalidNameMsg}"; return false; } @@ -217,9 +218,9 @@ private bool CheckPathValid(out string error) string path = String.Format("{0}\\{1}", folder, name); - if (!PathValidator.IsPathValid(path)) + if (!PathValidator.IsPathValid(path, out string invalidPathMsg)) { - error = Messages.BUGTOOL_PAGE_DESTINATION_INVALID_FOLDER; + error = $"{Messages.BUGTOOL_PAGE_DESTINATION_INVALID_FOLDER} {invalidPathMsg}"; return false; } diff --git a/XenAdmin/Wizards/BugToolWizardFiles/GenericSelectHostsPage.cs b/XenAdmin/Wizards/BugToolWizardFiles/GenericSelectHostsPage.cs index 92df49d320..24ada42d02 100644 --- a/XenAdmin/Wizards/BugToolWizardFiles/GenericSelectHostsPage.cs +++ b/XenAdmin/Wizards/BugToolWizardFiles/GenericSelectHostsPage.cs @@ -32,6 +32,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using System.Windows.Forms; using XenAdmin.Controls; using XenAdmin.Core; @@ -121,11 +122,11 @@ public void SelectHosts(List selectedObjects) node.State = CheckState.Checked; } + var checkedItems = HostListTreeView.CheckedItems(); //focus on first checked item so the user can find it in a long list - foreach (var node in HostListTreeView.CheckedItems()) + if (checkedItems.Count > 0) { - HostListTreeView.SelectedItems.Add(node); - break; + HostListTreeView.SelectedItems.Add(checkedItems.First()); } HostListTreeView.EndUpdate(); diff --git a/XenAdmin/Wizards/DRWizards/DRFailoverWizardPrecheckPage.cs b/XenAdmin/Wizards/DRWizards/DRFailoverWizardPrecheckPage.cs index ad6bfc2596..2cba22231c 100644 --- a/XenAdmin/Wizards/DRWizards/DRFailoverWizardPrecheckPage.cs +++ b/XenAdmin/Wizards/DRWizards/DRFailoverWizardPrecheckPage.cs @@ -599,8 +599,8 @@ public PreCheckHeaderRow(string text) private class PreCheckItemRow : PreCheckGridRow { - private Problem _problem = null; - private Check _check = null; + private readonly Problem _problem; + private readonly Check _check; public PreCheckItemRow(Problem problem) { _problem = problem; diff --git a/XenAdmin/Wizards/DRWizards/DRFailoverWizardStoragePage.cs b/XenAdmin/Wizards/DRWizards/DRFailoverWizardStoragePage.cs index 7b4f4a0fd2..22864e8f3e 100644 --- a/XenAdmin/Wizards/DRWizards/DRFailoverWizardStoragePage.cs +++ b/XenAdmin/Wizards/DRWizards/DRFailoverWizardStoragePage.cs @@ -179,8 +179,8 @@ private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventAr var vdis = sr.Connection.ResolveAll(sr.VDIs); bool poolMetadataDetected = vdis.Any(vdi => vdi.type == vdi_type.metadata); - SrRow row; - if (!FindRowByUuid(sr.uuid, out row)) + var row = dataGridViewSRs.Rows.Cast().FirstOrDefault(r => r.SrUuid == sr.uuid); + if (row != null) { row = new SrRow(sr, poolMetadataDetected, SelectedSRsUuids.Contains(sr.uuid)); dataGridViewSRs.Rows.Add(row); @@ -192,8 +192,8 @@ private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventAr { foreach (var srInfo in scannedDevice.SRList) { - SrRow row; - if (!FindRowByUuid(srInfo.UUID, out row)) + var row = dataGridViewSRs.Rows.Cast().FirstOrDefault(r => r.SrUuid == srInfo.UUID); + if (row != null) { row = new SrRow(srInfo, scannedDevice.Type, srInfo.PoolMetadataDetected, SelectedSRsUuids.Contains(srInfo.UUID)); @@ -356,8 +356,9 @@ private void AddScanResultsToDataGridView(List metadataSrs, SR.SRType foreach (SR.SRInfo srInfo in metadataSrs) { - SrRow row; - if (!FindRowByUuid(srInfo.UUID, out row)) + var row = dataGridViewSRs.Rows.Cast().FirstOrDefault(r => r.SrUuid == srInfo.UUID); + + if (row != null) { row = new SrRow(srInfo, type, srInfo.PoolMetadataDetected, srInfo.PoolMetadataDetected); dataGridViewSRs.Rows.Add(row); @@ -618,17 +619,6 @@ private void ToggleRowChecked(SrRow row) OnPageUpdated(); } - private bool FindRowByUuid(string uuid, out SrRow row) - { - row = null; - foreach (var srRow in dataGridViewSRs.Rows.Cast().Where(srRow => srRow.SrUuid == uuid)) - { - row = srRow; - return true; - } - return false; - } - private void buttonSelectAll_Click(object sender, EventArgs e) { SelectAllRows(true); diff --git a/XenAdmin/Wizards/ExportWizard/ExportAppliancePage.cs b/XenAdmin/Wizards/ExportWizard/ExportAppliancePage.cs index 7f2ca33b9d..78823b63fd 100644 --- a/XenAdmin/Wizards/ExportWizard/ExportAppliancePage.cs +++ b/XenAdmin/Wizards/ExportWizard/ExportAppliancePage.cs @@ -36,6 +36,7 @@ using XenAdmin.Controls.Common; using XenAdmin.Wizards.ExportWizard.ApplianceChecks; using XenCenterLib; +using XenModel; namespace XenAdmin.Wizards.ExportWizard { @@ -166,9 +167,9 @@ private bool CheckPathValid(out string error) if (String.IsNullOrEmpty(ApplianceFileName)) return false; - if (!PathValidator.IsFileNameValid(ApplianceFileName)) + if (!PathValidator.IsFileNameValid(ApplianceFileName, out string invalidNameMsg)) { - error = Messages.EXPORT_APPLIANCE_PAGE_ERROR_INALID_APP; + error = string.Join(" ", new []{ Messages.EXPORT_APPLIANCE_PAGE_ERROR_INALID_APP , invalidNameMsg}); return false; } @@ -177,9 +178,9 @@ private bool CheckPathValid(out string error) string path = String.Format("{0}\\{1}", ApplianceDirectory, ApplianceFileName); - if (!PathValidator.IsPathValid(path)) + if (!PathValidator.IsPathValid(path, out string invalidPathMsg)) { - error = Messages.EXPORT_APPLIANCE_PAGE_ERROR_INVALID_DIR; + error = string.Join(" ", new[] { Messages.EXPORT_APPLIANCE_PAGE_ERROR_INVALID_DIR, invalidPathMsg }); return false; } diff --git a/XenAdmin/Wizards/ExportWizard/ExportOptionsPage.cs b/XenAdmin/Wizards/ExportWizard/ExportOptionsPage.cs index 60762d6323..b4e98b98c5 100644 --- a/XenAdmin/Wizards/ExportWizard/ExportOptionsPage.cs +++ b/XenAdmin/Wizards/ExportWizard/ExportOptionsPage.cs @@ -35,18 +35,18 @@ using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Windows.Forms; -using XenCenterLib; using XenOvf; using XenAdmin.Controls; +using XenModel; namespace XenAdmin.Wizards.ExportWizard { - /// - /// Class representing the page of the ExportAppliance wizard where the user specifies - /// whether to create a manifest, sign the appliance or encrypt files and whether to - /// create an OVA package or compress the OVF files - /// - internal partial class ExportOptionsPage : XenTabPage + /// + /// Class representing the page of the ExportAppliance wizard where the user specifies + /// whether to create a manifest, sign the appliance or encrypt files and whether to + /// create an OVA package or compress the OVF files + /// + internal partial class ExportOptionsPage : XenTabPage { private const int MIN_PASSWORD_STRENGTH = 1; private int m_passwordStrength; @@ -285,9 +285,9 @@ private bool CheckCertificatePathValid(out string error) { error = string.Empty; - if (!PathValidator.IsPathValid(m_textBoxCertificate.Text))//includes null check + if (!PathValidator.IsPathValid(m_textBoxCertificate.Text, out string invalidPathMsg))//includes null check { - error = Messages.EXPORT_SECURITY_PAGE_ERROR_INVALID_CERT; + error = string.Join(" ", new[] { Messages.EXPORT_SECURITY_PAGE_ERROR_INVALID_CERT, invalidPathMsg }); return false; } diff --git a/XenAdmin/Wizards/GenericPages/SelectMultipleVMDestinationPage.cs b/XenAdmin/Wizards/GenericPages/SelectMultipleVMDestinationPage.cs index 3f4d11e791..0688804fae 100755 --- a/XenAdmin/Wizards/GenericPages/SelectMultipleVMDestinationPage.cs +++ b/XenAdmin/Wizards/GenericPages/SelectMultipleVMDestinationPage.cs @@ -413,16 +413,17 @@ private void PopulateDataGridView(IEnableableXenObjectComboBoxItem selectedItem) { if (hasPoolSharedStorage) { - foreach (var pool in target.Item.Connection.Cache.Pools) + //there exists one pool per connection + var pools = target.Item.Connection.Cache.Pools; + if (pools.Length > 0) { + var pool = pools.First(); var item = new NoTargetServerPoolItem(pool); cb.Items.Add(item); if ((m_selectedObject != null && m_selectedObject.opaque_ref == pool.opaque_ref) || (target.Item.opaque_ref == pool.opaque_ref)) cb.Value = item; - - break; //there exists one pool per connection } } diff --git a/XenAdmin/Wizards/ImportWizard/ImageVMConfigPage.cs b/XenAdmin/Wizards/ImportWizard/ImageVMConfigPage.cs index 3bf250a90c..7913c452f8 100644 --- a/XenAdmin/Wizards/ImportWizard/ImageVMConfigPage.cs +++ b/XenAdmin/Wizards/ImportWizard/ImageVMConfigPage.cs @@ -32,7 +32,7 @@ using System; using XenAdmin.Controls; using XenCenterLib; - +using XenModel; namespace XenAdmin.Wizards.ImportWizard { @@ -55,17 +55,17 @@ public ImageVMConfigPage() /// /// Gets the page's title (headline) /// - public override string PageTitle { get { return Messages.IMAGE_DEFINITION_PAGE_TITLE; } } + public override string PageTitle => Messages.IMAGE_DEFINITION_PAGE_TITLE; /// /// Gets the page's label in the (left hand side) wizard progress panel /// - public override string Text { get { return Messages.IMAGE_DEFINITION_PAGE_TEXT; } } + public override string Text => Messages.IMAGE_DEFINITION_PAGE_TEXT; /// /// Gets the value by which the help files section for this page is identified /// - public override string HelpID { get { return "VMConfig"; } } + public override string HelpID => "VMConfig"; protected override bool ImplementsIsDirty() { @@ -97,16 +97,16 @@ public override bool EnableNext() #region Accessors - public bool IsWim { private get; set; } + public bool IsWim { internal get; set; } - public string VmName { get { return m_textBoxVMName.Text; } } + public string VmName => m_textBoxVMName.Text; - public ulong CpuCount { get { return (ulong)m_upDownCpuCount.Value; } } + public ulong CpuCount => (ulong)m_upDownCpuCount.Value; - public ulong Memory { get { return (ulong)m_upDownMemory.Value; } } + public ulong Memory => (ulong)m_upDownMemory.Value; + + public ulong AdditionalSpace => m_groupBoxAddSpace.Visible && m_groupBoxAddSpace.Enabled ? (ulong)m_upDownAddSpace.Value * GB : 0; - public ulong AdditionalSpace { get { return m_groupBoxAddSpace.Enabled ? (ulong)m_upDownAddSpace.Value * GB : 0; } } - #endregion #region Private Methods @@ -118,9 +118,10 @@ private bool CheckVmNameValid(string name, out string error) if (String.IsNullOrEmpty(name)) return false; - if (!PathValidator.IsFileNameValid(name)) + + if (!PathValidator.IsFileNameValid(name, out string invalidNameMsg)) { - error = Messages.IMPORT_SELECT_APPLIANCE_PAGE_ERROR_INVALID_PATH; + error = invalidNameMsg; return false; } return true; diff --git a/XenAdmin/Wizards/ImportWizard/ImportSourcePage.cs b/XenAdmin/Wizards/ImportWizard/ImportSourcePage.cs index 3816258b0b..2b3c484d3e 100644 --- a/XenAdmin/Wizards/ImportWizard/ImportSourcePage.cs +++ b/XenAdmin/Wizards/ImportWizard/ImportSourcePage.cs @@ -50,7 +50,7 @@ using XenOvf; using XenOvf.Definitions.VMC; using XenOvf.Utilities; - +using XenModel; namespace XenAdmin.Wizards.ImportWizard { @@ -370,21 +370,20 @@ private bool IsUri() /// private bool CheckPathValid(out string error) { - error = string.Empty; - + error = string.Empty; if (String.IsNullOrEmpty(FilePath)) return false; if (IsUri()) return CheckDownloadFromUri(out error); - if (!PathValidator.IsPathValid(FilePath)) + if (!PathValidator.IsPathValid(FilePath, out string invalidNameMsg)) { - error = Messages.IMPORT_SELECT_APPLIANCE_PAGE_ERROR_INVALID_PATH; - return false; + error = invalidNameMsg; + return false; } - - return true; + + return true; } /// diff --git a/XenAdmin/Wizards/ImportWizard/ImportWizard.cs b/XenAdmin/Wizards/ImportWizard/ImportWizard.cs index 084954b1d0..3d4c64dd8c 100644 --- a/XenAdmin/Wizards/ImportWizard/ImportWizard.cs +++ b/XenAdmin/Wizards/ImportWizard/ImportWizard.cs @@ -32,18 +32,18 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text.RegularExpressions; using XenAdmin.Actions; using XenAdmin.Actions.OvfActions; +using XenAdmin.Actions.VMActions; +using XenAdmin.Commands; using XenAdmin.Controls; using XenAdmin.Core; using XenAdmin.Mappings; using XenAdmin.Network; using XenAdmin.Wizards.GenericPages; using XenAPI; -using System.Linq; -using XenAdmin.Actions.VMActions; -using XenAdmin.Commands; using XenOvf; using XenOvf.Definitions; using XenOvf.Utilities; @@ -51,9 +51,9 @@ namespace XenAdmin.Wizards.ImportWizard { - internal partial class ImportWizard : XenWizardBase - { - #region Private fields + internal partial class ImportWizard : XenWizardBase + { + #region Private fields private readonly ImportSelectStoragePage m_pageStorage; private readonly ImportSelectNetworkPage m_pageNetwork; private readonly ImportSelectHostPage m_pageHost; @@ -71,64 +71,67 @@ internal partial class ImportWizard : XenWizardBase private readonly ImportBootOptionPage m_pageBootOptions; private IXenObject m_selectedObject; - private Dictionary m_vmMappings = new Dictionary(); - /// - /// Make this nullable and initialize with null so the pages are added correctly to the wizard progress the first time - /// - private ImportType? m_typeOfImport; - private bool m_ignoreAffinitySet; - private EnvelopeType m_envelopeFromVhd; - private IXenConnection TargetConnection { get; set; } - #endregion - - public ImportWizard(IXenConnection con, IXenObject xenObject, string filename, bool ovfModeOnly) - : base(con) - { - InitializeComponent(); - - m_pageStorage = new ImportSelectStoragePage(); - m_pageNetwork = new ImportSelectNetworkPage(); - m_pageHost = new ImportSelectHostPage(); - m_pageSecurity = new ImportSecurityPage(); - m_pageEula = new ImportEulaPage(); - m_pageOptions = new ImportOptionsPage(); - m_pageFinish = new ImportFinishPage(); - m_pageRbac = new RBACWarningPage(); - m_pageVMconfig = new ImageVMConfigPage(); - m_pageImportSource = new ImportSourcePage(); - m_pageXvaStorage = new StoragePickerPage(); - m_pageXvaNetwork = new NetworkPickerPage(); - m_pageXvaHost = new GlobalSelectHost(); + private Dictionary m_vmMappings = new Dictionary(); + /// + /// Make this nullable and initialize with null so the pages are added correctly to the wizard progress the first time + /// + private ImportType? m_typeOfImport; + private bool m_ignoreAffinitySet; + private EnvelopeType m_envelopeFromVhd; + private Package _selectedOvfPackage; + private string _selectedImagePath; + private Host _selectedAffinity; + private IXenConnection _targetConnection; + #endregion + + public ImportWizard(IXenConnection con, IXenObject xenObject, string filename, bool ovfModeOnly = false) + : base(con) + { + InitializeComponent(); + + m_pageStorage = new ImportSelectStoragePage(); + m_pageNetwork = new ImportSelectNetworkPage(); + m_pageHost = new ImportSelectHostPage(); + m_pageSecurity = new ImportSecurityPage(); + m_pageEula = new ImportEulaPage(); + m_pageOptions = new ImportOptionsPage(); + m_pageFinish = new ImportFinishPage(); + m_pageRbac = new RBACWarningPage(); + m_pageVMconfig = new ImageVMConfigPage(); + m_pageImportSource = new ImportSourcePage(); + m_pageXvaStorage = new StoragePickerPage(); + m_pageXvaNetwork = new NetworkPickerPage(); + m_pageXvaHost = new GlobalSelectHost(); lunPerVdiMappingPage = new LunPerVdiImportPage { Connection = con }; - m_pageBootOptions = new ImportBootOptionPage(); + m_pageBootOptions = new ImportBootOptionPage(); - m_selectedObject = xenObject; - m_pageFinish.SummaryRetriever = GetSummary; - m_pageXvaStorage.ImportVmCompleted += m_pageXvaStorage_ImportVmCompleted; + m_selectedObject = xenObject; + m_pageFinish.SummaryRetriever = GetSummary; + m_pageXvaStorage.ImportVmCompleted += m_pageXvaStorage_ImportVmCompleted; - if (!string.IsNullOrEmpty(filename)) - m_pageImportSource.SetFileName(filename); + if (!string.IsNullOrEmpty(filename)) + m_pageImportSource.SetFileName(filename); - m_pageImportSource.OvfModeOnly = ovfModeOnly; + m_pageImportSource.OvfModeOnly = ovfModeOnly; AddPages(m_pageImportSource, m_pageHost, m_pageStorage, m_pageNetwork, m_pageFinish); m_pageHost.ConnectionSelectionChanged += pageHost_ConnectionSelectionChanged; m_pageXvaHost.ConnectionSelectionChanged += pageHost_ConnectionSelectionChanged; ShowXenAppXenDesktopWarning(con); - } + } - #region Override (XenWizardBase) Methods + #region Override (XenWizardBase) Methods protected override void FinishWizard() - { - switch (m_typeOfImport) - { - case ImportType.Xva: - if (m_pageXvaStorage.ImportXvaAction != null) - m_pageXvaStorage.ImportXvaAction.EndWizard(m_pageFinish.StartVmsAutomatically, m_pageXvaNetwork.VIFs); - break; - case ImportType.Ovf: - new ImportApplianceAction(TargetConnection, + { + switch (m_typeOfImport) + { + case ImportType.Xva: + if (m_pageXvaStorage.ImportXvaAction != null) + m_pageXvaStorage.ImportXvaAction.EndWizard(m_pageFinish.StartVmsAutomatically, m_pageXvaNetwork.VIFs); + break; + case ImportType.Ovf: + new ImportApplianceAction(_targetConnection, m_pageImportSource.SelectedOvfPackage, m_vmMappings, m_pageSecurity.VerifyManifest, @@ -137,9 +140,9 @@ protected override void FinishWizard() m_pageOptions.RunFixups, m_pageOptions.SelectedIsoSR, m_pageFinish.StartVmsAutomatically).RunAsync(); - break; - case ImportType.Vhd: - new ImportImageAction(TargetConnection, + break; + case ImportType.Vhd: + new ImportImageAction(_targetConnection, m_envelopeFromVhd, Path.GetDirectoryName(m_pageImportSource.FilePath), m_vmMappings, @@ -148,180 +151,271 @@ protected override void FinishWizard() m_pageFinish.StartVmsAutomatically, VMOperationCommand.WarningDialogHAInvalidConfig, VMOperationCommand.StartDiagnosisForm).RunAsync(); - break; - } + break; + } - base.FinishWizard(); - } + base.FinishWizard(); + } - protected override void OnCancel(ref bool cancel) - { - base.OnCancel(ref cancel); + protected override void OnCancel(ref bool cancel) + { + base.OnCancel(ref cancel); - if (cancel) - return; + if (cancel) + return; - if (m_pageXvaStorage.ImportXvaAction != null) - { - m_pageXvaStorage.ImportXvaAction.EndWizard(false, null); - m_pageXvaStorage.ImportXvaAction.Cancel(); - } - } + if (m_pageXvaStorage.ImportXvaAction != null) + { + m_pageXvaStorage.ImportXvaAction.EndWizard(false, null); + m_pageXvaStorage.ImportXvaAction.Cancel(); + } + } protected override void UpdateWizardContent(XenTabPage page) - { - Type type = page.GetType(); + { + var type = page.GetType(); - if (type == typeof(ImportSourcePage)) - { - #region ImportSourcePage + if (type == typeof(ImportSourcePage)) + { + var oldTypeOfImport = m_typeOfImport; //store previous type + m_typeOfImport = m_pageImportSource.TypeOfImport; - var oldTypeOfImport = m_typeOfImport;//store previous type - m_typeOfImport = m_pageImportSource.TypeOfImport; - var appliancePages = new XenTabPage[] {m_pageEula, m_pageHost, m_pageStorage, m_pageNetwork, m_pageSecurity, m_pageOptions}; + var appliancePages = new XenTabPage[] { m_pageEula, m_pageHost, m_pageStorage, m_pageNetwork, m_pageSecurity, m_pageOptions }; var imagePages = new XenTabPage[] { m_pageVMconfig, m_pageHost, m_pageStorage, m_pageNetwork, m_pageOptions }; var xvaPages = new XenTabPage[] { m_pageXvaHost, m_pageXvaStorage, m_pageXvaNetwork }; - switch (m_typeOfImport) - { - case ImportType.Ovf: - if (oldTypeOfImport != ImportType.Ovf) - { - Text = Messages.WIZARD_TEXT_IMPORT_OVF; - pictureBoxWizard.Image = Images.StaticImages._000_ImportVirtualAppliance_h32bit_32; + switch (m_typeOfImport) + { + case ImportType.Ovf: + if (oldTypeOfImport != ImportType.Ovf) + { + Text = Messages.WIZARD_TEXT_IMPORT_OVF; + pictureBoxWizard.Image = Images.StaticImages._000_ImportVirtualAppliance_h32bit_32; RemovePages(imagePages); RemovePage(m_pageBootOptions); RemovePages(xvaPages); AddAfterPage(m_pageImportSource, appliancePages); - } - - m_pageEula.SelectedOvfEnvelope = m_pageImportSource.SelectedOvfPackage.OvfEnvelope; - m_pageSecurity.SelectedOvfPackage = m_pageImportSource.SelectedOvfPackage; - - CheckDisabledPages(m_pageEula, m_pageSecurity); //decide whether to disable these progress steps - ResetVmMappings(m_pageImportSource.SelectedOvfPackage.OvfEnvelope); - m_pageHost.SelectedOvfEnvelope = m_pageImportSource.SelectedOvfPackage.OvfEnvelope; - m_pageHost.SetDefaultTarget(m_pageHost.ChosenItem ?? m_selectedObject); - m_pageHost.VmMappings = m_vmMappings; - m_pageStorage.SelectedOvfEnvelope = m_pageImportSource.SelectedOvfPackage.OvfEnvelope; - lunPerVdiMappingPage.SelectedOvfEnvelope = m_pageImportSource.SelectedOvfPackage.OvfEnvelope; - m_pageNetwork.SelectedOvfEnvelope = m_pageImportSource.SelectedOvfPackage.OvfEnvelope; - - NotifyNextPagesOfChange(m_pageEula, m_pageHost, m_pageStorage, m_pageNetwork, m_pageSecurity, m_pageOptions); - break; - case ImportType.Vhd: - if (oldTypeOfImport != ImportType.Vhd) - { - Text = Messages.WIZARD_TEXT_IMPORT_VHD; - pictureBoxWizard.Image = Images.StaticImages._000_ImportVM_h32bit_32; + } + + var oldSelectedOvfPackage = _selectedOvfPackage; + _selectedOvfPackage = m_pageImportSource.SelectedOvfPackage; + + if (oldTypeOfImport != ImportType.Ovf || oldSelectedOvfPackage != _selectedOvfPackage) + { + m_pageEula.SelectedOvfEnvelope = _selectedOvfPackage.OvfEnvelope; + m_pageSecurity.SelectedOvfPackage = _selectedOvfPackage; + CheckDisabledPages(m_pageEula, m_pageSecurity); //decide whether to disable these progress steps + + m_vmMappings.Clear(); + string[] sysIds = OVF.FindSystemIds(_selectedOvfPackage.OvfEnvelope); + foreach (string sysId in sysIds) + m_vmMappings.Add(sysId, new VmMapping {VmNameLabel = FindVMName(_selectedOvfPackage.OvfEnvelope, sysId)}); + + m_pageHost.SelectedOvfEnvelope = _selectedOvfPackage.OvfEnvelope; + m_pageHost.SetDefaultTarget(m_pageHost.ChosenItem ?? m_selectedObject); + m_pageHost.VmMappings = m_vmMappings; + m_pageStorage.SelectedOvfEnvelope = _selectedOvfPackage.OvfEnvelope; + lunPerVdiMappingPage.SelectedOvfEnvelope = _selectedOvfPackage.OvfEnvelope; + m_pageNetwork.SelectedOvfEnvelope = _selectedOvfPackage.OvfEnvelope; + + NotifyNextPagesOfChange(m_pageEula, m_pageHost, m_pageStorage, m_pageNetwork, m_pageSecurity, m_pageOptions); + } + break; + case ImportType.Vhd: + if (oldTypeOfImport != ImportType.Vhd) + { + Text = Messages.WIZARD_TEXT_IMPORT_VHD; + pictureBoxWizard.Image = Images.StaticImages._000_ImportVM_h32bit_32; RemovePages(appliancePages); RemovePages(xvaPages); AddAfterPage(m_pageImportSource, imagePages); - } - m_pageVMconfig.IsWim = m_pageImportSource.IsWIM; - m_pageHost.SetDefaultTarget(m_pageHost.ChosenItem ?? m_selectedObject); - m_pageHost.SelectedOvfEnvelope = null; - m_pageHost.VmMappings = m_vmMappings; - NotifyNextPagesOfChange(m_pageVMconfig, m_pageHost, m_pageStorage, m_pageNetwork, m_pageOptions); - break; - case ImportType.Xva: - if (oldTypeOfImport != ImportType.Xva) - { - Text = Messages.WIZARD_TEXT_IMPORT_XVA; - pictureBoxWizard.Image = Images.StaticImages._000_ImportVM_h32bit_32; + + //if _targetConnection=null, i.e. we haven't selected a connection yet, do not add the page + if (_targetConnection != null && BootModesControl.ShowBootModeOptions(_targetConnection)) + AddAfterPage(m_pageNetwork, m_pageBootOptions); + } + + var oldSelectedImagePath = _selectedImagePath; + _selectedImagePath = m_pageImportSource.FilePath; + + if (oldTypeOfImport != ImportType.Vhd || oldSelectedImagePath != _selectedImagePath) + { + m_vmMappings.Clear(); + m_pageVMconfig.IsWim = m_pageImportSource.IsWIM; + NotifyNextPagesOfChange(m_pageVMconfig, m_pageHost, m_pageStorage, m_pageNetwork, m_pageOptions); + } + break; + case ImportType.Xva: + if (oldTypeOfImport != ImportType.Xva) + { + Text = Messages.WIZARD_TEXT_IMPORT_XVA; + pictureBoxWizard.Image = Images.StaticImages._000_ImportVM_h32bit_32; RemovePages(imagePages); - RemovePage(m_pageBootOptions); + RemovePage(m_pageBootOptions); RemovePages(appliancePages); AddAfterPage(m_pageImportSource, xvaPages); - } - m_pageXvaHost.SetDefaultTarget(m_selectedObject); - m_pageXvaStorage.FilePath = m_pageImportSource.FilePath; - break; - } - - #endregion - } - else if (type == typeof(ImageVMConfigPage)) - { - //then use it to create an ovf for the import - - m_envelopeFromVhd = OVF.CreateOvfEnvelope(m_pageVMconfig.VmName, - m_pageVMconfig.CpuCount, m_pageVMconfig.Memory, - m_pageBootOptions.BootParams, m_pageBootOptions.PlatformSettings, - m_pageImportSource.DiskCapacity, m_pageImportSource.IsWIM, m_pageVMconfig.AdditionalSpace, - m_pageImportSource.FilePath, m_pageImportSource.ImageLength, BrandManager.ProductBrand); - - m_pageStorage.SelectedOvfEnvelope = m_envelopeFromVhd; - lunPerVdiMappingPage.SelectedOvfEnvelope = m_envelopeFromVhd; - m_pageNetwork.SelectedOvfEnvelope = m_envelopeFromVhd; - ResetVmMappings(m_envelopeFromVhd); - NotifyNextPagesOfChange(m_pageHost, m_pageStorage, m_pageNetwork); - } - else if (type == typeof(ImportSelectHostPage)) - { - TargetConnection = m_pageHost.ChosenItem == null ? null : m_pageHost.ChosenItem.Connection; - RemovePage(m_pageRbac); - ConfigureRbacPage(TargetConnection); - m_vmMappings = m_pageHost.VmMappings; - m_pageStorage.VmMappings = m_vmMappings; - m_pageStorage.Connection = TargetConnection; - m_pageNetwork.Connection = TargetConnection; - m_pageOptions.Connection = TargetConnection; - RemovePage(m_pageBootOptions); - if (m_typeOfImport == ImportType.Vhd && BootModesControl.ShowBootModeOptions(TargetConnection)) - { - AddAfterPage(m_pageNetwork, m_pageBootOptions); - m_pageBootOptions.Connection = TargetConnection; - } - m_pageBootOptions.Connection = TargetConnection; - NotifyNextPagesOfChange(m_pageStorage, m_pageNetwork, m_pageOptions); - } - else if (type == typeof(ImportSelectStoragePage)) - { - RemovePage(lunPerVdiMappingPage); - lunPerVdiMappingPage.ClearPickerData(); - m_vmMappings = m_pageStorage.VmMappings; - m_pageNetwork.VmMappings = m_vmMappings; + } + m_pageXvaHost.SetDefaultTarget(m_selectedObject); + m_pageXvaStorage.FilePath = m_pageImportSource.FilePath; + break; + } + } + else if (type == typeof(ImageVMConfigPage)) + { + var newMapping = new VmMapping + { + VmNameLabel = m_pageVMconfig.VmName, + CpuCount = m_pageVMconfig.CpuCount, + Capacity = m_pageImportSource.DiskCapacity + m_pageVMconfig.AdditionalSpace, + Memory = m_pageVMconfig.Memory, + BootParams = m_pageBootOptions.BootParams, + PlatformSettings = m_pageBootOptions.PlatformSettings + }; + + var oldMapping = m_vmMappings.Values.FirstOrDefault(); + if (oldMapping != null) + { + newMapping.XenRef = oldMapping.XenRef; + newMapping.TargetName = oldMapping.TargetName; + newMapping.Storage = oldMapping.Storage; + newMapping.StorageToAttach = oldMapping.StorageToAttach; + newMapping.Networks = oldMapping.Networks; + } + + if (!newMapping.Equals(oldMapping)) + { + m_envelopeFromVhd = OVF.CreateOvfEnvelope(newMapping.VmNameLabel, + newMapping.CpuCount, newMapping.Memory, + newMapping.BootParams, newMapping.PlatformSettings, + newMapping.Capacity, + m_pageImportSource.FilePath, m_pageImportSource.ImageLength, BrandManager.ProductBrand); + + m_vmMappings.Clear(); + var sysId = OVF.FindSystemIds(m_envelopeFromVhd).First(); + m_vmMappings.Add(sysId, newMapping); + + m_pageHost.VmMappings = m_vmMappings; + m_pageHost.SetDefaultTarget(m_pageHost.ChosenItem ?? m_selectedObject); + + m_pageHost.SelectedOvfEnvelope = m_envelopeFromVhd; + m_pageStorage.SelectedOvfEnvelope = m_envelopeFromVhd; + lunPerVdiMappingPage.SelectedOvfEnvelope = m_envelopeFromVhd; + m_pageNetwork.SelectedOvfEnvelope = m_envelopeFromVhd; + + NotifyNextPagesOfChange(m_pageHost, lunPerVdiMappingPage, m_pageStorage, m_pageNetwork); + } + } + else if (type == typeof(ImportSelectHostPage)) + { + var oldTargetConnection = _targetConnection; + _targetConnection = m_pageHost.ChosenItem?.Connection; + var oldVmMappings = m_vmMappings; + m_vmMappings = m_pageHost.VmMappings; + + if (oldTargetConnection != _targetConnection) + { + RemovePage(m_pageRbac); + ConfigureRbacPage(_targetConnection); + + RemovePage(m_pageBootOptions); + if (m_typeOfImport == ImportType.Vhd && BootModesControl.ShowBootModeOptions(_targetConnection)) + AddAfterPage(m_pageNetwork, m_pageBootOptions); + } + + m_pageStorage.VmMappings = m_vmMappings; + m_pageStorage.Connection = _targetConnection; + m_pageNetwork.Connection = _targetConnection; + m_pageOptions.Connection = _targetConnection; + m_pageBootOptions.Connection = _targetConnection; + + if (oldTargetConnection != _targetConnection || oldVmMappings != m_vmMappings) + NotifyNextPagesOfChange(m_pageStorage, m_pageNetwork, m_pageOptions); + } + else if (type == typeof(ImportBootOptionPage)) + { + var oldMapping = m_vmMappings.Values.First(); + + if (oldMapping.BootParams != m_pageBootOptions.BootParams || + oldMapping.PlatformSettings != m_pageBootOptions.PlatformSettings) + { + string systemId = null; + if (m_envelopeFromVhd.Item is VirtualSystem_Type vs) + systemId = vs.id; + else if (m_envelopeFromVhd.Item is VirtualSystemCollection_Type vsc) + systemId = vsc.Content.FirstOrDefault()?.id; + + if (oldMapping.BootParams != m_pageBootOptions.BootParams) + { + m_envelopeFromVhd = OVF.UpdateBootParams(m_envelopeFromVhd, systemId, m_pageBootOptions.BootParams); + m_vmMappings.Values.First().BootParams = m_pageBootOptions.BootParams; + } + + if (oldMapping.PlatformSettings != m_pageBootOptions.PlatformSettings) + { + m_envelopeFromVhd = OVF.UpdatePlatform(m_envelopeFromVhd, systemId, m_pageBootOptions.PlatformSettings); + m_vmMappings.Values.First().PlatformSettings = m_pageBootOptions.PlatformSettings; + } + } + + m_pageStorage.SelectedOvfEnvelope = m_envelopeFromVhd; + lunPerVdiMappingPage.SelectedOvfEnvelope = m_envelopeFromVhd; + m_pageNetwork.SelectedOvfEnvelope = m_envelopeFromVhd; + } + else if (type == typeof(ImportSelectStoragePage)) + { + RemovePage(lunPerVdiMappingPage); + lunPerVdiMappingPage.ClearPickerData(); + m_vmMappings = m_pageStorage.VmMappings; + m_pageNetwork.VmMappings = m_vmMappings; lunPerVdiMappingPage.VmMappings = m_vmMappings; - if (lunPerVdiMappingPage.IsAnyPickerDataMappable + if (lunPerVdiMappingPage.IsAnyPickerDataMappable && lunPerVdiMappingPage.MapLunsToVdisRequired && m_typeOfImport == ImportType.Ovf) AddAfterPage(m_pageStorage, lunPerVdiMappingPage); - } + } else if (type == typeof(LunPerVdiImportPage)) { m_vmMappings = lunPerVdiMappingPage.VmMappings; m_pageNetwork.VmMappings = m_vmMappings; } - else if (type == typeof(ImportSelectNetworkPage)) - { - m_vmMappings = m_pageNetwork.VmMappings; - m_pageOptions.VmMappings = m_vmMappings; - } - else if (type == typeof(GlobalSelectHost)) - { - var con = m_pageXvaHost.SelectedHost == null ? m_pageXvaHost.SelectedConnection : m_pageXvaHost.SelectedHost.Connection; - RemovePage(m_pageRbac); - ConfigureRbacPage(con); - - m_pageXvaStorage.SetConnection(con); - m_pageXvaStorage.SetTargetHost(m_ignoreAffinitySet ? null : m_pageXvaHost.SelectedHost); - - m_pageXvaNetwork.SetConnection(con); - m_pageXvaNetwork.SetAffinity(m_pageXvaHost.SelectedHost); - - NotifyNextPagesOfChange(m_pageXvaStorage, m_pageXvaNetwork); - } - else if (type == typeof(StoragePickerPage)) - { - m_pageFinish.ShowStartVmsGroupBox = m_pageXvaStorage.ImportedVm != null && !m_pageXvaStorage.ImportedVm.is_a_template; - m_pageXvaNetwork.SetVm(m_pageXvaStorage.ImportedVm); - NotifyNextPagesOfChange(m_pageXvaNetwork); - } - - if (type != typeof(ImportFinishPage)) - NotifyNextPagesOfChange(m_pageFinish); - } + else if (type == typeof(ImportSelectNetworkPage)) + { + m_vmMappings = m_pageNetwork.VmMappings; + m_pageOptions.VmMappings = m_vmMappings; + } + else if (type == typeof(GlobalSelectHost)) + { + var oldSelectedAffinity = _selectedAffinity; + _selectedAffinity = m_pageXvaHost.SelectedHost; + var oldTargetConnection = _targetConnection; + _targetConnection = _selectedAffinity == null ? m_pageXvaHost.SelectedConnection : _selectedAffinity.Connection; + + if (oldTargetConnection != _targetConnection) + { + RemovePage(m_pageRbac); + ConfigureRbacPage(_targetConnection); + } + + m_pageXvaStorage.TargetConnection = _targetConnection; + m_pageXvaStorage.TargetHost = m_ignoreAffinitySet ? null : _selectedAffinity; + + m_pageXvaNetwork.SelectedConnection = _targetConnection; + m_pageXvaNetwork.SelectedAffinity = _selectedAffinity; + + if (oldTargetConnection != _targetConnection || + oldSelectedAffinity != null && _selectedAffinity != null && oldSelectedAffinity.opaque_ref != _selectedAffinity.opaque_ref) + NotifyNextPagesOfChange(m_pageXvaStorage, m_pageXvaNetwork); + } + else if (type == typeof(StoragePickerPage)) + { + m_pageFinish.ShowStartVmsGroupBox = m_pageXvaStorage.ImportedVm != null && !m_pageXvaStorage.ImportedVm.is_a_template; + m_pageXvaNetwork.VM = m_pageXvaStorage.ImportedVm; + NotifyNextPagesOfChange(m_pageXvaNetwork); + } + + if (type != typeof(ImportFinishPage)) + NotifyNextPagesOfChange(m_pageFinish); + } protected override string WizardPaneHelpID() { @@ -395,9 +489,9 @@ protected override string WizardPaneHelpID() return base.WizardPaneHelpID(); } - #endregion + #endregion - #region Private methods + #region Private methods private void ConfigureRbacPage(IXenConnection selectedConnection) { @@ -405,32 +499,32 @@ private void ConfigureRbacPage(IXenConnection selectedConnection) return; } - m_ignoreAffinitySet = false; + m_ignoreAffinitySet = false; - switch (m_typeOfImport) - { - case ImportType.Ovf: - case ImportType.Vhd: - { - var check = m_typeOfImport == ImportType.Ovf - ? new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_APPLIANCE) {Blocking = true} - : new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_IMAGE) {Blocking = true}; - check.AddApiMethods(ApplianceAction.StaticRBACDependencies); - m_pageRbac.SetPermissionChecks(selectedConnection, check); + switch (m_typeOfImport) + { + case ImportType.Ovf: + case ImportType.Vhd: + { + var check = m_typeOfImport == ImportType.Ovf + ? new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_APPLIANCE) {Blocking = true} + : new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_IMAGE) {Blocking = true}; + check.AddApiMethods(ApplianceAction.StaticRBACDependencies); + m_pageRbac.SetPermissionChecks(selectedConnection, check); AddAfterPage(m_pageHost, m_pageRbac); - } - break; - case ImportType.Xva: - { - //Check to see if they can import VMs at all - var importCheck = new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_XVA) {Blocking = true}; - importCheck.AddApiMethods(ImportVmAction.ConstantRBACRequirements); + } + break; + case ImportType.Xva: + { + //Check to see if they can import VMs at all + var importCheck = new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_XVA) {Blocking = true}; + importCheck.AddApiMethods(ImportVmAction.ConstantRBACRequirements); importCheck.AddApiMethods("sr.scan");//CA-337323 - //Check to see if they can set the VM's affinity - var affinityCheck = new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_AFFINITY); - affinityCheck.AddApiMethods("vm.set_affinity"); + //Check to see if they can set the VM's affinity + var affinityCheck = new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_AFFINITY); + affinityCheck.AddApiMethods("vm.set_affinity"); affinityCheck.WarningAction = () => { //We cannot allow them to set the affinity, so we are only going @@ -439,167 +533,150 @@ private void ConfigureRbacPage(IXenConnection selectedConnection) }; m_pageRbac.SetPermissionChecks(selectedConnection, importCheck, affinityCheck); AddAfterPage(m_pageXvaHost, m_pageRbac); - } - break; - } + } + break; + } - //set page Connection after the page has been added to the wizard - //(because the Connection is reset when the page is added - m_pageRbac.Connection = selectedConnection; - } + //set page Connection after the page has been added to the wizard + //(because the Connection is reset when the page is added + m_pageRbac.Connection = selectedConnection; + } private void CheckDisabledPages(params XenTabPage[] pages) - { - foreach (var p in pages) - p.CheckPageDisabled(); - } - - protected override IEnumerable GetSummary() - { - switch (m_typeOfImport) - { - case ImportType.Xva: - return GetSummaryXva(); - case ImportType.Ovf: - return GetSummaryOvf(); - case ImportType.Vhd: - return GetSummaryVhd(); - default: - return new List(); - } - } - - private IEnumerable GetSummaryXva() - { - var temp = new List(); - temp.Add(new Tuple(Messages.FINISH_PAGE_VMNAME, m_pageXvaStorage.ImportedVm.Name())); - temp.Add(new Tuple(Messages.FINISH_PAGE_TARGET, m_pageXvaHost.SelectedHost == null ? m_pageXvaHost.SelectedConnection.Name : m_pageXvaHost.SelectedHost.Name())); - temp.Add(new Tuple(Messages.FINISH_PAGE_STORAGE, m_pageXvaStorage.SR.Name())); - - var con = m_pageXvaHost.SelectedHost == null ? m_pageXvaHost.SelectedConnection : m_pageXvaHost.SelectedHost.Connection; - - bool first = true; - foreach (var vif in m_pageXvaNetwork.VIFs) - { - var netref = new XenRef(vif.network); - var network = con.Resolve(netref); - // CA-218956 - Expose HIMN when showing hidden objects - if (network == null || (network.IsGuestInstallerNetwork() && !XenAdmin.Properties.Settings.Default.ShowHiddenVMs)) - continue; - - temp.Add(new Tuple(first ? Messages.FINISH_PAGE_NETWORK : "", network.Name())); - first = false; - } - - return temp; - } - - private IEnumerable GetSummaryOvf() - { - var temp = new List(); - - var appName = m_pageImportSource.SelectedOvfPackage.Name; - temp.Add(new Tuple(Messages.FINISH_PAGE_REVIEW_APPLIANCE, appName)); - temp.Add(new Tuple(Messages.FINISH_PAGE_VERIFY_MANIFEST, m_pageSecurity.VerifyManifest.ToYesNoStringI18n())); - temp.Add(new Tuple(Messages.FINISH_PAGE_VERIFY_SIGNATURE, m_pageSecurity.VerifySignature.ToYesNoStringI18n())); - - temp.Add(new Tuple(Messages.FINISH_PAGE_RUN_FIXUPS, m_pageOptions.RunFixups.ToYesNoStringI18n())); - if (m_pageOptions.RunFixups) - temp.Add(new Tuple(Messages.FINISH_PAGE_ISOSR, m_pageOptions.SelectedIsoSR.Name())); - - temp.AddRange(GetVmMappingsSummary()); - return temp; - } - - private IEnumerable GetSummaryVhd() - { - var temp = new List(); - temp.Add(new Tuple(Messages.FINISH_PAGE_IMAGEPATH, m_pageImportSource.FilePath)); - temp.Add(new Tuple(Messages.FINISH_PAGE_VMNAME, m_pageVMconfig.VmName)); - temp.Add(new Tuple(Messages.FINISH_PAGE_CPUCOUNT, m_pageVMconfig.CpuCount.ToString())); - temp.Add(new Tuple(Messages.FINISH_PAGE_MEMORY, string.Format(Messages.VAL_MB, m_pageVMconfig.Memory))); - if (Helpers.NaplesOrGreater(TargetConnection)) - temp.Add(new Tuple(Messages.BOOT_MODE, m_pageBootOptions.SelectedBootMode.StringOf())); - - if (m_pageImportSource.IsWIM) - temp.Add(new Tuple(Messages.FINISH_PAGE_ADDSPACE, Util.DiskSizeString(m_pageVMconfig.AdditionalSpace))); - - temp.Add(new Tuple(Messages.FINISH_PAGE_RUN_FIXUPS, m_pageOptions.RunFixups.ToYesNoStringI18n())); - if (m_pageOptions.RunFixups) - temp.Add(new Tuple(Messages.FINISH_PAGE_ISOSR, m_pageOptions.SelectedIsoSR.Name())); - - temp.AddRange(GetVmMappingsSummary()); - return temp; - } - - private IEnumerable GetVmMappingsSummary() - { - var temp = new List(); - - foreach (var mapping in m_vmMappings.Values) - { - var targetLbl = m_vmMappings.Count == 1 ? Messages.FINISH_PAGE_TARGET : string.Format(Messages.FINISH_PAGE_TARGET_FOR_VM, mapping.VmNameLabel); - var storageLbl = m_vmMappings.Count == 1 ? Messages.FINISH_PAGE_STORAGE : string.Format(Messages.FINISH_PAGE_STORAGE_FOR_VM, mapping.VmNameLabel); - var networkLbl = m_vmMappings.Count == 1 ? Messages.FINISH_PAGE_NETWORK : string.Format(Messages.FINISH_PAGE_NETWORK_FOR_VM, mapping.VmNameLabel); - - temp.Add(new Tuple(targetLbl, mapping.TargetName)); - bool first = true; - foreach (var sr in mapping.Storage) - { - temp.Add(new Tuple(first ? storageLbl : "", sr.Value.Name())); - first = false; - } - - first = true; - foreach (var net in mapping.Networks) - { - temp.Add(new Tuple(first ? networkLbl : "", net.Value.Name())); - first = false; - } - } - return temp; - } - - private void ResetVmMappings(EnvelopeType ovfEnvelope) - { - string[] sysIds = OVF.FindSystemIds(ovfEnvelope); - m_vmMappings.Clear(); - - foreach (string sysId in sysIds) - { - var vmMap = new VmMapping - { - VmNameLabel = (m_typeOfImport == ImportType.Ovf) - ? FindVMName(ovfEnvelope, sysId) - : m_pageVMconfig.VmName //it should only iterate once - }; - m_vmMappings.Add(sysId, vmMap); - } - } - - private bool IsGUID(string expression) - { - if (expression != null) - { - Regex guidRegEx = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$"); - - return guidRegEx.IsMatch(expression); - } - return false; - } + { + foreach (var p in pages) + p.CheckPageDisabled(); + } + + protected override IEnumerable GetSummary() + { + switch (m_typeOfImport) + { + case ImportType.Xva: + return GetSummaryXva(); + case ImportType.Ovf: + return GetSummaryOvf(); + case ImportType.Vhd: + return GetSummaryVhd(); + default: + return new List(); + } + } + + private IEnumerable GetSummaryXva() + { + var temp = new List(); + temp.Add(new Tuple(Messages.FINISH_PAGE_VMNAME, m_pageXvaStorage.ImportedVm.Name())); + temp.Add(new Tuple(Messages.FINISH_PAGE_TARGET, m_pageXvaHost.SelectedHost == null ? m_pageXvaHost.SelectedConnection.Name : m_pageXvaHost.SelectedHost.Name())); + temp.Add(new Tuple(Messages.FINISH_PAGE_STORAGE, m_pageXvaStorage.SR.Name())); + + var con = m_pageXvaHost.SelectedHost == null ? m_pageXvaHost.SelectedConnection : m_pageXvaHost.SelectedHost.Connection; + + bool first = true; + foreach (var vif in m_pageXvaNetwork.VIFs) + { + var netref = new XenRef(vif.network); + var network = con.Resolve(netref); + // CA-218956 - Expose HIMN when showing hidden objects + if (network == null || (network.IsGuestInstallerNetwork() && !XenAdmin.Properties.Settings.Default.ShowHiddenVMs)) + continue; + + temp.Add(new Tuple(first ? Messages.FINISH_PAGE_NETWORK : "", network.Name())); + first = false; + } + + return temp; + } + + private IEnumerable GetSummaryOvf() + { + var temp = new List(); + + var appName = m_pageImportSource.SelectedOvfPackage.Name; + temp.Add(new Tuple(Messages.FINISH_PAGE_REVIEW_APPLIANCE, appName)); + temp.Add(new Tuple(Messages.FINISH_PAGE_VERIFY_MANIFEST, m_pageSecurity.VerifyManifest.ToYesNoStringI18n())); + temp.Add(new Tuple(Messages.FINISH_PAGE_VERIFY_SIGNATURE, m_pageSecurity.VerifySignature.ToYesNoStringI18n())); + + temp.Add(new Tuple(Messages.FINISH_PAGE_RUN_FIXUPS, m_pageOptions.RunFixups.ToYesNoStringI18n())); + if (m_pageOptions.RunFixups) + temp.Add(new Tuple(Messages.FINISH_PAGE_ISOSR, m_pageOptions.SelectedIsoSR.Name())); + + temp.AddRange(GetVmMappingsSummary()); + return temp; + } + + private IEnumerable GetSummaryVhd() + { + var temp = new List(); + temp.Add(new Tuple(Messages.FINISH_PAGE_IMAGEPATH, m_pageImportSource.FilePath)); + temp.Add(new Tuple(Messages.FINISH_PAGE_VMNAME, m_pageVMconfig.VmName)); + temp.Add(new Tuple(Messages.FINISH_PAGE_CPUCOUNT, m_pageVMconfig.CpuCount.ToString())); + temp.Add(new Tuple(Messages.FINISH_PAGE_MEMORY, string.Format(Messages.VAL_MB, m_pageVMconfig.Memory))); + if (Helpers.NaplesOrGreater(_targetConnection)) + temp.Add(new Tuple(Messages.BOOT_MODE, m_pageBootOptions.SelectedBootMode.StringOf())); + + if (m_pageImportSource.IsWIM) + temp.Add(new Tuple(Messages.FINISH_PAGE_ADDSPACE, Util.DiskSizeString(m_pageVMconfig.AdditionalSpace))); + + temp.Add(new Tuple(Messages.FINISH_PAGE_RUN_FIXUPS, m_pageOptions.RunFixups.ToYesNoStringI18n())); + if (m_pageOptions.RunFixups) + temp.Add(new Tuple(Messages.FINISH_PAGE_ISOSR, m_pageOptions.SelectedIsoSR.Name())); + + temp.AddRange(GetVmMappingsSummary()); + return temp; + } + + private IEnumerable GetVmMappingsSummary() + { + var temp = new List(); + + foreach (var mapping in m_vmMappings.Values) + { + var targetLbl = m_vmMappings.Count == 1 ? Messages.FINISH_PAGE_TARGET : string.Format(Messages.FINISH_PAGE_TARGET_FOR_VM, mapping.VmNameLabel); + var storageLbl = m_vmMappings.Count == 1 ? Messages.FINISH_PAGE_STORAGE : string.Format(Messages.FINISH_PAGE_STORAGE_FOR_VM, mapping.VmNameLabel); + var networkLbl = m_vmMappings.Count == 1 ? Messages.FINISH_PAGE_NETWORK : string.Format(Messages.FINISH_PAGE_NETWORK_FOR_VM, mapping.VmNameLabel); + + temp.Add(new Tuple(targetLbl, mapping.TargetName)); + bool first = true; + foreach (var sr in mapping.Storage) + { + temp.Add(new Tuple(first ? storageLbl : "", sr.Value.Name())); + first = false; + } + + first = true; + foreach (var net in mapping.Networks) + { + temp.Add(new Tuple(first ? networkLbl : "", net.Value.Name())); + first = false; + } + } + return temp; + } + + private bool IsGUID(string expression) + { + if (expression != null) + { + Regex guidRegEx = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$"); + + return guidRegEx.IsMatch(expression); + } + return false; + } // Find a name to use of a VM within an envelope that could have come from any hypervisor. // TODO: Consider refactoring this method because it is very similar to OVF.FindSystemName(). - private string FindVMName(EnvelopeType ovfEnv, string systemid) - { - VirtualSystem_Type vSystem = OVF.FindVirtualSystemById(ovfEnv, systemid); + private string FindVMName(EnvelopeType ovfEnv, string systemid) + { + VirtualSystem_Type vSystem = OVF.FindVirtualSystemById(ovfEnv, systemid); // Use the given name if present and valid. // The given name is Envelope.VirtualSystem.Name specified in the OVF Specification 1.1 clause 7.2. // XenServer sets the name property. // vSphere 4.1 and Virtual Box 4.0.6 do not. if ((Tools.ValidateProperty("Name", vSystem)) && !String.IsNullOrEmpty(vSystem.Name[0].Value)) - return vSystem.Name[0].Value; + return vSystem.Name[0].Value; // The VM wasn't given a name. // Build a list of choices from various properties. @@ -610,7 +687,7 @@ private string FindVMName(EnvelopeType ovfEnv, string systemid) choices.Add(vSystem.id); // VirtualHardwareSection_Type.VirtualSystemIdentifier is next preference because Virtual Box will also set this property to the VM name. - VirtualHardwareSection_Type[] vhsList = OVF.FindVirtualHardwareSection(ovfEnv, systemid); + VirtualHardwareSection_Type[] vhsList = OVF.FindVirtualHardwareSection(ovfEnv, systemid); foreach (VirtualHardwareSection_Type vhs in vhsList) { @@ -622,11 +699,11 @@ private string FindVMName(EnvelopeType ovfEnv, string systemid) } // Operating system description is next preference. - OperatingSystemSection_Type[] ossList = OVF.FindSections(vSystem.Items); + OperatingSystemSection_Type[] ossList = OVF.FindSections(vSystem.Items); foreach (OperatingSystemSection_Type oss in ossList) { - if (Tools.ValidateProperty("Description", oss)) + if (Tools.ValidateProperty("Description", oss)) choices.Add(oss.Description.Value); } @@ -635,7 +712,7 @@ private string FindVMName(EnvelopeType ovfEnv, string systemid) choices.Add(Path.GetFileNameWithoutExtension(ovfEnv.Name)); // Last preference is file name. - choices.Add(Path.GetFileNameWithoutExtension(m_pageImportSource.SelectedOvfPackage.PackageSourceFile)); + choices.Add(Path.GetFileNameWithoutExtension(m_pageImportSource.SelectedOvfPackage.PackageSourceFile)); // First choice is one that is not a GUID. foreach (var choice in choices) @@ -653,23 +730,23 @@ private string FindVMName(EnvelopeType ovfEnv, string systemid) // Last resort is a new GUID. return Guid.NewGuid().ToString(); - } - - #endregion - - private void m_pageXvaStorage_ImportVmCompleted() - { - Program.Invoke(this, () => - { - if (CurrentStepTabPage.GetType() == typeof(StoragePickerPage)) - { - m_pageFinish.ShowStartVmsGroupBox = m_pageXvaStorage.ImportedVm != null && !m_pageXvaStorage.ImportedVm.is_a_template; - m_pageXvaNetwork.SetVm(m_pageXvaStorage.ImportedVm); - NotifyNextPagesOfChange(m_pageXvaNetwork); - NextStep(); - } - }); - } + } + + #endregion + + private void m_pageXvaStorage_ImportVmCompleted() + { + Program.Invoke(this, () => + { + if (CurrentStepTabPage.GetType() == typeof(StoragePickerPage)) + { + m_pageFinish.ShowStartVmsGroupBox = m_pageXvaStorage.ImportedVm != null && !m_pageXvaStorage.ImportedVm.is_a_template; + m_pageXvaNetwork.VM = m_pageXvaStorage.ImportedVm; + NotifyNextPagesOfChange(m_pageXvaNetwork); + NextStep(); + } + }); + } private void ShowXenAppXenDesktopWarning(IXenConnection connection) { @@ -689,27 +766,27 @@ private void pageHost_ConnectionSelectionChanged(IXenConnection connection) ShowXenAppXenDesktopWarning(connection); } - #region Nested items - - /// - /// Type of the object we want to import - /// - public enum ImportType - { - /// - /// Exported VM or template; filetype *.xva, *.xva.gz - /// - Xva, - /// - /// Appliance; filetypes *.ovf, *.ova, *.ova.gz - /// - Ovf, - /// - /// Virtual disk image; filetypes *.vhd, *.vmdk (CA-61385: remove ".vdi", ".wim" support for Boston) - /// - Vhd - } - - #endregion - } + #region Nested items + + /// + /// Type of the object we want to import + /// + public enum ImportType + { + /// + /// Exported VM or template; filetype *.xva, *.xva.gz + /// + Xva, + /// + /// Appliance; filetypes *.ovf, *.ova, *.ova.gz + /// + Ovf, + /// + /// Virtual disk image; filetypes *.vhd, *.vmdk (CA-61385: remove ".vdi", ".wim" support for Boston) + /// + Vhd + } + + #endregion + } } diff --git a/XenAdmin/Wizards/ImportWizard/NetworkPickerPage.cs b/XenAdmin/Wizards/ImportWizard/NetworkPickerPage.cs index 16d8c4e00f..c3a90ed3a3 100644 --- a/XenAdmin/Wizards/ImportWizard/NetworkPickerPage.cs +++ b/XenAdmin/Wizards/ImportWizard/NetworkPickerPage.cs @@ -49,9 +49,6 @@ public partial class NetworkPickerPage : XenTabPage #region Private fields private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - private IXenConnection m_selectedConnection; - private Host m_selectedAffinity; - private VM m_vm; private bool m_buttonNextEnabled; #endregion @@ -108,6 +105,15 @@ public override bool EnableNext() #region Accessors + /// + /// Should be set before the Affinity is set. + /// + internal IXenConnection SelectedConnection { get; set; } + + internal Host SelectedAffinity { get; set; } + + internal VM VM { get; set; } + public List VIFs { get @@ -136,24 +142,6 @@ public List VIFs #endregion - public void SetAffinity(Host host) - { - m_selectedAffinity = host; - } - - public void SetVm(VM vm) - { - m_vm = vm; - } - - /// - /// Should be called before the Affinity is set. - /// - public void SetConnection(IXenConnection con) - { - m_selectedConnection = con; - } - #region Private methods private void UpdateControlsEnabledState(bool enabled) @@ -167,7 +155,7 @@ private void SetNetworkList() { NetworkNetworkColumn.Items.Clear(); - var networks = m_selectedConnection.Cache.Networks.Where(ShowNetwork); + var networks = SelectedConnection.Cache.Networks.Where(ShowNetwork); foreach (XenAPI.Network network in networks) { @@ -186,18 +174,18 @@ private void BuildVIFList() m_networkGridView.SuspendLayout(); m_networkGridView.Rows.Clear(); - if (m_vm.is_a_template && m_vm.VIFs.Count < 1) + if (VM.is_a_template && VM.VIFs.Count < 1) { // We need to automatically generate VIFs for Networks marked AutoPlug=true - var networks = m_selectedConnection.Cache.Networks; + var networks = SelectedConnection.Cache.Networks; foreach (XenAPI.Network network in networks) { - if (m_networkGridView.Rows.Count < m_vm.MaxVIFsAllowed() && ShowNetwork(network) && network.GetAutoPlug()) + if (m_networkGridView.Rows.Count < VM.MaxVIFsAllowed() && ShowNetwork(network) && network.GetAutoPlug()) { AddVIFRow(new VIF { - Connection = m_selectedConnection, + Connection = SelectedConnection, device = m_networkGridView.Rows.Count.ToString(), network = new XenRef(network.opaque_ref), MAC = Messages.MAC_AUTOGENERATE @@ -205,16 +193,16 @@ private void BuildVIFList() } } } - else if (m_vm.is_a_template) + else if (VM.is_a_template) { // We need to create off the _vmTemplate - var vifs = m_selectedConnection.ResolveAll(m_vm.VIFs); + var vifs = SelectedConnection.ResolveAll(VM.VIFs); foreach (VIF vif in vifs) { AddVIFRow(new VIF { - Connection = m_selectedConnection, + Connection = SelectedConnection, device = vif.device, network = vif.network, MAC = Messages.MAC_AUTOGENERATE @@ -224,7 +212,7 @@ private void BuildVIFList() else { //We need to recreate off vm - var vifs = m_selectedConnection.ResolveAll(m_vm.VIFs); + var vifs = SelectedConnection.ResolveAll(VM.VIFs); foreach (VIF vif in vifs) AddVIFRow(vif); } @@ -240,7 +228,7 @@ private void BuildVIFList() private XenAPI.Network GetDefaultNetwork() { - foreach (XenAPI.Network network in m_selectedConnection.Cache.Networks) + foreach (XenAPI.Network network in SelectedConnection.Cache.Networks) if (ShowNetwork(network)) return network; @@ -261,13 +249,13 @@ private bool ShowNetwork(XenAPI.Network network) if (network.IsMember()) return false; - if (m_selectedAffinity != null && !m_selectedAffinity.CanSeeNetwork(network)) + if (SelectedAffinity != null && !SelectedAffinity.CanSeeNetwork(network)) return false; - if (m_selectedAffinity == null && !network.AllHostsCanSeeNetwork()) + if (SelectedAffinity == null && !network.AllHostsCanSeeNetwork()) return false; - if (network.IsSriov() && !m_vm.HasSriovRecommendation()) + if (network.IsSriov() && !VM.HasSriovRecommendation()) return false; return true; @@ -276,7 +264,7 @@ private bool ShowNetwork(XenAPI.Network network) private void AddVIFRow(VIF vif) { var row = new VifRow(vif); - XenAPI.Network network = m_selectedConnection.Resolve(vif.network); + XenAPI.Network network = SelectedConnection.Resolve(vif.network); bool isGuestInstallerNetwork = network != null && network.IsGuestInstallerNetwork(); ToStringWrapper comboBoxEntry = FindComboBoxEntryForNetwork(network); @@ -344,7 +332,7 @@ private void m_buttonDeleteNetwork_Click(object sender, EventArgs e) private void m_buttonAddNetwork_Click(object sender, EventArgs e) { - if (m_networkGridView.Rows.Count >= m_vm.MaxVIFsAllowed()) + if (m_networkGridView.Rows.Count >= VM.MaxVIFsAllowed()) { using (var dlg = new ErrorDialog(FriendlyErrorNames.VIFS_MAX_ALLOWED) {WindowTitle = FriendlyErrorNames.VIFS_MAX_ALLOWED_TITLE}) @@ -354,7 +342,7 @@ private void m_buttonAddNetwork_Click(object sender, EventArgs e) return; } - VIF vif = new VIF {Connection = m_selectedConnection}; + VIF vif = new VIF {Connection = SelectedConnection}; int i = 0; while (true) diff --git a/XenAdmin/Wizards/ImportWizard/StoragePickerPage.cs b/XenAdmin/Wizards/ImportWizard/StoragePickerPage.cs index 600d5c4ca0..615036d25d 100644 --- a/XenAdmin/Wizards/ImportWizard/StoragePickerPage.cs +++ b/XenAdmin/Wizards/ImportWizard/StoragePickerPage.cs @@ -45,8 +45,6 @@ namespace XenAdmin.Wizards.ImportWizard public partial class StoragePickerPage : XenTabPage { #region Private fields - private Host m_targetHost; - private IXenConnection m_targetConnection; private volatile Task m_importTask; private bool m_alreadyFoundVM; private ActionProgressDialog m_actionDialog; @@ -98,8 +96,8 @@ protected override void PageLeaveCore(PageLoadedDirection direction, ref bool ca SetButtonNextEnabled(false); m_buttonPreviousEnabled = false; OnPageUpdated(); - ImportXvaAction = new ImportVmAction(m_targetHost == null ? m_targetConnection : m_targetHost.Connection, - m_targetHost, FilePath, SR, + ImportXvaAction = new ImportVmAction(TargetHost == null ? TargetConnection : TargetHost.Connection, + TargetHost, FilePath, SR, VMOperationCommand.WarningDialogHAInvalidConfig, VMOperationCommand.StartDiagnosisForm); ImportXvaAction.Completed += m_importXvaAction_Completed; @@ -119,7 +117,7 @@ public override string NextText(bool isLastPage) public override void PopulatePage() { SetButtonNextEnabled(false); - m_srPicker.PopulateAsync(SrPicker.SRPickerType.VM, m_targetConnection, m_targetHost, null, null); + m_srPicker.PopulateAsync(SrPicker.SRPickerType.VM, TargetConnection, TargetHost, null, null); IsDirty = true; } @@ -137,6 +135,10 @@ public override bool EnableNext() #region Accessors + internal IXenConnection TargetConnection { get; set; } + + internal Host TargetHost { get; set; } + public ImportVmAction ImportXvaAction { get; private set; } public string FilePath { private get; set; } @@ -147,19 +149,6 @@ public override bool EnableNext() #endregion - /// - /// Should be called before the Affinity is set. - /// - public void SetConnection(IXenConnection con) - { - m_targetConnection = con; - } - - public void SetTargetHost(Host host) - { - m_targetHost = host; - } - #region Private methods private void SetButtonNextEnabled(bool enabled) @@ -196,12 +185,12 @@ private void ScanTask(object obj) while (ImportXvaAction.RelatedTask == null) Thread.Sleep(100); - while ((m_importTask = m_targetConnection.Resolve(ImportXvaAction.RelatedTask)) == null) + while ((m_importTask = TargetConnection.Resolve(ImportXvaAction.RelatedTask)) == null) Thread.Sleep(100); // We register a XenObjectsUpdated event handler where we check that the import task has the object creation phase marked as "complete"; // Once the object creation is complete, we look for the vm; When we found the vm we unregister this event handler; - m_targetConnection.XenObjectsUpdated += targetConnection_XenObjectsUpdated; + TargetConnection.XenObjectsUpdated += targetConnection_XenObjectsUpdated; Program.Invoke(this, CheckTask); } @@ -233,11 +222,11 @@ private void GetVm() { // Should never get here (as we unregister XenObjectsUpdated event handler after we find the vm) but just in case, // unregister XenObjectsUpdated event handler - m_targetConnection.XenObjectsUpdated -= targetConnection_XenObjectsUpdated; + TargetConnection.XenObjectsUpdated -= targetConnection_XenObjectsUpdated; return; } - foreach (VM vm in m_targetConnection.Cache.VMs) + foreach (VM vm in TargetConnection.Cache.VMs) { if (!vm.other_config.ContainsKey(ImportVmAction.IMPORT_TASK)) continue; @@ -250,7 +239,7 @@ private void GetVm() ImportedVm = vm; // We found the VM, unregister XenObjectsUpdated event handler - m_targetConnection.XenObjectsUpdated -= targetConnection_XenObjectsUpdated; + TargetConnection.XenObjectsUpdated -= targetConnection_XenObjectsUpdated; // And close the dialog, flick to next page. m_actionDialog.Close(); @@ -279,7 +268,7 @@ private void m_importXvaAction_Completed(ActionBase sender) if (!(ImportXvaAction.Succeeded) || ImportXvaAction.Cancelled) { // task failed or has been cancelled, unregister XenObjectsUpdated event handler - m_targetConnection.XenObjectsUpdated -= targetConnection_XenObjectsUpdated; + TargetConnection.XenObjectsUpdated -= targetConnection_XenObjectsUpdated; // Give the user a chance to correct any errors m_actionDialog = null; diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PrecheckPage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PrecheckPage.cs index 323f305648..f974842839 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PrecheckPage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PrecheckPage.cs @@ -614,8 +614,8 @@ public void UpdateDescription(PreCheckResult precheckResult) private class PreCheckHostRow : PreCheckGridRow { - private Problem _problem = null; - private Check _check = null; + private readonly Problem _problem = null; + private readonly Check _check = null; public PreCheckHostRow(Problem problem) : base(new DataGridViewTextBoxCell()) { diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs index bd3e5f754b..0590d4912b 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs @@ -49,7 +49,7 @@ public PatchingWizard_UploadPage() } #region Accessors - public readonly List PatchMappings = new List(); + public List PatchMappings { get; } = new List(); public UpdateType SelectedUpdateType { private get; set; } public string SelectedPatchFilePath { get; set; } diff --git a/XenAdmin/Wizards/PatchingWizard/PlanActions/RebootPlanAction.cs b/XenAdmin/Wizards/PatchingWizard/PlanActions/RebootPlanAction.cs index 152f521a85..fe940b0cab 100644 --- a/XenAdmin/Wizards/PatchingWizard/PlanActions/RebootPlanAction.cs +++ b/XenAdmin/Wizards/PatchingWizard/PlanActions/RebootPlanAction.cs @@ -39,7 +39,8 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions public abstract class RebootPlanAction : HostPlanAction { private bool _cancelled; - private bool lostConnection; + private bool _lostConnection; + private readonly object _lockObj = new object(); protected RebootPlanAction(Host host) : base(host) @@ -50,9 +51,9 @@ public override void Cancel() { _cancelled = true; - lock (this) + lock (_lockObj) { - Monitor.PulseAll(this); + Monitor.PulseAll(_lockObj); } } @@ -98,7 +99,7 @@ protected void WaitForReboot(ref Session session, Func { bool isCoordinator = GetResolvedHost().IsCoordinator(); - lostConnection = false; + _lostConnection = false; _cancelled = false; double metric = metricDelegate(session, HostXenRef.opaque_ref); @@ -134,7 +135,7 @@ private Session WaitForHostToStart(bool coordinator, Session session, Func HostPlans { get; private set; } public List FinalActions { get; private set; } public List CleanupActions { get; private set; } - public readonly List DoneActions = new List(); - public readonly List InProgressActions = new List(); + public List DoneActions { get; } = new List(); + public List InProgressActions { get; } = new List(); public Pool Pool { get; private set; } public string Name { get; private set; } diff --git a/XenAdmin/Wizards/RollingUpgradeWizard/RollingUpgradeWizardPrecheckPage.cs b/XenAdmin/Wizards/RollingUpgradeWizard/RollingUpgradeWizardPrecheckPage.cs index 886e688708..b74722b7cb 100644 --- a/XenAdmin/Wizards/RollingUpgradeWizard/RollingUpgradeWizardPrecheckPage.cs +++ b/XenAdmin/Wizards/RollingUpgradeWizard/RollingUpgradeWizardPrecheckPage.cs @@ -240,7 +240,7 @@ where check.CanRun() //Checking PV guests - for hosts that have any PV guests and warn the user before the upgrade. var pvChecks = (from Host server in SelectedCoordinators - let check = new PVGuestsCheck(server, true, ManualUpgrade, InstallMethodConfig) + let check = new PVGuestsCheck(server, ManualUpgrade, InstallMethodConfig) where check.CanRun() select check as Check).ToList(); diff --git a/XenAdmin/XenAdmin.csproj b/XenAdmin/XenAdmin.csproj index 9936cfe275..2627960208 100755 --- a/XenAdmin/XenAdmin.csproj +++ b/XenAdmin/XenAdmin.csproj @@ -744,7 +744,6 @@ KeyMap.cs - diff --git a/XenCenterLib/PathValidator.cs b/XenCenterLib/PathValidator.cs deleted file mode 100644 index b2e233d0ac..0000000000 --- a/XenCenterLib/PathValidator.cs +++ /dev/null @@ -1,100 +0,0 @@ -/* 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.IO; - -namespace XenCenterLib -{ - public class PathValidator - { - private static readonly char[] m_invalidFileCharList = Path.GetInvalidFileNameChars(); - private static readonly string[] m_deviceNames = { - "CON", "PRN", "AUX", "NUL", - "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", - "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" - }; - - public static bool IsFileNameValid(string filename) - { - if (filename.IndexOfAny(m_invalidFileCharList) > -1) - return false; - - foreach (var name in m_deviceNames) - { - if (name == filename.ToUpper()) - return false; - } - - return true; - } - - public static bool IsPathValid(string path) - { - if (string.IsNullOrEmpty(path)) - return false; - - try - { - if (Path.IsPathRooted(path)) - { - path = path[0] == '\\' && path.Length == 1 - ? path.Substring(1) - : path.Substring(2); - } - } - catch(ArgumentException) - { - //path contains a character from Path.GetInvalidPathChars() - return false; - } - - string[] parts = path.Split(new[] {'\\'}); - - if (parts.Length > 0) - { - foreach (var part in parts) - { - if (part.IndexOfAny(m_invalidFileCharList) > -1) - return false; - - foreach (var name in m_deviceNames) - { - if (name == part.ToUpper()) - return false; - } - } - } - - return true; - } - } -} diff --git a/XenCenterLib/XenCenterLib.csproj b/XenCenterLib/XenCenterLib.csproj index 8664d927f6..962af04449 100644 --- a/XenCenterLib/XenCenterLib.csproj +++ b/XenCenterLib/XenCenterLib.csproj @@ -79,7 +79,6 @@ - diff --git a/XenModel/Actions/AsyncAction.cs b/XenModel/Actions/AsyncAction.cs index 30db5aede0..1d7d8b3bd9 100644 --- a/XenModel/Actions/AsyncAction.cs +++ b/XenModel/Actions/AsyncAction.cs @@ -378,10 +378,9 @@ private bool Poll(double start, double finish) doc.LoadXml(task.result); var nodes = doc.GetElementsByTagName("value"); - foreach (XmlNode node in nodes) + if (nodes.Count > 0) { - Result = node.InnerText; - break; + Result = nodes[0].InnerText; } } catch //CA-352946 diff --git a/XenModel/Actions/DR/ShutdownAndDestroyVMsAction.cs b/XenModel/Actions/DR/ShutdownAndDestroyVMsAction.cs index c2e978dba0..ab84fc2b23 100644 --- a/XenModel/Actions/DR/ShutdownAndDestroyVMsAction.cs +++ b/XenModel/Actions/DR/ShutdownAndDestroyVMsAction.cs @@ -84,7 +84,6 @@ protected override void Run() internal static void DestroyVM(Session session, VM vm) { - Exception caught = null; log.DebugFormat("Destroying VM '{0}'", vm.Name()); if (vm.snapshots.Count > 0) @@ -143,9 +142,6 @@ internal static void DestroyVM(Session session, VM vm) } log.DebugFormat("VM '{0}' destroyed", vm.Name()); - - if (caught != null) - throw caught; } } } diff --git a/XenModel/Actions/DR/VdiLoadMetadataAction.cs b/XenModel/Actions/DR/VdiLoadMetadataAction.cs index 284783d5f9..9c30fcc383 100644 --- a/XenModel/Actions/DR/VdiLoadMetadataAction.cs +++ b/XenModel/Actions/DR/VdiLoadMetadataAction.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; +using System.Linq; using XenAdmin.Core; using XenAdmin.Network; using XenAPI; @@ -91,25 +92,21 @@ protected override void Run() MetadataSession = Session.get_record(Session, MetadataSessionRef); #region FIND POOL - Dictionary, XenAPI.Pool> pools = XenAPI.Pool.get_all_records(MetadataSession); - foreach (var pool in pools.Values) + var pools = Pool.get_all_records(MetadataSession); + var poolValues = pools.Values; + if (poolValues.Count > 0) { - _poolMetadata.Pool = pool; - string poolName = String.IsNullOrEmpty(pool.name_label) && pool.master != null - ? XenAPI.Host.get_name_label(MetadataSession, pool.master.opaque_ref) - : pool.name_label; + var pool = poolValues.First(); + var poolName = string.IsNullOrEmpty(pool.name_label) && pool.master != null + ? Host.get_name_label(MetadataSession, pool.master.opaque_ref) + : pool.name_label; _poolMetadata.Pool.name_label = poolName; log.DebugFormat("Found metadata of pool '{0}' (UUID={1})", _poolMetadata.Pool.Name(), - _poolMetadata.Pool.uuid); - break; + _poolMetadata.Pool.uuid); } + #endregion - /*if (_poolMetadata.Pool.uuid == Pool.uuid) // metadata of current pool - { - return; - }*/ - _poolMetadata.VmAppliances = VM_appliance.get_all_records(MetadataSession); foreach (var vmAppRef in _poolMetadata.VmAppliances.Keys) { diff --git a/XenModel/Actions/Host/ApplyLicenseEditionAction.cs b/XenModel/Actions/Host/ApplyLicenseEditionAction.cs index 7609fa131c..c5292f6697 100644 --- a/XenModel/Actions/Host/ApplyLicenseEditionAction.cs +++ b/XenModel/Actions/Host/ApplyLicenseEditionAction.cs @@ -64,9 +64,11 @@ public class ApplyLicenseEditionAction : AsyncAction public ApplyLicenseEditionAction(IEnumerable xos, Host.Edition edition, string licenseServerAddress, string licenseServerPort, Action, string> doOnLicensingFailure = null) : base(null, Messages.LICENSE_UPDATING_LICENSES) { - LicenseFailures = new List(); - Util.ThrowIfEnumerableParameterNullOrEmpty(xos, "xenobjects"); + if (xos == null || !xos.Any()) + throw new ArgumentException(@"Parameter cannot be null or empty", nameof(xos)); + LicenseFailures = new List(); + _edition = edition; this.xos = xos; _licenseServerAddress = licenseServerAddress; diff --git a/XenModel/Actions/Host/EnableHostAction.cs b/XenModel/Actions/Host/EnableHostAction.cs index ebc07ffe34..7e287b03bc 100644 --- a/XenModel/Actions/Host/EnableHostAction.cs +++ b/XenModel/Actions/Host/EnableHostAction.cs @@ -42,12 +42,10 @@ public class EnableHostAction:HostAbstractAction private readonly bool _resumeVMs; public EnableHostAction(Host host, bool resumeVMs,Func acceptNTolChangesOnEnable) - : base(host.Connection, Messages.HOST_ENABLE, Messages.WAITING, null, acceptNTolChangesOnEnable) + : base(host?.Connection, Messages.HOST_ENABLE, Messages.WAITING, null, acceptNTolChangesOnEnable) { - if (host == null) - throw new ArgumentNullException("host"); + Host = host ?? throw new ArgumentNullException("host"); _resumeVMs = resumeVMs; - this.Host = host; AddCommonAPIMethodsToRoleCheck(); ApiMethodsToRoleCheck.Add("pool.ha_compute_hypothetical_max_host_failures_to_tolerate"); ApiMethodsToRoleCheck.Add("pool.set_ha_host_failures_to_tolerate"); diff --git a/XenModel/Actions/Host/EvacuateHostAction.cs b/XenModel/Actions/Host/EvacuateHostAction.cs index 2dc5e3a512..461557976a 100644 --- a/XenModel/Actions/Host/EvacuateHostAction.cs +++ b/XenModel/Actions/Host/EvacuateHostAction.cs @@ -60,8 +60,6 @@ public class EvacuateHostAction:HostAbstractAction public EvacuateHostAction(Host host, Host newCoordinator, Dictionary, String[]> hostRecommendations, Func acceptNTolChanges, Func acceptNTolChangesOnEnable) : base(host.Connection, null, Messages.HOST_EVACUATE, acceptNTolChanges, acceptNTolChangesOnEnable) { - if (host == null) - throw new ArgumentNullException("host"); Host = host; _newCoordinator = newCoordinator; _hostRecommendations = hostRecommendations; diff --git a/XenModel/Actions/Host/RebootHostAction.cs b/XenModel/Actions/Host/RebootHostAction.cs index 15ca51340b..0650d163dc 100644 --- a/XenModel/Actions/Host/RebootHostAction.cs +++ b/XenModel/Actions/Host/RebootHostAction.cs @@ -50,9 +50,7 @@ public class RebootHostAction : HostAbstractAction public RebootHostAction(Host host, Func acceptNTolChanges) : base(host.Connection, Messages.HOST_REBOOTING, Messages.WAITING, acceptNTolChanges, null) { - if (host == null) - throw new ArgumentNullException("host"); - this.Host = host; + Host = host; AddCommonAPIMethodsToRoleCheck(); ApiMethodsToRoleCheck.Add("pool.ha_compute_hypothetical_max_host_failures_to_tolerate"); ApiMethodsToRoleCheck.Add("pool.set_ha_host_failures_to_tolerate"); diff --git a/XenModel/Actions/Host/ShutdownHostAction.cs b/XenModel/Actions/Host/ShutdownHostAction.cs index 9d819f3868..99250f2be5 100644 --- a/XenModel/Actions/Host/ShutdownHostAction.cs +++ b/XenModel/Actions/Host/ShutdownHostAction.cs @@ -44,8 +44,6 @@ public class ShutdownHostAction:HostAbstractAction public ShutdownHostAction(Host host, Func acceptNTolChanges) : base(host.Connection, Messages.HOST_SHUTDOWN, Messages.WAITING, acceptNTolChanges, null) { - if (host == null) - throw new ArgumentNullException("host"); Host = host; ApiMethodsToRoleCheck.Add("pool.ha_compute_hypothetical_max_host_failures_to_tolerate"); ApiMethodsToRoleCheck.Add("pool.set_ha_host_failures_to_tolerate"); diff --git a/XenModel/Actions/Pool/EnableHAAction.cs b/XenModel/Actions/Pool/EnableHAAction.cs index 6015b1be12..83b23e9378 100644 --- a/XenModel/Actions/Pool/EnableHAAction.cs +++ b/XenModel/Actions/Pool/EnableHAAction.cs @@ -49,12 +49,10 @@ public class EnableHAAction : PureAsyncAction public EnableHAAction(Pool pool, Dictionary startupOptions, List heartbeatSRs, long failuresToTolerate) : base(pool.Connection, string.Format(Messages.ENABLING_HA_ON, Helpers.GetName(pool).Ellipsise(50)), Messages.ENABLING_HA, false) { - if (pool == null) - throw new ArgumentNullException("pool"); if (heartbeatSRs.Count == 0) throw new ArgumentException("You must specify at least 1 heartbeat SR"); - this.Pool = pool; + Pool = pool; this.startupOptions = startupOptions; this.heartbeatSRs = heartbeatSRs.ToArray(); this.failuresToTolerate = failuresToTolerate; @@ -69,7 +67,7 @@ protected override void Run() { if (startupOptions != null) { - double increment = 10 / Math.Max(startupOptions.Count, 1); + double increment = 10.0 / Math.Max(startupOptions.Count, 1); int i = 0; // First set any VM restart priorities supplied foreach (VM vm in startupOptions.Keys) diff --git a/XenModel/Actions/Pool_Patch/CheckDiskSpaceForPatchUploadAction.cs b/XenModel/Actions/Pool_Patch/CheckDiskSpaceForPatchUploadAction.cs index 40c6c885f8..e340d4591b 100644 --- a/XenModel/Actions/Pool_Patch/CheckDiskSpaceForPatchUploadAction.cs +++ b/XenModel/Actions/Pool_Patch/CheckDiskSpaceForPatchUploadAction.cs @@ -57,8 +57,6 @@ public CheckDiskSpaceForPatchUploadAction(Host host, string path, bool suppressH public CheckDiskSpaceForPatchUploadAction(Host host, string fileName, long size, bool suppressHistory) : base(host.Connection, Messages.ACTION_CHECK_DISK_SPACE_TITLE, "", suppressHistory) { - if (host == null) - throw new ArgumentNullException("host"); Host = host; this.fileName = fileName; fileSize = size; diff --git a/XenModel/Actions/Pool_Patch/CleanupDiskSpaceAction.cs b/XenModel/Actions/Pool_Patch/CleanupDiskSpaceAction.cs index 970c1d4e17..9e2e581999 100644 --- a/XenModel/Actions/Pool_Patch/CleanupDiskSpaceAction.cs +++ b/XenModel/Actions/Pool_Patch/CleanupDiskSpaceAction.cs @@ -45,8 +45,6 @@ public class CleanupDiskSpaceAction : PureAsyncAction public CleanupDiskSpaceAction(Host host, Pool_patch excludedPatch, bool suppressHistory) : base(host.Connection, Messages.ACTION_CLEANUP_DISK_SPACE_TITLE, "", suppressHistory) { - if (host == null) - throw new ArgumentNullException("host"); Host = host; this.excludedPatch = excludedPatch; } diff --git a/XenModel/Actions/Pool_Patch/GetDiskSpaceRequirementsAction.cs b/XenModel/Actions/Pool_Patch/GetDiskSpaceRequirementsAction.cs index 0da640e403..5b31a72a5a 100644 --- a/XenModel/Actions/Pool_Patch/GetDiskSpaceRequirementsAction.cs +++ b/XenModel/Actions/Pool_Patch/GetDiskSpaceRequirementsAction.cs @@ -81,8 +81,6 @@ public GetDiskSpaceRequirementsAction(Host host, long size, bool suppressHistory public GetDiskSpaceRequirementsAction(Host host, string updateName, long size, bool suppressHistory) : base(host.Connection, Messages.ACTION_GET_DISK_SPACE_REQUIREMENTS_TITLE, suppressHistory) { - if (host == null) - throw new ArgumentNullException("host"); Host = host; this.updateName = updateName; updateSize = size; diff --git a/XenModel/Actions/Pool_Patch/PoolPatchCleanAction.cs b/XenModel/Actions/Pool_Patch/PoolPatchCleanAction.cs index 6984584369..1806f45e24 100644 --- a/XenModel/Actions/Pool_Patch/PoolPatchCleanAction.cs +++ b/XenModel/Actions/Pool_Patch/PoolPatchCleanAction.cs @@ -43,8 +43,6 @@ public PoolPatchCleanAction(Pool pool, Pool_patch patch, bool suppressHistory) : base(pool.Connection, string.Format(Messages.UPDATES_WIZARD_REMOVING_UPDATE, patch.Name(), pool.Name()), suppressHistory) { this.patch = patch; - if (patch == null) - throw new ArgumentNullException("patch"); #region RBAC Dependencies ApiMethodsToRoleCheck.Add("pool_patch.pool_clean"); diff --git a/XenModel/Actions/SR/SrRepairAction.cs b/XenModel/Actions/SR/SrRepairAction.cs index 4568f45e61..16a6058b43 100644 --- a/XenModel/Actions/SR/SrRepairAction.cs +++ b/XenModel/Actions/SR/SrRepairAction.cs @@ -55,10 +55,8 @@ public class SrRepairAction : AsyncAction public SrRepairAction(IXenConnection connection, SR sr,bool isSharedAction) : base(connection, isSharedAction ? string.Format(Messages.ACTION_SR_SHARING, sr.NameWithoutHost()) : string.Format(Messages.ACTION_SR_REPAIRING, sr.NameWithoutHost())) { - if (sr == null) - throw new ArgumentNullException("sr"); this.isSharedAction = isSharedAction; - this.SR = sr; + SR = sr; #region RBAC Dependencies ApiMethodsToRoleCheck.Add("pbd.plug"); diff --git a/XenModel/Actions/VDI/MigrateVirtualDiskAction.cs b/XenModel/Actions/VDI/MigrateVirtualDiskAction.cs index 5cbd1654f5..3ef3d27ca7 100644 --- a/XenModel/Actions/VDI/MigrateVirtualDiskAction.cs +++ b/XenModel/Actions/VDI/MigrateVirtualDiskAction.cs @@ -44,16 +44,14 @@ public class MigrateVirtualDiskAction : PureAsyncAction private readonly VDI vdi; public MigrateVirtualDiskAction(IXenConnection connection, VDI vdi, SR sr) - : base(connection, string.Format(Messages.ACTION_MOVING_VDI_TO_SR, Helpers.GetName(vdi), Helpers.GetName(sr))) + : base(connection, string.Format(Messages.ACTION_MOVING_VDI_TO_SR, Helpers.GetName(vdi), Helpers.GetName(connection.Resolve(vdi.SR)), Helpers.GetName(sr))) { - Description = Messages.ACTION_PREPARING; this.vdi = vdi; SR = sr; } protected override void Run() { - Description = string.Format(Messages.ACTION_MOVING_VDI, Helpers.GetName(vdi)); RelatedTask = VDI.async_pool_migrate(Session, vdi.opaque_ref, SR.opaque_ref, new Dictionary()); PollToCompletion(); Description = Messages.MOVED; diff --git a/XenModel/Actions/VDI/MoveVirtualDiskAction.cs b/XenModel/Actions/VDI/MoveVirtualDiskAction.cs index d784e5fa1d..0de6066129 100644 --- a/XenModel/Actions/VDI/MoveVirtualDiskAction.cs +++ b/XenModel/Actions/VDI/MoveVirtualDiskAction.cs @@ -44,8 +44,8 @@ public class MoveVirtualDiskAction : AsyncAction private VDI vdi; - public MoveVirtualDiskAction(IXenConnection connection, XenAPI.VDI vdi, SR sr) - : base(connection, string.Format(Messages.ACTION_MOVING_VDI_TO_SR, Helpers.GetName(vdi), Helpers.GetName(sr))) + public MoveVirtualDiskAction(IXenConnection connection, VDI vdi, SR sr) + : base(connection, string.Format(Messages.ACTION_MOVING_VDI_TO_SR, Helpers.GetName(vdi), Helpers.GetName(connection.Resolve(vdi.SR)), Helpers.GetName(sr))) { this.vdi = vdi; SR = sr; @@ -61,7 +61,6 @@ public MoveVirtualDiskAction(IXenConnection connection, XenAPI.VDI vdi, SR sr) protected override void Run() { - Description = string.Format(Messages.ACTION_MOVING_VDI, Helpers.GetName(vdi)); PercentComplete = 10; log.DebugFormat("Moving VDI '{0}'", Helpers.GetName(vdi)); RelatedTask = VDI.async_copy(Session, vdi.opaque_ref, SR.opaque_ref); diff --git a/XenModel/Actions/VM/ImportVmAction.cs b/XenModel/Actions/VM/ImportVmAction.cs index bde26eacdb..fd227a6437 100644 --- a/XenModel/Actions/VM/ImportVmAction.cs +++ b/XenModel/Actions/VM/ImportVmAction.cs @@ -72,9 +72,10 @@ public class ImportVmAction : AsyncAction public ImportVmAction(IXenConnection connection, Host affinity, string filename, SR sr, Action warningDelegate, Action failureDiagnosisDelegate) - : base(connection, string.Format(Messages.IMPORTVM_TITLE, filename, Helpers.GetName(connection)), Messages.IMPORTVM_PREP) - { - Pool = Helpers.GetPoolOfOne(connection); + : base(connection, "") + { + Description = Messages.IMPORTVM_PREP; + Pool = Helpers.GetPoolOfOne(connection); m_affinity = affinity; Host = affinity ?? connection.Resolve(Pool.master); SR = sr; @@ -94,7 +95,9 @@ public class ImportVmAction : AsyncAction ApiMethodsToRoleCheck.AddRange(Role.CommonSessionApiList); #endregion - } + + Title = string.Format(Messages.IMPORTVM_TITLE, filename, Host.NameWithLocation()); + } protected override void Run() { diff --git a/XenModel/Actions/VM/VMCloneAction.cs b/XenModel/Actions/VM/VMCloneAction.cs index c07ef6180b..f8b622c8b8 100644 --- a/XenModel/Actions/VM/VMCloneAction.cs +++ b/XenModel/Actions/VM/VMCloneAction.cs @@ -37,18 +37,17 @@ namespace XenAdmin.Actions.VMActions { public class VMCloneAction : AsyncAction { + private readonly string _cloneName; + private readonly string _cloneDescription; - protected string _cloneName; - protected string _cloneDescription; public VMCloneAction(VM vm, string name, string description) - : base(vm.Connection, string.Format(Messages.CREATEVM_CLONE, name, vm.Name())) + : base(vm.Connection, string.Format(Messages.CREATEVM_CLONE, name, vm.NameWithLocation())) { - this.Description = Messages.ACTION_PREPARING; - this.VM = vm; - this.Host = vm.Home(); - this.Pool = Core.Helpers.GetPool(vm.Connection); + VM = vm; + Host = vm.Home(); + Pool = Helpers.GetPool(vm.Connection); if (vm.is_a_template) - this.Template = vm; + Template = vm; _cloneName = name; _cloneDescription = description; @@ -68,17 +67,14 @@ public static RbacMethodList StaticRBACDependencies protected override void Run() { - this.Description = Messages.ACTION_TEMPLATE_CLONING; - RelatedTask = XenAPI.VM.async_clone(Session, VM.opaque_ref, _cloneName); + RelatedTask = VM.async_clone(Session, VM.opaque_ref, _cloneName); PollToCompletion(); - { - VM created = Connection.WaitForCache(new XenRef(Result)); - XenAPI.VM.set_name_description(Session, created.opaque_ref, _cloneDescription); - Result = created.opaque_ref; - } - this.Description = Messages.ACTION_TEMPLATE_CLONED; - } - } + VM created = Connection.WaitForCache(new XenRef(Result)); + VM.set_name_description(Session, created.opaque_ref, _cloneDescription); + Result = created.opaque_ref; + Description = Messages.ACTION_TEMPLATE_CLONED; + } + } } diff --git a/XenModel/Actions/VM/VMCopyAction.cs b/XenModel/Actions/VM/VMCopyAction.cs index 5f9bea8658..cbd1ff344e 100644 --- a/XenModel/Actions/VM/VMCopyAction.cs +++ b/XenModel/Actions/VM/VMCopyAction.cs @@ -41,16 +41,15 @@ public class VMCopyAction : AsyncAction private string _namedescription; public VMCopyAction(VM vm, Host host, SR sr, string nameLabel, string description) - : base(vm.Connection, string.Format(Messages.ACTION_VM_COPYING_TITLE, vm.Name(), nameLabel, sr.NameWithoutHost())) + : base(vm.Connection, string.Format(Messages.ACTION_VM_COPYING_TITLE, vm.NameWithLocation(), nameLabel, sr.NameWithLocation())) { - this.Description = Messages.ACTION_PREPARING; - this.VM = vm; - this.Host = host; - this.Pool = Core.Helpers.GetPool(vm.Connection); - this.SR = sr; + VM = vm; + Host = host; + Pool = Core.Helpers.GetPool(vm.Connection); + SR = sr; _nameLabel = nameLabel; if (vm.is_a_template) - this.Template = vm; + Template = vm; _namedescription = description; ApiMethodsToRoleCheck.AddRange(StaticRBACDependencies); @@ -69,25 +68,21 @@ public static RbacMethodList StaticRBACDependencies protected override void Run() { - - this.Description = Messages.ACTION_VM_COPYING; - RelatedTask = XenAPI.VM.async_copy(Session, VM.opaque_ref, _nameLabel, this.SR.opaque_ref); + RelatedTask = VM.async_copy(Session, VM.opaque_ref, _nameLabel, SR.opaque_ref); try { PollToCompletion(); } catch (CancelledException) { - this.Description = string.Format(Messages.COPY_TO_SHARED_CANCELLED, VM.Name()); + Description = string.Format(Messages.COPY_TO_SHARED_CANCELLED, VM.NameWithLocation()); throw; } { VM created = Connection.WaitForCache(new XenRef(Result)); - XenAPI.VM.set_name_description(Session, created.opaque_ref, _namedescription); + VM.set_name_description(Session, created.opaque_ref, _namedescription); } - this.Description = Messages.ACTION_VM_COPIED; - - + Description = Messages.ACTION_VM_COPIED; } } } diff --git a/XenModel/Actions/VM/VMCrossPoolMigrateAction.cs b/XenModel/Actions/VM/VMCrossPoolMigrateAction.cs index efb15d9b24..a8cdeea409 100644 --- a/XenModel/Actions/VM/VMCrossPoolMigrateAction.cs +++ b/XenModel/Actions/VM/VMCrossPoolMigrateAction.cs @@ -55,7 +55,6 @@ public VMCrossPoolMigrateAction(VM vm, Host destinationHost, XenAPI.Network tran : base(vm.Connection, GetTitle(vm, destinationHost, copy)) { Session = vm.Connection.Session; - Description = Messages.ACTION_PREPARING; VM = vm; Host = destinationHost; Pool = Helpers.GetPool(vm.Connection); @@ -80,18 +79,20 @@ public static RbacMethodList StaticRBACDependencies public static string GetTitle(VM vm, Host toHost, bool copy) { if (copy) - return string.Format(Messages.ACTION_VM_CROSS_POOL_COPY_TITLE, vm.Name(), toHost.Name()); + return string.Format(Messages.ACTION_VM_CROSS_POOL_COPY_TITLE, + vm.NameWithLocation(), + Helpers.GetPool(vm.Connection)?.Name() ?? vm.Connection.Name, + toHost.NameWithLocation()); Host residentOn = vm.Connection.Resolve(vm.resident_on); - + return residentOn == null - ? string.Format(Messages.ACTION_VM_MIGRATING_NON_RESIDENT, vm.Name(), toHost.Name()) - : string.Format(Messages.ACTION_VM_MIGRATING_RESIDENT, vm.Name(), Helpers.GetName(residentOn), toHost.Name()); + ? string.Format(Messages.ACTION_VM_MIGRATING_NON_RESIDENT, vm.NameWithLocation(), toHost.NameWithLocation()) + : string.Format(Messages.ACTION_VM_MIGRATING_RESIDENT, vm.Name(), residentOn.NameWithLocation(), toHost.NameWithLocation()); } protected override void Run() { - Description = copy ? Messages.ACTION_VM_COPYING: Messages.ACTION_VM_MIGRATING; try { PercentComplete = 0; @@ -114,7 +115,7 @@ protected override void Run() Description = string.Format(copy ? Messages.ACTION_VM_CROSS_POOL_COPY_CANCELLED : Messages.ACTION_VM_MIGRATE_CANCELLED, - VM.Name()); + VM.NameWithLocation()); throw; } catch (Failure ex) diff --git a/XenModel/Actions/VM/VMMigrateAction.cs b/XenModel/Actions/VM/VMMigrateAction.cs index 9b5a9434a4..47209992e8 100644 --- a/XenModel/Actions/VM/VMMigrateAction.cs +++ b/XenModel/Actions/VM/VMMigrateAction.cs @@ -40,27 +40,22 @@ public class VMMigrateAction : PureAsyncAction { public VMMigrateAction(VM vm, Host destinationHost) - : base(vm.Connection, GetTitle(vm, destinationHost)) + : base(vm.Connection, "") { - this.Description = Messages.ACTION_PREPARING; - this.VM = vm; - this.Host = destinationHost; - this.Pool = Core.Helpers.GetPool(vm.Connection); - } + VM = vm; + Host = destinationHost; + Pool = Helpers.GetPool(vm.Connection); - private static string GetTitle(VM vm, Host toHost) - { - Host residentOn = vm.Connection.Resolve(vm.resident_on); - - return residentOn == null - ? string.Format(Messages.ACTION_VM_MIGRATING_NON_RESIDENT, vm.Name(), toHost.Name()) - : string.Format(Messages.ACTION_VM_MIGRATING_RESIDENT, vm.Name(), Helpers.GetName(residentOn), toHost.Name()); + var residentOn = vm.Connection.Resolve(vm.resident_on); + + Title = residentOn == null + ? string.Format(Messages.ACTION_VM_MIGRATING_NON_RESIDENT, vm.NameWithLocation(), Host.NameWithLocation()) + : string.Format(Messages.ACTION_VM_MIGRATING_RESIDENT, vm.Name(), residentOn.NameWithLocation(), Host.NameWithLocation()); } protected override void Run() { - this.Description = Messages.ACTION_VM_MIGRATING; - RelatedTask = XenAPI.VM.async_live_migrate(Session, VM.opaque_ref, Host.opaque_ref); + RelatedTask = VM.async_live_migrate(Session, VM.opaque_ref, Host.opaque_ref); try { PollToCompletion(); @@ -68,17 +63,15 @@ protected override void Run() catch (Failure f) { if (f.ErrorDescription.Count >= 5 && f.ErrorDescription[0] == "VM_MIGRATE_FAILED" - && f.ErrorDescription[4].Contains("VDI_MISSING")) + && f.ErrorDescription[4].Contains("VDI_MISSING")) { throw new Exception(Messages.MIGRATE_EJECT_TOOLS_ON_UPGRADE); } - else - { - throw; - } + + throw; } - this.Description = Messages.ACTION_VM_MIGRATED; + Description = Messages.ACTION_VM_MIGRATED; } } } diff --git a/XenModel/Actions/VM/VMMoveAction.cs b/XenModel/Actions/VM/VMMoveAction.cs index 5472eefe7a..7f77775e00 100644 --- a/XenModel/Actions/VM/VMMoveAction.cs +++ b/XenModel/Actions/VM/VMMoveAction.cs @@ -45,40 +45,44 @@ public class VMMoveAction : AsyncAction private Dictionary _storageMapping; public VMMoveAction(VM vm, Dictionary storageMapping, Host host) - : base(vm.Connection, string.Format(Messages.ACTION_VM_MOVING, vm.Name())) + : base(vm.Connection, "") { - this.VM = vm; - this.Host = host; - this.Pool = Helpers.GetPool(vm.Connection); + VM = vm; + Host = host; + Pool = Helpers.GetPool(vm.Connection); if (vm.is_a_template) - this.Template = vm; + Template = vm; _storageMapping = storageMapping; SR = _storageMapping.Values.FirstOrDefault(); PopulateApiMethodsToRoleCheck(); + + var sourceHost = vm.Home(); + if (sourceHost != null && !sourceHost.Equals(host)) + Title = string.Format(Messages.ACTION_VM_MOVING_HOST, vm.Name(), sourceHost, host.Name()); + else if (storageMapping.Count == 1) + Title = string.Format(Messages.ACTION_VM_MOVING_SR, vm.Name(), storageMapping.Values.ElementAt(0).Name()); + else + Title = string.Format(Messages.ACTION_VM_MOVING, vm.Name()); } - public VMMoveAction(VM vm, SR sr, Host host, string namelabel) - : base(vm.Connection, string.Format(Messages.ACTION_VM_MOVING_TITLE, vm.Name(), namelabel, sr.NameWithoutHost())) + public VMMoveAction(VM vm, SR sr, Host host) + : this(vm, GetStorageMapping(vm, sr), host) { - this.VM = vm; - this.Host = host; - this.Pool = Helpers.GetPool(vm.Connection); - this.SR = sr; - if (vm.is_a_template) - this.Template = vm; + } - // create a storage map where all VDIs are mapped to the same SR - _storageMapping = new Dictionary(); + private static Dictionary GetStorageMapping(VM vm, SR sr) + { + var storageMapping = new Dictionary(); foreach (var vbdRef in vm.VBDs) { var vbd = vm.Connection.Resolve(vbdRef); if (vbd != null) - _storageMapping.Add(vbd.VDI.opaque_ref, sr); + storageMapping.Add(vbd.VDI.opaque_ref, sr); } + return storageMapping; - PopulateApiMethodsToRoleCheck(); } #region RBAC Dependencies @@ -96,8 +100,6 @@ private void PopulateApiMethodsToRoleCheck() protected override void Run() { - Description = Messages.ACTION_PREPARING; - // move the progress bar above 0, it's more reassuring to see than a blank bar as we copy the first disk PercentComplete += 10; int halfstep = 90 / (VM.VBDs.Count * 2); @@ -126,7 +128,7 @@ protected override void Run() continue; Description = string.Format(Messages.ACTION_MOVING_VDI_TO_SR, - Helpers.GetName(curVdi), Helpers.GetName(sr)); + Helpers.GetName(curVdi), Helpers.GetName(Connection.Resolve(curVdi.SR)), Helpers.GetName(sr)); RelatedTask = VDI.async_copy(Session, oldVBD.VDI.opaque_ref, sr.opaque_ref); PollToCompletion(PercentComplete, PercentComplete + halfstep); @@ -160,11 +162,13 @@ protected override void Run() PercentComplete += halfstep; } + Description = string.Empty; + if (SR != null) VM.set_suspend_SR(Session, VM.opaque_ref, SR.opaque_ref); if (exceptions.Count > 0) - throw new Exception(Messages.ACTION_VM_MOVING_VDI_DESTROY_FAILURE); + throw new Exception(string.Format(Messages.ACTION_VM_MOVING_VDI_DESTROY_FAILURE, VM.NameWithLocation())); Description = Messages.MOVED; } diff --git a/XenModel/Alerts/PerfmonDefinition.cs b/XenModel/Alerts/PerfmonDefinition.cs index b0027b48b6..9b05ff2244 100644 --- a/XenModel/Alerts/PerfmonDefinition.cs +++ b/XenModel/Alerts/PerfmonDefinition.cs @@ -287,24 +287,20 @@ private static PerfmonDefinition[] GetPerfmonDefinitions(string xml) public static PerfmonDefinition[] GetPerfmonDefinitions(IXenObject xo) { if (!(xo is VM) && !(xo is Host) && !(xo is SR)) - return new PerfmonDefinition[0]; + return Array.Empty(); - Dictionary other_config = Helpers.GetOtherConfig(xo); + var other_config = Helpers.GetOtherConfig(xo); if (other_config == null) - return new PerfmonDefinition[0]; + return Array.Empty(); if (!other_config.ContainsKey(PERFMON_KEY_NAME)) - return new PerfmonDefinition[0]; + return Array.Empty(); - string perfmonConfigXML = other_config[PERFMON_KEY_NAME]; + var perfmonConfigXML = other_config[PERFMON_KEY_NAME]; if (perfmonConfigXML == null) - return new PerfmonDefinition[0]; - - perfmonConfigXML.Trim(); - if (String.IsNullOrEmpty(perfmonConfigXML)) - return new PerfmonDefinition[0]; + return Array.Empty(); - return GetPerfmonDefinitions(perfmonConfigXML); + return string.IsNullOrWhiteSpace(perfmonConfigXML) ? Array.Empty() : GetPerfmonDefinitions(perfmonConfigXML); } /// diff --git a/XenModel/Alerts/PerfmonOptionsDefinition.cs b/XenModel/Alerts/PerfmonOptionsDefinition.cs index 49bff4d9f3..5f920c7fb9 100755 --- a/XenModel/Alerts/PerfmonOptionsDefinition.cs +++ b/XenModel/Alerts/PerfmonOptionsDefinition.cs @@ -213,74 +213,53 @@ public static PerfmonOptionsDefinition GetPerfmonOptionsDefinitions(IXenObject x public static string GetMailDestination(IXenConnection connection) { - Pool pool = Helpers.GetPoolOfOne(connection); + var pool = Helpers.GetPoolOfOne(connection); if (pool == null) return null; - Dictionary other_config = Helpers.GetOtherConfig(pool); - if (other_config == null) + var otherConfig = Helpers.GetOtherConfig(pool); + if (otherConfig == null) return null; - if (!other_config.ContainsKey(MAIL_DESTINATION_KEY_NAME)) + if (!otherConfig.ContainsKey(MAIL_DESTINATION_KEY_NAME)) return null; - String mailAddress = other_config[MAIL_DESTINATION_KEY_NAME]; - if (mailAddress == null) - return null; - - mailAddress.Trim(); - if (String.IsNullOrEmpty(mailAddress)) - return null; - - return mailAddress; + var mailAddress = otherConfig[MAIL_DESTINATION_KEY_NAME]?.Trim(); + return string.IsNullOrEmpty(mailAddress) ? null : mailAddress; } public static string GetSmtpMailHub(IXenConnection connection) { - Pool pool = Helpers.GetPoolOfOne(connection); + var pool = Helpers.GetPoolOfOne(connection); if (pool == null) return null; - Dictionary other_config = Helpers.GetOtherConfig(pool); - if (other_config == null) - return null; - - if (!other_config.ContainsKey(SMTP_MAILHUB_KEY_NAME)) + var otherConfig = Helpers.GetOtherConfig(pool); + if (otherConfig == null) return null; - String mailHub = other_config[SMTP_MAILHUB_KEY_NAME]; - if (mailHub == null) + if (!otherConfig.ContainsKey(SMTP_MAILHUB_KEY_NAME)) return null; - mailHub.Trim(); - if (String.IsNullOrEmpty(mailHub)) - return null; - - return mailHub; + var mailHub = otherConfig[SMTP_MAILHUB_KEY_NAME]?.Trim(); + return string.IsNullOrEmpty(mailHub) ? null : mailHub; } public static string GetMailLanguageCode(IXenConnection connection) { - Pool pool = Helpers.GetPoolOfOne(connection); + var pool = Helpers.GetPoolOfOne(connection); if (pool == null) return null; - Dictionary other_config = Helpers.GetOtherConfig(pool); - if (other_config == null) - return null; - - if (!other_config.ContainsKey(MAIL_LANGUAGE_KEY_NAME)) - return null; - - String mailLanguageCode = other_config[MAIL_LANGUAGE_KEY_NAME]; - if (mailLanguageCode == null) + var otherConfig = Helpers.GetOtherConfig(pool); + if (otherConfig == null) return null; - mailLanguageCode.Trim(); - if (String.IsNullOrEmpty(mailLanguageCode)) + if (!otherConfig.ContainsKey(MAIL_LANGUAGE_KEY_NAME)) return null; - return mailLanguageCode; + var mailLanguageCode = otherConfig[MAIL_LANGUAGE_KEY_NAME]?.Trim(); + return string.IsNullOrEmpty(mailLanguageCode) ? null : mailLanguageCode; } public static String MailLanguageNameFromCode(String code) diff --git a/XenModel/BrandManager.cs b/XenModel/BrandManager.cs index 2f2416c70d..cd05cbcbc9 100644 --- a/XenModel/BrandManager.cs +++ b/XenModel/BrandManager.cs @@ -82,6 +82,8 @@ public class BrandManager public static readonly string ProductVersion82 = Get("PRODUCT_VERSION_8_2"); + public static readonly string ProductVersion821 = Get("PRODUCT_VERSION_8_2_1"); + public static readonly string ProductVersionPost82 = Get("PRODUCT_VERSION_POST_8_2"); public static readonly string ProductVersionText = Get("PRODUCT_VERSION_TEXT"); diff --git a/XenModel/CustomFields/CustomFieldsCache.cs b/XenModel/CustomFields/CustomFieldsCache.cs index 28d1a6ede8..6b18b9d397 100644 --- a/XenModel/CustomFields/CustomFieldsCache.cs +++ b/XenModel/CustomFields/CustomFieldsCache.cs @@ -68,36 +68,25 @@ public void RecalculateCustomFields() private static List GetCustomFieldsFromGuiConfig(IXenConnection connection) { - Pool pool = Helpers.GetPoolOfOne(connection); + var pool = Helpers.GetPoolOfOne(connection); if (pool == null) { return new List(); } - Dictionary other_config = Helpers.GetGuiConfig(pool); - if (other_config == null) + var otherConfig = Helpers.GetGuiConfig(pool); + if (otherConfig == null) { return new List(); } - if (!other_config.ContainsKey(CustomFieldsManager.CUSTOM_FIELD_BASE_KEY)) + if (!otherConfig.ContainsKey(CustomFieldsManager.CUSTOM_FIELD_BASE_KEY)) { return new List(); } - String customFields = other_config[CustomFieldsManager.CUSTOM_FIELD_BASE_KEY]; - if (customFields == null) - { - return new List(); - } - - customFields.Trim(); - if (String.IsNullOrEmpty(customFields)) - { - return new List(); - } - - return GetCustomFieldDefinitions(customFields); + var customFields = otherConfig[CustomFieldsManager.CUSTOM_FIELD_BASE_KEY]?.Trim(); + return string.IsNullOrEmpty(customFields) ? new List() : GetCustomFieldDefinitions(customFields); } public List GetCustomFields() diff --git a/XenModel/Mappings/VmMapping.cs b/XenModel/Mappings/VmMapping.cs index a7c85a665c..0696f002e4 100644 --- a/XenModel/Mappings/VmMapping.cs +++ b/XenModel/Mappings/VmMapping.cs @@ -44,6 +44,11 @@ public VmMapping() } public string VmNameLabel { get; set; } + public ulong Capacity { get; set; } + public ulong CpuCount { get; set; } + public ulong Memory { get; set; } + public string BootParams { get; set; } + public string PlatformSettings { get; set; } /// /// OpaqueRef of the target pool or host @@ -66,5 +71,26 @@ public VmMapping() /// Keyed on the id in the ovf file /// public Dictionary Networks { get; set; } - } + + public override bool Equals(object obj) + { + return obj is VmMapping other && + VmNameLabel == other.VmNameLabel && + Capacity == other.Capacity && + CpuCount == other.CpuCount && + Memory == other.Memory && + BootParams == other.BootParams && + PlatformSettings == other.PlatformSettings && + XenRef == other.XenRef && + TargetName == other.TargetName && + Storage == other.Storage && + StorageToAttach == other.StorageToAttach && + Networks == other.Networks; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } } diff --git a/XenModel/Messages.Designer.cs b/XenModel/Messages.Designer.cs index a4d12dd2f5..caf1406dcd 100755 --- a/XenModel/Messages.Designer.cs +++ b/XenModel/Messages.Designer.cs @@ -1593,16 +1593,7 @@ public class Messages { } /// - /// Looks up a localized string similar to Moving virtual disk '{0}'.... - /// - public static string ACTION_MOVING_VDI { - get { - return ResourceManager.GetString("ACTION_MOVING_VDI", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Moving Virtual Disk '{0}' to SR '{1}'. + /// Looks up a localized string similar to Moving Virtual Disk '{0}' from SR '{1}' to SR '{2}'. /// public static string ACTION_MOVING_VDI_TO_SR { get { @@ -2663,15 +2654,6 @@ public class Messages { } } - /// - /// Looks up a localized string similar to Duplicating. - /// - public static string ACTION_TEMPLATE_CLONING { - get { - return ResourceManager.GetString("ACTION_TEMPLATE_CLONING", resourceCulture); - } - } - /// /// Looks up a localized string similar to Restart toolstack on '{0}'. /// @@ -3114,7 +3096,7 @@ public class Messages { } /// - /// Looks up a localized string similar to Copying VM '{0}' to '{1}'. + /// Looks up a localized string similar to Copying VM '{0}' from '{1}' to '{2}'. /// public static string ACTION_VM_CROSS_POOL_COPY_TITLE { get { @@ -3231,11 +3213,20 @@ public class Messages { } /// - /// Looks up a localized string similar to Moving VM '{0}' to '{1}' on SR '{2}'. + /// Looks up a localized string similar to Moving VM '{0}' from server '{1}' to server '{2}'. /// - public static string ACTION_VM_MOVING_TITLE { + public static string ACTION_VM_MOVING_HOST { get { - return ResourceManager.GetString("ACTION_VM_MOVING_TITLE", resourceCulture); + return ResourceManager.GetString("ACTION_VM_MOVING_HOST", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moving VM '{0}' to SR '{1}'. + /// + public static string ACTION_VM_MOVING_SR { + get { + return ResourceManager.GetString("ACTION_VM_MOVING_SR", resourceCulture); } } @@ -15294,6 +15285,15 @@ public class Messages { } } + /// + /// Looks up a localized string similar to You cannot enable certificate verification while a rolling pool upgrade is in progress.. + /// + public static string ENABLE_TLS_VERIFICATION_RPU { + get { + return ResourceManager.GetString("ENABLE_TLS_VERIFICATION_RPU", resourceCulture); + } + } + /// /// Looks up a localized string similar to Res&ume. /// @@ -16978,6 +16978,24 @@ public class Messages { } } + /// + /// Looks up a localized string similar to A file name cannot be a device name.. + /// + public static string FILE_NAME_IS_DEVICE_NAME_ERROR_MESSAGE { + get { + return ResourceManager.GetString("FILE_NAME_IS_DEVICE_NAME_ERROR_MESSAGE", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Path section {0} matches a device name.. + /// + public static string FILE_PATH_DEVICE_NAME_ERROR_MESSAGE { + get { + return ResourceManager.GetString("FILE_PATH_DEVICE_NAME_ERROR_MESSAGE", resourceCulture); + } + } + /// /// Looks up a localized string similar to Acrobat (PDF) file. /// @@ -20224,6 +20242,15 @@ public class Messages { } } + /// + /// Looks up a localized string similar to The following characters are invalid: {0}. + /// + public static string ILLEGAL_CHARACTER_ERROR_MESSAGE { + get { + return ResourceManager.GetString("ILLEGAL_CHARACTER_ERROR_MESSAGE", resourceCulture); + } + } + /// /// Looks up a localized string similar to It is not possible to connect to the iLO service. Please review your configuration.. /// @@ -30178,6 +30205,15 @@ public class Messages { } } + /// + /// Looks up a localized string similar to Path cannot be null or empty.. + /// + public static string PATH_CAN_NOT_BE_NULL_ERROR_MESSAGE { + get { + return ResourceManager.GetString("PATH_CAN_NOT_BE_NULL_ERROR_MESSAGE", resourceCulture); + } + } + /// /// Looks up a localized string similar to Path does not exist.. /// diff --git a/XenModel/Messages.resx b/XenModel/Messages.resx index 8804aca6c9..507ce5020f 100755 --- a/XenModel/Messages.resx +++ b/XenModel/Messages.resx @@ -629,11 +629,8 @@ This could be because the data source is not generating any data. Ensure the pre Started migrating virtual disks - - Moving virtual disk '{0}'... - - Moving Virtual Disk '{0}' to SR '{1}' + Moving Virtual Disk '{0}' from SR '{1}' to SR '{2}' Moving {0} virtual disks to {1} @@ -986,9 +983,6 @@ This could be because the data source is not generating any data. Ensure the pre Copy of {0} - - Duplicating - Toolstack restarted. @@ -1158,7 +1152,7 @@ This could be because the data source is not generating any data. Ensure the pre Copying {0} canceled - Copying VM '{0}' to '{1}' + Copying VM '{0}' from '{1}' to '{2}' Deleting snapshots @@ -1196,8 +1190,11 @@ This could be because the data source is not generating any data. Ensure the pre Moving VM '{0}' to new storage - - Moving VM '{0}' to '{1}' on SR '{2}' + + Moving VM '{0}' from server '{1}' to server '{2}' + + + Moving VM '{0}' to SR '{1}' Failed to finalize moving VM '{0}' to new storage. Please see logs for details. @@ -5382,6 +5379,9 @@ Would you like to eject these ISOs before continuing? {1} + + You cannot enable certificate verification while a rolling pool upgrade is in progress. + Res&ume @@ -5938,6 +5938,12 @@ Would you like to eject these ISOs before continuing? All files + + A file name cannot be a device name. + + + Path section {0} matches a device name. + Acrobat (PDF) file @@ -7046,6 +7052,9 @@ This might result in failure to migrate VMs to this server during the RPU or to &Ignore + + The following characters are invalid: {0} + It is not possible to connect to the iLO service. Please review your configuration. @@ -10465,6 +10474,9 @@ File not found Update uploaded to server '{0}' + + Path cannot be null or empty. + Path does not exist. diff --git a/XenModel/Network/XenConnection.cs b/XenModel/Network/XenConnection.cs index d69d895eed..b1d0960969 100644 --- a/XenModel/Network/XenConnection.cs +++ b/XenModel/Network/XenConnection.cs @@ -41,6 +41,7 @@ using XenAPI; using XenCenterLib; using System.Diagnostics; +using System.Linq; using System.Xml.Serialization; using XenAdmin.ServerDBs; @@ -1757,12 +1758,14 @@ private void ReconnectCoordinator() private Pool getAPool(ICache objects, out string opaqueref) { - foreach (Pool pool in objects.Pools) + var pools = objects.Pools; + if (pools.Length > 0) { + var pool = pools.First(); opaqueref = pool.opaque_ref; return pool; } - System.Diagnostics.Trace.Assert(false); + Trace.Assert(false); opaqueref = null; return null; } diff --git a/XenModel/PathValidator.cs b/XenModel/PathValidator.cs new file mode 100644 index 0000000000..10e9338478 --- /dev/null +++ b/XenModel/PathValidator.cs @@ -0,0 +1,135 @@ +/* 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.IO; +using System.Linq; +using XenAdmin; + +namespace XenModel +{ + public class PathValidator + { + private static readonly char[] m_invalidFileCharList = Path.GetInvalidFileNameChars(); + private static readonly string[] m_deviceNames = { + "CON", "PRN", "AUX", "NUL", + "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", + "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" + }; + + private static string IllegalFileCharMsg { + get { + return string.Format(Messages.ILLEGAL_CHARACTER_ERROR_MESSAGE, string.Join(" ", m_invalidFileCharList.Where(c => !char.IsControl(c)))); + } + } + + private static string IllegalPathCharMsg + { + get + { + return string.Format(Messages.ILLEGAL_CHARACTER_ERROR_MESSAGE, string.Join(" ", m_invalidFileCharList.Where(c => !char.IsControl(c) && c != '\\'))); + + } + } + + public static bool IsFileNameValid(string filename, out string invalidNameMsg) + { + invalidNameMsg = string.Empty; + if (filename.IndexOfAny(m_invalidFileCharList) > -1) + { + invalidNameMsg = IllegalFileCharMsg; + return false; + } + + foreach (var name in m_deviceNames) + { + if (name == filename.ToUpper()) + { + invalidNameMsg = Messages.FILE_NAME_IS_DEVICE_NAME_ERROR_MESSAGE; + return false; + } + } + + return true; + } + + public static bool IsPathValid(string path, out string invalidPathMsg) + { + invalidPathMsg = string.Empty; + if (string.IsNullOrEmpty(path)) + { + invalidPathMsg = Messages.PATH_CAN_NOT_BE_NULL_ERROR_MESSAGE; + return false; + } + + try + { + if (Path.IsPathRooted(path)) + { + path = path[0] == '\\' && path.Length == 1 + ? path.Substring(1) + : path.Substring(2); + } + } + catch (ArgumentException) + { + //path contains some of the characters from Path.GetInvalidPathChars() + invalidPathMsg = IllegalPathCharMsg; + return false; + } + + var parts = path.Split('\\'); + + if (parts.Length > 0) + { + foreach (var part in parts) + { + if (part.IndexOfAny(m_invalidFileCharList) > -1) + { + invalidPathMsg = IllegalPathCharMsg; + return false; + } + + foreach (var name in m_deviceNames) + { + if (name == part.ToUpper()) + { + invalidPathMsg = string.Format(Messages.FILE_PATH_DEVICE_NAME_ERROR_MESSAGE, name); + return false; + } + } + } + } + + return true; + } + } +} diff --git a/XenModel/ServerDBs/FakeAPI/fakeHost.cs b/XenModel/ServerDBs/FakeAPI/fakeHost.cs index decdc3cc5c..8fc2a30eae 100644 --- a/XenModel/ServerDBs/FakeAPI/fakeHost.cs +++ b/XenModel/ServerDBs/FakeAPI/fakeHost.cs @@ -34,6 +34,7 @@ using XenAPI; using System.Collections; using System.Globalization; +using System.Linq; using System.Threading; namespace XenAdmin.ServerDBs.FakeAPI @@ -107,14 +108,14 @@ public Response apply_edition(string dummy, string hostOpaqueRef, string public Response reboot(string session, string opaque_ref) { - string metrics_ref = (string)proxy.db.GetValue("host", opaque_ref, "metrics"); + var metrics_ref = (string)proxy.db.GetValue("host", opaque_ref, "metrics"); proxy.EditObject_(DbProxy.EditTypes.Replace, "host_metrics", metrics_ref, "live", false); - string coordinator_ref = ""; - foreach (string pool in proxy.db.Tables["pool"].Rows.Keys) + var coordinator_ref = string.Empty; + var pools = proxy.db.Tables["pool"].Rows.Keys; + if (pools.Count > 0) { - coordinator_ref = (string)proxy.db.GetValue("pool", pool, "master"); - break; + coordinator_ref = (string)proxy.db.GetValue("pool", pools.First(), "master"); } if (opaque_ref == coordinator_ref) diff --git a/XenModel/Utils/Helpers.cs b/XenModel/Utils/Helpers.cs index 3e12d011d8..52a614068e 100755 --- a/XenModel/Utils/Helpers.cs +++ b/XenModel/Utils/Helpers.cs @@ -212,13 +212,7 @@ public static Pool GetPool(IXenConnection connection) /// public static Pool GetPoolOfOne(IXenConnection connection) { - if (connection == null) - return null; - - foreach (Pool pool in connection.Cache.Pools) - return pool; - - return null; + return connection?.Cache.Pools.FirstOrDefault(); } /// @@ -497,6 +491,12 @@ public static bool PostStockholm(string platformVersion) return platformVersion != null && productVersionCompare(platformVersion, "3.2.50") >= 0; } + /// May be null, in which case true is returned. + public static bool YangtzeOrGreater(IXenConnection conn) + { + return conn == null || YangtzeOrGreater(Helpers.GetCoordinator(conn)); + } + /// May be null, in which case true is returned. public static bool YangtzeOrGreater(Host host) { @@ -1545,11 +1545,9 @@ public static IXenObject XenObjectFromMessage(XenAPI.Message message) public static string HostnameFromLocation(string p) { - foreach (Match m in HostnameOrIpRegex.Matches(p)) - { - return m.Value; // we only want the hostname or ip which should be the first match - } - return ""; + var matches = HostnameOrIpRegex.Matches(p); + // we only want the hostname or ip which should be the first match + return matches.Count > 0 ? matches[0].Value : string.Empty; } /// diff --git a/XenModel/Utils/Util.cs b/XenModel/Utils/Util.cs index c041611592..d7fd2dc4ea 100644 --- a/XenModel/Utils/Util.cs +++ b/XenModel/Utils/Util.cs @@ -33,6 +33,7 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Xml; @@ -476,20 +477,6 @@ public static void ThrowIfStringParameterNullOrEmpty(string value, string name) } } - public static void ThrowIfEnumerableParameterNullOrEmpty(IEnumerable value, string name) - { - ThrowIfParameterNull(value, name); - -#pragma warning disable 0168 - foreach (object _ in value) - { - return; - } -#pragma warning restore 0168 - - ThrowBecauseZeroLength(name); - } - private static void ThrowBecauseZeroLength(string name) { throw new ArgumentException(string.Format("{0} cannot have 0 length.", name), name); @@ -574,17 +561,13 @@ public static string GetContentsOfValueNode(string xml) { ThrowIfStringParameterNullOrEmpty(xml, "xml"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.LoadXml(xml); // If we've got this from an async task result, then it will be wrapped // in a element. - foreach (XmlNode node in doc.GetElementsByTagName("value")) - { - return node.InnerText; - } - - return null; + var nodes = doc.GetElementsByTagName("value"); + return nodes.Count > 0 ? nodes[0].InnerText : null; } } diff --git a/XenModel/WLB/WlbReportSubscription.cs b/XenModel/WLB/WlbReportSubscription.cs index 439a8def3d..1b7feffaf2 100644 --- a/XenModel/WLB/WlbReportSubscription.cs +++ b/XenModel/WLB/WlbReportSubscription.cs @@ -38,32 +38,32 @@ public class WlbReportSubscription : WlbConfigurationBase { #region Variables - private static string SUB_ID = "id"; - private static string CREATED = "created"; - private static string SUB_NAME = "name"; - private static string SUB_DESCRIPTION = "description"; - private static string SUBSCRIBER_ID = "subscriberId"; - private static string SUBSCRIBER_NAME = "subscriberName"; - private static string SCHEDULE_ID = "scheduleId"; - private static string DAYOFWEEK = "daysOfWeek"; - private static string EXECUTE_TIMEOFDAY = "executeTimeOfDay"; - private static string TRIGGER_TYPE = "triggerType"; - private static string ENABLED = "enabled"; - private static string ENABLE_DATE = "enableDate"; - private static string DISABLE_DATE = "disableDate"; - private static string LAST_TOUCHED = "lastTouched"; - private static string LAST_TOUCHEDBY = "lastTouchedBy"; - private static string LAST_RUN = "lastRun"; - private static string LAST_RUNRESULT = "lastRunResult"; - private static string EMAIL_TO = "emailTo"; - private static string EMAIL_REPLYTO = "emailReplyTo"; - private static string REPORT_RENDERFORMAT = "rpRenderFormat"; - private static string EMAIL_SUBJECT = "emailSubject"; - private static string EMAIL_COMMENT = "emailComment"; - private static string EMAIL_CC = "emailCc"; - private static string EMAIL_BCC = "emailBcc"; - private static string REPORT_ID = "reportId"; - public static string REPORT_NAME = "reportName"; + private const string SUB_ID_KEY = "id"; + private const string CREATED_KEY = "created"; + private const string SUB_NAME_KEY = "name"; + private const string SUB_DESCRIPTION_KEY = "description"; + private const string SUBSCRIBER_ID_KEY = "subscriberId"; + private const string SUBSCRIBER_NAME_KEY = "subscriberName"; + private const string SCHEDULE_ID_KEY = "scheduleId"; + private const string DAYOFWEEK_KEY = "daysOfWeek"; + private const string EXECUTE_TIMEOFDAY_KEY = "executeTimeOfDay"; + private const string TRIGGER_TYPE_KEY = "triggerType"; + private const string ENABLED_KEY = "enabled"; + private const string ENABLE_DATE_KEY = "enableDate"; + private const string DISABLE_DATE_KEY = "disableDate"; + private const string LAST_TOUCHED_KEY = "lastTouched"; + private const string LAST_TOUCHEDBY_KEY = "lastTouchedBy"; + private const string LAST_RUN_KEY = "lastRun"; + private const string LAST_RUNRESULT_KEY = "lastRunResult"; + private const string EMAIL_TO_KEY = "emailTo"; + private const string EMAIL_REPLYTO_KEY = "emailReplyTo"; + private const string REPORT_RENDERFORMAT_KEY = "rpRenderFormat"; + private const string EMAIL_SUBJECT_KEY = "emailSubject"; + private const string EMAIL_COMMENT_KEY = "emailComment"; + private const string EMAIL_CC_KEY = "emailCc"; + private const string EMAIL_BCC_KEY = "emailBcc"; + private const string REPORT_ID_KEY = "reportId"; + public const string REPORT_NAME_KEY = "reportName"; private string _reportDisplayName; @@ -101,41 +101,41 @@ public enum WlbReportRenderFormat : int /// Subscription id public WlbReportSubscription(string id) { - base.Configuration = new Dictionary(); - base.KeyBase = WlbConfigurationKeyBase.rpSub; - base.ItemId = (String.IsNullOrEmpty(id) ? "0" : id); - this._reportDisplayName = String.Empty; + Configuration = new Dictionary(); + KeyBase = WlbConfigurationKeyBase.rpSub; + ItemId = string.IsNullOrEmpty(id) ? "0" : id; + _reportDisplayName = string.Empty; //Define the known keys - base.WlbConfigurationKeys = - new List(new string[] + WlbConfigurationKeys = + new List(new[] { - SUB_ID, - CREATED, - SUB_NAME, - SUB_DESCRIPTION, - SUBSCRIBER_ID, - SUBSCRIBER_NAME, - SCHEDULE_ID, - DAYOFWEEK, - EXECUTE_TIMEOFDAY, - TRIGGER_TYPE, - ENABLED, - ENABLE_DATE, - DISABLE_DATE, - LAST_TOUCHED, - LAST_TOUCHEDBY, - LAST_RUN, - LAST_RUNRESULT, - EMAIL_TO, - EMAIL_REPLYTO, - REPORT_RENDERFORMAT, - EMAIL_SUBJECT, - EMAIL_COMMENT, - EMAIL_CC, - EMAIL_BCC, - REPORT_ID, - REPORT_NAME + SUB_ID_KEY, + CREATED_KEY, + SUB_NAME_KEY, + SUB_DESCRIPTION_KEY, + SUBSCRIBER_ID_KEY, + SUBSCRIBER_NAME_KEY, + SCHEDULE_ID_KEY, + DAYOFWEEK_KEY, + EXECUTE_TIMEOFDAY_KEY, + TRIGGER_TYPE_KEY, + ENABLED_KEY, + ENABLE_DATE_KEY, + DISABLE_DATE_KEY, + LAST_TOUCHED_KEY, + LAST_TOUCHEDBY_KEY, + LAST_RUN_KEY, + LAST_RUNRESULT_KEY, + EMAIL_TO_KEY, + EMAIL_REPLYTO_KEY, + REPORT_RENDERFORMAT_KEY, + EMAIL_SUBJECT_KEY, + EMAIL_COMMENT_KEY, + EMAIL_CC_KEY, + EMAIL_BCC_KEY, + REPORT_ID_KEY, + REPORT_NAME_KEY }); } @@ -148,8 +148,8 @@ public WlbReportSubscription(string id) /// public string Id { - get { return GetConfigValueString(base.BuildComplexKey(SUB_ID)); } - set { SetConfigValueString(base.BuildComplexKey(SUB_ID), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(SUB_ID_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(SUB_ID_KEY), value, true); } } /// @@ -157,8 +157,8 @@ public string Id /// public DateTime Created { - get { return GetConfigValueUTCDateTime(base.BuildComplexKey(CREATED)); } - set { SetConfigValueUTCDateTime(base.BuildComplexKey(CREATED), value, true); } + get { return GetConfigValueUTCDateTime(base.BuildComplexKey(CREATED_KEY)); } + set { SetConfigValueUTCDateTime(base.BuildComplexKey(CREATED_KEY), value, true); } } /// @@ -166,8 +166,8 @@ public DateTime Created /// public string Name { - get { return GetConfigValueString(base.BuildComplexKey(SUB_NAME)); } - set { SetConfigValueString(base.BuildComplexKey(SUB_NAME), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(SUB_NAME_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(SUB_NAME_KEY), value, true); } } /// @@ -175,8 +175,8 @@ public string Name /// public string Description { - get { return GetConfigValueString(base.BuildComplexKey(SUB_DESCRIPTION)); } - set { SetConfigValueString(base.BuildComplexKey(SUB_DESCRIPTION), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(SUB_DESCRIPTION_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(SUB_DESCRIPTION_KEY), value, true); } } /// @@ -184,8 +184,8 @@ public string Description /// public string SubscriberId { - get { return GetConfigValueString(base.BuildComplexKey(SUBSCRIBER_ID)); } - set { SetConfigValueString(base.BuildComplexKey(SUBSCRIBER_ID), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(SUBSCRIBER_ID_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(SUBSCRIBER_ID_KEY), value, true); } } /// @@ -193,8 +193,8 @@ public string SubscriberId /// public string SubscriberName { - get { return GetConfigValueString(base.BuildComplexKey(SUBSCRIBER_NAME)); } - set { SetConfigValueString(base.BuildComplexKey(SUBSCRIBER_NAME), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(SUBSCRIBER_NAME_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(SUBSCRIBER_NAME_KEY), value, true); } } /// @@ -202,8 +202,8 @@ public string SubscriberName /// public string ScheduleId { - get { return GetConfigValueString(base.BuildComplexKey(SCHEDULE_ID)); } - set { SetConfigValueString(base.BuildComplexKey(SCHEDULE_ID), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(SCHEDULE_ID_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(SCHEDULE_ID_KEY), value, true); } } /// @@ -211,8 +211,8 @@ public string ScheduleId /// public WlbScheduledTask.WlbTaskDaysOfWeek DaysOfWeek { - get { return (WlbScheduledTask.WlbTaskDaysOfWeek)GetConfigValueInt(base.BuildComplexKey(DAYOFWEEK)); } - set { SetConfigValueInt(base.BuildComplexKey(DAYOFWEEK), (int)value, true); } + get { return (WlbScheduledTask.WlbTaskDaysOfWeek)GetConfigValueInt(base.BuildComplexKey(DAYOFWEEK_KEY)); } + set { SetConfigValueInt(base.BuildComplexKey(DAYOFWEEK_KEY), (int)value, true); } } /// @@ -220,8 +220,8 @@ public WlbScheduledTask.WlbTaskDaysOfWeek DaysOfWeek /// public DateTime RunTimeOfDay { - get { return GetConfigValueUTCDateTime(base.BuildComplexKey(EXECUTE_TIMEOFDAY)); } - set { SetConfigValueUTCDateTime(base.BuildComplexKey(EXECUTE_TIMEOFDAY), value, true); } + get { return GetConfigValueUTCDateTime(base.BuildComplexKey(EXECUTE_TIMEOFDAY_KEY)); } + set { SetConfigValueUTCDateTime(base.BuildComplexKey(EXECUTE_TIMEOFDAY_KEY), value, true); } } /// @@ -229,8 +229,8 @@ public DateTime RunTimeOfDay /// public int TriggerType { - get { return GetConfigValueInt(base.BuildComplexKey(TRIGGER_TYPE)); } - set { SetConfigValueInt(base.BuildComplexKey(TRIGGER_TYPE), value, true); } + get { return GetConfigValueInt(base.BuildComplexKey(TRIGGER_TYPE_KEY)); } + set { SetConfigValueInt(base.BuildComplexKey(TRIGGER_TYPE_KEY), value, true); } } /// @@ -238,8 +238,8 @@ public int TriggerType /// public bool Enabled { - get { return GetConfigValueBool(base.BuildComplexKey(ENABLED)); } - set { SetConfigValueBool(base.BuildComplexKey(ENABLED), value, true); } + get { return GetConfigValueBool(base.BuildComplexKey(ENABLED_KEY)); } + set { SetConfigValueBool(base.BuildComplexKey(ENABLED_KEY), value, true); } } /// @@ -247,8 +247,8 @@ public bool Enabled /// public DateTime EnableDate { - get { return GetConfigValueUTCDateTime(base.BuildComplexKey(ENABLE_DATE)); } - set { SetConfigValueUTCDateTime(base.BuildComplexKey(ENABLE_DATE), value, true); } + get { return GetConfigValueUTCDateTime(base.BuildComplexKey(ENABLE_DATE_KEY)); } + set { SetConfigValueUTCDateTime(base.BuildComplexKey(ENABLE_DATE_KEY), value, true); } } /// @@ -256,8 +256,8 @@ public DateTime EnableDate /// public DateTime DisableDate { - get { return GetConfigValueUTCDateTime(base.BuildComplexKey(DISABLE_DATE)); } - set { SetConfigValueUTCDateTime(base.BuildComplexKey(DISABLE_DATE), value, true); } + get { return GetConfigValueUTCDateTime(base.BuildComplexKey(DISABLE_DATE_KEY)); } + set { SetConfigValueUTCDateTime(base.BuildComplexKey(DISABLE_DATE_KEY), value, true); } } /// @@ -265,8 +265,8 @@ public DateTime DisableDate /// public DateTime LastTouched { - get { return GetConfigValueUTCDateTime(base.BuildComplexKey(LAST_TOUCHED)); } - set { SetConfigValueUTCDateTime(base.BuildComplexKey(LAST_TOUCHED), value, true); } + get { return GetConfigValueUTCDateTime(base.BuildComplexKey(LAST_TOUCHED_KEY)); } + set { SetConfigValueUTCDateTime(base.BuildComplexKey(LAST_TOUCHED_KEY), value, true); } } /// @@ -274,8 +274,8 @@ public DateTime LastTouched /// public string LastTouchedBy { - get { return GetConfigValueString(base.BuildComplexKey(LAST_TOUCHEDBY)); } - set { SetConfigValueString(base.BuildComplexKey(LAST_TOUCHEDBY), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(LAST_TOUCHEDBY_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(LAST_TOUCHEDBY_KEY), value, true); } } /// @@ -283,8 +283,8 @@ public string LastTouchedBy /// public DateTime LastRun { - get { return GetConfigValueUTCDateTime(base.BuildComplexKey(LAST_RUN)); } - set { SetConfigValueUTCDateTime(base.BuildComplexKey(LAST_RUN), value, true); } + get { return GetConfigValueUTCDateTime(base.BuildComplexKey(LAST_RUN_KEY)); } + set { SetConfigValueUTCDateTime(base.BuildComplexKey(LAST_RUN_KEY), value, true); } } /// @@ -292,8 +292,8 @@ public DateTime LastRun /// public string LastRunResult { - get { return GetConfigValueString(base.BuildComplexKey(LAST_RUNRESULT)); } - set { SetConfigValueString(base.BuildComplexKey(LAST_RUNRESULT), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(LAST_RUNRESULT_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(LAST_RUNRESULT_KEY), value, true); } } /// @@ -301,8 +301,8 @@ public string LastRunResult /// public string EmailTo { - get { return GetConfigValueString(base.BuildComplexKey(EMAIL_TO)); } - set { SetConfigValueString(base.BuildComplexKey(EMAIL_TO), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(EMAIL_TO_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(EMAIL_TO_KEY), value, true); } } /// @@ -310,8 +310,8 @@ public string EmailTo /// public string EmailReplyTo { - get { return GetConfigValueString(base.BuildComplexKey(EMAIL_REPLYTO)); } - set { SetConfigValueString(base.BuildComplexKey(EMAIL_REPLYTO), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(EMAIL_REPLYTO_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(EMAIL_REPLYTO_KEY), value, true); } } /// @@ -319,8 +319,8 @@ public string EmailReplyTo /// public int ReportRenderFormat { - get { return GetConfigValueInt(base.BuildComplexKey(REPORT_RENDERFORMAT)); } - set { SetConfigValueInt(base.BuildComplexKey(REPORT_RENDERFORMAT), (int)value, true); } + get { return GetConfigValueInt(base.BuildComplexKey(REPORT_RENDERFORMAT_KEY)); } + set { SetConfigValueInt(base.BuildComplexKey(REPORT_RENDERFORMAT_KEY), (int)value, true); } } /// @@ -328,8 +328,8 @@ public int ReportRenderFormat /// public string EmailSubject { - get { return GetConfigValueString(base.BuildComplexKey(EMAIL_SUBJECT)); } - set { SetConfigValueString(base.BuildComplexKey(EMAIL_SUBJECT), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(EMAIL_SUBJECT_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(EMAIL_SUBJECT_KEY), value, true); } } /// @@ -337,8 +337,8 @@ public string EmailSubject /// public string EmailComment { - get { return GetConfigValueString(base.BuildComplexKey(EMAIL_COMMENT)); } - set { SetConfigValueString(base.BuildComplexKey(EMAIL_COMMENT), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(EMAIL_COMMENT_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(EMAIL_COMMENT_KEY), value, true); } } /// @@ -346,8 +346,8 @@ public string EmailComment /// public string EmailCc { - get { return GetConfigValueString(base.BuildComplexKey(EMAIL_CC)); } - set { SetConfigValueString(base.BuildComplexKey(EMAIL_CC), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(EMAIL_CC_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(EMAIL_CC_KEY), value, true); } } /// @@ -355,8 +355,8 @@ public string EmailCc /// public string EmailBcc { - get { return GetConfigValueString(base.BuildComplexKey(EMAIL_BCC)); } - set { SetConfigValueString(base.BuildComplexKey(EMAIL_BCC), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(EMAIL_BCC_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(EMAIL_BCC_KEY), value, true); } } /// @@ -364,8 +364,8 @@ public string EmailBcc /// public int ReportId { - get { return GetConfigValueInt(base.BuildComplexKey(REPORT_ID)); } - set { SetConfigValueInt(base.BuildComplexKey(REPORT_ID), value, true); } + get { return GetConfigValueInt(base.BuildComplexKey(REPORT_ID_KEY)); } + set { SetConfigValueInt(base.BuildComplexKey(REPORT_ID_KEY), value, true); } } /// @@ -373,8 +373,8 @@ public int ReportId /// public string ReportName { - get { return GetConfigValueString(base.BuildComplexKey(REPORT_NAME)); } - set { SetConfigValueString(base.BuildComplexKey(REPORT_NAME), value, true); } + get { return GetConfigValueString(base.BuildComplexKey(REPORT_NAME_KEY)); } + set { SetConfigValueString(base.BuildComplexKey(REPORT_NAME_KEY), value, true); } } /// diff --git a/XenModel/XenAPI-Extensions/Network.cs b/XenModel/XenAPI-Extensions/Network.cs index 149189ee65..2d0c071c97 100644 --- a/XenModel/XenAPI-Extensions/Network.cs +++ b/XenModel/XenAPI-Extensions/Network.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; +using System.Linq; using XenAdmin; using XenAdmin.Core; @@ -67,25 +68,21 @@ public override string Name() return name_label; } - Pool pool = Helpers.GetPoolOfOne(Connection); + var pool = Helpers.GetPoolOfOne(Connection); if (pool == null) return name_label; - string coordinator_ref = pool.master.opaque_ref; + var coordinator_ref = pool.master.opaque_ref; - foreach (PIF pif in Connection.ResolveAll(PIFs)) - { - if (pif.host.opaque_ref == coordinator_ref) - { - return PIFName(pif); - } - } - - foreach (PIF pif in Connection.ResolveAll(PIFs)) - { - return PIFName(pif); - } + var pifs = Connection.ResolveAll(PIFs); + var pif = pifs.FirstOrDefault(p => p.host.opaque_ref == coordinator_ref); + if (pif != null) + return PIFName(pif); + pif = pifs.FirstOrDefault(); + if (pif != null) + return PIFName(pif); + return name_label; } diff --git a/XenModel/XenAPI-Extensions/SR.cs b/XenModel/XenAPI-Extensions/SR.cs index 6b9aa0cc08..8b1779f3cb 100644 --- a/XenModel/XenAPI-Extensions/SR.cs +++ b/XenModel/XenAPI-Extensions/SR.cs @@ -568,12 +568,12 @@ public static List ParseSupportedVersionsListXML(string xml) // If we've got this from an async task result, then it will be wrapped // in a element. Parse the contents instead. - foreach (XmlNode node in doc.GetElementsByTagName("value")) + var nodes = doc.GetElementsByTagName("value"); + if (nodes.Count > 0) { - xml = node.InnerText; + xml = nodes[0].InnerText; doc = new XmlDocument(); doc.LoadXml(xml); - break; } diff --git a/XenModel/XenModel.csproj b/XenModel/XenModel.csproj index 423381b953..78e009645e 100755 --- a/XenModel/XenModel.csproj +++ b/XenModel/XenModel.csproj @@ -168,6 +168,7 @@ + True True diff --git a/XenModel/XenSearch/GroupAlg.cs b/XenModel/XenSearch/GroupAlg.cs index 4e6ac63c00..65ce7cede5 100644 --- a/XenModel/XenSearch/GroupAlg.cs +++ b/XenModel/XenSearch/GroupAlg.cs @@ -167,7 +167,7 @@ protected int CompareGroupKeys(GroupKey one, GroupKey other) return -1; if (other == null) return 1; - return Compare(one.key, other.key); + return Compare(one.Key, other.Key); } /// @@ -294,29 +294,28 @@ public virtual bool Populate(IAcceptGroups adapter) public class GroupKey : IEquatable { - public Grouping grouping; - public object key; + public readonly Grouping Grouping; + public readonly object Key; public GroupKey(Grouping grouping, object key) { - this.grouping = grouping; - this.key = key; + Grouping = grouping; + Key = key; } public override int GetHashCode() { - return key.GetHashCode(); + return Key.GetHashCode(); } public bool Equals(GroupKey other) { - return other != null && grouping.Equals(other.grouping) && key.Equals(other.key); + return other != null && Grouping.Equals(other.Grouping) && Key.Equals(other.Key); } public override bool Equals(object obj) { - GroupKey other = obj as GroupKey; - return other != null && Equals(other); + return obj is GroupKey other && Equals(other); } } @@ -350,7 +349,7 @@ public override bool Populate(IAcceptGroups adapter, int indent, bool defaultExp foreach (GroupKey group in groups) { - IAcceptGroups subAdapter = adapter.Add(group.grouping, group.key, indent); + IAcceptGroups subAdapter = adapter.Add(group.Grouping, group.Key, indent); if (subAdapter == null) continue; diff --git a/XenModel/XenSearch/Query.cs b/XenModel/XenSearch/Query.cs index 49163729d8..04f01c177c 100644 --- a/XenModel/XenSearch/Query.cs +++ b/XenModel/XenSearch/Query.cs @@ -36,8 +36,8 @@ namespace XenAdmin.XenSearch { public class Query { - private QueryScope scope; - private QueryFilter filter; + private readonly QueryScope scope; + private readonly QueryFilter filter; public Query(QueryScope scope, QueryFilter filter) { diff --git a/XenModel/XenSearch/QueryScope.cs b/XenModel/XenSearch/QueryScope.cs index dd9da3cd24..6443c28036 100644 --- a/XenModel/XenSearch/QueryScope.cs +++ b/XenModel/XenSearch/QueryScope.cs @@ -37,7 +37,7 @@ namespace XenAdmin.XenSearch { public class QueryScope: IEquatable { - private ObjectTypes types; + private readonly ObjectTypes types; public QueryScope(ObjectTypes types) { diff --git a/XenModel/XenSearch/QueryTypes.cs b/XenModel/XenSearch/QueryTypes.cs index 7ae873d7bc..1099022206 100644 --- a/XenModel/XenSearch/QueryTypes.cs +++ b/XenModel/XenSearch/QueryTypes.cs @@ -481,27 +481,31 @@ public RecursiveXMOListPropertyQuery(XmlNode node) // item doesn't use a Server). public override bool? MatchProperty(List list) { - bool seenFalse = false; - bool seenNull = false; - foreach (T o in list) + var seenFalse = false; + var seenNull = false; + foreach (var o in list) { if (o != null) { - bool? b = subQuery.Match(o); - if (b == true) - return true; - else if (b == false) - seenFalse = true; - else - seenNull = true; + var b = subQuery.Match(o); + switch (b) + { + case true: + return true; + case false: + seenFalse = true; + break; + default: + seenNull = true; + break; + } } } if (seenFalse) return false; - else if (seenNull) + if (seenNull) return null; - else - return false; + return false; } } @@ -1189,6 +1193,11 @@ public override int GetHashCode() { return address.GetHashCode(); } + + public override bool Equals(object obj) + { + return obj is IPAddressQuery other && address.Equals(other.address); + } } public class BooleanQuery : PropertyQuery diff --git a/XenModel/XenSearch/Search.cs b/XenModel/XenSearch/Search.cs index e7324886ab..cad88e3641 100644 --- a/XenModel/XenSearch/Search.cs +++ b/XenModel/XenSearch/Search.cs @@ -32,6 +32,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using XenAPI; using XenAdmin.Core; @@ -280,8 +281,8 @@ public bool Save() if (uuid == null) uuid = System.Guid.NewGuid().ToString(); - String key = SearchPrefix + uuid; - String value = GetXML(); + var key = SearchPrefix + uuid; + var value = GetXML(); if (connection == null) return false; @@ -289,16 +290,16 @@ public bool Save() if (!connection.IsConnected) return false; - Session session = connection.DuplicateSession(); - foreach (Pool pool in connection.Cache.Pools) - { - Pool.remove_from_gui_config(session, pool.opaque_ref, key); - Pool.add_to_gui_config(session, pool.opaque_ref, key, value); + var session = connection.DuplicateSession(); - return true; - } + var pools = connection.Cache.Pools; + if (pools.Length <= 0) + return false; - return false; + var pool = pools.First(); + Pool.remove_from_gui_config(session, pool.opaque_ref, key); + Pool.add_to_gui_config(session, pool.opaque_ref, key, value); + return true; } public void Save(String filename) diff --git a/XenOvfApi/Conversions.cs b/XenOvfApi/Conversions.cs index e30d19b550..3d85950cf2 100644 --- a/XenOvfApi/Conversions.cs +++ b/XenOvfApi/Conversions.cs @@ -487,10 +487,16 @@ private void CollectInformation() try { searcher = new ManagementObjectSearcher(@"select * from Win32_ComputerSystem"); - foreach (ManagementObject mgtobj in searcher.Get()) + var mgtObjs = searcher.Get(); + + // only want one. + if (mgtObjs.Count > 0) { - Win32_ComputerSystem = mgtobj; // only want one. - break; + using (var iterator = mgtObjs.GetEnumerator()) + { + iterator.MoveNext(); + Win32_ComputerSystem = (ManagementObject) iterator.Current; + } } log.Debug("OVF.CollectionInformation Win32_ComputerSystem.1"); } @@ -512,11 +518,18 @@ private void CollectInformation() try { searcher = new ManagementObjectSearcher(@"select * from Win32_Processor"); - foreach (ManagementObject mgtobj in searcher.Get()) + var mgtObjs = searcher.Get(); + + // only want one. + if (mgtObjs.Count > 0) { - Win32_Processor.Add(mgtobj); // only want one. - break; + using (var iterator = mgtObjs.GetEnumerator()) + { + iterator.MoveNext(); + Win32_Processor.Add((ManagementObject) iterator.Current); + } } + log.DebugFormat("OVF.CollectionInformation Win32_Processor.{0}", Win32_Processor.Count); } catch (Exception ex) diff --git a/XenOvfApi/OVF.cs b/XenOvfApi/OVF.cs index 3cd2c657ba..310dd4fbfa 100644 --- a/XenOvfApi/OVF.cs +++ b/XenOvfApi/OVF.cs @@ -1388,7 +1388,7 @@ public static void AddVirtualSystemSettingData(EnvelopeType ovfObj, string vsId, #region CREATEs public static EnvelopeType CreateOvfEnvelope(string vmName, ulong cpuCount, ulong memory, - string bootParams, string platformSettings, ulong diskCapacity, bool isWim, ulong additionalSpace, + string bootParams, string platformSettings, ulong capacity, string diskPath, ulong imageLength, string productBrand) { EnvelopeType env = CreateEnvelope(vmName); @@ -1415,10 +1415,6 @@ public static void AddVirtualSystemSettingData(EnvelopeType ovfObj, string vsId, AddNetwork(env, systemID, netId, string.Format(Messages.NETWORK_NAME, 0), Messages.OVF_NET_DESCRIPTION, null); string diskId = Guid.NewGuid().ToString(); - ulong capacity = diskCapacity; - - if (isWim) - capacity += additionalSpace; AddDisk(env, systemID, diskId, diskPath, true, Messages.OVF_DISK_CAPTION, Messages.OVF_CREATED, imageLength, capacity); @@ -1426,6 +1422,45 @@ public static void AddVirtualSystemSettingData(EnvelopeType ovfObj, string vsId, return env; } + public static EnvelopeType UpdateBootParams(EnvelopeType env, string systemID, string bootParams) + { + return UpdateOtherSystemSettingsData(env, systemID, "HVM_boot_params", "order=dc;" + bootParams); + } + + public static EnvelopeType UpdatePlatform(EnvelopeType env, string systemID, string platformSettings) + { + return UpdateOtherSystemSettingsData(env, systemID, "platform", "nx=true;acpi=true;apic=true;pae=true;stdvga=0;" + platformSettings); + } + + private static EnvelopeType UpdateOtherSystemSettingsData(EnvelopeType env, string systemID, string setting, string value) + { + VirtualHardwareSection_Type[] vhsArray = FindVirtualHardwareSection(env, systemID); + VirtualHardwareSection_Type foundVhs = null; + + foreach (VirtualHardwareSection_Type vhs in vhsArray) + { + if (vhs.System?.VirtualSystemType == null) + continue; + + var vst = vhs.System.VirtualSystemType.Value; + if (string.IsNullOrEmpty(vst) || !vst.ToLower().StartsWith("xen") && !vst.ToLower().StartsWith("hvm")) + continue; + + foundVhs = vhs; + break; + } + + if (foundVhs == null) + return env; + + var config = foundVhs.VirtualSystemOtherConfigurationData.FirstOrDefault(d => d.Name == setting); + if (config == null) + return env; + + config.Value = new cimString(value); + return env; + } + public EnvelopeType Create(DiskInfo[] vhdExports, string pathToOvf, string ovfName) { return Create(vhdExports, pathToOvf, ovfName, LANGUAGE); diff --git a/packages/DOTNET_BUILD_LOCATION b/packages/DOTNET_BUILD_LOCATION index 28c745af78..4e274d991a 100644 --- a/packages/DOTNET_BUILD_LOCATION +++ b/packages/DOTNET_BUILD_LOCATION @@ -1 +1 @@ -xc-local-release/dotnet-packages/master/37 +xc-local-release/dotnet-packages/master/39