vlad 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,31 +1,89 @@
1
- == 1.1.1 / 2008-01-14
1
+ === 1.3.0 / 2009-03-04
2
+
3
+ * 9 major enhancements:
4
+
5
+ * Added darcs support. (Brian Palmer)
6
+ * Added git support. (Garry Dolley)
7
+ * Added lighttpd support.
8
+ * Added merb support. (Jamie Macey)
9
+ * Added passenger support. (Alan Harper)
10
+ * Added/merged god, nginx, thin, and maintenance tasks. (github clusterfuck)
11
+ * Allow set to specify that a proc value is :per_thread.
12
+ * Apply Mercurial SCM support patch. Closes ticket 13475
13
+ * remote_task now supports args and supplies task (by Daniel P. Kionka).
14
+
15
+ * 19 minor enhancements:
16
+
17
+ * Add role toplevel method similar to namespace.
18
+ * Added #put method that wraps up Tempfile/rsync pattern.
19
+ * Added #role toplevel method, similar to #namespace.
20
+ * Added FAQ for using vlad through a gateway.
21
+ * Added Phil Hagelburg's one-line multi-stage deployment patch
22
+ * Added rake tracing for rsync command.
23
+ * Added umask variable.
24
+ * Adds specific order to loading. Should fix a number of bugs.
25
+ * Extended vladdemo.sh to allow for N simulated hosts (mostly for testing)
26
+ * Fixed tempfile dependency in #put if you don't load lighttpd or perforce (yipstar)
27
+ * Mercurial now automatically initializes the repository. (Jamie Macey)
28
+ * Moved everything over to put.
29
+ * Now requires rake 0.8.1+.
30
+ * Parameterized 'head' into 'revision' variable (with head as default).
31
+ * Split shared symlink creation to a separate task. (Steve Purcell)
32
+ * Support rake 0.8.
33
+ * Switched to ThreadGroup for Action#execute
34
+ * Updated rakefile for new hoe abilities
35
+ * remote_task :role now allows an empty list of hosts.
36
+
37
+ * 11 bug fixes:
38
+
39
+ * Fixed vladdemo.rb, now uses my checkout for further stress testing.
40
+ * Moved core recipe to front. Was breaking mongrel setup.
41
+ * Added automatic client setup for perforce.
42
+ * Fix mercurial support.
43
+ * Fixed 'too many files' error.
44
+ * Fixed a lame warning in the tests.
45
+ * Fixed cleanup to actually properly clean up.
46
+ * Fixed rake var doco
47
+ * Moved generic app setup to core from mongrel.
48
+ * SSH flags are now an Array for proper inclusion in the command. (Guillaume Pierronnet)
49
+ * git archive now specifically specifies tar format. (knaveofdiamonds)
50
+
51
+ === 1.1.1 / 2008-01-14
2
52
 
3
53
  * 5 major enhancements:
54
+
4
55
  * Support for Rake 0.8. Should still work for Rake 0.7.
5
56
  * Added git support (contributed by Garry Dolley).
6
57
  * Reviewed for accuracy by Evan Phoenix.
7
58
  * Added lighttpd.rb
8
59
  * Added automatic client setup for perforce.
9
60
  * Added mercurial SCM support patch. Closes ticket 13475.
61
+
10
62
  * 6 minor enhancements:
63
+
11
64
  * Added #put method that wraps up Tempfile/rsync pattern.
12
65
  * Added automatic p4 client setup for perforce.
13
66
  * Added vladdemo.sh
14
67
  * Moved everything over to put.
15
68
  * Moved generic app setup to core from mongrel.
16
69
  * Parameterized 'head' into 'revision' variable (with head as default).
70
+
17
71
  * 1 bug fix
72
+
18
73
  * Fixed cleanup to actually properly clean up.
19
74
 
20
- == 1.1.0 / 2007-09-12
75
+ === 1.1.0 / 2007-09-12
21
76
 
22
77
  * 3 major enhancements:
78
+
23
79
  * Vlad.load now takes a hash of recipe overrides, eg: Vlad.load :web => :nginx.
24
80
  See rdoc for defaults.
25
81
  * Removed vlad_tasks.rb and split into vlad/apache.rb, vlad/mongrel.rb,
26
82
  and vlad/core.rb.
27
83
  * The flog ratio between capistrano+deps / vlad+deps is pi (or, damn close)!
84
+
28
85
  * 12 minor enhancements:
86
+
29
87
  * Added $TRACE to make it more available and cleaner to read.
30
88
  * Added :svn_cmd variable.
31
89
  * Added Rake.clear_tasks *str_or_regexp
@@ -38,12 +96,15 @@
38
96
  * Removed :application var. Use it if you want it. We don't require it.
39
97
  * Renamed :p4cmd to :p4_cmd.
40
98
  * Renamed :rake var to :rake_cmd.
99
+
41
100
  * 2 (important) bug fixes:
42
- * HUGE: Fixed sudo hang bug #13072. Fix suggested by Chris Van Pelt.
101
+
102
+ * HUGE: Fixed sudo hang bug #13072. Fix suggested by Chris Van Pelt.
43
103
  * HUGE: Vlad.load calls user config last, allowing variable overrides.
44
104
  ACK! Sorry!
45
105
 
46
- == 1.0.0 / 2007-08-04
106
+ === 1.0.0 / 2007-08-04
47
107
 
48
108
  * 1 major enhancement
109
+
49
110
  * Birthday!
@@ -12,12 +12,19 @@ lib/rake_remote_task.rb
12
12
  lib/vlad.rb
13
13
  lib/vlad/apache.rb
14
14
  lib/vlad/core.rb
15
+ lib/vlad/darcs.rb
15
16
  lib/vlad/git.rb
17
+ lib/vlad/god.rb
16
18
  lib/vlad/lighttpd.rb
19
+ lib/vlad/maintenance.rb
20
+ lib/vlad/merb.rb
17
21
  lib/vlad/mercurial.rb
18
22
  lib/vlad/mongrel.rb
23
+ lib/vlad/nginx.rb
24
+ lib/vlad/passenger.rb
19
25
  lib/vlad/perforce.rb
20
26
  lib/vlad/subversion.rb
27
+ lib/vlad/thin.rb
21
28
  test/test_rake_remote_task.rb
22
29
  test/test_vlad.rb
23
30
  test/test_vlad_git.rb
data/README.txt CHANGED
@@ -1,9 +1,9 @@
1
- Vlad the Deployer
2
- by the Ruby Hit Squad
3
- http://rubyhitsquad.com/
4
- http://rubyforge.org/projects/hitsquad/
1
+ = Vlad the Deployer by the Ruby Hit Squad
5
2
 
6
- == DESCRIPTION:
3
+ * http://rubyhitsquad.com/
4
+ * http://rubyforge.org/projects/hitsquad/
5
+
6
+ == DESCRIPTION
7
7
 
8
8
  Vlad the Deployer is pragmatic application deployment automation,
9
9
  without mercy. Much like Capistrano, but with 1/10th the
@@ -12,7 +12,7 @@ and standard tools like ssh and rsync.
12
12
 
13
13
  Impale your application on the heartless spike of the Deployer.
14
14
 
15
- == FEATURES/PROBLEMS:
15
+ == FEATURES/PROBLEMS
16
16
 
17
17
  * Full deployment automation stack.
18
18
  * Turnkey deployment for mongrel+apache+svn.
@@ -27,36 +27,36 @@ Impale your application on the heartless spike of the Deployer.
27
27
  * Ships with tests that actually pass in 0.028 seconds!
28
28
  * Does NOT support Windows right now (we think). Coming soon in 1.2.
29
29
 
30
- == SYNOPSIS:
30
+ == SYNOPSIS
31
31
 
32
32
  % rake vlad:setup # first time only
33
33
  % rake vlad:update
34
34
  % rake vlad:migrate # optional
35
35
  % rake vlad:start
36
36
 
37
- == REQUIREMENTS:
37
+ == REQUIREMENTS
38
38
 
39
39
  * Rake
40
40
  * Hoe
41
41
  * Rubyforge
42
42
  * open4
43
43
 
44
- == INSTALL:
44
+ == INSTALL
45
45
 
46
- * sudo gem install -y vlad
46
+ * sudo gem install vlad
47
47
 
48
- == SPECIAL THANKS:
48
+ == SPECIAL THANKS
49
49
 
50
50
  * First, of course, to Capistrano. For coming up with the idea and
51
51
  providing a lot of meat for the recipes.
52
52
  * Scott Baron for coming up with one of the best project names evar.
53
53
  * Bradley Taylor for giving us permission to use RailsMachine recipes sans-LGPL.
54
54
 
55
- == LICENSE:
55
+ == LICENSE
56
56
 
57
57
  (The MIT License)
58
58
 
59
- Copyright (c) 2007 Ryan Davis and the rest of the Ruby Hit Squad
59
+ Copyright (c) 2007-2009 Ryan Davis and the rest of the Ruby Hit Squad
60
60
 
61
61
  Permission is hereby granted, free of charge, to any person obtaining
62
62
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -5,16 +5,17 @@ require 'hoe'
5
5
  $: << 'lib'
6
6
  require 'vlad'
7
7
 
8
- Hoe.new('vlad', Vlad::VERSION) do |p|
9
- p.rubyforge_name = 'hitsquad'
10
- p.author = ["Ryan Davis", "Eric Hodel", "Wilson Bilkovich"]
11
- p.email = "ryand-ruby@zenspider.com"
12
- p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/).map { |s| s.strip }[2..-1]
13
- p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
14
- p.summary = p.paragraphs_of('README.txt', 2).join
15
- p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
- p.extra_deps << 'rake'
17
- p.extra_deps << 'open4'
8
+ Hoe.new('vlad', Vlad::VERSION) do |vlad|
9
+ vlad.rubyforge_name = 'hitsquad'
10
+
11
+ vlad.developer('Ryan Davis', 'ryand-ruby@zenspider.com')
12
+ vlad.developer('Eric Hodel', 'drbrain@segment7.net')
13
+ vlad.developer('Wilson Bilkovich', 'wilson@supremetyrant.com')
14
+
15
+ vlad.extra_deps << ['rake', '>= 0.8.1']
16
+ vlad.extra_deps << 'open4'
17
+
18
+ vlad.multiruby_skip << "1.9" << "rubinius"
18
19
  end
19
20
 
20
21
  desc "quick little hack to see what the state of the nation looks like"
@@ -72,4 +72,10 @@ Put a password on your key, distribute your public key to the server and then us
72
72
 
73
73
  Check out this tiny tutorial at LBL: A brief ssh-agent tutorial <http://upc.lbl.gov/docs/user/sshagent.html>
74
74
 
75
- If you're on a mac, use SSHKeychain, we love it. <http://www.sshkeychain.org/>
75
+ If you're on a mac (on tiger, not leopard), use SSHKeychain, we love it. <http://www.sshkeychain.org/>. If you are on leopard, you get all of this for free.
76
+
77
+ === Q: How do I use Vlad with a gateway?
78
+ === A: Add the following to your deploy.rb variables:
79
+
80
+ set :ssh_flags, "-A #{mygateway}"
81
+ set :rsync_flags, "--rsh ssh -A #{mygateway} ssh"
@@ -21,7 +21,7 @@ migrate_target:: Set this if you need to specify a particular migration
21
21
  'VERSION' number. Defaults to "latest".
22
22
  rails_env:: Specifies the RAILS_ENV environment variable that will
23
23
  be used. Defaults to "production".
24
- rake:: Set this if you need to specify an alternate path to
24
+ rake_cmd:: Set this if you need to specify an alternate path to
25
25
  'rake'. Defaults to "rake".
26
26
  release_name:: Name of the release directory, if deploy_timestamped is
27
27
  true. Defaults to timestamp: "YYYYMMDDHHMMSS".
@@ -39,10 +39,11 @@ scm_path:: Path on the remote host that will be used as 'working
39
39
  shared_path:: Full path to remote 'shared' directory, symlinked into
40
40
  your app by default. Defaults to "#{deploy_to}/shared".
41
41
  ssh_cmd:: Path to ssh. Defaults to "ssh".
42
- ssh_flags:: Flags for ssh. Defaults to "".
42
+ ssh_flags:: Flags for ssh. Defaults to [].
43
43
  sudo_cmd:: Path to sudo command. Defaults to "sudo".
44
44
  sudo_flags:: Flogs for sudo. Defaults to nil.
45
45
  sudo_password:: Asks for password when referenced.
46
+ umask:: Sets your umask value. Defaults to "02".
46
47
 
47
48
  == Apache Web Variables:
48
49
 
@@ -5,31 +5,7 @@ require 'vlad'
5
5
 
6
6
  $TESTING ||= false
7
7
  $TRACE = Rake.application.options.trace
8
-
9
- module Rake
10
- module TaskManager
11
- ##
12
- # This gives us access to the tasks already defined in rake.
13
- def all_tasks
14
- @tasks
15
- end
16
- end
17
-
18
- ##
19
- # Hooks into rake and allows us to clear out a task by name or
20
- # regexp. Use this if you want to completely override a task instead
21
- # of extend it.
22
- def self.clear_tasks(*tasks)
23
- tasks.flatten.each do |name|
24
- case name
25
- when Regexp then
26
- Rake.application.all_tasks.delete_if { |k,_| k =~ name }
27
- else
28
- Rake.application.all_tasks.delete(name)
29
- end
30
- end
31
- end
32
- end
8
+ $-w = true if $TRACE # asshat, don't mess with my warn.
33
9
 
34
10
  ##
35
11
  # Declare a remote host and its roles. Equivalent to <tt>role</tt>,
@@ -44,6 +20,7 @@ end
44
20
  # base_name for the tempfile (aids in debugging).
45
21
 
46
22
  def put remote_path, base_name = 'vlad.unknown'
23
+ require 'tempfile'
47
24
  Tempfile.open base_name do |fp|
48
25
  fp.puts yield
49
26
  fp.flush
@@ -55,16 +32,28 @@ end
55
32
  # Declare a Vlad task that will execute on all hosts by default. To
56
33
  # limit that task to specific roles, use:
57
34
  #
58
- # remote_task :example, :roles => [:app, :web] do
59
- def remote_task name, options = {}, &b
60
- Rake::RemoteTask.remote_task name, options, &b
35
+ # remote_task :example, :arg1, :roles => [:app, :web] do
36
+ def remote_task name, *args_options, &b
37
+ Rake::RemoteTask.remote_task name, *args_options, &b
61
38
  end
62
39
 
63
40
  ##
64
41
  # Declare a role and assign a remote host to it. Equivalent to the
65
42
  # <tt>host</tt> method; provided for capistrano compatibility.
66
- def role role_name, host, args = {}
67
- Rake::RemoteTask.role role_name, host, args
43
+ def role role_name, host = nil, args = {}
44
+ if block_given? then
45
+ raise ArgumentError, 'host not allowed with block' unless host.nil?
46
+
47
+ begin
48
+ Rake::RemoteTask.current_roles << role_name
49
+ yield
50
+ ensure
51
+ Rake::RemoteTask.current_roles.delete role_name
52
+ end
53
+ else
54
+ raise ArgumentError, 'host required' if host.nil?
55
+ Rake::RemoteTask.role role_name, host, args
56
+ end
68
57
  end
69
58
 
70
59
  ##
@@ -106,12 +95,39 @@ if Gem::Version.new(RAKEVERSION) < Gem::Version.new('0.8') then
106
95
  end
107
96
  end
108
97
 
98
+ module Rake
99
+ module TaskManager
100
+ ##
101
+ # This gives us access to the tasks already defined in rake.
102
+ def all_tasks
103
+ @tasks
104
+ end
105
+ end
106
+
107
+ ##
108
+ # Hooks into rake and allows us to clear out a task by name or
109
+ # regexp. Use this if you want to completely override a task instead
110
+ # of extend it.
111
+ def self.clear_tasks(*tasks)
112
+ tasks.flatten.each do |name|
113
+ case name
114
+ when Regexp then
115
+ Rake.application.all_tasks.delete_if { |k,_| k =~ name }
116
+ else
117
+ Rake.application.all_tasks.delete(name)
118
+ end
119
+ end
120
+ end
121
+ end
122
+
109
123
  ##
110
124
  # Rake::RemoteTask is a subclass of Rake::Task that adds
111
125
  # remote_actions that execute in parallel on multiple hosts via ssh.
112
126
 
113
127
  class Rake::RemoteTask < Rake::Task
114
128
 
129
+ @@current_roles = []
130
+
115
131
  include Open4
116
132
 
117
133
  ##
@@ -130,6 +146,10 @@ class Rake::RemoteTask < Rake::Task
130
146
 
131
147
  attr_reader :remote_actions
132
148
 
149
+ def self.current_roles
150
+ @@current_roles
151
+ end
152
+
133
153
  ##
134
154
  # Create a new task named +task_name+ attached to Rake::Application +app+.
135
155
 
@@ -160,19 +180,22 @@ class Rake::RemoteTask < Rake::Task
160
180
 
161
181
  def execute(args = nil)
162
182
  raise(Vlad::ConfigurationError,
163
- "No target hosts specified for task: #{self.name}") if
164
- target_hosts.empty?
183
+ "No target hosts specified on task #{self.name} for roles #{options[:roles].inspect}") if
184
+ ! defined_target_hosts?
165
185
 
166
186
  super args
167
187
 
168
- @remote_actions.each { |act| act.execute(target_hosts, args) }
188
+ @remote_actions.each { |act| act.execute(target_hosts, self, args) }
169
189
  end
170
190
 
171
191
  ##
172
192
  # Use rsync to send +local+ to +remote+ on target_host.
173
193
 
174
194
  def rsync local, remote
175
- cmd = [rsync_cmd, rsync_flags, local, "#{@target_host}:#{remote}"].flatten.compact
195
+ cmd = [rsync_cmd, rsync_flags, local, "#{target_host}:#{remote}"]
196
+ cmd = cmd.flatten.compact
197
+
198
+ warn cmd.join(' ') if $TRACE
176
199
 
177
200
  success = system(*cmd)
178
201
 
@@ -186,10 +209,11 @@ class Rake::RemoteTask < Rake::Task
186
209
  # sudo password will be prompted for then saved for subsequent sudo commands.
187
210
 
188
211
  def run command
189
- cmd = [ssh_cmd, ssh_flags, target_host, command].compact
212
+ cmd = [ssh_cmd, ssh_flags, target_host, command].flatten
190
213
  result = []
191
214
 
192
- warn cmd.join(' ') if $TRACE
215
+ trace = [ssh_cmd, ssh_flags, target_host, "'#{command}'"].flatten.join(' ')
216
+ warn trace if $TRACE
193
217
 
194
218
  pid, inn, out, err = popen4(*cmd)
195
219
 
@@ -237,6 +261,10 @@ class Rake::RemoteTask < Rake::Task
237
261
  end
238
262
 
239
263
  result.join
264
+ ensure
265
+ inn.close rescue nil
266
+ out.close rescue nil
267
+ err.close rescue nil
240
268
  end
241
269
 
242
270
  ##
@@ -254,6 +282,10 @@ class Rake::RemoteTask < Rake::Task
254
282
  @@default_env
255
283
  end
256
284
 
285
+ def self.per_thread
286
+ @@per_thread
287
+ end
288
+
257
289
  ##
258
290
  # The vlad environment.
259
291
 
@@ -270,7 +302,8 @@ class Rake::RemoteTask < Rake::Task
270
302
  if @@env.has_key? name then
271
303
  protect_env(name) do
272
304
  v = @@env[name]
273
- v = @@env[name] = v.call if Proc === v
305
+ v = @@env[name] = v.call if Proc === v unless per_thread[name]
306
+ v = v.call if Proc === v
274
307
  v
275
308
  end
276
309
  elsif default
@@ -330,8 +363,11 @@ class Rake::RemoteTask < Rake::Task
330
363
  # Adds a remote task named +name+ with options +options+ that will
331
364
  # execute +block+.
332
365
 
333
- def self.remote_task name, options = {}, &block
334
- t = Rake::RemoteTask.define_task(name, &block)
366
+ def self.remote_task name, *args, &block
367
+ options = (Hash === args.last) ? args.pop : {}
368
+ t = Rake::RemoteTask.define_task(name, *args, &block)
369
+ options[:roles] = Array options[:roles]
370
+ options[:roles] |= @@current_roles
335
371
  t.options = options
336
372
  t
337
373
  end
@@ -348,10 +384,11 @@ class Rake::RemoteTask < Rake::Task
348
384
  # to the defaults.
349
385
 
350
386
  def self.reset
351
- @@roles = Hash.new { |h,k| h[k] = {} }
352
- @@env = {}
353
- @@tasks = {}
354
- @@env_locks = Hash.new { |h,k| h[k] = Mutex.new }
387
+ @@def_role_hash = {} # official default role value
388
+ @@env = {}
389
+ @@tasks = {}
390
+ @@roles = Hash.new { |h,k| h[k] = @@def_role_hash }
391
+ @@env_locks = Hash.new { |h,k| h[k] = Mutex.new }
355
392
 
356
393
  @@default_env.each do |k,v|
357
394
  case v
@@ -367,7 +404,10 @@ class Rake::RemoteTask < Rake::Task
367
404
  # Adds role +role_name+ with +host+ and +args+ for that host.
368
405
 
369
406
  def self.role role_name, host, args = {}
370
- raise ArgumentError, "invalid host" if host.nil? or host.empty?
407
+ [*host].each do |hst|
408
+ raise ArgumentError, "invalid host: #{hst}" if hst.nil? or hst.empty?
409
+ end
410
+ @@roles[role_name] = {} if @@def_role_hash.eql? @@roles[role_name]
371
411
  @@roles[role_name][host] = args
372
412
  end
373
413
 
@@ -389,12 +429,18 @@ class Rake::RemoteTask < Rake::Task
389
429
 
390
430
  def self.set name, value = nil, &default_block
391
431
  raise ArgumentError, "cannot provide both a value and a block" if
392
- value and default_block
432
+ value and default_block unless
433
+ value == :per_thread
393
434
  raise ArgumentError, "cannot set reserved name: '#{name}'" if
394
435
  Rake::RemoteTask.reserved_name?(name) unless $TESTING
395
436
 
396
- Rake::RemoteTask.default_env[name.to_s] = Rake::RemoteTask.env[name.to_s] =
397
- value || default_block
437
+ name = name.to_s
438
+
439
+ Rake::RemoteTask.per_thread[name] = true if
440
+ default_block && value == :per_thread
441
+
442
+ Rake::RemoteTask.default_env[name] = Rake::RemoteTask.env[name] =
443
+ default_block || value
398
444
 
399
445
  Object.send :define_method, name do
400
446
  Rake::RemoteTask.fetch name
@@ -407,6 +453,7 @@ class Rake::RemoteTask < Rake::Task
407
453
 
408
454
  def self.set_defaults
409
455
  @@default_env ||= {}
456
+ @@per_thread ||= {}
410
457
  self.reset
411
458
 
412
459
  mandatory :repository, "repository path"
@@ -424,9 +471,10 @@ class Rake::RemoteTask < Rake::Task
424
471
  :rsync_cmd, "rsync",
425
472
  :rsync_flags, ['-azP', '--delete'],
426
473
  :ssh_cmd, "ssh",
427
- :ssh_flags, nil,
474
+ :ssh_flags, [],
428
475
  :sudo_cmd, "sudo",
429
- :sudo_flags, nil)
476
+ :sudo_flags, nil,
477
+ :umask, '02')
430
478
 
431
479
  set(:current_release) { File.join(releases_path, releases[-1]) }
432
480
  set(:latest_release) { deploy_timestamped ?release_path: current_release }
@@ -503,11 +551,31 @@ class Rake::RemoteTask < Rake::Task
503
551
  if hosts = ENV["HOSTS"] then
504
552
  hosts.strip.gsub(/\s+/, '').split(",")
505
553
  else
506
- roles = options[:roles]
507
- roles ? Rake::RemoteTask.hosts_for(roles) : Rake::RemoteTask.all_hosts
554
+ roles = Array options[:roles]
555
+
556
+ if roles.empty? then
557
+ Rake::RemoteTask.all_hosts
558
+ else
559
+ Rake::RemoteTask.hosts_for roles
560
+ end
508
561
  end
509
562
  end
510
563
 
564
+ ##
565
+ # Similar to target_hosts, but returns true if user defined any hosts, even
566
+ # an empty list.
567
+
568
+ def defined_target_hosts?
569
+ return true if ENV["HOSTS"]
570
+ roles = Array options[:roles]
571
+ return true if roles.empty?
572
+ # borrowed from hosts_for:
573
+ roles.flatten.each { |r|
574
+ return true unless @@def_role_hash.eql? Rake::RemoteTask.roles[r]
575
+ }
576
+ return false
577
+ end
578
+
511
579
  ##
512
580
  # Action is used to run a task's remote_actions in parallel on each
513
581
  # of its hosts. Actions are created automatically in
@@ -536,7 +604,7 @@ class Rake::RemoteTask < Rake::Task
536
604
  def initialize task, block
537
605
  @task = task
538
606
  @block = block
539
- @workers = []
607
+ @workers = ThreadGroup.new
540
608
  end
541
609
 
542
610
  def == other # :nodoc:
@@ -548,17 +616,23 @@ class Rake::RemoteTask < Rake::Task
548
616
  # Execute this action on +hosts+ in parallel. Returns when block
549
617
  # has completed for each host.
550
618
 
551
- def execute hosts, args = nil
619
+ def execute hosts, task, args
552
620
  hosts.each do |host|
553
621
  t = task.clone
554
622
  t.target_host = host
555
623
  thread = Thread.new(t) do |task|
556
624
  Thread.current[:task] = task
557
- block.call args
625
+ case block.arity
626
+ when 1
627
+ block.call task
628
+ else
629
+ block.call task, args
630
+ end
631
+ Thread.current[:task] = nil
558
632
  end
559
- @workers << thread
633
+ @workers.add thread
560
634
  end
561
- @workers.each { |w| w.join }
635
+ @workers.list.each { |thr| thr.join }
562
636
  end
563
637
  end
564
638
  end
@@ -20,7 +20,7 @@ module Vlad
20
20
 
21
21
  ##
22
22
  # This is the version of Vlad you are running.
23
- VERSION = '1.2.0'
23
+ VERSION = '1.3.0'
24
24
 
25
25
  ##
26
26
  # Base error class for all Vlad errors.
@@ -58,6 +58,8 @@ module Vlad
58
58
  # Rakefile. YAY for simple and clean!
59
59
  def self.load options = {}
60
60
  options = {:config => options} if String === options
61
+ order = [:core, :app, :config, :scm, :web]
62
+ order += options.keys - order
61
63
 
62
64
  recipes = {
63
65
  :app => :mongrel,
@@ -67,12 +69,14 @@ module Vlad
67
69
  :web => :apache,
68
70
  }.merge(options)
69
71
 
70
- recipes.each do |flavor, recipe|
72
+ order.each do |flavor|
73
+ recipe = recipes[flavor]
71
74
  next if recipe.nil? or flavor == :config
72
75
  require "vlad/#{recipe}"
73
76
  end
74
77
 
75
78
  Kernel.load recipes[:config]
79
+ Kernel.load "config/deploy_#{ENV['to']}.rb" if ENV['to']
76
80
  end
77
81
  end
78
82
 
@@ -41,7 +41,7 @@ namespace :vlad do
41
41
  remote_task :setup_app, :roles => :app do
42
42
  dirs = [deploy_to, releases_path, scm_path, shared_path]
43
43
  dirs += %w(system log pids).map { |d| File.join(shared_path, d) }
44
- run "umask 02 && mkdir -p #{dirs.join(' ')}"
44
+ run "umask #{umask} && mkdir -p #{dirs.join(' ')}"
45
45
  end
46
46
 
47
47
  desc "Updates your application server to the latest revision. Syncs
@@ -53,15 +53,13 @@ namespace :vlad do
53
53
  symlink = false
54
54
  begin
55
55
  run [ "cd #{scm_path}",
56
- "#{source.checkout revision, '.'}",
57
- "#{source.export ".", release_path}",
56
+ "#{source.checkout revision, scm_path}",
57
+ "#{source.export scm_path, release_path}",
58
58
  "chmod -R g+w #{latest_release}",
59
59
  "rm -rf #{latest_release}/log #{latest_release}/public/system #{latest_release}/tmp/pids",
60
- "mkdir -p #{latest_release}/db #{latest_release}/tmp",
61
- "ln -s #{shared_path}/log #{latest_release}/log",
62
- "ln -s #{shared_path}/system #{latest_release}/public/system",
63
- "ln -s #{shared_path}/pids #{latest_release}/tmp/pids",
60
+ "mkdir -p #{latest_release}/db #{latest_release}/tmp"
64
61
  ].join(" && ")
62
+ Rake::Task['vlad:update_symlinks'].invoke
65
63
 
66
64
  symlink = true
67
65
  run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
@@ -75,6 +73,14 @@ namespace :vlad do
75
73
  end
76
74
  end
77
75
 
76
+ desc "Updates the symlinks for shared paths".cleanup
77
+
78
+ remote_task :update_symlinks, :roles => :app do
79
+ run [ "ln -s #{shared_path}/log #{latest_release}/log",
80
+ "ln -s #{shared_path}/system #{latest_release}/public/system",
81
+ "ln -s #{shared_path}/pids #{latest_release}/tmp/pids" ].join(" && ")
82
+ end
83
+
78
84
  desc "Run the migrate rake task for the the app. By default this is run in
79
85
  the latest app directory. You can run migrations for the current app
80
86
  directory by setting :migrate_target to :current. Additional environment
@@ -0,0 +1,24 @@
1
+ class Vlad::Darcs
2
+
3
+ set :source, Vlad::Darcs.new
4
+ set :darcs_cmd, "darcs"
5
+
6
+ ##
7
+ # Ignores +revision+ for now, exports into directory +destination+
8
+
9
+ def checkout(revision, destination)
10
+ [ %{(test ! -d #{destination}/_darcs && #{darcs_cmd} init "--repodir=#{destination}") || true},
11
+ %{#{darcs_cmd} pull -a "--repodir=#{destination}" #{repository}},
12
+ ].join(" && ")
13
+ end
14
+
15
+ def export(dir, dest)
16
+ [ %{mkdir -p #{dest}},
17
+ %{ls | grep ^[^_] | xargs -I vlad cp -R vlad #{dest}}
18
+ ].join(" && ")
19
+ end
20
+
21
+ def revision(revision)
22
+ revision
23
+ end
24
+ end
@@ -27,7 +27,7 @@ class Vlad::Git
27
27
  revision = 'HEAD' if revision == "."
28
28
 
29
29
  [ "mkdir -p #{destination}",
30
- "#{git_cmd} archive #{revision} | (cd #{destination} && tar xf -)"
30
+ "#{git_cmd} archive --format=tar #{revision} | (cd #{destination} && tar xf -)"
31
31
  ].join(" && ")
32
32
  end
33
33
 
@@ -0,0 +1,23 @@
1
+ require 'vlad'
2
+
3
+ namespace :vlad do
4
+ ## God module for merb app server
5
+
6
+ desc "Prepares application servers for deployment.".cleanup
7
+
8
+ remote_task :setup_app, :roles => :app do
9
+ # do nothing?
10
+ end
11
+
12
+ desc "Restart the app servers"
13
+
14
+ remote_task :start_app, :roles => :app do
15
+ run "god restart #{cluster_name}"
16
+ end
17
+
18
+ desc "Stop the app servers"
19
+
20
+ remote_task :stop_app, :roles => :app do
21
+ run "god stop #{cluster_name}"
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ require 'vlad'
2
+
3
+ namespace :vlad do
4
+ namespace :maintenance do
5
+ remote_task :on, :roles => [:web] do
6
+ run "cp -f #{shared_path}/config/maintenance.html #{shared_path}/system/"
7
+ end
8
+
9
+ remote_task :off, :roles => [:web] do
10
+ run "rm -f #{shared_path}/system/maintenance.html"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ require 'vlad'
2
+
3
+ namespace :vlad do
4
+ ##
5
+ # Merb app server
6
+
7
+ set :merb_address, "127.0.0.1"
8
+ set :merb_command, 'merb'
9
+ set :merb_environment, "production"
10
+ set :merb_port, 8000
11
+ set :merb_servers, 2
12
+
13
+ # maybe needed later
14
+ #set :merb_clean, false
15
+ #set(:merb_conf) { "#{current_path}/config/merb.yml" }
16
+ #set :merb_config_script, nil
17
+ #set :merb_group, nil
18
+ #set :merb_log_file, nil
19
+ #set :merb_pid_file, nil
20
+ #set :merb_prefix, nil
21
+ #set :merb_user, nil
22
+
23
+ desc "Start the app servers"
24
+ remote_task :start_app, :roles => :app do
25
+ cmd = [
26
+ "cd #{current_path} &&", # work around merb bug,
27
+ # http://merb.devjavu.com/ticket/469
28
+ "#{merb_command}",
29
+ #"-m #{current_path}", # the buggy behaviour
30
+ "-e #{merb_environment}",
31
+ "-p #{merb_port}",
32
+ "-c #{merb_servers}"
33
+ ].compact.join ' '
34
+ run cmd
35
+ end
36
+
37
+ desc "Stop the app servers"
38
+ remote_task :stop_app, :roles => :app do
39
+ merb_servers.times do |i|
40
+ cmd = "#{current_path}/script/stop_merb #{merb_port + i}"
41
+ puts "$ #{cmd}"
42
+ run cmd
43
+ end
44
+ end
45
+
46
+ desc "Stop, then restart the app servers"
47
+ remote_task :restart_app, :roles => :app do
48
+ Rake::Task['vlad:stop_app'].invoke
49
+ Rake::Task['vlad:start_app'].invoke
50
+ end
51
+ end
@@ -8,7 +8,10 @@ class Vlad::Mercurial
8
8
 
9
9
  def checkout(revision, destination)
10
10
  revision = 'tip' if revision =~ /^head$/i
11
- "hg pull -r #{revision} -R #{destination} #{repository}"
11
+
12
+ [ "if [ ! -d #{destination}/.hg ]; then hg init -R #{destination}; fi",
13
+ "hg pull -r #{revision} -R #{destination} #{repository}"
14
+ ].join(' && ')
12
15
  end
13
16
 
14
17
  ##
@@ -23,28 +23,29 @@ configuration is set via the mongrel_* variables.".cleanup
23
23
 
24
24
  remote_task :setup_app, :roles => :app do
25
25
  cmd = [
26
- "#{mongrel_command} cluster::configure",
26
+ 'cluster::configure',
27
27
  "-N #{mongrel_servers}",
28
28
  "-p #{mongrel_port}",
29
29
  "-e #{mongrel_environment}",
30
30
  "-a #{mongrel_address}",
31
31
  "-c #{current_path}",
32
- "-C #{mongrel_conf}",
33
32
  ("-P #{mongrel_pid_file}" if mongrel_pid_file),
34
33
  ("-l #{mongrel_log_file}" if mongrel_log_file),
35
34
  ("--user #{mongrel_user}" if mongrel_user),
36
35
  ("--group #{mongrel_group}" if mongrel_group),
37
36
  ("--prefix #{mongrel_prefix}" if mongrel_prefix),
38
37
  ("-S #{mongrel_config_script}" if mongrel_config_script),
39
- ].compact.join ' '
38
+ ]
40
39
 
41
- run cmd
40
+ run mongrel(*cmd)
42
41
  end
43
42
 
44
- def mongrel(cmd) # :nodoc:
45
- cmd = "#{mongrel_command} #{cmd} -C #{mongrel_conf}"
46
- cmd << ' --clean' if mongrel_clean
47
- cmd
43
+ def mongrel(cmd, *opts) # :nodoc:
44
+ cmd = ["#{mongrel_command} #{cmd} -C #{mongrel_conf}"]
45
+ cmd << ' --clean' if mongrel_clean unless cmd == 'cluster::configure'
46
+ cmd.push(*opts)
47
+
48
+ cmd.compact.join ' '
48
49
  end
49
50
 
50
51
  desc "Restart the app servers"
@@ -0,0 +1,48 @@
1
+ require 'vlad'
2
+
3
+ namespace :vlad do
4
+ ##
5
+ # Nginx web server on Gentoo/Debian init.d systems FIX
6
+
7
+ set :web_command, "/etc/init.d/nginx"
8
+
9
+ remote_task :setup_app, :roles => :web do
10
+ config_file = "/etc/nginx/vhosts/#{application}_#{environment}.conf"
11
+ raise "not yet... must review this code"
12
+ run [ "sudo test -e #{config_file} || ",
13
+ "sudo sh -c \"ruby ",
14
+ " /etc/sliceconfig/install/interactive/nginx_config.rb ",
15
+ "'#{app_domain}' '#{application}' '#{environment}' ",
16
+ "'#{app_port}' '#{app_servers}' #{only_www ? 1 : 0} ",
17
+ "> #{config_file}\""
18
+ ].join(" ")
19
+ end
20
+
21
+ desc "(Re)Start the web servers"
22
+
23
+ remote_task :start_web, :roles => :web do
24
+ run "#{web_command} restart"
25
+ # TODO: run %Q(sudo #{web_command} configtest && sudo #{web_command} reload)
26
+ end
27
+
28
+ desc "Stop the web servers"
29
+
30
+ remote_task :stop_web, :roles => :web do
31
+ run "#{web_command} stop"
32
+ end
33
+
34
+ ##
35
+ # Everything HTTP.
36
+
37
+ desc "(Re)Start the web and app servers"
38
+
39
+ remote_task :start do
40
+ Rake::Task['vlad:start_app'].invoke
41
+ Rake::Task['vlad:start_web'].invoke
42
+ end
43
+
44
+ remote_task :stop do
45
+ Rake::Task['vlad:stop_app'].invoke
46
+ Rake::Task['vlad:stop_web'].invoke
47
+ end
48
+ end
@@ -0,0 +1,8 @@
1
+ require 'vlad'
2
+
3
+ namespace :vlad do
4
+ desc 'Restart Passenger'
5
+ remote_task :start_app, :roles => :app do
6
+ run "touch #{release_path}/tmp/restart.txt"
7
+ end
8
+ end
@@ -0,0 +1,63 @@
1
+ # $GEM_HOME/gems/vlad-1.2.0/lib/vlad/thin.rb
2
+ # Thin tasks for Vlad the Deployer
3
+ # By cnantais
4
+ require 'vlad'
5
+
6
+ namespace :vlad do
7
+ ##
8
+ # Thin app server
9
+
10
+ set :thin_address, "127.0.0.1"
11
+ set :thin_command, 'thin'
12
+ set(:thin_conf) { "#{shared_path}/thin_cluster.conf" }
13
+ set :thin_environment, "production"
14
+ set :thin_group, nil
15
+ set :thin_log_file, nil
16
+ set :thin_pid_file, nil
17
+ set :thin_port, nil
18
+ set :thin_socket, "/tmp/thin.sock"
19
+ set :thin_prefix, nil
20
+ set :thin_servers, 2
21
+ set :thin_user, nil
22
+ set :thin_rackup, nil
23
+
24
+ desc "Prepares application servers for deployment. thin
25
+ configuration is set via the thin_* variables.".cleanup
26
+
27
+ remote_task :setup_app, :roles => :app do
28
+ cmd = [
29
+ "#{thin_command} config",
30
+ "-s #{thin_servers}",
31
+ "-S #{thin_socket}",
32
+ "-e #{thin_environment}",
33
+ "-c #{current_path}",
34
+ "-C #{thin_conf}",
35
+ ("-a #{thin_address}" if thin_address),
36
+ ("-R #{thin_rackup}" if thin_rackup),
37
+ ("-P #{thin_pid_file}" if thin_pid_file),
38
+ ("-l #{thin_log_file}" if thin_log_file),
39
+ ("--user #{thin_user}" if thin_user),
40
+ ("--group #{thin_group}" if thin_group),
41
+ ("--prefix #{thin_prefix}" if thin_prefix),
42
+ ("-p #{thin_port}" if thin_port),
43
+ ].compact.join ' '
44
+
45
+ run cmd
46
+ end
47
+
48
+ def thin(cmd) # :nodoc:
49
+ "#{thin_command} #{cmd} -C #{thin_conf}"
50
+ end
51
+
52
+ desc "Restart the app servers"
53
+
54
+ remote_task :start_app, :roles => :app do
55
+ run thin("restart -s #{thin_servers}")
56
+ end
57
+
58
+ desc "Stop the app servers"
59
+
60
+ remote_task :stop_app, :roles => :app do
61
+ run thin("stop -s #{thin_servers}")
62
+ end
63
+ end
@@ -26,7 +26,6 @@ class TestRakeRemoteTask < VladTestCase
26
26
  task = @vlad.remote_task(:some_task) { x += some_variable }
27
27
  task.execute nil
28
28
  assert_equal 1, task.some_variable
29
- assert_equal 2, task.remote_actions.first.workers.size
30
29
  assert_equal 7, x
31
30
  end
32
31
 
@@ -41,13 +40,15 @@ class TestRakeRemoteTask < VladTestCase
41
40
  @vlad.host "app.example.com", :app
42
41
  t = @vlad.remote_task(:flunk, :roles => :db) { flunk "should not have run" }
43
42
  e = assert_raise(Vlad::ConfigurationError) { t.execute nil }
44
- assert_equal "No target hosts specified for task: flunk", e.message
43
+ assert_equal "No target hosts specified on task flunk for roles [:db]",
44
+ e.message
45
45
  end
46
46
 
47
47
  def test_execute_with_no_roles
48
48
  t = @vlad.remote_task(:flunk, :roles => :junk) { flunk "should not have run" }
49
49
  e = assert_raise(Vlad::ConfigurationError) { t.execute nil }
50
- assert_equal "No target hosts specified for task: flunk", e.message
50
+ assert_equal "No target hosts specified on task flunk for roles [:junk]",
51
+ e.message
51
52
  end
52
53
 
53
54
  def test_execute_with_roles
@@ -26,7 +26,6 @@ class TestVlad < VladTestCase
26
26
  end
27
27
 
28
28
  def test_host_invalid
29
- assert_raise(ArgumentError) { @vlad.host "", :app, :db }
30
29
  assert_raise(ArgumentError) { @vlad.host nil, :web }
31
30
  end
32
31
 
@@ -102,7 +101,7 @@ class TestVlad < VladTestCase
102
101
  def test_remote_task
103
102
  t = @vlad.remote_task(:test_task) { 5 }
104
103
  assert_equal @task_count + 1, Rake.application.tasks.size
105
- assert_equal Hash.new, t.options
104
+ assert_equal({ :roles => [] }, t.options)
106
105
  end
107
106
 
108
107
  def test_remote_task_all_hosts_by_default
@@ -26,7 +26,7 @@ class TestVladGit < VladTestCase
26
26
 
27
27
  def test_export
28
28
  cmd = @scm.export 'master', 'the/release/path'
29
- assert_equal 'mkdir -p the/release/path && git archive master | (cd the/release/path && tar xf -)', cmd
29
+ assert_equal 'mkdir -p the/release/path && git archive --format=tar master | (cd the/release/path && tar xf -)', cmd
30
30
  end
31
31
 
32
32
  def test_revision
@@ -10,7 +10,11 @@ class TestVladMercurial < Test::Unit::TestCase
10
10
 
11
11
  def test_checkout
12
12
  cmd = @scm.checkout 'head', '/the/place'
13
- assert_equal 'hg pull -r tip -R /the/place http://repo/project', cmd
13
+
14
+ expected = "if [ ! -d /the/place/.hg ]; then hg init -R /the/place; fi " \
15
+ "&& hg pull -r tip -R /the/place http://repo/project"
16
+
17
+ assert_equal expected, cmd
14
18
  end
15
19
 
16
20
  def test_export
@@ -24,3 +28,4 @@ class TestVladMercurial < Test::Unit::TestCase
24
28
  assert_equal expected, cmd
25
29
  end
26
30
  end
31
+
@@ -12,8 +12,12 @@ module Process
12
12
  @@expected << status
13
13
  end
14
14
 
15
- def self.waitpid2(pid)
16
- [ @@expected.shift ]
15
+ class << self
16
+ alias :waitpid2_old :waitpid2
17
+
18
+ def waitpid2(pid)
19
+ [ @@expected.shift ]
20
+ end
17
21
  end
18
22
  end
19
23
 
@@ -1,5 +1,7 @@
1
1
  #!/bin/bash
2
2
 
3
+ N=$1; shift
4
+
3
5
  killall mongrel svnserve 2> /dev/null
4
6
 
5
7
  rm -rf ~/demo
@@ -23,6 +25,16 @@ echo "anon-access = write" >> svnrepo/conf/svnserve.conf
23
25
 
24
26
  svnserve -d --foreground -r svnrepo --listen-host localhost &
25
27
 
28
+ echo "cd ~/demo
29
+ rm -rf website_*
30
+ svnserve -d --foreground -r svnrepo --listen-host localhost &
31
+
32
+ cd mydemoapp
33
+ ruby -I ~/Work/p4/zss/src/vlad/dev/lib -S rake -t vlad:setup vlad:update
34
+
35
+ kill %1" > go.sh
36
+ chmod u+x go.sh
37
+
26
38
  rails mydemoapp
27
39
 
28
40
  cd mydemoapp
@@ -33,23 +45,44 @@ Vlad.load" >> Rakefile
33
45
 
34
46
  echo "set :repository, 'svn://localhost/blah'
35
47
  set :domain, 'localhost'
36
- set :deploy_to, '/Users/ryan/demo/website'
37
48
  set :web_command, 'sudo apachectl'" > config/deploy.rb
38
49
 
50
+ # TODO: add a knob
51
+ if [ -n "$N" ]; then
52
+ echo "set(:deploy_to, :per_thread) {
53
+ File.expand_path(\"~/demo/website_#{target_host}\")
54
+ }
55
+
56
+ %w(current_path current_release latest_release
57
+ previous_release releases_path release_path
58
+ scm_path shared_path).each do |name|
59
+ Rake::RemoteTask.per_thread[name] = true
60
+ end
61
+
62
+ (1..$N).each do |n|
63
+ host 'localhost%02d' % n, :web, :app
64
+ end" >> config/deploy.rb
65
+ else
66
+ echo "set :deploy_to, File.expand_path('~/demo/website')" >> config/deploy.rb
67
+ fi
68
+
39
69
  svn import -m Added . svn://localhost/blah
40
70
 
71
+ echo
72
+ echo "Here is your config:"
73
+ cat config/deploy.rb
41
74
  echo
42
75
  echo "Here are the tasks available:"
43
76
  echo
44
77
 
45
- rake -T vlad
78
+ ruby -I ~/Work/p4/zss/src/vlad/dev/lib -S rake -T vlad
46
79
 
47
80
  echo
48
81
  echo "The next step deploys and fires up the application"
49
82
  echo
50
83
  pause
51
84
 
52
- rake -t vlad:setup vlad:update vlad:start
85
+ ruby -I ~/Work/p4/zss/src/vlad/dev/lib -S rake -t vlad:setup vlad:update vlad:start
53
86
 
54
87
  open http://localhost:8000/
55
88
 
@@ -58,7 +91,7 @@ echo "done! check it out"
58
91
  echo
59
92
  pause
60
93
 
61
- rake vlad:stop
94
+ ruby -I ~/Work/p4/zss/src/vlad/dev/lib -S rake vlad:stop
62
95
 
63
96
  kill %1
64
97
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vlad
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Davis
@@ -11,20 +11,22 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2008-01-14 00:00:00 -08:00
14
+ date: 2009-03-04 00:00:00 -08:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rake
19
+ type: :runtime
19
20
  version_requirement:
20
21
  version_requirements: !ruby/object:Gem::Requirement
21
22
  requirements:
22
23
  - - ">="
23
24
  - !ruby/object:Gem::Version
24
- version: "0"
25
+ version: 0.8.1
25
26
  version:
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: open4
29
+ type: :runtime
28
30
  version_requirement:
29
31
  version_requirements: !ruby/object:Gem::Requirement
30
32
  requirements:
@@ -34,15 +36,19 @@ dependencies:
34
36
  version:
35
37
  - !ruby/object:Gem::Dependency
36
38
  name: hoe
39
+ type: :development
37
40
  version_requirement:
38
41
  version_requirements: !ruby/object:Gem::Requirement
39
42
  requirements:
40
43
  - - ">="
41
44
  - !ruby/object:Gem::Version
42
- version: 1.4.0
45
+ version: 1.9.0
43
46
  version:
44
- description: "Vlad the Deployer is pragmatic application deployment automation, without mercy. Much like Capistrano, but with 1/10th the complexity. Vlad integrates seamlessly with Rake, and uses familiar and standard tools like ssh and rsync. Impale your application on the heartless spike of the Deployer. == FEATURES/PROBLEMS: * Full deployment automation stack. * Turnkey deployment for mongrel+apache+svn. * Supports single server deployment with just 3 variables defined. * Built on rake. Easy. Engine is small. * Very few dependencies. All simple. * Uses ssh with your ssh settings already in place. * Uses rsync for efficient transfers. * Run remote commands on one or more servers. * Mix and match local and remote tasks. * Compatible with all of your tab completion shell script rake-tastic goodness. * Ships with tests that actually pass in 0.028 seconds! * Does NOT support Windows right now (we think). Coming soon in 1.2."
45
- email: ryand-ruby@zenspider.com
47
+ description: Vlad the Deployer is pragmatic application deployment automation, without mercy. Much like Capistrano, but with 1/10th the complexity. Vlad integrates seamlessly with Rake, and uses familiar and standard tools like ssh and rsync. Impale your application on the heartless spike of the Deployer.
48
+ email:
49
+ - ryand-ruby@zenspider.com
50
+ - drbrain@segment7.net
51
+ - wilson@supremetyrant.com
46
52
  executables: []
47
53
 
48
54
  extensions: []
@@ -72,12 +78,19 @@ files:
72
78
  - lib/vlad.rb
73
79
  - lib/vlad/apache.rb
74
80
  - lib/vlad/core.rb
81
+ - lib/vlad/darcs.rb
75
82
  - lib/vlad/git.rb
83
+ - lib/vlad/god.rb
76
84
  - lib/vlad/lighttpd.rb
85
+ - lib/vlad/maintenance.rb
86
+ - lib/vlad/merb.rb
77
87
  - lib/vlad/mercurial.rb
78
88
  - lib/vlad/mongrel.rb
89
+ - lib/vlad/nginx.rb
90
+ - lib/vlad/passenger.rb
79
91
  - lib/vlad/perforce.rb
80
92
  - lib/vlad/subversion.rb
93
+ - lib/vlad/thin.rb
81
94
  - test/test_rake_remote_task.rb
82
95
  - test/test_vlad.rb
83
96
  - test/test_vlad_git.rb
@@ -109,10 +122,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
122
  requirements: []
110
123
 
111
124
  rubyforge_project: hitsquad
112
- rubygems_version: 1.0.1
125
+ rubygems_version: 1.3.1
113
126
  signing_key:
114
127
  specification_version: 2
115
- summary: Vlad the Deployer is pragmatic application deployment automation, without mercy. Much like Capistrano, but with 1/10th the complexity. Vlad integrates seamlessly with Rake, and uses familiar and standard tools like ssh and rsync.
128
+ summary: Vlad the Deployer is pragmatic application deployment automation, without mercy
116
129
  test_files:
117
130
  - test/test_rake_remote_task.rb
118
131
  - test/test_vlad.rb