mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2025-01-20 07:19:18 +01:00
CP-28284: Updates wizard: Add a "pause and resume" mechanism to handle failures
Signed-off-by: Mihaela Stoica <mihaela.stoica@citrix.com>
This commit is contained in:
parent
da2c96ad1c
commit
7fa9d0b94f
@ -55,6 +55,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
protected static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool _thisPageIsCompleted = false;
|
||||
private bool _someWorkersFailed = false;
|
||||
|
||||
public List<Problem> ProblemsResolvedPreCheck { private get; set; }
|
||||
|
||||
@ -69,6 +70,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
public KeyValuePair<XenServerPatch, string> PatchFromDisk { private get; set; }
|
||||
|
||||
private List<UpdateProgressBackgroundWorker> backgroundWorkers = new List<UpdateProgressBackgroundWorker>();
|
||||
private List<UpdateProgressBackgroundWorker> failedWorkers = new List<UpdateProgressBackgroundWorker>();
|
||||
|
||||
public PatchingWizard_AutomatedUpdatesPage()
|
||||
{
|
||||
@ -136,6 +138,8 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
labelTitle.Text = Messages.PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_AUTOMATED_MODE;
|
||||
else if (WizardMode == WizardMode.NewVersion)
|
||||
labelTitle.Text = Messages.PATCHINGWIZARD_UPLOAD_AND_INSTALL_TITLE_NEW_VERSION_AUTOMATED_MODE;
|
||||
|
||||
ToggleRetryButton();
|
||||
|
||||
if (!StartUpgradeWorkers())
|
||||
{
|
||||
@ -213,17 +217,18 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
if (action != null && delayedActionsPerHost.All(a => a.GetType() != action.GetType()))
|
||||
delayedActionsPerHost.Add(action);
|
||||
}
|
||||
var isLastHostInPool = hosts.IndexOf(host) == hosts.Count - 1;
|
||||
if (isLastHostInPool)
|
||||
{
|
||||
// add cleanup action for current patch at the end of the update seuence for the last host in the pool
|
||||
planActionsPerHost.Add(new RemoveUpdateFileFromMasterPlanAction(master, patchMappings, patch));
|
||||
}
|
||||
}
|
||||
|
||||
planActions.Add(new HostActionTuple(host, planActionsPerHost, delayedActionsPerHost));
|
||||
}
|
||||
|
||||
var finalActions = new List<PlanAction>();
|
||||
|
||||
//clean up master at the end
|
||||
foreach (var patch in uploadedPatches)
|
||||
finalActions.Add(new RemoveUpdateFileFromMasterPlanAction(master, patchMappings, patch));
|
||||
|
||||
//add a revert pre-check action for this pool
|
||||
var problemsToRevert = ProblemsResolvedPreCheck.Where(p => hosts.ToList().Select(h => h.uuid).ToList().Contains(p.Check.Host.uuid)).ToList();
|
||||
if (problemsToRevert.Count > 0)
|
||||
@ -271,7 +276,14 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
actionsWorker.DoneActions.Add(action);
|
||||
actionsWorker.InProgressActions.Remove(action);
|
||||
|
||||
progressBar.Value += e.ProgressPercentage / backgroundWorkers.Count; //extend with error handling related numbers
|
||||
if (action.Error == null)
|
||||
{
|
||||
// remove the successful action from the cleanup actions (we are running the cleanup actions in case of failures or if the user cancelled the process, but we shouldn't re-run the actions that have already been run)
|
||||
actionsWorker.CleanupActions.Remove(action);
|
||||
|
||||
// only increase the progress if the action succeeded
|
||||
progressBar.Value += e.ProgressPercentage/backgroundWorkers.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,8 +467,12 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
|
||||
doWorkEventArgs.Result = new Exception(action.Title, e);
|
||||
|
||||
|
||||
failedWorkers.Add(sender as UpdateProgressBackgroundWorker);
|
||||
bgw.ReportProgress(0);
|
||||
|
||||
//this pool failed, we will stop here, but try to remove update files at least
|
||||
try
|
||||
/*try
|
||||
{
|
||||
if (action is DownloadPatchPlanAction || action is UploadPatchToMasterPlanAction)
|
||||
return;
|
||||
@ -487,14 +503,20 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
finally
|
||||
{
|
||||
bgw.ReportProgress(0);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
private void RunPlanAction(UpdateProgressBackgroundWorker bgw, PlanAction action)
|
||||
{
|
||||
action.OnProgressChange += action_OnProgressChange;
|
||||
if (bgw.DoneActions.Contains(action) && action.Error == null) // this action was completed successfully, do not run it again
|
||||
return;
|
||||
|
||||
// if we retry a failed action, we need to firstly remove it from DoneActions and reset it's Error
|
||||
bgw.DoneActions.Remove(action);
|
||||
action.Error = null;
|
||||
|
||||
action.OnProgressChange += action_OnProgressChange;
|
||||
bgw.ReportProgress(0, action);
|
||||
action.Run();
|
||||
|
||||
@ -523,6 +545,8 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
: Messages.PATCHINGWIZARD_AUTOUPDATINGPAGE_ERROR_ONE;
|
||||
pictureBox1.Image = Images.StaticImages._000_error_h32bit_16;
|
||||
panel1.Visible = true;
|
||||
|
||||
_someWorkersFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -536,9 +560,12 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
: Messages.PATCHINGWIZARD_AUTOUPDATINGPAGE_SUCCESS_ONE;
|
||||
pictureBox1.Image = Images.StaticImages._000_Tick_h32bit_16;
|
||||
panel1.Visible = true;
|
||||
progressBar.Value = 100;
|
||||
}
|
||||
|
||||
progressBar.Value = 100;
|
||||
|
||||
// show the retry button, if needed
|
||||
ToggleRetryButton();
|
||||
|
||||
_thisPageIsCompleted = true;
|
||||
_cancelEnabled = false;
|
||||
_nextEnabled = true;
|
||||
@ -566,7 +593,32 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
}
|
||||
}
|
||||
|
||||
private void RetryFailedActions()
|
||||
{
|
||||
_someWorkersFailed = false;
|
||||
panel1.Visible = false;
|
||||
ToggleRetryButton();
|
||||
|
||||
var workers = new List<UpdateProgressBackgroundWorker>(failedWorkers);
|
||||
failedWorkers.Clear();
|
||||
|
||||
foreach (var failedWorker in workers)
|
||||
{
|
||||
failedWorker.RunWorkerAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleRetryButton()
|
||||
{
|
||||
labelRetry.Visible = buttonRetry.Visible = _someWorkersFailed;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void retryButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
RetryFailedActions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,8 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
this.labelError = new System.Windows.Forms.Label();
|
||||
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||
this.panel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.buttonRetry = new System.Windows.Forms.Button();
|
||||
this.labelRetry = new System.Windows.Forms.Label();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||
this.panel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
@ -75,8 +77,24 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
this.panel1.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.panel1.Controls.Add(this.pictureBox1, 0, 0);
|
||||
this.panel1.Controls.Add(this.labelError, 1, 0);
|
||||
this.panel1.Controls.Add(this.buttonRetry, 2, 0);
|
||||
this.panel1.Controls.Add(this.labelRetry, 1, 1);
|
||||
this.panel1.Name = "panel1";
|
||||
//
|
||||
// buttonRetry
|
||||
//
|
||||
resources.ApplyResources(this.buttonRetry, "buttonRetry");
|
||||
this.buttonRetry.Name = "buttonRetry";
|
||||
this.panel1.SetRowSpan(this.buttonRetry, 2);
|
||||
this.buttonRetry.UseVisualStyleBackColor = true;
|
||||
this.buttonRetry.Click += new System.EventHandler(this.retryButton_Click);
|
||||
//
|
||||
// labelRetry
|
||||
//
|
||||
resources.ApplyResources(this.labelRetry, "labelRetry");
|
||||
this.labelRetry.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.labelRetry.Name = "labelRetry";
|
||||
//
|
||||
// PatchingWizard_AutomatedUpdatesPage
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
@ -102,6 +120,8 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
private System.Windows.Forms.Label labelError;
|
||||
private System.Windows.Forms.PictureBox pictureBox1;
|
||||
private System.Windows.Forms.TableLayoutPanel panel1;
|
||||
private System.Windows.Forms.Button buttonRetry;
|
||||
private System.Windows.Forms.Label labelRetry;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +163,7 @@
|
||||
<value>Both</value>
|
||||
</data>
|
||||
<data name="textBoxLog.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>502, 235</value>
|
||||
<value>502, 222</value>
|
||||
</data>
|
||||
<data name="textBoxLog.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
@ -223,7 +223,7 @@
|
||||
<value>25, 4</value>
|
||||
</data>
|
||||
<data name="labelError.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>483, 13</value>
|
||||
<value>426, 13</value>
|
||||
</data>
|
||||
<data name="labelError.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
@ -271,19 +271,79 @@
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="panel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="buttonRetry.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="buttonRetry.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>457, 3</value>
|
||||
</data>
|
||||
<data name="buttonRetry.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>51, 23</value>
|
||||
</data>
|
||||
<data name="buttonRetry.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="buttonRetry.Text" xml:space="preserve">
|
||||
<value>&Retry</value>
|
||||
</data>
|
||||
<data name=">>buttonRetry.Name" xml:space="preserve">
|
||||
<value>buttonRetry</value>
|
||||
</data>
|
||||
<data name=">>buttonRetry.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>buttonRetry.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name=">>buttonRetry.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="labelRetry.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left, Right</value>
|
||||
</data>
|
||||
<data name="labelRetry.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="labelRetry.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="labelRetry.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>25, 25</value>
|
||||
</data>
|
||||
<data name="labelRetry.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>426, 13</value>
|
||||
</data>
|
||||
<data name="labelRetry.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="labelRetry.Text" xml:space="preserve">
|
||||
<value>The update process has been paused. Press Retry to resume the update process.</value>
|
||||
</data>
|
||||
<data name=">>labelRetry.Name" xml:space="preserve">
|
||||
<value>labelRetry</value>
|
||||
</data>
|
||||
<data name=">>labelRetry.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>labelRetry.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name=">>labelRetry.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 313</value>
|
||||
<value>0, 293</value>
|
||||
</data>
|
||||
<data name="panel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>511, 22</value>
|
||||
<value>511, 42</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
@ -301,7 +361,7 @@
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="panel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="pictureBox1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelError" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100,Absolute,20" /><Rows Styles="Percent,100" /></TableLayoutSettings></value>
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="pictureBox1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelError" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonRetry" Row="0" RowSpan="2" Column="2" ColumnSpan="1" /><Control Name="labelRetry" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100,AutoSize,0" /><Rows Styles="Percent,100,Absolute,20" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
|
@ -46,7 +46,7 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
|
||||
private readonly Host host;
|
||||
|
||||
public PatchPrecheckOnHostPlanAction(IXenConnection connection, XenServerPatch patch, Host host, List<PoolPatchMapping> mappings)
|
||||
: base(connection, string.Format(Messages.UPDATES_WIZARD_RUNNING_PRECHECK, patch.Name, connection.Name))
|
||||
: base(connection, string.Format(Messages.UPDATES_WIZARD_RUNNING_PRECHECK, patch.Name, host.Name()))
|
||||
{
|
||||
this.patch = patch;
|
||||
this.host = host;
|
||||
|
@ -43,6 +43,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
private readonly int _actionsCount;
|
||||
public List<HostActionTuple> HostActions { get; private set; }
|
||||
public List<PlanAction> FinalActions { get; private set; }
|
||||
public List<PlanAction> CleanupActions { get; private set; }
|
||||
public readonly List<PlanAction> DoneActions = new List<PlanAction>();
|
||||
public readonly List<PlanAction> InProgressActions = new List<PlanAction>();
|
||||
public string Name { get; set; }
|
||||
@ -51,6 +52,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
{
|
||||
HostActions = planActions;
|
||||
FinalActions = finalActions;
|
||||
CleanupActions = finalActions.Where(a => a is RemoveUpdateFileFromMasterPlanAction).ToList();
|
||||
_actionsCount = HostActions.Sum(t => t.Item2.Count + t.Item3.Count) + FinalActions.Count;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user