Scalr\Upgrade\UpgradeHandler::applyUpdate PHP 메소드

applyUpdate() 보호된 메소드

Applies update
protected applyUpdate ( Scalr\Upgrade\AbstractUpdate $upd ) : boolean
$upd Scalr\Upgrade\AbstractUpdate Update to apply
리턴 boolean Returns true if update is successful, false otherwise
    protected function applyUpdate(AbstractUpdate $upd)
    {
        if (!isset($this->attempts[$upd->getUuidHex()])) {
            $this->attempts[$upd->getUuidHex()] = 1;
        } else {
            $this->attempts[$upd->getUuidHex()]++;
        }
        if ($this->attempts[$upd->getUuidHex()] > self::MAX_ATTEMPTS) {
            throw new Exception\UpgradeException(sprintf('"%s" Failed due to infinity loop. Max number of attempts (%d) reached!', $upd->getName(), self::MAX_ATTEMPTS));
        }
        $refuseReason = $upd->isRefused();
        if (false !== $refuseReason) {
            if ($this->opt->verbosity) {
                $this->console->notice('%s is ignored. %s', $upd->getName(), (string) $refuseReason);
            }
            return true;
        }
        if ($upd->getStatus() == AbstractUpgradeEntity::STATUS_OK) {
            //Upgrade file is updated.
            $upd->updateAppears();
            if (isset($this->opt->cmd) && $this->opt->cmd == self::CMD_RUN_SPECIFIC && $this->opt->uuid == $upd->getUuidHex()) {
                //User has requested re-execution of update
                $upd->setStatus(AbstractUpgradeEntity::STATUS_PENDING);
                $upd->updateHash();
                $upd->getEntity()->save();
            } else {
                //Compare checksum
                if ($upd->getEntity()->hash == $upd->getHash()) {
                    //file modified time could be the issue
                    $upd->updateApplied();
                    $upd->getEntity()->save();
                    if (!empty($this->opt->verbosity) || isset($this->opt->cmd) && $this->opt->cmd == self::CMD_RUN_SPECIFIC && $this->opt->uuid == $upd->getUuidHex()) {
                        $this->console->warning('Ingnoring %s because of having complete status.', $upd->getName());
                    }
                    return true;
                } else {
                    //We should ignore changes in the script and update hash
                    $upd->updateHash();
                    $upd->getEntity()->save();
                    return true;
                }
            }
        }
        $this->console->success('%s...', $upd->description ?: $upd->getName());
        //Checks updates this upgrade depends upon
        if (!empty($upd->depends)) {
            foreach ($upd->depends as $uuid) {
                $uuidhex = AbstractUpdate::castUuid($uuid);
                if (!empty($this->updates[$uuidhex])) {
                    $update = $this->updates[$uuidhex];
                    if ($update->getStatus() == AbstractUpgradeEntity::STATUS_OK) {
                        //Relative update has already been successfully applied.
                        continue;
                    }
                } else {
                    if (isset($this->stateBefore[$uuidhex])) {
                        /* @var $upgradeEntity \Scalr\Upgrade\Entity\AbstractUpgradeEntity */
                        $upgradeEntity = $this->stateBefore[$uuidhex];
                        if ($upgradeEntity->status == AbstractUpgradeEntity::STATUS_OK) {
                            //Relative update has already been applied
                            continue;
                        } else {
                            //Relative update needs to be applied before dependant.
                            $this->console->warning('"%s" has been declined as it depends on incomplete update "%s" which has status "%s". ' . 'Desired class "%s" does not exist in the expected folder.', $upd->getName(), $uuid, $upgradeEntity->getStatusName(), $upgradeEntity->getUpdateClassName());
                            return false;
                        }
                    } else {
                        //Relative update has not been delivered yet.
                        $this->console->warning('"%s" has been postponed as it depends on "%s" which has not been delivered yet.', $upd->getName(), $uuid);
                        return false;
                    }
                }
                if ($update->getStatus() == AbstractUpgradeEntity::STATUS_FAILED && isset($this->recurrences[$update->getUuidHex()])) {
                    //Recurrence of the failed status. We don't need to report about it again.
                    $this->console->warning('"%s" has been declined because of failure dependent update "%s".', $upd->getName(), $uuid);
                    return false;
                }
                //Relative update has not been applied or it has incomplete status.
                //We need to apply it first.
                if ($this->applyUpdate($update) === false) {
                    $this->console->warning('"%s" has been declined. Could not apply related update "%s".', $upd->getName(), $update->getName());
                    return false;
                }
            }
        }
        //Checks if update class implements SequenceInterface
        $stages = $upd instanceof SequenceInterface ? range(1, $upd->getNumberStages()) : array(1);
        $skip = 0;
        foreach ($stages as $stage) {
            //Checks if update is applied
            if ($upd->isApplied($stage)) {
                $upd->console->warning('Skips over the stage %d of update %s because it has already been applied.', $stage, $upd->getName());
                $skip++;
                continue;
            }
            //Validates environment before applying
            if (!$upd->validateBefore($stage)) {
                $this->console->error('Error. Stage %d of update %s could not be applied because of invalid environment! validateBefore(%d) returned false.', $stage, $upd->getName(), $stage);
                return false;
            }
            //Applies the update
            try {
                $upd->run($stage);
            } catch (\Exception $e) {
                //We should avoid repetition when another update depends on failed.
                $this->recurrences[$upd->getUuidHex()] = true;
                $upd->setStatus(AbstractUpgradeEntity::STATUS_FAILED);
                $upd->console->error('Error. Stage %d of update %s failed! %s', $stage, $upd->getName(), $e->getMessage());
                $upd->getEntity()->save();
                $upd->getEntity()->createFailureMessage($upd->console->getLog());
                return false;
            }
        }
        $this->console->success("%s - OK", $upd->description ?: $upd->getName());
        $upd->setStatus(AbstractUpgradeEntity::STATUS_OK);
        $upd->updateHash();
        $upd->updateApplied();
        $upd->getEntity()->save();
        return true;
    }