rick-vlad 1.2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +49 -0
- data/Manifest.txt +35 -0
- data/README.txt +78 -0
- data/Rakefile +51 -0
- data/considerations.txt +91 -0
- data/doco/faq.txt +75 -0
- data/doco/getting_started.txt +41 -0
- data/doco/migration.txt +43 -0
- data/doco/perforce.txt +5 -0
- data/doco/variables.txt +77 -0
- data/lib/rake_remote_task.rb +573 -0
- data/lib/vlad/apache.rb +37 -0
- data/lib/vlad/core.rb +178 -0
- data/lib/vlad/git.rb +43 -0
- data/lib/vlad/lighttpd.rb +85 -0
- data/lib/vlad/maintenance.rb +23 -0
- data/lib/vlad/merb.god.rb +21 -0
- data/lib/vlad/mercurial.rb +34 -0
- data/lib/vlad/mongrel.rb +61 -0
- data/lib/vlad/nginx.rb +44 -0
- data/lib/vlad/perforce.rb +117 -0
- data/lib/vlad/subversion.rb +34 -0
- data/lib/vlad/thin.rb +71 -0
- data/lib/vlad/web.rb +12 -0
- data/lib/vlad.rb +90 -0
- data/test/test_rake_remote_task.rb +186 -0
- data/test/test_vlad.rb +211 -0
- data/test/test_vlad_git.rb +39 -0
- data/test/test_vlad_mercurial.rb +26 -0
- data/test/test_vlad_perforce.rb +37 -0
- data/test/test_vlad_subversion.rb +27 -0
- data/test/vlad_test_case.rb +71 -0
- data/vladdemo.sh +64 -0
- metadata +127 -0
@@ -0,0 +1,573 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'open4'
|
3
|
+
require 'rake'
|
4
|
+
require 'vlad'
|
5
|
+
|
6
|
+
$TESTING ||= false
|
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
|
33
|
+
|
34
|
+
##
|
35
|
+
# Declare a remote host and its roles. Equivalent to <tt>role</tt>,
|
36
|
+
# but shorter for multiple roles.
|
37
|
+
def host host_name, *roles
|
38
|
+
Rake::RemoteTask.host host_name, *roles
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Copy a (usually generated) file to +remote_path+. Contents of block
|
43
|
+
# are copied to +remote_path+ and you may specify an optional
|
44
|
+
# base_name for the tempfile (aids in debugging).
|
45
|
+
|
46
|
+
def put remote_path, base_name = 'vlad.unknown'
|
47
|
+
Tempfile.open base_name do |fp|
|
48
|
+
fp.puts yield
|
49
|
+
fp.flush
|
50
|
+
rsync fp.path, remote_path
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Declare a Vlad task that will execute on all hosts by default. To
|
56
|
+
# limit that task to specific roles, use:
|
57
|
+
#
|
58
|
+
# remote_task :example, :roles => [:app, :web] do
|
59
|
+
def remote_task name, options = {}, &b
|
60
|
+
Rake::RemoteTask.remote_task name, options, &b
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Declare a role and assign a remote host to it. Equivalent to the
|
65
|
+
# <tt>host</tt> method; provided for capistrano compatibility.
|
66
|
+
def role role_name, host, args = {}
|
67
|
+
Rake::RemoteTask.role role_name, host, args
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Execute the given command on the <tt>target_host</tt> for the
|
72
|
+
# current task.
|
73
|
+
def run *args, &b
|
74
|
+
Thread.current[:task].run(*args, &b)
|
75
|
+
end
|
76
|
+
|
77
|
+
# rsync the given files to <tt>target_host</tt>.
|
78
|
+
def rsync local, remote
|
79
|
+
Thread.current[:task].rsync local, remote
|
80
|
+
end
|
81
|
+
|
82
|
+
# Declare a variable called +name+ and assign it a value. A
|
83
|
+
# globally-visible method with the name of the variable is defined.
|
84
|
+
# If a block is given, it will be called when the variable is first
|
85
|
+
# accessed. Subsequent references to the variable will always return
|
86
|
+
# the same value. Raises <tt>ArgumentError</tt> if the +name+ would
|
87
|
+
# conflict with an existing method.
|
88
|
+
def set name, val = nil, &b
|
89
|
+
Rake::RemoteTask.set name, val, &b
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the name of the host that the current task is executing on.
|
93
|
+
# <tt>target_host</tt> can uniquely identify a particular task/host
|
94
|
+
# combination.
|
95
|
+
def target_host
|
96
|
+
Thread.current[:task].target_host
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Execute the given command with sudo on the <tt>target_host</tt>
|
101
|
+
# for the current task.
|
102
|
+
def sudo *args, &b
|
103
|
+
Thread.current[:task].sudo(*args, &b)
|
104
|
+
end
|
105
|
+
|
106
|
+
if Gem::Version.new(RAKEVERSION) < Gem::Version.new('0.8') then
|
107
|
+
class Rake::Task
|
108
|
+
alias vlad_original_execute execute
|
109
|
+
|
110
|
+
def execute(args = nil)
|
111
|
+
vlad_original_execute
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Rake::RemoteTask is a subclass of Rake::Task that adds
|
118
|
+
# remote_actions that execute in parallel on multiple hosts via ssh.
|
119
|
+
|
120
|
+
class Rake::RemoteTask < Rake::Task
|
121
|
+
|
122
|
+
include Open4
|
123
|
+
|
124
|
+
##
|
125
|
+
# Options for execution of this task.
|
126
|
+
|
127
|
+
attr_accessor :options
|
128
|
+
|
129
|
+
##
|
130
|
+
# The host this task is running on during execution.
|
131
|
+
|
132
|
+
attr_accessor :target_host
|
133
|
+
|
134
|
+
##
|
135
|
+
# An Array of Actions this host will perform during execution. Use
|
136
|
+
# enhance to add new actions to a task.
|
137
|
+
|
138
|
+
attr_reader :remote_actions
|
139
|
+
|
140
|
+
##
|
141
|
+
# Create a new task named +task_name+ attached to Rake::Application +app+.
|
142
|
+
|
143
|
+
def initialize(task_name, app)
|
144
|
+
super
|
145
|
+
@remote_actions = []
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Add a local action to this task. This calls Rake::Task#enhance.
|
150
|
+
|
151
|
+
alias_method :original_enhance, :enhance
|
152
|
+
|
153
|
+
##
|
154
|
+
# Add remote action +block+ to this task with dependencies +deps+. See
|
155
|
+
# Rake::Task#enhance.
|
156
|
+
|
157
|
+
def enhance(deps=nil, &block)
|
158
|
+
original_enhance(deps) # can't use super because block passed regardless.
|
159
|
+
@remote_actions << Action.new(self, block) if block_given?
|
160
|
+
self
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# Execute this action. Local actions will be performed first, then remote
|
165
|
+
# actions will be performed in parallel on each host configured for this
|
166
|
+
# RemoteTask.
|
167
|
+
|
168
|
+
def execute(args = nil)
|
169
|
+
raise(Vlad::ConfigurationError,
|
170
|
+
"No target hosts specified for task: #{self.name}") if
|
171
|
+
target_hosts.empty?
|
172
|
+
|
173
|
+
super args
|
174
|
+
|
175
|
+
@remote_actions.each { |act| act.execute(target_hosts, args) }
|
176
|
+
end
|
177
|
+
|
178
|
+
##
|
179
|
+
# Use rsync to send +local+ to +remote+ on target_host.
|
180
|
+
|
181
|
+
def rsync local, remote
|
182
|
+
cmd = [rsync_cmd, rsync_flags, local, "#{@target_host}:#{remote}"].flatten.compact
|
183
|
+
|
184
|
+
success = system(*cmd)
|
185
|
+
|
186
|
+
unless success then
|
187
|
+
raise Vlad::CommandFailedError, "execution failed: #{cmd.join ' '}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
##
|
192
|
+
# Use ssh to execute +command+ on target_host. If +command+ uses sudo, the
|
193
|
+
# sudo password will be prompted for then saved for subsequent sudo commands.
|
194
|
+
|
195
|
+
def run command
|
196
|
+
cmd = [ssh_cmd, ssh_flags, target_host, command].compact
|
197
|
+
result = []
|
198
|
+
|
199
|
+
warn cmd.join(' ') if $TRACE
|
200
|
+
|
201
|
+
pid, inn, out, err = popen4(*cmd)
|
202
|
+
|
203
|
+
inn.sync = true
|
204
|
+
streams = [out, err]
|
205
|
+
out_stream = {
|
206
|
+
out => $stdout,
|
207
|
+
err => $stderr,
|
208
|
+
}
|
209
|
+
|
210
|
+
# Handle process termination ourselves
|
211
|
+
status = nil
|
212
|
+
Thread.start do
|
213
|
+
status = Process.waitpid2(pid).last
|
214
|
+
end
|
215
|
+
|
216
|
+
until streams.empty? do
|
217
|
+
# don't busy loop
|
218
|
+
selected, = select streams, nil, nil, 0.1
|
219
|
+
|
220
|
+
next if selected.nil? or selected.empty?
|
221
|
+
|
222
|
+
selected.each do |stream|
|
223
|
+
if stream.eof? then
|
224
|
+
streams.delete stream if status # we've quit, so no more writing
|
225
|
+
next
|
226
|
+
end
|
227
|
+
|
228
|
+
data = stream.readpartial(1024)
|
229
|
+
out_stream[stream].write data
|
230
|
+
|
231
|
+
if stream == err and data =~ /^Password:/ then
|
232
|
+
inn.puts sudo_password
|
233
|
+
data << "\n"
|
234
|
+
$stderr.write "\n"
|
235
|
+
end
|
236
|
+
|
237
|
+
result << data
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
unless status.success? then
|
242
|
+
raise(Vlad::CommandFailedError,
|
243
|
+
"execution failed with status #{status.exitstatus}: #{cmd.join ' '}")
|
244
|
+
end
|
245
|
+
|
246
|
+
result.join
|
247
|
+
end
|
248
|
+
|
249
|
+
##
|
250
|
+
# Returns an Array with every host configured.
|
251
|
+
|
252
|
+
def self.all_hosts
|
253
|
+
hosts_for(roles.keys)
|
254
|
+
end
|
255
|
+
|
256
|
+
##
|
257
|
+
# The default environment values. Used for resetting (mostly for
|
258
|
+
# tests).
|
259
|
+
|
260
|
+
def self.default_env
|
261
|
+
@@default_env
|
262
|
+
end
|
263
|
+
|
264
|
+
##
|
265
|
+
# The vlad environment.
|
266
|
+
|
267
|
+
def self.env
|
268
|
+
@@env
|
269
|
+
end
|
270
|
+
|
271
|
+
##
|
272
|
+
# Fetches environment variable +name+ from the environment using
|
273
|
+
# default +default+.
|
274
|
+
|
275
|
+
def self.fetch name, default = nil
|
276
|
+
name = name.to_s if Symbol === name
|
277
|
+
if @@env.has_key? name then
|
278
|
+
protect_env(name) do
|
279
|
+
v = @@env[name]
|
280
|
+
v = @@env[name] = v.call if Proc === v
|
281
|
+
v
|
282
|
+
end
|
283
|
+
elsif default
|
284
|
+
v = @@env[name] = default
|
285
|
+
else
|
286
|
+
raise Vlad::FetchError
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
##
|
291
|
+
# Add host +host_name+ that belongs to +roles+. Extra arguments may
|
292
|
+
# be specified for the host as a hash as the last argument.
|
293
|
+
#
|
294
|
+
# host is the inversion of role:
|
295
|
+
#
|
296
|
+
# host 'db1.example.com', :db, :master_db
|
297
|
+
#
|
298
|
+
# Is equivalent to:
|
299
|
+
#
|
300
|
+
# role :db, 'db1.example.com'
|
301
|
+
# role :master_db, 'db1.example.com'
|
302
|
+
|
303
|
+
def self.host host_name, *roles
|
304
|
+
opts = Hash === roles.last ? roles.pop : {}
|
305
|
+
|
306
|
+
roles.each do |role_name|
|
307
|
+
role role_name, host_name, opts.dup
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
##
|
312
|
+
# Returns an Array of all hosts in +roles+.
|
313
|
+
|
314
|
+
def self.hosts_for *roles
|
315
|
+
roles.flatten.map { |r|
|
316
|
+
self.roles[r].keys
|
317
|
+
}.flatten.uniq.sort
|
318
|
+
end
|
319
|
+
|
320
|
+
def self.mandatory name, desc # :nodoc:
|
321
|
+
self.set(name) do
|
322
|
+
raise(Vlad::ConfigurationError,
|
323
|
+
"Please specify the #{desc} via the #{name.inspect} variable")
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
##
|
328
|
+
# Ensures exclusive access to +name+.
|
329
|
+
|
330
|
+
def self.protect_env name # :nodoc:
|
331
|
+
@@env_locks[name].synchronize do
|
332
|
+
yield
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
##
|
337
|
+
# Adds a remote task named +name+ with options +options+ that will
|
338
|
+
# execute +block+.
|
339
|
+
|
340
|
+
def self.remote_task name, options = {}, &block
|
341
|
+
t = Rake::RemoteTask.define_task(name, &block)
|
342
|
+
t.options = options
|
343
|
+
t
|
344
|
+
end
|
345
|
+
|
346
|
+
##
|
347
|
+
# Ensures +name+ does not conflict with an existing method.
|
348
|
+
|
349
|
+
def self.reserved_name? name # :nodoc:
|
350
|
+
!@@env.has_key?(name.to_s) && self.respond_to?(name)
|
351
|
+
end
|
352
|
+
|
353
|
+
##
|
354
|
+
# Resets vlad, restoring all roles, tasks and environment variables
|
355
|
+
# to the defaults.
|
356
|
+
|
357
|
+
def self.reset
|
358
|
+
@@roles = Hash.new { |h,k| h[k] = {} }
|
359
|
+
@@env = {}
|
360
|
+
@@tasks = {}
|
361
|
+
@@env_locks = Hash.new { |h,k| h[k] = Mutex.new }
|
362
|
+
|
363
|
+
@@default_env.each do |k,v|
|
364
|
+
case v
|
365
|
+
when Symbol, Fixnum, nil, true, false, 42 then # ummmm... yeah. bite me.
|
366
|
+
@@env[k] = v
|
367
|
+
else
|
368
|
+
@@env[k] = v.dup
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
##
|
374
|
+
# Adds role +role_name+ with +host+ and +args+ for that host.
|
375
|
+
|
376
|
+
def self.role role_name, host, args = {}
|
377
|
+
raise ArgumentError, "invalid host" if host.nil? or host.empty?
|
378
|
+
@@roles[role_name][host] = args
|
379
|
+
end
|
380
|
+
|
381
|
+
##
|
382
|
+
# The configured roles.
|
383
|
+
|
384
|
+
def self.roles
|
385
|
+
host domain, :app, :web, :db if @@roles.empty?
|
386
|
+
|
387
|
+
@@roles
|
388
|
+
end
|
389
|
+
|
390
|
+
##
|
391
|
+
# Set environment variable +name+ to +value+ or +default_block+.
|
392
|
+
#
|
393
|
+
# If +default_block+ is defined, the block will be executed the
|
394
|
+
# first time the variable is fetched, and the value will be used for
|
395
|
+
# every subsequent fetch.
|
396
|
+
|
397
|
+
def self.set name, value = nil, &default_block
|
398
|
+
raise ArgumentError, "cannot provide both a value and a block" if
|
399
|
+
value and default_block
|
400
|
+
raise ArgumentError, "cannot set reserved name: '#{name}'" if
|
401
|
+
Rake::RemoteTask.reserved_name?(name) unless $TESTING
|
402
|
+
|
403
|
+
Rake::RemoteTask.default_env[name.to_s] = Rake::RemoteTask.env[name.to_s] =
|
404
|
+
value || default_block
|
405
|
+
|
406
|
+
Object.send :define_method, name do
|
407
|
+
Rake::RemoteTask.fetch name
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
##
|
412
|
+
# Sets all the default values. Should only be called once. Use reset
|
413
|
+
# if you need to restore values.
|
414
|
+
|
415
|
+
def self.set_defaults
|
416
|
+
@@default_env ||= {}
|
417
|
+
self.reset
|
418
|
+
|
419
|
+
mandatory :code_repo, "code repo path"
|
420
|
+
mandatory :deploy_to, "deploy path"
|
421
|
+
mandatory :domain, "server domain"
|
422
|
+
|
423
|
+
simple_set(:deploy_timestamped, true,
|
424
|
+
:deploy_via, :export,
|
425
|
+
:keep_releases, 5,
|
426
|
+
:migrate_args, "",
|
427
|
+
:migrate_target, :latest,
|
428
|
+
:rails_env, "production",
|
429
|
+
:rake_cmd, "rake",
|
430
|
+
:revision, "head",
|
431
|
+
:rsync_cmd, "rsync",
|
432
|
+
:rsync_flags, ['-azP', '--delete'],
|
433
|
+
:ssh_cmd, "ssh",
|
434
|
+
:ssh_flags, nil,
|
435
|
+
:sudo_cmd, "sudo",
|
436
|
+
:sudo_flags, nil)
|
437
|
+
|
438
|
+
set(:current_release) { File.join(releases_path, releases[-1]) }
|
439
|
+
set(:latest_release) { deploy_timestamped ?release_path: current_release }
|
440
|
+
set(:previous_release) { File.join(releases_path, releases[-2]) }
|
441
|
+
set(:release_name) { Time.now.utc.strftime("%Y%m%d%H%M%S") }
|
442
|
+
set(:release_path) { File.join(releases_path, release_name) }
|
443
|
+
set(:releases) { task.run("ls -x #{releases_path}").split.sort }
|
444
|
+
|
445
|
+
set_path :current_path, "current"
|
446
|
+
set_path :releases_path, "releases"
|
447
|
+
set_path :scm_path, "scm"
|
448
|
+
set_path :shared_path, "shared"
|
449
|
+
|
450
|
+
set(:sudo_password) do
|
451
|
+
state = `stty -g`
|
452
|
+
|
453
|
+
raise Vlad::Error, "stty(1) not found" unless $?.success?
|
454
|
+
|
455
|
+
begin
|
456
|
+
system "stty -echo"
|
457
|
+
$stdout.print "sudo password: "
|
458
|
+
$stdout.flush
|
459
|
+
sudo_password = $stdin.gets
|
460
|
+
$stdout.puts
|
461
|
+
ensure
|
462
|
+
system "stty #{state}"
|
463
|
+
end
|
464
|
+
sudo_password
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
def self.set_path(name, subdir) # :nodoc:
|
469
|
+
set(name) { File.join(deploy_to, subdir) }
|
470
|
+
end
|
471
|
+
|
472
|
+
def self.simple_set(*args) # :nodoc:
|
473
|
+
args = Hash[*args]
|
474
|
+
args.each do |k, v|
|
475
|
+
set k, v
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
##
|
480
|
+
# The Rake::RemoteTask executing in this Thread.
|
481
|
+
|
482
|
+
def self.task
|
483
|
+
Thread.current[:task]
|
484
|
+
end
|
485
|
+
|
486
|
+
##
|
487
|
+
# The configured Rake::RemoteTasks.
|
488
|
+
|
489
|
+
def self.tasks
|
490
|
+
@@tasks
|
491
|
+
end
|
492
|
+
|
493
|
+
##
|
494
|
+
# Execute +command+ under sudo using run.
|
495
|
+
|
496
|
+
def sudo command
|
497
|
+
run [sudo_cmd, sudo_flags, command].compact.join(" ")
|
498
|
+
end
|
499
|
+
|
500
|
+
##
|
501
|
+
# The hosts this task will execute on. The hosts are determined from
|
502
|
+
# the role this task belongs to.
|
503
|
+
#
|
504
|
+
# The target hosts may be overridden by providing a comma-separated
|
505
|
+
# list of commands to the HOSTS environment variable:
|
506
|
+
#
|
507
|
+
# rake my_task HOSTS=app1.example.com,app2.example.com
|
508
|
+
|
509
|
+
def target_hosts
|
510
|
+
if hosts = ENV["HOSTS"] then
|
511
|
+
hosts.strip.gsub(/\s+/, '').split(",")
|
512
|
+
else
|
513
|
+
roles = options[:roles]
|
514
|
+
roles ? Rake::RemoteTask.hosts_for(roles) : Rake::RemoteTask.all_hosts
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
##
|
519
|
+
# Action is used to run a task's remote_actions in parallel on each
|
520
|
+
# of its hosts. Actions are created automatically in
|
521
|
+
# Rake::RemoteTask#enhance.
|
522
|
+
|
523
|
+
class Action
|
524
|
+
|
525
|
+
##
|
526
|
+
# The task this action is attached to.
|
527
|
+
|
528
|
+
attr_reader :task
|
529
|
+
|
530
|
+
##
|
531
|
+
# The block this action will execute.
|
532
|
+
|
533
|
+
attr_reader :block
|
534
|
+
|
535
|
+
##
|
536
|
+
# An Array of threads, one for each host this action executes on.
|
537
|
+
|
538
|
+
attr_reader :workers
|
539
|
+
|
540
|
+
##
|
541
|
+
# Creates a new Action that will run +block+ for +task+.
|
542
|
+
|
543
|
+
def initialize task, block
|
544
|
+
@task = task
|
545
|
+
@block = block
|
546
|
+
@workers = []
|
547
|
+
end
|
548
|
+
|
549
|
+
def == other # :nodoc:
|
550
|
+
return false unless Action === other
|
551
|
+
block == other.block && task == other.task
|
552
|
+
end
|
553
|
+
|
554
|
+
##
|
555
|
+
# Execute this action on +hosts+ in parallel. Returns when block
|
556
|
+
# has completed for each host.
|
557
|
+
|
558
|
+
def execute hosts, args = nil
|
559
|
+
hosts.each do |host|
|
560
|
+
t = task.clone
|
561
|
+
t.target_host = host
|
562
|
+
thread = Thread.new(t) do |task|
|
563
|
+
Thread.current[:task] = task
|
564
|
+
block.call args
|
565
|
+
end
|
566
|
+
@workers << thread
|
567
|
+
end
|
568
|
+
@workers.each { |w| w.join }
|
569
|
+
end
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
Rake::RemoteTask.set_defaults
|
data/lib/vlad/apache.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'vlad'
|
2
|
+
|
3
|
+
namespace :vlad do
|
4
|
+
##
|
5
|
+
# Apache web server
|
6
|
+
|
7
|
+
set :web_command, "apachectl"
|
8
|
+
|
9
|
+
desc "(Re)Start the web servers"
|
10
|
+
|
11
|
+
remote_task :start_web, :roles => :web do
|
12
|
+
run "#{web_command} restart"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Stop the web servers"
|
16
|
+
|
17
|
+
remote_task :stop_web, :roles => :web do
|
18
|
+
run "#{web_command} stop"
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Everything HTTP.
|
23
|
+
|
24
|
+
desc "(Re)Start the web and app servers"
|
25
|
+
|
26
|
+
remote_task :start do
|
27
|
+
Rake::Task['vlad:start_app'].invoke
|
28
|
+
Rake::Task['vlad:start_web'].invoke
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Stop the web and app servers"
|
32
|
+
|
33
|
+
remote_task :stop do
|
34
|
+
Rake::Task['vlad:stop_app'].invoke
|
35
|
+
Rake::Task['vlad:stop_web'].invoke
|
36
|
+
end
|
37
|
+
end
|