diff --git a/XenAdmin/Core/Registry.cs b/XenAdmin/Core/Registry.cs index 76e79e5d2..7a0525de1 100644 --- a/XenAdmin/Core/Registry.cs +++ b/XenAdmin/Core/Registry.cs @@ -379,6 +379,11 @@ namespace XenAdmin.Core get { return ReadInstalledKey(ADDITIONAL_FEATURES); } } + public static string CustomUpdatesXmlLocation + { + get { return ReadKey(CUSTOM_UPDATES_XML_LOCATION); } + } + private const string SSL_CERTIFICATES_CHANGED_ONLY = "CHANGED"; private const string SSL_CERTIFICATES_ALL = "ALL"; private const string SSL_CERTIFICATES_KEY = "ForceSSLCertificates"; @@ -402,6 +407,7 @@ namespace XenAdmin.Core private const string HEALTH_CHECK_PRODUCT_KEY = "HealthCheckProductKey"; private const string HIDDEN_FEATURES = "HiddenFeatures"; private const string ADDITIONAL_FEATURES = "AdditionalFeatures"; + private const string CUSTOM_UPDATES_XML_LOCATION = "CheckForUpdatesXmlLocationOverride"; } public enum SSLCertificateTypes { None, Changed, All } diff --git a/XenAdmin/Core/Updates.cs b/XenAdmin/Core/Updates.cs index 5933e04a8..a9699b182 100644 --- a/XenAdmin/Core/Updates.cs +++ b/XenAdmin/Core/Updates.cs @@ -197,7 +197,7 @@ namespace XenAdmin.Core Properties.Settings.Default.AllowXenCenterUpdates || force, Properties.Settings.Default.AllowXenServerUpdates || force, Properties.Settings.Default.AllowPatchesUpdates || force, - Branding.CheckForUpdatesUrl); + Updates.CheckForUpdatesUrl); { action.Completed += actionCompleted; } @@ -208,7 +208,15 @@ namespace XenAdmin.Core action.RunAsync(); } } - + + public static string CheckForUpdatesUrl + { + get + { + return Registry.CustomUpdatesXmlLocation ?? Branding.CheckForUpdatesUrl; + } + } + private static void actionCompleted(ActionBase sender) { Program.AssertOffEventThread(); @@ -406,15 +414,52 @@ namespace XenAdmin.Core return alerts; } + /// + /// This method returns the minimal set of patches for a host if this class already has information about them. Otherwise it returns empty list. + /// Calling this function will not initiate a download or update. + /// + /// + /// + public static List RecommendedPatchesForHost(Host host) + { + var recommendedPatches = new List(); + + if (XenServerVersions == null) + return recommendedPatches; + + 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()); + }); + + if (serverVersions.Count != 0) + { + var minimumPatches = new List(); + minimumPatches = serverVersions[0].MinimalPatches; + + var appliedPatches = host.AppliedPatches(); + recommendedPatches = minimumPatches.FindAll(p => !appliedPatches.Any(ap => string.Equals(ap.uuid, p.Uuid, StringComparison.OrdinalIgnoreCase))); + + } + + return recommendedPatches; + } + public static UpgradeSequence GetUpgradeSequence(IXenConnection conn) { var uSeq = new UpgradeSequence(); Host master = Helpers.GetMaster(conn); - List hosts = conn.Cache.Hosts.ToList(); if (master == null) return null; + List hosts = conn.Cache.Hosts.ToList(); + var serverVersions = XenServerVersions.FindAll(version => { if (version.BuildNumber != string.Empty) diff --git a/XenAdmin/TabPages/GeneralTabPage.cs b/XenAdmin/TabPages/GeneralTabPage.cs index d1909b084..615858a37 100644 --- a/XenAdmin/TabPages/GeneralTabPage.cs +++ b/XenAdmin/TabPages/GeneralTabPage.cs @@ -676,6 +676,12 @@ namespace XenAdmin.TabPages s.AddEntry(FriendlyName("Pool_patch.applied"), hostAppliedPatches(host)); } + var recommendedPatches = RecommendedPatchesForHost(host); + if (!string.IsNullOrEmpty(recommendedPatches)) + { + s.AddEntry(FriendlyName("Pool_patch.recommended"), recommendedPatches); + } + // add supplemental packs var suppPacks = hostInstalledSuppPacks(host); if (!string.IsNullOrEmpty(suppPacks)) @@ -1613,6 +1619,17 @@ namespace XenAdmin.TabPages return true; } + private string RecommendedPatchesForHost(Host host) + { + var result = new List(); + var recommendedPatches = Updates.RecommendedPatchesForHost(host); + + foreach (var patch in recommendedPatches) + result.Add(patch.Name); + + return string.Join(Environment.NewLine, result.ToArray()); + } + private string hostAppliedPatches(Host host) { List result = new List(); diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectPatchPage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectPatchPage.cs index f7ca0a801..f3de64649 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectPatchPage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectPatchPage.cs @@ -184,7 +184,7 @@ namespace XenAdmin.Wizards.PatchingWizard } else //In Automatic Mode { - var downloadUpdatesAction = new DownloadUpdatesXmlAction(false, true, true); + var downloadUpdatesAction = new DownloadUpdatesXmlAction(false, true, true, Updates.CheckForUpdatesUrl); var dialog = new ActionProgressDialog(downloadUpdatesAction, ProgressBarStyle.Marquee); dialog.ShowDialog(this.Parent); //Will block until dialog closes, action completed diff --git a/XenModel/Actions/Updates/DownloadUpdatesXmlAction.cs b/XenModel/Actions/Updates/DownloadUpdatesXmlAction.cs index da24ff39a..4d5f537d0 100644 --- a/XenModel/Actions/Updates/DownloadUpdatesXmlAction.cs +++ b/XenModel/Actions/Updates/DownloadUpdatesXmlAction.cs @@ -36,6 +36,7 @@ using XenAPI; using System.IO; using System.Xml; using XenAdmin.Core; +using System.Diagnostics; namespace XenAdmin.Actions @@ -76,6 +77,8 @@ namespace XenAdmin.Actions public DownloadUpdatesXmlAction(bool checkForXenCenter, bool checkForServerVersion, bool checkForPatches, string checkForUpdatesUrl) : base(null, "_get_updates", "_get_updates", true) { + Debug.Assert(checkForUpdatesUrl != null, "Parameter checkForUpdatesUrl should not be null. This class does not default its value anymore."); + XenServerPatches = new List(); XenServerVersions = new List(); XenCenterVersions = new List(); @@ -83,10 +86,10 @@ namespace XenAdmin.Actions _checkForXenCenter = checkForXenCenter; _checkForServerVersion = checkForServerVersion; _checkForPatches = checkForPatches; - _checkForUpdatesUrl = string.IsNullOrEmpty(checkForUpdatesUrl) ? InvisibleMessages.XENSERVER_UPDATE_URL : checkForUpdatesUrl; + _checkForUpdatesUrl = checkForUpdatesUrl; } - public DownloadUpdatesXmlAction(bool checkForXenCenter, bool checkForServerVersion, bool checkForPatches) + protected DownloadUpdatesXmlAction(bool checkForXenCenter, bool checkForServerVersion, bool checkForPatches) : this(checkForXenCenter, checkForServerVersion, checkForPatches, null) { } @@ -288,10 +291,19 @@ namespace XenAdmin.Actions protected virtual XmlDocument FetchCheckForUpdatesXml(string location) { - XmlDocument xdoc; - using (Stream xmlstream = HTTPHelper.GET(new Uri(location), Connection, false, true)) + var xdoc = new XmlDocument(); + var uri = new Uri(location); + + if (uri.IsFile) { - xdoc = Helpers.LoadXmlDocument(xmlstream); + xdoc.Load(location); + } + else + { + using (Stream xmlstream = HTTPHelper.GET(new Uri(location), Connection, false, true)) + { + xdoc = Helpers.LoadXmlDocument(xmlstream); + } } return xdoc; } diff --git a/XenModel/FriendlyNames.Designer.cs b/XenModel/FriendlyNames.Designer.cs index 68b7ae111..0d4cb96f5 100644 --- a/XenModel/FriendlyNames.Designer.cs +++ b/XenModel/FriendlyNames.Designer.cs @@ -2652,6 +2652,15 @@ namespace XenAdmin { } } + /// + /// Looks up a localized string similar to Recommended Patches. + /// + public static string Label_Pool_patch_recommended { + get { + return ResourceManager.GetString("Label-Pool_patch.recommended", resourceCulture); + } + } + /// /// Looks up a localized string similar to Disk space allocations. /// @@ -4041,7 +4050,7 @@ namespace XenAdmin { } /// - /// Looks up a localized string similar to Pool '{0}' failed to retrieve placement recommendations from WLB for VM '{1}'.. + /// Looks up a localized string similar to Pool '{0}' failed to retrieve placement recommendations from WLB for '{1}'.. /// public static string Message_body_wlb_consultation_failed { get { diff --git a/XenModel/FriendlyNames.resx b/XenModel/FriendlyNames.resx index 92b0aa556..e6cd8f7db 100644 --- a/XenModel/FriendlyNames.resx +++ b/XenModel/FriendlyNames.resx @@ -1859,4 +1859,7 @@ [Citrix] [XenServer product] Standard Edition + + Recommended Patches + \ No newline at end of file diff --git a/XenModel/Messages.Designer.cs b/XenModel/Messages.Designer.cs index bddba2cbc..c4f9b9a07 100755 --- a/XenModel/Messages.Designer.cs +++ b/XenModel/Messages.Designer.cs @@ -25604,7 +25604,7 @@ namespace XenAdmin { } /// - /// Looks up a localized string similar to Update process was not completed successfully. Check . + /// Looks up a localized string similar to Update process was not completed successfully.. /// public static string PATCHINGWIZARD_AUTOUPDATINGPAGE_ERROR { get { diff --git a/XenModel/Messages.resx b/XenModel/Messages.resx index 574daf220..7e91073cc 100755 --- a/XenModel/Messages.resx +++ b/XenModel/Messages.resx @@ -8857,7 +8857,7 @@ However, there is not enough space to perform the repartitioning, so the current Paste - Update process was not completed successfully. Check + Update process was not completed successfully. Following errors occured while automatic upgrade was in progress: