vlad 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +65 -4
- data/Manifest.txt +7 -0
- data/README.txt +13 -13
- data/Rakefile +11 -10
- data/doco/faq.txt +7 -1
- data/doco/variables.txt +3 -2
- data/lib/rake_remote_task.rb +130 -56
- data/lib/vlad.rb +6 -2
- data/lib/vlad/core.rb +13 -7
- data/lib/vlad/darcs.rb +24 -0
- data/lib/vlad/git.rb +1 -1
- data/lib/vlad/god.rb +23 -0
- data/lib/vlad/maintenance.rb +13 -0
- data/lib/vlad/merb.rb +51 -0
- data/lib/vlad/mercurial.rb +4 -1
- data/lib/vlad/mongrel.rb +9 -8
- data/lib/vlad/nginx.rb +48 -0
- data/lib/vlad/passenger.rb +8 -0
- data/lib/vlad/thin.rb +63 -0
- data/test/test_rake_remote_task.rb +4 -3
- data/test/test_vlad.rb +1 -2
- data/test/test_vlad_git.rb +1 -1
- data/test/test_vlad_mercurial.rb +6 -1
- data/test/vlad_test_case.rb +6 -2
- data/vladdemo.sh +37 -4
- metadata +21 -8
data/History.txt
CHANGED
@@ -1,31 +1,89 @@
|
|
1
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
106
|
+
=== 1.0.0 / 2007-08-04
|
47
107
|
|
48
108
|
* 1 major enhancement
|
109
|
+
|
49
110
|
* Birthday!
|
data/Manifest.txt
CHANGED
@@ -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
|
-
|
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
|
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 |
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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"
|
data/doco/faq.txt
CHANGED
@@ -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"
|
data/doco/variables.txt
CHANGED
@@ -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
|
-
|
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
|
|
data/lib/rake_remote_task.rb
CHANGED
@@ -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,
|
60
|
-
Rake::RemoteTask.remote_task name,
|
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
|
-
|
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
|
164
|
-
|
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, "#{
|
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].
|
212
|
+
cmd = [ssh_cmd, ssh_flags, target_host, command].flatten
|
190
213
|
result = []
|
191
214
|
|
192
|
-
|
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,
|
334
|
-
|
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
|
-
@@
|
352
|
-
@@env
|
353
|
-
@@tasks
|
354
|
-
@@
|
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
|
-
|
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
|
-
|
397
|
-
|
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,
|
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
|
-
|
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
|
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.
|
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
|
633
|
+
@workers.add thread
|
560
634
|
end
|
561
|
-
@workers.each { |
|
635
|
+
@workers.list.each { |thr| thr.join }
|
562
636
|
end
|
563
637
|
end
|
564
638
|
end
|
data/lib/vlad.rb
CHANGED
@@ -20,7 +20,7 @@ module Vlad
|
|
20
20
|
|
21
21
|
##
|
22
22
|
# This is the version of Vlad you are running.
|
23
|
-
VERSION = '1.
|
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
|
-
|
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
|
|
data/lib/vlad/core.rb
CHANGED
@@ -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
|
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
|
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
|
data/lib/vlad/darcs.rb
ADDED
@@ -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
|
data/lib/vlad/git.rb
CHANGED
@@ -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
|
|
data/lib/vlad/god.rb
ADDED
@@ -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
|
data/lib/vlad/merb.rb
ADDED
@@ -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
|
data/lib/vlad/mercurial.rb
CHANGED
@@ -8,7 +8,10 @@ class Vlad::Mercurial
|
|
8
8
|
|
9
9
|
def checkout(revision, destination)
|
10
10
|
revision = 'tip' if revision =~ /^head$/i
|
11
|
-
|
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
|
##
|
data/lib/vlad/mongrel.rb
CHANGED
@@ -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
|
-
|
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
|
-
]
|
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"
|
data/lib/vlad/nginx.rb
ADDED
@@ -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
|
data/lib/vlad/thin.rb
ADDED
@@ -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
|
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
|
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
|
data/test/test_vlad.rb
CHANGED
@@ -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
|
104
|
+
assert_equal({ :roles => [] }, t.options)
|
106
105
|
end
|
107
106
|
|
108
107
|
def test_remote_task_all_hosts_by_default
|
data/test/test_vlad_git.rb
CHANGED
@@ -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
|
data/test/test_vlad_mercurial.rb
CHANGED
@@ -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
|
-
|
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
|
+
|
data/test/vlad_test_case.rb
CHANGED
data/vladdemo.sh
CHANGED
@@ -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.
|
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:
|
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:
|
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.
|
45
|
+
version: 1.9.0
|
43
46
|
version:
|
44
|
-
description:
|
45
|
-
email:
|
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.
|
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
|
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
|