/** * Creates new Symfony process with given arguments. * * @param string $commandline The command line to run. * @param integer|null $idle_timeout Idle timeout. * * @return Process */ public function createProcess($commandline, $idle_timeout = null) { $process = new Process($commandline); $process->setTimeout(null); $process->setIdleTimeout($idle_timeout); return $process; }
public function testHttpDataDownloadUsingManyWorkers() { $filesystem = new Filesystem(); $targetDirPath = TEMP_DIR . '/' . uniqid('test_http_download'); $filesystem->mkdir($targetDirPath); $workersManager = new Process('php ' . BIN_DIR . '/spider.php worker:start-many -c 3'); $workersManager->start(); $this->assertTrue($workersManager->isRunning(), 'Workers Manager should be working'); $collector = new Process('php ' . BIN_DIR . '/spider.php collector:start --target-folder=' . $targetDirPath); $collector->setIdleTimeout(10); // there should be an output/result at least once every 10 seconds $collector->start(); $this->assertTrue($collector->isRunning(), 'Task Results Collector should be working'); $taskLoader = new Process('php ' . BIN_DIR . '/spider.php tasks:load < ' . FIXTURES_DIR . '/uris.txt'); $taskLoader->setTimeout(120); // 120 seconds is enough to complete the task $taskLoader->start(); $this->assertTrue($taskLoader->isRunning(), 'Task Loader should be working'); while ($taskLoader->isRunning()) { sleep(1); // waiting for process to complete } $taskLoaderOutput = $taskLoader->getOutput() . $taskLoader->getErrorOutput(); $this->assertContains('Total count of Tasks put in the Queue: 10', $taskLoaderOutput, 'Task Loader should have loaded 10 Tasks'); $this->assertContains('Waiting for acknowledgement from Task Result Collector', $taskLoaderOutput, 'Task Loader should have been waiting for Task Result Collector acknowledgement'); $this->assertContains('Informing all workers to stop', $taskLoaderOutput, 'Task Loader should have inform Workers to stop'); $fi = new \FilesystemIterator($targetDirPath, \FilesystemIterator::SKIP_DOTS); $this->assertEquals(10, iterator_count($fi), '10 Task Result Files expected'); }
public function mustRun(array $commands, $timeout = 60) { $command_format = <<<SHELL echo {{ESCAPED_COMMAND}} {{COMMAND}} SHELL; $formatted_commands = $this->formatCommands($commands, $command_format); $shell = <<<SHELL set -e set -u {$formatted_commands} SHELL; $log_service = $this->log_service; $process = new Process($shell); $process->setTimeout($timeout); $process->setIdleTimeout($timeout); $process->mustRun(function ($type, $buffer) use($log_service) { if (Process::ERR === $type) { $this->log_service->error($buffer); } else { $this->log_service->info($buffer); } }); }
protected function execute(InputInterface $input, OutputInterface $output) { $commandLine = $input->getArgument('command-line'); if (!$this->tryParseChunkSize($input->getOption('chunk-size'), $chunkSize)) { $output->writeln('<error>Chunk size must be number optionally suffixed with k or M.</error>'); return 1; } $model = $this->model; if ($id = $input->getOption('instance')) { if (!($entity = $model->getById($id))) { $output->writeln('<error>Rixxi\\Process\\Entities\\IProcess instance does not exist.</error>'); return 1; } } else { $entity = $model->create($commandLine); } $process = new Process($commandLine); $process->setTimeout(NULL); $process->setIdleTimeout(NULL); $exitCode = $process->run(function ($type, $output) use($entity, $model, $chunkSize) { if (strlen($output) > $chunkSize) { $output = str_split($output, $chunkSize); } else { $output = array($output); } foreach ($output as $chunk) { $model->append($entity, $chunk, $type === Process::ERR); } }); $model->finish($entity, $exitCode); }
public function run() { $command = $this->getCommand(); $dir = $this->workingDirectory ? " in " . $this->workingDirectory : ""; $this->printTaskInfo("Running <info>{$command}</info>{$dir}"); $this->process = new Process($command); $this->process->setTimeout($this->timeout); $this->process->setIdleTimeout($this->idleTimeout); $this->process->setWorkingDirectory($this->workingDirectory); if (isset($this->env)) { $this->process->setEnv($this->env); } if (!$this->background and !$this->isPrinted) { $this->startTimer(); $this->process->run(); $this->stopTimer(); return new Result($this, $this->process->getExitCode(), $this->process->getOutput(), ['time' => $this->getExecutionTime()]); } if (!$this->background and $this->isPrinted) { $this->startTimer(); $this->process->run(function ($type, $buffer) { print $buffer; }); $this->stopTimer(); return new Result($this, $this->process->getExitCode(), $this->process->getOutput(), ['time' => $this->getExecutionTime()]); } try { $this->process->start(); } catch (\Exception $e) { return Result::error($this, $e->getMessage()); } return Result::success($this); }
/** * {@inheritdoc} */ public function run() { $this->printAction(); $this->process = new Process($this->getCommand()); $this->process->setTimeout($this->timeout); $this->process->setIdleTimeout($this->idleTimeout); $this->process->setWorkingDirectory($this->workingDirectory); if (isset($this->env)) { $this->process->setEnv($this->env); } if (!$this->background and !$this->isPrinted) { $this->startTimer(); $this->process->run(); $this->stopTimer(); return new Result($this, $this->process->getExitCode(), $this->process->getOutput(), ['time' => $this->getExecutionTime()]); } if (!$this->background and $this->isPrinted) { $this->startTimer(); $this->process->run(function ($type, $buffer) { $progressWasVisible = $this->hideTaskProgress(); print $buffer; $this->showTaskProgress($progressWasVisible); }); $this->stopTimer(); return new Result($this, $this->process->getExitCode(), $this->process->getOutput(), ['time' => $this->getExecutionTime()]); } try { $this->process->start(); } catch (\Exception $e) { return Result::fromException($this, $e); } return Result::success($this); }
public function run() { $command = $this->getCommand(); $dir = $this->workingDirectory ? " in " . $this->workingDirectory : ""; $this->printTaskInfo("running <info>{$command}</info>{$dir}"); $this->process = new Process($command); $this->process->setTimeout($this->timeout); $this->process->setIdleTimeout($this->idleTimeout); $this->process->setWorkingDirectory($this->workingDirectory); if (!$this->background and !$this->isPrinted) { $this->process->run(); return new Result($this, $this->process->getExitCode(), $this->process->getOutput()); } if (!$this->background and $this->isPrinted) { $this->process->run(function ($type, $buffer) { Process::ERR === $type ? print 'ER» ' . $buffer : (print '» ' . $buffer); }); return new Result($this, $this->process->getExitCode(), $this->process->getOutput()); } try { $this->process->start(); } catch (\Exception $e) { return Result::error($this, $e->getMessage()); } return Result::success($this); }
public function runCommands() { $commands = implode('; ', $this->getCommands()); $process = new Process($commands, $this->getPath()); $process->setTimeout(600); $process->setIdleTimeout(null); $this->logger->info('Running "' . $process->getCommandLine() . '"'); $process->mustRun(); }
public static function create(callable $retryCallback, callable $killCallback, callable $successCallback, callable $errorCallback, Logger $logger) { return function ($command, QueueMessage $message, Job $job) use($retryCallback, $killCallback, $successCallback, $errorCallback, $logger) { $process = new Process($command); $process->setTimeout(86400); $process->setIdleTimeout(null); try { $process->run(); } catch (ProcessTimedOutException $e) { $errorCallback($job, "Process timed out"); return $process; } catch (RuntimeException $e) { // process has been signaled or some other error occurred, handled down in code } switch ($process->getExitCode()) { case self::JOB_EXIT_STATUS_LOCK: case self::OLD_JOB_EXIT_STATUS_LOCK: $newMessageId = $retryCallback($job, $message); $logger->info("DB is locked. Message requeued", ['jobId' => $job->getId(), 'oldMessageId' => $message->getId(), 'newMessageId' => $newMessageId, 'lockName' => $job->getLockName()]); break; case JobCommand::STATUS_RETRY: $message->incrementRetries(); if ($message->getRetryCount() > self::MAX_EXECUTION_RETRIES) { $errorCallback($job, "Retries exceeded"); $logger->info("Maximum retries exceeded", ['jobId' => $job->getId(), 'messageId' => $message->getId()]); break; } $newMessageId = $retryCallback($job, $message); $logger->info("Retry due to an error. Message requeued", ['jobId' => $job->getId(), 'oldMessageId' => $message->getId(), 'newMessageId' => $newMessageId]); break; case 137: case 143: // process has been signaled $killCallback($job); $logger->info("Process has been killed", ['jobId' => $job->getId(), 'messageId' => $message->getId()]); break; case JobCommand::STATUS_SUCCESS: $successCallback(); $logger->info("Process finished successfully", ['jobId' => $job->getId(), 'messageId' => $message->getId()]); break; case JobCommand::STATUS_ERROR: default: $errorCallback($job, $process->getOutput()); $logger->info("Process finished with an error", ['jobId' => $job->getId(), 'messageId' => $message->getId()]); break; } return $process; }; }
public function run($task, $live = false) { $result = []; $process = new Process('~/.composer/vendor/bin/envoy run ' . $task); $process->setTimeout(3600); $process->setIdleTimeout(300); $process->setWorkingDirectory(base_path()); $process->run(function ($type, $buffer) use($live, &$result) { $buffer = str_replace('[127.0.0.1]: ', '', $buffer); if ($live) { echo $buffer . '</br />'; } $result[] = $buffer; }); return $result; }
/** * @param BackgroundCommand $command * @return string */ protected function runProcess(BackgroundCommand $command) { $binary = $this->getBackgroundHandlerBinary(); $path = $this->getBackgroundHandlerPath(); $route = $this->getBackgroundHandlerRoute(); $arguments = implode(' ', $this->getBackgroundHandlerArguments($command)); $binaryArguments = implode(' ', $this->backgroundHandlerBinaryArguments); $process = new Process("{$binary} {$binaryArguments} {$path} {$route} {$arguments}"); $process->setTimeout($this->backgroundProcessTimeout); $process->setIdleTimeout($this->backgroundProcessIdleTimeout); if ($command->isAsync()) { $process->start(); } else { $process->run(); } return $process; }
/** * Executes a command. * When no working directory is passed, the project directory is used. * * @param string $command The command line to run * @param string $cwd The working directory or null to use the project directory * @param int $timeout The process timeout (max. runtime). To disable set to null. * @param callable $callback A PHP callback to run whenever there is some output available on STDOUT or STDERR * * @return Process */ public function exec($command, $cwd = null, $timeout = 60, $callback = null) { \Assert\that($command)->string()->notEmpty(); \Assert\that($cwd)->nullOr()->string()->notEmpty(); \Assert\that($timeout)->nullOr()->integer()->min(5); if (!is_null($callback) && !is_callable($callback)) { throw new \InvalidArgumentException('Given callback must be a callable.'); } $cwd = $this->prepareWorkingDirectory($cwd); $callback = $this->prepareCallback($callback); $process = new Process($command, $cwd); $process->setTimeout($timeout); $process->setIdleTimeout($timeout); $this->logger->debug(sprintf("Executing command '%s' in '%s', timeout %s seconds", $command, $cwd, $timeout)); $process->run($callback); return $process; }
public function execute($command, array $cpu = null) { $fs = new Filesystem(); $tempfile = tempnam(sys_get_temp_dir(), ''); if (file_exists($tempfile)) { unlink($tempfile); } $fs->mkdir($tempfile); $process = new Process($command, $tempfile); $process->setTimeout(null); $process->setIdleTimeout(null); $process->run(); $fs->remove($tempfile); if (!$process->isSuccessful()) { throw new \RuntimeException($process->getErrorOutput()); } //TODO mix strerr and strout. return sprintf("%s\n%s", $process->getOutput(), $process->getErrorOutput()); }
/** * @param DBPatcher\PatchFile $patchFile * @param \Symfony\Component\Process\Process $process * @param resource $stdout * @param resource $stderr * @return DBPatcher\PatchFile */ function applyPhpPatch($patchFile, $process, $stdout = null, $stderr = null) { if ($patchFile->extension === 'php') { $process->setTimeout(null); $process->setIdleTimeout(null); $process->setCommandLine('/usr/bin/env php ' . $patchFile->filename); $process->start(function ($type, $buffer) use($stdout, $stderr) { $pipe = $type === Process::ERR && is_resource($stderr) ? $stderr : $stdout; if ($pipe) { fputs($pipe, $buffer); } }); if ($process->wait() === 0) { return array(DBPatcher\PatchFile::copyWithNewStatus($patchFile, DBPatcher\PatchFile::STATUS_INSTALLED)); } else { return array(DBPatcher\PatchFile::copyWithNewStatus($patchFile, DBPatcher\PatchFile::STATUS_ERROR), $process->getErrorOutput()); } } return array(DBPatcher\PatchFile::copyWithNewStatus($patchFile, DBPatcher\PatchFile::STATUS_ERROR)); }
public static function create(Lock $lock, callable $retryCallback, callable $killCallback, callable $successCallback, callable $errorCallback) { return function ($command, QueueMessage $message, Job $job) use($lock, $retryCallback, $killCallback, $successCallback, $errorCallback) { if (!$lock->lock()) { $retryCallback($message, "DB is locked"); } $process = new Process($command); $process->setTimeout(86400); $process->setIdleTimeout(null); try { $process->run(); } catch (ProcessTimedOutException $e) { $errorCallback($job, "Process timed out"); } catch (RuntimeException $e) { // process has been signaled or some other error occurred, handled down in code } switch ($process->getExitCode()) { case JobCommand::STATUS_RETRY: $message->incrementRetries(); if ($message->getRetryCount() > self::MAX_EXECUTION_RETRIES) { $errorCallback($job, "Retries exceeded"); break; } $retryCallback($message); break; case 137: case 143: // process has been signaled $killCallback($job); break; case JobCommand::STATUS_SUCCESS: $successCallback(); break; case JobCommand::STATUS_ERROR: default: $errorCallback($job, $process->getOutput()); break; } return $process; }; }
protected function shell($theme) { $process = new Process(trim(implode(' ', $this->argument('shell')))); $process->setWorkingDirectory(config('themes.path') . '/' . $theme); $process->setTimeout(null); $process->setIdleTimeout(null); $process->start(); $this->block("start theme <info>{$theme}'s</info> shell command!"); $process->wait(function ($type, $buffer) { if (Process::ERR === $type) { $this->error($buffer); } else { echo $buffer; } }); if (!$process->isSuccessful()) { throw new ProcessFailedException($process); } else { $this->block('run shell finish and everything is success!'); } }
/** * @Then it should print: */ public function itShouldPrint(PyStringNode $expectedOutput) { $interact = <<<BASH expect EOF ' BASH; $this->processCommand .= $interact; $process = new Process($this->processCommand); $process->setWorkingDirectory($this->workingDir); $process->setTimeout(3600); $process->setIdleTimeout(60); $process->run(); if (!$process->isSuccessful()) { throw new \RuntimeException($process->getErrorOutput()); } $actualOutput = $this->normalizeNewlines($process->getOutput()); $expectedOutput = $this->prependExpectScriptUsage($expectedOutput); $this->filesystem->dumpFile('/tmp/actual_output.txt', $actualOutput); $this->filesystem->dumpFile('/tmp/expected_output.txt', $expectedOutput); $diffProcess = new Process('diff /tmp/expected_output.txt /tmp/actual_output.txt'); $diffProcess->run(); echo $diffProcess->getOutput(); expect($actualOutput)->toBe($expectedOutput); }
/** * Starts the proxy server container if not running. */ private function startProxyServer() { // Check if proxy is already running. $process = new Process('docker top proxy', '/', $this->environmentVariables); $process->setTimeout(null); $process->setIdleTimeout(null); $process->run(function ($type, $buffer) { if ($type == 'err') { $this->removeProxyServer(); $this->run('docker run -it -p 80:80 -d --name proxy ' . '-e DOCKER_HOST ' . '-e DOCKER_CERT_PATH ' . '-e DOCKER_TLS_VERIFY ' . '-v $DOCKER_CERT_PATH:$DOCKER_CERT_PATH ' . 'jwilder/nginx-proxy'); } }); }
/** * Build the process from the given commandOptions * @param {Array} the options from which to build the process */ protected function buildProcess($commandOptions) { if (is_string($commandOptions)) { $process = new Process(escapeshellcmd((string) $commandOptions)); return array("process" => $process, "output" => true); } else { if (is_array($commandOptions)) { $commandline = escapeshellcmd((string) $commandOptions["command"]); $cwd = isset($commandOptions["cwd"]) ? $commandOptions["cwd"] : null; $env = isset($commandOptions["env"]) ? $commandOptions["env"] : null; $input = isset($commandOptions["input"]) ? $commandOptions["input"] : null; $timeout = isset($commandOptions["timeout"]) ? $commandOptions["timeout"] : null; $options = isset($commandOptions["options"]) ? $commandOptions["options"] : array(); $idle = isset($commandOptions["idle"]) ? $commandOptions["idle"] : null; $output = isset($commandOptions["output"]) ? $commandOptions["output"] : true; $process = new Process($commandline, $cwd, $env, $input, $timeout, $options); // double-check idle if (!empty($idle)) { $process->setIdleTimeout($idle); } return array("process" => $process, "output" => $output); } } }
public function shellCommand($cmd) { $process = new Process($cmd); $process->setTimeout(3600 * 6); $process->setIdleTimeout(3600); $process->run(function ($type, $buffer) { $this->output->writeln($buffer); }); }
/** * @param $host * @param $database * @return array */ private function create($host, $database) { $command = $host->getPathToPgBin('createdb') . " -U " . escapeshellarg($host->getUsername()) . " -h " . escapeshellarg($host->getHostname()) . " " . escapeshellarg($database); $process = new Process($command); $process->setTimeout(60); // 1 minute $process->setIdleTimeout(60); // 1 minute $process->run(); $return = ['exitCode' => $process->getExitCode()]; if ($return['exitCode']) { $return['stderr'] = $process->getErrorOutput(); $return['command'] = $command; } return $return; }
/** * @param string $cmd * @param bool $isDryRun * @param bool $tty * @return null|Process */ public function runCommand($cmd, $isDryRun = false, $tty = false) { $this->getLogger()->debug($cmd, ['dry_run' => $isDryRun, 'tty' => $tty]); $process = null; if (!$isDryRun) { $process = new Process($cmd); $process->setTty($tty); $process->mustRun(); $process->setTimeout(null); $process->setIdleTimeout(null); $process->setWorkingDirectory($this->getRepositoryPath()); } return $process; }
/** * @param \Symfony\Component\Console\Input\InputInterface $input * @param \Symfony\Component\Console\Output\OutputInterface $output * @return int|void */ protected function execute(InputInterface $input, OutputInterface $output) { $this->detectMagento($output); if ($this->initMagento()) { $config = \Mage::app()->getConfig(); $dialog = $this->getHelperSet()->get('dialog'); // SSH or FTP? $mode = strtolower($dialog->ask($output, '<question>Mode (SSH or FTP) </question> <comment>[ssh]</comment>: ', 'ssh')); $values = array(); $fields = array('host' => false, 'username' => false, 'path' => true, 'exclude' => true); // Also ask password for FTP if ($mode == 'ftp') { $fields['password'] = false; } foreach ($fields as $field => $optional) { // Fetch config value from app/etc/local.xml (if available) $node = $config->getNode('global/production/' . $mode . '/' . $field); $value = (string) $node[0]; if (!empty($value)) { $value = $dialog->ask($output, '<question>' . strtoupper($mode) . ' ' . ucwords($field) . ' </question> <comment>[' . $value . ']</comment>: ', $value); } else { $value = $dialog->ask($output, '<question>' . strtoupper($mode) . ' ' . ucwords($field) . ' </question>: '); } if (!$optional && empty($value)) { $output->writeln('<error>Field ' . $field . ' can not be empty!</error>'); exit; } $values[$field] = $value; } $values['path'] = trim($values['path'], DS); $excludes = explode(',', $values['exclude']); if ($mode == 'ssh') { // Syncing over SSH using rsync $package = exec('which rsync'); if (empty($package)) { $output->writeln('Package rsync is not installed!'); exit; } if (isset($values['port'])) { $exec = 'rsync -avz -e "ssh -p ' . $values['port'] . '" --ignore-existing --exclude=*cache* '; if (count($excludes)) { foreach ($excludes as $exclude) { $exec .= '--exclude=' . $exclude . ' '; } } $exec .= $values['username'] . '@' . $values['host'] . ':' . $values['path'] . DS . 'media/* ' . $this->getApplication()->getMagentoRootFolder() . '/media'; } else { $exec = 'rsync -avz --ignore-existing --exclude=*cache* '; if (count($excludes)) { foreach ($excludes as $exclude) { $exec .= '--exclude=' . $exclude . ' '; } } $exec .= $values['username'] . '@' . $values['host'] . ':' . $values['path'] . DS . 'media/* ' . $this->getApplication()->getMagentoRootFolder() . '/media'; } $output->writeln($exec); } elseif ($mode == 'ftp') { // Syncing over FTP using ncftpget $package = exec('which ncftpget'); if (empty($package)) { $output->writeln('Package ncftpget is not installed!'); exit; } // Unfortunately no exclude option with ncftpget so cache files are also synced $exec = 'ncftpget -R -v -u "' . $values['username'] . '" -p "' . $values['password'] . '" ' . $values['host'] . ' ' . $values['path'] . DS . 'media' . DS . '* ' . $this->getApplication()->getMagentoRootFolder() . DS . 'media' . DS; } $output->writeln('Syncing media files to local server...'); $process = new Process($exec); $process->setTimeout(3600 * 10); $process->setIdleTimeout(3600); $process->run(function ($type, $buffer) { if (Process::ERR === $type) { echo 'ERROR > ' . $buffer; } else { echo $buffer; } }); $output->writeln('<info>Finished</info>'); } }
/** * @param \Symfony\Component\Console\Input\InputInterface $input * @param \Symfony\Component\Console\Output\OutputInterface $output * @return int|void */ protected function execute(InputInterface $input, OutputInterface $output) { $this->detectMagento($output); if (!$this->initMagento()) { return; } $options = array('port' => '', 'host' => '', 'username' => '', 'password' => '', 'path' => '', 'exclude' => array(), 'ignore-permissions' => ''); $requiredOptions = array('ftp' => array('host', 'username', 'password'), 'ssh' => array('host', 'username')); $config = \Mage::app()->getConfig(); $dialog = $this->getHelperSet()->get('dialog'); $mode = $input->getOption('mode'); $interactiveExecution = $mode === null; // if no mode is set, this run is interactive if ($interactiveExecution) { $mode = strtolower($dialog->ask($output, '<question>Mode (SSH or FTP)</question> <comment>[ssh]</comment>: ', 'ssh')); } if (!array_key_exists($mode, $requiredOptions)) { $output->writeln('<error>Only SSH or FTP is supported.</error>'); } if ($mode === 'ssh') { // rsync doesn't allow SSH password (easily) due to security concerns // assume key auth unset($options['password']); } foreach ($options as $option => $defaultValue) { // Fetch config value from app/etc/local.xml (if available) $node = $config->getNode('global/production/' . $mode . '/' . $option); $configValue = (string) $node[0]; if (!empty($configValue)) { // use the configuration value automatically when running non-interactively, otherwise allow confirmation or change if (!$interactiveExecution) { $optionValue = $configValue; } else { $optionValue = $dialog->ask($output, '<question>' . strtoupper($mode) . ' ' . ucwords($option) . ' </question> <comment>[' . $configValue . ']</comment>: ', $configValue); } } else { // no configuration value, get option value if running non-interactively, otherwise ask interactively if (!$interactiveExecution) { $optionValue = $input->getOption($option); } else { $optionValue = $dialog->ask($output, '<question>' . strtoupper($mode) . ' ' . ucwords($option) . '</question> <comment>[' . $defaultValue . ']</comment>: ', $defaultValue); } } if (in_array($option, $requiredOptions[$mode]) && empty($optionValue)) { $output->writeln('<error>Option ' . $option . ' cannot be empty!</error>'); exit; } $options[$option] = $optionValue; } if (!is_array($options['exclude'])) { // If this value is set interactively, it is supposed to come in as (comma-separated) string $options['exclude'] = array_filter(explode(',', $options['exclude'])); } $options['path'] = trim($options['path'], DIRECTORY_SEPARATOR); if ($mode === 'ssh') { // Syncing over SSH using rsync $package = exec('which rsync'); if (empty($package)) { $output->writeln('<error>Package rsync is not installed!</error>'); exit; } $exec = 'rsync -avz '; if (!empty($options['port'])) { $exec .= '-e "ssh -p ' . $options['port'] . '" '; } if (!empty($options['ignore-permissions'])) { $exec .= '--no-perms --no-owner --no-group '; } $exec .= '--ignore-existing --exclude=*cache* '; if (!empty($options['exclude'])) { foreach ($options['exclude'] as $exclude) { $exec .= '--exclude=' . $exclude . ' '; } } $exec .= $options['username'] . '@' . $options['host'] . ':' . $options['path'] . DS . 'media/* ' . $this->getApplication()->getMagentoRootFolder() . '/media'; } elseif ($mode == 'ftp') { // Syncing over FTP using ncftpget $package = exec('which ncftpget'); if (empty($package)) { $output->writeln('<error>Package ncftpget is not installed!</error>'); exit; } // Unfortunately no exclude option with ncftpget so cache files are also synced $exec = 'ncftpget -R -v -u "' . $options['username'] . '" -p "' . $options['password'] . '" ' . $options['host'] . ' ' . $options['path'] . DS . 'media' . DS . '* ' . $this->getApplication()->getMagentoRootFolder() . DS . 'media' . DS; } $output->writeln($exec); $output->writeln('<info>Syncing media files to local server...</info>'); $process = new Process($exec); $process->setTimeout(3600 * 10); $process->setIdleTimeout(3600); $process->run(function ($type, $buffer) { if (Process::ERR === $type) { echo 'ERROR > ' . $buffer; } else { echo $buffer; } }); $output->writeln('<info>Finished</info>'); }