diff --git a/XenAdmin/Images.cs b/XenAdmin/Images.cs index 4e29d5d713..5961b85f68 100644 --- a/XenAdmin/Images.cs +++ b/XenAdmin/Images.cs @@ -70,6 +70,8 @@ static Images() ImageList16.Images.Add("000_HostUnpatched_h32bit_16.png", XenAdmin.Properties.Resources._000_HostUnpatched_h32bit_16); ImageList16.Images.Add("server_up_16.png", XenAdmin.Properties.Resources.server_up_16); ImageList16.Images.Add("000_ServerErrorFile_h32bit_16.png", XenAdmin.Properties.Resources._000_ServerErrorFile_h32bit_16); + ImageList16.Images.Add("000_Server_h32bit_16-w-alert.png", Properties.Resources._000_Server_h32bit_16_w_alert); + ImageList16.Images.Add("000_StartVM_h32bit_16.png", XenAdmin.Properties.Resources._000_StartVM_h32bit_16); ImageList16.Images.Add("000_VMDisabled_h32bit_16.png", XenAdmin.Properties.Resources._000_VMDisabled_h32bit_16); ImageList16.Images.Add("000_StoppedVM_h32bit_16.png", XenAdmin.Properties.Resources._000_StoppedVM_h32bit_16); @@ -86,11 +88,11 @@ static Images() ImageList16.Images.Add("000_VMSnapshotDiskMemory_h32bit_16.png", XenAdmin.Properties.Resources._000_VMSnapshotDiskMemory_h32bit_16); ImageList16.Images.Add("_000_ScheduledVMsnapshotDiskOnly_h32bit_16.png", XenAdmin.Properties.Resources._000_ScheduledVMsnapshotDiskOnly_h32bit_16); ImageList16.Images.Add("_000_ScheduledVMsnapshotDiskMemory_h32bit_16.png", XenAdmin.Properties.Resources._000_ScheduledVMsnapshotDiskMemory_h32bit_16); + ImageList16.Images.Add("000_PoolConnected_h32bit_16.png", XenAdmin.Properties.Resources._000_PoolConnected_h32bit_16); ImageList16.Images.Add("pool_up_16.png", XenAdmin.Properties.Resources.pool_up_16); - + ImageList16.Images.Add("pool_unpatched.png", Properties.Resources.pool_unpatched); ImageList16.Images.Add("000_Pool_h32bit_16-w-alert.png", Properties.Resources._000_Pool_h32bit_16_w_alert); - ImageList16.Images.Add("000_Server_h32bit_16-w-alert.png", Properties.Resources._000_Server_h32bit_16_w_alert); ImageList16.Images.Add("000_Storage_h32bit_16.png", XenAdmin.Properties.Resources._000_Storage_h32bit_16); ImageList16.Images.Add("000_StorageBroken_h32bit_16.png", XenAdmin.Properties.Resources._000_StorageBroken_h32bit_16); @@ -459,55 +461,74 @@ public static Icons GetIconFor(SR sr) public static Icons GetIconFor(Host host) { + Host_metrics metrics = host.Connection.Resolve(host.metrics); - Host_metrics metrics = host.Connection.Resolve(host.metrics); - bool host_is_live = metrics != null && metrics.live; - - if (host_is_live) + if (metrics != null && metrics.live) { if (host.IsFreeLicenseOrExpired()) - { return Icons.ServerUnlicensed; - } + if (host.HasCrashDumps()) - { return Icons.HostHasCrashDumps; - } - if (host.current_operations.ContainsValue(host_allowed_operations.evacuate) - || !host.enabled) - { + + if (host.current_operations.ContainsValue(host_allowed_operations.evacuate) || !host.enabled) return Icons.HostEvacuate; - } - else if (Helpers.IsOlderThanCoordinator(host)) - { + + if (Helpers.IsOlderThanCoordinator(host)) return Icons.HostOlderThanCoordinator; + + if (Helpers.CloudOrGreater(host)) + { + if (Updates.CdnUpdateInfoPerConnection.TryGetValue(host.Connection, out var updateInfo)) + { + var hostUpdateInfo = updateInfo?.HostsWithUpdates.FirstOrDefault(u => u.HostOpaqueRef == host.opaque_ref); + + if (hostUpdateInfo?.UpdateIDs.Length > 0) + return Icons.HostUnpatched; + } } else { - return Icons.HostConnected; + if (Updates.RecommendedPatchesForHost(host).Count > 0) + return Icons.HostUnpatched; } + + return Icons.HostConnected; } - else - { - // XenAdmin.XenSearch.Group puts a fake host in the treeview for disconnected - // XenConnections. So here we give the yellow 'connection in progress' icon which formerly - // applied only to XenConnections. - if (host.Connection.InProgress && !host.Connection.IsConnected) - return Icons.HostConnecting; - else - return Icons.HostDisconnected; - } + + // XenAdmin.XenSearch.Group puts a fake host in the treeview for disconnected + // XenConnections. So here we give the yellow 'connection in progress' icon which formerly + // applied only to XenConnections. + if (host.Connection.InProgress && !host.Connection.IsConnected) + return Icons.HostConnecting; + + return Icons.HostDisconnected; } public static Icons GetIconFor(Pool pool) { if (!pool.Connection.IsConnected) return Icons.HostDisconnected; + if (pool.Connection.Cache.Hosts.Any(h => h.IsFreeLicenseOrExpired())) return Icons.PoolUnlicensed; - if (pool.IsPoolFullyUpgraded()) - return Icons.PoolConnected; - return Icons.PoolNotFullyUpgraded; + + if (!pool.IsPoolFullyUpgraded()) + return Icons.PoolNotFullyUpgraded; + + if (Helpers.CloudOrGreater(pool.Connection)) + { + if (Updates.CdnUpdateInfoPerConnection.TryGetValue(pool.Connection, out var updateInfo) && + updateInfo?.Updates.Length > 0) + return Icons.PoolUnPatched; + } + else + { + if (pool.Connection.Cache.Hosts.Any(h => Updates.RecommendedPatchesForHost(h).Count > 0)) + return Icons.PoolUnPatched; + } + + return Icons.PoolConnected; } public static Icons GetIconFor(XenAPI.Network network) @@ -860,6 +881,7 @@ public static class StaticImages public static Bitmap PDChevronRight = Properties.Resources.PDChevronRight; public static Bitmap PDChevronUp = Properties.Resources.PDChevronUp; public static Bitmap PDChevronUpOver = Properties.Resources.PDChevronUpOver; + public static Bitmap pool_unpatched = Properties.Resources.pool_unpatched; public static Bitmap pool_up_16 = Properties.Resources.pool_up_16; public static Bitmap redhat_16x = Properties.Resources.redhat_16x; public static Bitmap Refresh16 = Properties.Resources.Refresh16; diff --git a/XenAdmin/Images/pool_unpatched.png b/XenAdmin/Images/pool_unpatched.png new file mode 100644 index 0000000000..c58ac8672a Binary files /dev/null and b/XenAdmin/Images/pool_unpatched.png differ diff --git a/XenAdmin/MainWindow.cs b/XenAdmin/MainWindow.cs index 60fc29a99f..661cdba790 100755 --- a/XenAdmin/MainWindow.cs +++ b/XenAdmin/MainWindow.cs @@ -259,6 +259,7 @@ private void RegisterEvents() OtherConfigAndTagsWatcher.RegisterEventHandlers(); Alert.RegisterAlertCollectionChanged(XenCenterAlerts_CollectionChanged); Updates.UpdateAlertCollectionChanged += Updates_CollectionChanged; + Updates.CdnUpdateInfoChanged += Cdn_UpdateInfoChanged; Updates.CheckForClientUpdatesStarted += ClientUpdatesCheck_Started; Updates.CheckForClientUpdatesCompleted += ClientUpdatesCheck_Completed; ConnectionsManager.History.CollectionChanged += History_CollectionChanged; @@ -274,6 +275,7 @@ private void UnRegisterEvents() OtherConfigAndTagsWatcher.DeregisterEventHandlers(); Alert.DeregisterAlertCollectionChanged(XenCenterAlerts_CollectionChanged); Updates.UpdateAlertCollectionChanged -= Updates_CollectionChanged; + Updates.CdnUpdateInfoChanged -= Cdn_UpdateInfoChanged; Updates.CheckForClientUpdatesStarted -= ClientUpdatesCheck_Started; Updates.CheckForClientUpdatesCompleted -= ClientUpdatesCheck_Completed; ConnectionsManager.History.CollectionChanged -= History_CollectionChanged; @@ -2650,6 +2652,11 @@ private void eventsPage_GoToXenObjectRequested(IXenObject obj) navigationPane.SelectObject(obj); } + private void Cdn_UpdateInfoChanged(IXenConnection obj) + { + RequestRefreshTreeView(); + } + private void Updates_CollectionChanged(CollectionChangeEventArgs e) { Program.Invoke(this, () => @@ -2668,6 +2675,8 @@ private void Updates_CollectionChanged(CollectionChangeEventArgs e) TitleIcon.Image = NotificationsSubModeItem.GetImage(NotificationsSubMode.Updates, updatesCount); } }); + + RequestRefreshTreeView();//to update item icons } private void ClientUpdatesCheck_Completed() diff --git a/XenAdmin/Properties/Resources.Designer.cs b/XenAdmin/Properties/Resources.Designer.cs index 05ef7d5e66..d0a9c1164c 100755 --- a/XenAdmin/Properties/Resources.Designer.cs +++ b/XenAdmin/Properties/Resources.Designer.cs @@ -2816,6 +2816,16 @@ internal static System.Drawing.Bitmap PDChevronUpOver { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pool_unpatched { + get { + object obj = ResourceManager.GetObject("pool_unpatched", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/XenAdmin/Properties/Resources.resx b/XenAdmin/Properties/Resources.resx index 5f1c476131..15fbc9fcd2 100755 --- a/XenAdmin/Properties/Resources.resx +++ b/XenAdmin/Properties/Resources.resx @@ -1144,4 +1144,7 @@ ..\Images\015_Download_h32bit_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Images\pool_unpatched.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/XenAdmin/XenAdmin.csproj b/XenAdmin/XenAdmin.csproj index 36b41ddd55..329ec3334f 100755 --- a/XenAdmin/XenAdmin.csproj +++ b/XenAdmin/XenAdmin.csproj @@ -4541,6 +4541,7 @@ + @@ -6779,4 +6780,4 @@ copy "$(ProjectDir)\ReportViewer\resource_report.rdlc" "$(TargetDir)" - \ No newline at end of file + diff --git a/XenModel/Icons.cs b/XenModel/Icons.cs index 95df8cb63a..a820f933d6 100644 --- a/XenModel/Icons.cs +++ b/XenModel/Icons.cs @@ -41,6 +41,7 @@ public enum Icons HostUnpatched, HostOlderThanCoordinator, HostHasCrashDumps, + ServerUnlicensed, VmRunning, VmRunningDisabled, @@ -62,9 +63,8 @@ public enum Icons PoolConnected, PoolNotFullyUpgraded, - + PoolUnPatched, PoolUnlicensed, - ServerUnlicensed, Storage, StorageBroken, diff --git a/XenModel/Utils/Helpers.cs b/XenModel/Utils/Helpers.cs index 0b7f4986ed..b974ea5abb 100755 --- a/XenModel/Utils/Helpers.cs +++ b/XenModel/Utils/Helpers.cs @@ -409,13 +409,12 @@ public static bool ValidateIscsiIQN(string iqn) public static bool IsOlderThanCoordinator(Host host) { - Host coordinator = Helpers.GetCoordinator(host.Connection); + Host coordinator = GetCoordinator(host.Connection); + if (coordinator == null || coordinator.opaque_ref == host.opaque_ref) return false; - else if (Helpers.ProductVersionCompare(Helpers.HostProductVersion(host), Helpers.HostProductVersion(coordinator)) >= 0) - return false; - else - return true; + + return ProductVersionCompare(HostProductVersion(host), HostProductVersion(coordinator)) < 0; } diff --git a/XenModel/XenAPI-Extensions/Host.cs b/XenModel/XenAPI-Extensions/Host.cs index 28ac38214e..e555018c15 100644 --- a/XenModel/XenAPI-Extensions/Host.cs +++ b/XenModel/XenAPI-Extensions/Host.cs @@ -35,7 +35,6 @@ using System.Threading; using XenAdmin; using XenAdmin.Core; -using XenAdmin.Network; using System.Diagnostics; using System.Web.Script.Serialization; @@ -700,26 +699,6 @@ public void SetSysLogDestination(string value) logging = SetDictionaryKey(logging, "syslog_destination", value); } - public static bool IsFullyPatched(Host host,IEnumerable connections) - { - List patches = Pool_patch.GetAllThatApply(host,connections); - - List appliedPatches - = host.AppliedPatches(); - - if (appliedPatches.Count == patches.Count) - return true; - - foreach (Pool_patch patch in patches) - { - Pool_patch patch1 = patch; - if (!appliedPatches.Exists(otherPatch => string.Equals(patch1.uuid, otherPatch.uuid, StringComparison.OrdinalIgnoreCase))) - return false; - } - - return true; - } - public virtual List AppliedPatches() { List patches = new List();