Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable operation systems for servers and ability to make some commands depends on them #123

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Configuration/AbstractConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ public function __construct()
$this->servers = new ServerRepository();
}

public function server(string $sshDsn, array $roles = [Server::ROLE_APP], array $properties = [])
public function server(string $sshDsn, array $roles = [Server::ROLE_APP], array $properties = [], $system = null)
{
$reservedProperties = array_merge(self::RESERVED_SERVER_PROPERTIES, $this->getReservedServerProperties());
$reservedPropertiesUsed = array_intersect($reservedProperties, array_keys($properties));
if (!empty($reservedPropertiesUsed)) {
throw new InvalidConfigurationException(sprintf('These properties set for the "%s" server are reserved: %s. Use different property names.', $sshDsn, implode(', ', $reservedPropertiesUsed)));
}

$this->servers->add(new Server($sshDsn, $roles, $properties));
$this->servers->add(new Server($sshDsn, $roles, $properties, $system));
}

public function useSshAgentForwarding(bool $useIt)
Expand Down
4 changes: 2 additions & 2 deletions src/Configuration/CustomConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ class CustomConfiguration extends AbstractConfiguration
{
// this proxy method is needed because the autocompletion breaks
// if the parent method is used directly
public function server(string $sshDsn, array $roles = [Server::ROLE_APP], array $properties = []): self
public function server(string $sshDsn, array $roles = [Server::ROLE_APP], array $properties = [], $system = null): self
{
parent::server($sshDsn, $roles, $properties);
parent::server($sshDsn, $roles, $properties, $system);

return $this;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Configuration/DefaultConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ public function __construct(string $localProjectDir)

// this proxy method is needed because the autocompletion breaks
// if the parent method is used directly
public function server(string $sshDsn, array $roles = [Server::ROLE_APP], array $properties = []): self
public function server(string $sshDsn, array $roles = [Server::ROLE_APP], array $properties = [], $system = null): self
{
parent::server($sshDsn, $roles, $properties);
parent::server($sshDsn, $roles, $properties, $system);

return $this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function getOutput(): OutputInterface

private function createLocalHost(): Server
{
$localhost = new Server('localhost');
$localhost = new Server('localhost', [], [], '\\' === DIRECTORY_SEPARATOR ? 'windows': null);
$localhost->set(Property::project_dir, $this->projectDir);

return $localhost;
Expand Down
8 changes: 4 additions & 4 deletions src/Deployer/DefaultDeployer.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use EasyCorp\Bundle\EasyDeployBundle\Requirement\CommandExists;
use EasyCorp\Bundle\EasyDeployBundle\Server\Property;
use EasyCorp\Bundle\EasyDeployBundle\Server\Server;
use EasyCorp\Bundle\EasyDeployBundle\Task\Task;
use EasyCorp\Bundle\EasyDeployBundle\Task\TaskCompleted;

abstract class DefaultDeployer extends AbstractDeployer
Expand Down Expand Up @@ -45,7 +46,6 @@ public function getRequirements(): array
if ('acl' === $this->getConfig(Option::permissionMethod)) {
$requirements[] = new CommandExists($appServers, 'setfacl');
}

return $requirements;
}

Expand Down Expand Up @@ -161,14 +161,14 @@ private function doCheckPreviousReleases(): void
private function doSymlinkToPreviousRelease(): void
{
$this->log('<h2>Reverting the current symlink to the previous version</>');
$this->runRemote('export _previous_release_dirname=$(ls -r1 {{ deploy_dir }}/releases | head -n 2 | tail -n 1) && rm -f {{ deploy_dir }}/current && ln -s {{ deploy_dir }}/releases/$_previous_release_dirname {{ deploy_dir }}/current');
$this->runRemote('{{ _env_command export}} _previous_release_dirname=$(ls -r1 {{ deploy_dir }}/releases | head -n 2 | tail -n 1) && rm -f {{ deploy_dir }}/current && ln -s {{ deploy_dir }}/releases/$_previous_release_dirname {{ deploy_dir }}/current');
}

private function doDeleteLastReleaseDirectory(): void
{
// this is needed to avoid rolling back in the future to this version
$this->log('<h2>Deleting the last release directory</>');
$this->runRemote('export _last_release_dirname=$(ls -r1 {{ deploy_dir }}/releases | head -n 1) && rm -fr {{ deploy_dir }}/releases/$_last_release_dirname');
$this->runRemote('{{ _env_command export}} _last_release_dirname=$(ls -r1 {{ deploy_dir }}/releases | head -n 1) && rm -fr {{ deploy_dir }}/releases/$_last_release_dirname');
}

private function initializeServerOptions(): void
Expand Down Expand Up @@ -232,7 +232,7 @@ private function createRemoteDirectoryLayout(): void
$this->runRemote('mkdir -p {{ deploy_dir }} && mkdir -p {{ deploy_dir }}/releases && mkdir -p {{ deploy_dir }}/shared');

/** @var TaskCompleted[] $results */
$results = $this->runRemote('export _release_path="{{ deploy_dir }}/releases/$(date +%Y%m%d%H%M%S)" && mkdir -p $_release_path && echo $_release_path');
$results = $this->runRemote('{{ _env_command export}} _release_path={{ deploy_dir }}/releases/' . date('dmYHis') . ' && mkdir -p $_release_path && echo $_release_path');
foreach ($results as $result) {
$remoteProjectDir = $this->getContext()->isDryRun() ? '(the remote project_dir)' : $result->getTrimmedOutput();
$result->getServer()->set(Property::project_dir, $remoteProjectDir);
Expand Down
8 changes: 2 additions & 6 deletions src/Requirement/CommandExists.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace EasyCorp\Bundle\EasyDeployBundle\Requirement;

use EasyCorp\Bundle\EasyDeployBundle\Server\Server;
use EasyCorp\Bundle\EasyDeployBundle\Task\Task;

class CommandExists extends AbstractRequirement
Expand All @@ -30,13 +31,8 @@ public function getMessage(): string

public function getChecker(): Task
{
$shellCommand = sprintf('%s %s', $this->isWindows() ? 'where' : 'which', $this->commandName);
$shellCommand = sprintf('%s %s', '{{ _env_command which }}', $this->commandName);

return new Task($this->getServers(), $shellCommand);
}

private function isWindows(): bool
{
return '\\' === DIRECTORY_SEPARATOR;
}
}
26 changes: 25 additions & 1 deletion src/Server/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

use EasyCorp\Bundle\EasyDeployBundle\Exception\ServerConfigurationException;
use EasyCorp\Bundle\EasyDeployBundle\Helper\Str;
use EasyCorp\Bundle\EasyDeployBundle\System\AbstractSystem;
use EasyCorp\Bundle\EasyDeployBundle\System\DefaultSystem;
use Symfony\Component\HttpFoundation\ParameterBag;

class Server
Expand All @@ -24,8 +26,9 @@ class Server
private $host;
private $port;
private $properties;
private $system;

public function __construct(string $dsn, array $roles = [self::ROLE_APP], array $properties = [])
public function __construct(string $dsn, array $roles = [self::ROLE_APP], array $properties = [], string $system = null)
{
$this->roles = $roles;
$this->properties = new ParameterBag($properties);
Expand All @@ -41,6 +44,14 @@ public function __construct(string $dsn, array $roles = [self::ROLE_APP], array
$this->host = $params['host'];

$this->port = $params['port'] ?? null;

$systemClassName = '\\EasyCorp\\Bundle\\EasyDeployBundle\\System\\' . ucfirst((string)$system) . 'System';
if($system && class_exists($systemClassName)){
$this->system = new $systemClassName();
}else{
$this->system = new DefaultSystem();
}

}

public function __toString(): string
Expand All @@ -58,6 +69,13 @@ public function resolveProperties(string $expression): string
$definedProperties = $this->properties;
$resolved = preg_replace_callback('/(\{\{\s*(?<propertyName>.+)\s*\}\})/U', function (array $matches) use ($definedProperties, $expression) {
$propertyName = trim($matches['propertyName']);
//Resolve special environment command
if(substr($propertyName,0, strlen('_env_command')) === '_env_command'){
if(!isset(explode(' ', $propertyName)[1])){
return '';
}
return $this->system->getCommand(explode(' ', $propertyName)[1]);
}
if (!$definedProperties->has($propertyName)) {
throw new \InvalidArgumentException(sprintf('The "%s" property in "%s" expression is not a valid server property.', $propertyName, $expression));
}
Expand Down Expand Up @@ -121,4 +139,10 @@ public function getPort(): ?int
{
return $this->port;
}

public function getSystem(): AbstractSystem
{
return $this->system;
}

}
26 changes: 26 additions & 0 deletions src/System/AbstractSystem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php


namespace EasyCorp\Bundle\EasyDeployBundle\System;


class AbstractSystem
{

protected $commands;
protected $sessionPrefix;

public function getCommand(string $command)
{
if(isset($this->commands[$command])){
return $this->commands[$command];
}

return $command;
}

public function getSessionPrefix(){

}

}
10 changes: 10 additions & 0 deletions src/System/DefaultSystem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php


namespace EasyCorp\Bundle\EasyDeployBundle\System;


class DefaultSystem extends AbstractSystem
{

}
10 changes: 10 additions & 0 deletions src/System/LinuxSystem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php


namespace EasyCorp\Bundle\EasyDeployBundle\System;


class LinuxSystem extends AbstractSystem
{
public $sessionPrefix = 'bash; ';
}
13 changes: 13 additions & 0 deletions src/System/WindowsSystem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php


namespace EasyCorp\Bundle\EasyDeployBundle\System;


class WindowsSystem extends AbstractSystem
{
public $commands = [
'export' => 'set',
'which' => 'where'
];
}
6 changes: 5 additions & 1 deletion src/Task/TaskRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ private function doRun(Server $server, string $shellCommand, array $envVars): Ta
$envVarsAsString = http_build_query($envVars, '', ' ');
// the ';' after the env vars makes them available to all commands, not only the first one
// parenthesis create a sub-shell so the env vars don't affect to the parent shell
$shellCommand = sprintf('(export %s; %s)', $envVarsAsString, $shellCommand);
$shellCommand = sprintf('(' . $server->getSystem()->getCommand('export') . ' %s; %s)', $envVarsAsString, $shellCommand);
}

if($server->getSystem()->getSessionPrefix()){
$shellCommand = $server->getSystem()->getSessionPrefix() . $shellCommand;
}

$this->logger->log(sprintf('[<server>%s</>] Executing command: <command>%s</>', $server, $shellCommand));
Expand Down