/** * 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\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { if (!$application->hasOption('keepReleases')) { $deployment->getLogger()->log(($deployment->isDryRun() ? 'Would keep' : 'Keeping') . ' all releases for "' . $application->getName() . '"', LOG_DEBUG); return; } $keepReleases = $application->getOption('keepReleases'); $releasesPath = $application->getDeploymentPath() . '/releases'; $currentReleaseIdentifier = $deployment->getReleaseIdentifier(); $previousReleasePath = $application->getDeploymentPath() . '/releases/previous'; $previousReleaseIdentifier = trim($this->shell->execute("if [ -h {$previousReleasePath} ]; then basename `readlink {$previousReleasePath}` ; fi", $node, $deployment)); $allReleasesList = $this->shell->execute("find {$releasesPath}/. -maxdepth 1 -type d -exec basename {} \\;", $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()->log(($deployment->isDryRun() ? 'Would remove' : 'Removing') . ' releases ' . implode(', ', $removeReleases)); $this->shell->executeOrSimulate($removeCommand, $node, $deployment); } else { $deployment->getLogger()->log('No releases to remove', LOG_DEBUG); } }
/** * Executes this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $releaseIdentifier = $deployment->getReleaseIdentifier(); $releasesPath = $application->getDeploymentPath() . '/releases'; $this->shell->executeOrSimulate('cd ' . $releasesPath . ' && rm -f ./previous && if [ -e ./current ]; then mv ./current ./previous; fi && ln -s ./' . $releaseIdentifier . ' ./current', $node, $deployment); $deployment->getLogger()->log('Node "' . $node->getName() . '" ' . ($deployment->isDryRun() ? 'would be' : 'is') . ' live!'); }
/** * Executes this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $releaseIdentifier = $deployment->getReleaseIdentifier(); $releasesPath = $application->getDeploymentPath() . '/releases'; $commands = array("mkdir -p {$releasesPath}/{$releaseIdentifier}/Data", "cd {$releasesPath}/{$releaseIdentifier}", "ln -sf ../../../shared/Data/Logs ./Data/Logs", "ln -sf ../../../shared/Data/Persistent ./Data/Persistent"); $this->shell->executeOrSimulate($commands, $node, $deployment); }
/** * Simulate this task * * @param Node $node * @param Application $application * @param Deployment $deployment * @param array $options * @return void */ public function simulate(Node $node, Application $application, Deployment $deployment, array $options = array()) { $this->checkOptionsForValidity($options); $secretFile = isset($options['secretFile']) ? $options['secretFile'] : '/etc/varnish/secret'; $purgeUrl = isset($options['purgeUrl']) ? $options['purgeUrl'] : '.'; $varnishadm = isset($options['varnishadm']) ? $options['varnishadm'] : '/usr/bin/varnishadm'; $this->shell->executeOrSimulate($varnishadm . ' -S ' . $secretFile . ' -T 127.0.0.1:6082 status', $node, $deployment); }
/** * Execute this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $this->checkOptionsForValidity($options); $projectName = $options['sourceforgeProjectName']; $sourceforgeLogin = $options['sourceforgeUserName'] . ',' . $options['sourceforgeProjectName']; $projectDirectory = sprintf('/home/frs/project/%s/%s/%s/%s/%s', substr($projectName, 0, 1), substr($projectName, 0, 2), $projectName, $options['sourceforgePackageName'], $options['version']); $this->shell->executeOrSimulate('rsync -e ssh ' . implode(' ', $options['files']) . ' ' . $sourceforgeLogin . '@frs.sourceforge.net:' . $projectDirectory, $node, $deployment); }
/** * Execute this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $targetPath = $deployment->getApplicationReleasePath($application); $arguments = isset($options['shellUsername']) ? $options['shellUsername'] : '******'; $arguments .= ' ' . (isset($options['webserverUsername']) ? $options['webserverUsername'] : '******'); $arguments .= ' ' . (isset($options['webserverGroupname']) ? $options['webserverGroupname'] : 'www-data'); $this->shell->executeOrSimulate('cd ' . $targetPath . ' && FLOW3_CONTEXT=Production ./flow3 typo3.flow3:core:setfilepermissions ' . $arguments, $node, $deployment); }
/** * Execute this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { if (!$application->hasOption('sitePackageKey')) { throw new \Exception('Missing site package key.', 1312312646); } $targetPath = $deployment->getApplicationReleasePath($application); $sitePackageKey = $application->getOption('sitePackageKey'); $this->shell->executeOrSimulate('cd ' . $targetPath . ' && FLOW3_CONTEXT=Production ./flow3 typo3.typo3:site:import --package-key ' . $sitePackageKey, $node, $deployment); }
/** * Executes this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $deploymentPath = $application->getDeploymentPath(); $sharedPath = $application->getSharedPath(); $result = $this->shell->execute('test -d ' . $deploymentPath, $node, $deployment, TRUE); if ($result === FALSE) { throw new \Exception('Deployment directory "' . $deploymentPath . '" does not exist on ' . $node->getName(), 1311003253); } $this->shell->executeOrSimulate('mkdir -p ' . $deploymentPath . '/releases;mkdir -p ' . $sharedPath, $node, $deployment); }
/** * Execute this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $targetPath = $deployment->getApplicationReleasePath($application); if (!isset($options['tagName'])) { throw new \Exception('tagName not set', 1314186541); } if (!isset($options['description'])) { throw new \Exception('description not set', 1314186553); } $targetPath = $deployment->getApplicationReleasePath($application); $this->shell->executeOrSimulate(sprintf('cd ' . $targetPath . '; git tag -f -a -m "%s" %s', $options['description'], $options['tagName']), $node, $deployment); $this->shell->executeOrSimulate(sprintf('cd ' . $targetPath . '; git submodule foreach \'git tag -f -a -m "%s" %s\'', $options['description'], $options['tagName']), $node, $deployment); }
/** * Execute this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $releasePath = $deployment->getApplicationReleasePath($application); $deploymentPath = $application->getDeploymentPath(); $repositoryUrl = $application->getOption('repositoryUrl'); $sha1 = $this->shell->execute("git ls-remote {$repositoryUrl} master | awk '{print \$1 }'", $node, $deployment, TRUE); if ($sha1 === FALSE) { throw new \Exception('Could not retrieve sha1 of git master'); } $command = strtr("\n\t\t\tif [ -d {$deploymentPath}/cache/localgitclone ];\n\t\t\t\tthen\n\t\t\t\t\tcd {$deploymentPath}/cache/localgitclone\n\t\t\t\t\t&& git fetch -q origin\n\t\t\t\t\t&& git reset -q --hard {$sha1}\n\t\t\t\t\t&& git submodule -q init\n\t\t\t\t\t&& for mod in `git submodule status | awk '{ print \$2 }'`; do git config -f .git/config submodule.\${mod}.url `git config -f .gitmodules --get submodule.\${mod}.url` && echo synced \$mod; done\n\t\t\t\t\t&& git submodule -q sync\n\t\t\t\t\t&& git submodule -q update\n\t\t\t\t\t&& git clean -q -d -x -ff;\n\t\t\t\telse git clone -q {$repositoryUrl} {$deploymentPath}/cache/localgitclone\n\t\t\t\t\t&& cd {$deploymentPath}/cache/localgitclone\n\t\t\t\t\t&& git checkout -q -b deploy {$sha1}\n\t\t\t\t\t&& git submodule -q init\n\t\t\t\t\t&& git submodule -q sync\n\t\t\t\t\t&& git submodule -q update;\n\t\t\t\tfi\n\t\t", "\t\n", " "); $this->shell->executeOrSimulate($command, $node, $deployment); $command = strtr("\n\t\t\tcp -RPp {$deploymentPath}/cache/localgitclone/ {$releasePath}\n\t\t\t\t&& (echo {$sha1} > {$releasePath}" . "REVISION)\n\t\t\t", "\t\n", " "); $this->shell->executeOrSimulate($command, $node, $deployment); }
/** * Executes this task * * Options: * command: The command to execute * rollbackCommand: The command to execute as a rollback (optional) * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $deploymentPath = $application->getDeploymentPath(); $sharedPath = $application->getSharedPath(); $releasePath = $deployment->getApplicationReleasePath($application); $currentPath = $application->getDeploymentPath() . '/releases/current'; $previousPath = $application->getDeploymentPath() . '/releases/previous'; if (!isset($options['command'])) { throw new \Exception('No command option provided for ShellTask', 1311168045); } $command = $options['command']; $command = str_replace(array('{deploymentPath}', '{sharedPath}', '{releasePath}', '{currentPath}', '{previousPath}'), array($deploymentPath, $sharedPath, $releasePath, $currentPath, $previousPath), $command); $this->shell->executeOrSimulate($command, $node, $deployment); }
/** * Executes this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $targetReleasePath = $deployment->getApplicationReleasePath($application); $username = $node->getOption('username'); $hostname = $node->getHostname(); $configurationPath = $this->getDeploymentConfigurationPath() . '/Configuration/' . $deployment->getName() . '/'; $encryptedConfiguration = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($configurationPath, 'yaml.encrypted'); if (count($encryptedConfiguration) > 0) { throw new \Exception('You have sealed configuration files, please open the configuration for "' . $deployment->getName() . '"', 1317229449); } $configurations = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($configurationPath, 'yaml'); $commands = array(); foreach ($configurations as $configuration) { $targetConfigurationPath = dirname(str_replace($configurationPath, '', $configuration)); $commands[] = "scp {$configuration} {$username}@{$hostname}:{$targetReleasePath}/Configuration/{$targetConfigurationPath}/"; } $localhost = new Node('localhost'); $localhost->setHostname('localhost'); $this->shell->executeOrSimulate($commands, $localhost, $deployment); }
/** * Executes this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $targetReleasePath = $deployment->getApplicationReleasePath($application); $commands = array("cd {$targetReleasePath}/Configuration", "mkdir -p ../../../shared/Configuration/Production", "ln -snf ../../../shared/Configuration/Production Production"); $this->shell->executeOrSimulate($commands, $node, $deployment); }
/** * Execute this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $targetPath = $deployment->getApplicationReleasePath($application); $this->shell->executeOrSimulate('cd ' . $targetPath . ' && phpunit -c Build/Common/PhpUnit/FunctionalTests.xml', $node, $deployment); }
/** * Execute this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $deploymentPath = $application->getDeploymentPath(); $this->shell->executeOrSimulate(array('mkdir -p ' . $deploymentPath . '/shared/Data/Logs', 'mkdir -p ' . $deploymentPath . '/shared/Data/Persistent', 'mkdir -p ' . $deploymentPath . '/shared/Configuration'), $node, $deployment); }
/** * Execute this task * * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $targetPath = $deployment->getApplicationReleasePath($application); $this->shell->executeOrSimulate('cd ' . $targetPath . ' && FLOW3_CONTEXT=Production ./flow3 typo3.flow3:doctrine:migrate', $node, $deployment); }