Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 165 additions & 18 deletions src/Provision/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -996,28 +996,19 @@ public function shell_exec($command, $dir = NULL, $return = 'stdout') {
$this->getProperty('root')
;

if ($this->getProvision()->getOutput()->isVerbose()) {
$this->getProvision()->io()->commandBlock($command, $effective_wd);
$this->getProvision()->io()->customLite("Writing output to <comment>$tmp_output_file</comment>", ProvisionStyle::ICON_FILE, 'comment');

// If verbose, Use tee so we see it and it saves to file.
// Thanks to https://askubuntu.com/a/731237
// Uses "2>&1 |" so it works with older bash shells.
$command = "$command 2>&1 | tee -a $tmp_output_file; exit \${PIPESTATUS[0]}
";
}
else {
// If not verbose, just save it to file.
$command .= "> $tmp_output_file 2>&1";
}

// Output and Errors to file.
$process = $this->process_exec($command, $effective_wd);
$process = $this->process_exec($command, $effective_wd, $tmp_output_file);
$exit_code = $process->getExitCode();

// print 'EXIT CODE! ' . $exit_code; die;
$exit = $process->getExitCode();
$stdout = file_get_contents($tmp_output_file);


$this->getProvision()->getLogger()->debug('Shell exec command: ' . print_r($command, 1));
$this->getProvision()->getLogger()->debug('Shell exec dir: ' . print_r($effective_wd, 1));
$this->getProvision()->getLogger()->debug('Shell exec exit code: ' . print_r($exit, 1));
$this->getProvision()->getLogger()->debug('Shell exec output: ' . print_r($stdout, 1));

if ($exit != ResultData::EXITCODE_OK) {
throw new \Exception($stdout);
}
Expand All @@ -1030,14 +1021,39 @@ public function shell_exec($command, $dir = NULL, $return = 'stdout') {
* @param null $dir
* @param string $return
*/
public function process_exec($command, $dir = NULL) {
public function process_exec($command, $dir = NULL, $output_file = NULL) {

if(!$this->isLocalHost()){
$ssh_command = 'ssh -o PasswordAuthentication=no ' . $this->getProperty('script_user') . '@' . $this->getProperty('remote_host');
if($dir){
$command = 'cd ' . $dir . ' && ' . $command;
}
$command = $ssh_command . ' "' . $command . '"';
}

if($output_file){
if ($this->getProvision()->getOutput()->isVerbose()) {
$this->getProvision()->io()->commandBlock($command, $dir);
$this->getProvision()->io()->customLite("Writing output to <comment>$output_file</comment>", ProvisionStyle::ICON_FILE, 'comment');

// If verbose, Use tee so we see it and it saves to file.
// Thanks to https://askubuntu.com/a/731237
// Uses "2>&1 |" so it works with older bash shells.
$command = "$command 2>&1 | tee -a $output_file";
}
else {
// If not verbose, just save it to file.
$command .= " > $output_file 2>&1";
}
}

$process = new Process($command);
$process->setTimeout(null);
$process->setTty(true);

$env = $_SERVER;

$this->getProvision()->getLogger()->debug('Command: ' . print_r($command, 1));
$this->getProvision()->getLogger()->debug('Environment: ' . print_r($env, 1));

$env['PROVISION_CONTEXT'] = $this->name;
Expand Down Expand Up @@ -1091,4 +1107,135 @@ function getServiceCommandClasses() {

return $classes;
}

public function isLocalHost(){
if($this->hasProperty('remote_host')){
$host = $this->getProperty('remote_host');

$host = strtolower($host);
// In order for this to work right, you must use 'localhost' or '127.0.0.1'
// or the machine returned by 'uname -n' for your 'remote-host' entry in
// your site alias. Note that sometimes 'uname -n' does not return the
// correct value. To fix it, put the correct hostname in /etc/hostname
// and then run 'hostname -F /etc/hostname'.
return ($host == 'localhost') ||
($host == '127.0.0.1') ||
(gethostbyname($host) == '127.0.0.1') ||
(gethostbyname($host) == '127.0.1.1') || // common setting on
// ubuntu and friends
($host == strtolower(php_uname('n'))) ||
($host == static::provisionFqdn());
}

return true;
}

public static function provisionFqdn($host = NULL) {
if (is_null($host)) {
$host = php_uname('n');
}
return strtolower(gethostbyaddr(gethostbyname($host)));
}

public function sync($path = NULL, $additional_options = array()) {
if(!$this->isLocalHost()){
if (is_null($path)) {
$path = $this->getWorkingDir();
}
if ($this->fs->exists($path)) {
$default_options = array(
'relative' => TRUE,
'keep-dirlinks' => TRUE,
'omit-dir-times' => TRUE,
);
$options = array_merge($default_options,$additional_options);
$parameters[] = $this->rsyncOptions($options);
$parameters[] = $path;
$parameters[] = $this->getProperty('script_user') . '@' . $this->getProperty('remote_host') . ':/';

$exec = "rsync -e 'ssh -o PasswordAuthentication=no' " . implode(' ', array_filter($parameters)) . ' 2>&1';

$process = new \Symfony\Component\Process\Process($exec);
$process->run();

$this->getProvision()->getLogger()->debug('Sync command: ' . print_r($exec, 1));
$this->getProvision()->getLogger()->debug('Sync command output: ' . print_r($process->getOutput(), 1));
$this->getProvision()->getLogger()->debug('Sync command exitcode: ' . print_r($process->getExitCode(), 1));

return $process->getExitCode() == ResultData::EXITCODE_OK;
}
else { // File does not exist, remove it.
return $this->shell_exec('rm -rf ' . escapeshellarg($path));
}
}
return 0;
}
public function fetch($path, $additional_options = array()) {
if(!$this->isLocalHost()){
if (is_null($path)) {
return;
}
if ($this->fs->exists($path)) {
$default_options = array(
'omit-dir-times' => TRUE,
);
$options = array_merge($default_options,$additional_options);
$parameters[] = $this->rsyncOptions($options);
$parameters[] = $this->getProperty('script_user') . '@' . $this->getProperty('remote_host') . ':' . $path ;
$parameters[] = $path;

$exec = "rsync -e 'ssh -o PasswordAuthentication=no' " . implode(' ', array_filter($parameters)) . ' 2>&1';

$process = new \Symfony\Component\Process\Process($exec);
$process->run();

$this->getProvision()->getLogger()->debug('Sync command: ' . print_r($exec, 1));
$this->getProvision()->getLogger()->debug('Sync command output: ' . print_r($process->getOutput(), 1));
$this->getProvision()->getLogger()->debug('Sync command exitcode: ' . print_r($process->getExitCode(), 1));

return $process->getExitCode() == ResultData::EXITCODE_OK;
}
else { // File does not exist, remove it.
return $this->shell_exec('rm -rf ' . escapeshellarg($path));
}
}
}

public function rsyncOptions($options)
{
$verbose = $paths = $op = '';
$options += [
'mode' => 'akz'
];
// Process --include-paths and --exclude-paths options the same way
foreach (['include', 'exclude'] as $include_exclude) {
// Get the option --include-paths or --exclude-paths and explode to an array of paths
// that we will translate into an --include or --exclude option to pass to rsync
$inc_ex_path = explode(PATH_SEPARATOR, @$options[$include_exclude . '-paths']);
foreach ($inc_ex_path as $one_path_to_inc_ex) {
if (!empty($one_path_to_inc_ex)) {
$paths .= ' --' . $include_exclude . '="' . $one_path_to_inc_ex . '"';
}
}
}

$mode = '-'. $options['mode'];
if ($this->getProvision()->getOutput()->isVerbose()) {
$mode .= 'v';
$verbose = ' --stats --progress';
}
$options_to_exclude = array('mode','ssh-options');
foreach ($options as $test_option => $value) {
if ((isset($test_option)) && !in_array($test_option, $options_to_exclude) && (isset($value) && !is_array($value))) {
if (($value === TRUE) || (!isset($value))) {
$op .= " --$test_option";
}
else {
$op .= " --$test_option=" . escapeshellarg($value);
}
}
}

return implode(' ', array_filter([$mode, $verbose, $op, $paths]));
}
}
13 changes: 12 additions & 1 deletion src/Provision/Context/SiteContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public function verify()
// @TODO: This is only true for Drupal version 7.50 and up. See Provision/Config/Drupal/Settings.php
// We are treading more and more into the Drupal-only world, so I'm leaving this hard coded to TRUE until we develop something else.
$database_settings = <<<PHP

// PROVISION SETTINGS
\$databases['default']['default'] = array(
'driver' => \$_SERVER['db_type'],
Expand Down Expand Up @@ -260,6 +260,14 @@ public function verify()
//
// provision_drupal_push_site(drush_get_option('override_slave_authority', FALSE));
//
$steps['site.sync'] = Provision::newStep()
->start("Running site sync ...")
->execute(function (){
if($this->sync()){
return 0;
}
return 1;
});
return $steps;
}

Expand Down Expand Up @@ -315,4 +323,7 @@ public static function randomBytes($count) {
public static function randomBytesBase64($count = 32) {
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(static::randomBytes($count)));
}
public function sync($path = NULL, $additional_options = array()) {
return $this->getSubscription('http')->service->provider->sync($this->getWorkingDir(), $additional_options);
}
}
12 changes: 6 additions & 6 deletions src/Provision/Provision.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,22 @@ class Provision implements ConfigAwareInterface, ContainerAwareInterface, Logger
/**
* @var \Robo\Runner
*/
private $runner;
protected $runner;

/**
* @var ProvisionTasks
*/
private $tasks;
protected $tasks;

/**
* @var string[]
*/
private $commands = [];
protected $commands = [];

/**
* @var \Aegir\Provision\Application
*/
private $application;
protected $application;

/**
* @var \Aegir\Provision\Context[]
Expand All @@ -99,7 +99,7 @@ class Provision implements ConfigAwareInterface, ContainerAwareInterface, Logger
/**
* @var array[]
*/
private $context_files = [];
protected $context_files = [];

/**
* @var ConsoleOutput
Expand Down Expand Up @@ -168,7 +168,7 @@ public function __construct(
/**
* Lookup all context yml files and load into Context classes.
*/
private function loadAllContexts()
protected function loadAllContexts()
{
try {
$folder = $this->getConfig()->get('contexts_path');
Expand Down
4 changes: 4 additions & 0 deletions src/Provision/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ protected function writeConfigurations(Context $context = NULL)
$success = FALSE;
}
}
if($context->type != 'server'){
$context = $context->getSubscription('http')->service->provider;
}
$success = $success && $context->sync();
return $success;
}

Expand Down