From 16d575bbe9d910da95abeda1f4cebf999a6121da Mon Sep 17 00:00:00 2001 From: IBrows Date: Tue, 3 Jul 2012 10:28:45 +0300 Subject: [PATCH 01/26] add ssh_port --- Deployer/Rsync.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Deployer/Rsync.php b/Deployer/Rsync.php index 11df8ea..aa2b1a1 100644 --- a/Deployer/Rsync.php +++ b/Deployer/Rsync.php @@ -149,6 +149,10 @@ protected function buildCommand(array $connection, array $rules, $real = false) if (!empty($connection['port'])) { $options[] = '-p '.$connection['port']; } + + if($connection['ssh_port']!=22) { + $options[] = sprintf('--rsh="ssh -p%d"', $connection['ssh_port']); + } if ($this->config['delete']) { $options[] = '--delete'; From b011cde0755cfa615de0e52979adb2b058547841 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Thu, 1 Nov 2012 09:45:53 +0100 Subject: [PATCH 02/26] Update Deployer/Deployer.php If no serverName is given on the deploy command, only deploy on the first server --- Deployer/Deployer.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Deployer/Deployer.php b/Deployer/Deployer.php index e3a8be8..d4c39e0 100755 --- a/Deployer/Deployer.php +++ b/Deployer/Deployer.php @@ -67,12 +67,10 @@ public function test($server = null) */ protected function deploy($server = null, $real = false) { - if(is_null($server)) { - foreach($this->config->getServerNames() as $server) { - $this->deploy($server, $real); - } - - return; + if(is_null($server)){ + $serverNames = $this->config->getServerNames(); + reset($serverNames); + return $this->deploy(current($serverNames)); } $this->dispatcher->dispatch(Events::onDeploymentStart, new DeployerEvent($server, $real)); From 0cf86e668f7975c05be6d23082289c5ff5a08239 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 28 Dec 2012 17:17:33 +0100 Subject: [PATCH 03/26] using the correct array keys and check if existing --- DependencyInjection/BeSimpleDeploymentExtension.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DependencyInjection/BeSimpleDeploymentExtension.php b/DependencyInjection/BeSimpleDeploymentExtension.php index af459a9..5798846 100755 --- a/DependencyInjection/BeSimpleDeploymentExtension.php +++ b/DependencyInjection/BeSimpleDeploymentExtension.php @@ -24,11 +24,11 @@ public function load(array $configs, ContainerBuilder $container) $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('deployment.xml'); - $container->setParameter('be_simple_deployment.config.rsync', $config['rsync']); - $container->setParameter('be_simple_deployment.config.ssh', $config['rsync']); - $container->setParameter('be_simple_deployment.config.rules', $config['rules']); - $container->setParameter('be_simple_deployment.config.commands', $config['commands']); - $container->setParameter('be_simple_deployment.config.servers', $config['servers']); + $container->setParameter('be_simple_deployment.config.rsync', isset($config['rsync']) ? $config['rsync'] : array()); + $container->setParameter('be_simple_deployment.config.ssh', isset($config['ssh']) ? $config['ssh'] : array()); + $container->setParameter('be_simple_deployment.config.rules', isset($config['rules']) ? $config['rules'] : array()); + $container->setParameter('be_simple_deployment.config.commands', isset($config['commands']) ? $config['commands'] : array()); + $container->setParameter('be_simple_deployment.config.servers', isset($config['servers']) ? $config['servers'] : array()); } /** From 23b8902767e97990bba232bbdf1d6a6c87a4e418 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 28 Dec 2012 17:18:52 +0100 Subject: [PATCH 04/26] add default ssh config and give possibility to overwrite the options in the servers section add connect_methods for ssh2_connect third parameter methods add default env dev add pub/priv ssh auth key with passphrase --- DependencyInjection/Configuration.php | 55 ++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ed27bda..245cce2 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -52,9 +52,34 @@ protected function addSshSection(ArrayNodeDefinition $node) { $node->children() ->arrayNode('ssh')->children() + ->scalarNode('username')->defaultNull()->end() + ->scalarNode('password')->defaultNull()->end() + ->scalarNode('pubkey_file')->defaultNull()->end() ->scalarNode('privkey_file')->defaultNull()->end() ->scalarNode('passphrase')->defaultNull()->end() + ->arrayNode('connect_methods') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('kex')->defaultNull()->end() + ->scalarNode('hostkey')->defaultNull()->end() + ->arrayNode('client_to_server') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('crypt')->defaultNull()->end() + ->scalarNode('comp')->defaultNull()->end() + ->scalarNode('mac')->defaultNull()->end() + ->end() + ->end() + ->arrayNode('server_to_client') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('crypt')->defaultNull()->end() + ->scalarNode('comp')->defaultNull()->end() + ->scalarNode('mac')->defaultNull()->end() + ->end() + ->end() + ->end() ->end() ; } @@ -96,7 +121,7 @@ protected function addCommandsSection(ArrayNodeDefinition $node) ->prototype('array')->children() ->scalarNode('type')->defaultValue('symfony')->end() ->scalarNode('command')->isRequired()->cannotBeEmpty()->end() - ->scalarNode('env')->defaultNull()->end() + ->scalarNode('env')->defaultValue('dev')->end() ->end() ; } @@ -114,8 +139,36 @@ protected function addServersSection(ArrayNodeDefinition $node) ->scalarNode('host')->defaultValue('localhost')->end() ->scalarNode('rsync_port')->defaultNull()->end() ->scalarNode('ssh_port')->defaultValue(22)->cannotBeEmpty()->end() + ->scalarNode('username')->defaultNull()->end() ->scalarNode('password')->defaultNull()->end() + + ->scalarNode('symfony_command')->defaultValue('php app/console')->end() + + ->scalarNode('pubkey_file')->defaultNull()->end() + ->scalarNode('privkey_file')->defaultNull()->end() + ->scalarNode('passphrase')->defaultNull()->end() + + ->arrayNode('connect_methods') + ->children() + ->scalarNode('kex')->end() + ->scalarNode('hostkey')->end() + ->arrayNode('client_to_server') + ->children() + ->scalarNode('crypt')->end() + ->scalarNode('comp')->end() + ->scalarNode('mac')->end() + ->end() + ->end() + ->arrayNode('server_to_client') + ->children() + ->scalarNode('crypt')->end() + ->scalarNode('comp')->end() + ->scalarNode('mac')->end() + ->end() + ->end() + ->end() + ->end() ->scalarNode('path')->isRequired()->cannotBeEmpty()->end() ->arrayNode('rules') ->useAttributeAsKey('rules')->prototype('scalar')->end() From c2aedce6546ccd037651b9c8ec29280823860721 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 28 Dec 2012 17:20:17 +0100 Subject: [PATCH 05/26] cd always on each command because ssh2_exec is used using ssh2_connect methods parameter try username and pass and then pub/priv key with passphrase buildCommand with symfony command prefix (php app/console e.g.) --- Deployer/Ssh.php | 87 +++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/Deployer/Ssh.php b/Deployer/Ssh.php index 653f2ce..7d21bb0 100644 --- a/Deployer/Ssh.php +++ b/Deployer/Ssh.php @@ -96,16 +96,13 @@ public function getStderr($glue = "\n") public function run(array $connection, array $commands, $real = false) { $this->connect($connection); - $this->execute(array('type' => 'shell', 'command' => sprintf('cd %s', $connection['path']))); - if ($real) { - foreach ($commands as $command) { - $this->execute($command); + if($real){ + foreach($commands as $command){ + $this->execute($command, $connection); } } - $this->disconnect(); - return $this->stdout; } @@ -116,72 +113,62 @@ public function run(array $connection, array $commands, $real = false) */ protected function connect(array $connection) { - $this->session = ssh2_connect($connection['host'], $connection['ssh_port']); + $methods = @$connection['connect_methods'] ?: @$this->config['connect_methods']; + $this->session = @ssh2_connect($connection['host'], $connection['ssh_port'], $methods); if (!$this->session) { throw new \InvalidArgumentException(sprintf('SSH connection failed on "%s:%s"', $connection['host'], $connection['ssh_port'])); } - if (isset($connection['username']) && isset($connection['pubkey_file']) && isset($connection['privkey_file'])) { - if (!ssh2_auth_pubkey_file($connection['username'], $connection['pubkey_file'], $connection['privkey_file'], $connection['passphrase'])) { - throw new \InvalidArgumentException(sprintf('SSH authentication failed for user "%s" with public key "%s"', $connection['username'], $connection['pubkey_file'])); - } - } else if ($connection['username'] && $connection['password']) { - if (!ssh2_auth_password($this->session, $connection['username'], $connection['password'])) { - throw new \InvalidArgumentException(sprintf('SSH authentication failed for user "%s"', $connection['username'])); - } - } + $username = @$connection['username'] ?: @$this->config['username']; + $password = @$connection['password'] ?: @$this->config['password']; - $this->shell = ssh2_shell($this->session); + if($username && $password){ + if(!ssh2_auth_password($this->session, $username, $password)){ + throw new \InvalidArgumentException(sprintf('SSH authentication failed for user "%s"', $username)); + } + }elseif($username){ + $pubkey = @$connection['pubkey_file'] ?: @$this->config['pubkey_file']; + $privkey = @$connection['privkey_file'] ?: @$this->config['privkey_file']; + $passphrase = @$connection['passphrase'] ?: @$this->config['passphrase']; - if (!$this->shell) { - throw new \RuntimeException(sprintf('Failed opening "%s" shell', $this->config['shell'])); + if(!ssh2_auth_pubkey_file($this->session, $username, $pubkey, $privkey, $passphrase)){ + throw new \InvalidArgumentException(sprintf('SSH authentication failed for user "%s" with public key "%s"', $username, $pubkey)); + } } $this->stdout = array(); $this->stdin = array(); } - /** - * @return void - */ - protected function disconnect() - { - fclose($this->shell); - } - /** * @param array $command - * @return void + * @param array $connection */ - protected function execute(array $command) + protected function execute(array $command, array $connection) { - $command = $this->buildCommand($command); + $command = $this->buildCommand($command, $connection); $this->dispatcher->dispatch(Events::onDeploymentSshStart, new CommandEvent($command)); - $outStream = ssh2_exec($this->session, $command); + $outStream = ssh2_exec($this->session, $command, "xterm"); $errStream = ssh2_fetch_stream($outStream, SSH2_STREAM_STDERR); stream_set_blocking($outStream, true); stream_set_blocking($errStream, true); - $stdout = explode("\n", stream_get_contents($outStream)); - $stderr = explode("\n", stream_get_contents($errStream)); + $stdout = stream_get_contents($outStream); + $stderr = stream_get_contents($errStream); - if (count($stdout)) { - $this->dispatcher->dispatch(Events::onDeploymentRsyncFeedback, new FeedbackEvent('out', implode("\n", $stdout))); + if($stdout){ + $this->dispatcher->dispatch(Events::onDeploymentSshFeedback, new FeedbackEvent('out', $stdout)); } - if (count($stdout)) { - $this->dispatcher->dispatch(Events::onDeploymentRsyncFeedback, new FeedbackEvent('err', implode("\n", $stderr))); + if($stderr){ + $this->dispatcher->dispatch(Events::onDeploymentSshFeedback, new FeedbackEvent('err', $stderr)); } - $this->stdout = array_merge($this->stdout, $stdout); - - if (is_array($stderr)) { - $this->stderr = array_merge($this->stderr, $stderr); - } else { + if(!$stderr){ $this->dispatcher->dispatch(Events::onDeploymentSshSuccess, new CommandEvent($command)); } @@ -193,15 +180,17 @@ protected function execute(array $command) * @param array $command * @return string */ - protected function buildCommand(array $command) + protected function buildCommand(array $command, array $connection) { - if ($command['type'] === 'shell') { - return $command['command']; + switch($command['type']){ + case 'shell': + return $command['command']; + break; + case 'symfony': + return sprintf('cd %s && %s %s --env=%s', $connection['path'], $connection['symfony_command'], $command['command'], $command['env']); + break; } - $symfony = $this->config['symfony_command']; - $env = $command['env'] ?: $this->env; - - return sprintf('%s %s --env="%s"', $symfony, $command['command'], $env); + throw new \InvalidArgumentException(sprintf('CommandType "%s" invalid', $command['type'])); } } From 5237f7af3e4611eaed9e8163bae0203afd1ef23a Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 28 Dec 2012 17:30:46 +0100 Subject: [PATCH 06/26] remove env - moved to symfony_command --- DependencyInjection/Configuration.php | 1 - Deployer/Ssh.php | 2 +- README.md | 140 ++++++++++++-------------- 3 files changed, 63 insertions(+), 80 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 245cce2..375bf76 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -121,7 +121,6 @@ protected function addCommandsSection(ArrayNodeDefinition $node) ->prototype('array')->children() ->scalarNode('type')->defaultValue('symfony')->end() ->scalarNode('command')->isRequired()->cannotBeEmpty()->end() - ->scalarNode('env')->defaultValue('dev')->end() ->end() ; } diff --git a/Deployer/Ssh.php b/Deployer/Ssh.php index 7d21bb0..51dd8f5 100644 --- a/Deployer/Ssh.php +++ b/Deployer/Ssh.php @@ -187,7 +187,7 @@ protected function buildCommand(array $command, array $connection) return $command['command']; break; case 'symfony': - return sprintf('cd %s && %s %s --env=%s', $connection['path'], $connection['symfony_command'], $command['command'], $command['env']); + return sprintf('cd %s && %s %s', $connection['path'], $connection['symfony_command'], $command['command']); break; } diff --git a/README.md b/README.md index 2f36e3c..da091c9 100755 --- a/README.md +++ b/README.md @@ -1,14 +1,11 @@ Symfony2 applications deployment made easy ========================================== - *Up to date thanks to jonaswouters* - A few words ----------- - ###Description - Deploy your project usinc rsync (must be installed) in ssh mode. @@ -16,24 +13,20 @@ A few words - Easily create rules for rsync (ignore / force files). - Schedule commands to run on ditant server via ssh (SSH2 PHP extension required). - ###Links - Stable releases : [https://github.com/besimple/DeploymentBundle](https://github.com/besimple/DeploymentBundle) - Nightly builds : [https://github.com/jfsimon/DeploymentBundle](https://github.com/jfsimon/DeploymentBundle) - Rest documentation : *will come later* - ###Requirements - Rsync package : [http://samba.anu.edu.au/rsync/](http://samba.anu.edu.au/rsync/) - SSH2 extension : [http://fr.php.net/manual/en/book.ssh2.php](http://fr.php.net/manual/en/book.ssh2.php) - How to install -------------- - 1. Get the sources via GIT - Use clone method if not using GIT for your project @@ -82,79 +75,71 @@ How to install How to configure ---------------- - ###An example be_simple_deployment: - - rsync: - delete: true - - ssh: - pubkey_file: /home/me/.ssh/id_rsa.pub - privkey_file: /home/me/.ssh/id_rsa - passwphrase: secret - - rules: - eclipse: - ignore: [.settings, .buildpath, .project] - git: - ignore: [.git, .git*, .svn] - symfony: - ignore: [/app/logs/*, /app/cache/*, /web/uploads/*, /web/*_dev.php] - - commands: - cache_warmup: - type: symfony - command: cache:warmup - fix_perms: - type: shell - command: ./bin/fix_perms.sh - - servers: - staging: - host: localhost - username: login - password: passwd - path: /path/to/project - rules: [eclipse, symfony] - commands: [cache_warmup, fix_perms] - production: - # ... - - -###Rsync configuration - -To be continued. - - -###SSH configuration - -To be continued. - - -###Rules configuration - -Rules can be declared as templates for reuse in your servers configuration. -Some templates are already bundled by default. The following parameters can be used : - -- ignore : masks for the files to be ignored -- force : ignored files can be forced this way - - -###Servers configuration - -Here is the full list of parameters : - -- host : -- rsync_port : -- ssh_port : -- username -- password : -- path : the path for your application root on the remote server -- rules : list of rules templates to apply -- commands : list of commands to trigger on destination server - + rsync: + delete: true + rules: + eclipse: + ignore: [.settings, .buildpath, .project] + netbeans: + ignore: [nbproject] + phpstorm: + ignore: [.idea] + git: + ignore: [.git, .git*] + svn: + ignore: [.svn] + symfony: + ignore: [/app/cache/*, /app/logs/*, /app/config/parameters.yml, /web/bundles/*, /web/uploads/*, /web/js/*, /web/css/*] + hosting: + ignore: [/.htaccess, /.htpasswd, /web/.htaccess, /web/.user.ini, /web/manage.php, /web/phpinfo.php, /web/ntunnel_mysql.php] + system: + ignore: [._*, .DS_Store] + commands: + cache_clear: + type: symfony + command: cache:clear + assetic_dump: + type: symfony + command: assetic:dump + assets_install: + type: symfony + command: assets:install + ssh: + connect_methods: + server_to_client: + crypt: rijndael-cbc@lysator.liu.se, aes256-cbc, aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, cast128-cbc, arcfour + client_to_server: + crypt: rijndael-cbc@lysator.liu.se, aes256-cbc, aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, cast128-cbc, arcfour + servers: + dev: + host: dev.server.ch + username: username + + pubkey_file: %deploy_dev_pubkey_file% + privkey_file: %deploy_dev_privkey_file% + passphrase: %deploy_dev_passphrase% + + path: /home/user/www/dev.project.com/ + rules: [eclipse, netbeans, phpstorm, git, svn, symfony, hosting, system] + commands: [cache_clear, assetic_dump, assets_install] + + symfony_command: php -c web/.user.ini app/console --env=dev + prod: + host: prod.server.ch + username: username + + pubkey_file: %deploy_prod_pubkey_file% + privkey_file: %deploy_prod_privkey_file% + passphrase: %deploy_prod_passphrase% + + path: /home/user/www/prod.project.com/ + rules: [eclipse, netbeans, phpstorm, git, svn, symfony, hosting, system] + commands: [cache_clear_dev, assetic_dump, assets_install] + + symfony_command: php -c web/.user.ini app/console --env=prod How to use ---------- @@ -174,7 +159,6 @@ go into your project root folder and type the following commands : You can use the verbose option (`-v`) to get all feedback from rsync and remote ssh commands. - ###Using the service You can also use the deployment feature within your controller From a4e24da902f542edd96bf0dc501ecd2a8f217ffe Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 28 Dec 2012 17:41:08 +0100 Subject: [PATCH 07/26] format --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index da091c9..7992558 100755 --- a/README.md +++ b/README.md @@ -144,7 +144,6 @@ How to configure How to use ---------- - ###Using the commands The simpliest way to deploy your application is to use the command line, From e61bf8f2b85609f9fe6936224844e52b7a3c9a41 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 28 Dec 2012 17:52:38 +0100 Subject: [PATCH 08/26] format --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 7992558..4a570d6 100755 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ How to install git submodule add git://github.com/besimple/DeploymentBundle.git vendor/BeSimple/DeploymentBundle - 2. Register bundle in `AppKernel` class // app/AppKernel.php @@ -48,7 +47,6 @@ How to install // ... ); - 3. Add `besimple_deployment` entry to your config file # app/config.yml @@ -60,7 +58,6 @@ How to install commands: ~ servers: ~ - 4. Add `BeSimple` namespace to autoload // app/autoload.php @@ -71,7 +68,6 @@ How to install // ... )); - How to configure ---------------- @@ -176,16 +172,14 @@ You can connect many events to know what's happening. - **onDeploymentStart** : fired on deployment start. - **onDeploymentSuccess** : fired on deployment success. - ###Rsync events - **onDeploymentRsyncStart** : fired when rsync is started. - **onDeploymentRsyncFeedback** : fired on each rsync `stdout` or `stderr` line. - **onDeploymentRsyncSuccess** : fired on rsync success. - ###SSH events - **onDeploymentSshStart** : fired when SSH command run. - **onDeploymentSshFeedback** : fired on each SSH `stdout` or `stderr` line. -- **onDeploymentSshSuccess** : fired on SSH command success. +- **onDeploymentSshSuccess** : fired on SSH command success. \ No newline at end of file From 3d3ce28201647942aeac2aceca5147f63a5c0d1d Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 28 Dec 2012 18:01:32 +0100 Subject: [PATCH 09/26] add composer.json --- composer.json | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..5084be8 --- /dev/null +++ b/composer.json @@ -0,0 +1,27 @@ +{ + "name": "ibrows/be-simple-deployment-bundle", + "description": "Symfony2 applications deployment made easy", + "keywords": ["ibrows", "deployment", "deploy"], + "type": "symfony-bundle", + "license": "MIT", + "authors": [ + { + "name": "Mike Meier", + "email": "mike.meier@ibrows.ch" + } + ], + + "require": { + "php": ">=5.3.0", + "symfony/console": "2.1.*", + "symfony/framework-bundle": ">=2.0,<2.2-dev" + }, + + "autoload": { + "psr-0": { "BeSimple\\DeploymentBundle": "" } + }, + + "target-dir": "BeSimple/DeploymentBundle", + + "minimum-stability": "dev" +} \ No newline at end of file From af21a384cc5250fee607b034fa4066be7f7c65a3 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 28 Dec 2012 18:10:35 +0100 Subject: [PATCH 10/26] format --- composer.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/composer.json b/composer.json index 5084be8..ace3793 100644 --- a/composer.json +++ b/composer.json @@ -10,18 +10,14 @@ "email": "mike.meier@ibrows.ch" } ], - "require": { "php": ">=5.3.0", "symfony/console": "2.1.*", "symfony/framework-bundle": ">=2.0,<2.2-dev" }, - "autoload": { "psr-0": { "BeSimple\\DeploymentBundle": "" } }, - "target-dir": "BeSimple/DeploymentBundle", - "minimum-stability": "dev" } \ No newline at end of file From 965d5188bfbf72319a4d7313b9a6d1052bd6511c Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Tue, 8 Jan 2013 09:40:31 +0100 Subject: [PATCH 11/26] Update Deployer/Ssh.php --- Deployer/Ssh.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Deployer/Ssh.php b/Deployer/Ssh.php index 51dd8f5..f38c8b1 100644 --- a/Deployer/Ssh.php +++ b/Deployer/Ssh.php @@ -148,6 +148,7 @@ protected function connect(array $connection) protected function execute(array $command, array $connection) { $command = $this->buildCommand($command, $connection); + $this->dispatcher->dispatch(Events::onDeploymentSshFeedback, new FeedbackEvent('out', 'Trying: '. $command)); $this->dispatcher->dispatch(Events::onDeploymentSshStart, new CommandEvent($command)); From 5273d0ed2aacb16bebff9a8330441366332c3921 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Tue, 8 Jan 2013 09:41:24 +0100 Subject: [PATCH 12/26] Update Deployer/Ssh.php --- Deployer/Ssh.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/Deployer/Ssh.php b/Deployer/Ssh.php index f38c8b1..b0e77d1 100644 --- a/Deployer/Ssh.php +++ b/Deployer/Ssh.php @@ -148,8 +148,6 @@ protected function connect(array $connection) protected function execute(array $command, array $connection) { $command = $this->buildCommand($command, $connection); - $this->dispatcher->dispatch(Events::onDeploymentSshFeedback, new FeedbackEvent('out', 'Trying: '. $command)); - $this->dispatcher->dispatch(Events::onDeploymentSshStart, new CommandEvent($command)); $outStream = ssh2_exec($this->session, $command, "xterm"); From ffc8498887d4831090228a6e5d0bb7464e2a78af Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Tue, 8 Jan 2013 15:06:17 +0100 Subject: [PATCH 13/26] add onDeploymentSshStart eventListener for output --- Command/DeploymentCommand.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Command/DeploymentCommand.php b/Command/DeploymentCommand.php index 49c52a8..6fff8be 100644 --- a/Command/DeploymentCommand.php +++ b/Command/DeploymentCommand.php @@ -58,6 +58,13 @@ protected function execute(InputInterface $input, OutputInterface $output) )); }); + $eventDispatcher->addListener(Events::onDeploymentSshStart, function (CommandEvent $event) use ($self) { + $self->write(sprintf( + '[Try SSH Command] %s', + $event->getCommand() + )); + }); + // Feedback events if ($output->getVerbosity() > Output::VERBOSITY_NORMAL) { From d51ddb7cb6769aee2409e8845281ec9f9f179e7a Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Wed, 9 Jan 2013 11:16:51 +0100 Subject: [PATCH 14/26] allow to export env variables to commands --- DependencyInjection/Configuration.php | 1 + Deployer/Ssh.php | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 375bf76..172ed41 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -121,6 +121,7 @@ protected function addCommandsSection(ArrayNodeDefinition $node) ->prototype('array')->children() ->scalarNode('type')->defaultValue('symfony')->end() ->scalarNode('command')->isRequired()->cannotBeEmpty()->end() + ->arrayNode('env')->prototype('scalar')->end() ->end() ; } diff --git a/Deployer/Ssh.php b/Deployer/Ssh.php index b0e77d1..19218a5 100644 --- a/Deployer/Ssh.php +++ b/Deployer/Ssh.php @@ -142,15 +142,15 @@ protected function connect(array $connection) } /** - * @param array $command + * @param array $commandArray * @param array $connection */ - protected function execute(array $command, array $connection) + protected function execute(array $commandArray, array $connection) { - $command = $this->buildCommand($command, $connection); + $command = $this->buildCommand($commandArray, $connection); $this->dispatcher->dispatch(Events::onDeploymentSshStart, new CommandEvent($command)); - $outStream = ssh2_exec($this->session, $command, "xterm"); + $outStream = ssh2_exec($this->session, $command); $errStream = ssh2_fetch_stream($outStream, SSH2_STREAM_STDERR); stream_set_blocking($outStream, true); @@ -176,20 +176,27 @@ protected function execute(array $command, array $connection) } /** - * @param array $command + * @param array $commandArray + * @param array $connection * @return string + * @throws \InvalidArgumentException */ - protected function buildCommand(array $command, array $connection) + protected function buildCommand(array $commandArray, array $connection) { - switch($command['type']){ + $envs = ''; + foreach($commandArray['env'] as $key => $value){ + $envs .= 'declare -x '.$key.'='.$value.' && '; + } + + switch($commandArray['type']){ case 'shell': - return $command['command']; + return sprintf("%s%s", $envs, $commandArray['command']); break; case 'symfony': - return sprintf('cd %s && %s %s', $connection['path'], $connection['symfony_command'], $command['command']); + return sprintf('%scd %s && %s %s', $envs, $connection['path'], $connection['symfony_command'], $commandArray['command']); break; } - throw new \InvalidArgumentException(sprintf('CommandType "%s" invalid', $command['type'])); + throw new \InvalidArgumentException(sprintf('CommandType "%s" invalid', $commandArray['type'])); } } From 35dc89af52e59f75457bf3cb517873dab8bf1e71 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Mon, 14 Jan 2013 09:37:19 +0100 Subject: [PATCH 15/26] remove console requirement --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index ace3793..6dec93c 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,6 @@ ], "require": { "php": ">=5.3.0", - "symfony/console": "2.1.*", "symfony/framework-bundle": ">=2.0,<2.2-dev" }, "autoload": { From 85d1076b1327ccc25a21c85a2529b2244720284c Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Wed, 6 Feb 2013 17:36:44 +0100 Subject: [PATCH 16/26] remove target dir --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 6dec93c..b9291e3 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,5 @@ "autoload": { "psr-0": { "BeSimple\\DeploymentBundle": "" } }, - "target-dir": "BeSimple/DeploymentBundle", "minimum-stability": "dev" } \ No newline at end of file From fc702a854232d2606a998a93ccef71a76ce4ee06 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Wed, 6 Feb 2013 17:47:39 +0100 Subject: [PATCH 17/26] add target dir --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index b9291e3..6dec93c 100644 --- a/composer.json +++ b/composer.json @@ -17,5 +17,6 @@ "autoload": { "psr-0": { "BeSimple\\DeploymentBundle": "" } }, + "target-dir": "BeSimple/DeploymentBundle", "minimum-stability": "dev" } \ No newline at end of file From 1935cb749f619c7ce54ae40552a29dca72d7f25a Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Wed, 13 Feb 2013 12:10:54 +0100 Subject: [PATCH 18/26] increase rsync timeout from default 60s to 120s --- Deployer/Rsync.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Deployer/Rsync.php b/Deployer/Rsync.php index aa2b1a1..6fe3c13 100644 --- a/Deployer/Rsync.php +++ b/Deployer/Rsync.php @@ -99,6 +99,7 @@ public function run(array $connection, array $rules, $real = false) $command = $this->buildCommand($connection, $rules, $real); $process = new Process($command, $root); + $process->setTimeout(120); $this->stderr = array(); $this->stdout = array(); From ceefcd577c747aa2d8424fda662ac483a2559227 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Fri, 15 Feb 2013 15:26:10 +0100 Subject: [PATCH 19/26] add version --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 6dec93c..603398c 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,7 @@ "keywords": ["ibrows", "deployment", "deploy"], "type": "symfony-bundle", "license": "MIT", + "version": "1.0.0", "authors": [ { "name": "Mike Meier", From dbebfbd6264d7e7b0c471c05f1004a90e84ce821 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Tue, 19 Feb 2013 15:41:09 +0100 Subject: [PATCH 20/26] allow symfony upgrades --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 603398c..5f60249 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ ], "require": { "php": ">=5.3.0", - "symfony/framework-bundle": ">=2.0,<2.2-dev" + "symfony/framework-bundle": ">=2.0" }, "autoload": { "psr-0": { "BeSimple\\DeploymentBundle": "" } From 677cec1ba1947d1a5255b62debf87d4d49c7fc52 Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Wed, 20 Feb 2013 10:18:04 +0100 Subject: [PATCH 21/26] remove version --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 5f60249..0940c42 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,6 @@ "keywords": ["ibrows", "deployment", "deploy"], "type": "symfony-bundle", "license": "MIT", - "version": "1.0.0", "authors": [ { "name": "Mike Meier", From 2c6c05d7922f689daf7164463129cad30fb88b7a Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Tue, 5 Mar 2013 12:41:20 +0100 Subject: [PATCH 22/26] enable git tagging --- BeSimpleDeploymentBundle.php | 2 +- Command/DeploymentCommand.php | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/BeSimpleDeploymentBundle.php b/BeSimpleDeploymentBundle.php index f783299..06f27a3 100755 --- a/BeSimpleDeploymentBundle.php +++ b/BeSimpleDeploymentBundle.php @@ -6,4 +6,4 @@ class BeSimpleDeploymentBundle extends Bundle { -} +} \ No newline at end of file diff --git a/Command/DeploymentCommand.php b/Command/DeploymentCommand.php index 6fff8be..1d8e84c 100644 --- a/Command/DeploymentCommand.php +++ b/Command/DeploymentCommand.php @@ -27,6 +27,7 @@ protected function configure() $this ->setDefinition(array( new InputArgument('server', InputArgument::OPTIONAL, 'The target server name', null), + new InputOption('tag', 't', InputOption::VALUE_NONE, 'Tag with git if real deployment') )) ; } @@ -93,6 +94,49 @@ protected function execute(InputInterface $input, OutputInterface $output) ), 'info'); }); + if($input->getOption('tag')){ + $eventDispatcher->addListener(Events::onDeploymentSuccess, function (DeployerEvent $event) use ($self) { + if(!$event->isTest()){ + $path = realpath($this->getApplication()->getKernel()->getRootDir().'/..'); + if(is_dir($path)){ + $tag = 'deploy-'. strtolower($event->getServer()); + + $self->write(sprintf( + 'Trying to set GIT tag %s in %s', + $tag, + $path + ), 'comment'); + + $gitCmd = sprintf( + 'git --git-dir=%s --work-tree=%s', + $path.'/.git', + $path + ); + + $status = shell_exec($gitCmd.' status -s'); + if($status !== null){ + $self->write(sprintf('There are uncommitted changes - wont set the tag: %s', $status), 'error'); + return; + } + + $commit = shell_exec($gitCmd.' rev-parse HEAD'); + if(!$commit){ + $self->write('Last commit-hash not found for HEAD', 'error'); + return; + } + + $tagResult = shell_exec($gitCmd.' tag -f '. $tag .' '. $commit); + if(!$tagResult){ + $self->write('Tagging seems ok. Try "git push --tags"', 'info'); + return; + } + + $self->write($tagResult, 'info'); + } + } + }); + } + $eventDispatcher->addListener(Events::onDeploymentRsyncSuccess, function (CommandEvent $event) use ($self) { $self->write(sprintf( '[Rsync success] %s', From 68374f235574cf7dfd7ad6111dc039be97df062e Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Thu, 11 Apr 2013 14:44:36 +0200 Subject: [PATCH 23/26] also pass real parameter --- Deployer/Deployer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Deployer/Deployer.php b/Deployer/Deployer.php index d4c39e0..c7b5096 100755 --- a/Deployer/Deployer.php +++ b/Deployer/Deployer.php @@ -70,7 +70,7 @@ protected function deploy($server = null, $real = false) if(is_null($server)){ $serverNames = $this->config->getServerNames(); reset($serverNames); - return $this->deploy(current($serverNames)); + return $this->deploy(current($serverNames), $real); } $this->dispatcher->dispatch(Events::onDeploymentStart, new DeployerEvent($server, $real)); From a653fd1511773d1f132cf52d426322cf19154b6a Mon Sep 17 00:00:00 2001 From: Gladhon Date: Fri, 15 Nov 2013 11:42:17 +0100 Subject: [PATCH 24/26] add timeout config option to rsync --- DependencyInjection/Configuration.php | 1 + Deployer/Rsync.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 172ed41..8108e1a 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -39,6 +39,7 @@ protected function addRsyncSection(ArrayNodeDefinition $node) ->scalarNode('command')->defaultValue('rsync')->cannotBeEmpty()->end() ->booleanNode('delete')->defaultFalse()->end() ->scalarNode('options')->defaultValue('-Cva')->end() + ->scalarNode('timeout')->defaultValue(120)->end() ->scalarNode('root')->defaultValue('%kernel.root_dir%/..')->cannotBeEmpty()->end() ->end() ; diff --git a/Deployer/Rsync.php b/Deployer/Rsync.php index 6fe3c13..e7ab4f0 100644 --- a/Deployer/Rsync.php +++ b/Deployer/Rsync.php @@ -99,7 +99,7 @@ public function run(array $connection, array $rules, $real = false) $command = $this->buildCommand($connection, $rules, $real); $process = new Process($command, $root); - $process->setTimeout(120); + $process->setTimeout($this->config['timeout']); $this->stderr = array(); $this->stdout = array(); @@ -150,7 +150,7 @@ protected function buildCommand(array $connection, array $rules, $real = false) if (!empty($connection['port'])) { $options[] = '-p '.$connection['port']; } - + if($connection['ssh_port']!=22) { $options[] = sprintf('--rsh="ssh -p%d"', $connection['ssh_port']); } From f6fe16e81b27d1a9d51f374e91fbdfa4a2e1218e Mon Sep 17 00:00:00 2001 From: Mike Meier Date: Wed, 30 Apr 2014 13:46:21 +0200 Subject: [PATCH 25/26] Use psr-4 --- composer.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 0940c42..be9e3ca 100644 --- a/composer.json +++ b/composer.json @@ -15,8 +15,6 @@ "symfony/framework-bundle": ">=2.0" }, "autoload": { - "psr-0": { "BeSimple\\DeploymentBundle": "" } - }, - "target-dir": "BeSimple/DeploymentBundle", - "minimum-stability": "dev" -} \ No newline at end of file + "psr-4": { "BeSimple\\DeploymentBundle\\": "" } + } +} From a1d1136ddcda5753ec395be66268172ddf1a07aa Mon Sep 17 00:00:00 2001 From: Gladhon Date: Tue, 3 Jun 2014 18:03:51 +0200 Subject: [PATCH 26/26] Ask for arguments like password if not given --- Deployer/Ssh.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Deployer/Ssh.php b/Deployer/Ssh.php index 19218a5..bd43411 100644 --- a/Deployer/Ssh.php +++ b/Deployer/Ssh.php @@ -2,6 +2,8 @@ namespace BeSimple\DeploymentBundle\Deployer; +use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper; +use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use BeSimple\DeploymentBundle\Event\CommandEvent; use BeSimple\DeploymentBundle\Event\FeedbackEvent; @@ -132,6 +134,19 @@ protected function connect(array $connection) $privkey = @$connection['privkey_file'] ?: @$this->config['privkey_file']; $passphrase = @$connection['passphrase'] ?: @$this->config['passphrase']; + $co = new ConsoleOutput(); + $helper = new DialogHelper(); + $helper->setInputStream($this->stdin); + if(!$pubkey){ + $pubkey = $helper->ask($co,'pubkey_file?'); + } + if(!$privkey){ + $privkey = $helper->ask($co,'privkey_file?'); + } + if(!$passphrase){ + $passphrase = $helper->askHiddenResponse($co,'passphrase?'); + } + if(!ssh2_auth_pubkey_file($this->session, $username, $pubkey, $privkey, $passphrase)){ throw new \InvalidArgumentException(sprintf('SSH authentication failed for user "%s" with public key "%s"', $username, $pubkey)); }