Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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;
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
            }
        }
Ejemplo n.º 6
0
 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());
             }
Ejemplo n.º 8
0
        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.");
            }
        }
Ejemplo n.º 9
0
        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;
        }
Ejemplo n.º 10
0
        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;
            }
        }
Ejemplo n.º 11
0
        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;
                }
            }
        }
Ejemplo n.º 12
0
        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;
            }
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        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);
                }
            }
        }
Ejemplo n.º 16
0
        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;
 }
Ejemplo n.º 21
0
 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);
             }
         });
 }
Ejemplo n.º 22
0
 public HostOutOfSpaceProblem(Check check, Host host, Pool_update update, DiskSpaceRequirements diskSpaceReq)
     : base(check, host)
 {
     this.update = update;
     this.diskSpaceReq = diskSpaceReq;
 }
Ejemplo n.º 23
0
 public PatchPrecheckCheck(Host host, Pool_update update, Dictionary <string, livepatch_status> livePatchCodesByHost)
     : base(host)
 {
     _update = update;
     this.livePatchCodesByHost = livePatchCodesByHost;
 }
Ejemplo n.º 24
0
 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;
 }
Ejemplo n.º 25
0
 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);
                    }
                }
            }
        }
Ejemplo n.º 27
0
        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)));
                    }
                }
            });
        }
Ejemplo n.º 28
0
        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);
        }
Ejemplo n.º 29
0
 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;
 }
Ejemplo n.º 30
0
        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);
        }
Ejemplo n.º 33
0
 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);
        }
Ejemplo n.º 36
0
 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));
 }
Ejemplo n.º 37
0
        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));
            }
        }
Ejemplo n.º 38
0
 public PatchPrecheckCheck(Host host, Pool_update update)
     : this(host, update, null)
 {
 }
Ejemplo n.º 39
0
 public PatchPrecheckCheck(Host host, Pool_update update, Dictionary<string, livepatch_status> livePatchCodesByHost)
     : base(host)
 {
     _update = update;
     this.livePatchCodesByHost = livePatchCodesByHost;
 }
Ejemplo n.º 40
0
 public PatchPrecheckCheck(Host host, Pool_update update)
     : this(host, update, 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;
        }
Ejemplo n.º 42
0
        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;
        }