예제 #1
0
        protected override void Run()
        {
            SafeToExit = false;

            if (update.AppliedOn(host))
            {
                return;
            }

            Description = string.Format(Messages.APPLYING_PATCH, update.Name(), host.Name());
            log.Debug(Description);

            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))
            {
                RelatedTask = Pool_update.async_apply(Session, poolUpdate.opaque_ref, host.opaque_ref);
                PollToCompletion();
                Description = string.Format(Messages.PATCH_APPLIED, update.Name(), host.Name());
            }
            else
            {
                Description = string.Format(Messages.PATCH_APPLIED_ALREADY, update.Name(), host.Name());
            }
        }
예제 #2
0
        protected override void RunWithSession(ref Session session)
        {
            AddProgressStep(string.Format(Messages.UPDATES_WIZARD_APPLYING_UPDATE, _poolUpdate.Name(), _host.Name()));
            XenRef <Task> task = Pool_update.async_apply(session, _poolUpdate.opaque_ref, _host.opaque_ref);

            PollTaskForResultAndDestroy(Connection, ref session, task);
        }
예제 #3
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;
            }
        }
예제 #4
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;
            }
        }
예제 #5
0
        protected override void RunWithSession(ref Session session)
        {
            var host = GetResolvedHost();

            // evacuate the host, if needed,  before applying the update
            if (_hostNeedsEvacuated)
            {
                EvacuateHost(ref session);
            }

            AddProgressStep(string.Format(Messages.UPDATES_WIZARD_APPLYING_UPDATE, _poolUpdate.Name(), host.Name()));
            new ApplyUpdateAction(_poolUpdate, host, true).RunExternal(session);
        }
 protected override void RunWithSession(ref Session session)
 {
     AddProgressStep(string.Format(Messages.UPDATES_WIZARD_APPLYING_UPDATE, _poolUpdate.Name(), _host.Name()));
     new ApplyUpdateAction(_poolUpdate, _host, true).RunExternal(session);
 }
예제 #7
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;
 }
예제 #8
0
        private Problem FindProblem(string errorcode, string found, string required)
        {
            long requiredSpace        = 0;
            long foundSpace           = 0;
            long reclaimableDiskSpace = 0;

            DiskSpaceRequirements diskSpaceReq;

            switch (errorcode)
            {
            case "UPDATE_PRECHECK_FAILED_WRONG_SERVER_VERSION":
                return(new WrongServerVersion(this, Host));

            case "UPDATE_PRECHECK_FAILED_CONFLICT_PRESENT":
                return(new ConflictingUpdatePresent(this, found, Host));

            case "UPDATE_PRECHECK_FAILED_PREREQUISITE_MISSING":
                return(new PrerequisiteUpdateMissing(this, found, Host));

            case "PATCH_PRECHECK_FAILED_WRONG_SERVER_VERSION":
                return(new WrongServerVersion(this, required, Host));

            case "PATCH_PRECHECK_FAILED_OUT_OF_SPACE":
                System.Diagnostics.Trace.Assert(!Helpers.ElyOrGreater(Host.Connection));       // If Ely or greater, we shouldn't get this error

                long.TryParse(found, out foundSpace);
                long.TryParse(required, out requiredSpace);
                // get reclaimable disk space (excluding current patch)
                try
                {
                    var args = new Dictionary <string, string> {
                        { "exclude", Patch.uuid }
                    };
                    var resultReclaimable = Host.call_plugin(Host.Connection.Session, Host.opaque_ref, "disk-space", "get_reclaimable_disk_space", args);
                    reclaimableDiskSpace = Convert.ToInt64(resultReclaimable);
                }
                catch (Failure failure)
                {
                    log.WarnFormat("Plugin call disk-space.get_reclaimable_disk_space on {0} failed with {1}", Host.Name(), failure.Message);
                }

                diskSpaceReq = new DiskSpaceRequirements(DiskSpaceRequirements.OperationTypes.install, Host, Patch.Name(), requiredSpace, foundSpace, reclaimableDiskSpace);

                return(new HostOutOfSpaceProblem(this, Host, Patch, diskSpaceReq));

            case "UPDATE_PRECHECK_FAILED_OUT_OF_SPACE":
                System.Diagnostics.Trace.Assert(Helpers.ElyOrGreater(Host.Connection));      // If not Ely or greater, we shouldn't get this error
                long.TryParse(found, out foundSpace);
                long.TryParse(required, out requiredSpace);

                diskSpaceReq = new DiskSpaceRequirements(DiskSpaceRequirements.OperationTypes.install, Host, Update.Name(), requiredSpace, foundSpace, 0);

                return(new HostOutOfSpaceProblem(this, Host, Update, diskSpaceReq));

            case "OUT_OF_SPACE":
                if (Patch != null || Update != null)
                {
                    var action = Patch != null
                            ? new GetDiskSpaceRequirementsAction(Host, Patch, true)
                            : new GetDiskSpaceRequirementsAction(Host, Update.Name(), Update.installation_size, true);
                    try
                    {
                        action.RunExternal(action.Session);
                    }
                    catch
                    {
                        log.WarnFormat("Could not get disk space requirements");
                    }
                    if (action.Succeeded)
                    {
                        return(Patch != null
                                ? new HostOutOfSpaceProblem(this, Host, Patch, action.DiskSpaceRequirements)
                                : new HostOutOfSpaceProblem(this, Host, Update, action.DiskSpaceRequirements));
                    }
                }
                break;

            case "LICENCE_RESTRICTION":
                return(new LicenseRestrictionProblem(this, Host));

            case "UPDATE_PRECHECK_FAILED_UNKNOWN_ERROR":
                // try to find the problem from the error parameters as xml string
                // e.g.
                //   ErrorDescription[0] = "UPDATE_PRECHECK_FAILED_UNKNOWN_ERROR"
                //   ErrorDescription[1] = "test-update"
                //   ErrorDescription[2] = "<?xml version="1.0" ?><error errorcode="LICENCE_RESTRICTION"></error>"
                return(FindProblem(found));
            }
            return(null);
        }
예제 #9
0
        private Problem FindProblem(string errorcode, string param1, string param2, string param3)
        {
            long requiredSpace;
            long foundSpace;
            long reclaimableDiskSpace = 0;

            DiskSpaceRequirements diskSpaceReq;

            switch (errorcode)
            {
            case "UPDATE_PRECHECK_FAILED_WRONG_SERVER_VERSION":
                return(new WrongServerVersion(this, Host));

            case "UPDATE_PRECHECK_FAILED_CONFLICT_PRESENT":
                return(new ConflictingUpdatePresent(this, param2, Host));

            case "UPDATE_PRECHECK_FAILED_PREREQUISITE_MISSING":
                return(new PrerequisiteUpdateMissing(this, param2, Host));

            case "PATCH_PRECHECK_FAILED_WRONG_SERVER_VERSION":
                return(new WrongServerVersion(this, param3, Host));

            case "PATCH_PRECHECK_FAILED_OUT_OF_SPACE":
                System.Diagnostics.Trace.Assert(!Helpers.ElyOrGreater(Host.Connection));       // If Ely or greater, we shouldn't get this error

                long.TryParse(param2, out foundSpace);
                long.TryParse(param3, out requiredSpace);
                // get reclaimable disk space (excluding current patch)
                try
                {
                    var args = new Dictionary <string, string> {
                        { "exclude", Patch.uuid }
                    };
                    var resultReclaimable = Host.call_plugin(Host.Connection.Session, Host.opaque_ref, "disk-space", "get_reclaimable_disk_space", args);
                    reclaimableDiskSpace = Convert.ToInt64(resultReclaimable);
                }
                catch (Exception exception)
                {
                    log.WarnFormat("Plugin call disk-space.get_reclaimable_disk_space on {0} failed with {1}", Host.Name(), exception.Message);
                }

                diskSpaceReq = new DiskSpaceRequirements(DiskSpaceRequirements.OperationTypes.install, Host, Patch.Name(), requiredSpace, foundSpace, reclaimableDiskSpace);

                return(new HostOutOfSpaceProblem(this, Host, Patch, diskSpaceReq));

            case "UPDATE_PRECHECK_FAILED_OUT_OF_SPACE":
                System.Diagnostics.Trace.Assert(Helpers.ElyOrGreater(Host.Connection));      // If not Ely or greater, we shouldn't get this error

                long.TryParse(param2, out foundSpace);
                long.TryParse(param3, out requiredSpace);

                diskSpaceReq = new DiskSpaceRequirements(DiskSpaceRequirements.OperationTypes.install, Host, Update.Name(), requiredSpace, foundSpace, 0);

                return(new HostOutOfSpaceProblem(this, Host, Update, diskSpaceReq));

            case "OUT_OF_SPACE":
                if (Patch != null || Update != null)
                {
                    var action = Patch != null
                            ? new GetDiskSpaceRequirementsAction(Host, Patch, true)
                            : new GetDiskSpaceRequirementsAction(Host, Update.Name(), Update.installation_size, true);
                    try
                    {
                        action.RunExternal(action.Session);
                    }
                    catch
                    {
                        log.WarnFormat("Could not get disk space requirements");
                    }
                    if (action.Succeeded)
                    {
                        return(Patch != null
                                ? new HostOutOfSpaceProblem(this, Host, Patch, action.DiskSpaceRequirements)
                                : new HostOutOfSpaceProblem(this, Host, Update, action.DiskSpaceRequirements));
                    }
                }
                break;

            case "LICENCE_RESTRICTION":
                return(new LicenseRestrictionProblem(this, Host));

            case "UPDATE_PRECHECK_FAILED_UNKNOWN_ERROR":
                if (param1 == "CH82" && param2.StartsWith("VSWITCH_CONTROLLER_CONNECTED"))
                {
                    var pool = Helpers.GetPoolOfOne(Host.Connection);
                    if (pool.vSwitchController())
                    {
                        return(new VSwitchControllerProblem(this, pool));
                    }
                    return(null);
                }
                else
                {
                    return(FindProblem(param2));
                }
            }
            return(null);
        }
예제 #10
0
 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;
 }