mirror of
https://github.com/hauke68/Magallanes.git
synced 2026-09-06 09:28:57 +02:00
Merge branch 'develop' into task-factory-test
Conflicts: Mage/Task/Factory.php
This commit is contained in:
@@ -211,7 +211,11 @@ class DeployCommand extends AbstractCommand implements RequiresEnvironment
|
||||
if (self::$failedTasks === 0) {
|
||||
$exitCode = 0;
|
||||
}
|
||||
|
||||
|
||||
if (self::$deployStatus === self::FAILED) {
|
||||
$exitCode = 1;
|
||||
}
|
||||
|
||||
return $exitCode;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,14 +43,17 @@ class Factory
|
||||
// try a custom command
|
||||
$className = 'Command\\' . $commandName;
|
||||
|
||||
// TODO use a custom exception
|
||||
if (!class_exists($className)) {
|
||||
throw new Exception('Command "' . $commandName . '" not found.');
|
||||
}
|
||||
}
|
||||
|
||||
/** @var AbstractCommand $instance */
|
||||
// TODO dependencies like $config should be injected into constructor
|
||||
$instance = new $className;
|
||||
if (! $instance instanceOf AbstractCommand) {
|
||||
// TODO use a custom exception
|
||||
throw new Exception('The command ' . $commandName . ' must be an instance of Mage\Command\AbstractCommand.');
|
||||
}
|
||||
|
||||
|
||||
@@ -391,6 +391,16 @@ class Config
|
||||
return $this->deployment('identity-file') ? ('-i ' . $this->deployment('identity-file') . ' ') : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ConnectTimeout option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConnectTimeoutOption()
|
||||
{
|
||||
return $this->environmentConfig('connect-timeout') ? ('-o ConnectTimeout=' . $this->environmentConfig('connect-timeout') . ' ') : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Host
|
||||
*
|
||||
|
||||
@@ -201,6 +201,7 @@ abstract class AbstractTask
|
||||
|
||||
$localCommand = 'ssh ' . $this->getConfig()->getHostIdentityFileOption() . $needs_tty . ' -p ' . $this->getConfig()->getHostPort() . ' '
|
||||
. '-q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '
|
||||
. $this->getConfig()->getConnectTimeoutOption()
|
||||
. $this->getConfig()->deployment('user') . '@' . $this->getConfig()->getHostName();
|
||||
|
||||
$remoteCommand = str_replace('"', '\"', $command);
|
||||
|
||||
@@ -74,20 +74,21 @@ class ReleaseTask extends AbstractTask implements IsReleaseAware, SkipOnOverride
|
||||
}
|
||||
}
|
||||
|
||||
// Remove symlink if exists; create new symlink and change owners
|
||||
$command = 'rm -f ' . $symlink
|
||||
. ' ; '
|
||||
. 'ln -sf ' . $currentCopy . ' ' . $symlink;
|
||||
|
||||
if ($resultFetch && $userGroup != '') {
|
||||
$command .= ' && '
|
||||
. 'chown -h ' . $userGroup . ' ' . $symlink
|
||||
if ($resultFetch && $userGroup != '') {
|
||||
$command = 'chown -h ' . $userGroup . ' ' . $symlink
|
||||
. ' && '
|
||||
. 'chown -R ' . $userGroup . ' ' . $currentCopy
|
||||
. ' && '
|
||||
. 'chown ' . $userGroup . ' ' . $releasesDirectory;
|
||||
$result = $this->runCommandRemote($command);
|
||||
if (!$result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove symlink if exists; create new symlink and change owner
|
||||
$tmplink = $currentCopy . '.tmp';
|
||||
$command = "ln -sfn {$currentCopy} {$tmplink} && mv -fT {$tmplink} {$symlink}";
|
||||
$result = $this->runCommandRemote($command);
|
||||
|
||||
if ($result) {
|
||||
|
||||
@@ -77,7 +77,10 @@ class TarGzTask extends BaseStrategyTaskAbstract implements IsReleaseAware
|
||||
$strategyFlags = '';
|
||||
}
|
||||
|
||||
$command = 'tar cfzh' . $strategyFlags . ' ' . $localTarGz . '.tar.gz ' . $excludeCmd . $excludeFromFileCmd . ' -C ' . $this->getConfig()->deployment('from') . ' .';
|
||||
// remove h option only if dump-symlinks is allowed in the release config part
|
||||
$dumpSymlinks = $this->getConfig()->release('dump-symlinks') ? '' : 'h';
|
||||
|
||||
$command = 'tar cfz'. $dumpSymlinks . $strategyFlags . ' ' . $localTarGz . '.tar.gz ' . $excludeCmd . $excludeFromFileCmd . ' -C ' . $this->getConfig()->deployment('from') . ' .';
|
||||
$result = $this->runCommandLocal($command);
|
||||
|
||||
// Strategy Flags
|
||||
@@ -89,7 +92,7 @@ class TarGzTask extends BaseStrategyTaskAbstract implements IsReleaseAware
|
||||
}
|
||||
|
||||
// Copy Tar Gz to Remote Host
|
||||
$command = 'scp ' . $strategyFlags . ' ' . $this->getConfig()->getHostIdentityFileOption() . '-P ' . $this->getConfig()->getHostPort() . ' ' . $localTarGz . '.tar.gz '
|
||||
$command = 'scp ' . $strategyFlags . ' ' . $this->getConfig()->getHostIdentityFileOption() . $this->getConfig()->getConnectTimeoutOption() . '-P ' . $this->getConfig()->getHostPort() . ' ' . $localTarGz . '.tar.gz '
|
||||
. $this->getConfig()->deployment('user') . '@' . $this->getConfig()->getHostName() . ':' . $deployToDirectory;
|
||||
$result = $this->runCommandLocal($command) && $result;
|
||||
|
||||
@@ -106,11 +109,11 @@ class TarGzTask extends BaseStrategyTaskAbstract implements IsReleaseAware
|
||||
$result = $this->runCommandRemote($command) && $result;
|
||||
|
||||
// Delete Tar Gz from Remote Host
|
||||
$command = $this->getReleasesAwareCommand('rm ' . $remoteTarGz . '.tar.gz');
|
||||
$command = $this->getReleasesAwareCommand('rm -f ' . $remoteTarGz . '.tar.gz');
|
||||
$result = $this->runCommandRemote($command) && $result;
|
||||
|
||||
// Delete Tar Gz from Local
|
||||
$command = 'rm ' . $localTarGz . ' ' . $localTarGz . '.tar.gz';
|
||||
$command = 'rm -f ' . $localTarGz . ' ' . $localTarGz . '.tar.gz';
|
||||
$result = $this->runCommandLocal($command) && $result;
|
||||
|
||||
return $result;
|
||||
|
||||
@@ -25,7 +25,6 @@ class ApplyFaclsTask extends AbstractTask implements IsReleaseAware
|
||||
public function run()
|
||||
{
|
||||
$releasesDirectory = $this->getConfig()->release('directory', 'releases');
|
||||
$releasesDirectory = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $releasesDirectory;
|
||||
$currentCopy = $releasesDirectory . '/' . $this->getConfig()->getReleaseId();
|
||||
|
||||
|
||||
|
||||
@@ -5,21 +5,47 @@ use Mage\Task\AbstractTask;
|
||||
use Mage\Task\Releases\IsReleaseAware;
|
||||
use Mage\Task\SkipException;
|
||||
|
||||
/**
|
||||
* Class LinkSharedFilesTask
|
||||
*
|
||||
* @package Mage\Task\BuiltIn\Filesystem
|
||||
* @author Andrey Kolchenko <andrey@kolchenko.me>
|
||||
*/
|
||||
class LinkSharedFilesTask extends AbstractTask implements IsReleaseAware
|
||||
{
|
||||
/**
|
||||
* Linked folders parameter name
|
||||
*/
|
||||
const LINKED_FILES = 'linked_files';
|
||||
/**
|
||||
* Linked folders parameter name
|
||||
*/
|
||||
const LINKED_FOLDERS = 'linked_folders';
|
||||
/**
|
||||
* Linking strategy parameter name
|
||||
*/
|
||||
const LINKED_STRATEGY = 'linking_strategy';
|
||||
|
||||
const LINKED_FOLDERS = 'linked_folders';
|
||||
const LINKED_STRATEGY = 'linking_strategy';
|
||||
|
||||
/**
|
||||
* Absolute linked strategy
|
||||
*/
|
||||
const ABSOLUTE_LINKING = 'absolute';
|
||||
/**
|
||||
* Relative linked strategy
|
||||
*/
|
||||
const RELATIVE_LINKING = 'relative';
|
||||
|
||||
public $linkingStrategies = array(
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $linkingStrategies = array(
|
||||
self::ABSOLUTE_LINKING,
|
||||
self::RELATIVE_LINKING
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the Title of the Task
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
@@ -35,41 +61,92 @@ class LinkSharedFilesTask extends AbstractTask implements IsReleaseAware
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$linkedFiles = $this->getParameter('linked_files', []);
|
||||
$linkedFolders = $this->getParameter(self::LINKED_FOLDERS, []);
|
||||
$linkingStrategy = $this->getParameter(self::LINKED_STRATEGY, self::ABSOLUTE_LINKING);
|
||||
$linkedEntities = array_merge(
|
||||
$this->getParameter(self::LINKED_FILES, array()),
|
||||
$this->getParameter(self::LINKED_FOLDERS, array())
|
||||
);
|
||||
|
||||
$linkedEntities = array_merge($linkedFiles,$linkedFolders);
|
||||
|
||||
if (sizeof($linkedFiles) == 0 && sizeof($linkedFolders) == 0) {
|
||||
if (empty($linkedEntities)) {
|
||||
throw new SkipException('No files and folders configured for sym-linking.');
|
||||
}
|
||||
|
||||
$sharedFolderName = $this->getParameter('shared', 'shared');
|
||||
$sharedFolderPath = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $sharedFolderName;
|
||||
$releasesDirectory = $this->getConfig()->release('directory', 'releases');
|
||||
$releasesDirectoryPath = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $releasesDirectory;
|
||||
|
||||
$remoteDirectory = rtrim($this->getConfig()->deployment('to'), '/') . '/';
|
||||
$sharedFolderPath = $remoteDirectory . $this->getParameter('shared', 'shared');
|
||||
$releasesDirectoryPath = $remoteDirectory . $this->getConfig()->release('directory', 'releases');
|
||||
$currentCopy = $releasesDirectoryPath . '/' . $this->getConfig()->getReleaseId();
|
||||
$relativeDiffPath = str_replace($this->getConfig()->deployment('to'),'',$currentCopy) . '/';
|
||||
|
||||
foreach ($linkedEntities as $ePath) {
|
||||
if(is_array($ePath) && in_array($strategy = reset($ePath), $this->linkingStrategies ) ) {
|
||||
$entityPath = key($ePath);
|
||||
list($entityPath, $strategy) = $this->getPath($ePath);
|
||||
if ($strategy === self::RELATIVE_LINKING) {
|
||||
$dirName = dirname($currentCopy . '/' . $entityPath);
|
||||
$target = $this->makePathRelative($sharedFolderPath, $dirName) . $entityPath;
|
||||
} else {
|
||||
$strategy = $linkingStrategy;
|
||||
$entityPath = $ePath;
|
||||
$target = $sharedFolderPath . '/' . $entityPath;
|
||||
}
|
||||
$sharedEntityLinkedPath = "$sharedFolderPath/$entityPath";
|
||||
if($strategy==self::RELATIVE_LINKING) {
|
||||
$parentFolderPath = dirname($entityPath);
|
||||
$relativePath = $parentFolderPath=='.'?$relativeDiffPath:$relativeDiffPath.$parentFolderPath.'/';
|
||||
$sharedEntityLinkedPath = ltrim(preg_replace('/(\w+\/)/', '../', $relativePath),'/').$sharedFolderName .'/'. $entityPath;
|
||||
}
|
||||
$command = "ln -nfs $sharedEntityLinkedPath $currentCopy/$entityPath";
|
||||
$command = 'mkdir -p ' . escapeshellarg(dirname($target));
|
||||
$this->runCommandRemote($command);
|
||||
$command = 'ln -nfs ' . escapeshellarg($target) . ' ' . escapeshellarg($currentCopy . '/' . $entityPath);
|
||||
$this->runCommandRemote($command);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an existing path, convert it to a path relative to a given starting path
|
||||
*
|
||||
* @param string $endPath Absolute path of target
|
||||
* @param string $startPath Absolute path where traversal begins
|
||||
*
|
||||
* @return string Path of target relative to starting path
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @see https://github.com/symfony/Filesystem/blob/v2.6.1/Filesystem.php#L332
|
||||
*/
|
||||
private function makePathRelative($endPath, $startPath)
|
||||
{
|
||||
// Normalize separators on Windows
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
|
||||
$endPath = strtr($endPath, '\\', '/');
|
||||
$startPath = strtr($startPath, '\\', '/');
|
||||
}
|
||||
// Split the paths into arrays
|
||||
$startPathArr = explode('/', trim($startPath, '/'));
|
||||
$endPathArr = explode('/', trim($endPath, '/'));
|
||||
// Find for which directory the common path stops
|
||||
$index = 0;
|
||||
while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
|
||||
$index++;
|
||||
}
|
||||
// Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
|
||||
$depth = count($startPathArr) - $index;
|
||||
// Repeated "../" for each level need to reach the common path
|
||||
$traverser = str_repeat('../', $depth);
|
||||
$endPathRemainder = implode('/', array_slice($endPathArr, $index));
|
||||
// Construct $endPath from traversing to the common path, then to the remaining $endPath
|
||||
$relativePath = $traverser . (strlen($endPathRemainder) > 0 ? $endPathRemainder . '/' : '');
|
||||
|
||||
return (strlen($relativePath) === 0) ? './' : $relativePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $linkedEntity
|
||||
*
|
||||
* @return array [$path, $strategy]
|
||||
*/
|
||||
private function getPath($linkedEntity)
|
||||
{
|
||||
$linkingStrategy = $this->getParameter(self::LINKED_STRATEGY, self::ABSOLUTE_LINKING);
|
||||
if (is_array($linkedEntity)) {
|
||||
list($path, $strategy) = each($linkedEntity);
|
||||
if (!in_array($strategy, self::$linkingStrategies)) {
|
||||
$strategy = $linkingStrategy;
|
||||
}
|
||||
} else {
|
||||
$strategy = $linkingStrategy;
|
||||
$path = $linkedEntity;
|
||||
}
|
||||
|
||||
return [$path, $strategy];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Mage\Task\BuiltIn\Filesystem;
|
||||
|
||||
use Mage\Task\SkipException;
|
||||
|
||||
/**
|
||||
* Task for giving only to web server read permissions on given paths.
|
||||
*
|
||||
* Usage :
|
||||
* pre-deploy:
|
||||
* - filesystem/permissions-readable-only-by-web-server: {paths: /var/www/myapp/app/config/config.yml:/var/www/myapp/app/config/parameters.yml, recursive: false, checkPathsExist: true}
|
||||
* - filesystem/permissions-readable-only-by-web-server:
|
||||
* paths:
|
||||
* - /var/www/myapp/app/config/config.yml
|
||||
* - /var/www/myapp/app/config/parameters.yml
|
||||
* recursive: false
|
||||
* checkPathsExist: true
|
||||
* on-deploy:
|
||||
* - filesystem/permissions-readable-only-by-web-server: {paths: app/config/config.yml:app/config/parameters.yml, recursive: false, checkPathsExist: true}
|
||||
*
|
||||
* @author Jérémy Huet <jeremy.huet@gmail.com>
|
||||
*/
|
||||
class PermissionsReadableOnlyByWebServerTask extends PermissionsTask
|
||||
{
|
||||
/**
|
||||
* Set group with web server user and give group write permissions.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$this->setGroup($this->getParameter('group') ? $this->getParameter('group') : $this->getWebServerUser())
|
||||
->setRights('040');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return "Giving read permissions only to web server user for given paths [built-in]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to guess the web server user by going thru the running processes.
|
||||
*
|
||||
* @return string
|
||||
* @throws SkipException
|
||||
*/
|
||||
protected function getWebServerUser()
|
||||
{
|
||||
$this->runCommand("ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1", $webServerUser);
|
||||
|
||||
if (empty($webServerUser)) {
|
||||
throw new SkipException("Can't guess web server user. Please check if it is running or force it by setting the group parameter");
|
||||
}
|
||||
|
||||
return $webServerUser;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
<?php
|
||||
namespace Mage\Task\BuiltIn\Filesystem;
|
||||
|
||||
use Mage\Task\AbstractTask;
|
||||
use Mage\Task\SkipException;
|
||||
|
||||
/**
|
||||
* Task for setting permissions on given paths. Change will be done on local or
|
||||
* remote host depending on the stage of the deployment.
|
||||
*
|
||||
* Usage :
|
||||
* pre-deploy:
|
||||
* - filesystem/permissions: {paths: /var/www/myapp/app/cache:/var/www/myapp/app/cache, recursive: false, checkPathsExist: true, owner: www-data, group: www-data, rights: 775}
|
||||
* - filesystem/permissions:
|
||||
* paths:
|
||||
* - /var/www/myapp/app/cache
|
||||
* - /var/www/myapp/app/logs
|
||||
* recursive: false
|
||||
* checkPathsExist: true
|
||||
* owner: www-data:www-data
|
||||
* rights: 775
|
||||
* on-deploy:
|
||||
* - filesystem/permissions: {paths: app/cache:app/logs, recursive: false, checkPathsExist: true, owner: www-data, group: www-data, rights: 775}
|
||||
*
|
||||
* @author Jérémy Huet <jeremy.huet@gmail.com>
|
||||
*/
|
||||
class PermissionsTask extends AbstractTask
|
||||
{
|
||||
/**
|
||||
* Paths to change of permissions in an array or a string separated by
|
||||
* PATH_SEPARATOR.
|
||||
*
|
||||
* If the stage is on local host you should give full paths. If on remote
|
||||
* you may give full or relative to the current release directory paths.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $paths;
|
||||
|
||||
/**
|
||||
* If set to true, will check existance of given paths on the host and
|
||||
* throw SkipException if at least one does not exist.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $checkPathsExist = true;
|
||||
|
||||
/**
|
||||
* Owner to set for the given paths (ex : "www-data" or "www-data:www-data"
|
||||
* to set both owner and group at the same time)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $owner;
|
||||
|
||||
/**
|
||||
* Group to set for the given paths (ex : "www-data")
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $group;
|
||||
|
||||
/**
|
||||
* Rights to set for the given paths (ex: "755" or "g+w")
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $rights;
|
||||
|
||||
/**
|
||||
* If set to true, will recursively change permissions on given paths.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $recursive = false;
|
||||
|
||||
/**
|
||||
* Initialize parameters.
|
||||
*
|
||||
* @throws SkipException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if (! is_null($this->getParameter('checkPathsExist'))) {
|
||||
$this->setCheckPathsExist($this->getParameter('checkPathsExist'));
|
||||
}
|
||||
|
||||
if (! $this->getParameter('paths')) {
|
||||
throw new SkipException('Param paths is mandatory');
|
||||
}
|
||||
$this->setPaths(is_array($this->getParameter('paths')) ? $this->getParameter('paths') : explode(PATH_SEPARATOR, $this->getParameter('paths', '')));
|
||||
|
||||
if (! is_null($owner = $this->getParameter('owner'))) {
|
||||
if (strpos($owner, ':') !== false) {
|
||||
$this->setOwner(array_shift(explode(':', $owner)));
|
||||
$this->setGroup(array_pop(explode(':', $owner)));
|
||||
} else {
|
||||
$this->setOwner($owner);
|
||||
}
|
||||
}
|
||||
|
||||
if (! is_null($group = $this->getParameter('group'))) {
|
||||
$this->setGroup($group);
|
||||
}
|
||||
|
||||
if (! is_null($rights = $this->getParameter('rights'))) {
|
||||
$this->setRights($rights);
|
||||
}
|
||||
|
||||
if (! is_null($recursive = $this->getParameter('recursive'))) {
|
||||
$this->setRecursive($recursive);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return "Changing rights / owner / group for given paths [built-in]";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$commands = array();
|
||||
|
||||
if ($this->paths && $this->owner) {
|
||||
$commands []= 'chown '. $this->getOptionsForCmd() .' ' . $this->owner . ' ' . $this->getPathsForCmd();
|
||||
}
|
||||
|
||||
if ($this->paths && $this->group) {
|
||||
$commands []= 'chgrp '. $this->getOptionsForCmd() .' ' . $this->group . ' ' . $this->getPathsForCmd();
|
||||
}
|
||||
|
||||
if ($this->paths && $this->rights) {
|
||||
$commands []= 'chmod '. $this->getOptionsForCmd() .' ' . $this->rights . ' ' . $this->getPathsForCmd();
|
||||
}
|
||||
|
||||
$result = $this->runCommand(implode(' && ', $commands));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the options for the commands to run. Only supports -R for now.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getOptionsForCmd()
|
||||
{
|
||||
$optionsForCmd = '';
|
||||
$options = array(
|
||||
'R' => $this->recursive
|
||||
);
|
||||
|
||||
foreach($options as $option => $apply) {
|
||||
if ($apply === true) {
|
||||
$optionsForCmd .= $option;
|
||||
}
|
||||
}
|
||||
|
||||
return $optionsForCmd ? '-' . $optionsForCmd : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms paths array to a string separated by 1 space in order to use
|
||||
* it in a command line.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPathsForCmd($paths = null)
|
||||
{
|
||||
if (is_null($paths)) {
|
||||
$paths = $this->paths;
|
||||
}
|
||||
|
||||
return implode(' ', $paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set paths. Will check if they exist on the host depending on
|
||||
* checkPathsExist flag.
|
||||
*
|
||||
* @param array $paths
|
||||
* @return PermissionsTask
|
||||
* @throws SkipException
|
||||
*/
|
||||
protected function setPaths(array $paths)
|
||||
{
|
||||
if ($this->checkPathsExist === true) {
|
||||
$commands = array();
|
||||
foreach ($paths as $path) {
|
||||
$commands[] = '(([ -f ' . $path . ' ]) || ([ -d ' . $path . ' ]))';
|
||||
}
|
||||
|
||||
$command = implode(' && ', $commands);
|
||||
if (! $this->runCommand($command)) {
|
||||
throw new SkipException('Make sure all paths given exist on the host : ' . $this->getPathsForCmd($paths));
|
||||
}
|
||||
}
|
||||
|
||||
$this->paths = $paths;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getPaths()
|
||||
{
|
||||
return $this->paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set checkPathsExist.
|
||||
*
|
||||
* @param boolean $checkPathsExist
|
||||
* @return PermissionsTask
|
||||
*/
|
||||
protected function setCheckPathsExist($checkPathsExist)
|
||||
{
|
||||
$this->checkPathsExist = (bool) $checkPathsExist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
protected function getCheckPathsExist()
|
||||
{
|
||||
return $this->checkPathsExist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set owner.
|
||||
*
|
||||
* @param string $owner
|
||||
* @return PermissionsTask
|
||||
*/
|
||||
protected function setOwner($owner)
|
||||
{
|
||||
$this->owner = $owner;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getOwner()
|
||||
{
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set group.
|
||||
*
|
||||
* @param string $group
|
||||
* @return PermissionsTask
|
||||
*/
|
||||
protected function setGroup($group)
|
||||
{
|
||||
$this->group = $group;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getGroup()
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rights.
|
||||
*
|
||||
* @param string $rights
|
||||
* @return PermissionsTask
|
||||
*/
|
||||
protected function setRights($rights)
|
||||
{
|
||||
$this->rights = $rights;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getRights()
|
||||
{
|
||||
return $this->rights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set recursive.
|
||||
*
|
||||
* @param boolean $recursive
|
||||
* @return PermissionsTask
|
||||
*/
|
||||
protected function setRecursive($recursive)
|
||||
{
|
||||
$this->recursive = (bool) $recursive;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
protected function getRecursive()
|
||||
{
|
||||
return $this->recursive;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Mage\Task\BuiltIn\Filesystem;
|
||||
|
||||
use Mage\Task\SkipException;
|
||||
|
||||
/**
|
||||
* Task for giving web server write permissions on given paths.
|
||||
*
|
||||
* Usage :
|
||||
* pre-deploy:
|
||||
* - filesystem/permissions-writable-by-web-server: {paths: /var/www/myapp/app/cache:/var/www/myapp/app/logs, recursive: false, checkPathsExist: true}
|
||||
* - filesystem/permissions-writable-by-web-server:
|
||||
* paths:
|
||||
* - /var/www/myapp/app/cache
|
||||
* - /var/www/myapp/app/logs
|
||||
* recursive: false
|
||||
* checkPathsExist: true
|
||||
* on-deploy:
|
||||
* - filesystem/permissions-writable-by-web-server: {paths: app/cache:app/logs, recursive: false, checkPathsExist: true}
|
||||
*
|
||||
* @author Jérémy Huet <jeremy.huet@gmail.com>
|
||||
*/
|
||||
class PermissionsWritableByWebServerTask extends PermissionsTask
|
||||
{
|
||||
/**
|
||||
* Set group with web server user and give group write permissions.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$this->setGroup($this->getParameter('group') ? $this->getParameter('group') : $this->getWebServerUser())
|
||||
->setRights('g+w');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return "Giving write permissions to web server user for given paths [built-in]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to guess the web server user by going thru the running processes.
|
||||
*
|
||||
* @return string
|
||||
* @throws SkipException
|
||||
*/
|
||||
protected function getWebServerUser()
|
||||
{
|
||||
$this->runCommand("ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1", $webServerUser);
|
||||
|
||||
if (empty($webServerUser)) {
|
||||
throw new SkipException("Can't guess web server user. Please check if it is running or force it by setting the group parameter");
|
||||
}
|
||||
|
||||
return $webServerUser;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,6 @@ use Mage\Task\ErrorWithMessageException;
|
||||
*
|
||||
* Example enviroment.yaml file at end
|
||||
*
|
||||
* @todo add support for creating license files.
|
||||
*
|
||||
* (c) ActWeb 2013
|
||||
* (c) Matt Lowe (marl.scot.1@googlemail.com)
|
||||
@@ -202,7 +201,7 @@ class EncryptTask extends AbstractTask
|
||||
/*
|
||||
* Get all our IonCube config options
|
||||
*/
|
||||
$this->_getAllIonCubeConfigs();
|
||||
$this->getAllIonCubeConfigs();
|
||||
/*
|
||||
* get the source code location
|
||||
*/
|
||||
@@ -279,7 +278,7 @@ class EncryptTask extends AbstractTask
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _getAllIonCubeConfigs()
|
||||
private function getAllIonCubeConfigs()
|
||||
{
|
||||
|
||||
/*
|
||||
@@ -553,7 +552,6 @@ class EncryptTask extends AbstractTask
|
||||
* D - Default options as stored in script
|
||||
*
|
||||
* more options could be added to make this a bit more flexable
|
||||
* @todo I'm sure this could be combined into a loop to make it easier and shorter
|
||||
*
|
||||
*/
|
||||
$s = array();
|
||||
|
||||
@@ -51,12 +51,14 @@ class RollbackTask extends AbstractTask implements IsReleaseAware
|
||||
$releasesDirectory = $this->getConfig()->release('directory', 'releases');
|
||||
$symlink = $this->getConfig()->release('symlink', 'current');
|
||||
|
||||
if (substr($symlink, 0, 1) == '/') {
|
||||
$releasesDirectory = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $releasesDirectory;
|
||||
}
|
||||
|
||||
$output = '';
|
||||
$result = $this->runCommandRemote('ls -1 ' . $releasesDirectory, $output);
|
||||
$releases = ($output == '') ? array() : explode(PHP_EOL, $output);
|
||||
|
||||
$inDeploy = $this->getParameter('inDeploy',false);
|
||||
|
||||
if (count($releases) == 0) {
|
||||
Console::output('Release are not available for <bold>' . $this->getConfig()->getHost() . '</bold> ... <red>FAIL</red>');
|
||||
|
||||
@@ -133,9 +135,11 @@ class RollbackTask extends AbstractTask implements IsReleaseAware
|
||||
|
||||
$userGroup = '';
|
||||
$resultFetch = $this->runCommandRemote('ls -ld ' . $rollbackTo . ' | awk \'{print \$3":"\$4}\'', $userGroup);
|
||||
$command = 'rm -f ' . $symlink
|
||||
|
||||
$tmplink = $rollbackTo . '.tmp';
|
||||
$command = 'ln -sfn ' . $currentCopy . ' ' . $tmplink
|
||||
. ' && '
|
||||
. 'ln -sf ' . $rollbackTo . ' ' . $symlink;
|
||||
. 'mv -T ' . $tmplink . ' ' . $symlink;
|
||||
|
||||
if ($resultFetch) {
|
||||
$command .= ' && chown -h ' . $userGroup . ' ' . $symlink;
|
||||
|
||||
@@ -63,14 +63,15 @@ class ChangeBranchTask extends AbstractTask
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$preCommand = 'cd ' . $this->getConfig()->deployment('from', './') . '; ';
|
||||
switch ($this->getConfig()->general('scm')) {
|
||||
case 'git':
|
||||
if ($this->getParameter('_changeBranchRevert', false)) {
|
||||
$command = 'git checkout ' . self::$startingBranch;
|
||||
$command = $preCommand . 'git checkout ' . self::$startingBranch;
|
||||
$result = $this->runCommandLocal($command);
|
||||
|
||||
} else {
|
||||
$command = 'git branch | grep \'*\' | cut -d\' \' -f 2';
|
||||
$command = $preCommand . 'git branch | grep \'*\' | cut -d\' \' -f 2';
|
||||
$currentBranch = 'master';
|
||||
$result = $this->runCommandLocal($command, $currentBranch);
|
||||
|
||||
|
||||
@@ -54,9 +54,10 @@ class UpdateTask extends AbstractTask
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = 'cd ' . $this->getConfig()->deployment('from', './') . '; ';
|
||||
switch ($this->getConfig()->general('scm')) {
|
||||
case 'git':
|
||||
$command = 'git pull';
|
||||
$command .= 'git pull';
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -59,7 +59,7 @@ class Factory
|
||||
|
||||
$instance = new $className($taskConfig, $inRollback, $stage, $taskParameters);
|
||||
|
||||
if (!$instance instanceof AbstractTask) {
|
||||
if (!($instance instanceof AbstractTask)) {
|
||||
throw new Exception('The Task ' . $taskName . ' must be an instance of Mage\Task\AbstractTask.');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user