function testSqlFromZip() { $target = '/tmp/miketestsite_dev_2014-10-30T18-59-07_UTC_database.sql.gz'; $actual = \Terminus\Utils\sql_from_zip($target); $this->assertEquals('/tmp/miketestsite_dev_2014-10-30T18-59-07_UTC_database.sql', $actual); }
/** * 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* only used for the 'create' * * [--to-directory=<directory>] * : Download the file if set * * [--latest] * : if set no the latest backup will be selected automatically * * [--keep-for] * : number of days to keep this backup. * * @subcommand backup * */ public function backup($args, $assoc_args) { $action = array_shift($args); $site = SiteFactory::instance(Input::site($assoc_args)); $env = Input::env($assoc_args, 'env'); switch ($action) { case 'get': // prompt for backup type if (!($element = @$assoc_args['element'])) { $element = Terminus::menu(array('code', 'files', 'database'), null, "Select type backup", TRUE); } if (!in_array($element, array('code', 'files', 'database'))) { Terminus::error("Invalid backup element specified."); } $latest = Input::optional('latest', $assoc_args, false); $backups = $site->environment($env)->backups($element, $latest); if (empty($backups)) { \Terminus::error('No backups available.'); } $menu = $folders = array(); // build a menu for selecting back ups foreach ($backups as $folder => $backup) { if (!isset($backup->filename)) { continue; } if (!isset($backup->folder)) { $backup->folder = $folder; } $buckets[] = $backup->folder; $menu[] = $backup->filename; } if (empty($menu)) { Terminus::error("No backups available. Create one with `terminus site backup create --site=%s --env=%s`", array($site->getName(), $env)); } $index = 0; if (!$latest) { $index = Terminus::menu($menu, null, "Select backup"); } $bucket = $buckets[$index]; $filename = $menu[$index]; $url = $site->environment($env)->backupUrl($bucket, $element); if (isset($assoc_args['to-directory'])) { Terminus::line("Downloading ... please wait ..."); $filename = \Terminus\Utils\get_filename_from_url($url->url); $target = sprintf("%s/%s", $assoc_args['to-directory'], $filename); if (Terminus_Command::download($url->url, $target)) { Terminus::success("Downloaded %s", $target); return $target; } else { Terminus::error("Could not download file"); } } echo $url->url; return $url->url; break; case 'load': $assoc_args['to-directory'] = '/tmp'; $assoc_args['element'] = 'database'; $database = @$assoc_args['database'] ?: false; $username = @$assoc_args['username'] ?: false; $password = @$assoc_args['password'] ?: false; exec("mysql -e 'show databases'", $stdout, $exit); if (0 != $exit) { Terminus::error("MySQL does not appear to be installed on your server."); } $assoc_args['env'] = $env; $target = $this->backup(array('get'), $assoc_args); $target = \Terminus\Utils\get_filename_from_url($target); $target = "/tmp/{$target}"; if (!file_exists($target)) { Terminus::error("Can't read database file %s", array($target)); } Terminus::line("Unziping database"); exec("gunzip {$target}", $stdout, $exit); // trim the gz of the target $target = Terminus\Utils\sql_from_zip($target); $target = escapeshellarg($target); if (!$database) { $database = escapeshellarg(Terminus::prompt("Name of database to import to")); } if (!$username) { $username = escapeshellarg(Terminus::prompt("Username")); } if (!$password) { $password = escapeshellarg(Terminus::prompt("Password")); } exec("mysql {$database} -u {$username} -p'{$password}' < {$target}", $stdout, $exit); if (0 != $exit) { Terminus::error("Could not import database"); } Terminus::success("%s successfuly imported to %s", array($target, $database)); return true; break; case 'create': if (!array_key_exists('element', $assoc_args)) { $assoc_args['element'] = Input::menu(array('code', 'db', 'files', 'all'), 'all', "Select element"); } $result = $site->environment($env)->createBackup($assoc_args); if ($result) { Terminus::success("Created backup"); } else { Terminus::error("Couldn't create backup."); } break; case 'list': case 'default': $backups = $site->environment($env)->backups(); $element = @$assoc_args['element']; $data = array(); foreach ($backups as $id => $backup) { if (!isset($backup->filename)) { continue; } $data[] = array($backup->filename, sprintf("%dMB", $backup->size / 1024 / 1024), date("Y-m-d H:i:s", $backup->finish_time)); } if (empty($backups)) { \Terminus::error("No backups found."); return false; } else { //munging data $this->handleDisplay($data, $args, array('File', 'Size', 'Date')); return $data; } break; } }
/** * 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* only used for 'create' * * [--to-directory=<directory>] * : Absolute path of directory to download the file * * [--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 = 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': if (isset($assoc_args['element'])) { $element = $assoc_args['element']; } else { $element = Terminus::menu(array('code', 'files', 'db'), null, 'Select backup element', true); } if (!in_array($element, array('code', 'files', 'db'))) { Terminus::error('Invalid backup element specified.'); } $latest = Input::optional('latest', $assoc_args, false); $backups = $site->environments->get($env)->backups($element); //Ensure that that backups being presented for retrieval have finished $backups = array_filter($backups, function ($backup) { return isset($backup->finish_time) && $backup->finish_time; }); if ($latest) { $backups = array(array_pop($backups)); } if (empty($backups)) { \Terminus::error('No backups available.'); } $menu = $folders = array(); foreach ($backups as $folder => $backup) { if (!isset($backup->filename)) { continue; } if (!isset($backup->folder)) { $backup->folder = $folder; } $buckets[] = $backup->folder; $menu[] = $backup->filename; } if (empty($menu)) { Terminus::error('No backups available. Create one with ' . '`terminus site backup create --site=%s --env=%s`', array($site->get('name'), $env)); } $index = 0; if (!$latest) { $index = Terminus::menu($menu, null, 'Select backup'); } $bucket = $buckets[$index]; $filename = $menu[$index]; $url = $site->environments->get($env)->backupUrl($bucket, $element); if (isset($assoc_args['to-directory'])) { Terminus::line('Downloading ... please wait ...'); $filename = \Terminus\Utils\get_filename_from_url($url->url); $target = sprintf('%s/%s', $assoc_args['to-directory'], $filename); if (TerminusCommand::download($url->url, $target)) { Terminus::success('Downloaded %s', $target); return $target; } else { Terminus::error('Could not download file'); } } Terminus::success($url->url); return $url->url; break; case 'load': $assoc_args['to-directory'] = '/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) { Terminus::error('MySQL does not appear to be installed on your server.'); } $assoc_args['env'] = $env; $target = $this->backup(array('get'), $assoc_args); $target = '/tmp/' . \Terminus\Utils\get_filename_from_url($target); if (!file_exists($target)) { Terminus::error('Cannot read database file %s', array($target)); } Terminus::line('Unziping database'); exec("gunzip {$target}", $stdout, $exit); // trim the gz of the target $target = Terminus\Utils\sql_from_zip($target); $target = escapeshellarg($target); exec("mysql {$database} -u {$username} -p'{$password}' < {$target}", $stdout, $exit); if ($exit != 0) { Terminus::error('Could not import database'); } Terminus::success('%s successfuly imported to %s', array($target, $database)); return true; break; case 'create': if (!array_key_exists('element', $assoc_args)) { $assoc_args['element'] = Input::menu(array('code', 'db', 'files', 'all'), 'all', 'Select element'); } $workflow = $site->environments->get($env)->createBackup($assoc_args); $workflow->wait(); $this->workflowOutput($workflow); break; case 'list': default: $backups = $site->environments->get($env)->backups(); $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('/backup_%s/', $element_name), $id)) { continue; } $date = 'Pending'; if (isset($backup->finish_time)) { $date = date('Y-m-d H:i:s', $backup->finish_time); } $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($backups)) { \Terminus::error('No backups found.'); return false; } else { $this->outputter->outputRecordList($data, array('file' => 'File', 'size' => 'Size', 'date' => 'Date')); return $data; } break; } }