Merge pull request #1029 from GaborApatiNagy/master_batch_new2

CP-17699, CA-213232: Batch Updates fixes and improvements
This commit is contained in:
Mihaela Stoica 2016-06-17 15:15:11 +01:00 committed by GitHub
commit 7273f8a886
12 changed files with 184 additions and 53 deletions

View File

@ -104,13 +104,14 @@ namespace XenAdmin.Wizards.PatchingWizard
if (prevPageType == typeof(PatchingWizard_SelectPatchPage))
{
var updateType = PatchingWizard_SelectPatchPage.SelectedUpdateType;
var newPatch = PatchingWizard_SelectPatchPage.SelectedNewPatch;
var existPatch = PatchingWizard_SelectPatchPage.SelectedExistingPatch;
var alertPatch = PatchingWizard_SelectPatchPage.SelectedUpdateAlert;
var fileFromDiskAlertPatch = PatchingWizard_SelectPatchPage.FileFromDiskAlert;
var wizardModeAutomatic = PatchingWizard_SelectPatchPage.IsInAutomaticMode;
var updateType = wizardModeAutomatic ? UpdateType.NewRetail : PatchingWizard_SelectPatchPage.SelectedUpdateType;
var newPatch = wizardModeAutomatic ? null : PatchingWizard_SelectPatchPage.SelectedNewPatch;
var existPatch = wizardModeAutomatic ? null : PatchingWizard_SelectPatchPage.SelectedExistingPatch;
var alertPatch = wizardModeAutomatic ? null : PatchingWizard_SelectPatchPage.SelectedUpdateAlert;
var fileFromDiskAlertPatch = wizardModeAutomatic ? null : PatchingWizard_SelectPatchPage.FileFromDiskAlert;
PatchingWizard_SelectServers.IsInAutomaticMode = wizardModeAutomatic;
PatchingWizard_SelectServers.SelectedUpdateType = updateType;
PatchingWizard_SelectServers.Patch = existPatch;
@ -311,7 +312,20 @@ namespace XenAdmin.Wizards.PatchingWizard
private void RemoveDownloadedPatches()
{
foreach (string downloadedPatch in PatchingWizard_UploadPage.AllDownloadedPatches.Values)
var isInAutomaticMode = PatchingWizard_SelectPatchPage.IsInAutomaticMode;
List<string> listOfDownloadedFiles = new List<string>();
if (isInAutomaticMode)
{
listOfDownloadedFiles.AddRange(PatchingWizard_AutoUpdatingPage.AllDownloadedPatches.Values);
}
else
{
listOfDownloadedFiles.AddRange(PatchingWizard_UploadPage.AllDownloadedPatches.Values);
}
foreach (string downloadedPatch in listOfDownloadedFiles)
{
try
{

View File

@ -55,16 +55,16 @@ namespace XenAdmin.Wizards.PatchingWizard
protected static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public XenAdmin.Core.Updates.UpgradeSequence UpgradeSequences { get; set; }
private bool _thisPageHasBeenCompleted = false;
private bool _thisPageIsCompleted = false;
public List<Problem> ProblemsResolvedPreCheck { private get; set; }
public List<Host> SelectedMasters { private get; set; }
private List<PoolPatchMapping> patchMappings = new List<PoolPatchMapping>();
private Dictionary<XenServerPatch, string> AllDownloadedPatches = new Dictionary<XenServerPatch, string>();
public Dictionary<XenServerPatch, string> AllDownloadedPatches = new Dictionary<XenServerPatch, string>();
private List<BackgroundWorker> backgroundWorkers = new List<BackgroundWorker>();
private List<UpdateProgressBackgroundWorker> backgroundWorkers = new List<UpdateProgressBackgroundWorker>();
public PatchingWizard_AutoUpdatingPage()
{
@ -109,15 +109,28 @@ namespace XenAdmin.Wizards.PatchingWizard
return _cancelEnabled;
}
public override void PageCancelled()
{
if (!_thisPageIsCompleted)
{
backgroundWorkers.ForEach(bgw => bgw.CancelAsync());
backgroundWorkers.Clear();
}
base.PageCancelled();
}
public override void PageLeave(PageLoadedDirection direction, ref bool cancel)
{
base.PageLeave(direction, ref cancel);
}
public override void PageLoaded(PageLoadedDirection direction)
{
base.PageLoaded(direction);
if (_thisPageHasBeenCompleted)
if (_thisPageIsCompleted)
{
backgroundWorkers.ForEach(bgw => bgw.CancelAsync());
backgroundWorkers.Clear();
return;
}
@ -157,9 +170,11 @@ namespace XenAdmin.Wizards.PatchingWizard
foreach (var host in hostsToApply)
{
if (host != master)
{
planActionsByHost[host].Add(new ApplyXenServerPatchPlanAction(host, patch, patchMappings));
planActionsByHost[host].AddRange(GetMandatoryActionListForPatch(delayedActionsByHost[host], host, patch));
UpdateDelayedAfterPatchGuidanceActionListForHost(delayedActionsByHost[host], host, patch);
}
}
// now add all non-delayed actions to the pool action list
@ -202,7 +217,7 @@ namespace XenAdmin.Wizards.PatchingWizard
if (backgroundWorkers.Count == 0)
{
_thisPageHasBeenCompleted = true;
_thisPageIsCompleted = true;
_nextEnabled = true;
OnPageUpdated();
@ -224,16 +239,19 @@ namespace XenAdmin.Wizards.PatchingWizard
if (!actionsWorker.CancellationPending)
{
PlanAction action = (PlanAction)e.UserState;
if (e.ProgressPercentage == 0)
if (action != null)
{
inProgressActions.Add(action);
}
else
{
doneActions.Add(action);
inProgressActions.Remove(action);
if (e.ProgressPercentage == 0)
{
inProgressActions.Add(action);
}
else
{
doneActions.Add(action);
inProgressActions.Remove(action);
progressBar.Value += (int)((float)e.ProgressPercentage / (float)backgroundWorkers.Count); //extend with error handling related numbers
progressBar.Value += (int)((float)e.ProgressPercentage / (float)backgroundWorkers.Count); //extend with error handling related numbers
}
}
UpdateStatusTextBox();
@ -247,8 +265,11 @@ namespace XenAdmin.Wizards.PatchingWizard
foreach (var pa in doneActions)
{
sb.Append(pa);
sb.AppendLine(Messages.DONE);
if (pa.Visible)
{
sb.Append(pa);
sb.AppendLine(Messages.DONE);
}
}
foreach (var pa in errorActions)
@ -259,8 +280,11 @@ namespace XenAdmin.Wizards.PatchingWizard
foreach (var pa in inProgressActions)
{
sb.Append(pa);
sb.AppendLine();
if (pa.Visible)
{
sb.Append(pa);
sb.AppendLine(Messages.DONE);
}
}
textBoxLog.Text = sb.ToString();
@ -325,7 +349,7 @@ namespace XenAdmin.Wizards.PatchingWizard
AllWorkersFinished();
ShowErrors();
_thisPageHasBeenCompleted = true;
_thisPageIsCompleted = true;
}
_cancelEnabled = false;

View File

@ -100,24 +100,33 @@ namespace XenAdmin.Wizards.PatchingWizard
xenConnections.Sort();
foreach (IXenConnection xenConnection in xenConnections)
{
Pool pool = Helpers.GetPool(xenConnection);
bool hasPool = true;
if (pool != null)
if (IsInAutomaticMode)
{
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(pool));
Host master = pool.Connection.Resolve(pool.master);
EnabledRow(master, SelectedUpdateType, index);
if (!xenConnection.IsConnected)
continue;
var host = Helpers.GetMaster(xenConnection);
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(host, false));
EnabledRow(host, SelectedUpdateType, index);
}
else
{
hasPool = false;
}
Host[] hosts = xenConnection.Cache.Hosts;
Array.Sort(hosts);
foreach (Host host in hosts)
{
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(host, hasPool));
EnabledRow(host, SelectedUpdateType, index);
Pool pool = Helpers.GetPool(xenConnection);
bool hasPool = pool != null;
if (hasPool)
{
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(pool));
Host master = pool.Connection.Resolve(pool.master);
EnabledRow(master, SelectedUpdateType, index);
}
Host[] hosts = xenConnection.Cache.Hosts;
Array.Sort(hosts);
foreach (Host host in hosts)
{
int index = dataGridViewHosts.Rows.Add(new PatchingHostsDataGridViewRow(host, hasPool));
EnabledRow(host, SelectedUpdateType, index);
}
}
}

View File

@ -57,10 +57,16 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
protected override void RunWithSession(ref Session session)
{
this.visible = false;
lock (patch)
{
this.visible = true;
this._title = string.Format(Messages.PATCHINGWIZARD_DOWNLOADUPDATE_ACTION_TITLE_DOWNLOADING, patch.Name);
if (Cancelling)
return;
//if it has not been already downloaded
if (!AllDownloadedPatches.Any(dp => dp.Key == patch && !string.IsNullOrEmpty(dp.Value))
|| !File.Exists(AllDownloadedPatches[patch]))
@ -69,6 +75,7 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
}
else
{
this.visible = false;
this._title = string.Format(Messages.PATCHINGWIZARD_DOWNLOADUPDATE_ACTION_TITLE_SKIPPING, patch.Name);
}
}
@ -101,6 +108,9 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
if (action == null)
return;
if (Cancelling)
action.Cancel();
Program.Invoke(Program.MainWindow, () =>
{
//UpdateActionProgress(action);

View File

@ -60,9 +60,13 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
var mapping = mappings.Find(m => m.XenServerPatch == patch);
if (mapping != null && mapping.Pool_patch != null)
{
foreach (var host in hosts)
{
if (Cancelling)
{
throw new CancelledException();
}
try
{
var check = new PatchPrecheckCheck(host, mapping.Pool_patch);

View File

@ -35,6 +35,7 @@ using System.Threading;
using log4net;
using XenAdmin.Network;
using XenAPI;
using System.Diagnostics;
namespace XenAdmin.Wizards.PatchingWizard.PlanActions
@ -48,6 +49,16 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
public event EventHandler OnActionError;
public event Action<PlanAction, Host> StatusChanged;
public Exception Error;
protected bool Cancelling = false;
protected bool visible = true;
public bool Visible
{
get
{
return visible;
}
}
private string status;
public string Status
@ -230,6 +241,11 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
{
return this.Title;
}
public virtual void Cancel()
{
Cancelling = true;
}
}
}

View File

@ -33,6 +33,7 @@ using System.Collections.Generic;
using XenAdmin.Core;
using XenAPI;
using System.Linq;
using System;
namespace XenAdmin.Wizards.PatchingWizard.PlanActions
{
@ -52,14 +53,33 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
protected override void RunWithSession(ref Session session)
{
var mapping = patchMappings.FirstOrDefault(pm => pm.Host == master && pm.XenServerPatch == patch);
if (mapping != null)
try
{
var task = Pool_patch.async_pool_clean(session, mapping.Pool_patch.opaque_ref);
PollTaskForResultAndDestroy(Connection, ref session, task);
Pool_patch poolPatch = null;
patchMappings.Remove(mapping);
var mapping = patchMappings.FirstOrDefault(pm => pm.Host == master && pm.XenServerPatch == patch);
if (mapping != null || mapping.Pool_patch != null && mapping.Pool_patch.opaque_ref != null)
{
poolPatch = mapping.Pool_patch;
}
else
{
poolPatch = session.Connection.Cache.Pool_patches.FirstOrDefault(pp => string.Equals(pp.uuid, patch.Uuid, System.StringComparison.InvariantCultureIgnoreCase));
}
if (poolPatch != null && poolPatch.opaque_ref != null )
{
var task = Pool_patch.async_pool_clean(session, mapping.Pool_patch.opaque_ref);
PollTaskForResultAndDestroy(Connection, ref session, task);
patchMappings.Remove(mapping);
}
}
catch (Exception ex)
{
//best effort
log.Error("Failed to remove Pool_patch from the server.", ex);
}
}
}

View File

@ -47,6 +47,7 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
private readonly List<PoolPatchMapping> mappings;
private Dictionary<XenServerPatch, string> AllDownloadedPatches = new Dictionary<XenServerPatch, string>();
private string tempFileName = null;
private AsyncAction inProgressAction = null;
public UploadPatchToMasterPlanAction(IXenConnection connection, XenServerPatch patch, List<PoolPatchMapping> mappings, Dictionary<XenServerPatch, string> allDownloadedPatches)
: base(connection, string.Format("Uploading update {0} to {1}...", patch.Name, connection.Name))
@ -71,10 +72,12 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
try
{
var checkSpaceForUpload = new CheckDiskSpaceForPatchUploadAction(Helpers.GetMaster(conn), path, true);
inProgressAction = checkSpaceForUpload;
checkSpaceForUpload.RunExternal(session);
var action = new UploadPatchAction(session.Connection, path, true, false);
action.RunExternal(session);
var uploadPatchAction = new UploadPatchAction(session.Connection, path, true, false);
inProgressAction = uploadPatchAction;
uploadPatchAction.RunExternal(session);
var poolPatch = poolPatches.Find(p => string.Equals(p.uuid, patch.Uuid, StringComparison.OrdinalIgnoreCase));
if (poolPatch == null)
@ -126,6 +129,9 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
if (action == null)
return;
if (Cancelling)
action.Cancel();
Program.Invoke(Program.MainWindow, () =>
{
//UpdateActionProgress(action);
@ -154,5 +160,13 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
}
}
public override void Cancel()
{
if (inProgressAction != null)
inProgressAction.Cancel();
base.Cancel();
}
}
}

View File

@ -18,6 +18,7 @@ namespace XenAdmin.Wizards.PatchingWizard
public List<PlanAction> FinsihedActions = new List<PlanAction>();
public PlanAction FailedWithExceptionAction = null;
public List<PlanAction> doneActions = new List<PlanAction>();
public PlanAction InProgressAction { get; set; }
public UpdateProgressBackgroundWorker(Host master, List<PlanAction> planActions, List<PlanAction> delayedActions)
{
@ -49,5 +50,17 @@ namespace XenAdmin.Wizards.PatchingWizard
return (int)(1.0 / (double)TotalNumberOfActions * (double)(FinsihedActions.Count));
}
}
public new void CancelAsync()
{
if (PlanActions != null)
PlanActions.ForEach(pa =>
{
if (!pa.IsComplete)
pa.Cancel();
});
base.CancelAsync();
}
}
}

View File

@ -31,10 +31,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using XenAPI;
namespace XenAdmin.Core
{
[DebuggerDisplay("XenServerPatch (Name={Name}; Uuid={Uuid})")]
public class XenServerPatch : IEquatable<XenServerPatch>
{
private string _uuid;

View File

@ -31,9 +31,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace XenAdmin.Core
{
[DebuggerDisplay("XenServerVersion (Name={Name}; Patches.Count={Patches.Count}; MinimalPatches.Count={MinimalPatches.Count})")]
public class XenServerVersion
{
public Version Version;

View File

@ -1410,6 +1410,9 @@ namespace XenAdmin.Core
/// </summary>
public static string OEMName(Host host)
{
if (host.software_version == null)
return string.Empty;
if (!host.software_version.ContainsKey("oem_manufacturer"))
return "";