public PoolPatchMapping(XenServerPatch xenServerPatch, Pool_update pool_update, Host masterHost) { if (xenServerPatch == null) throw new ArgumentNullException("xenServerPatch"); if (pool_update == null) throw new ArgumentNullException("pool_update"); if (masterHost == null) throw new ArgumentNullException("masterHost"); this.XenServerPatch = xenServerPatch; this.Pool_update = pool_update; this.MasterHost = masterHost; }
private void ApplyUpdate(Host host, Pool_update update) { // Set the correct connection object, for RecomputeCanCancel Connection = host.Connection; Session session = host.Connection.DuplicateSession(); try { this.Description = String.Format(Messages.APPLYING_PATCH, update.Name, host.Name); output += String.Format(Messages.APPLY_PATCH_LOG_MESSAGE, update.Name, host.Name); var poolUpdates = new List <Pool_update>(session.Connection.Cache.Pool_updates); var poolUpdate = poolUpdates.FirstOrDefault(u => u != null && string.Equals(u.uuid, update.uuid, StringComparison.OrdinalIgnoreCase)); if (poolUpdate == null) { throw new Exception("Pool_update not found"); } if (!poolUpdate.AppliedOn(host)) { Pool_update.apply(session, poolUpdate.opaque_ref, host.opaque_ref); this.Description = String.Format(Messages.PATCH_APPLIED, update.Name, host.Name); } else { this.Description = String.Format(Messages.PATCH_APPLIED, update.Name, host.Name); } } catch (Failure f) { if (f.ErrorDescription.Count > 1 && f.ErrorDescription[0] == XenAPI.Failure.PATCH_APPLY_FAILED) { output += Messages.APPLY_PATCH_FAILED_LOG_MESSAGE; output += f.ErrorDescription[1]; } log.Error(output, f); throw; } finally { Connection = null; } }
protected virtual List <KeyValuePair <string, List <Check> > > GenerateChecks(Pool_update update) { List <KeyValuePair <string, List <Check> > > checks = GenerateCommonChecks(); List <Check> checkGroup; //Checking other things if (update != null) { checks.Add(new KeyValuePair <string, List <Check> >(Messages.CHECKING_SERVER_SIDE_STATUS, new List <Check>())); checkGroup = checks[checks.Count - 1].Value; foreach (Host host in SelectedServers) { 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)); checkGroup.Add(new PatchPrecheckCheck(host, poolUpdateFromHost, LivePatchCodesByHost)); } } //Checking if the host needs a reboot if (!IsInAutomatedUpdatesMode) { checks.Add(new KeyValuePair <string, List <Check> >(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List <Check>())); checkGroup = checks[checks.Count - 1].Value; var guidance = update != null ? update.after_apply_guidance : new List <update_after_apply_guidance> { update_after_apply_guidance.restartHost }; foreach (var host in SelectedServers) { checkGroup.Add(new HostNeedsRebootCheck(host, guidance, LivePatchCodesByHost)); } } //Checking can evacuate host if (update == null || update.after_apply_guidance.Contains(update_after_apply_guidance.restartHost)) { checks.Add(new KeyValuePair <string, List <Check> >(Messages.CHECKING_CANEVACUATE_STATUS, new List <Check>())); checkGroup = checks[checks.Count - 1].Value; foreach (Host host in SelectedServers) { checkGroup.Add(new AssertCanEvacuateCheck(host, LivePatchCodesByHost)); } } return(checks); }
private void UploadAndApplyUpdate(Host host, Session session) { var update = host.Connection.Cache.Find_By_Uuid <Pool_update>(UUID); if (update == null) { var master = Helpers.GetMaster(host.Connection); var filePath = Path.Combine(Program.AssemblyDir, String.Format("{0}.{1}", Filename, Branding.UpdateIso)); var action = new Actions.UploadSupplementalPackAction(master.Connection, new List <Host>() { master }, filePath, true); action.RunExternal(session); update = action.PoolUpdate; } Pool_update.apply(session, update.opaque_ref, host.opaque_ref); }
private void PrecheckSuppPack(Pool_update update, string suppPack, out bool alreadyApplied, out bool updateRequiresHostEvacuation) { alreadyApplied = false; if (Cancelling) { throw new CancelledException(); } var livePatchStatus = new Dictionary <string, livepatch_status>(); try { AddProgressStep(string.Format(Messages.UPDATES_WIZARD_RUNNING_PRECHECK, suppPack, host.Name())); PatchPrecheckCheck check = new PatchPrecheckCheck(host, update, livePatchStatus); var problems = check.RunAllChecks(); updateRequiresHostEvacuation = WizardHelpers.IsHostRebootRequiredForUpdate(host, update, livePatchStatus); if (problems != null && problems.Count > 0) { if (problems[0] is PatchAlreadyApplied) { log.InfoFormat("The update {0} is already applied on {1}. Ignore it.", suppPack, host.Name()); ReplaceProgressStep(string.Format(Messages.UPDATES_WIZARD_SKIPPING_UPDATE, suppPack, host.Name())); alreadyApplied = true; } else { throw new Exception(problems[0].Description); } } } catch (Exception ex) { log.Error(string.Format("Precheck failed on host {0}", host.Name()), ex); throw; } if (livePatchStatus.ContainsKey(host.uuid) && livePatchStatus[host.uuid] != livepatch_status.ok_livepatch_complete && !hostsThatWillRequireReboot.Contains(host.uuid)) { hostsThatWillRequireReboot.Add(host.uuid); } }
private static AsyncAction GetCleanUpPoolUpdateAction(Pool_update poolUpdate) { return (new DelegatedAsyncAction(poolUpdate.Connection, Messages.REMOVE_PATCH, "", "", session => { try { Pool_update.pool_clean(session, poolUpdate.opaque_ref); if (!poolUpdate.AppliedOnHosts().Any()) { Pool_update.destroy(session, poolUpdate.opaque_ref); } } catch (Failure f) { log.Error("Clean up failed", f); } })); }
public static void RefreshUpdate(Host host, HostUpdateMapping mapping, Session session) { // re-introduce pool_update if needed if (mapping is PoolUpdateMapping poolUpdateMapping && session.Connection.Cache.Pool_updates.FirstOrDefault(u => string.Equals(u.uuid, poolUpdateMapping.Pool_update.uuid, StringComparison.OrdinalIgnoreCase)) == null) { log.InfoFormat("Re-introduce update on '{0}'. Update = '{1}' (uuid = '{2}'; old opaque_ref = '{3}')", host.Name(), poolUpdateMapping.Pool_update.Name(), poolUpdateMapping.Pool_update.uuid, poolUpdateMapping.Pool_update.opaque_ref); try { var newUpdateRef = Pool_update.introduce(session, poolUpdateMapping.Pool_update.vdi.opaque_ref); session.Connection.WaitForCache(newUpdateRef); } catch (Exception e) { if (e is Failure failure && failure.ErrorDescription != null && failure.ErrorDescription.Count > 1 && failure.ErrorDescription[0] == Failure.UPDATE_ALREADY_EXISTS) { log.InfoFormat("Update '{0}' already exists", poolUpdateMapping.Pool_update.Name()); }
protected override void RunWithSession(ref Session session) { var mapping = mappings.Find(m => m.XenServerPatch.Equals(xenServerPatch) && m.MasterHost != null && m.MasterHost.uuid == masterUuid); if (mapping != null && (mapping.Pool_patch != null || mapping.Pool_update != null)) { try { AddProgressStep(string.Format(Messages.UPDATES_WIZARD_APPLYING_UPDATE, xenServerPatch.Name, host.Name())); var task = mapping.Pool_patch == null ? Pool_update.async_apply(session, mapping.Pool_update.opaque_ref, host.opaque_ref) : Pool_patch.async_apply(session, mapping.Pool_patch.opaque_ref, host.opaque_ref); PollTaskForResultAndDestroy(Connection, ref session, task); } catch (Failure f) { if (f.ErrorDescription.Count > 1 && (f.ErrorDescription[0] == Failure.PATCH_ALREADY_APPLIED || f.ErrorDescription[0] == Failure.UPDATE_ALREADY_APPLIED)) { log.InfoFormat("The update {0} is already applied on {1}. Ignoring this error.", xenServerPatch.Name, host.Name()); ReplaceProgressStep(string.Format(Messages.UPDATES_WIZARD_SKIPPING_UPDATE, xenServerPatch.Name, host.Name())); } else { throw; } } } else { if (xenServerPatch != null) { log.ErrorFormat("Mapping not found for patch {0} on master {1}", xenServerPatch.Uuid, masterUuid); } throw new Exception("Pool_patch or Pool_update not found."); } }
public PoolPatchMapping(XenServerPatch xenServerPatch, Pool_update pool_update, Host masterHost) { if (xenServerPatch == null) { throw new ArgumentNullException("xenServerPatch"); } if (pool_update == null) { throw new ArgumentNullException("pool_update"); } if (masterHost == null) { throw new ArgumentNullException("masterHost"); } this.XenServerPatch = xenServerPatch; this.Pool_update = pool_update; this.MasterHost = masterHost; }
private void ApplyUpdate() { try { this.Description = String.Format(Messages.APPLYING_PATCH, update.Name(), host.Name()); output += String.Format(Messages.APPLY_PATCH_LOG_MESSAGE, update.Name(), host.Name()); var poolUpdates = new List <Pool_update>(Connection.Cache.Pool_updates); var poolUpdate = poolUpdates.FirstOrDefault(u => u != null && string.Equals(u.uuid, update.uuid, StringComparison.OrdinalIgnoreCase)); if (poolUpdate == null) { throw new Failure(Failure.INTERNAL_ERROR, Messages.POOL_UPDATE_GONE); } if (!poolUpdate.AppliedOn(host)) { Pool_update.apply(Session, poolUpdate.opaque_ref, host.opaque_ref); this.Description = String.Format(Messages.PATCH_APPLIED, update.Name(), host.Name()); } else { this.Description = String.Format(Messages.PATCH_APPLIED, update.Name(), host.Name()); } } catch (Failure f) { if (f.ErrorDescription.Count > 1 && f.ErrorDescription[0] == XenAPI.Failure.PATCH_APPLY_FAILED) { output += Messages.APPLY_PATCH_FAILED_LOG_MESSAGE; output += f.ErrorDescription[1]; } log.Error(output, f); throw; } }
private void ApplySuppPack(IXenConnection connection, Session session, string suppPack, Pool_update update) { try { AddProgressStep(string.Format(Messages.UPDATES_WIZARD_APPLYING_UPDATE, suppPack, host.Name())); var task = Pool_update.async_apply(session, update.opaque_ref, host.opaque_ref); PollTaskForResultAndDestroy(connection, ref session, task); } catch (Failure f) { if (f.ErrorDescription.Count > 1 && f.ErrorDescription[0] == Failure.UPDATE_ALREADY_APPLIED) { log.InfoFormat("The update {0} is already applied on {1}. Ignoring this error.", suppPack, host.Name()); ReplaceProgressStep(string.Format(Messages.UPDATES_WIZARD_SKIPPING_UPDATE, suppPack, host.Name())); } else { throw; } } }
protected override void Run() { SafeToExit = false; if (update.AppliedOn(host)) { return; } Description = string.Format(Messages.APPLYING_PATCH, update.Name(), host.Name()); log.DebugFormat("Applying update '{0}' to server '{1}'...", update.Name(), host.Name()); var poolUpdates = new List <Pool_update>(Connection.Cache.Pool_updates); var poolUpdate = poolUpdates.FirstOrDefault(u => u != null && string.Equals(u.uuid, update.uuid, StringComparison.OrdinalIgnoreCase)); if (poolUpdate == null) { throw new Failure(Failure.INTERNAL_ERROR, Messages.POOL_UPDATE_GONE); } if (poolUpdate.AppliedOn(host)) { Description = string.Format(Messages.PATCH_APPLIED_ALREADY, update.Name(), host.Name()); return; } try { RelatedTask = Pool_update.async_apply(Session, poolUpdate.opaque_ref, host.opaque_ref); PollToCompletion(); Description = string.Format(Messages.PATCH_APPLIED, update.Name(), host.Name()); } catch (Failure f) { log.ErrorFormat("Failed to apply update '{0}' on server '{1}': '{2}'", update.Name(), host.Name(), string.Join(", ", f.ErrorDescription)); //CA-339237 throw; } }
private List <PlanAction> CompilePoolUpdateActionList(Host host, Pool_update poolUpdate) { List <PlanAction> actions = new List <PlanAction>(); if (SelectedUpdateType != UpdateType.ISO || poolUpdate == null) { return(actions); } List <XenRef <VM> > runningVMs = RunningVMs(host); actions.Add(new ApplyPoolUpdatePlanAction(host, poolUpdate)); if (poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartHost) && !(LivePatchCodesByHost != null && LivePatchCodesByHost.ContainsKey(host.uuid) && LivePatchCodesByHost[host.uuid] == livepatch_status.ok_livepatch_complete)) { actions.Add(new EvacuateHostPlanAction(host)); actions.Add(new RebootHostPlanAction(host)); actions.Add(new BringBabiesBackAction(runningVMs, host, false)); } if (poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartXAPI)) { actions.Add(new RestartAgentPlanAction(host)); } if (poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartHVM)) { actions.Add(new RebootVMsPlanAction(host, RunningHvmVMs(host))); } if (poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartPV)) { actions.Add(new RebootVMsPlanAction(host, RunningPvVMs(host))); } return(actions); }
private AsyncAction GetCleanActionForPoolUpdate(Pool_update update) { if (update == null || update.Connection == null || !update.Connection.IsConnected) { return(null); } return(new DelegatedAsyncAction(update.Connection, Messages.REMOVE_PATCH, "", "", session => { try { Pool_update.pool_clean(session, update.opaque_ref); if (!update.AppliedOnHosts().Any()) { Pool_update.destroy(session, update.opaque_ref); } } catch (Failure f) { log.Error("Clean up failed", f); } })); }
private void RemoveSuppPackFromMaster(Session session, Host master, string suppPack, Pool_update update) { var isLastHostInPool = hosts.IndexOf(host) == hosts.Count - 1; if (isLastHostInPool) { try { AddProgressStep(string.Format(Messages.UPDATES_WIZARD_REMOVING_UPDATES_FROM_POOL, suppPack)); Pool_update.pool_clean(session, update.opaque_ref); if (!update.AppliedOnHosts().Any()) { Pool_update.destroy(session, update.opaque_ref); } uploadedSuppPacks.Remove(master); } catch (Exception ex) { log.Error(string.Format("Remove update file from master failed on host {0}", master.Name()), ex); } } }
private void ApplyUpdate(Host host, Pool_update update) { // Set the correct connection object, for RecomputeCanCancel Connection = host.Connection; Session session = host.Connection.DuplicateSession(); try { this.Description = String.Format(Messages.APPLYING_PATCH, update.Name, host.Name); output += String.Format(Messages.APPLY_PATCH_LOG_MESSAGE, update.Name, host.Name); var poolUpdates = new List<Pool_update>(session.Connection.Cache.Pool_updates); var poolUpdate = poolUpdates.FirstOrDefault(u => u != null && string.Equals(u.uuid, update.uuid, StringComparison.OrdinalIgnoreCase)); if (poolUpdate == null) throw new Exception("Pool_update not found"); if (!poolUpdate.AppliedOn(host)) { Pool_update.apply(session, poolUpdate.opaque_ref, host.opaque_ref); this.Description = String.Format(Messages.PATCH_APPLIED, update.Name, host.Name); } else { this.Description = String.Format(Messages.PATCH_APPLIED, update.Name, host.Name); } } catch (Failure f) { if (f.ErrorDescription.Count > 1 && f.ErrorDescription[0] == XenAPI.Failure.PATCH_APPLY_FAILED) { output += Messages.APPLY_PATCH_FAILED_LOG_MESSAGE; output += f.ErrorDescription[1]; } log.Error(output, f); throw; } finally { Connection = null; } }
public ApplyPoolUpdatePlanAction(Host host, Pool_update patch) : base(host.Connection, string.Format(Messages.UPDATES_WIZARD_APPLYING_UPDATE, patch.Name, host.Name)) { this.host = host; this.poolUpdate = patch; }
private void singleAction_Completed(ActionBase sender) { var action = sender as AsyncAction; if (action == null) return; action.Changed -= singleAction_Changed; action.Completed -= singleAction_Completed; Program.Invoke(this, () => { if (action.Succeeded) { Host master = Helpers.GetMaster(action.Connection); if (action is UploadPatchAction) { _patch = (action as UploadPatchAction).PatchRefs[master]; _poolUpdate = null; AddToUploadedUpdates(SelectedNewPatchPath, master); } if (action is CopyPatchFromHostToOther && action.Host != null) { _poolUpdate = null; _patch = action.Host.Connection.Cache.Resolve((action as CopyPatchFromHostToOther).NewPatchRef); } if (_patch != null && !NewUploadedPatches.ContainsKey(_patch)) { NewUploadedPatches.Add(_patch, SelectedNewPatchPath); _poolUpdate = null; } if (action is UploadSupplementalPackAction) { _patch = null; foreach (var vdiRef in (action as UploadSupplementalPackAction).VdiRefsToCleanUp) { SuppPackVdis[vdiRef.Key] = action.Connection.Resolve(vdiRef.Value); } AllCreatedSuppPackVdis.AddRange(SuppPackVdis.Values.Where(vdi => !AllCreatedSuppPackVdis.Contains(vdi))); AddToUploadedUpdates(SelectedNewPatchPath, master); if (Helpers.ElyOrGreater(action.Connection)) { var newPoolUpdate = ((UploadSupplementalPackAction)action).PoolUpdate; if (newPoolUpdate != null) { _poolUpdate = newPoolUpdate; AllIntroducedPoolUpdates.Add(PoolUpdate); } } } if (action is DownloadAndUnzipXenServerPatchAction) { SelectedNewPatchPath = ((DownloadAndUnzipXenServerPatchAction)action).PatchPath; if (SelectedUpdateAlert is XenServerPatchAlert && (SelectedUpdateAlert as XenServerPatchAlert).Patch != null) { AllDownloadedPatches.Add((SelectedUpdateAlert as XenServerPatchAlert).Patch.Uuid, SelectedNewPatchPath); } _patch = null; PrepareUploadActions(); TryUploading(); } } else // if !action.Succeeded { if (action is UploadSupplementalPackAction) { _patch = null; _poolUpdate = null; foreach (var vdiRef in (action as UploadSupplementalPackAction).VdiRefsToCleanUp) { SuppPackVdis[vdiRef.Key] = action.Connection.Resolve(vdiRef.Value); } AllCreatedSuppPackVdis.AddRange(SuppPackVdis.Values.Where(vdi => !AllCreatedSuppPackVdis.Contains(vdi))); } } }); }
private void PrepareUploadActions() { OnPageUpdated(); SuppPackVdis.Clear(); uploadActions.Clear(); //Upload the patches to the masters if it is necessary List<Host> masters = SelectedMasters; foreach (Host selectedServer in masters) { AsyncAction action = null; switch (SelectedUpdateType) { case UpdateType.NewRetail: if (CanUploadUpdateOnHost(SelectedNewPatchPath, selectedServer)) { bool deleteFileOnCancel = AllDownloadedPatches.ContainsValue(SelectedNewPatchPath); action = new UploadPatchAction(selectedServer.Connection, SelectedNewPatchPath, true, deleteFileOnCancel); } break; case UpdateType.Existing: if (!PatchExistsOnPool(_patch, selectedServer)) { //Download patch from server Upload in the selected server action = new CopyPatchFromHostToOther(SelectedExistingPatch.Connection, selectedServer, SelectedExistingPatch); } break; case UpdateType.ISO: if (CanUploadUpdateOnHost(SelectedNewPatchPath, selectedServer)) { _poolUpdate = null; _patch = null; action = new UploadSupplementalPackAction( selectedServer.Connection, SelectedServers.Where(s => s.Connection == selectedServer.Connection).ToList(), SelectedNewPatchPath, true); } break; } if (action != null) { action.Changed += singleAction_Changed; action.Completed += singleAction_Completed; } else { _patch = GetPatchFromPatchPath(); } uploadActions.Add(selectedServer, action); } foreach (KeyValuePair<Host, AsyncAction> uploadAction in uploadActions) { flickerFreeListBox1.Items.Add(uploadAction); } flickerFreeListBox1.Refresh(); OnPageUpdated(); }
public ApplyPoolUpdatePlanAction(Host host, Pool_update patch) : base(host.Connection) { _host = host; _poolUpdate = patch; }
private static AsyncAction GetCleanUpPoolUpdateAction(Pool_update poolUpdate) { return new DelegatedAsyncAction(poolUpdate.Connection, Messages.REMOVE_PATCH, "", "", session => { try { Pool_update.pool_clean(session, poolUpdate.opaque_ref); if(!poolUpdate.AppliedOnHosts.Any()) Pool_update.destroy(session, poolUpdate.opaque_ref); } catch (Failure f) { log.Error("Clean up failed", f); } }); }
public HostOutOfSpaceProblem(Check check, Host host, Pool_update update, DiskSpaceRequirements diskSpaceReq) : base(check, host) { this.update = update; this.diskSpaceReq = diskSpaceReq; }
public PatchPrecheckCheck(Host host, Pool_update update, Dictionary <string, livepatch_status> livePatchCodesByHost) : base(host) { _update = update; this.livePatchCodesByHost = livePatchCodesByHost; }
public SuppPackMapping(string path, Pool_update pool_update, Host masterHost) : base(masterHost) { Path = !string.IsNullOrEmpty(path) ? path : throw new ArgumentNullException("path"); Pool_update = pool_update; }
public PoolUpdateMapping(XenServerPatch xenServerPatch, Pool_update pool_update, Host masterHost) : base(xenServerPatch, masterHost) { Pool_update = pool_update ?? throw new ArgumentNullException("pool_update"); }
private void worker_DoWork(object sender, DoWorkEventArgs e) { var bgw = sender as BackgroundWorker; if (bgw == null) { return; } lock (_lock) { bgw.ReportProgress(0, null); Program.Invoke(this, () => { dataGridView1.Rows.Clear(); labelProgress.Text = Messages.PATCHING_WIZARD_RUNNING_PRECHECKS; OnPageUpdated(); }); Pool_patch patch = e.Argument as Pool_patch; Pool_update update = e.Argument as Pool_update; LivePatchCodesByHost = new Dictionary <string, livepatch_status>(); // Note: represent the groups as list so as to enforce the order of checks; // a dictionary that looks sensible from a first look is not guranteed to // keep the order, especially if items are removed (although not the case here) var groups = update != null?GenerateChecks(update) : GenerateChecks(patch); //patch is expected to be null for RPU int totalChecks = groups.Sum(c => c.Value == null ? 0 : c.Value.Count); int doneCheckIndex = 0; allRows.Clear(); foreach (var group in groups) { if (bgw.CancellationPending) { e.Cancel = true; return; } var headerRow = new PreCheckHeaderRow(string.Format(Messages.PATCHING_WIZARD_PRECHECK_STATUS, group.Key)); //multiply with 100 first, otherwise the quotient is 0 bgw.ReportProgress(doneCheckIndex * 100 / totalChecks, headerRow); PreCheckResult precheckResult = PreCheckResult.OK; var checks = group.Value; foreach (var check in checks) { if (bgw.CancellationPending) { e.Cancel = true; return; } var rows = ExecuteCheck(check); doneCheckIndex++; foreach (PreCheckHostRow row in rows) { if (precheckResult != PreCheckResult.Failed && row.Problem != null) { precheckResult = row.PrecheckResult; } //multiply with 100 first, otherwise the quotient is 0 bgw.ReportProgress(doneCheckIndex * 100 / totalChecks, row); } } lock (_update_grid_lock) { headerRow.UpdateDescription(precheckResult); } } } }
private void singleAction_Completed(ActionBase sender) { var action = sender as AsyncAction; if (action == null) { return; } action.Changed -= singleAction_Changed; action.Completed -= singleAction_Completed; Program.Invoke(this, () => { if (action.Succeeded) { Host master = Helpers.GetMaster(action.Connection); if (action is UploadPatchAction) { _patch = (action as UploadPatchAction).PatchRefs[master]; _poolUpdate = null; AddToUploadedUpdates(SelectedNewPatchPath, master); } if (action is CopyPatchFromHostToOther && action.Host != null) { _poolUpdate = null; _patch = action.Host.Connection.Cache.Resolve((action as CopyPatchFromHostToOther).NewPatchRef); } if (_patch != null && !NewUploadedPatches.ContainsKey(_patch)) { NewUploadedPatches.Add(_patch, SelectedNewPatchPath); _poolUpdate = null; } if (action is UploadSupplementalPackAction) { _patch = null; foreach (var vdiRef in (action as UploadSupplementalPackAction).VdiRefsToCleanUp) { SuppPackVdis[vdiRef.Key] = action.Connection.Resolve(vdiRef.Value); } AllCreatedSuppPackVdis.AddRange(SuppPackVdis.Values.Where(vdi => !AllCreatedSuppPackVdis.Contains(vdi))); AddToUploadedUpdates(SelectedNewPatchPath, master); if (Helpers.ElyOrGreater(action.Connection)) { var newPoolUpdate = ((UploadSupplementalPackAction)action).PoolUpdate; if (newPoolUpdate != null) { _poolUpdate = newPoolUpdate; AllIntroducedPoolUpdates.Add(PoolUpdate, SelectedNewPatchPath); } } } if (action is DownloadAndUnzipXenServerPatchAction) { SelectedNewPatchPath = ((DownloadAndUnzipXenServerPatchAction)action).PatchPath; if (SelectedUpdateAlert is XenServerPatchAlert && (SelectedUpdateAlert as XenServerPatchAlert).Patch != null) { AllDownloadedPatches.Add((SelectedUpdateAlert as XenServerPatchAlert).Patch.Uuid, SelectedNewPatchPath); } _patch = null; PrepareUploadActions(); TryUploading(); } } else // if !action.Succeeded { if (action is UploadSupplementalPackAction) { _patch = null; _poolUpdate = null; foreach (var vdiRef in (action as UploadSupplementalPackAction).VdiRefsToCleanUp) { SuppPackVdis[vdiRef.Key] = action.Connection.Resolve(vdiRef.Value); } AllCreatedSuppPackVdis.AddRange(SuppPackVdis.Values.Where(vdi => !AllCreatedSuppPackVdis.Contains(vdi))); } } }); }
private KeyValuePair<string, string> CreateWarningRow(Host host, Pool_update update) { var key = String.Format(Messages.GENERAL_PANEL_UPDATE_KEY, update.Name, host.Name); var value = string.Format(Messages.GENERAL_PANEL_UPDATE_REBOOT_WARNING, host.Name, update.Name); return new KeyValuePair<string, string>(key, value); }
public ApplyUpdateAction(Pool_update update, Host host) : base(host.Connection, string.Format(Messages.UPDATES_WIZARD_APPLYING_UPDATE, update.Name(), host.Name())) { this.update = update; this.host = host; }
private void PrepareUploadActions() { OnPageUpdated(); SuppPackVdis.Clear(); uploadActions.Clear(); //Upload the patches to the masters if it is necessary List <Host> masters = SelectedMasters; foreach (Host selectedServer in masters) { AsyncAction action = null; switch (SelectedUpdateType) { case UpdateType.NewRetail: if (CanUploadUpdateOnHost(SelectedNewPatchPath, selectedServer)) { bool deleteFileOnCancel = AllDownloadedPatches.ContainsValue(SelectedNewPatchPath); action = new UploadPatchAction(selectedServer.Connection, SelectedNewPatchPath, true, deleteFileOnCancel); } break; case UpdateType.Existing: if (!PatchExistsOnPool(_patch, selectedServer)) { //Download patch from server Upload in the selected server action = new CopyPatchFromHostToOther(SelectedExistingPatch.Connection, selectedServer, SelectedExistingPatch); } break; case UpdateType.ISO: if (CanUploadUpdateOnHost(SelectedNewPatchPath, selectedServer)) { _poolUpdate = null; _patch = null; action = new UploadSupplementalPackAction( selectedServer.Connection, SelectedServers.Where(s => s.Connection == selectedServer.Connection).ToList(), SelectedNewPatchPath, true); } break; } if (action != null) { action.Changed += singleAction_Changed; action.Completed += singleAction_Completed; } else { _poolUpdate = GetUpdateFromUpdatePath(); _patch = GetPatchFromPatchPath(); } uploadActions.Add(selectedServer, action); } foreach (KeyValuePair <Host, AsyncAction> uploadAction in uploadActions) { flickerFreeListBox1.Items.Add(uploadAction); } flickerFreeListBox1.Refresh(); OnPageUpdated(); }
private string UploadSupplementalPack(SR sr) { this.Description = String.Format(Messages.SUPP_PACK_UPLOADING_TO, sr.Name); String result; log.DebugFormat("Creating vdi of size {0} bytes on SR '{1}'", diskSize, sr.Name); VDI vdi = NewVDI(sr); XenRef<VDI> vdiRef = null; try { vdiRef = VDI.create(Session, vdi); } catch (Exception ex) { log.ErrorFormat("{0} {1}", "Failed to create VDI", ex.Message); throw; } log.DebugFormat("Uploading file '{0}' to VDI '{1}' on SR '{2}'", suppPackFilePath, vdi.Name, sr.Name); Host localStorageHost = sr.GetStorageHost(); string hostUrl; if (localStorageHost == null) { Uri uri = new Uri(Session.Url); hostUrl = uri.Host; } else { log.DebugFormat("SR is not shared -- redirecting to {0}", localStorageHost.address); hostUrl = localStorageHost.address; } log.DebugFormat("Using {0} for import", hostUrl); try { HTTP.UpdateProgressDelegate progressDelegate = delegate(int percent) { var actionPercent = (int)(((totalUploaded * 100) + percent) / totalCount); Tick(actionPercent, Description); }; Session session = NewSession(); RelatedTask = Task.create(Session, "uploadTask", hostUrl); result = HTTPHelper.Put(progressDelegate, GetCancelling, true, Connection, RelatedTask, ref session, suppPackFilePath, hostUrl, (HTTP_actions.put_sss)HTTP_actions.put_import_raw_vdi, session.uuid, vdiRef.opaque_ref); } catch (Exception ex) { log.ErrorFormat("{0} {1}", "Failed to import a virtual disk over HTTP.", ex.Message); if (vdiRef != null) RemoveVDI(Session, vdiRef); throw; } finally { Task.destroy(Session, RelatedTask); RelatedTask = null; } if (localStorageHost != null) VdiRefsToCleanUp.Add(localStorageHost, vdiRef); else // shared SR foreach (var server in servers) VdiRefsToCleanUp.Add(server, vdiRef); //introduce ISO for Ely and higher if (Helpers.ElyOrGreater(Connection)) { try { var poolUpdateRef = Pool_update.introduce(Connection.Session, vdiRef); poolUpdate = Connection.WaitForCache(poolUpdateRef); if (poolUpdate == null) throw new Exception(Messages.UPDATE_ERROR_INTRODUCE); // This should not happen, because such case will result in a XAPI Failure. But this code has to be protected at this point. VdiRefsToCleanUp.Clear(); } catch (Failure ex) { if (ex.ErrorDescription != null && ex.ErrorDescription.Count > 1 && string.Equals("UPDATE_ALREADY_EXISTS", ex.ErrorDescription[0], StringComparison.InvariantCultureIgnoreCase)) { string uuidFound = ex.ErrorDescription[1]; poolUpdate = Connection.Cache.Pool_updates.FirstOrDefault(pu => string.Equals(pu.uuid, uuidFound, System.StringComparison.InvariantCultureIgnoreCase)); //clean-up the VDI we've just created try { RemoveVDI(Session, vdiRef); //remove the vdi that have just been cleaned up var remaining = VdiRefsToCleanUp.Where(kvp => kvp.Value != null && kvp.Value.opaque_ref != vdiRef.opaque_ref).ToList(); VdiRefsToCleanUp.Clear(); remaining.ForEach(rem => VdiRefsToCleanUp.Add(rem.Key, rem.Value)); } catch { //best effort cleanup } } else { throw; } } catch (Exception ex) { log.ErrorFormat("Upload failed when introducing update from VDI {0} on {1}: {2}", vdi.opaque_ref, Connection, ex.Message); poolUpdate = null; throw; } } else { poolUpdate = null; } totalUploaded++; Description = String.Format(Messages.SUPP_PACK_UPLOADED, sr.Name); return result; }
private string UploadSupplementalPack(SR sr) { this.Description = String.Format(Messages.SUPP_PACK_UPLOADING_TO, sr.Name()); String result; log.DebugFormat("Creating vdi of size {0} bytes on SR '{1}'", diskSize, sr.Name()); VDI vdi = NewVDI(sr); XenRef <VDI> vdiRef = null; try { vdiRef = VDI.create(Session, vdi); } catch (Exception ex) { log.ErrorFormat("{0} {1}", "Failed to create VDI", ex.Message); throw; } log.DebugFormat("Uploading file '{0}' to VDI '{1}' on SR '{2}'", suppPackFilePath, vdi.Name(), sr.Name()); Host localStorageHost = sr.GetStorageHost(); string hostUrl; if (localStorageHost == null) { Uri uri = new Uri(Session.Url); hostUrl = uri.Host; } else { log.DebugFormat("SR is not shared -- redirecting to {0}", localStorageHost.address); hostUrl = localStorageHost.address; } log.DebugFormat("Using {0} for import", hostUrl); try { HTTP.UpdateProgressDelegate progressDelegate = delegate(int percent) { var actionPercent = (int)(((totalUploaded * 100) + percent) / totalCount); Tick(actionPercent, Description); }; Session session = NewSession(); RelatedTask = Task.create(Session, "uploadTask", hostUrl); result = HTTPHelper.Put(progressDelegate, GetCancelling, true, Connection, RelatedTask, ref session, suppPackFilePath, hostUrl, (HTTP_actions.put_sss)HTTP_actions.put_import_raw_vdi, session.opaque_ref, vdiRef.opaque_ref); } catch (Exception ex) { log.ErrorFormat("{0} {1}", "Failed to import a virtual disk over HTTP.", ex.Message); if (vdiRef != null) { log.DebugFormat("Removing the VDI on a best effort basis."); try { RemoveVDI(Session, vdiRef); } catch (Exception removeEx) { //best effort log.Error("Failed to remove the VDI.", removeEx); } } //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 { throw ex; } } finally { Task.destroy(Session, RelatedTask); RelatedTask = null; } if (localStorageHost != null) { VdiRefsToCleanUp.Add(localStorageHost, vdiRef); } else // shared SR { foreach (var server in servers) { VdiRefsToCleanUp.Add(server, vdiRef); } } //introduce ISO for Ely and higher if (Helpers.ElyOrGreater(Connection)) { try { var poolUpdateRef = Pool_update.introduce(Connection.Session, vdiRef); poolUpdate = Connection.WaitForCache(poolUpdateRef); if (poolUpdate == null) { throw new Exception(Messages.UPDATE_ERROR_INTRODUCE); // This should not happen, because such case will result in a XAPI Failure. But this code has to be protected at this point. } VdiRefsToCleanUp.Clear(); } catch (Failure ex) { if (ex.ErrorDescription != null && ex.ErrorDescription.Count > 1 && string.Equals("UPDATE_ALREADY_EXISTS", ex.ErrorDescription[0], StringComparison.InvariantCultureIgnoreCase)) { string uuidFound = ex.ErrorDescription[1]; poolUpdate = Connection.Cache.Pool_updates.FirstOrDefault(pu => string.Equals(pu.uuid, uuidFound, System.StringComparison.InvariantCultureIgnoreCase)); //clean-up the VDI we've just created try { RemoveVDI(Session, vdiRef); //remove the vdi that have just been cleaned up var remaining = VdiRefsToCleanUp.Where(kvp => kvp.Value != null && kvp.Value.opaque_ref != vdiRef.opaque_ref).ToList(); VdiRefsToCleanUp.Clear(); remaining.ForEach(rem => VdiRefsToCleanUp.Add(rem.Key, rem.Value)); } catch { //best effort cleanup } } else { throw; } } catch (Exception ex) { log.ErrorFormat("Upload failed when introducing update from VDI {0} on {1}: {2}", vdi.opaque_ref, Connection, ex.Message); poolUpdate = null; throw; } } else { poolUpdate = null; } totalUploaded++; Description = String.Format(Messages.SUPP_PACK_UPLOADED, sr.Name()); foreach (Host host in servers) { SrUploadedUpdates[host] = sr; } return(result); }
public static bool IsHostRebootRequiredForUpdate(Host host, Pool_update poolUpdate, Dictionary <string, livepatch_status> livePatchCodesByHost = null) { return(poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartHost) && (livePatchCodesByHost == null || !livePatchCodesByHost.ContainsKey(host.uuid) || livePatchCodesByHost[host.uuid] != livepatch_status.ok_livepatch_complete)); }
protected virtual List <CheckGroup> GenerateChecks(Pool_update update) { List <Host> applicableServers = update != null?SelectedServers.Where(h => !update.AppliedOn(h)).ToList() : SelectedServers; var groups = GenerateCommonChecks(applicableServers); //Update Homogeneity check for InvernessOrGreater if (update != null) { var homogeneityChecks = new List <Check>(); foreach (var pool in SelectedPools.Where(pool => Helpers.InvernessOrGreater(pool.Connection))) { homogeneityChecks.Add(new ServerSelectionCheck(pool, update, SelectedServers)); } if (homogeneityChecks.Count > 0) { groups.Add(new CheckGroup(Messages.CHECKING_SERVER_SELECTION, homogeneityChecks)); } } //Checking other things if (update != null) { var serverChecks = new List <Check>(); foreach (Host host in SelectedServers) { var updates = new List <Pool_update>(host.Connection.Cache.Pool_updates); var poolUpdateFromHost = updates.Find(p => string.Equals(p.uuid, update.uuid, StringComparison.OrdinalIgnoreCase)); SR uploadSr = null; if (SrUploadedUpdates != null && poolUpdateFromHost != 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)); } //Checking if the host needs a reboot if (WizardMode == WizardMode.SingleUpdate) { var rebootChecks = new List <Check>(); var guidance = update != null ? update.after_apply_guidance : new List <update_after_apply_guidance> { update_after_apply_guidance.restartHost }; foreach (var host in applicableServers) { rebootChecks.Add(new HostNeedsRebootCheck(host, guidance, LivePatchCodesByHost)); } groups.Add(new CheckGroup(Messages.CHECKING_SERVER_NEEDS_REBOOT, rebootChecks)); } //Checking can evacuate host if (WizardMode == WizardMode.SingleUpdate && (update == null || update.after_apply_guidance.Contains(update_after_apply_guidance.restartHost))) { var evacuateChecks = new List <Check>(); foreach (Host host in applicableServers) { evacuateChecks.Add(new AssertCanEvacuateCheck(host, LivePatchCodesByHost)); } groups.Add(new CheckGroup(Messages.CHECKING_CANEVACUATE_STATUS, evacuateChecks)); } //Checking if a reboot is pending on master var restartChecks = new List <Check>(); foreach (var pool in SelectedPools) { restartChecks.Add(new RestartHostOrToolstackPendingOnMasterCheck(pool, update == null ? null : update.uuid)); } groups.Add(new CheckGroup(Messages.CHECKING_FOR_PENDING_RESTART, restartChecks)); return(groups); }
private string UploadSupplementalPack(SR sr) { this.Description = String.Format(Messages.SUPP_PACK_UPLOADING_TO, _updateName, sr.Name()); log.DebugFormat("Creating vdi of size {0} bytes on SR '{1}'", _totalUpdateSize, sr.Name()); VDI vdi = NewVDI(sr); var vdiRef = VDI.create(Session, vdi); Host localStorageHost = sr.GetStorageHost(); string hostUrl; if (localStorageHost == null) { Uri uri = new Uri(Session.Url); hostUrl = uri.Host; } else { log.DebugFormat("SR is not shared -- redirecting to {0}", localStorageHost.address); hostUrl = localStorageHost.address; } log.DebugFormat("Using {0} for import", hostUrl); string result; try { log.DebugFormat("Uploading file '{0}' to VDI '{1}' on SR '{2}'", suppPackFilePath, vdi.Name(), sr.Name()); HTTP.UpdateProgressDelegate progressDelegate = delegate(int percent) { var sr1 = sr; var descr = string.Format(Messages.UPLOAD_PATCH_UPLOADING_TO_SR_PROGRESS_DESCRIPTION, _updateName, sr1.Name(), Util.DiskSizeString(percent * _totalUpdateSize / 100, "F1"), Util.DiskSizeString(_totalUpdateSize)); var actionPercent = (int)((totalUploaded * 100 + percent) / totalCount); ByteProgressDescription = descr; Tick(actionPercent, descr); }; Session session = NewSession(); RelatedTask = Task.create(Session, "uploadTask", hostUrl); result = HTTPHelper.Put(progressDelegate, GetCancelling, true, Connection, RelatedTask, ref session, suppPackFilePath, hostUrl, (HTTP_actions.put_sss)HTTP_actions.put_import_raw_vdi, session.opaque_ref, vdiRef.opaque_ref); } catch (Exception ex) { log.Error("Failed to import a virtual disk over HTTP", ex); if (vdiRef != null) { try { log.ErrorFormat("Deleting VDI '{0}' on a best effort basis.", vdiRef.opaque_ref); Thread.Sleep(1000); VDI.destroy(Session, vdiRef); } catch (Exception removeEx) { log.Error("Failed to remove VDI.", removeEx); } } //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 { throw; } } finally { Task.destroy(Session, RelatedTask); RelatedTask = null; } //introduce ISO for Ely and higher if (Helpers.ElyOrGreater(Connection)) { try { var poolUpdateRef = Pool_update.introduce(Connection.Session, vdiRef); poolUpdate = Connection.WaitForCache(poolUpdateRef); if (poolUpdate == null) { throw new Exception(Messages.UPDATE_ERROR_INTRODUCE); // This should not happen, because such case will result in a XAPI Failure. But this code has to be protected at this point. } } catch (Exception ex) { //clean-up the VDI we've just created try { log.ErrorFormat("Deleting VDI '{0}' on a best effor basis.", vdiRef); VDI.destroy(Session, vdiRef); } catch (Exception removeEx) { log.Error("Failed to remove VDI", removeEx); } var failure = ex as Failure; if (failure != null && failure.ErrorDescription != null && failure.ErrorDescription.Count > 1 && failure.ErrorDescription[0] == Failure.UPDATE_ALREADY_EXISTS) { string uuidFound = failure.ErrorDescription[1]; poolUpdate = Connection.Cache.Pool_updates.FirstOrDefault(pu => string.Equals(pu.uuid, uuidFound, StringComparison.InvariantCultureIgnoreCase)); } else { log.Error("Failed to introduce the update", ex); poolUpdate = null; throw; } } } else { poolUpdate = null; } if (localStorageHost != null) { VdiRefsPerHost.Add(localStorageHost, vdiRef); } else // shared SR { foreach (var server in servers) { VdiRefsPerHost.Add(server, vdiRef); } } totalUploaded++; Description = string.Format(Messages.SUPP_PACK_UPLOADED, sr.Name()); foreach (Host host in servers) { SrsWithUploadedUpdatesPerHost[host] = sr; } return(result); }
public bool Matches(Host masterHost, XenServerPatch xenServerPatch, Pool_update update) { return(Matches(masterHost, xenServerPatch) && update != null && string.Equals(update.uuid, Pool_update.uuid, StringComparison.OrdinalIgnoreCase)); }
protected override Problem RunCheck() { // // Check that the SR where the update was uploaded is still attached // if (srUploadedUpdates != null && ((srUploadedUpdates.shared && !srUploadedUpdates.CanBeSeenFrom(Host)) || (!srUploadedUpdates.shared && srUploadedUpdates.IsBroken()))) { return(new BrokenSRWarning(this, Host, srUploadedUpdates)); } // // Check patch isn't already applied here // if ((Patch != null && Patch.AppliedOn(Host) != DateTime.MaxValue) || (Update != null && Update.AppliedOn(Host))) { return(new PatchAlreadyApplied(this, Host)); } if (!Host.IsLive()) { return(new HostNotLiveWarning(this, Host)); } if (!Host.Connection.IsConnected) { throw new EndOfStreamException(Helpers.GetName(Host.Connection)); } Session session = Host.Connection.DuplicateSession(); try { if (Patch != null) { string result = Pool_patch.precheck(session, Patch.opaque_ref, Host.opaque_ref); log.DebugFormat("Pool_patch.precheck returned: '{0}'", result); return(FindProblem(result)); } if (Update != null) { var livepatchStatus = Pool_update.precheck(session, Update.opaque_ref, Host.opaque_ref); log.DebugFormat("Pool_update.precheck returned livepatch_status: '{0}'", livepatchStatus); if (livePatchCodesByHost != null) { livePatchCodesByHost[Host.uuid] = livepatchStatus; } return(null); } //trying to apply update to partially upgraded pool if (Helpers.ElyOrGreater(Helpers.GetMaster(Host.Connection)) && !Helpers.ElyOrGreater(Host)) { return(new WrongServerVersion(this, Host)); } return(null); } catch (Failure f) { log.Error(f.ToString()); if (f.ErrorDescription.Count > 0) { log.Error(f.ErrorDescription[0]); } if (f.ErrorDescription.Count > 1) { log.Error(f.ErrorDescription[1]); } if (f.ErrorDescription.Count > 2) { log.Error(f.ErrorDescription[2]); } if (f.ErrorDescription.Count > 3) { log.Error(f.ErrorDescription[3]); } // try and find problem from the xapi failure Problem problem = FindProblem(f); return(problem ?? new PrecheckFailed(this, Host, f)); } }
public PatchPrecheckCheck(Host host, Pool_update update) : this(host, update, null) { }
public PatchPrecheckCheck(Host host, Pool_update update, Dictionary<string, livepatch_status> livePatchCodesByHost) : base(host) { _update = update; this.livePatchCodesByHost = livePatchCodesByHost; }
protected virtual List<KeyValuePair<string, List<Check>>> GenerateChecks(Pool_update update) { List<KeyValuePair<string, List<Check>>> checks = GenerateCommonChecks(); List<Check> checkGroup; //Checking other things if (update != null) { checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_SIDE_STATUS, new List<Check>())); checkGroup = checks[checks.Count - 1].Value; foreach (Host host in SelectedServers) { 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)); checkGroup.Add(new PatchPrecheckCheck(host, poolUpdateFromHost, LivePatchCodesByHost)); } } //Checking if the host needs a reboot if (!IsInAutomatedUpdatesMode) { checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List<Check>())); checkGroup = checks[checks.Count - 1].Value; var guidance = update != null ? update.after_apply_guidance : new List<update_after_apply_guidance> {update_after_apply_guidance.restartHost}; foreach (var host in SelectedServers) { checkGroup.Add(new HostNeedsRebootCheck(host, guidance, LivePatchCodesByHost)); } } //Checking can evacuate host if (update == null || update.after_apply_guidance.Contains(update_after_apply_guidance.restartHost)) { checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_CANEVACUATE_STATUS, new List<Check>())); checkGroup = checks[checks.Count - 1].Value; foreach (Host host in SelectedServers) { checkGroup.Add(new AssertCanEvacuateCheck(host, LivePatchCodesByHost)); } } return checks; }
protected override Problem RunCheck() { if (!Host.IsLive) { return(new HostNotLiveWarning(this, Host)); } if (!Host.Connection.IsConnected) { throw new EndOfStreamException(Helpers.GetName(Host.Connection)); } Session session = Host.Connection.DuplicateSession(); // // Check patch isn't already applied here // if ((Patch != null && Patch.AppliedOn(Host) != DateTime.MaxValue) || (Update != null && Update.AppliedOn(Host))) { return(new PatchAlreadyApplied(this, Host)); } try { if (Patch != null) { string result = Pool_patch.precheck(session, Patch.opaque_ref, Host.opaque_ref); log.DebugFormat("Pool_patch.precheck returned: '{0}'", result); return(FindProblem(result)); } else if (Helpers.ElyOrGreater(Host)) { var livepatchStatus = Pool_update.precheck(session, Update.opaque_ref, Host.opaque_ref); log.DebugFormat("Pool_update.precheck returned livepatch_status: '{0}'", livepatchStatus); if (livePatchCodesByHost != null) { livePatchCodesByHost[Host.uuid] = livepatchStatus; } } return(null); } catch (Failure f) { log.Error(f.ToString()); if (f.ErrorDescription.Count > 0) { log.Error(f.ErrorDescription[0]); } if (f.ErrorDescription.Count > 1) { log.Error(f.ErrorDescription[1]); } if (f.ErrorDescription.Count > 2) { log.Error(f.ErrorDescription[2]); } if (f.ErrorDescription.Count > 3) { log.Error(f.ErrorDescription[3]); } // try and find problem from the xapi failure Problem problem = FindProblem(f); return(problem ?? new PrecheckFailed(this, Host, f)); } }
private List<PlanAction> CompilePoolUpdateActionList(Host host, Pool_update poolUpdate) { List<PlanAction> actions = new List<PlanAction>(); if (SelectedUpdateType != UpdateType.ISO || poolUpdate == null) return actions; List<XenRef<VM>> runningVMs = RunningVMs(host); actions.Add(new ApplyPoolUpdatePlanAction(host, poolUpdate)); if (poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartHost) && !(LivePatchCodesByHost != null && LivePatchCodesByHost.ContainsKey(host.uuid) && LivePatchCodesByHost[host.uuid] == livepatch_status.ok_livepatch_complete)) { actions.Add(new EvacuateHostPlanAction(host)); actions.Add(new RebootHostPlanAction(host)); actions.Add(new BringBabiesBackAction(runningVMs, host, false)); } if (poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartXAPI)) { actions.Add(new RestartAgentPlanAction(host)); } if (poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartHVM)) { actions.Add(new RebootVMsPlanAction(host, RunningHvmVMs(host))); } if (poolUpdate.after_apply_guidance.Contains(update_after_apply_guidance.restartPV)) { actions.Add(new RebootVMsPlanAction(host, RunningPvVMs(host))); } return actions; }