Inheritance: extends DataObject
コード例 #1
0
 protected function canSendEmail(\DNDeployment $deployment)
 {
     $deployer = $deployment->Deployer();
     $approver = $deployment->Approver();
     if (!$deployer || !$deployer->exists()) {
         return false;
     }
     if (!$approver || !$approver->exists()) {
         return false;
     }
     return true;
 }
コード例 #2
0
ファイル: RollbackStep.php プロジェクト: ss23/deploynaut
 /**
  * Begin a new deployment
  *
  * @return boolean
  */
 protected function startRevertDeploy()
 {
     $this->Status = 'Started';
     $this->Doing = 'Deployment';
     $this->log("{$this->Title} starting revert deployment");
     // Skip deployment for dry run
     if ($this->Pipeline()->DryRun) {
         $this->log("[Skipped] Create DNDeployment");
         $this->write();
         return true;
     }
     // Get old deployment from pipeline
     $pipeline = $this->Pipeline();
     $previous = $pipeline->PreviousDeployment();
     if (empty($previous) || empty($previous->SHA)) {
         $this->log("No available SHA for {$this->Title}");
         $this->markFailed();
         return false;
     }
     // Initialise deployment
     $deployment = DNDeployment::create();
     // Leave the maintenance page up if we are restoring the DB
     $deployment->LeaveMaintenacePage = $this->doRestoreDB();
     $deployment->EnvironmentID = $pipeline->EnvironmentID;
     $deployment->SHA = $previous->SHA;
     $deployment->DeployerID = $pipeline->AuthorID;
     $deployment->write();
     $deployment->start();
     $this->RollbackDeploymentID = $deployment->ID;
     $this->write();
     return true;
 }
コード例 #3
0
ファイル: DeployJob.php プロジェクト: udomsak/deploynaut
 /**
  * @param string $status
  * @global array $databaseConfig
  */
 protected function updateStatus($status)
 {
     global $databaseConfig;
     DB::connect($databaseConfig);
     $dnDeployment = DNDeployment::get()->byID($this->args['deploymentID']);
     $dnDeployment->Status = $status;
     $dnDeployment->write();
 }
コード例 #4
0
ファイル: PingJob.php プロジェクト: udomsak/deploynaut
 /**
  * Do the actual job by calling the appropiate backend
  */
 public function perform()
 {
     echo "[-] PingJob starting" . PHP_EOL;
     $log = new DeploynautLogFile($this->args['logfile']);
     $ping = DNDeployment::get()->byID($this->args['pingID']);
     $environment = $ping->Environment();
     $project = $environment->Project();
     $environment->Backend()->ping($environment, $log, $project);
 }
コード例 #5
0
 /**
  * Makes the dummy deployment step
  *
  * @return Pipeline
  */
 public function getDummyPipeline($restoreDB = true)
 {
     // Get default backups
     $previous = DNDeployment::create();
     $previous->write();
     $current = DNDeployment::create();
     $current->write();
     $snapshot = DNDataTransfer::create();
     $snapshot->write();
     // Setup default pipeline
     $pipeline = $this->objFromFixture('Pipeline', 'testpipesmoketest');
     $pipeline->Config = serialize(array('RollbackStep1' => array('Class' => 'RollbackStep', 'RestoreDB' => $restoreDB, 'MaxDuration' => '3600')));
     $pipeline->PreviousDeploymentID = $previous->ID;
     $pipeline->CurrentDeploymentID = $current->ID;
     $pipeline->PreviousSnapshotID = $snapshot->ID;
     $pipeline->write();
     return $pipeline;
 }
コード例 #6
0
 /**
  * Begin a new deployment
  * 
  * @return boolean
  */
 protected function startDeploy()
 {
     $this->Status = 'Started';
     $this->Doing = 'Deployment';
     $this->log("{$this->Title} starting deployment");
     // Check environment and SHA
     $pipeline = $this->Pipeline();
     $environment = $pipeline->Environment();
     if (empty($environment) || !$environment->exists()) {
         $this->log("No available environment for {$this->Title}");
         $this->markFailed();
         return false;
     }
     if (empty($pipeline->SHA)) {
         $this->log("No available SHA for {$this->Title}");
         $this->markFailed();
         return false;
     }
     // Skip deployment for dry run
     if ($this->Pipeline()->DryRun) {
         $this->log("[Skipped] Create DNDeployment for SHA " . $pipeline->SHA);
         $this->write();
         return true;
     }
     // Initialise deployment
     $deployment = DNDeployment::create();
     $deployment->EnvironmentID = $environment->ID;
     $deployment->SHA = $pipeline->SHA;
     $previousStep = $pipeline->findPreviousStep();
     $deployment->DeployerID = $previousStep && $previousStep->ResponderID ? $previousStep->ResponderID : $pipeline->AuthorID;
     $deployment->write();
     $deployment->start();
     $pipeline->CurrentDeploymentID = $deployment->ID;
     $pipeline->write();
     $this->write();
     return true;
 }
コード例 #7
0
 public function DeployHistory()
 {
     return DNDeployment::get()->filter('EnvironmentID', $this->ID)->sort('LastEdited DESC');
 }
コード例 #8
0
ファイル: DNEnvironment.php プロジェクト: udomsak/deploynaut
 /**
  * Get the current deployed build for this environment
  *
  * Dear people of the future: If you are looking to optimize this, simply create a CurrentBuildSHA(), which can be
  * a lot faster. I presume you came here because of the Project display template, which only needs a SHA.
  *
  * @return false|DNDeployment
  */
 public function CurrentBuild()
 {
     // The DeployHistory function is far too slow to use for this
     /** @var DNDeployment $deploy */
     $deploy = DNDeployment::get()->filter(array('EnvironmentID' => $this->ID, 'Status' => 'Finished'))->sort('LastEdited DESC')->first();
     if (!$deploy || !$deploy->SHA) {
         return false;
     }
     $repo = $this->Project()->getRepository();
     if (!$repo) {
         return $deploy;
     }
     try {
         $commit = $repo->getCommit($deploy->SHA);
         if ($commit) {
             $deploy->Message = Convert::raw2xml($commit->getMessage());
             $deploy->Committer = Convert::raw2xml($commit->getCommitterName());
             $deploy->CommitDate = $commit->getCommitterDate()->Format('d/m/Y g:ia');
             $deploy->Author = Convert::raw2xml($commit->getAuthorName());
             $deploy->AuthorDate = $commit->getAuthorDate()->Format('d/m/Y g:ia');
         }
         // We can't find this SHA, so we ignore adding a commit message to the deployment
     } catch (Exception $ex) {
     }
     return $deploy;
 }
コード例 #9
0
 /**
  * Provide rollback-able pipeline on the verge of failing.
  */
 public function getFailingPipeline()
 {
     // Get default backups
     $previous = DNDeployment::create();
     $previous->SHA = '9f0a012e97715b1871n41gk30f34268u12a0029q';
     $previous->write();
     $current = DNDeployment::create();
     $current->write();
     $snapshot = DNDataTransfer::create();
     $snapshot->write();
     $pipeline = $this->objFromFixture('Pipeline', 'FailingPipe');
     $pipeline->Config = serialize(array('RollbackStep1' => array('Class' => 'RollbackStep', 'RestoreDB' => false, 'MaxDuration' => '3600'), 'RollbackStep2' => array('Class' => 'SmokeTestPipelineStep', 'MaxDuration' => '3600')));
     $pipeline->PreviousDeploymentID = $previous->ID;
     $pipeline->CurrentDeploymentID = $current->ID;
     $pipeline->PreviousSnapshotID = $snapshot->ID;
     $pipeline->write();
     return $pipeline;
 }
コード例 #10
0
 /**
  * Fetchs all deployments in progress. Limits to 1 hour to prevent deployments
  * if an old deployment is stuck.
  *
  * @return DataList
  */
 public function runningDeployments()
 {
     return DNDeployment::get()->filter(['EnvironmentID' => $this->ID, 'Status' => ['Queued', 'Started'], 'Created:GreaterThan' => strtotime('-1 hour')]);
 }
コード例 #11
0
 /**
  * @param int $deploymentID
  * @return \DNDeployment
  */
 public function updateDeployment($deploymentID)
 {
     $deployment = \DNDeployment::get()->byId($deploymentID);
     $deployment->EnvironmentID = $this->environment->ID;
     $deployment->SHA = $this->getOption('sha');
     $deployment->RefType = $this->getOption('ref_type');
     $deployment->RefName = $this->getOption('ref_name');
     $deployment->Summary = $this->getOption('summary');
     $deployment->Title = $this->getOption('title');
     $deployment->Strategy = $this->toJSON();
     $deployment->DeployerID = \Member::currentUserID();
     $deployment->write();
     // re-get and return the deployment so we have the correct state
     return \DNDeployment::get()->byId($deployment->ID);
 }
コード例 #12
0
ファイル: APIEnvironment.php プロジェクト: ss23/deploynaut
 /**
  *
  * @param int $id
  * @return SS_HTTPResponse
  */
 protected function getDeploy($id)
 {
     $deploy = DNDeployment::get()->byID($id);
     if (!$deploy) {
         return $this->message('Deploy not found', 404);
     }
     $output = array('status' => $deploy->ResqueStatus(), 'message' => $deploy->LogContent());
     return $this->getAPIResponse($output);
 }
コード例 #13
0
ファイル: DNEnvironment.php プロジェクト: ss23/deploynaut
 /**
  * Get the current deployed build for this environment
  *
  * Dear people of the future: If you are looking to optimize this, simply create a CurrentBuildSHA(), which can be a lot faster.
  * I presume you came here because of the Project display template, which only needs a SHA.
  *
  * @return string
  */
 public function CurrentBuild()
 {
     // The DeployHistory function is far too slow to use for this
     $deploy = DNDeployment::get()->filter(array('EnvironmentID' => $this->ID, 'Status' => 'Finished'))->sort('LastEdited DESC')->first();
     if (!$deploy || !$deploy->SHA) {
         return false;
     }
     $repo = $this->Project()->getRepository();
     if (!$repo) {
         return $deploy;
     }
     try {
         $commit = $repo->getCommit($deploy->SHA);
         if ($commit) {
             $deploy->Message = Convert::raw2xml($commit->getMessage());
         }
         // We can't find this SHA, so we ignore adding a commit message to the deployment
     } catch (Gitonomy\Git\Exception\ReferenceNotFoundException $ex) {
     }
     return $deploy;
 }
コード例 #14
0
 public function getSHA()
 {
     $sha = parent::getField('SHA');
     return $sha ?: '9ae502821345ab39b04d46ce6bb822ccdd7f7414';
 }
コード例 #15
0
 /**
  * Check if a DNDeployment exists and do permission checks on it. If there is something wrong it will return
  * an APIResponse with the error, otherwise null.
  *
  * @param \DNDeployment $deployment
  *
  * @return null|SS_HTTPResponse
  */
 protected function validateDeployment($deployment)
 {
     if (!$deployment || !$deployment->exists()) {
         return $this->getAPIResponse(['message' => 'This deployment does not exist'], 404);
     }
     if ($deployment->EnvironmentID != $this->environment->ID) {
         return $this->getAPIResponse(['message' => 'This deployment does not belong to the environment'], 403);
     }
     if (!$deployment->canView()) {
         return $this->getAPIResponse(['message' => 'You are not authorised to view this deployment'], 403);
     }
     return null;
 }
コード例 #16
0
ファイル: DNEnvironment.php プロジェクト: adrexia/deploynaut
 /**
  * A history of all builds deployed to this environment
  *
  * @return ArrayList
  */
 public function DeployHistory()
 {
     $history = DNDeployment::get()->filter('EnvironmentID', $this->ID)->sort('LastEdited DESC');
     $repo = $this->Project()->getRepository();
     if (!$repo) {
         return $history;
     }
     $ammendedHistory = new ArrayList();
     foreach ($history as $deploy) {
         if (!$deploy->SHA) {
             continue;
         }
         try {
             $commit = $repo->getCommit($deploy->SHA);
             if ($commit) {
                 $deploy->Message = Convert::raw2xml($commit->getMessage());
             }
             // We can't find this SHA, so we ignore adding a commit message to the deployment
         } catch (Gitonomy\Git\Exception\ReferenceNotFoundException $ex) {
         }
         $ammendedHistory->push($deploy);
     }
     return $ammendedHistory;
 }
コード例 #17
0
 /**
  * @return DNDeployment
  */
 public function createDeployment()
 {
     $deployment = DNDeployment::create();
     $deployment->EnvironmentID = $this->environment->ID;
     // Pull out the SHA from the options so we can make it queryable.
     $deployment->SHA = $this->getOption('sha');
     $deployment->Strategy = $this->toJSON();
     $deployment->write();
     return $deployment;
 }
コード例 #18
0
ファイル: DeployJob.php プロジェクト: silverstripe/deploynaut
 /**
  * @param string $status Transition
  * @global array $databaseConfig
  */
 protected function updateStatus($status)
 {
     global $databaseConfig;
     DB::connect($databaseConfig);
     $deployment = DNDeployment::get()->byID($this->args['deploymentID']);
     $deployment->getMachine()->apply($status);
 }
コード例 #19
0
 /**
  * Return data about a single deployment for use in API response.
  * @param \DNDeployment $deployment
  * @return array
  */
 public function getDeploymentData(\DNDeployment $deployment)
 {
     if (empty(self::$_cache_current_build[$deployment->EnvironmentID])) {
         self::$_cache_current_build[$deployment->EnvironmentID] = $deployment->Environment()->CurrentBuild();
     }
     $environment = $deployment->Environment();
     $project = $environment->Project();
     $deployerData = $this->getStackMemberData($project, $deployment->DeployerID);
     $approverData = $this->getStackMemberData($project, $deployment->ApproverID);
     $started = null;
     $startedNice = null;
     $startedAgo = null;
     // we check first, before we do a expensive ->Nice() and ->Ago()
     if (!$deployment->DeployStarted) {
         $started = $deployment->Created;
         $startedNice = $deployment->obj('Created')->Nice();
         $startedAgo = $deployment->obj('Created')->Ago();
     } else {
         $started = $deployment->DeployStarted;
         $startedNice = $deployment->obj('DeployStarted')->Nice();
         $startedAgo = $deployment->obj('DeployStarted')->Ago();
     }
     $isCurrentBuild = self::$_cache_current_build[$deployment->EnvironmentID] ? $deployment->ID === self::$_cache_current_build[$deployment->EnvironmentID]->ID : false;
     $supportedOptions = $environment->getSupportedOptions();
     $setOptions = $deployment->getDeploymentStrategy() ? $deployment->getDeploymentStrategy()->getOptions() : [];
     $options = [];
     foreach ($supportedOptions as $option) {
         if (!isset($setOptions[$option->getName()])) {
             continue;
         }
         if ($setOptions[$option->getName()] === 'true' || $setOptions[$option->getName()] === true) {
             $options[$option->getName()] = true;
         }
     }
     $tags = [];
     try {
         $tags = $deployment->getTags()->toArray();
     } catch (\Exception $e) {
         // gitonomy exception
     }
     $type = 'full';
     if ($deployment->getDeploymentStrategy()->getActionCode() === 'fast') {
         $type = 'code-only';
     }
     return ['id' => $deployment->ID, 'date_created' => $deployment->Created, 'date_created_nice' => $deployment->obj('Created')->Nice(), 'date_created_ago' => $deployment->obj('Created')->Ago(), 'date_started' => $started, 'date_started_nice' => $startedNice, 'date_started_ago' => $startedAgo, 'date_requested' => $deployment->DeployRequested, 'date_requested_nice' => $deployment->obj('DeployRequested')->Nice(), 'date_requested_ago' => $deployment->obj('DeployRequested')->Ago(), 'date_updated' => $deployment->LastEdited, 'date_updated_nice' => $deployment->obj('LastEdited')->Nice(), 'date_updated_ago' => $deployment->obj('LastEdited')->Ago(), 'title' => $deployment->Title, 'summary' => $deployment->Summary, 'ref_type' => $deployment->RefType, 'ref_name' => $deployment->RefName, 'rejected_reason' => $deployment->RejectedReason ?: '', 'tags' => $tags, 'changes' => $deployment->getDeploymentStrategy()->getChanges(), 'deployment_type' => $type, 'deployment_estimate' => $deployment->getDeploymentStrategy()->getEstimatedTime(), 'sha' => $deployment->SHA, 'short_sha' => substr($deployment->SHA, 0, 7), 'options' => $options, 'commit_subject' => $deployment->getCommitSubjectMessage(), 'commit_message' => $deployment->getCommitMessage(), 'commit_url' => $deployment->getCommitURL(), 'deployer' => $deployerData, 'approver_id' => $deployment->ApproverID ?: '', 'approver' => $approverData, 'state' => $deployment->State, 'is_current_build' => $isCurrentBuild, 'dirty' => false];
 }
コード例 #20
0
ファイル: DNCommit.php プロジェクト: adrexia/deploynaut
 /**
  *
  * @param string $environmentName
  * @return boolean True if this release has ever been deployed to the given environment
  */
 public function EverDeployedTo($environmentName)
 {
     $environments = $this->project->Environments()->filter('Name', $environmentName);
     if (!$environments->count()) {
         return false;
     }
     $environment = $environments->first();
     $deployments = DNDeployment::get()->filter('Status', 'Finished')->filter('EnvironmentID', $environment->ID);
     if ($deployments->count()) {
         return true;
     }
     return false;
 }
コード例 #21
0
 public function run($request)
 {
     $args = $request->getVar('args');
     $dryRun = $args && in_array('--dry-run', $args);
     $log = function ($message) {
         $message = sprintf('[%s] ', date('Y-m-d H:i:s')) . $message;
         echo $message . PHP_EOL;
     };
     if (!Director::is_cli()) {
         $log('This task must be run under the command line');
         return;
     }
     if ($dryRun) {
         $log('Running in dry-run mode. No data will be deleted');
     }
     $count = 0;
     foreach (DNEnvironment::get() as $environment) {
         $project = $environment->Project();
         if (!$project || !$project->exists()) {
             $log(sprintf('Environment (ID %s, Name: %s, Created: %s) is linked to a non-existent project. Deleting', $environment->ID, $environment->Name, $environment->Created));
             if (!$dryRun) {
                 $environment->delete();
                 $environment->destroy();
             }
             $count++;
         }
     }
     foreach (DNDeployment::get() as $deployment) {
         $environment = $deployment->Environment();
         if (!$environment || !$environment->exists()) {
             $log(sprintf('Deployment (ID %s, Created: %s) is linked to a non-existent environment. Deleting', $deployment->ID, $deployment->Created));
             if (!$dryRun) {
                 $deployment->delete();
                 $deployment->destroy();
             }
             $count++;
         }
     }
     foreach (DNDataTransfer::get() as $transfer) {
         $environment = $transfer->Environment();
         if (!$environment || !$environment->exists()) {
             $log(sprintf('Data transfer (ID %s, Created: %s) is linked to a non-existent environment. Deleting', $transfer->ID, $transfer->Created));
             if (!$dryRun) {
                 $transfer->delete();
                 $transfer->destroy();
             }
             $count++;
         }
     }
     foreach (DNDataArchive::get() as $archive) {
         $environment = $archive->Environment();
         if (!$environment || !$environment->exists()) {
             $log(sprintf('Archive (ID %s, Created: %s) is linked to a non-existent environment. Deleting', $archive->ID, $archive->Created));
             if (!$dryRun) {
                 $archive->delete();
                 $archive->destroy();
             }
             $count++;
         }
     }
     foreach (DNGitFetch::get() as $fetch) {
         $project = $fetch->Project();
         if (!$project || !$project->exists()) {
             $log(sprintf('Git fetch (ID %s, Created: %s) is linked to a non-existent project. Deleting', $fetch->ID, $fetch->Created));
             if (!$dryRun) {
                 $fetch->delete();
                 $fetch->destroy();
             }
             $count++;
         }
     }
     foreach (DNPing::get() as $ping) {
         $environment = $ping->Environment();
         if (!$environment || !$environment->exists()) {
             $log(sprintf('Ping (ID %s, Created: %s) is linked to a non-existent environment. Deleting', $ping->ID, $ping->Created));
             if (!$dryRun) {
                 $ping->delete();
                 $ping->destroy();
             }
             $count++;
         }
     }
     $log(sprintf('Finished. Processed %s records', $count));
 }
コード例 #22
0
 /**
  * Fetchs all deployments in progress. Limits to 1 hour to prevent deployments
  * if an old deployment is stuck.
  *
  * @return DataList
  */
 public function runningDeployments()
 {
     return DNDeployment::get()->filter(['EnvironmentID' => $this->ID, 'State' => [DNDeployment::STATE_QUEUED, DNDeployment::STATE_DEPLOYING, DNDeployment::STATE_ABORTING], 'Created:GreaterThan' => strtotime('-1 hour')]);
 }
コード例 #23
0
ファイル: DNRoot.php プロジェクト: silverstripe/deploynaut
 /**
  * @deprecated 2.0.0 - moved to DeployDispatcher
  *
  * @param \SS_HTTPRequest $request
  *
  * @return string
  * @throws SS_HTTPResponse_Exception
  */
 public function abortDeploy(\SS_HTTPRequest $request)
 {
     $params = $request->params();
     $deployment = DNDeployment::get()->byId($params['Identifier']);
     if (!$deployment || !$deployment->ID) {
         throw new SS_HTTPResponse_Exception('Deployment not found', 404);
     }
     if (!$deployment->canView()) {
         return Security::permissionFailure();
     }
     // For now restrict to ADMINs only.
     if (!Permission::check('ADMIN')) {
         return Security::permissionFailure();
     }
     $environment = $deployment->Environment();
     $project = $environment->Project();
     if ($environment->Name != $params['Environment']) {
         throw new LogicException("Environment in URL doesn't match this deploy");
     }
     if ($project->Name != $params['Project']) {
         throw new LogicException("Project in URL doesn't match this deploy");
     }
     if (!in_array($deployment->Status, ['Queued', 'Deploying', 'Aborting'])) {
         throw new LogicException(sprintf("Cannot abort from %s state.", $deployment->Status));
     }
     $deployment->getMachine()->apply(DNDeployment::TR_ABORT);
     return $this->sendResponse($deployment->ResqueStatus(), []);
 }
コード例 #24
0
ファイル: DNRoot.php プロジェクト: udomsak/deploynaut
 /**
  * Action - Get the latest deploy log
  *
  * @param SS_HTTPRequest $request
  *
  * @return string
  * @throws SS_HTTPResponse_Exception
  */
 public function deploylog(SS_HTTPRequest $request)
 {
     $params = $request->params();
     $deployment = DNDeployment::get()->byId($params['Identifier']);
     if (!$deployment || !$deployment->ID) {
         throw new SS_HTTPResponse_Exception('Deployment not found', 404);
     }
     if (!$deployment->canView()) {
         return Security::permissionFailure();
     }
     $environment = $deployment->Environment();
     $project = $environment->Project();
     if ($environment->Name != $params['Environment']) {
         throw new LogicException("Environment in URL doesn't match this deploy");
     }
     if ($project->Name != $params['Project']) {
         throw new LogicException("Project in URL doesn't match this deploy");
     }
     $log = $deployment->log();
     if ($log->exists()) {
         $content = $log->content();
     } else {
         $content = 'Waiting for action to start';
     }
     return $this->sendResponse($deployment->ResqueStatus(), $content);
 }
コード例 #25
0
ファイル: DNRoot.php プロジェクト: adrexia/deploynaut
 /**
  * Action - Get the latest deploy log
  *
  * @return string
  */
 public function deploylog(SS_HTTPRequest $request)
 {
     $params = $request->params();
     $deployment = DNDeployment::get()->byId($params['Identifier']);
     if (!$deployment || !$deployment->ID) {
         throw new SS_HTTPResponse_Exception('Deployment not found', 404);
     }
     if (!$deployment->canView()) {
         return Security::permissionFailure();
     }
     $environment = $deployment->Environment();
     $project = $environment->Project();
     if ($environment->Name != $params['Environment']) {
         throw new LogicException("Environment in URL doesn't match this deploy");
     }
     if ($project->Name != $params['Project']) {
         throw new LogicException("Project in URL doesn't match this deploy");
     }
     $log = $deployment->log();
     if ($log->exists()) {
         $content = $log->content();
     } else {
         $content = 'Waiting for action to start';
     }
     $sendJSON = strpos($request->getHeader('Accept'), 'application/json') !== false || $request->getExtension() == 'json';
     $content = preg_replace('/(?:(?:\\r\\n|\\r|\\n)\\s*){2}/s', "\n", $content);
     if ($sendJSON) {
         $this->response->addHeader("Content-type", "application/json");
         return json_encode(array('status' => $deployment->ResqueStatus(), 'content' => $content));
     } else {
         $this->response->addHeader("Content-type", "text/plain");
         return $content;
     }
 }