/** * Retrieves a single backup or downloads it as requested * * @params [array] $assoc_args Parameters and flags from the command line * @return [string] $url->url */ private function getBackup($assoc_args) { $site = $this->sites->get(Input::sitename($assoc_args)); $env = $site->environments->get(Input::env(array('args' => $assoc_args, 'site' => $site))); $file = Input::optional('file', $assoc_args, false); if ($file) { $backup = $env->backups->getBackupByFileName($file); $element = $backup->getElement(); } else { $element = Input::backupElement(array('args' => $assoc_args)); $latest = (bool) Input::optional('latest', $assoc_args, false); $backups = $env->backups->getFinishedBackups($element); if ($latest) { $backup = array_pop($backups); } else { $context = array('site' => $site->get('name'), 'env' => $env->get('id')); $backup = Input::backup(array('backups' => $backups, 'context' => $context)); } } $url = $backup->getUrl(); if (isset($assoc_args['to'])) { $target = str_replace('~', $_SERVER['HOME'], $assoc_args['to']); if (is_dir($target)) { $filename = Utils\getFilenameFromUrl($url); $target = sprintf('%s/%s', $target, $filename); } $this->log()->info('Downloading ... please wait ...'); if (Request::download($url, $target)) { $this->log()->info('Downloaded {target}', compact('target')); return $target; } else { $this->failure('Could not download file'); } } return $url; }
/** * Get, load, create, or list backup information * * ## OPTIONS * * <get|load|create|list> * : Function to run - get, load, create, or list * * [--site=<site>] * : Site to load * * [--env=<env>] * : Environment to load * * [--element=<code|files|db|all>] * : Element to download or create. `all` is only used for 'create' * * [--to=<directory|file>] * : Absolute path of a directory or filename to save the downloaded backup to * * [--file=<filename>] * : Select one of the files from the list subcommand. Only used for 'get' * * [--latest] * : If set the latest backup will be selected automatically * * [--keep-for] * : Number of days to keep this backup * * @subcommand backups * */ public function backups($args, $assoc_args) { $action = array_shift($args); $site = $this->sites->get(Input::sitename($assoc_args)); $env = $site->environments->get(Input::env($assoc_args, 'env')); //Backward compatability supports "database" as a valid element value. if (isset($assoc_args['element']) && $assoc_args['element'] == 'database') { $assoc_args['element'] = 'db'; } switch ($action) { case 'get': $file = Input::optional('file', $assoc_args, false); if ($file) { $backup = $env->getBackupByFile($file); $element = $backup->element; } else { $element = Input::backupElement(array('args' => $assoc_args)); $latest = (bool) Input::optional('latest', $assoc_args, false); $backups = $env->getFinishedBackups($element); if ($latest) { $backup = array_pop($backups); } else { $context = array('site' => $site->get('name'), 'env' => $env->get('id')); $backup = Input::backup(array('backups' => $backups, 'context' => $context)); } } $url = $env->getBackupUrl($backup->folder, $element); if (isset($assoc_args['to'])) { $target = str_replace('~', $_SERVER['HOME'], $assoc_args['to']); if (is_dir($target)) { $filename = Utils\getFilenameFromUrl($url->url); $target = sprintf('%s/%s', $target, $filename); } $this->log()->info('Downloading ... please wait ...'); if ($this->download($url->url, $target)) { $this->log()->info('Downloaded {target}', compact('target')); return $target; } else { $this->failure('Could not download file'); } } $this->output()->outputValue($url->url, 'Backup URL'); return $url->url; break; case 'load': $assoc_args['to'] = '/tmp'; $assoc_args['element'] = 'database'; if (isset($assoc_args['database'])) { $database = $assoc_args['database']; } else { $database = escapeshellarg(Terminus::prompt('Name of database to import to')); } if (isset($assoc_args['username'])) { $username = $assoc_args['username']; } else { $username = escapeshellarg(Terminus::prompt('Username')); } if (isset($assoc_args['password'])) { $password = $assoc_args['password']; } else { $password = escapeshellarg(Terminus::prompt('Password')); } exec('mysql -e "show databases"', $stdout, $exit); if ($exit != 0) { $this->failure('MySQL does not appear to be installed on your server.'); } $assoc_args['env'] = $env->get('id'); $target = $this->backup(array('get'), $assoc_args); $target = '/tmp/' . Utils\getFilenameFromUrl($target); if (!file_exists($target)) { $this->failure('Cannot read database file {target}', array('target' => $target)); } $this->log()->info('Unziping database'); exec("gunzip {$target}", $stdout, $exit); // trim the gz of the target $target = Utils\sqlFromZip($target); $target = escapeshellarg($target); exec("mysql {$database} -u {$username} -p'{$password}' < {$target}", $stdout, $exit); if ($exit != 0) { $this->failure('Could not import database'); } $this->log()->info('{target} successfully imported to {db}', array('target' => $target, 'db' => $database)); return true; break; case 'create': if (!array_key_exists('element', $assoc_args)) { $options = array('code', 'db', 'files', 'all'); $assoc_args['element'] = $options[Input::menu($options, 'all', 'Select element')]; } $workflow = $env->createBackup($assoc_args); $workflow->wait(); $this->workflowOutput($workflow); break; case 'list': default: $backups = $env->getBackups(); $element_name = false; if (isset($assoc_args['element']) && $assoc_args['element'] != 'all') { $element_name = $assoc_args['element']; } if ($element_name == 'db') { $element_name = 'database'; } $data = array(); foreach ($backups as $id => $backup) { if (!isset($backup->filename) || $element_name && !preg_match(sprintf('/_%s/', $element_name), $id)) { continue; } $date = 'Pending'; if (isset($backup->finish_time)) { $date = date('Y-m-d H:i:s', $backup->finish_time); } $size = 0; if (isset($backup->size)) { $size = $backup->size / 1048576; } if ($size > 0.1) { $size = sprintf('%.1fMB', $size); } elseif ($size > 0) { $size = '0.1MB'; } else { //0-byte backups should not be recommended for restoration $size = 'Incomplete'; } $data[] = array('file' => $backup->filename, 'size' => $size, 'date' => $date); } if (empty($data)) { $this->log()->warning('No backups found.'); } $this->output()->outputRecordList($data, array('file' => 'File', 'size' => 'Size', 'date' => 'Date')); return $data; break; } }