Exemplo n.º 1
0
 /**
  * Loads a single backup
  *
  * @params [array] $assoc_args Parameters and flags from the command line
  * @return [boolean] Always true, else the function has thrown an exception
  */
 private function loadBackup($assoc_args)
 {
     $site = $this->sites->get(Input::sitename($assoc_args));
     $env = $site->environments->get(Input::env(array('args' => $assoc_args, 'site' => $site)));
     $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}', compact('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(sprintf('mysql %s -u %s -p"%s" < %s', $database, $username, $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;
 }
Exemplo n.º 2
0
 /**
  * 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;
     }
 }
Exemplo n.º 3
0
 /**
  * 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 = 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) {
                 $regex = sprintf("/%s_%s_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_UTC_(.*).tar.gz/", $site->get('name'), $env);
                 preg_match($regex, $file, $matches);
                 $element = $matches[1];
             } elseif (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'))) {
                     $this->failure('Invalid backup element specified.');
                 }
             }
             $latest = (bool) Input::optional('latest', $assoc_args, false);
             if (!in_array($element, array('code', 'files', 'db'))) {
                 $this->failure('Invalid backup element specified.');
             }
             $latest = Input::optional('latest', $assoc_args, false);
             $backups = $site->environments->get($env)->backups($element);
             if (empty($backups)) {
                 $this->failure('No backups available. Create one with `terminus site backup create --site={site} --env={env}`', array('site' => $site->get('name'), 'env' => $env));
             }
             //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) {
                 $backup = array_pop($backups);
             } elseif ($file) {
                 do {
                     try {
                         $candidate = array_pop($backups);
                     } catch (\Exception $e) {
                         $this->failure("{$file} is not a valid backup archive");
                     }
                     if ($candidate->filename == $file) {
                         $backup = $candidate;
                     }
                 } while (!isset($backup));
             }
             if (!isset($backup)) {
                 $menu = $folders = array();
                 foreach ($backups as $folder => $backup) {
                     if (!isset($backup->filename)) {
                         continue;
                     }
                     if (!isset($backup->folder)) {
                         $backup->folder = $folder;
                     }
                     $menu[] = $backup->filename;
                 }
                 $index = Terminus::menu($menu, null, 'Select backup');
                 $backup_elements = array_values($backups);
                 $backup = $backup_elements[$index];
             }
             if (empty($menu)) {
                 $this->failure('No backups available. Create one with `terminus site backup create --site={site} --env={env}`', array('site' => $site->get('name'), 'env' => $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'])) {
                 $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}', array('target' => $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;
             $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 = $site->environments->get($env)->createBackup($assoc_args);
             $workflow->wait();
             $this->workflowOutput($workflow);
             break;
         case 'list':
         default:
             $backups = $site->environments->get($env)->backups();
             //die(print_r($backups, true));
             $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;
     }
 }
Exemplo n.º 4
0
 /**
  * Loads a single backup
  *
  * @params array $assoc_args Parameters and flags from the command line
  * @return bool Always true, else the function has thrown an exception
  */
 private function loadBackup($assoc_args)
 {
     $assoc_args['to'] = '/tmp';
     $assoc_args['element'] = 'database';
     if (isset($assoc_args['database'])) {
         $database = $assoc_args['database'];
     } else {
         $database = escapeshellarg(Input::prompt(array('message' => 'Name of database to import to')));
     }
     if (isset($assoc_args['username'])) {
         $username = $assoc_args['username'];
     } else {
         $username = escapeshellarg(Input::prompt(array('message' => 'Username')));
     }
     if (isset($assoc_args['password'])) {
         $password = $assoc_args['password'];
     } else {
         $password = Input::promptSecret(array('message' => 'Your MySQL password (input will not be shown)'));
     }
     exec('mysql --version', $stdout, $exit);
     if ($exit != 0) {
         $this->failure('MySQL does not appear to be installed on your server.');
     }
     $target = $this->getBackup($assoc_args);
     $target = '/tmp/' . Utils\getFilenameFromUrl($target);
     if (!file_exists($target)) {
         $this->failure('Cannot read database file {target}', compact('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(sprintf('mysql %s -u %s -p"%s" < %s', $database, $username, $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;
 }
Exemplo n.º 5
0
 function testSqlFromZip()
 {
     $target = '/tmp/miketestsite_dev_2014-10-30T18-59-07_UTC_database.sql.gz';
     $actual = Utils\sqlFromZip($target);
     $this->assertEquals('/tmp/miketestsite_dev_2014-10-30T18-59-07_UTC_database.sql', $actual);
 }