public function run() { if ($this->getStage() == self::STAGE_DEPLOY || $this->getStage() == self::STAGE_POST_RELEASE) { $defaultDir = 'to'; } else { $defaultDir = 'from'; } $files = $this->getParameter('files', $this->getConfig()->deployment($defaultDir)); if (!$files) { throw new ErrorWithMessageException('No target file(s) for executable given'); } if (is_array($files)) { $files = implode(' ', array_map(function ($dir) { return escapeshellarg($dir); }, $files)); } else { $files = escapeshellarg($files); } $this->runCommand('chmod -f ugo+x ' . $files, $output); Console::log('Result of console call: ' . $output); if (trim($output) !== '') { throw new ErrorWithMessageException($output); } return true; }
public function run() { if ($this->getStage() == self::STAGE_DEPLOY || $this->getStage() == self::STAGE_POST_RELEASE) { $defaultDir = 'to'; } else { $defaultDir = 'from'; } $directory = $this->getParameter('directory', $this->getConfig()->deployment($defaultDir)); if (!$directory) { throw new ErrorWithMessageException('No target directory for chown given'); } if (is_array($directory)) { $directory = implode(' ', array_map(function ($dir) { return escapeshellarg($dir); }, $directory)); } else { $directory = escapeshellarg($directory); } $user = $this->getParameter('user', 'rwX'); $group = $this->getParameter('user', 'rX'); $other = $this->getParameter('user', 'rX'); $command = sprintf('chmod -Rf u=%s,g=%s,o=%s %s', $user, $group, $other, $directory); $response = $this->runCommand($command, $output); Console::log('Result of console call: ' . $output); return $response; }
/** * Runs the task * * @return boolean * @throws Exception * @throws ErrorWithMessageException * @throws SkipException */ public function run() { $this->checkOverrideRelease(); // If we are working with releases $deployToDirectory = $this->getConfig()->deployment('to'); if ($this->getConfig()->release('enabled', false) === true) { $releasesDirectory = $this->getConfig()->release('directory', 'releases'); $symlink = $this->getConfig()->release('symlink', 'public'); $currentRelease = false; $deployToDirectory = rtrim($deployToDirectory, '/') . '/' . $releasesDirectory . '/' . $this->getConfig()->getReleaseId(); Console::log('Deploy to ' . $deployToDirectory); $resultFetch = $this->runCommandRemote('ls -ld ' . $symlink . ' | cut -d"/" -f2', $currentRelease); if ($resultFetch && $currentRelease) { // If deployment configuration is rsync, include a flag to // simply sync the deltas between the prior release $rsync_copy = $this->getConfig()->extras('vcs', 'rsync'); // rsync: { copy: yes } // If copy_tool_rsync, use rsync rather than cp for finer control of what is copied if ($rsync_copy && is_array($rsync_copy) && $rsync_copy['copy'] && $this->runCommandRemote('test -d ' . $releasesDirectory . '/' . $currentRelease)) { if (isset($rsync_copy['copy_tool_rsync'])) { $this->runCommandRemote("rsync -a {$this->excludes(array_merge($excludes, $rsync_copy['rsync_excludes']))} " . "{$releasesDirectory}/{$currentRelease}/ {$releasesDirectory}/{$this->getConfig()->getReleaseId()}"); } else { $this->runCommandRemote('cp -R ' . $releasesDirectory . '/' . $currentRelease . ' ' . $releasesDirectory . '/' . $this->getConfig()->getReleaseId()); } } else { $this->runCommandRemote('mkdir -p ' . $releasesDirectory . '/' . $this->getConfig()->getReleaseId()); } } } $branch = $this->getConfig()->extras('vcs', 'branch', 'master'); $remote = $this->getConfig()->extras('vcs', 'remote', 'origin'); $sharedDirectory = $this->getConfig()->extras('directory', 'top', 'shared'); $cacheDirectory = $this->getConfig()->extras('vcs', 'directory', 'git-remote-cache'); $remoteCacheFolder = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $sharedDirectory . '/' . $cacheDirectory; $this->runCommandRemote('mkdir -p ' . $remoteCacheFolder); // Fetch Remote $command = $this->getGitCacheAwareCommand('git fetch ' . $remote); $result = $this->runCommandRemote($command); if ($result === false) { $repository = $this->getConfig()->extras('vcs', 'repository'); if ($repository) { $command = $this->getGitCacheAwareCommand('git clone --mirror ' . $repository . ' .'); $result = $this->runCommandRemote($command); $command = $this->getGitCacheAwareCommand('git fetch ' . $remote); $result = $this->runCommandRemote($command); } } // Archive Remote $command = $this->getGitCacheAwareCommand('git archive ' . $branch . ' | tar -x -C ' . $deployToDirectory); $result = $this->runCommandRemote($command) && $result; return $result; }
public function run() { if ($this->getParameter('copyEntryPoint')) { $command = sprintf('cd %s && cp typo3conf/ext/typo3_console/Scripts/typo3cms .', $this->getConfig()->deployment('document-root')); $this->runCommandRemote($command, $output, false); } $command = $this->getParameter('command'); if (empty($command)) { throw new ErrorWithMessageException('No command given! Use something like "typo3-console: {command: backend:lock}" '); } $command = sprintf('cd %s && %s ./typo3cms %s', $this->getConfig()->deployment('document-root'), $this->getParameter('php', ''), $command); $response = $this->runCommandRemote($command, $output, false); Console::log('Result of console call: ' . $response); return true; }
/** * Syncs the Local Code to the Remote Host * * @return boolean * @throws Exception * @throws ErrorWithMessageException * @throws SkipException */ public function run() { $this->checkOverrideRelease(); $excludes = $this->getExcludes(); $excludesListFilePath = $this->getConfig()->deployment('excludes_file', ''); // If we are working with releases $deployToDirectory = $this->getConfig()->deployment('to'); if ($this->getConfig()->release('enabled', false) === true) { $releasesDirectory = $this->getConfig()->release('directory', 'releases'); $symlink = $this->getConfig()->release('symlink', 'current'); $currentRelease = false; $deployToDirectory = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $releasesDirectory . '/' . $this->getConfig()->getReleaseId(); Console::log('Deploy to ' . $deployToDirectory); $resultFetch = $this->runCommandRemote('ls -ld ' . $symlink . ' | cut -d"/" -f2', $currentRelease); if ($resultFetch && $currentRelease) { // If deployment configuration is rsync, include a flag to simply sync the deltas between the prior release // rsync: { copy: yes } $rsync_copy = $this->getConfig()->deployment('rsync'); // If copy_tool_rsync, use rsync rather than cp for finer control of what is copied if ($rsync_copy && is_array($rsync_copy) && $rsync_copy['copy'] && $this->runCommandRemote('test -d ' . $releasesDirectory . '/' . $currentRelease)) { if (isset($rsync_copy['copy_tool_rsync'])) { $this->runCommandRemote("rsync -a {$this->excludes(array_merge($excludes, $rsync_copy['rsync_excludes']))} " . "{$releasesDirectory}/{$currentRelease}/ {$releasesDirectory}/{$this->getConfig()->getReleaseId()}"); } else { $this->runCommandRemote('cp -R ' . $releasesDirectory . '/' . $currentRelease . ' ' . $releasesDirectory . '/' . $this->getConfig()->getReleaseId()); } } else { $this->runCommandRemote('mkdir -p ' . $releasesDirectory . '/' . $this->getConfig()->getReleaseId()); } } } // Strategy Flags $defaultFlags = $this->getConfig()->general('strategy_flags', array()); $strategyFlags = $this->getConfig()->deployment('strategy_flags', $defaultFlags); if (isset($strategyFlags['rsync'])) { $strategyFlags = $strategyFlags['rsync']; } else { $strategyFlags = ''; } $command = 'rsync -aHAXxv --numeric-ids --delete -e ' . $strategyFlags . ' ' . '"ssh -T -o Compression=no -x" ' . $this->excludes($excludes) . ' ' . $this->excludesListFile($excludesListFilePath) . ' ' . $this->getConfig()->deployment('from') . ' ' . ($this->getConfig()->deployment('user') ? $this->getConfig()->deployment('user') . '@' : '') . $this->getConfig()->getHostName() . ':' . $deployToDirectory; $result = $this->runCommandLocal($command); return $result; }
/** * Deletes tempory folder and project file * if 'keeptemp' is set then skips delete * process * * @throws ErrorWithMessageException If there was a problem with deleting the tempory files * * @return void */ private function deleteTmpFiles() { if (isset($this->mageConfig['keeptemp'])) { return; } Console::log('Deleting tempory files :', 1); $ret1 = Console::executeCommand('rm -Rf ' . $this->ionSource, $out1); $ret2 = Console::executeCommand('rm ' . $this->projectFile, $out2); if ($ret1 && $ret2) { return; } throw new ErrorWithMessageException('Error deleting temp files :' . $out1 . ' : ' . $out2, 40); }
/** * Releases a Deployment: points the current symbolic link to the release directory * @see \Mage\Task\AbstractTask::run() */ public function run() { $resultFetch = false; if ($this->getConfig()->release('enabled', false) === true) { $releasesDirectory = $this->getConfig()->release('directory', 'releases'); $symlink = $this->getConfig()->release('symlink', 'current'); if (substr($symlink, 0, 1) == '/') { $releasesDirectory = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $releasesDirectory; } $releaseId = $this->getConfig()->getReleaseId(); $currentCopy = $releasesDirectory . '/' . $releaseId; //Check if target user:group is specified $userGroup = $this->getConfig()->deployment('owner'); // Fetch the user and group from base directory; defaults usergroup to 33:33 if (empty($userGroup)) { $user = '******'; $group = '33'; $directoryInfos = ''; // Get raw directory info and parse it in php. // "stat" command don't behave the same on different systems, ls output format also varies // and awk parameters need special care depending on the executing shell $resultFetch = $this->runCommandRemote("ls -ld .", $directoryInfos); if (!empty($directoryInfos)) { //uniformize format as it depends on the system deployed on $directoryInfos = trim(str_replace(array(" ", "\t"), ' ', $directoryInfos)); $infoArray = explode(' ', $directoryInfos); if (!empty($infoArray[2])) { $user = $infoArray[2]; } if (!empty($infoArray[3])) { $group = $infoArray[3]; } $userGroup = $user . ':' . $group; } } if ($resultFetch && $userGroup != '') { $command = 'chown -R ' . $userGroup . ' ' . $currentCopy . ' && ' . 'chown ' . $userGroup . ' ' . $releasesDirectory; $result = $this->runCommandRemote($command); if (!$result) { return $result; } } // Switch symlink and change owner $tmplink = $symlink . '.tmp'; // Check if this is a bloody Magento project which follow Vuelo rules if ($this->getConfig()->extras('magento', 'enabled', false) === true) { Console::log('Re-deploy Octopius Magento source code structure to ServerPilot structure.'); $command = "ln -sfn {$currentCopy}/public {$tmplink}"; } else { $command = "ln -sfn {$currentCopy} {$tmplink}"; } if ($resultFetch && $userGroup != '') { $command .= " && chown -h {$userGroup} {$tmplink}"; } $command .= " && mv -fT {$tmplink} {$symlink}"; $result = $this->runCommandRemote($command); if ($result) { $this->cleanUpReleases(); } return $result; } else { return false; } }
/** * Runs a Shell Command on the Remote Host * * @param string $command * @param string $output * @param boolean $cdToDirectoryFirst * @return boolean */ protected final function runCommandRemote($command, &$output = null, $cdToDirectoryFirst = true) { if ($this->getConfig()->release('enabled', false) === true) { if ($this instanceof IsReleaseAware) { $releasesDirectory = ''; } else { $releasesDirectory = '/' . $this->getConfig()->release('directory', 'releases') . '/' . $this->getConfig()->getReleaseId(); } } else { $releasesDirectory = ''; } // if general.yml includes "ssy_needs_tty: true", then add "-t" to the ssh command $needs_tty = $this->getConfig()->general('ssh_needs_tty', false) ? '-t' : ''; $localCommand = 'ssh ' . $this->getConfig()->getHostIdentityFileOption() . $needs_tty . ' -p ' . $this->getConfig()->getHostPort() . ' ' . '-q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' . $this->getConfig()->getConnectTimeoutOption() . ($this->getConfig()->deployment('user') != '' ? $this->getConfig()->deployment('user') . '@' : '') . $this->getConfig()->getHostName(); $remoteCommand = str_replace('"', '\\"', $command); if ($cdToDirectoryFirst) { $remoteCommand = 'cd ' . rtrim($this->getConfig()->deployment('to'), '/') . $releasesDirectory . ' && ' . $remoteCommand; } $localCommand .= ' ' . '"sh -c \\"' . $remoteCommand . '\\""'; Console::log('Run remote command ' . $remoteCommand); return $this->runCommandLocal($localCommand, $output); }
/** * Execute delta. * Ignores empty files. * * @param string $delta * Path to SQL file to be executed * @param $db The * database object * @param string $lastDeltaFile * Path to file to save delta path on success * @return bool True if SQL execution returned no errors. */ protected function executeSQL($delta, $db, $lastDeltaFile) { Console::log('Executing delta: ' . $delta); // Get content $sql = file_get_contents($delta); // Parse any placeholders $sql = $this->parsePlaceHolders($sql, $this->getParameter('placeholders', array())); // Checking that the sql file isn't empty $sql = trim($sql); if ($sql == "") { Console::log("---------------------------------"); Console::log('Warning: Ignoring empty file: ' . $delta); Console::log("---------------------------------"); } else { // Execute Script From PHP $stmt = $db->prepare($sql); if ($stmt->execute()) { // Save last delta path to file system file_put_contents($lastDeltaFile, $delta); } else { Console::log("---------------------------------"); Console::log('Error executing delta: ' . $delta); Console::log("---------------------------------"); Console::log("SQL error code " . $stmt->errorInfo()[0] . " ::: Driver error code " . $stmt->errorInfo()[1] . " ::: " . $stmt->errorInfo()[2]); Console::log("---------------------------------"); return false; } } return true; }