Merge remote-tracking branch 'github_xenadmin/REQ-411' into master_REQ-411_merge

Signed-off-by: Gabor Apati-Nagy <gabor.apati-nagy@citrix.com>

Conflicts:
	XenAdmin/Core/Updates.cs
	XenAdmin/TabPages/ManageUpdatesPage.cs
	XenAdmin/Wizards/PatchingWizard/PatchingWizard_PrecheckPage.cs
	XenModel/Messages.Designer.cs
This commit is contained in:
Gabor Apati-Nagy 2017-09-29 11:56:46 +01:00
commit a8db7bfae9
31 changed files with 1263 additions and 329 deletions

View File

@ -0,0 +1,68 @@
/* 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.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XenAdmin.Alerts
{
public class NewVersionPriorityAlertComparer : IComparer<Alert>
{
public int Compare(Alert alert1, Alert alert2)
{
if (alert1 == null || alert2 == null)
return 0;
int sortResult = 0;
if (IsVersionOrVersionUpdateAlert(alert1) && !IsVersionOrVersionUpdateAlert(alert2))
sortResult = 1;
if (!IsVersionOrVersionUpdateAlert(alert1) && IsVersionOrVersionUpdateAlert(alert2))
sortResult = -1;
if (sortResult == 0)
sortResult = Alert.CompareOnDate(alert1, alert2);
return -sortResult;
}
private bool IsVersionOrVersionUpdateAlert(Alert alert)
{
return alert is XenServerPatchAlert && (alert as XenServerPatchAlert).ShowAsNewVersion
|| alert is XenServerVersionAlert
|| alert is XenCenterUpdateAlert;
}
}
}

View File

@ -61,7 +61,7 @@ namespace XenAdmin.Alerts
public override string Title
{
get { return Messages.ALERT_NEW_VERSION; }
get { return string.Format(Messages.ALERT_NEW_VERSION, NewVersion.Name); }
}
public override string Description
@ -101,16 +101,25 @@ namespace XenAdmin.Alerts
}
}
static int DISMISSED_XC_VERSIONS_LIMIT = 5;
public override void Dismiss()
{
Properties.Settings.Default.LatestXenCenterSeen = NewVersion.VersionAndLang;
{
List<string> current = new List<string>(Properties.Settings.Default.LatestXenCenterSeen.Split(','));
if (current.Contains(NewVersion.VersionAndLang))
return;
if (current.Count >= DISMISSED_XC_VERSIONS_LIMIT)
current.RemoveRange(0, current.Count - DISMISSED_XC_VERSIONS_LIMIT + 1);
current.Add(NewVersion.VersionAndLang);
Properties.Settings.Default.LatestXenCenterSeen = string.Join(",", current.ToArray());
Settings.TrySaveSettings();
Updates.RemoveUpdate(this);
}
public override bool IsDismissed()
{
return Properties.Settings.Default.LatestXenCenterSeen == NewVersion.VersionAndLang;
List<string> current = new List<string>(Properties.Settings.Default.LatestXenCenterSeen.Split(','));
return current.Contains(NewVersion.VersionAndLang);
}
public override bool Equals(Alert other)

View File

@ -36,6 +36,7 @@ using XenAdmin.Network;
using XenAdmin.Actions;
using XenAdmin.Core;
using XenAPI;
using System.Text;
namespace XenAdmin.Alerts
@ -43,7 +44,8 @@ namespace XenAdmin.Alerts
public class XenServerPatchAlert : XenServerUpdateAlert
{
public XenServerPatch Patch;
public XenServerVersion NewServerVersion;
/// <summary>
/// Can we apply this alert. Calling this sets the CannotApplyReason where applicable
/// </summary>
@ -83,9 +85,17 @@ namespace XenAdmin.Alerts
return !host.CanApplyHotfixes();
}
public XenServerPatchAlert(XenServerPatch patch)
/// <summary>
/// Creates a patch alert
/// </summary>
/// <param name="patch">The patch</param>
/// <param name="newServerVersion">The version that the patch installs, or null if the patch doesn't update the server version</param>
public XenServerPatchAlert(XenServerPatch patch, XenServerVersion newServerVersion = null)
{
Patch = patch;
NewServerVersion = newServerVersion;
if (NewServerVersion != null)
RequiredXenCenterVersion = Updates.GetRequiredXenCenterVersion(NewServerVersion);
_priority = patch.Priority;
_timestamp = Patch.TimeStamp;
}
@ -114,15 +124,30 @@ namespace XenAdmin.Alerts
{
get
{
StringBuilder sb = new StringBuilder();
sb.Append(Patch.Description);
if (Patch.InstallationSize != 0)
return string.Format(Messages.PATCH_DESCRIPTION_AND_INSTALLATION_SIZE, Patch.Description, Util.DiskSizeString(Patch.InstallationSize));
return Patch.Description;
{
sb.AppendLine();
sb.AppendFormat(Messages.PATCH_INSTALLATION_SIZE, Util.DiskSizeString(Patch.InstallationSize));
}
if (RequiredXenCenterVersion != null)
{
sb.AppendLine();
sb.AppendFormat(Messages.PATCH_NEEDS_NEW_XENCENTER, RequiredXenCenterVersion.Version);
}
return sb.ToString();
}
}
public override string Name
{
get { return Patch.Name; }
get
{
if (ShowAsNewVersion)
return NewServerVersion.Name;
return Patch.Name;
}
}
public override Action FixLinkAction
@ -148,7 +173,12 @@ namespace XenAdmin.Alerts
public override string Title
{
get { return string.Format(Messages.NEW_UPDATE_AVAILABLE, Patch.Name); }
get
{
if (ShowAsNewVersion)
return string.Format(Messages.DOWLOAD_LATEST_XS_TITLE, NewServerVersion.Name);
return string.Format(Messages.NEW_UPDATE_AVAILABLE, Patch.Name);
}
}
public override bool IsDismissed()
@ -185,5 +215,13 @@ namespace XenAdmin.Alerts
}
return base.Equals(other);
}
public bool ShowAsNewVersion
{
get
{
return NewServerVersion != null && !NewServerVersion.PresentAsUpdate;
}
}
}
}

View File

@ -45,6 +45,8 @@ namespace XenAdmin.Alerts
protected readonly List<IXenConnection> connections = new List<IXenConnection>();
private readonly List<Host> hosts = new List<Host>();
public XenCenterVersion RequiredXenCenterVersion;
public bool CanIgnore
{
get { return (connections.Count == 0 && hosts.Count == 0) || IsDismissed(); }

View File

@ -47,6 +47,7 @@ namespace XenAdmin.Alerts
public XenServerVersionAlert(XenServerVersion version)
{
Version = version;
RequiredXenCenterVersion = Updates.GetRequiredXenCenterVersion(Version);
_timestamp = version.TimeStamp;
}

View File

@ -305,13 +305,13 @@ namespace XenAdmin.Core
XenServerPatches = action.XenServerPatches;
}
var xenCenterAlert = NewXenCenterUpdateAlert(XenCenterVersions, Program.Version);
if (xenCenterAlert != null && !xenCenterAlert.IsDismissed())
updateAlerts.Add(xenCenterAlert);
var xenCenterAlerts = NewXenCenterUpdateAlerts(XenCenterVersions, Program.Version);
if (xenCenterAlerts != null)
updateAlerts.AddRange(xenCenterAlerts.Where(a=>!a.IsDismissed()));
var xenServerUpdateAlert = NewXenServerVersionAlert(XenServerVersionsForAutoCheck);
if (xenServerUpdateAlert != null && !xenServerUpdateAlert.CanIgnore)
updateAlerts.Add(xenServerUpdateAlert);
var xenServerUpdateAlerts = NewXenServerVersionAlerts(XenServerVersionsForAutoCheck);
if (xenServerUpdateAlerts != null)
updateAlerts.AddRange(xenServerUpdateAlerts.Where(a=>!a.CanIgnore));
var xenServerPatchAlerts = NewXenServerPatchAlerts(XenServerVersions, XenServerPatches);
if (xenServerPatchAlerts != null)
@ -354,33 +354,47 @@ namespace XenAdmin.Core
}
public static XenCenterUpdateAlert NewXenCenterUpdateAlert(List<XenCenterVersion> xenCenterVersions, Version currentProgramVersion)
public static List<XenCenterUpdateAlert> NewXenCenterUpdateAlerts(List<XenCenterVersion> xenCenterVersions,
Version currentProgramVersion)
{
if (Helpers.CommonCriteriaCertificationRelease)
return null;
XenCenterVersion toUse = null;
var alerts = new List<XenCenterUpdateAlert>();
XenCenterVersion latest = null, latestCr = null;
if (xenCenterVersions.Count != 0 && currentProgramVersion != new Version(0, 0, 0, 0))
{
var latest = from v in xenCenterVersions where v.IsLatest select v;
var latestVersions = from v in xenCenterVersions where v.Latest select v;
latest = latestVersions.FirstOrDefault(xcv => xcv.Lang == Program.CurrentLanguage) ??
latestVersions.FirstOrDefault(xcv => string.IsNullOrEmpty(xcv.Lang));
toUse = latest.FirstOrDefault(xcv => xcv.Lang == Program.CurrentLanguage) ??
latest.FirstOrDefault(xcv => string.IsNullOrEmpty(xcv.Lang));
if (IsSuitableForXenCenterAlert(latest, currentProgramVersion))
alerts.Add(new XenCenterUpdateAlert(latest));
var latestCrVersions = from v in xenCenterVersions where v.LatestCr select v;
latestCr = latestCrVersions.FirstOrDefault(xcv => xcv.Lang == Program.CurrentLanguage) ??
latestCrVersions.FirstOrDefault(xcv => string.IsNullOrEmpty(xcv.Lang));
if (latestCr != latest && IsSuitableForXenCenterAlert(latestCr, currentProgramVersion))
alerts.Add(new XenCenterUpdateAlert(latestCr));
}
if (toUse == null)
return null;
if (toUse.Version > currentProgramVersion ||
(toUse.Version == currentProgramVersion && toUse.Lang == Program.CurrentLanguage &&
!PropertyManager.IsCultureLoaded(Program.CurrentCulture)))
if (alerts.Count == 0)
{
return new XenCenterUpdateAlert(toUse);
log.Info(string.Format("Not alerting XenCenter update - latest = {0}, latestcr = {1}, detected = {2}",
latest != null ? latest.VersionAndLang : "", latestCr != null ? latestCr.VersionAndLang : "", Program.VersionAndLanguage));
}
log.Info(string.Format("Not alerting XenCenter update - lastest = {0}, detected = {1}",
toUse.VersionAndLang, Program.VersionAndLanguage));
return null;
return alerts;
}
private static bool IsSuitableForXenCenterAlert(XenCenterVersion toUse, Version currentProgramVersion)
{
if (toUse == null)
return false;
return toUse.Version > currentProgramVersion ||
(toUse.Version == currentProgramVersion && toUse.Lang == Program.CurrentLanguage &&
!PropertyManager.IsCultureLoaded(Program.CurrentCulture));
}
public static List<XenServerPatchAlert> NewXenServerPatchAlerts(List<XenServerVersion> xenServerVersions,
@ -391,6 +405,8 @@ namespace XenAdmin.Core
var alerts = new List<XenServerPatchAlert>();
var xenServerVersionsAsUpdates = xenServerVersions.Where(v => v.IsVersionAvailableAsAnUpdate);
foreach (IXenConnection xenConnection in ConnectionsManager.XenConnectionsCopy)
{
Host master = Helpers.GetMaster(xenConnection);
@ -399,15 +415,7 @@ namespace XenAdmin.Core
if (master == null || pool == null)
continue;
var serverVersions = xenServerVersions.FindAll(version =>
{
if (version.BuildNumber != string.Empty)
return (master.BuildNumberRaw() == version.BuildNumber);
return Helpers.HostProductVersionWithOEM(master) == version.VersionAndOEM
|| (version.Oem != null && Helpers.OEMName(master).StartsWith(version.Oem)
&& Helpers.HostProductVersion(master) == version.Version.ToString());
});
var serverVersions = GetServerVersions(master, xenServerVersions);
if (serverVersions.Count == 0)
continue;
@ -422,7 +430,9 @@ namespace XenAdmin.Core
foreach (XenServerPatch xenServerPatch in patches)
{
var alert = new XenServerPatchAlert(xenServerPatch);
XenServerVersion newServerVersion = xenServerVersionsAsUpdates.FirstOrDefault(newVersion => newVersion.PatchUuid.Equals(xenServerPatch.Uuid, StringComparison.OrdinalIgnoreCase));
var alert = new XenServerPatchAlert(xenServerPatch, newServerVersion);
var existingAlert = alerts.Find(al => al.Equals(alert));
if (existingAlert != null)
@ -435,46 +445,8 @@ namespace XenAdmin.Core
XenServerPatch serverPatch = xenServerPatch;
// A patch can be installed on a host if:
// 1. it is not already installed and
// 2. the host has all the required patches installed and
// 3. the host doesn't have any of the conflicting patches installed
var noPatchHosts = hosts.Where(host =>
{
bool elyOrGreater = Helpers.ElyOrGreater(host);
var appliedUpdates = host.AppliedUpdates();
var appliedPatches = host.AppliedPatches();
// 1. patch is not already installed
if (elyOrGreater && appliedUpdates.Any(update => string.Equals(update.uuid, serverPatch.Uuid, StringComparison.OrdinalIgnoreCase)))
return false;
else if (!elyOrGreater && appliedPatches.Any(patch => string.Equals(patch.uuid, serverPatch.Uuid, StringComparison.OrdinalIgnoreCase)))
return false;
// 2. the host has all the required patches installed
if (serverPatch.RequiredPatches != null && serverPatch.RequiredPatches.Count > 0 &&
!serverPatch.RequiredPatches
.All(requiredPatchUuid =>
elyOrGreater && appliedUpdates.Any(update => string.Equals(update.uuid, requiredPatchUuid, StringComparison.OrdinalIgnoreCase))
|| !elyOrGreater && appliedPatches.Any(patch => string.Equals(patch.uuid, requiredPatchUuid, StringComparison.OrdinalIgnoreCase))
)
)
return false;
// 3. the host doesn't have any of the conflicting patches installed
if (serverPatch.ConflictingPatches != null && serverPatch.ConflictingPatches.Count > 0 &&
serverPatch.ConflictingPatches
.Any(conflictingPatchUuid =>
elyOrGreater && appliedUpdates.Any(update => string.Equals(update.uuid, conflictingPatchUuid, StringComparison.OrdinalIgnoreCase))
|| !elyOrGreater && appliedPatches.Any(patch => string.Equals(patch.uuid, conflictingPatchUuid, StringComparison.OrdinalIgnoreCase))
)
)
return false;
return true;
});
var noPatchHosts = hosts.Where(host => PatchCanBeInstalledOnHost(serverPatch, host));
if (noPatchHosts.Count() == hosts.Count)
alert.IncludeConnection(xenConnection);
else
@ -485,6 +457,78 @@ namespace XenAdmin.Core
return alerts;
}
private static bool PatchCanBeInstalledOnHost(XenServerPatch serverPatch, Host host)
{
Debug.Assert(serverPatch != null);
Debug.Assert(host != null);
// A patch can be installed on a host if:
// 1. it is not already installed and
// 2. the host has all the required patches installed and
// 3. the host doesn't have any of the conflicting patches installed
bool elyOrGreater = Helpers.ElyOrGreater(host);
var appliedUpdates = host.AppliedUpdates();
var appliedPatches = host.AppliedPatches();
// 1. patch is not already installed
if (elyOrGreater && appliedUpdates.Any(update => string.Equals(update.uuid, serverPatch.Uuid, StringComparison.OrdinalIgnoreCase)))
return false;
if (!elyOrGreater && appliedPatches.Any(patch => string.Equals(patch.uuid, serverPatch.Uuid, StringComparison.OrdinalIgnoreCase)))
return false;
// 2. the host has all the required patches installed
if (serverPatch.RequiredPatches != null && serverPatch.RequiredPatches.Count > 0 &&
!serverPatch.RequiredPatches
.All(requiredPatchUuid =>
elyOrGreater && appliedUpdates.Any(update => string.Equals(update.uuid, requiredPatchUuid, StringComparison.OrdinalIgnoreCase))
|| !elyOrGreater && appliedPatches.Any(patch => string.Equals(patch.uuid, requiredPatchUuid, StringComparison.OrdinalIgnoreCase))
)
)
return false;
// 3. the host doesn't have any of the conflicting patches installed
if (serverPatch.ConflictingPatches != null && serverPatch.ConflictingPatches.Count > 0 &&
serverPatch.ConflictingPatches
.Any(conflictingPatchUuid =>
elyOrGreater && appliedUpdates.Any(update => string.Equals(update.uuid, conflictingPatchUuid, StringComparison.OrdinalIgnoreCase))
|| !elyOrGreater && appliedPatches.Any(patch => string.Equals(patch.uuid, conflictingPatchUuid, StringComparison.OrdinalIgnoreCase))
)
)
return false;
return true;
}
/// <summary>
/// Returns the latest XenCenter version or null, if the current version is the latest.
/// If a server version is provided, it returns the XenCenter version that is required to work with that server.
/// If no server version is provided it will return the latestCr XenCenter.
/// </summary>
/// <param name="serverVersion"></param>
/// <returns></returns>
public static XenCenterVersion GetRequiredXenCenterVersion(XenServerVersion serverVersion)
{
if (XenCenterVersions.Count == 0)
return null;
var currentProgramVersion = Program.Version;
if (currentProgramVersion == new Version(0, 0, 0, 0))
return null;
var latestVersions = from v in XenCenterVersions where v.Latest select v;
var latest = latestVersions.FirstOrDefault(xcv => xcv.Lang == Program.CurrentLanguage) ??
latestVersions.FirstOrDefault(xcv => string.IsNullOrEmpty(xcv.Lang));
var latestCrVersions = from v in XenCenterVersions where v.LatestCr select v;
var latestCr = latestCrVersions.FirstOrDefault(xcv => xcv.Lang == Program.CurrentLanguage) ??
latestCrVersions.FirstOrDefault(xcv => string.IsNullOrEmpty(xcv.Lang));
if (serverVersion != null && serverVersion.Latest && latest != null)
return latest.Version > currentProgramVersion ? latest : null;
return latestCr != null && latestCr.Version > currentProgramVersion ? latestCr : null;
}
/// <summary>
/// This method returns the minimal set of patches for a host if this class already has information about them. Otherwise it returns empty list.
@ -499,15 +543,7 @@ namespace XenAdmin.Core
if (XenServerVersions == null)
return null;
var serverVersions = XenServerVersions.FindAll(version =>
{
if (version.BuildNumber != string.Empty)
return (host.BuildNumberRaw() == version.BuildNumber);
return Helpers.HostProductVersionWithOEM(host) == version.VersionAndOEM
|| (version.Oem != null && Helpers.OEMName(host).StartsWith(version.Oem)
&& Helpers.HostProductVersion(host) == version.Version.ToString());
});
var serverVersions = GetServerVersions(host, XenServerVersions);
if (serverVersions.Count != 0)
{
@ -545,14 +581,27 @@ namespace XenAdmin.Core
return null;
var version = GetCommonServerVersionOfHostsInAConnection(conn, XenServerVersions);
if (version != null)
{
if (version.MinimalPatches == null)
return null;
var uSeq = new UpgradeSequence();
uSeq.MinimalPatches = version.MinimalPatches;
uSeq.MinimalPatches = new List<XenServerPatch>(version.MinimalPatches);
// if there is a "new version" update in the update sequence, also add the minimal patches of this new version
if (uSeq.MinimalPatches.Count > 0)
{
// assuming that the new version update (if there is one) is the last one in the minimal patches list
var lastUpdate = uSeq.MinimalPatches[uSeq.MinimalPatches.Count - 1];
var newServerVersion = XenServerVersions.FirstOrDefault(
v => v.IsVersionAvailableAsAnUpdate && v.PatchUuid.Equals(lastUpdate.Uuid, StringComparison.OrdinalIgnoreCase));
if (newServerVersion != null && newServerVersion.MinimalPatches != null)
uSeq.MinimalPatches.AddRange(newServerVersion.MinimalPatches);
}
List<Host> hosts = conn.Cache.Hosts.ToList();
@ -569,6 +618,52 @@ namespace XenAdmin.Core
}
}
/// <summary>
/// Gets an upgrade sequence that contains a version upgrade, optionally followed by the minimal patches for the new version
/// </summary>
/// <param name="conn">Connection for the pool</param>
/// <param name="alert">The alert that refers the version-update</param>
/// <param name="updateTheNewVersion">Also add the minimum patches for the new version (true) or not (false).</param>
/// <returns></returns>
public static UpgradeSequence GetUpgradeSequence(IXenConnection conn, XenServerPatchAlert alert, bool updateTheNewVersion)
{
Debug.Assert(conn != null);
Debug.Assert(alert != null);
var uSeq = new UpgradeSequence();
if (XenServerVersions == null)
return null;
Host master = Helpers.GetMaster(conn);
if (master == null)
return null;
var version = GetCommonServerVersionOfHostsInAConnection(conn, XenServerVersions);
// the pool has to be homogeneous
if (version != null)
{
uSeq.MinimalPatches = new List<XenServerPatch>();
uSeq.MinimalPatches.Add(alert.Patch);
// if it's a version updgrade the min sequence will be this patch (the upgrade) and the min patches for the new version
if (updateTheNewVersion && alert.NewServerVersion != null && alert.NewServerVersion.MinimalPatches != null)
{
uSeq.MinimalPatches.AddRange(alert.NewServerVersion.MinimalPatches);
}
conn.Cache.Hosts.ToList().ForEach(h =>
uSeq[h] = GetUpgradeSequenceForHost(h, uSeq.MinimalPatches)
);
return uSeq;
}
return null;
}
/// <summary>
/// Returns a XenServerVersion if all hosts of the pool have the same version
/// Returns null if it is unknown or they don't match
@ -585,15 +680,7 @@ namespace XenAdmin.Core
foreach (Host host in hosts)
{
var hostVersions = xsVersions.FindAll(version =>
{
if (version.BuildNumber != string.Empty)
return (host.BuildNumberRaw() == version.BuildNumber);
return Helpers.HostProductVersionWithOEM(host) == version.VersionAndOEM
|| (version.Oem != null && Helpers.OEMName(host).StartsWith(version.Oem)
&& Helpers.HostProductVersion(host) == version.Version.ToString());
});
var hostVersions = GetServerVersions(host, xsVersions);
var foundVersion = hostVersions.FirstOrDefault();
@ -726,16 +813,31 @@ namespace XenAdmin.Core
}
}
public static XenServerVersionAlert NewXenServerVersionAlert(List<XenServerVersion> xenServerVersions)
public static List<XenServerVersionAlert> NewXenServerVersionAlerts(List<XenServerVersion> xenServerVersions)
{
if (Helpers.CommonCriteriaCertificationRelease)
return null;
var latestVersion = xenServerVersions.FindAll(item => item.Latest).OrderByDescending(v => v.Version).FirstOrDefault();
if (latestVersion == null)
return null;
var latestCrVersion = xenServerVersions.FindAll(item => item.LatestCr).OrderByDescending(v => v.Version).FirstOrDefault();
var alert = new XenServerVersionAlert(latestVersion);
List<XenServerVersionAlert> alerts = new List<XenServerVersionAlert>();
if (latestVersion != null)
alerts.Add(CreateAlertForXenServerVersion(latestVersion));
if (latestCrVersion != null && latestCrVersion != latestVersion)
alerts.Add(CreateAlertForXenServerVersion(latestCrVersion));
return alerts;
}
private static XenServerVersionAlert CreateAlertForXenServerVersion(XenServerVersion version)
{
var alert = new XenServerVersionAlert(version);
// the patch that installs this version, if any
var patch = XenServerPatches.FirstOrDefault(p => p.Uuid.Equals(version.PatchUuid, StringComparison.OrdinalIgnoreCase));
foreach (IXenConnection xc in ConnectionsManager.XenConnectionsCopy)
{
@ -748,7 +850,12 @@ namespace XenAdmin.Core
if (master == null || pool == null)
continue;
var outOfDateHosts = hosts.Where(host => new Version(Helpers.HostProductVersion(host)) < latestVersion.Version);
// Show the Upgrade alert for a host if:
// - the host version is older than this version AND
// - there is no patch (amongst the current version patches) that can update to this version OR, if there is a patch, the patch cannot be installed
var patchApplicable = patch != null && GetServerVersions(master, XenServerVersions).Any(v => v.Patches.Contains(patch));
var outOfDateHosts = hosts.Where(host => new Version(Helpers.HostProductVersion(host)) < version.Version
&& (!patchApplicable || !PatchCanBeInstalledOnHost(patch, host)));
if (outOfDateHosts.Count() == hosts.Count)
alert.IncludeConnection(xc);
@ -759,14 +866,27 @@ namespace XenAdmin.Core
return alert;
}
private static List<XenServerVersion> GetServerVersions(Host host, List<XenServerVersion> xenServerVersions)
{
var serverVersions = xenServerVersions.FindAll(version =>
{
if (version.BuildNumber != string.Empty)
return (host.BuildNumberRaw() == version.BuildNumber);
return Helpers.HostProductVersionWithOEM(host) == version.VersionAndOEM
|| (version.Oem != null && Helpers.OEMName(host).StartsWith(version.Oem)
&& Helpers.HostProductVersion(host) == version.Version.ToString());
});
return serverVersions;
}
public static void CheckServerVersion()
{
var alert = NewXenServerVersionAlert(XenServerVersionsForAutoCheck);
if (alert == null)
var alerts = NewXenServerVersionAlerts(XenServerVersionsForAutoCheck);
if (alerts == null || alerts.Count == 0)
return;
CheckUpdate(alert);
alerts.ForEach(a => CheckUpdate(a));
}
public static void CheckServerPatches()
@ -775,8 +895,7 @@ namespace XenAdmin.Core
if (alerts == null)
return;
foreach (var alert in alerts)
CheckUpdate(alert);
alerts.ForEach(a => CheckUpdate(a));
}
private static void CheckUpdate(XenServerUpdateAlert alert)

View File

@ -0,0 +1,67 @@
/* 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 XenAPI;
using XenAdmin.Diagnostics.Problems;
using XenAdmin.Core;
using XenAdmin.Diagnostics.Problems.PoolProblem;
using XenAdmin.Alerts;
namespace XenAdmin.Diagnostics.Checks
{
public class XenCenterVersionCheck : Check
{
private XenServerVersion _newServerVersion;
public XenCenterVersionCheck(XenServerVersion newServerVersion)
: base(null)
{
_newServerVersion = newServerVersion;
}
protected override Problem RunCheck()
{
var requiredXenCenterVersion = Updates.GetRequiredXenCenterVersion(_newServerVersion);
if (requiredXenCenterVersion == null)
return null;
if (_newServerVersion != null)
return new XenCenterVersionProblem(this, requiredXenCenterVersion);
else
return new XenCenterVersionWarning(this, requiredXenCenterVersion);
}
public override string Description
{
get { return Messages.XENCENTER_VERSION_CHECK_DESCRIPTION; }
}
}
}

View File

@ -0,0 +1,109 @@
/* 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 XenAdmin.Core;
using XenAdmin.Diagnostics.Checks;
namespace XenAdmin.Diagnostics.Problems
{
public class XenCenterVersionProblem : ProblemWithInformationUrl
{
private XenCenterVersion _requiredXenCenterVersion;
public XenCenterVersionProblem(Check check, XenCenterVersion requiredXenCenterVersion)
: base(check)
{
_requiredXenCenterVersion = requiredXenCenterVersion;
}
public override string Title
{
get { return Messages.PROBLEM_XENCENTER_VERSION_TITLE; }
}
public override string Description
{
get { return string.Format(Messages.UPDATES_WIZARD_NEWER_XENCENTER_REQUIRED, _requiredXenCenterVersion.Version); }
}
public override string HelpMessage
{
get { return LinkText; }
}
public override string LinkText
{
get { return Messages.PATCHING_WIZARD_WEBPAGE_CELL; }
}
public override Uri UriToLaunch
{
get { return new Uri(_requiredXenCenterVersion.Url); }
}
}
public class XenCenterVersionWarning : WarningWithInformationUrl
{
private XenCenterVersion _requiredXenCenterVersion;
public XenCenterVersionWarning(Check check, XenCenterVersion requiredXenCenterVersion)
: base(check)
{
_requiredXenCenterVersion = requiredXenCenterVersion;
}
public override string Title
{
get { return Messages.PROBLEM_XENCENTER_VERSION_TITLE; }
}
public override string Description
{
get { return string.Format(Messages.UPDATES_WIZARD_NEWER_XENCENTER_WARNING, _requiredXenCenterVersion.Version); }
}
public override string HelpMessage
{
get { return LinkText; }
}
public override string LinkText
{
get { return Messages.PATCHING_WIZARD_WEBPAGE_CELL; }
}
public override Uri UriToLaunch
{
get { return new Uri(_requiredXenCenterVersion.Url); }
}
}
}

View File

@ -39,7 +39,6 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using XenAdmin.Actions;
using XenAdmin.Alerts;
using XenAdmin.Controls;
@ -75,7 +74,6 @@ namespace XenAdmin.TabPages
InitializeProgressControls();
tableLayoutPanel1.Visible = false;
UpdateButtonEnablement();
dataGridViewUpdates.Sort(ColumnDate, ListSortDirection.Descending);
informationLabel.Click += informationLabel_Click;
m_updateCollectionChangedWithInvoke = Program.ProgramInvokeHandler(UpdatesCollectionChanged);
Updates.RegisterCollectionChanged(m_updateCollectionChangedWithInvoke);
@ -584,19 +582,8 @@ namespace XenAdmin.TabPages
updates.RemoveAll(FilterAlert);
tableLayoutPanel3.Visible = false;
ToggleWarningVisibility(SomeButNotAllUpdatesDisabled());
if (dataGridViewUpdates.SortedColumn != null)
{
if (dataGridViewUpdates.SortedColumn.Index == ColumnMessage.Index)
updates.Sort(Alert.CompareOnTitle);
else if (dataGridViewUpdates.SortedColumn.Index == ColumnDate.Index)
updates.Sort(Alert.CompareOnDate);
else if (dataGridViewUpdates.SortedColumn.Index == ColumnLocation.Index)
updates.Sort(Alert.CompareOnAppliesTo);
if (dataGridViewUpdates.SortOrder == SortOrder.Descending)
updates.Reverse();
}
sortUpdates(updates);
var rowList = new List<DataGridViewRow>();
@ -829,13 +816,22 @@ namespace XenAdmin.TabPages
items.Add(dismiss);
}
if (patchAlert != null && patchAlert.CanApply && !string.IsNullOrEmpty(patchAlert.Patch.PatchUrl))
if (patchAlert != null && patchAlert.CanApply && !string.IsNullOrEmpty(patchAlert.Patch.PatchUrl) && patchAlert.RequiredXenCenterVersion == null)
{
var download = new ToolStripMenuItem(Messages.UPDATES_DOWNLOAD_AND_INSTALL);
download.Click += ToolStripMenuItemDownload_Click;
items.Add(download);
}
var updateAlert = alert as XenServerUpdateAlert;
if (updateAlert != null && updateAlert.RequiredXenCenterVersion != null)
{
var downloadNewXenCenter = new ToolStripMenuItem(Messages.UPDATES_DOWNLOAD_REQUIRED_XENCENTER);
downloadNewXenCenter.Click += ToolStripMenuItemDownloadNewXenCenter_Click;
items.Add(downloadNewXenCenter);
}
if (!string.IsNullOrEmpty(alert.WebPageLabel))
{
var fix = new ToolStripMenuItem(alert.FixLinkText);
@ -1091,6 +1087,24 @@ namespace XenAdmin.TabPages
}
}
private void ToolStripMenuItemDownloadNewXenCenter_Click(object sender, EventArgs e)
{
DataGridViewRow clickedRow = FindAlertRow(sender as ToolStripMenuItem);
if (clickedRow == null)
return;
XenServerUpdateAlert updateAlert = (XenServerUpdateAlert)clickedRow.Tag;
if (updateAlert == null || updateAlert.RequiredXenCenterVersion == null)
return;
string xenCenterUrl = updateAlert.RequiredXenCenterVersion.Url;
if (string.IsNullOrEmpty(xenCenterUrl))
return;
Program.Invoke(Program.MainWindow, () => Program.OpenURL(xenCenterUrl));
}
private void ToolStripMenuItemCopy_Click(object sender, EventArgs e)
{
DataGridViewRow clickedRow = FindAlertRow(sender as ToolStripMenuItem);
@ -1396,6 +1410,26 @@ namespace XenAdmin.TabPages
}
}
}
private void sortUpdates(List<Alert> updatesList)
{
if (dataGridViewUpdates.SortedColumn != null)
{
if (dataGridViewUpdates.SortedColumn.Index == ColumnMessage.Index)
updatesList.Sort(Alert.CompareOnTitle);
else if (dataGridViewUpdates.SortedColumn.Index == ColumnDate.Index)
updatesList.Sort(Alert.CompareOnDate);
else if (dataGridViewUpdates.SortedColumn.Index == ColumnLocation.Index)
updatesList.Sort(Alert.CompareOnAppliesTo);
if (dataGridViewUpdates.SortOrder == SortOrder.Descending)
updatesList.Reverse();
}
else
{
updatesList.Sort(new NewVersionPriorityAlertComparer());
}
}
private void checkForUpdatesNowButton_Click(object sender, EventArgs e)
{

View File

@ -42,6 +42,8 @@ using XenAdmin.Core;
namespace XenAdmin.Wizards.PatchingWizard
{
public enum WizardMode { SingleUpdate, AutomatedUpdates, NewVersion }
/// <summary>
/// Remember that equals for patches dont work across connections because
/// we are not allow to override equals. YOU SHOULD NOT USE ANY OPERATION THAT IMPLIES CALL EQUALS OF Pool_path or Host_patch
@ -85,6 +87,7 @@ namespace XenAdmin.Wizards.PatchingWizard
PatchingWizard_SelectPatchPage.SelectDownloadAlert(alert);
PatchingWizard_SelectPatchPage.SelectedUpdateAlert = alert;
PatchingWizard_SelectServers.SelectedUpdateAlert = alert;
PatchingWizard_PrecheckPage.UpdateAlert = alert;
PatchingWizard_UploadPage.SelectedUpdateAlert = alert;
}
@ -105,7 +108,8 @@ namespace XenAdmin.Wizards.PatchingWizard
if (prevPageType == typeof(PatchingWizard_SelectPatchPage))
{
var wizardIsInAutomatedUpdatesMode = PatchingWizard_SelectPatchPage.IsInAutomatedUpdatesMode;
var wizardMode = PatchingWizard_SelectPatchPage.WizardMode;
var wizardIsInAutomatedUpdatesMode = wizardMode == WizardMode.AutomatedUpdates;
var updateType = wizardIsInAutomatedUpdatesMode ? UpdateType.NewRetail : PatchingWizard_SelectPatchPage.SelectedUpdateType;
var newPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.SelectedNewPatch;
@ -113,7 +117,7 @@ namespace XenAdmin.Wizards.PatchingWizard
var alertPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.SelectedUpdateAlert;
var fileFromDiskAlertPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.FileFromDiskAlert;
PatchingWizard_SelectServers.IsInAutomaticMode = wizardIsInAutomatedUpdatesMode;
PatchingWizard_SelectServers.WizardMode = wizardMode;
PatchingWizard_SelectServers.SelectedUpdateType = updateType;
PatchingWizard_SelectServers.Patch = existPatch;
PatchingWizard_SelectServers.SelectedUpdateAlert = alertPatch;
@ -123,13 +127,13 @@ namespace XenAdmin.Wizards.PatchingWizard
RemovePage(PatchingWizard_ModePage);
RemovePage(PatchingWizard_PatchingPage);
RemovePage(PatchingWizard_AutomatedUpdatesPage);
if (!wizardIsInAutomatedUpdatesMode)
if (wizardMode == WizardMode.SingleUpdate)
{
AddAfterPage(PatchingWizard_SelectServers, PatchingWizard_UploadPage);
AddAfterPage(PatchingWizard_PrecheckPage, PatchingWizard_ModePage);
AddAfterPage(PatchingWizard_ModePage, PatchingWizard_PatchingPage);
}
else
else // AutomatedUpdates or NewVersion
{
AddAfterPage(PatchingWizard_PrecheckPage, PatchingWizard_AutomatedUpdatesPage);
}
@ -140,19 +144,19 @@ namespace XenAdmin.Wizards.PatchingWizard
PatchingWizard_UploadPage.SelectedUpdateAlert = alertPatch;
PatchingWizard_ModePage.Patch = existPatch;
PatchingWizard_ModePage.SelectedUpdateAlert = alertPatch;
PatchingWizard_PrecheckPage.IsInAutomatedUpdatesMode = wizardIsInAutomatedUpdatesMode;
PatchingWizard_PrecheckPage.Patch = existPatch;
PatchingWizard_PrecheckPage.PoolUpdate = null; //reset the PoolUpdate property; it will be updated on leaving the Upload page, if this page is visible
PatchingWizard_PatchingPage.Patch = existPatch;
PatchingWizard_PrecheckPage.SelectedUpdateType = updateType;
PatchingWizard_ModePage.SelectedUpdateType = updateType;
PatchingWizard_PrecheckPage.WizardMode = wizardMode;
PatchingWizard_PrecheckPage.Patch = existPatch;
PatchingWizard_PrecheckPage.PoolUpdate = null; //reset the PoolUpdate property; it will be updated on leaving the Upload page, if this page is visible
PatchingWizard_PrecheckPage.SelectedUpdateType = updateType;
PatchingWizard_PrecheckPage.UpdateAlert = alertPatch ?? fileFromDiskAlertPatch;
PatchingWizard_AutomatedUpdatesPage.WizardMode = wizardMode;
PatchingWizard_AutomatedUpdatesPage.UpdateAlert = alertPatch ?? fileFromDiskAlertPatch;
PatchingWizard_PatchingPage.SelectedUpdateType = updateType;
PatchingWizard_PatchingPage.Patch = existPatch;
PatchingWizard_PatchingPage.SelectedNewPatch = newPatch;
}
else if (prevPageType == typeof(PatchingWizard_SelectServers))
@ -160,8 +164,10 @@ namespace XenAdmin.Wizards.PatchingWizard
var selectedServers = PatchingWizard_SelectServers.SelectedServers;
var selectedPools = PatchingWizard_SelectServers.SelectedPools;
var selectedMasters = PatchingWizard_SelectServers.SelectedMasters;
var applyUpdatesToNewVersion = PatchingWizard_SelectServers.ApplyUpdatesToNewVersion;
PatchingWizard_PrecheckPage.SelectedServers = selectedServers;
PatchingWizard_PrecheckPage.ApplyUpdatesToNewVersion = applyUpdatesToNewVersion;
PatchingWizard_ModePage.SelectedServers = selectedServers;
@ -173,6 +179,7 @@ namespace XenAdmin.Wizards.PatchingWizard
PatchingWizard_UploadPage.SelectedServers = selectedServers;
PatchingWizard_AutomatedUpdatesPage.SelectedPools = selectedPools;
PatchingWizard_AutomatedUpdatesPage.ApplyUpdatesToNewVersion = applyUpdatesToNewVersion;
}
else if (prevPageType == typeof(PatchingWizard_UploadPage))
{
@ -328,11 +335,9 @@ namespace XenAdmin.Wizards.PatchingWizard
private void RemoveDownloadedPatches()
{
var isInAutomaticMode = PatchingWizard_SelectPatchPage.IsInAutomatedUpdatesMode;
List<string> listOfDownloadedFiles = new List<string>();
if (isInAutomaticMode)
if (PatchingWizard_SelectPatchPage.WizardMode != WizardMode.SingleUpdate) // AutomatedUpdates or NewVersion
{
listOfDownloadedFiles.AddRange(PatchingWizard_AutomatedUpdatesPage.AllDownloadedPatches.Values);
}

View File

@ -48,6 +48,7 @@ using XenAdmin.Core;
using XenAdmin.Network;
using System.Text;
using System.Diagnostics;
using XenAdmin.Alerts;
namespace XenAdmin.Wizards.PatchingWizard
{
@ -62,6 +63,10 @@ namespace XenAdmin.Wizards.PatchingWizard
public List<Pool> SelectedPools { private get; set; }
public XenServerPatchAlert UpdateAlert { private get; set; }
public WizardMode WizardMode { private get; set; }
public bool ApplyUpdatesToNewVersion { private get; set; }
private List<PoolPatchMapping> patchMappings = new List<PoolPatchMapping>();
public Dictionary<XenServerPatch, string> AllDownloadedPatches = new Dictionary<XenServerPatch, string>();
@ -135,6 +140,17 @@ namespace XenAdmin.Wizards.PatchingWizard
return;
}
Debug.Assert(WizardMode == WizardMode.AutomatedUpdates || WizardMode == WizardMode.NewVersion && UpdateAlert != null);
if (WizardMode == WizardMode.AutomatedUpdates)
{
labelTitle.Text = Messages.PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_AUTOMATED_MODE;
}
else if (WizardMode == WizardMode.NewVersion)
{
labelTitle.Text = Messages.PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_NEW_VERSION_AUTOMATED_MODE;
}
foreach (var pool in SelectedPools)
{
var master = Helpers.GetMaster(pool.Connection);
@ -150,7 +166,12 @@ namespace XenAdmin.Wizards.PatchingWizard
var hosts = pool.Connection.Cache.Hosts;
var us = Updates.GetUpgradeSequence(pool.Connection);
//if any host is not licensed for automated updates
bool automatedUpdatesRestricted = pool.Connection.Cache.Hosts.Any(Host.RestrictBatchHotfixApply);
var us = WizardMode == WizardMode.NewVersion
? Updates.GetUpgradeSequence(pool.Connection, UpdateAlert, ApplyUpdatesToNewVersion && !automatedUpdatesRestricted)
: Updates.GetUpgradeSequence(pool.Connection);
Debug.Assert(us != null, "Update sequence should not be null.");
@ -627,7 +648,15 @@ namespace XenAdmin.Wizards.PatchingWizard
private void AllWorkersFinished()
{
labelTitle.Text = Messages.PATCHINGWIZARD_UPDATES_DONE_AUTOMATED_UPDATES_MODE;
if (WizardMode == WizardMode.AutomatedUpdates)
{
labelTitle.Text = Messages.PATCHINGWIZARD_UPDATES_DONE_AUTOMATED_UPDATES_MODE;
}
else if (WizardMode == WizardMode.NewVersion)
{
labelTitle.Text = Messages.PATCHINGWIZARD_UPDATES_DONE_AUTOMATED_NEW_VERSION_MODE;
}
progressBar.Value = 100;
pictureBox1.Image = null;
labelError.Text = Messages.CLOSE_WIZARD_CLICK_FINISH;

View File

@ -86,7 +86,7 @@ namespace XenAdmin.Wizards.PatchingWizard
this.errorLinkLabel.Name = "errorLinkLabel";
this.errorLinkLabel.TabStop = true;
//
// PatchingWizard_AutoUpdatingPage
// PatchingWizard_AutomatedUpdatesPage
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
@ -94,7 +94,7 @@ namespace XenAdmin.Wizards.PatchingWizard
this.Controls.Add(this.progressBar);
this.Controls.Add(this.textBoxLog);
this.Controls.Add(this.labelTitle);
this.Name = "PatchingWizard_AutoUpdatingPage";
this.Name = "PatchingWizard_AutomatedUpdatesPage";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();

View File

@ -126,14 +126,11 @@
<value>3, 13</value>
</data>
<data name="labelTitle.Size" type="System.Drawing.Size, System.Drawing">
<value>92, 13</value>
<value>0, 13</value>
</data>
<data name="labelTitle.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="labelTitle.Text" xml:space="preserve">
<value>Installing updates:</value>
</data>
<data name="&gt;&gt;labelTitle.Name" xml:space="preserve">
<value>labelTitle</value>
</data>
@ -355,7 +352,7 @@
<value>511, 335</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>PatchingWizard_AutoUpdatingPage</value>
<value>PatchingWizard_AutomatedUpdatesPage</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>XenAdmin.Controls.XenTabPage, XenCenterMain, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>

View File

@ -45,8 +45,6 @@ namespace XenAdmin.Wizards.PatchingWizard
{
private bool _tooltipShowing;
public XenServerPatchAlert SelectedUpdateAlert { private get; set; }
public PatchingWizard_ModePage()
{
InitializeComponent();

View File

@ -37,6 +37,7 @@ using System.Linq;
using System.Threading;
using System.Windows.Forms;
using XenAdmin.Actions;
using XenAdmin.Alerts;
using XenAdmin.Controls;
using XenAdmin.Core;
using XenAdmin.Diagnostics.Checks;
@ -55,7 +56,6 @@ namespace XenAdmin.Wizards.PatchingWizard
private BackgroundWorker _worker = null;
public List<Host> SelectedServers = new List<Host>();
public List<Problem> ProblemsResolvedPreCheck = new List<Problem>();
public bool IsInAutomatedUpdatesMode { get; set; }
private AsyncAction resolvePrechecksAction = null;
protected List<Pool> SelectedPools
@ -66,6 +66,10 @@ namespace XenAdmin.Wizards.PatchingWizard
}
}
public XenServerPatchAlert UpdateAlert { private get; set; }
public WizardMode WizardMode { private get; set; }
public bool ApplyUpdatesToNewVersion { private get; set; }
public PatchingWizard_PrecheckPage()
{
InitializeComponent();
@ -123,7 +127,7 @@ namespace XenAdmin.Wizards.PatchingWizard
if (direction == PageLoadedDirection.Back)
return;
if (IsInAutomatedUpdatesMode)
if (WizardMode == WizardMode.AutomatedUpdates)
{
labelPrechecksFirstLine.Text = Messages.PATCHINGWIZARD_PRECHECKPAGE_FIRSTLINE_AUTOMATED_UPDATES_MODE;
}
@ -346,10 +350,19 @@ namespace XenAdmin.Wizards.PatchingWizard
protected virtual List<KeyValuePair<string, List<Check>>> GenerateCommonChecks(List<Host> applicableServers)
{
List<KeyValuePair<string, List<Check>>> checks = new List<KeyValuePair<string, List<Check>>>();
List<Check> checkGroup;
//XenCenter version check
if (UpdateAlert != null && UpdateAlert.NewServerVersion != null)
{
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_XENCENTER_VERSION, new List<Check>()));
checkGroup = checks[checks.Count - 1].Value;
checkGroup.Add(new XenCenterVersionCheck(UpdateAlert.NewServerVersion));
}
//HostLivenessCheck checks
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_HOST_LIVENESS_STATUS, new List<Check>()));
List<Check> checkGroup = checks[checks.Count - 1].Value;
checkGroup = checks[checks.Count - 1].Value;
foreach (Host host in applicableServers)
{
checkGroup.Add(new HostLivenessCheck(host));
@ -373,14 +386,24 @@ namespace XenAdmin.Wizards.PatchingWizard
}
//Disk space check for automated updates
if (IsInAutomatedUpdatesMode)
if (WizardMode != WizardMode.SingleUpdate)
{
checks.Add(new KeyValuePair<string, List<Check>>(Messages.PATCHINGWIZARD_PRECHECKPAGE_CHECKING_DISK_SPACE, new List<Check>()));
checkGroup = checks[checks.Count - 1].Value;
foreach (Pool pool in SelectedPools)
{
var us = Updates.GetUpgradeSequence(pool.Connection);
//if any host is not licensed for automated updates
bool automatedUpdatesRestricted = pool.Connection.Cache.Hosts.Any(Host.RestrictBatchHotfixApply);
var us = WizardMode == WizardMode.NewVersion
? Updates.GetUpgradeSequence(pool.Connection, UpdateAlert, ApplyUpdatesToNewVersion && !automatedUpdatesRestricted)
: Updates.GetUpgradeSequence(pool.Connection);
log.InfoFormat("Minimal patches for {0}: {1}", pool.Name(), us != null && us.MinimalPatches != null ? string.Join(",", us.MinimalPatches.Select(p => p.Name)) : "");
if (us == null)
continue;
bool elyOrGreater = Helpers.ElyOrGreater(pool.Connection);
@ -399,6 +422,26 @@ namespace XenAdmin.Wizards.PatchingWizard
}
}
//Checking reboot required and can evacuate host for version updates
if (WizardMode == Wizards.PatchingWizard.WizardMode.NewVersion && UpdateAlert != null && UpdateAlert.Patch != null && UpdateAlert.Patch.after_apply_guidance == after_apply_guidance.restartHost)
{
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List<Check>()));
checkGroup = checks[checks.Count - 1].Value;
var guidance = new List<after_apply_guidance>() { UpdateAlert.Patch.after_apply_guidance };
foreach (var host in SelectedServers)
{
checkGroup.Add(new HostNeedsRebootCheck(host, guidance, LivePatchCodesByHost));
}
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_CANEVACUATE_STATUS, new List<Check>()));
checkGroup = checks[checks.Count - 1].Value;
foreach (Host host in SelectedServers)
{
checkGroup.Add(new AssertCanEvacuateCheck(host, LivePatchCodesByHost));
}
}
return checks;
}
@ -424,7 +467,7 @@ namespace XenAdmin.Wizards.PatchingWizard
}
//Checking if the host needs a reboot
if (!IsInAutomatedUpdatesMode)
if (WizardMode == WizardMode.SingleUpdate)
{
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List<Check>()));
checkGroup = checks[checks.Count - 1].Value;
@ -440,7 +483,7 @@ namespace XenAdmin.Wizards.PatchingWizard
//Checking can evacuate host
//CA-97061 - evacuate host -> suspended VMs. This is only needed for restartHost
//Also include this check for the supplemental packs (patch == null), as their guidance is restartHost
if (patch == null || patch.after_apply_guidance.Contains(after_apply_guidance.restartHost))
if (WizardMode != WizardMode.NewVersion && (patch == null || patch.after_apply_guidance.Contains(after_apply_guidance.restartHost)))
{
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_CANEVACUATE_STATUS, new List<Check>()));
checkGroup = checks[checks.Count - 1].Value;
@ -474,7 +517,7 @@ namespace XenAdmin.Wizards.PatchingWizard
}
//Checking if the host needs a reboot
if (!IsInAutomatedUpdatesMode)
if (WizardMode == WizardMode.SingleUpdate)
{
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List<Check>()));
checkGroup = checks[checks.Count - 1].Value;
@ -649,7 +692,9 @@ namespace XenAdmin.Wizards.PatchingWizard
{
description = _check.SuccessfulCheckDescription;
if (string.IsNullOrEmpty(description))
description = String.Format(Messages.PATCHING_WIZARD_HOST_CHECK_OK, _check.Host.Name(), _check.Description);
description = _check.Host != null
? String.Format(Messages.PATCHING_WIZARD_HOST_CHECK_OK, _check.Host.Name(), _check.Description)
: String.Format(Messages.PATCHING_WIZARD_CHECK_OK, _check.Description);
}
if (description != string.Empty)

View File

@ -31,12 +31,13 @@ namespace XenAdmin.Wizards.PatchingWizard
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PatchingWizard_SelectPatchPage));
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.labelWithoutAutomatedUpdates = new System.Windows.Forms.Label();
this.labelWithAutomatedUpdates = new System.Windows.Forms.Label();
@ -213,28 +214,28 @@ namespace XenAdmin.Wizards.PatchingWizard
this.ColumnDescription,
this.ColumnDate,
this.webPageColumn});
dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridViewPatches.DefaultCellStyle = dataGridViewCellStyle4;
dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridViewPatches.DefaultCellStyle = dataGridViewCellStyle5;
resources.ApplyResources(this.dataGridViewPatches, "dataGridViewPatches");
this.dataGridViewPatches.HideSelection = true;
this.dataGridViewPatches.Name = "dataGridViewPatches";
this.dataGridViewPatches.ReadOnly = true;
dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridViewPatches.RowHeadersDefaultCellStyle = dataGridViewCellStyle5;
dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridViewPatches.RowsDefaultCellStyle = dataGridViewCellStyle6;
dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridViewPatches.RowHeadersDefaultCellStyle = dataGridViewCellStyle6;
dataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridViewPatches.RowsDefaultCellStyle = dataGridViewCellStyle7;
this.dataGridViewPatches.RowTemplate.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridViewPatches.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridViewPatches_CellContentClick);
this.dataGridViewPatches.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridViewPatches_CellMouseClick);
@ -279,6 +280,9 @@ namespace XenAdmin.Wizards.PatchingWizard
// webPageColumn
//
this.webPageColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.TopLeft;
dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.webPageColumn.DefaultCellStyle = dataGridViewCellStyle4;
this.webPageColumn.FillWeight = 60F;
resources.ApplyResources(this.webPageColumn, "webPageColumn");
this.webPageColumn.Name = "webPageColumn";
@ -317,10 +321,6 @@ namespace XenAdmin.Wizards.PatchingWizard
private System.Windows.Forms.RadioButton downloadUpdateRadioButton;
private System.Windows.Forms.Label labelWithAutomatedUpdates;
private System.Windows.Forms.Button RestoreDismUpdatesButton;
private System.Windows.Forms.DataGridViewTextBoxColumn ColumnUpdate;
private System.Windows.Forms.DataGridViewTextBoxColumn ColumnDescription;
private System.Windows.Forms.DataGridViewTextBoxColumn ColumnDate;
private System.Windows.Forms.DataGridViewLinkColumn webPageColumn;
private System.Windows.Forms.Label automatedUpdatesOptionLabel;
private System.Windows.Forms.RadioButton AutomatedUpdatesRadioButton;
private System.Windows.Forms.Label labelWithoutAutomatedUpdates;
@ -329,5 +329,9 @@ namespace XenAdmin.Wizards.PatchingWizard
private System.Windows.Forms.TableLayoutPanel tableLayoutPanelSpinner;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.DataGridViewTextBoxColumn ColumnUpdate;
private System.Windows.Forms.DataGridViewTextBoxColumn ColumnDescription;
private System.Windows.Forms.DataGridViewTextBoxColumn ColumnDate;
private System.Windows.Forms.DataGridViewLinkColumn webPageColumn;
}
}

View File

@ -64,8 +64,6 @@ namespace XenAdmin.Wizards.PatchingWizard
labelWithAutomatedUpdates.Visible = automatedUpdatesOptionLabel.Visible = AutomatedUpdatesRadioButton.Visible = false;
downloadUpdateRadioButton.Checked = true;
dataGridViewPatches.Sort(ColumnDate, ListSortDirection.Descending);
}
private void CheckForUpdates_CheckForUpdatesStarted()
@ -170,7 +168,24 @@ namespace XenAdmin.Wizards.PatchingWizard
firstLoad = false;
}
public bool IsInAutomatedUpdatesMode { get { return AutomatedUpdatesRadioButton.Visible && AutomatedUpdatesRadioButton.Checked; } }
private bool IsInAutomatedUpdatesMode { get { return AutomatedUpdatesRadioButton.Visible && AutomatedUpdatesRadioButton.Checked; } }
public WizardMode WizardMode
{
get
{
if (AutomatedUpdatesRadioButton.Visible && AutomatedUpdatesRadioButton.Checked)
return WizardMode.AutomatedUpdates;
var updateAlert = downloadUpdateRadioButton.Checked && dataGridViewPatches.SelectedRows.Count > 0
? (XenServerPatchAlert) ((PatchGridViewRow) dataGridViewPatches.SelectedRows[0]).UpdateAlert
: selectFromDiskRadioButton.Checked
? GetAlertFromFileName(fileNameTextBox.Text.ToLowerInvariant())
: null;
if (updateAlert != null && updateAlert.NewServerVersion != null)
return WizardMode.NewVersion;
return WizardMode.SingleUpdate;
}
}
public override void PageLeave(PageLoadedDirection direction, ref bool cancel)
{
@ -260,9 +275,9 @@ namespace XenAdmin.Wizards.PatchingWizard
{
foreach (PatchGridViewRow row in dataGridViewPatches.Rows)
{
if (string.Equals(row.UpdateAlert.Name, Path.GetFileNameWithoutExtension(fileName), StringComparison.OrdinalIgnoreCase))
if (string.Equals(row.UpdateAlert.Patch.Name, Path.GetFileNameWithoutExtension(fileName), StringComparison.OrdinalIgnoreCase))
{
return (XenServerPatchAlert)row.UpdateAlert;
return row.UpdateAlert;
}
}
return null;
@ -282,7 +297,9 @@ namespace XenAdmin.Wizards.PatchingWizard
private void PopulatePatchesBox()
{
dataGridViewPatches.Rows.Clear();
var updates = new List<Alert>(Updates.UpdateAlerts);
var updates = Updates.UpdateAlerts.ToList();
if (dataGridViewPatches.SortedColumn != null)
{
if (dataGridViewPatches.SortedColumn.Index == ColumnUpdate.Index)
@ -295,16 +312,29 @@ namespace XenAdmin.Wizards.PatchingWizard
if (dataGridViewPatches.SortOrder == SortOrder.Descending)
updates.Reverse();
}
foreach (Alert alert in updates)
{
if (alert is XenServerPatchAlert)
{
PatchGridViewRow row = new PatchGridViewRow(alert);
if (!dataGridViewPatches.Rows.Contains(row))
{
dataGridViewPatches.Rows.Add(row);
}
}
else
{
updates.Sort(new NewVersionPriorityAlertComparer());
}
foreach (Alert alert in updates)
{
var patchAlert = alert as XenServerPatchAlert;
if (patchAlert != null)
{
PatchGridViewRow row = new PatchGridViewRow(patchAlert);
if (!dataGridViewPatches.Rows.Contains(row))
{
dataGridViewPatches.Rows.Add(row);
if (patchAlert.RequiredXenCenterVersion != null)
{
row.Enabled = false;
row.SetToolTip(string.Format(Messages.UPDATES_WIZARD_NEWER_XENCENTER_REQUIRED, patchAlert.RequiredXenCenterVersion.Version));
}
}
}
}
}
@ -535,7 +565,7 @@ namespace XenAdmin.Wizards.PatchingWizard
private class PatchGridViewRow : DataGridViewExRow, IEquatable<PatchGridViewRow>
{
private readonly Alert _alert;
private readonly XenServerPatchAlert _alert;
private bool expanded = false;
@ -549,7 +579,7 @@ namespace XenAdmin.Wizards.PatchingWizard
private DataGridViewTextBoxCell _statusCell;
private DataGridViewLinkCell _webPageCell;
public PatchGridViewRow(Alert alert)
public PatchGridViewRow(XenServerPatchAlert alert)
{
_alert = alert;
_nameCell = new DataGridViewTextBoxCell();
@ -575,7 +605,7 @@ namespace XenAdmin.Wizards.PatchingWizard
SetupCells();
}
public Alert UpdateAlert
public XenServerPatchAlert UpdateAlert
{
get { return _alert; }
}
@ -656,6 +686,19 @@ namespace XenAdmin.Wizards.PatchingWizard
return this.Equals((PatchGridViewRow)obj);
return false;
}
public void SetToolTip(string toolTip)
{
foreach (var c in Cells)
{
if (c is DataGridViewLinkCell)
continue;
var cell = c as DataGridViewCell;
if (c != null)
((DataGridViewCell)c).ToolTipText = toolTip;
}
}
}
#endregion

View File

@ -241,13 +241,14 @@
<value>23, 83</value>
</data>
<data name="automatedUpdatesOptionLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>575, 13</value>
<value>575, 26</value>
</data>
<data name="automatedUpdatesOptionLabel.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="automatedUpdatesOptionLabel.Text" xml:space="preserve">
<value>[XenCenter] will download and install all current updates from [Citrix], usually with only a single reboot at the end.</value>
<value>[XenCenter] will download and install all released updates on the current version from [Citrix], usually with only a single reboot at the end.
</value>
</data>
<data name="&gt;&gt;automatedUpdatesOptionLabel.Name" xml:space="preserve">
<value>automatedUpdatesOptionLabel</value>
@ -268,19 +269,19 @@
<value>NoControl</value>
</data>
<data name="downloadUpdateRadioButton.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 108</value>
<value>3, 121</value>
</data>
<data name="downloadUpdateRadioButton.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 12, 3, 3</value>
</data>
<data name="downloadUpdateRadioButton.Size" type="System.Drawing.Size, System.Drawing">
<value>163, 17</value>
<value>235, 17</value>
</data>
<data name="downloadUpdateRadioButton.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="downloadUpdateRadioButton.Text" xml:space="preserve">
<value>&amp;Download update from [Citrix]</value>
<value>&amp;Download update or new version from [Citrix]</value>
</data>
<data name="&gt;&gt;downloadUpdateRadioButton.Name" xml:space="preserve">
<value>downloadUpdateRadioButton</value>
@ -583,7 +584,7 @@
<value>1</value>
</data>
<data name="tableLayoutPanelSpinner.Location" type="System.Drawing.Point, System.Drawing">
<value>178, 81</value>
<value>178, 75</value>
</data>
<data name="tableLayoutPanelSpinner.RowCount" type="System.Int32, mscorlib">
<value>1</value>
@ -664,7 +665,7 @@
<value>Vertical</value>
</data>
<data name="dataGridViewPatches.Size" type="System.Drawing.Size, System.Drawing">
<value>575, 189</value>
<value>575, 176</value>
</data>
<data name="dataGridViewPatches.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@ -685,10 +686,10 @@
<value>Fill</value>
</data>
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
<value>23, 131</value>
<value>23, 144</value>
</data>
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
<value>575, 189</value>
<value>575, 176</value>
</data>
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
<value>5</value>

View File

@ -34,8 +34,7 @@ namespace XenAdmin.Wizards.PatchingWizard
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PatchingWizard_SelectServers));
this.label1 = new System.Windows.Forms.Label();
this.buttonSelectAll = new System.Windows.Forms.Button();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.buttonClearAll = new System.Windows.Forms.Button();
this.dataGridViewHosts = new XenAdmin.Wizards.PatchingWizard.PatchingWizard_SelectServers.PatchingHostsDataGridView();
this.ColumnPoolCheckBox = new System.Windows.Forms.DataGridViewCheckBoxColumn();
@ -43,20 +42,22 @@ namespace XenAdmin.Wizards.PatchingWizard
this.ColumnPoolIconHostCheck = new System.Windows.Forms.DataGridViewImageColumn();
this.ColumnName = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ColumnVersion = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.label1 = new System.Windows.Forms.Label();
this.applyUpdatesCheckBox = new System.Windows.Forms.CheckBox();
this.buttonSelectAll = new System.Windows.Forms.Button();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridViewHosts)).BeginInit();
this.SuspendLayout();
//
// label1
// tableLayoutPanel1
//
resources.ApplyResources(this.label1, "label1");
this.label1.Name = "label1";
//
// buttonSelectAll
//
resources.ApplyResources(this.buttonSelectAll, "buttonSelectAll");
this.buttonSelectAll.Name = "buttonSelectAll";
this.buttonSelectAll.UseVisualStyleBackColor = true;
this.buttonSelectAll.Click += new System.EventHandler(this.buttonSelectAll_Click);
resources.ApplyResources(this.tableLayoutPanel1, "tableLayoutPanel1");
this.tableLayoutPanel1.Controls.Add(this.buttonClearAll, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.dataGridViewHosts, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.applyUpdatesCheckBox, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.buttonSelectAll, 0, 2);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
//
// buttonClearAll
//
@ -77,6 +78,7 @@ namespace XenAdmin.Wizards.PatchingWizard
this.ColumnPoolIconHostCheck,
this.ColumnName,
this.ColumnVersion});
this.tableLayoutPanel1.SetColumnSpan(this.dataGridViewHosts, 2);
this.dataGridViewHosts.Name = "dataGridViewHosts";
this.dataGridViewHosts.Updating = false;
//
@ -115,15 +117,36 @@ namespace XenAdmin.Wizards.PatchingWizard
resources.ApplyResources(this.ColumnVersion, "ColumnVersion");
this.ColumnVersion.Name = "ColumnVersion";
//
// label1
//
this.tableLayoutPanel1.SetColumnSpan(this.label1, 2);
resources.ApplyResources(this.label1, "label1");
this.label1.Name = "label1";
//
// applyUpdatesCheckBox
//
resources.ApplyResources(this.applyUpdatesCheckBox, "applyUpdatesCheckBox");
this.applyUpdatesCheckBox.Checked = true;
this.applyUpdatesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.tableLayoutPanel1.SetColumnSpan(this.applyUpdatesCheckBox, 2);
this.applyUpdatesCheckBox.Name = "applyUpdatesCheckBox";
this.applyUpdatesCheckBox.UseVisualStyleBackColor = true;
//
// buttonSelectAll
//
resources.ApplyResources(this.buttonSelectAll, "buttonSelectAll");
this.buttonSelectAll.Name = "buttonSelectAll";
this.buttonSelectAll.UseVisualStyleBackColor = true;
this.buttonSelectAll.Click += new System.EventHandler(this.buttonSelectAll_Click);
//
// PatchingWizard_SelectServers
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.Controls.Add(this.dataGridViewHosts);
this.Controls.Add(this.buttonClearAll);
this.Controls.Add(this.buttonSelectAll);
this.Controls.Add(this.label1);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "PatchingWizard_SelectServers";
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridViewHosts)).EndInit();
this.ResumeLayout(false);
@ -131,14 +154,16 @@ namespace XenAdmin.Wizards.PatchingWizard
#endregion
private Label label1;
private Button buttonSelectAll;
private Button buttonClearAll;
private XenAdmin.Wizards.PatchingWizard.PatchingWizard_SelectServers.PatchingHostsDataGridView dataGridViewHosts;
private TableLayoutPanel tableLayoutPanel1;
private CheckBox applyUpdatesCheckBox;
private PatchingWizard_SelectServers.PatchingHostsDataGridView dataGridViewHosts;
private DataGridViewCheckBoxColumn ColumnPoolCheckBox;
private DataGridViewImageColumn ColumnExpander;
private DataGridViewImageColumn ColumnPoolIconHostCheck;
private DataGridViewTextBoxColumn ColumnName;
private DataGridViewTextBoxColumn ColumnVersion;
private Label label1;
}
}

View File

@ -43,6 +43,7 @@ using XenAdmin.Properties;
using XenAPI;
using XenAdmin.Alerts;
using System.Linq;
using System.Diagnostics;
namespace XenAdmin.Wizards.PatchingWizard
{
@ -61,8 +62,8 @@ namespace XenAdmin.Wizards.PatchingWizard
private bool poolSelectionOnly;
public XenServerPatchAlert SelectedUpdateAlert { private get; set; }
public XenServerPatchAlert FileFromDiskAlert { private get; set; }
public WizardMode WizardMode { private get; set; }
public PatchingWizard_SelectServers()
{
@ -96,10 +97,20 @@ namespace XenAdmin.Wizards.PatchingWizard
base.PageLoaded(direction);
try
{
poolSelectionOnly = IsInAutomaticMode || SelectedUpdateAlert != null || FileFromDiskAlert != null;
label1.Text = IsInAutomaticMode
? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_AUTOMATED_MODE
: poolSelectionOnly ? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_POOL_SELECTION : Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_DEFAULT;
poolSelectionOnly = WizardMode == WizardMode.AutomatedUpdates || SelectedUpdateAlert != null || FileFromDiskAlert != null;
switch (WizardMode)
{
case WizardMode.AutomatedUpdates :
label1.Text = Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_AUTOMATED_MODE;
break;
case WizardMode.NewVersion :
label1.Text = Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_NEW_VERSION_MODE;
break;
case WizardMode.SingleUpdate :
label1.Text = poolSelectionOnly ? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_POOL_SELECTION : Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_DEFAULT;
break;
}
// catch selected servers, in order to restore selection after the dataGrid is reloaded
List<Host> selectedServers = SelectedServers;
@ -108,6 +119,8 @@ namespace XenAdmin.Wizards.PatchingWizard
List<IXenConnection> xenConnections = ConnectionsManager.XenConnectionsCopy;
xenConnections.Sort();
int licensedPoolCount = 0;
int poolCount = 0;
foreach (IXenConnection xenConnection in xenConnections)
{
// add pools, their members and standalone hosts
@ -121,6 +134,15 @@ namespace XenAdmin.Wizards.PatchingWizard
}
Host[] hosts = xenConnection.Cache.Hosts;
if (hosts.Length > 0)
{
poolCount++;
var automatedUpdatesRestricted = hosts.Any(Host.RestrictBatchHotfixApply); //if any host is not licensed for automated updates
if (!automatedUpdatesRestricted)
licensedPoolCount++;
}
Array.Sort(hosts);
foreach (Host host in hosts)
{
@ -129,6 +151,18 @@ namespace XenAdmin.Wizards.PatchingWizard
}
}
if (WizardMode == WizardMode.NewVersion && licensedPoolCount > 0) // in NewVersion mode and at least one pool licensed for automated updates
{
applyUpdatesCheckBox.Visible = true;
applyUpdatesCheckBox.Text = poolCount == licensedPoolCount
? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_APPLY_UPDATES
: Messages.PATCHINGWIZARD_SELECTSERVERPAGE_APPLY_UPDATES_MIXED;
}
else // not in NewVersion mode or all pools unlicensed
{
applyUpdatesCheckBox.Visible = false;
}
// restore server selection
SelectServers(selectedServers);
}
@ -143,16 +177,14 @@ namespace XenAdmin.Wizards.PatchingWizard
{
dataGridViewHosts.Select();
}
public bool IsInAutomaticMode { set; get; }
private void EnabledRow(Host host, UpdateType type, int index)
{
var row = (PatchingHostsDataGridViewRow)dataGridViewHosts.Rows[index];
var poolOfOne = Helpers.GetPoolOfOne(host.Connection);
if (IsInAutomaticMode)
if (WizardMode == WizardMode.AutomatedUpdates)
{
// This check is first because it generally can't be fixed, it's a property of the host
if (poolOfOne != null && poolOfOne.IsAutoUpdateRestartsForbidden()) // Forbids update auto restarts
@ -476,7 +508,7 @@ namespace XenAdmin.Wizards.PatchingWizard
{
if (poolSelectionOnly)
{
if (IsInAutomaticMode)
if (WizardMode != WizardMode.SingleUpdate)
//prechecks will fail in automated updates mode if one of the hosts is unreachable
return SelectedPools.SelectMany(p => p.Connection.Cache.Hosts).ToList();
//prechecks will issue warning but allow updates to be installed on the reachable hosts only
@ -525,6 +557,14 @@ namespace XenAdmin.Wizards.PatchingWizard
}
}
public bool ApplyUpdatesToNewVersion
{
get
{
return applyUpdatesCheckBox.Visible && applyUpdatesCheckBox.Checked;
}
}
public UpdateType SelectedUpdateType { private get; set; }
public void SelectServers(List<Host> selectedServers)

View File

@ -117,68 +117,20 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="label1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Top</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
<value>608, 37</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="label1.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>rubric</value>
</data>
<data name="&gt;&gt;label1.Name" xml:space="preserve">
<value>label1</value>
</data>
<data name="&gt;&gt;label1.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="buttonSelectAll.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
</data>
<data name="buttonSelectAll.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 382</value>
</data>
<data name="buttonSelectAll.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
</data>
<data name="buttonSelectAll.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="buttonSelectAll.Text" xml:space="preserve">
<value>&amp;Select All</value>
</data>
<data name="&gt;&gt;buttonSelectAll.Name" xml:space="preserve">
<value>buttonSelectAll</value>
</data>
<data name="&gt;&gt;buttonSelectAll.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonSelectAll.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;buttonSelectAll.ZOrder" xml:space="preserve">
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="buttonClearAll.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
</data>
<data name="buttonClearAll.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="buttonClearAll.Location" type="System.Drawing.Point, System.Drawing">
<value>81, 382</value>
<value>84, 359</value>
</data>
<data name="buttonClearAll.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
@ -196,10 +148,10 @@
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonClearAll.Parent" xml:space="preserve">
<value>$this</value>
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;buttonClearAll.ZOrder" xml:space="preserve">
<value>1</value>
<value>0</value>
</data>
<data name="dataGridViewHosts.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
@ -214,7 +166,7 @@
<value>16</value>
</data>
<data name="ColumnPoolCheckBox.Width" type="System.Int32, mscorlib">
<value>16</value>
<value>5</value>
</data>
<metadata name="ColumnExpander.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
@ -226,7 +178,7 @@
<value>16</value>
</data>
<data name="ColumnExpander.Width" type="System.Int32, mscorlib">
<value>16</value>
<value>5</value>
</data>
<metadata name="ColumnPoolIconHostCheck.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
@ -238,7 +190,7 @@
<value>16</value>
</data>
<data name="ColumnPoolIconHostCheck.Width" type="System.Int32, mscorlib">
<value>16</value>
<value>5</value>
</data>
<metadata name="ColumnName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
@ -256,10 +208,10 @@
<value>67</value>
</data>
<data name="dataGridViewHosts.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 40</value>
<value>3, 40</value>
</data>
<data name="dataGridViewHosts.Size" type="System.Drawing.Size, System.Drawing">
<value>608, 336</value>
<value>602, 313</value>
</data>
<data name="dataGridViewHosts.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
@ -271,11 +223,122 @@
<value>XenAdmin.Wizards.PatchingWizard.PatchingWizard_SelectServers+PatchingHostsDataGridView, XenCenterMain, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;dataGridViewHosts.Parent" xml:space="preserve">
<value>$this</value>
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;dataGridViewHosts.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="label1.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 0</value>
</data>
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
<value>602, 37</value>
</data>
<data name="label1.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="&gt;&gt;label1.Name" xml:space="preserve">
<value>label1</value>
</data>
<data name="&gt;&gt;label1.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label1.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="applyUpdatesCheckBox.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="applyUpdatesCheckBox.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="applyUpdatesCheckBox.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 388</value>
</data>
<data name="applyUpdatesCheckBox.Size" type="System.Drawing.Size, System.Drawing">
<value>15, 14</value>
</data>
<data name="applyUpdatesCheckBox.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="&gt;&gt;applyUpdatesCheckBox.Name" xml:space="preserve">
<value>applyUpdatesCheckBox</value>
</data>
<data name="&gt;&gt;applyUpdatesCheckBox.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;applyUpdatesCheckBox.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;applyUpdatesCheckBox.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="buttonSelectAll.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
</data>
<data name="buttonSelectAll.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="buttonSelectAll.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 359</value>
</data>
<data name="buttonSelectAll.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
</data>
<data name="buttonSelectAll.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="buttonSelectAll.Text" xml:space="preserve">
<value>&amp;Select All</value>
</data>
<data name="&gt;&gt;buttonSelectAll.Name" xml:space="preserve">
<value>buttonSelectAll</value>
</data>
<data name="&gt;&gt;buttonSelectAll.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonSelectAll.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;buttonSelectAll.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
<value>608, 405</value>
</data>
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Name" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="buttonClearAll" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="dataGridViewHosts" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /&gt;&lt;Control Name="label1" Row="0" RowSpan="1" Column="0" ColumnSpan="2" /&gt;&lt;Control Name="applyUpdatesCheckBox" Row="3" RowSpan="1" Column="0" ColumnSpan="2" /&gt;&lt;Control Name="buttonSelectAll" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,Percent,100,AutoSize,0,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>

View File

@ -141,10 +141,21 @@ namespace XenAdmin.Wizards.RollingUpgradeWizard
protected override List<KeyValuePair<string, List<Check>>> GenerateChecks(Pool_patch patch)
{
List<KeyValuePair<string, List<Check>>> checks = new List<KeyValuePair<string, List<Check>>>();
List<Check> checkGroup;
//XenCenter version check (if any of the selected server version is not the latest)
var latestCrVersion = Updates.XenServerVersions.FindAll(item => item.LatestCr).OrderByDescending(v => v.Version).FirstOrDefault();
if (latestCrVersion != null &&
SelectedServers.Any(host => new Version(Helpers.HostProductVersion(host)) < latestCrVersion.Version))
{
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_XENCENTER_VERSION, new List<Check>()));
checkGroup = checks[checks.Count - 1].Value;
checkGroup.Add(new XenCenterVersionCheck(null));
}
//HostMaintenanceModeCheck checks
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_HOST_LIVENESS_STATUS, new List<Check>()));
List<Check> checkGroup = checks[checks.Count - 1].Value;
checkGroup = checks[checks.Count - 1].Value;
foreach (Host host in SelectedServers)
{
checkGroup.Add(new HostMaintenanceModeCheck(host));

View File

@ -107,6 +107,7 @@
<Compile Include="Actions\GUIActions\IgnorePatchAction.cs" />
<Compile Include="Actions\GUIActions\SaveDataSourceStateAction.cs" />
<Compile Include="Actions\GUIActions\SearchAction.cs" />
<Compile Include="Alerts\NewVersionPriorityAlertComparer.cs" />
<Compile Include="Alerts\Types\AlarmMessageAlert.cs" />
<Compile Include="Alerts\Types\XenServerUpdateAlert.cs" />
<Compile Include="Alerts\Types\DuplicateIqnAlert.cs" />
@ -225,6 +226,7 @@
<Compile Include="Diagnostics\Checks\HostNeedsRebootCheck.cs" />
<Compile Include="Diagnostics\Checks\SafeToUpgradeCheck.cs" />
<Compile Include="Diagnostics\Checks\HostHasUnsupportedStorageLinkSRCheck.cs" />
<Compile Include="Diagnostics\Checks\XenCenterVersionCheck.cs" />
<Compile Include="Diagnostics\Problems\HostProblem\PrerequisiteUpdateMissing.cs" />
<Compile Include="Diagnostics\Problems\HostProblem\HostNeedsReboot.cs" />
<Compile Include="Diagnostics\Problems\HostProblem\HostNotSafeToUpgradeWarning.cs" />
@ -235,6 +237,7 @@
<Compile Include="Diagnostics\Problems\ProblemWithInformationUrl.cs" />
<Compile Include="Diagnostics\Problems\SRProblem\UnsupportedStorageLinkSrIsPresentProblem.cs" />
<Compile Include="Diagnostics\Problems\VMProblem\InvalidVCPUConfiguration.cs" />
<Compile Include="Diagnostics\Problems\XenCenterVersionProblem.cs" />
<Compile Include="Dialogs\EnablePvsReadCachingDialog.cs">
<SubType>Form</SubType>
</Compile>
@ -6882,4 +6885,4 @@
copy "$(ProjectDir)\..\packages\putty.exe" "$(TargetDir)"</PostBuildEvent>
</PropertyGroup>
</Project>
</Project>

View File

@ -43,7 +43,7 @@ namespace XenAdminTests.UnitTests.AlertTests
[Test]
public void VerifyStoredDataWithDefaultConstructor()
{
IUnitTestVerifier validator = new VerifyGetters(new XenCenterUpdateAlert(new XenCenterVersion("6.0.2", "xc", true, "http://url", new DateTime(2011, 12, 09).ToString())));
IUnitTestVerifier validator = new VerifyGetters(new XenCenterUpdateAlert(new XenCenterVersion("6.0.2", "xc", true, false, "http://url", new DateTime(2011, 12, 09).ToString())));
validator.Verify(new AlertClassUnitTestData
{
@ -52,7 +52,7 @@ namespace XenAdminTests.UnitTests.AlertTests
HelpID = "XenCenterUpdateAlert",
Description = "xc is now available. Download the new version from the " + XenAdmin.Branding.COMPANY_NAME_SHORT + " website.",
HelpLinkText = "Help",
Title = "New " + XenAdmin.Branding.BRAND_CONSOLE + " Available",
Title = "xc is now available",
Priority = "Priority5"
});
}

View File

@ -55,7 +55,7 @@ namespace XenAdminTests.UnitTests.AlertTests
[Test]
public void TestAlertWithConnectionAndHosts()
{
XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123");
XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, false, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123", "", false);
var alert = new XenServerVersionAlert(ver);
alert.IncludeConnection(connA.Object);
alert.IncludeConnection(connB.Object);
@ -83,7 +83,7 @@ namespace XenAdminTests.UnitTests.AlertTests
[Test]
public void TestAlertWithHostsAndNoConnection()
{
XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123");
XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, false, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123", "", false);
var alert = new XenServerVersionAlert(ver);
alert.IncludeHosts(new List<Host> { hostA.Object, hostB.Object });
@ -109,7 +109,7 @@ namespace XenAdminTests.UnitTests.AlertTests
[Test]
public void TestAlertWithConnectionAndNoHosts()
{
XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123");
XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, false, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123", "", false);
var alert = new XenServerVersionAlert(ver);
alert.IncludeConnection(connA.Object);
alert.IncludeConnection(connB.Object);
@ -136,7 +136,7 @@ namespace XenAdminTests.UnitTests.AlertTests
[Test]
public void TestAlertWithNoConnectionAndNoHosts()
{
XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123");
XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, false, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123", "", false);
var alert = new XenServerVersionAlert(ver);
IUnitTestVerifier validator = new VerifyGetters(alert);

View File

@ -76,7 +76,7 @@ namespace XenAdminTests.UnitTests
{
var serverVersions = new List<XenServerVersion>();
var version = new XenServerVersion("7.0.0", "XenServer Test 7", true, "", new List<XenServerPatch>(), new List<XenServerPatch>(), DateTime.MinValue.ToString(), "buildNo");
var version = new XenServerVersion("7.0.0", "XenServer Test 7", true, false, "", new List<XenServerPatch>(), new List<XenServerPatch>(), DateTime.MinValue.ToString(), "buildNo", "", false);
for (int ii = 0; ii < numberOfPatches; ii++)
{
var patch = new XenServerPatch("patch_uuid_" + ii, "patch name " + ii, "patch description" + ii, "", "", "1.0", "", "", "1970-01-01T00:00:00Z", "", "1000");

View File

@ -119,7 +119,8 @@ namespace XenAdmin.Actions
{
string version_lang = "";
string name = "";
bool is_latest = false;
bool latest = false;
bool latest_cr = false;
string url = "";
string timestamp = "";
@ -130,14 +131,16 @@ namespace XenAdmin.Actions
else if (attrib.Name == "name")
name = attrib.Value;
else if (attrib.Name == "latest")
is_latest = attrib.Value.ToUpperInvariant() == bool.TrueString.ToUpperInvariant();
latest = attrib.Value.ToUpperInvariant() == bool.TrueString.ToUpperInvariant();
else if (attrib.Name == "latestcr")
latest_cr = attrib.Value.ToUpperInvariant() == bool.TrueString.ToUpperInvariant();
else if (attrib.Name == "url")
url = attrib.Value;
else if (attrib.Name == "timestamp")
timestamp = attrib.Value;
}
XenCenterVersions.Add(new XenCenterVersion(version_lang, name, is_latest, url, timestamp));
XenCenterVersions.Add(new XenCenterVersion(version_lang, name, latest, latest_cr, url, timestamp));
}
}
}
@ -236,9 +239,12 @@ namespace XenAdmin.Actions
string version_oem = "";
string name = "";
bool is_latest = false;
bool is_latest_cr = false;
string url = "";
string timestamp = "";
string buildNumber = "";
string patchUuid = "";
bool presentAsUpdate = false;
foreach (XmlAttribute attrib in version.Attributes)
{
@ -248,12 +254,18 @@ namespace XenAdmin.Actions
name = attrib.Value;
else if (attrib.Name == "latest")
is_latest = attrib.Value.ToUpperInvariant() == bool.TrueString.ToUpperInvariant();
else if (attrib.Name == "latestcr")
is_latest_cr = attrib.Value.ToUpperInvariant() == bool.TrueString.ToUpperInvariant();
else if (attrib.Name == "url")
url = attrib.Value;
else if (attrib.Name == "timestamp")
timestamp = attrib.Value;
else if (attrib.Name == "build-number")
buildNumber = attrib.Value;
else if (attrib.Name == "patch-uuid")
patchUuid = attrib.Value;
else if (attrib.Name == "present-as-update")
presentAsUpdate = attrib.Value.ToUpperInvariant() == bool.TrueString.ToUpperInvariant();
}
List<XenServerPatch> patches = new List<XenServerPatch>();
@ -288,8 +300,8 @@ namespace XenAdmin.Actions
}
XenServerVersions.Add(new XenServerVersion(version_oem, name, is_latest, url, patches, minimalPatches, timestamp,
buildNumber));
XenServerVersions.Add(new XenServerVersion(version_oem, name, is_latest, is_latest_cr, url, patches, minimalPatches, timestamp,
buildNumber, patchUuid, presentAsUpdate));
}
}
}

View File

@ -38,16 +38,18 @@ namespace XenAdmin.Core
{
public Version Version;
public string Name;
public bool IsLatest;
public bool Latest;
public bool LatestCr;
public string Url;
public string Lang;
public DateTime TimeStamp;
public XenCenterVersion(string version_lang, string name, bool is_latest, string url, string timestamp)
public XenCenterVersion(string version_lang, string name, bool latest, bool latest_cr, string url, string timestamp)
{
ParseVersion(version_lang);
Name = name;
IsLatest = is_latest;
Latest = latest;
LatestCr = latest_cr;
Url = url;
DateTime.TryParse(timestamp, out TimeStamp);
}

View File

@ -41,9 +41,12 @@ namespace XenAdmin.Core
public Version Version;
public string Name;
public bool Latest;
public bool LatestCr;
public string Url;
public string Oem;
public List<XenServerPatch> Patches;
public string PatchUuid;
public bool PresentAsUpdate;
/// <summary>
/// A host of this version is considered up-to-date when it has all the patches in this list installed on it
@ -60,22 +63,28 @@ namespace XenAdmin.Core
/// <param name="version_oem"></param>
/// <param name="name"></param>
/// <param name="latest"></param>
/// <param name="latestCr"></param>
/// <param name="url"></param>
/// <param name="patches"></param>
/// <param name="minimumPatches">can be null (see <paramref name="MinimalPatches"/></param>
/// <param name="timestamp"></param>
/// <param name="buildNumber"></param>
public XenServerVersion(string version_oem, string name, bool latest, string url, List<XenServerPatch> patches, List<XenServerPatch> minimumPatches,
string timestamp, string buildNumber)
/// <param name="patchUuid"></param>
/// <param name="presentAsUpdate">Indicates that the new version (usually a CU) should be presented as an update where possible</param>
public XenServerVersion(string version_oem, string name, bool latest, bool latestCr, string url, List<XenServerPatch> patches, List<XenServerPatch> minimumPatches,
string timestamp, string buildNumber, string patchUuid, bool presentAsUpdate)
{
ParseVersion(version_oem);
Name = name;
Latest = latest;
LatestCr = latestCr;
Url = url;
Patches = patches;
MinimalPatches = minimumPatches;
DateTime.TryParse(timestamp, out TimeStamp);
BuildNumber = buildNumber;
PatchUuid = patchUuid;
PresentAsUpdate = presentAsUpdate;
}
private void ParseVersion(string version_oem)
@ -103,7 +112,13 @@ namespace XenAdmin.Core
}
}
public bool IsVersionAvailableAsAnUpdate
{
get
{
return !string.IsNullOrEmpty(PatchUuid);
}
}
}
}

View File

@ -4806,7 +4806,7 @@ namespace XenAdmin {
}
/// <summary>
/// Looks up a localized string similar to New [XenCenter] Available.
/// Looks up a localized string similar to {0} is now available.
/// </summary>
public static string ALERT_NEW_VERSION {
get {
@ -6830,6 +6830,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Checking [XenCenter] version.
/// </summary>
public static string CHECKING_XENCENTER_VERSION {
get {
return ResourceManager.GetString("CHECKING_XENCENTER_VERSION", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cross-server private network.
/// </summary>
@ -23375,6 +23384,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to New [XenCenter] version required.
/// </summary>
public static string NEW_XENCENTER_REQUIRED_INFO {
get {
return ResourceManager.GetString("NEW_XENCENTER_REQUIRED_INFO", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You need to shutdown and then restart the VM before it can access the new disk..
/// </summary>
@ -26236,6 +26254,24 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Installation size: {0}.
/// </summary>
public static string PATCH_INSTALLATION_SIZE {
get {
return ResourceManager.GetString("PATCH_INSTALLATION_SIZE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This version requires [XenCenter] {0} or newer.
/// </summary>
public static string PATCH_NEEDS_NEW_XENCENTER {
get {
return ResourceManager.GetString("PATCH_NEEDS_NEW_XENCENTER", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Not found.
/// </summary>
@ -26282,6 +26318,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to {0} ok..
/// </summary>
public static string PATCHING_WIZARD_CHECK_OK {
get {
return ResourceManager.GetString("PATCHING_WIZARD_CHECK_OK", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The patch {0} is going to be deleted. Do you want to continue?.
/// </summary>
@ -26823,6 +26868,24 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Also apply all released updates on the new version.
/// </summary>
public static string PATCHINGWIZARD_SELECTSERVERPAGE_APPLY_UPDATES {
get {
return ResourceManager.GetString("PATCHINGWIZARD_SELECTSERVERPAGE_APPLY_UPDATES", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Also apply all released updates on the new version (only on pools licensed for automated updates).
/// </summary>
public static string PATCHINGWIZARD_SELECTSERVERPAGE_APPLY_UPDATES_MIXED {
get {
return ResourceManager.GetString("PATCHINGWIZARD_SELECTSERVERPAGE_APPLY_UPDATES_MIXED", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Automated updates are not supported on this [XenServer] version.
/// </summary>
@ -26925,6 +26988,16 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Select one or more pools or standalone servers that you want to update to the new version.
///Servers where this update cannot be applied appear disabled in this list..
/// </summary>
public static string PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_NEW_VERSION_MODE {
get {
return ResourceManager.GetString("PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_NEW_VERSION_MODE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Select one or more pools or standalone servers where you want to apply the selected update.
///Servers where this update cannot be applied appear disabled in this list..
@ -26971,6 +27044,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to The new version has been installed..
/// </summary>
public static string PATCHINGWIZARD_UPDATES_DONE_AUTOMATED_NEW_VERSION_MODE {
get {
return ResourceManager.GetString("PATCHINGWIZARD_UPDATES_DONE_AUTOMATED_NEW_VERSION_MODE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Automated updates have finished..
/// </summary>
@ -26980,6 +27062,24 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Installing updates:.
/// </summary>
public static string PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_AUTOMATED_MODE {
get {
return ResourceManager.GetString("PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_AUTOMATED_MODE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Installing new version:.
/// </summary>
public static string PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_NEW_VERSION_AUTOMATED_MODE {
get {
return ResourceManager.GetString("PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_NEW_VERSION_AUTOMATED_MODE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to [XenCenter] is now downloading your update and uploading it to the servers specified in the previous step.
///Please wait for these operations to complete, then click Next to continue with the installation..
@ -28001,6 +28101,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to [XenCenter] version.
/// </summary>
public static string PROBLEM_XENCENTER_VERSION_TITLE {
get {
return ResourceManager.GetString("PROBLEM_XENCENTER_VERSION_TITLE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &amp;Proceed.
/// </summary>
@ -33328,6 +33437,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Download [XenCenter].
/// </summary>
public static string UPDATES_DOWNLOAD_REQUIRED_XENCENTER {
get {
return ResourceManager.GetString("UPDATES_DOWNLOAD_REQUIRED_XENCENTER", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Install Update.
/// </summary>
@ -33701,6 +33819,24 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to [XenCenter] version {0} or newer is required..
/// </summary>
public static string UPDATES_WIZARD_NEWER_XENCENTER_REQUIRED {
get {
return ResourceManager.GetString("UPDATES_WIZARD_NEWER_XENCENTER_REQUIRED", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Ensure you have upgraded [XenCenter] before upgrading [XenServer]..
/// </summary>
public static string UPDATES_WIZARD_NEWER_XENCENTER_WARNING {
get {
return ResourceManager.GetString("UPDATES_WIZARD_NEWER_XENCENTER_WARNING", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No further action is required for this update..
/// </summary>
@ -38758,6 +38894,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to [XenCenter] version check.
/// </summary>
public static string XENCENTER_VERSION_CHECK_DESCRIPTION {
get {
return ResourceManager.GetString("XENCENTER_VERSION_CHECK_DESCRIPTION", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Saved Searches (*.{0})|*.{0}.
/// </summary>

View File

@ -1782,7 +1782,7 @@ Note that if RBAC is enabled, only alerts which you have privileges to dismiss w
<value>Go to Web Page</value>
</data>
<data name="ALERT_NEW_VERSION" xml:space="preserve">
<value>New [XenCenter] Available</value>
<value>{0} is now available</value>
</data>
<data name="ALERT_NEW_VERSION_DETAILS" xml:space="preserve">
<value>{0} is now available. Download the new version from the [Citrix] website.</value>
@ -2480,6 +2480,9 @@ Do you want to assign it to the schedule '{2}' instead?</value>
<data name="CHECKING_UPGRADE_HOTFIX_STATUS" xml:space="preserve">
<value>Checking upgrade hotfix status</value>
</data>
<data name="CHECKING_XENCENTER_VERSION" xml:space="preserve">
<value>Checking [XenCenter] version</value>
</data>
<data name="CHECK_WLB_ENABLED" xml:space="preserve">
<value>Pool '{0}' cannot have WLB enabled</value>
</data>
@ -8766,6 +8769,9 @@ It is strongly recommended that you Cancel and apply the latest version of the p
<data name="NEW_VM_WIZARD_TEMPLATEPAGE_YINHEKYLIN" xml:space="preserve">
<value>YinheKylin</value>
</data>
<data name="NEW_XENCENTER_REQUIRED_INFO" xml:space="preserve">
<value>New [XenCenter] version required</value>
</data>
<data name="NFS_ISO_ALREADY_ATTACHED" xml:space="preserve">
<value>This NFS ISO storage is already attached to '{0}'</value>
</data>
@ -9263,6 +9269,12 @@ However, there is not enough space to perform the repartitioning, so the current
<data name="PATCHINGWIZARD_SELECTPATCHPAGE_UPDATESEXT" xml:space="preserve">
<value>[XenServer] Updates and Supplemental Packs (*.{0}, *.iso,*.zip)|*.{0};*.iso;*.zip</value>
</data>
<data name="PATCHINGWIZARD_SELECTSERVERPAGE_APPLY_UPDATES" xml:space="preserve">
<value>Also apply all released updates on the new version</value>
</data>
<data name="PATCHINGWIZARD_SELECTSERVERPAGE_APPLY_UPDATES_MIXED" xml:space="preserve">
<value>Also apply all released updates on the new version (only on pools licensed for automated updates)</value>
</data>
<data name="PATCHINGWIZARD_SELECTSERVERPAGE_AUTOMATED_UPDATES_NOT_SUPPORTED_HOST_VERSION" xml:space="preserve">
<value>Automated updates are not supported on this [XenServer] version</value>
</data>
@ -9296,6 +9308,10 @@ Servers that cannot be updated with automated updates appear disabled in this li
</data>
<data name="PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_DEFAULT" xml:space="preserve">
<value>Select one or more servers where you want to apply the selected update.
Servers where this update cannot be applied appear disabled in this list.</value>
</data>
<data name="PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_NEW_VERSION_MODE" xml:space="preserve">
<value>Select one or more pools or standalone servers that you want to update to the new version.
Servers where this update cannot be applied appear disabled in this list.</value>
</data>
<data name="PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_POOL_SELECTION" xml:space="preserve">
@ -9314,6 +9330,9 @@ Servers where this update cannot be applied appear disabled in this list.</value
<data name="PATCHINGWIZARD_SELECTSERVERPAGE_TITLE" xml:space="preserve">
<value>Select the servers you want to update</value>
</data>
<data name="PATCHINGWIZARD_UPDATES_DONE_AUTOMATED_NEW_VERSION_MODE" xml:space="preserve">
<value>The new version has been installed.</value>
</data>
<data name="PATCHINGWIZARD_UPDATES_DONE_AUTOMATED_UPDATES_MODE" xml:space="preserve">
<value>Automated updates have finished.</value>
</data>
@ -9334,12 +9353,21 @@ Please wait for this operation to complete, then click Next to continue with the
<data name="PATCHINGWIZARD_UPLOADPAGE_TITLE_ONLY_UPLOAD" xml:space="preserve">
<value>Uploading the selected file to your servers</value>
</data>
<data name="PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_AUTOMATED_MODE" xml:space="preserve">
<value>Installing updates:</value>
</data>
<data name="PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_NEW_VERSION_AUTOMATED_MODE" xml:space="preserve">
<value>Installing new version:</value>
</data>
<data name="PATCHING_EJECT_CDS" xml:space="preserve">
<value>Eject any virtual CDs from your VMs</value>
</data>
<data name="PATCHING_WARNING_HA" xml:space="preserve">
<value>Disable HA until after all the hosts have been rebooted</value>
</data>
<data name="PATCHING_WIZARD_CHECK_OK" xml:space="preserve">
<value>{0} ok.</value>
</data>
<data name="PATCHING_WIZARD_CONFIRMATION_DELETE" xml:space="preserve">
<value>The patch {0} is going to be deleted. Do you want to continue?</value>
</data>
@ -9401,6 +9429,12 @@ Size: {3}</value>
<data name="PATCH_FOR_XENSERVER_VERSION" xml:space="preserve">
<value>{0}: This patch is for servers with version matching the regular expression '{1}'.</value>
</data>
<data name="PATCH_INSTALLATION_SIZE" xml:space="preserve">
<value>Installation size: {0}</value>
</data>
<data name="PATCH_NEEDS_NEW_XENCENTER" xml:space="preserve">
<value>This version requires [XenCenter] {0} or newer</value>
</data>
<data name="PATCH_NOT_FOUND" xml:space="preserve">
<value>Not found</value>
</data>
@ -9737,6 +9771,9 @@ Please reconnect the host and try again</value>
<data name="PROBLEM_VMPROBLEM_TITLE" xml:space="preserve">
<value>VM '{0}'</value>
</data>
<data name="PROBLEM_XENCENTER_VERSION_TITLE" xml:space="preserve">
<value>[XenCenter] version</value>
</data>
<data name="PROCEED" xml:space="preserve">
<value>&amp;Proceed</value>
</data>
@ -11506,6 +11543,9 @@ Verify that the file is a valid {1} export.</value>
<data name="UPDATES_DOWNLOAD_AND_INSTALL" xml:space="preserve">
<value>Download and Install</value>
</data>
<data name="UPDATES_DOWNLOAD_REQUIRED_XENCENTER" xml:space="preserve">
<value>Download [XenCenter]</value>
</data>
<data name="UPDATES_WIZARD" xml:space="preserve">
<value>Install Update</value>
</data>
@ -11633,6 +11673,12 @@ Check your settings and try again.</value>
<data name="UPDATES_WIZARD_LOCAL_STORAGE" xml:space="preserve">
<value>{0}: The VM '{1}' uses local storage and cannot be migrated.</value>
</data>
<data name="UPDATES_WIZARD_NEWER_XENCENTER_REQUIRED" xml:space="preserve">
<value>[XenCenter] version {0} or newer is required.</value>
</data>
<data name="UPDATES_WIZARD_NEWER_XENCENTER_WARNING" xml:space="preserve">
<value>Ensure you have upgraded [XenCenter] before upgrading [XenServer].</value>
</data>
<data name="UPDATES_WIZARD_NOTVALID_EXTENSION" xml:space="preserve">
<value>The selected file does not have a valid extension. Valid extensions are: *.{0} and *.iso</value>
</data>
@ -13381,6 +13427,9 @@ Are you sure you want to enable automated power management for this Host?</value
<data name="XENCENTER_NEWER_AVAILABLE" xml:space="preserve">
<value>Newer [XenCenter] Available</value>
</data>
<data name="XENCENTER_VERSION_CHECK_DESCRIPTION" xml:space="preserve">
<value>[XenCenter] version check</value>
</data>
<data name="XENSEARCH_SAVED_SEARCH" xml:space="preserve">
<value>Saved Searches (*.{0})|*.{0}</value>
</data>