Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/*
4
 * This file is part of the symfony package.
5
 * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
 
11
/**
12
 * Deploys a project to another server.
13
 *
14
 * @package    symfony
15
 * @subpackage task
16
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17
 * @version    SVN: $Id: sfProjectDeployTask.class.php 23922 2009-11-14 14:58:38Z fabien $
18
 */
19
class sfProjectDeployTask extends sfBaseTask
20
{
21
  protected
22
    $outputBuffer = '',
23
    $errorBuffer = '';
24
 
25
  /**
26
   * @see sfTask
27
   */
28
  protected function configure()
29
  {
30
    $this->addArguments(array(
31
      new sfCommandArgument('server', sfCommandArgument::REQUIRED, 'The server name'),
32
    ));
33
 
34
    $this->addOptions(array(
35
      new sfCommandOption('go', null, sfCommandOption::PARAMETER_NONE, 'Do the deployment'),
36
      new sfCommandOption('rsync-dir', null, sfCommandOption::PARAMETER_REQUIRED, 'The directory where to look for rsync*.txt files', 'config'),
37
      new sfCommandOption('rsync-options', null, sfCommandOption::PARAMETER_OPTIONAL, 'To options to pass to the rsync executable', '-azC --force --delete --progress'),
38
    ));
39
 
40
    $this->namespace = 'project';
41
    $this->name = 'deploy';
42
    $this->briefDescription = 'Deploys a project to another server';
43
 
44
    $this->detailedDescription = <<<EOF
45
The [project:deploy|INFO] task deploys a project on a server:
46
 
47
  [./symfony project:deploy production|INFO]
48
 
49
The server must be configured in [config/properties.ini|COMMENT]:
50
 
51
  [[production]
52
    host=www.example.com
53
    port=22
54
    user=fabien
55
    dir=/var/www/sfblog/
56
    type=rsync|INFO]
57
 
58
To automate the deployment, the task uses rsync over SSH.
59
You must configure SSH access with a key or configure the password
60
in [config/properties.ini|COMMENT].
61
 
62
By default, the task is in dry-mode. To do a real deployment, you
63
must pass the [--go|COMMENT] option:
64
 
65
  [./symfony project:deploy --go production|INFO]
66
 
67
Files and directories configured in [config/rsync_exclude.txt|COMMENT] are
68
not deployed:
69
 
70
  [.svn
71
  /web/uploads/*
72
  /cache/*
73
  /log/*|INFO]
74
 
75
You can also create a [rsync.txt|COMMENT] and [rsync_include.txt|COMMENT] files.
76
 
77
If you need to customize the [rsync*.txt|COMMENT] files based on the server,
78
you can pass a [rsync-dir|COMMENT] option:
79
 
80
  [./symfony project:deploy --go --rsync-dir=config/production production|INFO]
81
 
82
Last, you can specify the options passed to the rsync executable, using the
83
[rsync-options|INFO] option (defaults are [-azC --force --delete --progress|INFO]):
84
 
85
  [./symfony project:deploy --go --rsync-options=-avz|INFO]
86
EOF;
87
  }
88
 
89
  /**
90
   * @see sfTask
91
   */
92
  protected function execute($arguments = array(), $options = array())
93
  {
94
    $env = $arguments['server'];
95
 
96
    $ini = sfConfig::get('sf_config_dir').'/properties.ini';
97
    if (!file_exists($ini))
98
    {
99
      throw new sfCommandException('You must create a config/properties.ini file');
100
    }
101
 
102
    $properties = parse_ini_file($ini, true);
103
 
104
    if (!isset($properties[$env]))
105
    {
106
      throw new sfCommandException(sprintf('You must define the configuration for server "%s" in config/properties.ini', $env));
107
    }
108
 
109
    $properties = $properties[$env];
110
 
111
    if (!isset($properties['host']))
112
    {
113
      throw new sfCommandException('You must define a "host" entry.');
114
    }
115
 
116
    if (!isset($properties['dir']))
117
    {
118
      throw new sfCommandException('You must define a "dir" entry.');
119
    }
120
 
121
    $host = $properties['host'];
122
    $dir  = $properties['dir'];
123
    $user = isset($properties['user']) ? $properties['user'].'@' : '';
124
 
125
    if (substr($dir, -1) != '/')
126
    {
127
      $dir .= '/';
128
    }
129
 
130
    $ssh = 'ssh';
131
 
132
    if (isset($properties['port']))
133
    {
134
      $port = $properties['port'];
135
      $ssh = '"ssh -p'.$port.'"';
136
    }
137
 
138
    if (isset($properties['parameters']))
139
    {
140
      $parameters = $properties['parameters'];
141
    }
142
    else
143
    {
144
      $parameters = $options['rsync-options'];
145
      if (file_exists($options['rsync-dir'].'/rsync_exclude.txt'))
146
      {
147
        $parameters .= sprintf(' --exclude-from=%s/rsync_exclude.txt', $options['rsync-dir']);
148
      }
149
 
150
      if (file_exists($options['rsync-dir'].'/rsync_include.txt'))
151
      {
152
        $parameters .= sprintf(' --include-from=%s/rsync_include.txt', $options['rsync-dir']);
153
      }
154
 
155
      if (file_exists($options['rsync-dir'].'/rsync.txt'))
156
      {
157
        $parameters .= sprintf(' --files-from=%s/rsync.txt', $options['rsync-dir']);
158
      }
159
    }
160
 
161
    $dryRun = $options['go'] ? '' : '--dry-run';
162
    $command = "rsync $dryRun $parameters -e $ssh ./ $user$host:$dir";
163
 
164
    $this->getFilesystem()->execute($command, $options['trace'] ? array($this, 'logOutput') : null, array($this, 'logErrors'));
165
 
166
    $this->clearBuffers();
167
  }
168
 
169
  public function logOutput($output)
170
  {
171
    if (false !== $pos = strpos($output, "\n"))
172
    {
173
      $this->outputBuffer .= substr($output, 0, $pos);
174
      $this->log($this->outputBuffer);
175
      $this->outputBuffer = substr($output, $pos + 1);
176
    }
177
    else
178
    {
179
      $this->outputBuffer .= $output;
180
    }
181
  }
182
 
183
  public function logErrors($output)
184
  {
185
    if (false !== $pos = strpos($output, "\n"))
186
    {
187
      $this->errorBuffer .= substr($output, 0, $pos);
188
      $this->log($this->formatter->format($this->errorBuffer, 'ERROR'));
189
      $this->errorBuffer = substr($output, $pos + 1);
190
    }
191
    else
192
    {
193
      $this->errorBuffer .= $output;
194
    }
195
  }
196
 
197
  protected function clearBuffers()
198
  {
199
    if ($this->outputBuffer)
200
    {
201
      $this->log($this->outputBuffer);
202
      $this->outputBuffer = '';
203
    }
204
 
205
    if ($this->errorBuffer)
206
    {
207
      $this->log($this->formatter->format($this->errorBuffer, 'ERROR'));
208
      $this->errorBuffer = '';
209
    }
210
  }
211
}