diff --git a/XenAdmin/Actions/GUIActions/DismissAlertsAction.cs b/XenAdmin/Actions/GUIActions/DismissAlertsAction.cs
index 7cc22100c..8d057f62e 100644
--- a/XenAdmin/Actions/GUIActions/DismissAlertsAction.cs
+++ b/XenAdmin/Actions/GUIActions/DismissAlertsAction.cs
@@ -96,9 +96,12 @@ namespace XenAdmin.Actions
if (_alerts.Count > 0)
midPoint = 100 * msgAlerts.Count / _alerts.Count;
- RelatedTask = Message.async_destroy_many(Session, msgRefs);
- PollToCompletion(0, midPoint);
- Alert.RemoveAlert(a => msgAlerts.Contains(a));
+ if (msgAlerts.Count > 0)
+ {
+ RelatedTask = Message.async_destroy_many(Session, msgRefs);
+ PollToCompletion(0, midPoint);
+ Alert.RemoveAlert(a => msgAlerts.Contains(a));
+ }
for (var i = 0; i < otherAlerts.Count; i++)
{
diff --git a/XenAdmin/Alerts/NewVersionPriorityAlertComparer.cs b/XenAdmin/Alerts/NewVersionPriorityAlertComparer.cs
index 6814957ab..13ecb8a71 100644
--- a/XenAdmin/Alerts/NewVersionPriorityAlertComparer.cs
+++ b/XenAdmin/Alerts/NewVersionPriorityAlertComparer.cs
@@ -39,18 +39,13 @@ namespace XenAdmin.Alerts
if (alert1 == null || alert2 == null)
return 0;
- int sortResult = 0;
-
if (IsVersionOrVersionUpdateAlert(alert1) && !IsVersionOrVersionUpdateAlert(alert2))
- sortResult = 1;
+ return -1;
if (!IsVersionOrVersionUpdateAlert(alert1) && IsVersionOrVersionUpdateAlert(alert2))
- sortResult = -1;
+ return 1;
- if (sortResult == 0)
- sortResult = Alert.CompareOnDate(alert1, alert2);
-
- return -sortResult;
+ return -Alert.CompareOnDate(alert1, alert2); //descending date
}
private bool IsVersionOrVersionUpdateAlert(Alert alert)
diff --git a/XenAdmin/Alerts/Types/OutOfSyncWithCdnAlert.cs b/XenAdmin/Alerts/Types/OutOfSyncWithCdnAlert.cs
new file mode 100644
index 000000000..9353a549a
--- /dev/null
+++ b/XenAdmin/Alerts/Types/OutOfSyncWithCdnAlert.cs
@@ -0,0 +1,159 @@
+/* Copyright (c) Cloud Software Group, Inc.
+ *
+ * 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.Actions;
+using XenAdmin.Core;
+using XenAdmin.Dialogs.ServerUpdates;
+using XenAdmin.Network;
+using XenAPI;
+
+
+namespace XenAdmin.Alerts
+{
+ public class OutOfSyncWithCdnAlert : Alert
+ {
+ private readonly int _outOfSyncDays;
+ private readonly Pool _pool;
+
+ private OutOfSyncWithCdnAlert(Pool pool, DateTime timestamp)
+ {
+ _timestamp = timestamp;
+ _pool = pool;
+ Connection = _pool.Connection;
+
+ if (_timestamp - _pool.last_update_sync >= TimeSpan.FromDays(180))
+ {
+ _outOfSyncDays = 180;
+ Priority = AlertPriority.Priority1;
+ }
+ else if (_timestamp - _pool.last_update_sync >= TimeSpan.FromDays(90))
+ {
+ _outOfSyncDays = 180;
+ Priority = AlertPriority.Priority2;
+ }
+ }
+
+ public static bool TryCreate(IXenConnection connection, out Alert alert)
+ {
+ if (Helpers.XapiEqualOrGreater_23_18_0(connection))
+ {
+ var pool = Helpers.GetPoolOfOne(connection);
+ var timestamp = DateTime.UtcNow;
+
+ if (timestamp - pool.last_update_sync >= TimeSpan.FromDays(90))
+ {
+ alert = new OutOfSyncWithCdnAlert(pool, timestamp);
+ return true;
+ }
+ }
+
+ alert = null;
+ return false;
+ }
+
+ public override AlertPriority Priority { get; }
+
+ public override string AppliesTo => Helpers.GetName(_pool);
+
+ public override string Description => Title;
+
+ public override Action FixLinkAction
+ {
+ get
+ {
+ return () =>
+ {
+ var syncAction = new SyncWithCdnAction(_pool);
+ syncAction.Completed += a => Updates.CheckForCdnUpdates(a.Connection);
+ syncAction.RunAsync();
+ };
+ }
+ }
+
+ public override string FixLinkText => Messages.UPDATES_GENERAL_TAB_SYNC_NOW;
+
+ public override string HelpID => "TODO";
+
+ public override string Title => string.Format(Messages.ALERT_CDN_OUT_OF_SYNC_TITLE, _outOfSyncDays);
+ }
+
+
+ public class YumRepoNotConfiguredAlert : Alert
+ {
+ private readonly Pool _pool;
+
+ private YumRepoNotConfiguredAlert(Pool pool, DateTime timestamp)
+ {
+ _timestamp = timestamp;
+ _pool = pool;
+ Connection = _pool.Connection;
+ }
+
+ public static bool TryCreate(IXenConnection connection, out Alert alert)
+ {
+ var pool = Helpers.GetPoolOfOne(connection);
+ var timestamp = DateTime.UtcNow;
+
+ if (pool.repositories.Count == 0)
+ {
+ alert = new YumRepoNotConfiguredAlert(pool, timestamp);
+ return true;
+ }
+
+ alert = null;
+ return false;
+ }
+
+ public override AlertPriority Priority => AlertPriority.Priority3;
+
+ public override string AppliesTo => Helpers.GetName(_pool);
+
+ public override string Description => Messages.ALERT_CDN_REPO_NOT_CONFIGURED_DESCRIPTION;
+
+ public override Action FixLinkAction
+ {
+ get
+ {
+ return () =>
+ {
+ using (var dialog = new ConfigUpdatesDialog())
+ dialog.ShowDialog(Program.MainWindow);
+ };
+ }
+ }
+
+ public override string FixLinkText => Messages.ALERT_CDN_REPO_NOT_CONFIGURED_ACTION_LINK;
+
+ public override string HelpID => "TODO";
+
+ public override string Title => string.Format(Messages.ALERT_CDN_REPO_NOT_CONFIGURED_TITLE, Connection.Name);
+ }
+}
diff --git a/XenAdmin/MainWindow.cs b/XenAdmin/MainWindow.cs
index 661cdba79..fdeda4729 100755
--- a/XenAdmin/MainWindow.cs
+++ b/XenAdmin/MainWindow.cs
@@ -1083,6 +1083,9 @@ namespace XenAdmin
if (Helpers.CloudOrGreater(connection))
{
+ if (YumRepoNotConfiguredAlert.TryCreate(connection, out var alert) || OutOfSyncWithCdnAlert.TryCreate(connection, out alert))
+ Alert.AddAlert(alert);
+
Updates.CheckForCdnUpdates(coordinator.Connection);
}
else
diff --git a/XenAdmin/TabPages/AlertSummaryPage.cs b/XenAdmin/TabPages/AlertSummaryPage.cs
index bff8c58e5..171203e38 100644
--- a/XenAdmin/TabPages/AlertSummaryPage.cs
+++ b/XenAdmin/TabPages/AlertSummaryPage.cs
@@ -648,11 +648,11 @@ namespace XenAdmin.TabPages
private void DismissAlerts(params Alert[] alerts)
{
- var groups = from Alert alert in alerts
- where alert != null && alert.AllowedToDismiss()
- group alert by alert.Connection
- into g
- select new { Connection = g.Key, Alerts = g };
+ var groups = (from Alert alert in alerts
+ where alert != null && alert.AllowedToDismiss()
+ group alert by alert.Connection
+ into g
+ select new { Connection = g.Key, Alerts = g }).ToList();
foreach (var g in groups)
{
diff --git a/XenModel/Alerts/Types/Alert.cs b/XenModel/Alerts/Types/Alert.cs
index 9f839880e..b83b22af9 100644
--- a/XenModel/Alerts/Types/Alert.cs
+++ b/XenModel/Alerts/Types/Alert.cs
@@ -192,7 +192,7 @@ namespace XenAdmin.Alerts
public string uuid;
protected int _priority;
- public Alert()
+ protected Alert()
{
uuid = Guid.NewGuid().ToString();
}
diff --git a/XenModel/Messages.Designer.cs b/XenModel/Messages.Designer.cs
index 0bfb5e1c1..2907ddca1 100755
--- a/XenModel/Messages.Designer.cs
+++ b/XenModel/Messages.Designer.cs
@@ -4984,6 +4984,42 @@ namespace XenAdmin {
}
}
+ ///
+ /// Looks up a localized string similar to You have not synchronized with the update channel in {0} days..
+ ///
+ public static string ALERT_CDN_OUT_OF_SYNC_TITLE {
+ get {
+ return ResourceManager.GetString("ALERT_CDN_OUT_OF_SYNC_TITLE", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configure Updates.
+ ///
+ public static string ALERT_CDN_REPO_NOT_CONFIGURED_ACTION_LINK {
+ get {
+ return ResourceManager.GetString("ALERT_CDN_REPO_NOT_CONFIGURED_ACTION_LINK", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configuring an update channel will allow your system to synchronize and retrieve available updates..
+ ///
+ public static string ALERT_CDN_REPO_NOT_CONFIGURED_DESCRIPTION {
+ get {
+ return ResourceManager.GetString("ALERT_CDN_REPO_NOT_CONFIGURED_DESCRIPTION", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You have not configured an update channel on '{0}'.
+ ///
+ public static string ALERT_CDN_REPO_NOT_CONFIGURED_TITLE {
+ get {
+ return ResourceManager.GetString("ALERT_CDN_REPO_NOT_CONFIGURED_TITLE", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to When CPU usage exceeds {0}% for {1} min(s).
///
@@ -37420,7 +37456,7 @@ namespace XenAdmin {
}
///
- /// Looks up a localized string similar to Configure updates....
+ /// Looks up a localized string similar to Configure Updates....
///
public static string UPDATES_GENERAL_TAB_CONFIG {
get {
diff --git a/XenModel/Messages.resx b/XenModel/Messages.resx
index e01bf00d3..b9acdd769 100755
--- a/XenModel/Messages.resx
+++ b/XenModel/Messages.resx
@@ -1831,6 +1831,18 @@ This alarm is set to be triggered when the total throughput exceeds {4}.
(Showing first {0} entries)
+
+ You have not synchronized with the update channel in {0} days.
+
+
+ Configure Updates
+
+
+ Configuring an update channel will allow your system to synchronize and retrieve available updates.
+
+
+ You have not configured an update channel on '{0}'
+
When CPU usage exceeds {0}% for {1} min(s)
@@ -12928,7 +12940,7 @@ Note that if RBAC is enabled, only updates which you have privileges to dismiss
Download {0}
- Configure updates...
+ Configure Updates...
(full application required)