mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-23 12:30:50 +01:00
Show update status for pools and hosts on the General tabPage:
- Show sync status for the pool in its Updates section. - Moved update date for the host from the Version to the Updates section. Signed-off-by: Konstantina Chremmou <Konstantina.Chremmou@cloud.com>
This commit is contained in:
parent
b0c23a2c36
commit
2774ea5c7f
@ -394,6 +394,13 @@ namespace XenAdmin.Controls
|
||||
AddRow(CreateKeyCell(key), valueCell, null, contextMenuItems);
|
||||
}
|
||||
|
||||
internal void AddEntryWithNoteLink(string key, string value, string note, Action action, params ToolStripMenuItem[] contextMenuItems)
|
||||
{
|
||||
var valueCell = new DataGridViewTextBoxCell { Value = value };
|
||||
var noteCell = new DataGridViewLinkCell { Value = note, Tag = action };
|
||||
AddRow(CreateKeyCell(key), valueCell, noteCell, contextMenuItems);
|
||||
}
|
||||
|
||||
internal void AddEntryWithNoteLink(string key, string value, string note, Action action, Color fontColor, params ToolStripMenuItem[] contextMenuItems)
|
||||
{
|
||||
var valueCell = new DataGridViewTextBoxCell { Value = value };
|
||||
|
@ -71,7 +71,7 @@ namespace XenAdmin.Controls
|
||||
comboBoxCacheSr.Items.Clear();
|
||||
|
||||
// add the "Not configured" item first
|
||||
var notConfiguredItem = new SrComboBoxItem(null, Messages.PVS_CACHE_NOT_CONFIGURED);
|
||||
var notConfiguredItem = new SrComboBoxItem(null, Messages.NOT_CONFIGURED);
|
||||
comboBoxCacheSr.Items.Add(notConfiguredItem);
|
||||
|
||||
// add Memory SR; if no memory SR found, add a placeholder (we will create the memory SR in ConfigurePvsCacheAction)
|
||||
|
@ -109,7 +109,7 @@ namespace XenAdmin.Dialogs
|
||||
var configuredRows = rows.Where(r => r.CacheSr != null).ToList();
|
||||
|
||||
if (configuredRows.Count == 0)
|
||||
return Messages.PVS_CACHE_NOT_CONFIGURED;
|
||||
return Messages.NOT_CONFIGURED;
|
||||
|
||||
return configuredRows.Any(row => row.CacheSr.GetSRType(false) != SR.SRTypes.tmpfs)
|
||||
? Messages.PVS_CACHE_MEMORY_AND_DISK
|
||||
|
@ -35,11 +35,13 @@ using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using XenAdmin.Actions;
|
||||
using XenAdmin.Commands;
|
||||
using XenAdmin.Controls;
|
||||
using XenAdmin.Core;
|
||||
using XenAdmin.CustomFields;
|
||||
using XenAdmin.Dialogs;
|
||||
using XenAdmin.Dialogs.ServerUpdates;
|
||||
using XenAdmin.Model;
|
||||
using XenAdmin.Network;
|
||||
using XenAdmin.SettingsPanels;
|
||||
@ -372,9 +374,8 @@ namespace XenAdmin.TabPages
|
||||
base.Text = Messages.CONNECTION_GENERAL_TAB_TITLE;
|
||||
else if (xenObject is Host)
|
||||
base.Text = Messages.HOST_GENERAL_TAB_TITLE;
|
||||
else if (xenObject is VM)
|
||||
else if (xenObject is VM vm)
|
||||
{
|
||||
VM vm = (VM)xenObject;
|
||||
if (vm.is_a_snapshot)
|
||||
base.Text = Messages.SNAPSHOT_GENERAL_TAB_TITLE;
|
||||
else if (vm.is_a_template)
|
||||
@ -417,12 +418,12 @@ namespace XenAdmin.TabPages
|
||||
GenerateVersionBox();
|
||||
GenerateLicenseBox();
|
||||
GenerateCPUBox();
|
||||
GenerateHostPatchesBox();
|
||||
GenerateHostUpdatesBox();
|
||||
GenerateBootBox();
|
||||
GenerateHABox();
|
||||
GenerateStatusBox();
|
||||
GenerateMultipathBox();
|
||||
GeneratePoolPatchesBox();
|
||||
GeneratePoolUpdatesBox();
|
||||
GenerateMultipathBootBox();
|
||||
GenerateVCPUsBox();
|
||||
GenerateDockerInfoBox();
|
||||
@ -543,24 +544,18 @@ namespace XenAdmin.TabPages
|
||||
}
|
||||
}
|
||||
|
||||
private void GeneratePoolPatchesBox()
|
||||
private void GeneratePoolUpdatesBox()
|
||||
{
|
||||
if (!(xenObject is Pool pool))
|
||||
return;
|
||||
|
||||
PDSection s = pdSectionUpdates;
|
||||
|
||||
var messages = CheckPoolUpdate(pool);
|
||||
if (messages.Count > 0)
|
||||
{
|
||||
foreach (var kvp in messages)
|
||||
s.AddEntry(kvp.Key, kvp.Value);
|
||||
pdSectionUpdates.AddEntry(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
Host coordinator = Helpers.GetCoordinator(xenObject.Connection);
|
||||
if (coordinator == null)
|
||||
return;
|
||||
|
||||
var fullyApplied = new List<string>();
|
||||
var partAppliedError = new List<string>();
|
||||
var partApplied = new List<string>();
|
||||
@ -568,7 +563,11 @@ namespace XenAdmin.TabPages
|
||||
var cache = xenObject.Connection.Cache;
|
||||
var allHostCount = xenObject.Connection.Cache.HostCount;
|
||||
|
||||
if (Helpers.ElyOrGreater(xenObject.Connection))
|
||||
if (Helpers.CloudOrGreater(pool.Connection))
|
||||
{
|
||||
GenerateCdnUpdatesBox(pool);
|
||||
}
|
||||
else if (Helpers.ElyOrGreater(xenObject.Connection))
|
||||
{
|
||||
foreach (var u in cache.Pool_updates)
|
||||
{
|
||||
@ -605,76 +604,127 @@ namespace XenAdmin.TabPages
|
||||
if (fullyApplied.Count > 0)
|
||||
{
|
||||
fullyApplied.Sort(StringUtility.NaturalCompare);
|
||||
s.AddEntry(FriendlyName("Pool_patch.fully_applied"), string.Join(Environment.NewLine, fullyApplied));
|
||||
pdSectionUpdates.AddEntry(FriendlyName("Pool_patch.fully_applied"), string.Join(Environment.NewLine, fullyApplied));
|
||||
}
|
||||
|
||||
if (partApplied.Count > 0)
|
||||
{
|
||||
var menuItems = new ToolStripMenuItem[] {new CommandToolStripMenuItem(new InstallNewUpdateCommand(Program.MainWindow), true)};
|
||||
partApplied.Sort(StringUtility.NaturalCompare);
|
||||
s.AddEntry(FriendlyName("Pool_patch.partially_applied"), string.Join(Environment.NewLine, partApplied), menuItems);
|
||||
pdSectionUpdates.AddEntry(FriendlyName("Pool_patch.partially_applied"), string.Join(Environment.NewLine, partApplied), menuItems);
|
||||
}
|
||||
|
||||
if (partAppliedError.Count > 0)
|
||||
{
|
||||
var menuItems = new ToolStripMenuItem[] {new CommandToolStripMenuItem(new InstallNewUpdateCommand(Program.MainWindow), true)};
|
||||
partAppliedError.Sort(StringUtility.NaturalCompare);
|
||||
s.AddEntry(string.Format(Messages.STRING_SPACE_STRING,
|
||||
pdSectionUpdates.AddEntry(string.Format(Messages.STRING_SPACE_STRING,
|
||||
FriendlyName("Pool_patch.partially_applied"), Messages.UPDATES_GENERAL_TAB_ENFORCE_HOMOGENEITY),
|
||||
string.Join(Environment.NewLine, partAppliedError), Color.Red, menuItems);
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateHostPatchesBox()
|
||||
private void GenerateCdnUpdatesBox(Pool pool)
|
||||
{
|
||||
Host host = xenObject as Host;
|
||||
if (host == null)
|
||||
return;
|
||||
var repoNames = (from repoRef in pool.repositories
|
||||
let repo = pool.Connection.Resolve(repoRef)
|
||||
where repo != null
|
||||
let found = RepoDescriptor.AllRepos.FirstOrDefault(rd => rd.MatchesRepository(repo))
|
||||
where found != null
|
||||
select found.FriendlyName).ToList();
|
||||
|
||||
PDSection s = pdSectionUpdates;
|
||||
List<KeyValuePair<String, String>> messages;
|
||||
|
||||
bool elyOrGreater = Helpers.ElyOrGreater(host);
|
||||
|
||||
if (elyOrGreater)
|
||||
{
|
||||
// As of Ely we use host.updates_requiring_reboot to generate the list of reboot required messages
|
||||
messages = CheckHostUpdatesRequiringReboot(host);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For older versions no change to how messages are generated
|
||||
messages = CheckServerUpdates(host);
|
||||
}
|
||||
|
||||
if (messages.Count > 0)
|
||||
{
|
||||
foreach (KeyValuePair<String, String> kvp in messages)
|
||||
pdSectionUpdates.AddEntryWithNoteLink(Messages.UPDATES_GENERAL_TAB_REPO,
|
||||
repoNames.Count == 0 ? Messages.NOT_CONFIGURED : string.Join("\n", repoNames),
|
||||
Messages.UPDATES_GENERAL_TAB_CONFIG,
|
||||
() =>
|
||||
{
|
||||
s.AddEntry(kvp.Key, kvp.Value);
|
||||
using (var dialog = new ConfigUpdatesDialog())
|
||||
dialog.ShowDialog(this);
|
||||
});
|
||||
|
||||
string lastSyncTime = Messages.INDETERMINABLE;
|
||||
|
||||
if (Helpers.XapiEqualOrGreater_23_18_0(pool.Connection))
|
||||
{
|
||||
lastSyncTime = Messages.NEVER;
|
||||
|
||||
if (pool.last_update_sync > Util.GetUnixMinDateTime())
|
||||
{
|
||||
lastSyncTime = HelpersGUI.DateTimeToString(pool.last_update_sync.ToLocalTime(), Messages.DATEFORMAT_DMY_HMS, true);
|
||||
}
|
||||
}
|
||||
|
||||
var appliedPatchesList = Helpers.HostAppliedPatchesList(host);
|
||||
var appliedPatches = string.Join(Environment.NewLine, appliedPatchesList.ToArray());
|
||||
pdSectionUpdates.AddEntryWithNoteLink(Messages.UPDATES_GENERAL_TAB_LAST_SYNCED,
|
||||
lastSyncTime, Messages.UPDATES_GENERAL_TAB_SYNC_NOW,
|
||||
() =>
|
||||
{
|
||||
var syncAction = new SyncWithCdnAction(pool);
|
||||
syncAction.Completed += a => Updates.CheckForCdnUpdates(a.Connection);
|
||||
syncAction.RunAsync();
|
||||
});
|
||||
}
|
||||
|
||||
private void GenerateHostUpdatesBox()
|
||||
{
|
||||
if (!(xenObject is Host host))
|
||||
return;
|
||||
|
||||
bool elyOrGreater = Helpers.ElyOrGreater(host);
|
||||
|
||||
// As of Ely we use host.updates_requiring_reboot to generate the list of reboot required messages
|
||||
// For older versions no change to how messages are generated
|
||||
|
||||
var messages = elyOrGreater ? CheckHostUpdatesRequiringReboot(host) : CheckServerUpdates(host);
|
||||
|
||||
foreach (var kvp in messages)
|
||||
pdSectionUpdates.AddEntry(kvp.Key, kvp.Value);
|
||||
|
||||
var appliedPatches = string.Join(Environment.NewLine, Helpers.HostAppliedPatchesList(host));
|
||||
|
||||
if (!string.IsNullOrEmpty(appliedPatches))
|
||||
{
|
||||
s.AddEntry(FriendlyName("Pool_patch.applied"), appliedPatches);
|
||||
}
|
||||
pdSectionUpdates.AddEntry(FriendlyName("Pool_patch.applied"), appliedPatches);
|
||||
|
||||
var recommendedPatches = RecommendedPatchesForHost(host);
|
||||
|
||||
if (!string.IsNullOrEmpty(recommendedPatches))
|
||||
{
|
||||
s.AddEntry(FriendlyName("Pool_patch.required-updates"), recommendedPatches);
|
||||
}
|
||||
pdSectionUpdates.AddEntry(FriendlyName("Pool_patch.required-updates"), recommendedPatches);
|
||||
|
||||
if (!elyOrGreater)
|
||||
{
|
||||
// add supplemental packs
|
||||
var suppPacks = hostInstalledSuppPacks(host);
|
||||
|
||||
if (!string.IsNullOrEmpty(suppPacks))
|
||||
pdSectionUpdates.AddEntry(FriendlyName("Supplemental_packs.installed"), suppPacks);
|
||||
}
|
||||
|
||||
if (Helpers.CloudOrGreater(host))
|
||||
{
|
||||
var pool = Helpers.GetPool(host.Connection);
|
||||
if (pool == null) //standalone host
|
||||
{
|
||||
s.AddEntry(FriendlyName("Supplemental_packs.installed"), suppPacks);
|
||||
pool = Helpers.GetPoolOfOne(host.Connection);
|
||||
GenerateCdnUpdatesBox(pool);
|
||||
}
|
||||
|
||||
if (Helpers.XapiEqualOrGreater_22_20_0(host))
|
||||
{
|
||||
var unixMinDateTime = Util.GetUnixMinDateTime();
|
||||
var softwareVersionDate = unixMinDateTime;
|
||||
|
||||
if (host.software_version.ContainsKey("date"))
|
||||
{
|
||||
if (!Util.TryParseIso8601DateTime(host.software_version["date"], out softwareVersionDate))
|
||||
Util.TryParseNonIso8601DateTime(host.software_version["date"], out softwareVersionDate);
|
||||
}
|
||||
|
||||
string lastUpdateTime = Messages.NEVER;
|
||||
|
||||
if (host.last_software_update > softwareVersionDate && host.last_software_update > unixMinDateTime)
|
||||
{
|
||||
lastUpdateTime = HelpersGUI.DateTimeToString(host.last_software_update.ToLocalTime(), Messages.DATEFORMAT_DMY_HMS, true);
|
||||
}
|
||||
|
||||
pdSectionUpdates.AddEntry(Messages.SOFTWARE_VERSION_LAST_UPDATED, lastUpdateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1080,19 +1130,16 @@ namespace XenAdmin.TabPages
|
||||
|
||||
private void GenerateVersionBox()
|
||||
{
|
||||
Host host = xenObject as Host;
|
||||
|
||||
if (host == null || host.software_version == null)
|
||||
if (!(xenObject is Host host) || host.software_version == null)
|
||||
return;
|
||||
|
||||
var softwareVersionDate = DateTime.MinValue;
|
||||
var unixMinDateTime = Util.GetUnixMinDateTime();
|
||||
|
||||
if (host.software_version.ContainsKey("date"))
|
||||
{
|
||||
string buildDate = host.software_version["date"];
|
||||
|
||||
if (Util.TryParseIso8601DateTime(host.software_version["date"], out softwareVersionDate) && softwareVersionDate > unixMinDateTime)
|
||||
if (Util.TryParseIso8601DateTime(host.software_version["date"], out var softwareVersionDate) && softwareVersionDate > unixMinDateTime)
|
||||
buildDate = HelpersGUI.DateTimeToString(softwareVersionDate.ToLocalTime(), Messages.DATEFORMAT_DMY_HMS, true);
|
||||
else if (Util.TryParseNonIso8601DateTime(host.software_version["date"], out softwareVersionDate) && softwareVersionDate > unixMinDateTime)
|
||||
buildDate = HelpersGUI.DateTimeToString(softwareVersionDate.ToLocalTime(), Messages.DATEFORMAT_DMY, true);
|
||||
@ -1116,11 +1163,6 @@ namespace XenAdmin.TabPages
|
||||
|
||||
if (host.software_version.ContainsKey("dbv"))
|
||||
pdSectionVersion.AddEntry("DBV", host.software_version["dbv"]);
|
||||
|
||||
if (Helpers.CloudOrGreater(host) && Helpers.XapiEqualOrGreater_22_20_0(host) &&
|
||||
host.last_software_update > softwareVersionDate && host.last_software_update > unixMinDateTime)
|
||||
pdSectionVersion.AddEntry(Messages.SOFTWARE_VERSION_LAST_UPDATED,
|
||||
HelpersGUI.DateTimeToString(host.last_software_update.ToLocalTime(), Messages.DATEFORMAT_DMY_HMS, true));
|
||||
}
|
||||
|
||||
private void GenerateCPUBox()
|
||||
|
63
XenModel/Messages.Designer.cs
generated
63
XenModel/Messages.Designer.cs
generated
@ -21503,6 +21503,15 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Indeterminable.
|
||||
/// </summary>
|
||||
public static string INDETERMINABLE {
|
||||
get {
|
||||
return ResourceManager.GetString("INDETERMINABLE", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Disk snapshots are not currently available for this VM.
|
||||
/// </summary>
|
||||
@ -28382,6 +28391,15 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not configured.
|
||||
/// </summary>
|
||||
public static string NOT_CONFIGURED {
|
||||
get {
|
||||
return ResourceManager.GetString("NOT_CONFIGURED", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to not contained in.
|
||||
/// </summary>
|
||||
@ -31749,15 +31767,6 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not configured.
|
||||
/// </summary>
|
||||
public static string PVS_CACHE_NOT_CONFIGURED {
|
||||
get {
|
||||
return ResourceManager.GetString("PVS_CACHE_NOT_CONFIGURED", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This PVS cache storage cannot be changed because it is in use..
|
||||
/// </summary>
|
||||
@ -37410,6 +37419,15 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Configure updates....
|
||||
/// </summary>
|
||||
public static string UPDATES_GENERAL_TAB_CONFIG {
|
||||
get {
|
||||
return ResourceManager.GetString("UPDATES_GENERAL_TAB_CONFIG", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to (full application required).
|
||||
/// </summary>
|
||||
@ -37419,6 +37437,33 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Last synchronized.
|
||||
/// </summary>
|
||||
public static string UPDATES_GENERAL_TAB_LAST_SYNCED {
|
||||
get {
|
||||
return ResourceManager.GetString("UPDATES_GENERAL_TAB_LAST_SYNCED", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Update channel.
|
||||
/// </summary>
|
||||
public static string UPDATES_GENERAL_TAB_REPO {
|
||||
get {
|
||||
return ResourceManager.GetString("UPDATES_GENERAL_TAB_REPO", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Synchronize Now.
|
||||
/// </summary>
|
||||
public static string UPDATES_GENERAL_TAB_SYNC_NOW {
|
||||
get {
|
||||
return ResourceManager.GetString("UPDATES_GENERAL_TAB_SYNC_NOW", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Automatically check for {0} updates.
|
||||
/// </summary>
|
||||
|
@ -7491,6 +7491,9 @@ This might result in failure to migrate VMs to this server during the RPU or to
|
||||
<data name="INCORRECT_OLD_PASSWORD" xml:space="preserve">
|
||||
<value>Incorrect old password</value>
|
||||
</data>
|
||||
<data name="INDETERMINABLE" xml:space="preserve">
|
||||
<value>Indeterminable</value>
|
||||
</data>
|
||||
<data name="INFO_DISK_MODE" xml:space="preserve">
|
||||
<value>Disk snapshots are not currently available for this VM</value>
|
||||
</data>
|
||||
@ -9858,6 +9861,9 @@ When you configure an NFS storage repository, you simply provide the host name o
|
||||
<data name="NOT_ATTACHED_TO" xml:space="preserve">
|
||||
<value>not attached to</value>
|
||||
</data>
|
||||
<data name="NOT_CONFIGURED" xml:space="preserve">
|
||||
<value>Not configured</value>
|
||||
</data>
|
||||
<data name="NOT_CONTAINED_IN" xml:space="preserve">
|
||||
<value>not contained in</value>
|
||||
</data>
|
||||
@ -10998,9 +11004,6 @@ Click Previous if you need to go back and specify a different network location o
|
||||
<data name="PVS_CACHE_MEMORY_SR_NAME" xml:space="preserve">
|
||||
<value>MemorySR</value>
|
||||
</data>
|
||||
<data name="PVS_CACHE_NOT_CONFIGURED" xml:space="preserve">
|
||||
<value>Not configured</value>
|
||||
</data>
|
||||
<data name="PVS_CACHE_STORAGE_CANNOT_BE_CHANGED" xml:space="preserve">
|
||||
<value>This PVS cache storage cannot be changed because it is in use.</value>
|
||||
</data>
|
||||
@ -12924,9 +12927,21 @@ Note that if RBAC is enabled, only updates which you have privileges to dismiss
|
||||
<data name="UPDATES_DOWNLOAD_REQUIRED_XENCENTER" xml:space="preserve">
|
||||
<value>Download {0}</value>
|
||||
</data>
|
||||
<data name="UPDATES_GENERAL_TAB_CONFIG" xml:space="preserve">
|
||||
<value>Configure updates...</value>
|
||||
</data>
|
||||
<data name="UPDATES_GENERAL_TAB_ENFORCE_HOMOGENEITY" xml:space="preserve">
|
||||
<value>(full application required)</value>
|
||||
</data>
|
||||
<data name="UPDATES_GENERAL_TAB_LAST_SYNCED" xml:space="preserve">
|
||||
<value>Last synchronized</value>
|
||||
</data>
|
||||
<data name="UPDATES_GENERAL_TAB_REPO" xml:space="preserve">
|
||||
<value>Update channel</value>
|
||||
</data>
|
||||
<data name="UPDATES_GENERAL_TAB_SYNC_NOW" xml:space="preserve">
|
||||
<value>Synchronize Now</value>
|
||||
</data>
|
||||
<data name="UPDATES_OPTIONS_DESC" xml:space="preserve">
|
||||
<value>Automatically check for {0} updates</value>
|
||||
</data>
|
||||
|
Loading…
Reference in New Issue
Block a user