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; }
/** * Rollback a release * @see \Mage\Command\AbstractCommand::run() */ public function run() { $exitCode = 450; $releaseId = $this->getConfig()->getArgument(1); if (!is_numeric($releaseId)) { Console::output('<red>This release is mandatory.</red>', 1, 2); return 451; } $lockFile = getcwd() . '/.mage/' . $this->getConfig()->getEnvironment() . '.lock'; if (file_exists($lockFile)) { Console::output('<red>This environment is locked!</red>', 1, 2); echo file_get_contents($lockFile); return 20; } // Run Tasks for Deployment $hosts = $this->getConfig()->getHosts(); if (count($hosts) == 0) { Console::output('<light_purple>Warning!</light_purple> <dark_gray>No hosts defined, unable to get releases.</dark_gray>', 1, 3); } else { $result = true; foreach ($hosts as $host) { $this->getConfig()->setHost($host); $this->getConfig()->setReleaseId($releaseId); $task = Factory::get('releases/rollback', $this->getConfig()); $task->init(); $result = $task->run() && $result; } if ($result) { $exitCode = 0; } } return $exitCode; }
/** * Command for Initalize a new Configuration Proyect * @see \Mage\Command\AbstractCommand::run() */ public function run() { $exitCode = 50; $configDir = getcwd() . '/.mage'; Console::output('Initiating managing process for application with <bold>Magallanes</bold>'); // Check if there is already a config dir if (file_exists($configDir)) { Console::output('<light_red>Error!!</light_red> Already exists <bold>.mage</bold> directory.', 1, 2); } else { $results = array(); $results[] = mkdir($configDir); $results[] = mkdir($configDir . '/logs'); $results[] = file_put_contents($configDir . '/logs/.gitignore', "*\n!.gitignore"); $results[] = mkdir($configDir . '/tasks'); $results[] = touch($configDir . '/tasks/.gitignore'); $results[] = mkdir($configDir . '/config'); $results[] = mkdir($configDir . '/config/environment'); $results[] = touch($configDir . '/config/environment/.gitignore'); $results[] = file_put_contents($configDir . '/config/general.yml', $this->getGeneralConfig()); if (!in_array(false, $results)) { Console::output('<light_green>Success!!</light_green> The configuration for <bold>Magallanes</bold> has been generated at <blue>.mage</blue> directory.'); Console::output('<bold>Please!! Review and adjust the configuration.</bold>', 2, 2); $exitCode = 0; } else { Console::output('<light_red>Error!!</light_red> Unable to generate the configuration.', 1, 2); } return $exitCode; } }
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; }
/** * Clones a Repository * * @see \Mage\Task\AbstractTask::run() */ public function run() { $from = $this->getConfig()->deployment('from'); // Clone Repo form Branch $commands = ['rm -fr ' . $from, 'mkdir -p ' . $from, 'cd ' . $from, 'git clone -b ' . $this->branch . ' ' . $this->repo . ' ./']; Console::output('Repo: (' . $this->branch . ')' . $this->repo, 1, 2); return $this->runCommand(implode(' && ', $commands)); }
/** * Unlocks an Environment * @see \Mage\Command\AbstractCommand::run() */ public function run() { $lockFile = getcwd() . '/.mage/' . $this->getConfig()->getEnvironment() . '.lock'; if (file_exists($lockFile)) { @unlink($lockFile); } Console::output('Unlocked deployment to <light_purple>' . $this->getConfig()->getEnvironment() . '</light_purple> environment', 1, 2); return 0; }
/** * @see \Mage\Compile::compile() */ public function run() { if (ini_get('phar.readonly')) { Console::output('The <purple>php.ini</purple> variable <light_red>phar.readonly</light_red>' . ' must be <yellow>Off</yellow>.', 1, 2); return 200; } $this->compiler->compile(); Console::output('<light_purple>mage.phar</light_purple> compiled <light_green>successfully</light_green>', 0, 2); return 0; }
/** * Command for Upgrading Magallanes * @see \Mage\Command\BuiltIn\InstallCommand::run() */ public function run() { $exitCode = 99; Console::output('Upgrading <bold>Magallanes</bold> ... ', 1, 0); $user = ''; // Check if user is root Console::executeCommand('whoami', $user); $owner = posix_getpwuid(fileowner(__FILE__)); $owner = $owner['name']; if ($user != 'root' && $user != $owner) { Console::output('<red>FAIL</red>', 0, 1); Console::output('You need to be the <bold>' . $owner . '</bold> user to perform the upgrade, or <bold>root</bold>.', 2); } else { // Check version $version = json_decode(file_get_contents(self::UPGRADE)); if ($version !== false && $version !== null) { $versionCompare = version_compare(MAGALLANES_VERSION, $version->latest); if ($versionCompare == 0) { Console::output('<yellow>SKIP</yellow>', 0, 1); Console::output('Your current version is up to date.', 2); $exitCode = 0; } elseif ($versionCompare == 1) { Console::output('<yellow>SKIP</yellow>', 0, 1); Console::output('Your current version is newer.', 2); $exitCode = 0; } elseif ($versionCompare == -1) { // Download Package $tarball = file_get_contents(str_replace('{version}', $version->latest, self::DOWNLOAD)); if ($tarball === false) { Console::output('<red>FAIL</red>', 0, 1); Console::output('Corrupted download.', 2); } else { $tarballFile = tempnam('/tmp', 'magallanes_download'); rename($tarballFile, $tarballFile . '.tar.gz'); $tarballFile .= '.tar.gz'; file_put_contents($tarballFile, $tarball); Console::executeCommand('rm -rf ' . MAGALLANES_DIRECTORY); Console::executeCommand('cd ' . dirname($tarballFile) . ' && tar xfz ' . $tarballFile); Console::executeCommand('mv ' . dirname($tarballFile) . '/magallanes ' . MAGALLANES_DIRECTORY); Console::output('<green>OK</green>', 0, 1); $exitCode = 0; } } else { Console::output('<red>FAIL</red>', 0, 1); Console::output('Invalid version.', 2); } } else { Console::output('<red>FAIL</red>', 0, 1); Console::output('Invalid version.', 2); } } return $exitCode; }
/** * 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; }
/** * @return boolean */ public function run() { $from = $this->getConfig()->deployment('from'); if (!($command = $this->getParameter('command'))) { throw new RequiredConfigNotFoundException('Missing required phing command.'); } // Update repo form Branch $commands[] = 'cd ' . $from; $commands[] = 'phing ' . $command; $result = $this->runCommand(implode(' ; ', $commands), $output); Console::output($output, 1, 2); return $result; }
/** * List the Releases, Rollback to a Release * @see \Mage\Command\AbstractCommand::run() */ public function run() { $exitCode = 100; $subCommand = $this->getConfig()->getArgument(1); // Run Tasks for Deployment $hosts = $this->getConfig()->getHosts(); if (count($hosts) == 0) { Console::output('<light_purple>Warning!</light_purple> <bold>No hosts defined, unable to get releases.</bold>', 1, 3); return 101; } $result = true; foreach ($hosts as $hostKey => $host) { // Check if Host has specific configuration $hostConfig = null; if (is_array($host)) { $hostConfig = $host; $host = $hostKey; } // Set Host and Host Specific Config $this->getConfig()->setHost($host); $this->getConfig()->setHostConfig($hostConfig); switch ($subCommand) { case 'list': $task = Factory::get('releases/list', $this->getConfig()); $task->init(); $result = $task->run() && $result; break; case 'rollback': if (!is_numeric($this->getConfig()->getParameter('release', ''))) { Console::output('<red>Missing required releaseid.</red>', 1, 2); return 102; } $lockFile = getcwd() . '/.mage/' . $this->getConfig()->getEnvironment() . '.lock'; if (file_exists($lockFile)) { Console::output('<red>This environment is locked!</red>', 1, 2); echo file_get_contents($lockFile); return 103; } $releaseId = $this->getConfig()->getParameter('release', ''); $this->getConfig()->setReleaseId($releaseId); $task = Factory::get('releases/rollback', $this->getConfig()); $task->init(); $result = $task->run() && $result; break; } } if ($result) { $exitCode = 0; } return $exitCode; }
/** * Updates the SCM Base Code * @see \Mage\Command\AbstractCommand::run() */ public function run() { $exitCode = 200; $task = Factory::get('scm/update', $this->getConfig()); $task->init(); Console::output('Updating application via ' . $task->getName() . ' ... ', 1, 0); $result = $task->run(); if ($result === true) { Console::output('<green>OK</green>' . PHP_EOL, 0); $exitCode = 0; } else { Console::output('<red>FAIL</red>' . PHP_EOL, 0); } return $exitCode; }
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 && ./typo3cms %s', $this->getConfig()->deployment('document-root'), $command); $response = $this->runCommandRemote($command, $output, false); Console::output('Result of console call: ' . $response); return true; }
/** * List the Releases, Rollback to a Release * @see \Mage\Command\AbstractCommand::run() */ public function run() { $exitCode = 400; $subCommand = $this->getConfig()->getArgument(1); // Run Tasks for Deployment $hosts = $this->getConfig()->getHosts(); if (count($hosts) == 0) { Console::output('<light_purple>Warning!</light_purple> <dark_gray>No hosts defined, unable to get releases.</dark_gray>', 1, 3); return 401; } $result = true; foreach ($hosts as $host) { $this->getConfig()->setHost($host); switch ($subCommand) { case 'list': $task = Factory::get('releases/list', $this->getConfig()); $task->init(); $result = $task->run() && $result; break; case 'rollback': if (!is_numeric($this->getConfig()->getParameter('release', ''))) { Console::output('<red>Missing required releaseid.</red>', 1, 2); return 410; } $lockFile = getcwd() . '/.mage/' . $this->getConfig()->getEnvironment() . '.lock'; if (file_exists($lockFile)) { Console::output('<red>This environment is locked!</red>', 1, 2); echo file_get_contents($lockFile); return 420; } $releaseId = $this->getConfig()->getParameter('release', ''); $this->getConfig()->setReleaseId($releaseId); $task = Factory::get('releases/rollback', $this->getConfig()); $task->init(); $result = $task->run() && $result; break; } } if ($result) { $exitCode = 0; } return $exitCode; }
/** * 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; }
/** * Installs Magallanes * @see \Mage\Command\AbstractCommand::run() */ public function run() { $exitCode = 88; Console::output('Installing <dark_gray>Magallanes</dark_gray>... ', 1, 0); // Vars $installDir = $this->getConfig()->getParameter('installDir', '/opt/magallanes'); $systemWide = $this->getConfig()->getParameter('systemWide', false); // Clean vars $baseDir = realpath(dirname($installDir)); $installDir = basename($installDir); // Check if install dir is available if (!is_dir($baseDir) || !is_writable($baseDir)) { Console::output('<red>Failure: install directory is invalid.</red>', 0, 2); // Chck if it is a system wide install the user is root } else { if ($systemWide && getenv('LOGNAME') != 'root') { Console::output('<red>Failure: you have to be root to perform a system wide install.</red>', 0, 2); } else { $destinationDir = $baseDir . '/' . $installDir; if (!is_dir($destinationDir)) { mkdir($destinationDir); } // Copy $this->recursiveCopy(MAGALLANES_DIRECTORY, $destinationDir . '/' . MAGALLANES_VERSION); // Check if there is already a symlink if (file_exists($destinationDir . '/' . 'latest') && is_link($destinationDir . '/' . 'latest')) { unlink($destinationDir . '/' . 'latest'); } // Create "latest" symlink symlink($destinationDir . '/' . MAGALLANES_VERSION, $destinationDir . '/' . 'latest'); chmod($destinationDir . '/' . MAGALLANES_VERSION . '/bin/mage', 0755); if ($systemWide) { if (!file_exists('/usr/bin/mage')) { symlink($destinationDir . '/latest/bin/mage', '/usr/bin/mage'); } } Console::output('<light_green>Success!</light_green>', 0, 2); $exitCode = 0; } } return $exitCode; }
/** * Rollback a release * @see \Mage\Command\AbstractCommand::run() */ public function run() { $exitCode = 105; $releaseId = $this->getConfig()->getArgument(1); if (!is_numeric($releaseId)) { Console::output('<red>This release is mandatory.</red>', 1, 2); return 104; } $lockFile = getcwd() . '/.mage/' . $this->getConfig()->getEnvironment() . '.lock'; if (file_exists($lockFile)) { Console::output('<red>This environment is locked!</red>', 1, 2); echo file_get_contents($lockFile); return 106; } // Run Tasks for Deployment $hosts = $this->getConfig()->getHosts(); if (count($hosts) == 0) { Console::output('<light_purple>Warning!</light_purple> <bold>No hosts defined, unable to get releases.</bold>', 1, 3); } else { $result = true; foreach ($hosts as $hostKey => $host) { // Check if Host has specific configuration $hostConfig = null; if (is_array($host)) { $hostConfig = $host; $host = $hostKey; } // Set Host and Host Specific Config $this->getConfig()->setHost($host); $this->getConfig()->setHostConfig($hostConfig); $this->getConfig()->setReleaseId($releaseId); $task = Factory::get('releases/rollback', $this->getConfig()); $task->init(); $result = $task->run() && $result; } if ($result) { $exitCode = 0; } } return $exitCode; }
/** * Adds an Environment * * @throws Exception */ protected function addEnvironment() { $withReleases = $this->getConfig()->getParameter('enableReleases', false); $environmentName = strtolower($this->getConfig()->getParameter('name')); if ($environmentName == '') { throw new Exception('You must specify a name for the environment.'); } $environmentConfigFile = getcwd() . '/.mage/config/environment/' . $environmentName . '.yml'; if (file_exists($environmentConfigFile)) { throw new Exception('The environment already exists.'); } Console::output('Adding new environment: <bold>' . $environmentName . '</bold>'); $releasesConfig = 'releases:' . PHP_EOL . ' enabled: true' . PHP_EOL . ' max: 10' . PHP_EOL . ' symlink: current' . PHP_EOL . ' directory: releases' . PHP_EOL; $baseConfig = '#' . $environmentName . PHP_EOL . 'deployment:' . PHP_EOL . ' user: dummy' . PHP_EOL . ' from: ./' . PHP_EOL . ' to: /var/www/vhosts/example.com/www' . PHP_EOL . ' excludes:' . PHP_EOL . ($withReleases ? $releasesConfig : '') . 'hosts:' . PHP_EOL . 'tasks:' . PHP_EOL . ' pre-deploy:' . PHP_EOL . ' on-deploy:' . PHP_EOL . ($withReleases ? ' post-release:' . PHP_EOL : '') . ' post-deploy:' . PHP_EOL; $result = file_put_contents($environmentConfigFile, $baseConfig); if ($result) { Console::output('<light_green>Success!!</light_green> Environment config file for <bold>' . $environmentName . '</bold> created successfully at <blue>' . $environmentConfigFile . '</blue>'); Console::output('<bold>So please! Review and adjust its configuration.</bold>', 2, 2); } else { Console::output('<light_red>Error!!</light_red> Unable to create config file for environment called <bold>' . $environmentName . '</bold>', 1, 2); } }
/** * List the Available Releases on an Environment * @see \Mage\Task\AbstractTask::run() */ public function run() { if ($this->getConfig()->release('enabled', false) == true) { $releasesDirectory = $this->getConfig()->release('directory', 'releases'); $symlink = $this->getConfig()->release('symlink', 'current'); Console::output('Releases available on <dark_gray>' . $this->getConfig()->getHost() . '</dark_gray>'); // Get Releases $output = ''; $result = $this->runCommandRemote('ls -1 ' . $releasesDirectory, $output); $releases = $output == '' ? array() : explode(PHP_EOL, $output); // Get Current $result = $this->runCommandRemote('ls -l ' . $symlink, $output) && $result; $currentRelease = explode('/', $output); $currentRelease = trim(array_pop($currentRelease)); if (count($releases) == 0) { Console::output('<dark_gray>No releases available</dark_gray> ... ', 2); } else { rsort($releases); $releases = array_slice($releases, 0, 10); foreach ($releases as $releaseIndex => $release) { $release = trim($release); $releaseIndex = str_pad($releaseIndex * -1, 2, ' ', STR_PAD_LEFT); $releaseDate = $release[0] . $release[1] . $release[2] . $release[3] . '-' . $release[4] . $release[5] . '-' . $release[6] . $release[7] . ' ' . $release[8] . $release[9] . ':' . $release[10] . $release[11] . ':' . $release[12] . $release[13]; $isCurrent = ''; if ($currentRelease == $release) { $isCurrent = ' <- current'; } $dateDiff = $this->dateDiff($releaseDate); Console::output('Release: <purple>' . $release . '</purple> ' . '- Date: <dark_gray>' . $releaseDate . '</dark_gray> ' . '- Index: <dark_gray>' . $releaseIndex . '</dark_gray>' . $dateDiff . $isCurrent, 2); } } Console::output(''); return $result; } else { Console::output(''); return false; } }
/** * Locks the Deployment to a Environment * @see \Mage\Command\AbstractCommand::run() */ public function run() { Console::output('Your name (enter to leave blank): ', 0, 0); $name = Console::readInput(); Console::output('Your email (enter to leave blank): ', 0, 0); $email = Console::readInput(); Console::output('Reason of lock (enter to leave blank): ', 0, 0); $reason = Console::readInput(); $lockmsg = PHP_EOL; if ($name) { $lockmsg .= 'Locked by ' . $name . ' '; } if ($email) { $lockmsg .= '(' . $email . ')'; } if ($reason) { $lockmsg .= PHP_EOL . $reason . PHP_EOL; } $lockFile = getcwd() . '/.mage/' . $this->getConfig()->getEnvironment() . '.lock'; file_put_contents($lockFile, 'Locked environment at date: ' . date('Y-m-d H:i:s') . $lockmsg); Console::output('Locked deployment to <light_purple>' . $this->getConfig()->getEnvironment() . '</light_purple> environment', 1, 2); return 0; }
/** * Lists the Environments */ protected function listEnvironments() { $exitCode = 220; $environments = array(); $content = scandir(getcwd() . '/.mage/config/environment/'); foreach ($content as $file) { if (strpos($file, '.yml') !== false) { $environments[] = str_replace('.yml', '', $file); } } sort($environments); if (count($environments) > 0) { Console::output('<bold>These are your configured environments:</bold>', 1, 1); foreach ($environments as $environment) { Console::output('* <light_red>' . $environment . '</light_red>', 2, 1); } Console::output('', 1, 1); $exitCode = 0; } else { Console::output('<bold>You don\'t have any environment configured.</bold>', 1, 2); } return $exitCode; }
/** * Send Email Notification if enabled * @param boolean $result * @return boolean */ protected function sendNotification($result) { $projectName = $this->getConfig()->general('name', false); $projectEmail = $this->getConfig()->general('email', false); $notificationsEnabled = $this->getConfig()->general('notifications', false); // We need notifications enabled, and a project name and email to send the notification if (!$projectName || !$projectEmail || !$notificationsEnabled) { return false; } $mailer = new Mailer(); $mailer->setAddress($projectEmail)->setProject($projectName)->setLogFile(Console::getLogFile())->setEnvironment($this->getConfig()->getEnvironment())->send($result); return true; }
/** * 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; }
public function run() { Console::output('Hello world', 1, 2); return 0; }
/** * Display the Magallanes Version * * @see \Mage\Command\AbstractCommand::run() */ public function run() { Console::output('Running <blue>Magallanes</blue> version <bold>' . MAGALLANES_VERSION . '</bold>', 0, 2); return 0; }
/** * 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); }
/** * Performs a Rollback Operation * @see \Mage\Task\AbstractTask::run() */ public function run() { 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; } $output = ''; $result = $this->runCommandRemote('ls -1 ' . $releasesDirectory, $output); $releases = $output == '' ? array() : explode(PHP_EOL, $output); if (count($releases) == 0) { Console::output('Release are not available for <bold>' . $this->getConfig()->getHost() . '</bold> ... <red>FAIL</red>'); } else { rsort($releases); $deleteCurrent = $this->getConfig()->getParameter('deleteCurrent', $this->getConfig()->deployment('delete-on-rollback', $this->getConfig()->general('delete-on-rollback', false))); $releaseIsAvailable = false; if ($this->getReleaseId() == '') { $releaseId = $releases[0]; $releaseIsAvailable = true; } elseif ($this->getReleaseId() <= 0) { $index = $this->getReleaseId() * -1; if (isset($releases[$index])) { $releaseId = $releases[$index]; $releaseIsAvailable = true; } } else { if (in_array($this->getReleaseId(), $releases)) { $releaseId = $this->getReleaseId(); $releaseIsAvailable = true; } } $currentCopy = rtrim($releasesDirectory, '/') . '/' . $releaseId; if (!$releaseIsAvailable) { Console::output('Release <bold>' . $this->getReleaseId() . '</bold> is invalid or unavailable for <bold>' . $this->getConfig()->getHost() . '</bold> ... <red>FAIL</red>'); } else { Console::output('Rollback release on <bold>' . $this->getConfig()->getHost() . '</bold>'); $rollbackTo = $releasesDirectory . '/' . $releaseId; // Get Current Release if ($deleteCurrent) { $result = $this->runCommandRemote('ls -l ' . $symlink, $output) && $result; $currentRelease = explode('/', $output); $currentRelease = trim(array_pop($currentRelease)); } // Tasks $tasks = 1; $completedTasks = 0; $tasksToRun = $this->getConfig()->getTasks(); $this->getConfig()->setReleaseId($releaseId); // Run Deploy Tasks foreach ($tasksToRun as $taskData) { $task = Factory::get($taskData, $this->getConfig(), true, self::STAGE_DEPLOY); $task->init(); Console::output('Running <purple>' . $task->getName() . '</purple> ... ', 2, false); if ($task instanceof RollbackAware) { /* @var $task AbstractTask */ $tasks++; $result = $task->run(); if ($result === true) { Console::output('<green>OK</green>', 0); $completedTasks++; } else { Console::output('<red>FAIL</red>', 0); } } else { Console::output('<yellow>SKIPPED</yellow>', 0); } } // Changing Release Console::output('Running <purple>Rollback Release [id=' . $releaseId . ']</purple> ... ', 2, false); $userGroup = ''; $resultFetch = $this->runCommandRemote('ls -ld ' . $rollbackTo . ' | awk \'{print \\$3":"\\$4}\'', $userGroup); $tmplink = $symlink . '.tmp'; $command = "ln -sfn {$currentCopy} {$tmplink}"; if ($resultFetch && $userGroup) { $command .= " && chown -h {$userGroup} {$tmplink}"; } $command .= " && mv -f {$tmplink} {$symlink}"; $result = $this->runCommandRemote($command); if ($result) { Console::output('<green>OK</green>', 0); $completedTasks++; // Delete Old Current Release if ($deleteCurrent && $currentRelease) { $this->runCommandRemote('rm -rf ' . $releasesDirectory . '/' . $currentRelease, $output); } } else { Console::output('<red>FAIL</red>', 0); } // Run Post Release Tasks $tasksToRun = $this->getConfig()->getTasks(AbstractTask::STAGE_POST_DEPLOY); foreach ($tasksToRun as $taskData) { $task = Factory::get($taskData, $this->getConfig(), true, self::STAGE_POST_DEPLOY); $task->init(); Console::output('Running <purple>' . $task->getName() . '</purple> ... ', 2, false); if ($task instanceof RollbackAware) { /* @var $task AbstractTask */ $tasks++; $result = $task->run(); if ($result === true) { Console::output('<green>OK</green>', 0); $completedTasks++; } else { Console::output('<red>FAIL</red>', 0); } } else { Console::output('<yellow>SKIPPED</yellow>', 0); } } if ($completedTasks == $tasks) { $tasksColor = 'green'; } else { $tasksColor = 'red'; } Console::output('Release rollback on <bold>' . $this->getConfig()->getHost() . '</bold> compted: <' . $tasksColor . '>' . $completedTasks . '/' . $tasks . '</' . $tasksColor . '> tasks done.', 1, 3); } } return $result; } else { return false; } }
/** * 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; } }
/** * Switches the original source * code dir to tempory name * and recreates orginal dir * allows encryption to be done * into source dir, so other functions * work without changing * * @throws ErrorWithMessageException If source dir can't be renamed * @throws ErrorWithMessageException If original source dir cant be created * * @return bool */ private function switchSrcToTmp() { $ret = Console::executeCommand('mv ' . $this->source . ' ' . $this->ionSource, $out); if (!$ret) { throw new ErrorWithMessageException('Cant create tmp dir :' . $out, $ret); } $ret = Console::executeCommand('mkdir -p ' . $this->source, $out); if (!$ret) { throw new ErrorWithMessageException('Cant re-create dir :' . $out, $ret); } return true; }