Ejemplo n.º 1
0
 /**
  * Executes this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @throws \TYPO3\Surf\Exception\TaskExecutionException
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $configurationFileExtension = isset($options['configurationFileExtension']) ? $options['configurationFileExtension'] : 'yaml';
     $targetReleasePath = $deployment->getApplicationReleasePath($application);
     $configurationPath = $deployment->getDeploymentConfigurationPath();
     if (!is_dir($configurationPath)) {
         return;
     }
     $commands = array();
     $configurationFiles = Files::readDirectoryRecursively($configurationPath, $configurationFileExtension);
     foreach ($configurationFiles as $configuration) {
         $targetConfigurationPath = dirname(str_replace($configurationPath, '', $configuration));
         $escapedSourcePath = escapeshellarg($configuration);
         $escapedTargetPath = escapeshellarg(Files::concatenatePaths(array($targetReleasePath, 'Configuration', $targetConfigurationPath)) . '/');
         if ($node->isLocalhost()) {
             $commands[] = 'mkdir -p ' . $escapedTargetPath;
             $commands[] = 'cp ' . $escapedSourcePath . ' ' . $escapedTargetPath;
         } else {
             $username = isset($options['username']) ? $options['username'] . '@' : '';
             $hostname = $node->getHostname();
             $sshPort = isset($options['port']) ? '-p ' . escapeshellarg($options['port']) . ' ' : '';
             $scpPort = isset($options['port']) ? '-P ' . escapeshellarg($options['port']) . ' ' : '';
             $createDirectoryCommand = '"mkdir -p ' . $escapedTargetPath . '"';
             $commands[] = "ssh {$sshPort}{$username}{$hostname} {$createDirectoryCommand}";
             $commands[] = "scp {$scpPort}{$escapedSourcePath} {$username}{$hostname}:\"{$escapedTargetPath}\"";
         }
     }
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate($commands, $localhost, $deployment);
 }
Ejemplo n.º 2
0
 /**
  * Execute this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @return void
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $localPackagePath = $deployment->getWorkspacePath($application);
     $releasePath = $deployment->getApplicationReleasePath($application);
     $remotePath = $application->getDeploymentPath() . '/cache/transfer';
     // make sure there is a remote .cache folder
     $command = 'mkdir -p ' . $remotePath;
     $this->shell->executeOrSimulate($command, $node, $deployment);
     $username = $node->hasOption('username') ? $node->getOption('username') . '@' : '';
     $hostname = $node->getHostname();
     $port = $node->hasOption('port') ? ' -p ' . escapeshellarg($node->getOption('port')) : '';
     $key = $node->hasOption('privateKeyFile') ? ' -i ' . escapeshellarg($node->getOption('privateKeyFile')) : '';
     $quietFlag = isset($options['verbose']) && $options['verbose'] ? '' : '-q';
     $rshFlag = $node->isLocalhost() ? '' : '--rsh="ssh' . $port . $key . '" ';
     $rsyncFlags = isset($options['rsyncFlags']) ? $options['rsyncFlags'] : "--recursive --times --perms --links --delete --delete-excluded --exclude '.git'";
     $destinationArgument = $node->isLocalhost() ? $remotePath : "{$username}{$hostname}:{$remotePath}";
     $command = "rsync {$quietFlag} --compress {$rshFlag} {$rsyncFlags} " . escapeshellarg($localPackagePath . '/.') . ' ' . escapeshellarg($destinationArgument);
     if ($node->hasOption('password')) {
         $resourcesPath = realpath(__DIR__ . '/../../../Resources');
         $passwordSshLoginScriptPathAndFilename = $resourcesPath . '/Private/Scripts/PasswordSshLogin.expect';
         $command = sprintf('expect %s %s %s', escapeshellarg($passwordSshLoginScriptPathAndFilename), escapeshellarg($node->getOption('password')), $command);
     }
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate($command, $localhost, $deployment);
     $command = strtr("cp -RPp {$remotePath}/. {$releasePath}", "\t\n", '  ');
     // TODO Copy revision file (if it exists) for application to deployment path with release identifier
     $this->shell->executeOrSimulate($command, $node, $deployment);
 }
Ejemplo n.º 3
0
 /**
  * Execute this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  * @return void
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $this->assertRequiredOptionsExist($options);
     $dumpCommand = new ProcessBuilder();
     $dumpCommand->setPrefix('mysqldump');
     $dumpCommand->setArguments(array('-h', $options['sourceHost'], '-u', $options['sourceUser'], '-p' . $options['sourcePassword'], $options['sourceDatabase']));
     $mysqlCommand = new ProcessBuilder();
     $mysqlCommand->setPrefix('mysql');
     $mysqlCommand->setArguments(array('-h', $options['targetHost'], '-u', $options['targetUser'], '-p' . $options['targetPassword'], $options['targetDatabase']));
     $arguments = array();
     $username = isset($options['username']) ? $options['username'] . '@' : '';
     $hostname = $node->getHostname();
     $arguments[] = $username . $hostname;
     if ($node->hasOption('port')) {
         $arguments[] = '-P';
         $arguments[] = $node->getOption('port');
     }
     $arguments[] = $mysqlCommand->getProcess()->getCommandLine();
     $sshCommand = new ProcessBuilder();
     $sshCommand->setPrefix('ssh');
     $sshCommand->setArguments($arguments);
     $command = $dumpCommand->getProcess()->getCommandLine() . ' | ' . $sshCommand->getProcess()->getCommandLine();
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate($command, $localhost, $deployment);
 }
 /**
  * Executes this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  * @return void
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $options['username'] = isset($options['username']) ? $options['username'] . '@' : '';
     $targetReleasePath = $deployment->getApplicationReleasePath($application);
     $configurationPath = $deployment->getDeploymentConfigurationPath() . '/';
     if (!is_dir($configurationPath)) {
         return;
     }
     $configurations = \TYPO3\Flow\Utility\Files::readDirectoryRecursively($configurationPath);
     $commands = array();
     foreach ($configurations as $configuration) {
         $targetConfigurationPath = dirname(str_replace($configurationPath, '', $configuration));
         if ($node->isLocalhost()) {
             $commands[] = "mkdir -p '{$targetReleasePath}/Configuration/{$targetConfigurationPath}/'";
             $commands[] = "cp {$configuration} {$targetReleasePath}/Configuration/{$targetConfigurationPath}/";
         } else {
             $username = $options['username'];
             $hostname = $node->getHostname();
             $port = $node->hasOption('port') ? '-P ' . escapeshellarg($node->getOption('port')) : '';
             $commands[] = "ssh {$port} {$username}{$hostname} 'mkdir -p {$targetReleasePath}/Configuration/{$targetConfigurationPath}/'";
             $commands[] = "scp {$port} {$configuration} {$username}{$hostname}:{$targetReleasePath}/Configuration/{$targetConfigurationPath}/";
         }
     }
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate($commands, $localhost, $deployment);
 }
Ejemplo n.º 5
0
 /**
  * Executes this task
  *
  * Options:
  *   command: The command to execute
  *   rollbackCommand: The command to execute as a rollback (optional)
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @return void
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     if (!isset($options['folders'])) {
         return;
     }
     $folders = $options['folders'];
     if (!is_array($folders)) {
         $folders = array($folders);
     }
     $replacePaths = array('{deploymentPath}' => escapeshellarg($application->getDeploymentPath()), '{sharedPath}' => escapeshellarg($application->getSharedPath()), '{releasePath}' => escapeshellarg($deployment->getApplicationReleasePath($application)), '{currentPath}' => escapeshellarg($application->getReleasesPath() . '/current'), '{previousPath}' => escapeshellarg($application->getReleasesPath() . '/previous'));
     $commands = array();
     $username = isset($options['username']) ? $options['username'] . '@' : '';
     $hostname = $node->getHostname();
     $port = $node->hasOption('port') ? '-P ' . escapeshellarg($node->getOption('port')) : '';
     foreach ($folders as $folderPair) {
         if (!is_array($folderPair) || count($folderPair) !== 2) {
             throw new InvalidConfigurationException('Each rsync folder definition must be an array of exactly two folders', 1405599056);
         }
         $sourceFolder = rtrim(str_replace(array_keys($replacePaths), $replacePaths, $folderPair[0]), '/') . '/';
         $targetFolder = rtrim(str_replace(array_keys($replacePaths), $replacePaths, $folderPair[1]), '/') . '/';
         $commands[] = "rsync -avz --delete -e ssh {$sourceFolder} {$username}{$hostname}:{$targetFolder}";
     }
     $ignoreErrors = isset($options['ignoreErrors']) && $options['ignoreErrors'] === true;
     $logOutput = !(isset($options['logOutput']) && $options['logOutput'] === false);
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate($commands, $localhost, $deployment, $ignoreErrors, $logOutput);
 }
Ejemplo n.º 6
0
 /**
  * Execute this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options Supported options: "scriptBasePath" and "scriptIdentifier"
  * @return void
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  * @throws \TYPO3\Surf\Exception\TaskExecutionException
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $workspacePath = $deployment->getWorkspacePath($application);
     $scriptBasePath = isset($options['scriptBasePath']) ? $options['scriptBasePath'] : Files::concatenatePaths(array($workspacePath, 'Web'));
     if (!isset($options['scriptIdentifier'])) {
         // Generate random identifier
         $factory = new \RandomLib\Factory();
         $generator = $factory->getMediumStrengthGenerator();
         $scriptIdentifier = $generator->generateString(32, \RandomLib\Generator::CHAR_ALNUM);
         // Store the script identifier as an application option
         $application->setOption('TYPO3\\Surf\\Task\\Php\\WebOpcacheResetExecuteTask[scriptIdentifier]', $scriptIdentifier);
     } else {
         $scriptIdentifier = $options['scriptIdentifier'];
     }
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $commands = array('cd ' . escapeshellarg($scriptBasePath), 'rm -f surf-opcache-reset-*');
     $this->shell->executeOrSimulate($commands, $localhost, $deployment);
     if (!$deployment->isDryRun()) {
         $scriptFilename = $scriptBasePath . '/surf-opcache-reset-' . $scriptIdentifier . '.php';
         $result = file_put_contents($scriptFilename, '<?php
             if (function_exists("opcache_reset")) {
                 opcache_reset();
             }
             @unlink(__FILE__);
             echo "success";
         ');
         if ($result === false) {
             throw new \TYPO3\Surf\Exception\TaskExecutionException('Could not write file "' . $scriptFilename . '"', 1421932414);
         }
     }
 }
Ejemplo n.º 7
0
 /**
  * Execute this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @throws InvalidConfigurationException
  * @return void
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $this->assertRequiredOptionsExist($options);
     $username = isset($options['username']) ? $options['username'] . '@' : '';
     $hostname = $node->getHostname();
     $port = $node->hasOption('port') ? '-P ' . escapeshellarg($node->getOption('port')) : '';
     $commands[] = "mysqldump -h {$options['sourceHost']} -u{$options['sourceUser']} -p{$options['sourcePassword']} {$options['sourceDatabase']} | ssh {$port} {$username}{$hostname} 'mysql -h {$options['targetHost']} -u{$options['targetUser']} -p{$options['targetPassword']} {$options['targetDatabase']}'";
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate($commands, $localhost, $deployment);
 }
Ejemplo n.º 8
0
 /**
  * Rollback this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @return void
  */
 public function rollback(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $replacePaths = array();
     $replacePaths['{workspacePath}'] = escapeshellarg($deployment->getWorkspacePath($application));
     if (!isset($options['rollbackCommand'])) {
         return;
     }
     $command = $options['rollbackCommand'];
     $command = str_replace(array_keys($replacePaths), $replacePaths, $command);
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->execute($command, $localhost, $deployment, true);
 }
Ejemplo n.º 9
0
 /**
  * Execute this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @return void
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     if (!$node->getOption('webBaseUrl')) {
         throw new \InvalidArgumentException('The webBaseUrl option must be set in all nodes for which the ClearOpcacheTask should be executed.');
     }
     if (empty($options['deployutilsToken'])) {
         throw new \InvalidArgumentException('The deployutilsToken option is missing.');
     }
     $url = rtrim($node->getOption('webBaseUrl'), '/') . '/typo3conf/ext/deployutils/Resources/Php/ClearOpcache.php?token=';
     $deployment->getLogger()->debug('Calling opcache clearing script at: ' . $url . 'xxx');
     $url = $url . urlencode($options['deployutilsToken']);
     $result = $this->executeLocalCurlRequest($url, 5);
     $this->assertExpectedStatus(['expectedStatus' => 200], $result);
     $this->assertExpectedRegexp(['expectedRegexp' => '/success/'], $result);
 }
Ejemplo n.º 10
0
 /**
  * @param Node $node
  * @param Application $application
  * @param string $path
  * @param string $file
  * @return string
  */
 protected function getArgument(Node $node, Application $application, $path, $file)
 {
     $argument = '';
     if ($node->hasOption('username')) {
         $username = $node->getOption('username');
         if (!empty($username)) {
             $argument .= $username . '@';
         }
     }
     $argument .= $node->getHostname() . ':';
     $argument .= rtrim($application->getReleasesPath(), '/') . '/';
     $argument = rtrim($argument . $path, '/') . '/';
     $argument .= $file;
     return $argument;
 }
Ejemplo n.º 11
0
 /**
  * Executes this task
  *
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param array $options
  * @throws \TYPO3\Surf\Exception\TaskExecutionException
  * @throws \TYPO3\Surf\Exception\InvalidConfigurationException
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $options['username'] = isset($options['username']) ? $options['username'] . '@' : '';
     $targetReleasePath = $deployment->getApplicationReleasePath($application);
     $configurationPath = $deployment->getDeploymentConfigurationPath() . '/';
     if (!is_dir($configurationPath)) {
         return;
     }
     $encryptedConfiguration = glob($configurationPath . '*.yaml.encrypted');
     if (count($encryptedConfiguration) > 0) {
         throw new \TYPO3\Surf\Exception\TaskExecutionException('You have sealed configuration files, please open the configuration for "' . $deployment->getName() . '"', 1317229449);
     }
     $configurations = glob($configurationPath . '*.yaml');
     $commands = array();
     foreach ($configurations as $configuration) {
         $targetConfigurationPath = dirname(str_replace($configurationPath, '', $configuration));
         if ($node->isLocalhost()) {
             $commands[] = "mkdir -p '{$targetReleasePath}/Configuration/{$targetConfigurationPath}/'";
             $commands[] = "cp {$configuration} {$targetReleasePath}/Configuration/{$targetConfigurationPath}/";
         } else {
             $username = $options['username'];
             $hostname = $node->getHostname();
             $sshPort = $node->hasOption('port') ? '-p ' . escapeshellarg($node->getOption('port')) : '';
             $scpPort = $node->hasOption('port') ? '-P ' . escapeshellarg($node->getOption('port')) : '';
             $commands[] = "ssh {$sshPort} {$username}{$hostname} 'mkdir -p {$targetReleasePath}/Configuration/{$targetConfigurationPath}/'";
             $commands[] = "scp {$scpPort} {$configuration} {$username}{$hostname}:{$targetReleasePath}/Configuration/{$targetConfigurationPath}/";
         }
     }
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate($commands, $localhost, $deployment);
 }
Ejemplo n.º 12
0
 /**
  * Set up test dependencies
  *
  * This sets up a stubbed shell command service to record command executions
  * and return predefined command responses.
  */
 protected function setUp()
 {
     $this->commands = array('executed' => array());
     $commands =& $this->commands;
     $this->responses = array();
     $responses =& $this->responses;
     /** @var \TYPO3\Surf\Domain\Service\ShellCommandService|\PHPUnit_Framework_MockObject_MockObject $shellCommandService */
     $shellCommandService = $this->getMock('TYPO3\\Surf\\Domain\\Service\\ShellCommandService');
     $shellCommandService->expects($this->any())->method('execute')->will($this->returnCallback(function ($command) use(&$commands, &$responses) {
         if (is_array($command)) {
             $commands['executed'] = array_merge($commands['executed'], $command);
         } else {
             $commands['executed'][] = $command;
             if (isset($responses[$command])) {
                 return $responses[$command];
             }
         }
         return '';
     }));
     $shellCommandService->expects($this->any())->method('executeOrSimulate')->will($this->returnCallback(function ($command) use(&$commands, $responses) {
         if (is_array($command)) {
             $commands['executed'] = array_merge($commands['executed'], $command);
         } else {
             $commands['executed'][] = $command;
             if (isset($responses[$command])) {
                 return $responses[$command];
             }
         }
         return '';
     }));
     $this->task = $this->createTask();
     if ($this->task instanceof ShellCommandServiceAwareInterface) {
         $this->task->setShellCommandService($shellCommandService);
     }
     $this->node = new \TYPO3\Surf\Domain\Model\Node('TestNode');
     $this->node->setHostname('hostname');
     $this->deployment = new \TYPO3\Surf\Domain\Model\Deployment('TestDeployment');
     /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $mockLogger */
     $mockLogger = $this->getMock('Psr\\Log\\LoggerInterface');
     $this->deployment->setLogger($mockLogger);
     $this->deployment->setWorkspacesBasePath('./Data/Surf');
     $this->application = new \TYPO3\Surf\Domain\Model\Application('TestApplication');
     $this->deployment->initialize();
 }
Ejemplo n.º 13
0
 /**
  * Executes this task
  *
  * @param Node $node
  * @param Application $application
  * @param Deployment $deployment
  * @param array $options
  * @return void
  * @throws InvalidConfigurationException
  * @throws TaskExecutionException
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     if (!empty($options['disableDeploymentTag'])) {
         return;
     }
     if (isset($options['useApplicationWorkspace']) && $options['useApplicationWorkspace'] === TRUE) {
         $gitRootPath = $deployment->getWorkspacePath($application);
     } else {
         $gitRootPath = $deployment->getApplicationReleasePath($application);
     }
     $tagPrefix = isset($options['deploymentTagPrefix']) ? $options['deploymentTagPrefix'] : 'server-';
     $tagName = preg_replace('/[^a-zA-Z0-9-_\\.]*/', '', $tagPrefix . $node->getName());
     $quietFlag = isset($options['verbose']) && $options['verbose'] ? '' : '-q';
     if (!empty($options['nodeName'])) {
         $node = $deployment->getNode($options['nodeName']);
         if ($node === NULL) {
             throw new InvalidConfigurationException(sprintf('Node "%s" not found', $options['nodeName']), 1408441582);
         }
     }
     $commands = array('cd ' . escapeshellarg($gitRootPath), 'git tag --force -- ' . escapeshellarg($tagName), 'git push origin --force ' . $quietFlag . ' -- ' . escapeshellarg($tagName));
     $this->shell->executeOrSimulate($commands, $node, $deployment);
 }
Ejemplo n.º 14
0
 /**
  * @test
  */
 public function applicationOptionsOverrideNodeOptions()
 {
     $nodeOptions = array('MyVendor\\MyPackage\\Task\\TaskGroup\\MyTask[taskOption]' => 'Node');
     $this->node->setOptions($nodeOptions);
     $applicationOptions = array('MyVendor\\MyPackage\\Task\\TaskGroup\\MyTask[taskOption]' => 'Application');
     $this->application->setOptions($applicationOptions);
     $this->task->expects($this->atLeastOnce())->method('execute')->willReturnCallback(function ($_, $__, $___, $options) {
         if ($options['taskOption'] !== 'Application') {
             throw new \RuntimeException('Node options do not override deployment options!');
         }
     });
     $localOptions = array();
     $this->taskManager->execute('MyVendor\\MyPackage\\Task\\TaskGroup\\MyTask', $this->node, $this->application, $this->deployment, 'test', $localOptions);
 }
Ejemplo n.º 15
0
 /**
  * Executes this task
  *
  * @param Node $node
  * @param Application $application
  * @param Deployment $deployment
  * @param array $options
  * @throws TaskExecutionException
  * @return void
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     if ($node->isLocalhost()) {
         $deployment->getLogger()->log('node seems not to be a remote node', LOG_DEBUG);
     } else {
         $username = $node->hasOption('username') ? $node->getOption('username') : NULL;
         if (!empty($username)) {
             $username = $username . '@';
         }
         $hostname = $node->getHostname();
         $sshOptions = array('-A', '-q', '-o BatchMode=yes');
         if ($node->hasOption('port')) {
             $sshOptions[] = '-p ' . escapeshellarg($node->getOption('port'));
         }
         $command = 'ssh ' . implode(' ', $sshOptions) . ' ' . escapeshellarg($username . $hostname) . ' exit;';
         $this->shell->execute($command, $deployment->getNode('localhost'), $deployment);
         $deployment->getLogger()->log('SSH connection successfully established', LOG_DEBUG);
     }
 }
Ejemplo n.º 16
0
 /**
  * @param Node $node
  * @param string $file
  * @return string
  */
 protected function getArgument(Node $node, $file)
 {
     if ($node->isLocalhost() === TRUE) {
         return $file;
     }
     $argument = '';
     if ($node->hasOption('port')) {
         $port = $node->getOption('port');
         if (!empty($port)) {
             $argument .= '-P ' . $port . ' ';
         }
     }
     if ($node->hasOption('username')) {
         $username = $node->getOption('username');
         if (!empty($username)) {
             $argument .= $username . '@';
         }
     }
     $argument .= $node->getHostname() . ':';
     $argument .= $file;
     return $argument;
 }
Ejemplo n.º 17
0
 /**
  * Return TRUE if the given node is registered for this application
  *
  * @param Node $node The node to test
  * @return bool TRUE if the node is registered for this application
  */
 public function hasNode(Node $node)
 {
     return isset($this->nodes[$node->getName()]);
 }
Ejemplo n.º 18
0
 /**
  * @param Node $node
  * @param string $path
  * @return string
  */
 protected function getFullPath(Node $node, $path)
 {
     $hostArgument = '';
     if ($node->isLocalhost() === FALSE) {
         if ($node->hasOption('username')) {
             $hostArgument .= $node->getOption('username') . '@';
         }
         $hostArgument .= $node->getHostname() . ':';
     }
     return escapeshellarg($hostArgument . rtrim($path, '/') . '/');
 }
Ejemplo n.º 19
0
 /**
  * Execute a stage for a node and application
  *
  * @param string $stage
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @return void
  */
 protected function executeStage($stage, Node $node, Application $application, Deployment $deployment)
 {
     foreach (array('before', 'tasks', 'after') as $stageStep) {
         foreach (array('_', $application->getName()) as $applicationName) {
             $label = $applicationName === '_' ? 'for all' : 'for application ' . $applicationName;
             if (isset($this->tasks['stage'][$applicationName][$stage][$stageStep])) {
                 $deployment->getLogger()->debug('Executing stage "' . $stage . '" (step "' . $stageStep . '") on "' . $node->getName() . '" ' . $label);
                 foreach ($this->tasks['stage'][$applicationName][$stage][$stageStep] as $task) {
                     $this->executeTask($task, $node, $application, $deployment, $stage);
                 }
             }
         }
     }
 }
 public function copy($source, $destination)
 {
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate(array('scp ' . $source . ' ' . $this->username . '@' . $this->hostname . ':' . $destination), $localhost, $this->deployment);
 }
Ejemplo n.º 21
0
 /**
  * @param Node $node
  * @param Deployment $deployment
  * @param array $options
  * @param Application $application
  * @return string
  * @throws InvalidConfigurationException
  * @throws TaskExecutionException
  */
 protected function getSharedPathFromNode(Node $node, Deployment $deployment, $options, Application $application)
 {
     if ($node->hasOption('sharedPath')) {
         $sharedPath = $node->getOption('sharedPath');
     } else {
         if ($node->hasOption('deploymentPath')) {
             $deploymentPath = $node->getOption('deploymentPath');
         } elseif (!empty($options['deploymentPath'])) {
             $deploymentPath = $options['deploymentPath'];
         } else {
             throw new InvalidConfigurationException('No deploymentPath defined!', 1414849872);
         }
         $webDir = $this->getWebDir($deployment, $application);
         if ($webDir !== '') {
             $deploymentPath = rtrim($deploymentPath, '/') . '/' . $webDir;
         }
         $commands = array();
         $commands[] = 'cd ' . escapeshellarg($deploymentPath);
         $commands[] = 'readlink ' . escapeshellarg('fileadmin');
         $output = $this->shell->execute($commands, $node, $deployment, TRUE);
         if (preg_match('/(.+)\\/fileadmin\\/?$/', trim($output), $matches)) {
             $sharedPath = $matches[1];
         } else {
             $sharedPath = str_replace('htdocs', 'shared', $deploymentPath);
         }
     }
     if ($sharedPath[0] !== '/') {
         $sharedPath = rtrim($deploymentPath, '/') . '/' . $sharedPath;
     }
     return rtrim($sharedPath, '/') . '/';
 }
 /**
  * @param string $localPath
  * @param string $remotePath
  */
 protected function upload($localPath, $remotePath)
 {
     $cmd = sprintf('rsync  -e "ssh -p %d" -avz %s %s@%s:%s', $this->remoteNode->getOption('port'), $localPath, $this->remoteNode->getOption('username'), $this->remoteNode->getHostname(), $remotePath);
     $this->log('Uploading files to remote instance');
     $this->shell->executeOrSimulate($cmd, $this->localNode, $this->deployment);
 }
Ejemplo n.º 23
0
 /**
  * Get a node by name
  *
  * In the special case "localhost" an ad-hoc Node with hostname "localhost" is returned.
  *
  * @return \TYPO3\Surf\Domain\Model\Node The Node or NULL if no Node with the given name was found
  */
 public function getNode($name)
 {
     if ($name === 'localhost') {
         $node = new Node('localhost');
         $node->setHostname('localhost');
         return $node;
     }
     $nodes = $this->getNodes();
     return isset($nodes[$name]) ? $nodes[$name] : null;
 }
Ejemplo n.º 24
0
 /**
  * Execute a shell command via SSH
  *
  * @param mixed $command
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param bool $logOutput TRUE if the output of the command should be logged
  * @return array
  */
 protected function executeRemoteCommand($command, Node $node, Deployment $deployment, $logOutput = true)
 {
     $command = $this->prepareCommand($command);
     $deployment->getLogger()->debug('$' . $node->getName() . ': "' . $command . '"');
     if ($node->hasOption('remoteCommandExecutionHandler')) {
         $remoteCommandExecutionHandler = $node->getOption('remoteCommandExecutionHandler');
         /** @var $remoteCommandExecutionHandler callable */
         return $remoteCommandExecutionHandler($this, $command, $node, $deployment, $logOutput);
     }
     $username = $node->hasOption('username') ? $node->getOption('username') : null;
     if (!empty($username)) {
         $username = $username . '@';
     }
     $hostname = $node->getHostname();
     // TODO Get SSH options from node or deployment
     $sshOptions = array('-A');
     if ($node->hasOption('port')) {
         $sshOptions[] = '-p ' . escapeshellarg($node->getOption('port'));
     }
     if ($node->hasOption('password')) {
         $sshOptions[] = '-o PubkeyAuthentication=no';
     }
     if ($node->hasOption('privateKeyFile')) {
         $sshOptions[] = '-i ' . escapeshellarg($node->getOption('privateKeyFile'));
     }
     $sshCommand = 'ssh ' . implode(' ', $sshOptions) . ' ' . escapeshellarg($username . $hostname) . ' ' . escapeshellarg($command);
     if ($node->hasOption('password')) {
         $resourcesPath = realpath(__DIR__ . '/../../../Resources');
         $passwordSshLoginScriptPathAndFilename = $resourcesPath . '/Private/Scripts/PasswordSshLogin.expect';
         $sshCommand = sprintf('expect %s %s %s', escapeshellarg($passwordSshLoginScriptPathAndFilename), escapeshellarg($node->getOption('password')), $sshCommand);
     }
     return $this->executeProcess($deployment, $sshCommand, $logOutput, '    > ');
 }
Ejemplo n.º 25
0
 /**
  * Override options for a task
  *
  * The order of the options is:
  *
  *   Deployment, Node, Application, Task
  *
  * A task option will always override more global options from the
  * Deployment, Node or Application.
  *
  * Global options for a task should be prefixed with the task name to prevent naming
  * issues between different tasks. For example passing a special option to the
  * GitCheckoutTask could be expressed like 'TYPO3\\Surf\\Task\\GitCheckoutTask[sha1]' => '1234...'.
  *
  * @param string $taskName
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Application $application
  * @param array $taskOptions
  * @return array
  */
 protected function overrideOptions($taskName, Deployment $deployment, Node $node, Application $application, array $taskOptions)
 {
     $globalOptions = array_merge($deployment->getOptions(), $node->getOptions(), $application->getOptions());
     $globalTaskOptions = array();
     foreach ($globalOptions as $optionKey => $optionValue) {
         if (strlen($optionKey) > strlen($taskName) && strpos($optionKey, $taskName) === 0 && $optionKey[strlen($taskName)] === '[') {
             $globalTaskOptions[substr($optionKey, strlen($taskName) + 1, -1)] = $optionValue;
         }
     }
     return array_merge($globalOptions, $globalTaskOptions, $taskOptions);
 }
Ejemplo n.º 26
0
    $application->setDeploymentPath(getenv('DEPLOYMENT_PATH'));
} else {
    throw new \Exception('Deployment path must be set in the DEPLOYMENT_PATH env variable.');
}
$application->setOption('repositoryUrl', 'git://git.typo3.org/Sites/NeosTypo3Org.git');
$application->setOption('sitePackageKey', 'TYPO3.NeosTypo3Org');
$application->setOption('keepReleases', 50);
$application->setOption('composerCommandPath', 'php /var/www/vhosts/neos.typo3.org/home/composer.phar');
$deployment->addApplication($application);
$workflow = new SimpleWorkflow();
# $workflow->setEnableRollback(FALSE);
$deployment->setWorkflow($workflow);
$deployment->onInitialize(function () use($workflow, $application) {
    $workflow->removeTask('typo3.surf:flow3:setfilepermissions');
    $workflow->removeTask('typo3.surf:flow3:copyconfiguration');
    $workflow->removeTask('typo3.surf:typo3:importsite');
});
#$workflow->afterTask('typo3.surf:symlinkrelease', array('typo3.surf:varnishpurge'), $application);
if (getenv('DEPLOYMENT_HOST')) {
    $hostName = getenv('DEPLOYMENT_HOST');
} else {
    throw new \Exception('Deployment host name must be set in the DEPLOYMENT_HOST env variable.');
}
$node = new Node($hostName);
$node->setHostname($hostName);
if (getenv('DEPLOYMENT_USERNAME')) {
    $node->setOption('username', getenv('DEPLOYMENT_USERNAME'));
} else {
    throw new \Exception('Username must be set in the DEPLOYMENT_USERNAME env variable.');
}
$application->addNode($node);
<?php

use TYPO3\Surf\Domain\Model\Workflow;
use TYPO3\Surf\Domain\Model\Node;
use TYPO3\Surf\Domain\Model\SimpleWorkflow;
$application = new \Famelo\Surf\SharedHosting\Application\Flow();
$application->setOption('repositoryUrl', '{repositoryUrl}');
$application->setDeploymentPath('{directory}');
$application->setOption('keepReleases', 3);
$application->setOption('defaultContext', 'Production');
$application->setOption('composerCommandPath', '/html/composer.phar');
$application->setHosting('Mittwald');
$application->setOption('transferMethod', 'rsync');
$application->setOption('packageMethod', 'git');
$application->setOption('updateMethod', NULL);
$deployment->addApplication($application);
$workflow = new SimpleWorkflow();
$workflow->setEnableRollback(FALSE);
$workflow->afterTask('typo3.surf:typo3:flow:copyconfiguration', array('famelo.surf.sharedhosting:downloadbeard', 'famelo.surf.sharedhosting:beardpatch'), $application);
$deployment->setWorkflow($workflow);
$node = new Node('{host}');
$node->setHostname('{host}');
$node->setOption('username', '{user}');
$application->addNode($node);
$deployment->addApplication($application);
Ejemplo n.º 28
0
 /**
  * Execute a shell command via SSH
  *
  * @param mixed $command
  * @param \TYPO3\Surf\Domain\Model\Node $node
  * @param \TYPO3\Surf\Domain\Model\Deployment $deployment
  * @param bool $logOutput TRUE if the output of the command should be logged
  * @return array
  */
 protected function executeRemoteCommand($command, Node $node, Deployment $deployment, $logOutput = true)
 {
     $command = $this->prepareCommand($command);
     $deployment->getLogger()->debug('$' . $node->getName() . ': "' . $command . '"');
     if ($node->hasOption('remoteCommandExecutionHandler')) {
         $remoteCommandExecutionHandler = $node->getOption('remoteCommandExecutionHandler');
         /** @var $remoteCommandExecutionHandler callable */
         return $remoteCommandExecutionHandler($this, $command, $node, $deployment, $logOutput);
     }
     $username = $node->hasOption('username') ? $node->getOption('username') : null;
     if (!empty($username)) {
         $username = $username . '@';
     }
     $hostname = $node->getHostname();
     // TODO Get SSH options from node or deployment
     $sshOptions = array('-A');
     if ($node->hasOption('port')) {
         $sshOptions[] = '-p ' . escapeshellarg($node->getOption('port'));
     }
     if ($node->hasOption('password')) {
         $sshOptions[] = '-o PubkeyAuthentication=no';
     }
     if ($node->hasOption('privateKeyFile')) {
         $sshOptions[] = '-i ' . escapeshellarg($node->getOption('privateKeyFile'));
     }
     $sshCommand = 'ssh ' . implode(' ', $sshOptions) . ' ' . escapeshellarg($username . $hostname) . ' ' . escapeshellarg($command);
     if ($node->hasOption('password')) {
         $passwordSshLoginScriptPathAndFilename = Files::concatenatePaths(array(dirname(dirname(dirname(__DIR__))), 'Resources', 'Private/Scripts/PasswordSshLogin.expect'));
         if (\Phar::running() !== '') {
             $passwordSshLoginScriptContents = file_get_contents($passwordSshLoginScriptPathAndFilename);
             $passwordSshLoginScriptPathAndFilename = Files::concatenatePaths(array($deployment->getTemporaryPath(), 'PasswordSshLogin.expect'));
             file_put_contents($passwordSshLoginScriptPathAndFilename, $passwordSshLoginScriptContents);
         }
         $sshCommand = sprintf('expect %s %s %s', escapeshellarg($passwordSshLoginScriptPathAndFilename), escapeshellarg($node->getOption('password')), $sshCommand);
     }
     $success = $this->executeProcess($deployment, $sshCommand, $logOutput, '    > ');
     if (isset($passwordSshLoginScriptPathAndFilename) && \Phar::running() !== '') {
         unlink($passwordSshLoginScriptPathAndFilename);
     }
     return $success;
 }
$application->setOption('createTags', getenv('CREATE_TAGS') !== 'false');
$application->setOption('pushTags', getenv('PUSH_TAGS') === 'true');
if (getenv('SOURCEFORGE_USER') && getenv('ENABLE_SOURCEFORGE_UPLOAD') === 'true') {
    $application->setOption('enableSourceforgeUpload', TRUE);
    $application->setOption('sourceforgeUserName', getenv('SOURCEFORGE_USER'));
}
if (getenv('RELEASE_HOST')) {
    $application->setOption('releaseHost', getenv('RELEASE_HOST'));
    $application->setOption('releaseHostLogin', getenv('RELEASE_HOST_LOGIN'));
    $application->setOption('releaseHostSitePath', getenv('RELEASE_HOST_SITE_PATH'));
}
if (getenv('WORKSPACE')) {
    $application->setDeploymentPath(getenv('WORKSPACE'));
} else {
    throw new \Exception('Deployment path must be set in the WORKSPACE env variable');
}
$deployment->addApplication($application);
$workflow = new SimpleWorkflow();
$deployment->setWorkflow($workflow);
// Remove the setfilepermissions task because Surf doesn't use sudo ...
// And we do not need any data or configuration in the release archives ...
$deployment->onInitialize(function () use($workflow, $application) {
    $workflow->removeTask('typo3.surf:flow:setfilepermissions');
    $workflow->removeTask('typo3.surf:flow:symlinkdata');
    $workflow->removeTask('typo3.surf:flow:symlinkconfiguration');
    $workflow->removeTask('typo3.surf:flow:copyconfiguration');
});
$workflow->setEnableRollback(FALSE);
$node = new Node('localhost');
$node->setHostname('localhost');
$application->addNode($node);
Ejemplo n.º 30
0
$application->setOption('packageMethod', 'git');
$application->setOption('updateMethod', NULL);
$application->setContext('Production');
$application->setDeploymentPath('/home/hostroot/sites/langeland/iotdemo');
$application->setOption('keepReleases', 2);
$deployment->addApplication($application);
$workflow = new SimpleWorkflow();
$workflow->setEnableRollback(TRUE);
// Prevent local Settings.yaml from being transferred
$workflow->defineTask('typo3.surf:shell:removeLocalConfiguration', 'typo3.surf:shell', array('command' => 'cd "{releasePath}" && rm -f Configuration/Settings.yaml'));
$workflow->beforeStage('migrate', array('typo3.surf:shell:removeLocalConfiguration'), $application);
// Remove resource links since they're absolute symlinks to previous releases (will be generated again automatically)
$workflow->defineTask('typo3.surf:shell:unsetResourceLinks', 'typo3.surf:shell', array('command' => 'cd {releasePath} && rm -rf Web/_Resources/Persistent/*(N)'));
$workflow->beforeStage('switch', array('typo3.surf:shell:unsetResourceLinks'), $application);
$workflow->afterStage('switch', 'typo3.surf:typo3:flow:publishresources', $application);
// Clear PHP 5.5+ OpCache (required for php-fpm)
//$resetScriptFilename = 'surf-opcache-reset-' . uniqid() . '.php';
//$workflow->defineTask('fn:clearopcache',
//	'typo3.surf:shell',
//	array('command' => 'cd {currentPath}/Web && echo "<?php if (function_exists(\"opcache_reset\")) { opcache_reset(); } @unlink(__FILE__); echo \"cache cleared\";" > ' . $resetScriptFilename . ' && curl -s "http://kmcpr-live.lombard.pil.dk/' . $resetScriptFilename . '" && rm -rf ' . $resetScriptFilename)
//);
//$workflow->afterStage('switch', array('fn:clearopcache'), $application);
$deployment->setWorkflow($workflow);
$deployment->onInitialize(function () use($workflow, $application) {
    $workflow->setTaskOptions('typo3.surf:generic:createDirectories', array('directories' => array('shared/Data/Web/_Resources', 'shared/Data/Session')));
    $workflow->setTaskOptions('typo3.surf:generic:createSymlinks', array('symlinks' => array('Web/_Resources' => '../../../shared/Data/Web/_Resources/', 'Data/Session' => '../../../shared/Data/Session/')));
});
$node = new Node('Flab');
$node->setHostname('ny.flab.dk');
$node->setOption('username', 'langeland');
$application->addNode($node);