CA-274082: Check status of SR uploaded updates during update installa… (#1937)

* CA-274082: Check status of SR uploaded updates during update installation
* fix review comments

Signed-off-by: Jisheng Xing <jisheng.xing@citrix.com>
This commit is contained in:
jishengx 2018-03-14 20:19:14 +08:00 committed by Mihaela Stoica
parent c9214af05f
commit 0c13d8786d
10 changed files with 124 additions and 33 deletions

View File

@ -40,8 +40,11 @@ namespace XenAdmin.Diagnostics.Checks
{
public class PBDsPluggedCheck : Check
{
public PBDsPluggedCheck(Host host):base(host)
SR srUploadedUpdates;
public PBDsPluggedCheck(Host host, SR sr = null) : base(host)
{
srUploadedUpdates = sr;
}
protected override Problem RunCheck()
@ -54,8 +57,12 @@ namespace XenAdmin.Diagnostics.Checks
foreach (SR sr in brokenSRs)
{
return new BrokenSR(this, sr);
return new BrokenSR(this, sr, Host);
}
if (srUploadedUpdates != null && !srUploadedUpdates.CanBeSeenFrom(Host))
return new BrokenSR(this, srUploadedUpdates, Host);
return null;
}

View File

@ -35,6 +35,7 @@ using XenAdmin.Diagnostics.Problems;
using XenAdmin.Core;
using System.IO;
using XenAdmin.Diagnostics.Problems.HostProblem;
using XenAdmin.Diagnostics.Problems.SRProblem;
using System.Text.RegularExpressions;
using System.Xml;
using System.Collections.Generic;
@ -53,6 +54,7 @@ namespace XenAdmin.Diagnostics.Checks
private static Regex LivePatchResponseRegex = new Regex("(<livepatch).+(</livepatch>)");
private readonly Dictionary<string, livepatch_status> livePatchCodesByHost;
private SR srUploadedUpdates;
public PatchPrecheckCheck(Host host, Pool_patch patch)
: this(host, patch, null)
@ -71,15 +73,22 @@ namespace XenAdmin.Diagnostics.Checks
this.livePatchCodesByHost = livePatchCodesByHost;
}
public PatchPrecheckCheck(Host host, Pool_update update, Dictionary<string, livepatch_status> livePatchCodesByHost)
public PatchPrecheckCheck(Host host, Pool_update update, Dictionary<string, livepatch_status> livePatchCodesByHost, SR srUploadedUpdates = null)
: base(host)
{
_update = update;
this.livePatchCodesByHost = livePatchCodesByHost;
this.srUploadedUpdates = srUploadedUpdates;
}
protected override Problem RunCheck()
{
//
// Check that the SR where the update was uploaded is still attached
//
if (srUploadedUpdates != null && !srUploadedUpdates.CanBeSeenFrom(Host))
return new BrokenSRWarning(this, Host, srUploadedUpdates);
//
// Check patch isn't already applied here
//

View File

@ -34,25 +34,30 @@ using XenAdmin.Diagnostics.Checks;
using XenAPI;
using XenAdmin.Dialogs;
using XenAdmin.Actions;
using XenAdmin.Core;
namespace XenAdmin.Diagnostics.Problems.SRProblem
{
public class BrokenSR : SRProblem
{
public BrokenSR(Check check, SR sr)
: base(check,sr) { }
private readonly Host host;
public BrokenSR(Check check, SR sr, Host host)
: base(check, sr)
{
this.host = host;
}
public override string Description
{
get { return string.Format(Messages.UPDATES_WIZARD_BROKEN_STORAGE, Sr.NameWithoutHost()); }
get { return string.Format(Messages.UPDATES_WIZARD_BROKEN_STORAGE, Helpers.GetName(host).Ellipsise(30), Sr.NameWithoutHost()); }
}
protected override AsyncAction CreateAction(out bool cancelled)
{
Program.AssertOnEventThread();
RepairSRDialog dlg = new RepairSRDialog(Sr);
RepairSRDialog dlg = new RepairSRDialog(Sr, false);
if (dlg.ShowDialog(Program.MainWindow) == DialogResult.OK)
{
cancelled = false;
@ -68,4 +73,30 @@ namespace XenAdmin.Diagnostics.Problems.SRProblem
get { return Messages.REPAIR_SR; }
}
}
class BrokenSRWarning : Warning
{
private readonly Host host;
private readonly SR sr;
public BrokenSRWarning(Check check, Host host, SR sr)
: base(check)
{
this.sr = sr;
this.host = host;
}
public override string Title
{
get { return Check.Description; }
}
public override string Description
{
get
{
return string.Format(Messages.UPDATES_WIZARD_BROKEN_SR_WARNING, Helpers.GetName(host).Ellipsise(30), sr);
}
}
}
}

View File

@ -59,7 +59,7 @@ namespace XenAdmin.Dialogs
private Font BoldFont;
private readonly CollectionChangeEventHandler Host_CollectionChangedWithInvoke;
private readonly CollectionChangeEventHandler PBD_CollectionChangedWithInvoke;
private bool runAction;
public AsyncAction RepairAction
{
get
@ -72,18 +72,18 @@ namespace XenAdmin.Dialogs
/// Initializes a new instance of the <see cref="RepairSRDialog"/> class.
/// </summary>
/// <param name="sr">The SR to be repaired.</param>
public RepairSRDialog(SR sr)
: this(new SR[] { sr })
{
}
public RepairSRDialog(SR sr, bool runAction = true)
: this(new SR[] { sr }, runAction)
{}
/// <summary>
/// Initializes a new instance of the <see cref="RepairSRDialog"/> class.
/// </summary>
/// <param name="srs">The SRs to be repaired.</param>
public RepairSRDialog(IEnumerable<SR> srs)
public RepairSRDialog(IEnumerable<SR> srs, bool runAction = true)
{
Util.ThrowIfEnumerableParameterNullOrEmpty(srs, "srs");
this.runAction = runAction;
BoldFont = new Font(Font, FontStyle.Bold);
List<SR> srList = new List<SR>(srs);
srList.Sort();
@ -279,10 +279,14 @@ namespace XenAdmin.Dialogs
_repairAction = new MultipleAction(null, string.Empty, string.Empty, string.Empty, subActions, true);
}
_repairAction.Changed += action_Changed;
_repairAction.Completed += action_Completed;
Grow(_repairAction.RunAsync);
if (runAction)
{
_repairAction.Changed += action_Changed;
_repairAction.Completed += action_Completed;
Grow(_repairAction.RunAsync);
}
}
private void action_Changed(ActionBase action)

View File

@ -199,6 +199,7 @@ namespace XenAdmin.Wizards.PatchingWizard
PatchingWizard_PatchingPage.Patch = PatchingWizard_UploadPage.Patch;
}
PatchingWizard_PrecheckPage.PoolUpdate = PatchingWizard_UploadPage.PoolUpdate;
PatchingWizard_PrecheckPage.SrUploadedUpdates = PatchingWizard_UploadPage.SrUploadedUpdates;
PatchingWizard_PatchingPage.PoolUpdate = PatchingWizard_UploadPage.PoolUpdate;
PatchingWizard_ModePage.PoolUpdate = PatchingWizard_UploadPage.PoolUpdate;
PatchingWizard_PatchingPage.SuppPackVdis = PatchingWizard_UploadPage.SuppPackVdis;
@ -248,7 +249,7 @@ namespace XenAdmin.Wizards.PatchingWizard
private List<AsyncAction> GetRemovePatchActions(List<Pool_patch> patchesToRemove)
{
if (patchesToRemove == null)
if (patchesToRemove == null || patchesToRemove.Count == 0)
return null;
List<AsyncAction> list = new List<AsyncAction>();
@ -276,7 +277,7 @@ namespace XenAdmin.Wizards.PatchingWizard
private List<AsyncAction> GetRemoveVdiActions(List<VDI> vdisToRemove)
{
if (vdisToRemove == null)
if (vdisToRemove == null || vdisToRemove.Count == 0)
return null;
var list = (from vdi in vdisToRemove

View File

@ -59,6 +59,7 @@ namespace XenAdmin.Wizards.PatchingWizard
public List<Host> SelectedServers = new List<Host>();
public List<Problem> ProblemsResolvedPreCheck = new List<Problem>();
private AsyncAction resolvePrechecksAction;
public Dictionary<Pool_update, Dictionary<Host, SR>> SrUploadedUpdates = new Dictionary<Pool_update, Dictionary<Host, SR>>();
protected List<Pool> SelectedPools
{
@ -363,11 +364,24 @@ namespace XenAdmin.Wizards.PatchingWizard
//PBDsPluggedCheck
var pbdChecks = new List<Check>();
foreach (Host host in applicableServers)
pbdChecks.Add(new PBDsPluggedCheck(host));
{
SR uploadSr = null;
if (PoolUpdate != null && SrUploadedUpdates != null)
{
foreach (var dict in SrUploadedUpdates)
{
if (dict.Key.uuid == PoolUpdate.uuid && dict.Value.ContainsKey(host))
{
uploadSr = dict.Value[host];
break;
}
}
}
pbdChecks.Add(new PBDsPluggedCheck(host, uploadSr));
}
groups.Add(new CheckGroup(Messages.CHECKING_STORAGE_CONNECTIONS_STATUS, pbdChecks));
//Disk space check for automated updates
if (WizardMode != WizardMode.SingleUpdate)
{
@ -506,7 +520,10 @@ namespace XenAdmin.Wizards.PatchingWizard
{
List<Pool_update> updates = new List<Pool_update>(host.Connection.Cache.Pool_updates);
Pool_update poolUpdateFromHost = updates.Find(otherPatch => string.Equals(otherPatch.uuid, update.uuid, StringComparison.OrdinalIgnoreCase));
serverChecks.Add(new PatchPrecheckCheck(host, poolUpdateFromHost, LivePatchCodesByHost));
SR uploadSr = null;
if (SrUploadedUpdates != null && SrUploadedUpdates.ContainsKey(poolUpdateFromHost) && SrUploadedUpdates[poolUpdateFromHost].ContainsKey(host))
uploadSr = SrUploadedUpdates[poolUpdateFromHost][host];
serverChecks.Add(new PatchPrecheckCheck(host, poolUpdateFromHost, LivePatchCodesByHost, uploadSr));
}
groups.Add(new CheckGroup(Messages.CHECKING_SERVER_SIDE_STATUS, serverChecks));
}

View File

@ -88,7 +88,7 @@ namespace XenAdmin.Wizards.PatchingWizard
public readonly List<VDI> AllCreatedSuppPackVdis = new List<VDI>();
public Dictionary<Host, VDI> SuppPackVdis = new Dictionary<Host, VDI>();
public Dictionary<Pool_update, string> AllIntroducedPoolUpdates = new Dictionary<Pool_update, string>();
public Dictionary<Pool_update, Dictionary<Host, SR>> SrUploadedUpdates = new Dictionary<Pool_update, Dictionary<Host, SR>>();
#endregion
protected override void PageLoadedCore(PageLoadedDirection direction)
@ -484,29 +484,32 @@ namespace XenAdmin.Wizards.PatchingWizard
_poolUpdate = null;
}
if (action is UploadSupplementalPackAction)
var supplementalPackUploadAction = action as UploadSupplementalPackAction;
if (supplementalPackUploadAction != null)
{
_patch = null;
foreach (var vdiRef in (action as UploadSupplementalPackAction).VdiRefsToCleanUp)
foreach (var vdiRef in supplementalPackUploadAction.VdiRefsToCleanUp)
{
SuppPackVdis[vdiRef.Key] = action.Connection.Resolve(vdiRef.Value);
SuppPackVdis[vdiRef.Key] = supplementalPackUploadAction.Connection.Resolve(vdiRef.Value);
}
AllCreatedSuppPackVdis.AddRange(SuppPackVdis.Values.Where(vdi => !AllCreatedSuppPackVdis.Contains(vdi)));
AddToUploadedUpdates(SelectedNewPatchPath, master);
if (Helpers.ElyOrGreater(action.Connection))
if (Helpers.ElyOrGreater(supplementalPackUploadAction.Connection))
{
var newPoolUpdate = ((UploadSupplementalPackAction)action).PoolUpdate;
var newPoolUpdate = (supplementalPackUploadAction).PoolUpdate;
if (newPoolUpdate != null)
{
_poolUpdate = newPoolUpdate;
AllIntroducedPoolUpdates.Add(PoolUpdate, SelectedNewPatchPath);
SrUploadedUpdates[newPoolUpdate] = new Dictionary<Host, SR>(supplementalPackUploadAction.SrUploadedUpdates);
}
}
}
}
if (action is DownloadAndUnzipXenServerPatchAction)

View File

@ -52,6 +52,9 @@ namespace XenAdmin.Actions
private readonly List<Host> servers;
private Pool_update poolUpdate = null;
public Dictionary<Host, SR> SrUploadedUpdates = new Dictionary<Host, SR>();
public Pool_update PoolUpdate
{
get { return poolUpdate; }
@ -185,7 +188,7 @@ namespace XenAdmin.Actions
//after having tried to remove the VDI, the original exception is thrown for the UI
if (ex is TargetInvocationException && ex.InnerException != null)
throw ex.InnerException;
else
else
throw ex;
}
finally
@ -257,6 +260,10 @@ namespace XenAdmin.Actions
totalUploaded++;
Description = String.Format(Messages.SUPP_PACK_UPLOADED, sr.Name());
foreach (Host host in servers)
SrUploadedUpdates[host] = sr;
return result;
}
@ -357,5 +364,5 @@ namespace XenAdmin.Actions
{
return sr.FreeSpace() >= diskSize;
}
}
}
}

View File

@ -34031,7 +34031,16 @@ namespace XenAdmin {
}
/// <summary>
/// Looks up a localized string similar to The {0} storage repository is broken..
/// Looks up a localized string similar to {0}: Check skipped because the &apos;{1}&apos; storage repository is broken..
/// </summary>
public static string UPDATES_WIZARD_BROKEN_SR_WARNING {
get {
return ResourceManager.GetString("UPDATES_WIZARD_BROKEN_SR_WARNING", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}: The &apos;{1}&apos; storage repository is broken..
/// </summary>
public static string UPDATES_WIZARD_BROKEN_STORAGE {
get {

View File

@ -11740,8 +11740,11 @@ Verify that the file is a valid {1} export.</value>
<data name="UPDATES_WIZARD_APPLY_UPDATE" xml:space="preserve">
<value>&amp;Install update</value>
</data>
<data name="UPDATES_WIZARD_BROKEN_SR_WARNING" xml:space="preserve">
<value>{0}: Check skipped because the '{1}' storage repository is broken.</value>
</data>
<data name="UPDATES_WIZARD_BROKEN_STORAGE" xml:space="preserve">
<value>The {0} storage repository is broken.</value>
<value>{0}: The '{1}' storage repository is broken.</value>
</data>
<data name="UPDATES_WIZARD_CANNOT_DOWNLOAD_PATCH" xml:space="preserve">
<value>Unable to download update from '{0}': no longer connected.