Example #1
0
 /**
  * Cleanup old releases by listing all releases and keeping a configurable
  * number of old releases (application option "keepReleases"). The current
  * and previous release (if one exists) are protected from removal.
  *
  * Example configuration:
  *
  *     $application->setOption('keepReleases', 2);
  *
  * Note: There is no rollback for this cleanup, so we have to be sure not to delete any
  *       live or referenced releases.
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @return void
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     if (!isset($options['keepReleases'])) {
         $deployment->getLogger()->debug(($deployment->isDryRun() ? 'Would keep' : 'Keeping') . ' all releases for "' . $application->getName() . '"');
         return;
     }
     $keepReleases = $options['keepReleases'];
     $releasesPath = $application->getReleasesPath();
     $currentReleaseIdentifier = $deployment->getReleaseIdentifier();
     $previousReleasePath = $application->getReleasesPath() . '/previous';
     $previousReleaseIdentifier = trim($this->shell->execute("if [ -h {$previousReleasePath} ]; then basename `readlink {$previousReleasePath}` ; fi", $node, $deployment));
     $allReleasesList = $this->shell->execute("if [ -d {$releasesPath}/. ]; then find {$releasesPath}/. -maxdepth 1 -type d -exec basename {} \\; ; fi", $node, $deployment);
     $allReleases = preg_split('/\\s+/', $allReleasesList, -1, PREG_SPLIT_NO_EMPTY);
     $removableReleases = array();
     foreach ($allReleases as $release) {
         if ($release !== '.' && $release !== $currentReleaseIdentifier && $release !== $previousReleaseIdentifier && $release !== 'current' && $release !== 'previous') {
             $removableReleases[] = trim($release);
         }
     }
     sort($removableReleases);
     $removeReleases = array_slice($removableReleases, 0, count($removableReleases) - $keepReleases);
     $removeCommand = '';
     foreach ($removeReleases as $removeRelease) {
         $removeCommand .= "rm -rf {$releasesPath}/{$removeRelease};rm -f {$releasesPath}/{$removeRelease}REVISION;";
     }
     if (count($removeReleases) > 0) {
         $deployment->getLogger()->info(($deployment->isDryRun() ? 'Would remove' : 'Removing') . ' releases ' . implode(', ', $removeReleases));
         $this->shell->executeOrSimulate($removeCommand, $node, $deployment);
     } else {
         $deployment->getLogger()->info('No releases to remove');
     }
 }
Example #2
0
 /**
  * Execute this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @return void
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  * @throws \TYPO3\Surf\Exception\TaskExecutionException
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     if (!isset($options['repositoryUrl'])) {
         throw new \TYPO3\Surf\Exception\InvalidConfigurationException(sprintf('Missing "repositoryUrl" option for application "%s"', $application->getName()), 1374074052);
     }
     $localCheckoutPath = $deployment->getWorkspacePath($application);
     $node = $deployment->getNode('localhost');
     $sha1 = $this->executeOrSimulateGitCloneOrUpdate($localCheckoutPath, $node, $deployment, $options);
     $this->executeOrSimulatePostGitCheckoutCommands($localCheckoutPath, $sha1, $node, $deployment, $options);
 }
Example #3
0
 /**
  * Execute a task
  *
  * @param string $taskName
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param string $stage
  * @param array $options Local task options
  * @return void
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  */
 public function execute($taskName, Node $node, Application $application, Deployment $deployment, $stage, array $options = array())
 {
     $deployment->getLogger()->info($node->getName() . ' (' . $application->getName() . ') ' . $taskName);
     $task = $this->createTaskInstance($taskName);
     $globalOptions = $this->overrideOptions($taskName, $deployment, $node, $application, $options);
     if (!$deployment->isDryRun()) {
         $task->execute($node, $application, $deployment, $globalOptions);
     } else {
         $task->simulate($node, $application, $deployment, $globalOptions);
     }
     $this->taskHistory[] = array('task' => $task, 'node' => $node, 'application' => $application, 'deployment' => $deployment, 'stage' => $stage, 'options' => $globalOptions);
 }
Example #4
0
 /**
  * @param Application $application
  * @return string
  */
 public function getWorkspacePath(Application $application)
 {
     $workspacePath = FLOW_PATH_DATA . 'Surf/';
     if ($application->hasOption('repositoryUrl')) {
         $urlParts = GeneralUtility::getUrlPartsFromRepositoryUrl($application->getOption('repositoryUrl'));
         $workspacePath .= preg_replace('/[^a-zA-Z0-9]/', '-', $urlParts['path']);
         $workspacePath .= '_' . substr(sha1($application->getOption('repositoryUrl')), 0, 5);
     } else {
         // Default
         $workspacePath .= $this->getName() . '/' . $application->getName();
     }
     return $workspacePath;
 }
 /**
  * Executes this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @return void
  * @throws TaskExecutionException
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $targetPath = isset($options['deploymentLogTargetPath']) ? $options['deploymentLogTargetPath'] : '.';
     $fileName = !empty($options['deploymentLogFileName']) ? $options['deploymentLogFileName'] : 'deployment.log';
     $optionsToLog = !empty($options['deploymentLogOptions']) ? $options['deploymentLogOptions'] : array('tag', 'branch', 'sha1');
     $logContent = array(date('Y-m-d H:i:s (D)'), 'Application: ' . $application->getName(), 'Deployment: ' . $deployment->getName(), 'Status: ' . $deployment->getStatus());
     foreach ($optionsToLog as $key) {
         if (!empty($options[$key])) {
             $logContent[] = $key . ' = ' . $options[$key];
         }
     }
     $commands = array('cd ' . escapeshellarg($application->getReleasesPath()), 'echo ' . escapeshellarg(implode(' | ', $logContent)) . ' >> ' . rtrim($targetPath, '/') . '/' . $fileName);
     $this->shell->executeOrSimulate($commands, $node, $deployment);
 }
Example #6
0
    /**
     * Execute this task
     *
     * @param \TYPO3\Surf\Domain\Model\Node $node
     * @param \TYPO3\Surf\Domain\Model\Application $application
     * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
     * @param array $options
     * @return void
     * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
     * @throws \TYPO3\Surf\Exception\TaskExecutionException
     */
    public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
    {
        if (!isset($options['repositoryUrl'])) {
            throw new \TYPO3\Surf\Exception\InvalidConfigurationException(sprintf('Missing "repositoryUrl" option for application "%s"', $application->getName()), 1335974764);
        }
        $releasePath = $deployment->getApplicationReleasePath($application);
        $checkoutPath = $application->getDeploymentPath() . '/cache/transfer';
        if (!isset($options['hardClean'])) {
            $options['hardClean'] = true;
        }
        $sha1 = $this->executeOrSimulateGitCloneOrUpdate($checkoutPath, $node, $deployment, $options);
        $command = strtr("\n\t\t\tcp -RPp {$checkoutPath}/. {$releasePath}\n\t\t\t\t&& (echo {$sha1} > {$releasePath}" . 'REVISION)
			', "\t\n", '  ');
        $this->shell->executeOrSimulate($command, $node, $deployment);
        $this->executeOrSimulatePostGitCheckoutCommands($releasePath, $sha1, $node, $deployment, $options);
    }
Example #7
0
 /**
  * Get a local workspace directory for the application
  */
 public function getWorkspacePath(Application $application)
 {
     return $this->workspacesBasePath . '/' . $this->getName() . '/' . $application->getName();
 }
Example #8
0
 /**
  * Execute a task and consider configured before / after "hooks"
  *
  * Will also execute tasks that are registered to run before or after this task.
  *
  * @param string $task
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param string $stage
  * @param array $callstack
  * @return void
  * @throws \TYPO3\Surf\Exception\TaskExecutionException
  */
 protected function executeTask($task, Node $node, Application $application, Deployment $deployment, $stage, array &$callstack = array())
 {
     foreach (array('_', $application->getName()) as $applicationName) {
         if (isset($this->tasks['before'][$applicationName][$task])) {
             foreach ($this->tasks['before'][$applicationName][$task] as $beforeTask) {
                 $deployment->getLogger()->debug('Task "' . $beforeTask . '" before "' . $task);
                 $this->executeTask($beforeTask, $node, $application, $deployment, $stage, $callstack);
             }
         }
     }
     if (isset($callstack[$task])) {
         throw new \TYPO3\Surf\Exception\TaskExecutionException('Cycle for task "' . $task . '" detected, aborting.', 1335976544);
     }
     if (isset($this->tasks['defined'][$task])) {
         $this->taskManager->execute($this->tasks['defined'][$task]['task'], $node, $application, $deployment, $stage, $this->tasks['defined'][$task]['options'], $task);
     } else {
         $this->taskManager->execute($task, $node, $application, $deployment, $stage);
     }
     $callstack[$task] = true;
     foreach (array('_', $application->getName()) as $applicationName) {
         $label = $applicationName === '_' ? 'for all' : 'for application ' . $applicationName;
         if (isset($this->tasks['after'][$applicationName][$task])) {
             foreach ($this->tasks['after'][$applicationName][$task] as $beforeTask) {
                 $deployment->getLogger()->debug('Task "' . $beforeTask . '" after "' . $task . '" ' . $label);
                 $this->executeTask($beforeTask, $node, $application, $deployment, $stage, $callstack);
             }
         }
     }
 }
 /**
  * @param \TYPO3\Surf\Domain\Model\Application $application
  *
  * @return void
  *
  * @throws TaskExecutionException
  */
 protected function setRemoteNode(Application $application)
 {
     $this->requireApplication(__METHOD__);
     $nodes = $application->getNodes();
     if (count($nodes) < 1) {
         throw new TaskExecutionException("There is no node is set for application '{$application->getName()}'. Please check your TYPO3/Surf configuration.");
     }
     $this->remoteNode = array_shift($nodes);
 }
Example #10
0
 /**
  * Prints stages and contained tasks for given application
  *
  * @param Application $application
  * @param array $stages
  * @param array $tasks
  */
 protected function printStages(Application $application, array $stages, array $tasks)
 {
     foreach ($stages as $stage) {
         $this->output->writeln('      <comment>' . $stage . ':</comment>');
         foreach (['before', 'tasks', 'after'] as $stageStep) {
             $output = '';
             foreach (['_', $application->getName()] as $applicationName) {
                 $label = $applicationName === '_' ? 'for all applications' : 'for application ' . $applicationName;
                 if (isset($tasks['stage'][$applicationName][$stage][$stageStep])) {
                     foreach ($tasks['stage'][$applicationName][$stage][$stageStep] as $task) {
                         $output .= '          <success>' . $task . '</success> <info>(' . $label . ')</info>' . PHP_EOL;
                     }
                 }
             }
             if (strlen($output) > 0) {
                 $this->output->writeln('        <info>' . $stageStep . ':</info>');
             }
             $this->output->write($output);
         }
     }
 }