vlad 1.3.2 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/.autotest +24 -0
- data/History.txt +25 -0
- data/Manifest.txt +1 -0
- data/Rakefile +11 -19
- data/doco/faq.txt +38 -0
- data/doco/getting_started.txt +20 -0
- data/lib/rake_remote_task.rb +71 -128
- data/lib/vlad.rb +3 -3
- data/lib/vlad/maintenance.rb +7 -0
- data/lib/vlad/passenger.rb +2 -2
- data/test/test_rake_remote_task.rb +102 -32
- data/test/test_vlad.rb +18 -18
- data/test/test_vlad_mercurial.rb +1 -1
- data/test/vlad_test_case.rb +2 -5
- metadata +15 -6
- metadata.gz.sig +2 -3
data.tar.gz.sig
CHANGED
Binary file
|
data/.autotest
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
Autotest.add_hook :initialize do |at|
|
6
|
+
at.testlib = "minitest/autorun"
|
7
|
+
# at.extra_files << "../some/external/dependency.rb"
|
8
|
+
#
|
9
|
+
# at.libs << ":../some/external"
|
10
|
+
#
|
11
|
+
# at.add_exception 'vendor'
|
12
|
+
#
|
13
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
14
|
+
# at.files_matching(/test_.*rb$/)
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# %w(TestA TestB).each do |klass|
|
18
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
19
|
+
# end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Autotest.add_hook :run_command do |at|
|
23
|
+
# system "rake build"
|
24
|
+
# end
|
data/History.txt
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
=== 1.4.0 / 2009-06-23
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
|
5
|
+
* Switched to passenger as default app server.
|
6
|
+
|
7
|
+
* 11 minor enhancements:
|
8
|
+
|
9
|
+
* #rsync now takes ANY number of arguments and expects to you add "host:".
|
10
|
+
* Added Rake::RemoteTask#get.
|
11
|
+
* Added doco for why we don't ship a deploy task
|
12
|
+
* Added links to example maintenance recipes
|
13
|
+
* Added multi-env doco to getting_started.txt
|
14
|
+
* Added svn-over-ssh faq item. gah.
|
15
|
+
* Flipped tests to minitest
|
16
|
+
* Merged global #role and Rake::RemoteTask::role.
|
17
|
+
* Moved all global methods to Rake::RemoteTask and wrote #external to clean up.
|
18
|
+
* Moved rake extensions to hoe so everyone can enjoy the fun.
|
19
|
+
* put names the tempfile based on the remote path to ease debugging
|
20
|
+
|
21
|
+
* 2 bug fixes:
|
22
|
+
|
23
|
+
* passenger:start_app wasn't using the latest_release path
|
24
|
+
* set/fetch wasn't dealing with a default of false well. (Seth Falcon)
|
25
|
+
|
1
26
|
=== 1.3.2 / 2009-03-16
|
2
27
|
|
3
28
|
* 3 minor enhancements:
|
data/Manifest.txt
CHANGED
data/Rakefile
CHANGED
@@ -2,20 +2,20 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'hoe'
|
5
|
-
$: << 'lib'
|
6
|
-
require 'vlad'
|
7
5
|
|
8
|
-
Hoe.
|
9
|
-
vlad.rubyforge_name = 'hitsquad'
|
6
|
+
Hoe.plugin :seattlerb
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
vlad.developer('Wilson Bilkovich', 'wilson@supremetyrant.com')
|
8
|
+
Hoe.spec 'vlad' do
|
9
|
+
self.rubyforge_name = 'hitsquad'
|
14
10
|
|
15
|
-
|
16
|
-
|
11
|
+
developer 'Ryan Davis', 'ryand-ruby@zenspider.com'
|
12
|
+
developer 'Eric Hodel', 'drbrain@segment7.net'
|
13
|
+
developer 'Wilson Bilkovich', 'wilson@supremetyrant.com'
|
17
14
|
|
18
|
-
|
15
|
+
extra_deps << ['rake', '>= 0.8.1']
|
16
|
+
extra_deps << 'open4'
|
17
|
+
|
18
|
+
multiruby_skip << "1.9" << "rubinius"
|
19
19
|
end
|
20
20
|
|
21
21
|
desc "quick little hack to see what the state of the nation looks like"
|
@@ -28,14 +28,6 @@ task :debug do
|
|
28
28
|
Rake::Task['vlad:debug'].invoke
|
29
29
|
end
|
30
30
|
|
31
|
-
task :flog do
|
32
|
-
sh 'flog -s lib'
|
33
|
-
end
|
34
|
-
|
35
|
-
task :flog_full do
|
36
|
-
sh 'flog -a lib'
|
37
|
-
end
|
38
|
-
|
39
31
|
task :mana_from_heaven do
|
40
32
|
# vlad = vlad + rake + open4
|
41
33
|
# rake sans-contrib = 2035.98356718206
|
@@ -49,4 +41,4 @@ task :mana_from_heaven do
|
|
49
41
|
puts "%14.8f = %s" % [target - vlad, "needed delta"]
|
50
42
|
end
|
51
43
|
|
52
|
-
# vim: syntax=
|
44
|
+
# vim: syntax=ruby
|
data/doco/faq.txt
CHANGED
@@ -5,6 +5,25 @@
|
|
5
5
|
|
6
6
|
We don't want to have to think about what state we're in and where. So vlad:start does a restart if necessary. Restart is just "start again" after all... That is what start does.
|
7
7
|
|
8
|
+
=== Q: Why is there no vlad:deploy?
|
9
|
+
=== A: Because everyone is a unique beautiful flower.
|
10
|
+
|
11
|
+
Everyone's deployment is different. Everyone. Unique scaling
|
12
|
+
requirements. Yadda yadda yadda. So rather than supply something that
|
13
|
+
nobody will use, we decided not to supply anything at all. Here is an
|
14
|
+
example deploy that I stole from the web (and improved) that you may like:
|
15
|
+
|
16
|
+
desc "Full deployment cycle"
|
17
|
+
task "vlad:deploy" => %w[
|
18
|
+
vlad:update
|
19
|
+
vlad:migrate
|
20
|
+
vlad:reset_session
|
21
|
+
vlad:start
|
22
|
+
vlad:cleanup
|
23
|
+
]
|
24
|
+
|
25
|
+
Just pop that in your config/deploy.rb, tweak it as necessary, and have at it.
|
26
|
+
|
8
27
|
=== Q: Why are there no before_action and after_action hooks?
|
9
28
|
=== A: Because we use rake!
|
10
29
|
|
@@ -91,3 +110,22 @@ If you're on a mac (on tiger, not leopard), use SSHKeychain, we love it. <http:/
|
|
91
110
|
|
92
111
|
set :ssh_flags, "-A #{mygateway}"
|
93
112
|
set :rsync_flags, "--rsh ssh -A #{mygateway} ssh"
|
113
|
+
|
114
|
+
=== Q: OMG subversion is stupid! It keeps asking for "Authentication Realm"
|
115
|
+
=== A: Yes, yes it is.
|
116
|
+
|
117
|
+
If you're seeing local checkouts work fine but they don't over ssh
|
118
|
+
(even to localhost!) then ssh into that machine (yes, even localhost)
|
119
|
+
and do a checkout there to a temporary directory. From then on,
|
120
|
+
checkout over ssh should work fine.
|
121
|
+
|
122
|
+
% svn co https://blah/blah /tmp/happy
|
123
|
+
... works fine ...
|
124
|
+
% ssh localhost svn co https://blah/blah /tmp/sad
|
125
|
+
... asks for authentication and then hangs ...
|
126
|
+
% ssh localhost
|
127
|
+
% svn co https://blah/blah /tmp/sad-no-happy
|
128
|
+
... asks for authentication ...
|
129
|
+
... works fine ...
|
130
|
+
% ssh localhost svn co https://blah/blah /tmp/happy2
|
131
|
+
... works fine ...
|
data/doco/getting_started.txt
CHANGED
@@ -14,6 +14,26 @@ This defaults to using 'svn export' from +repository+, and a single
|
|
14
14
|
server for +app+, +db+, and +www+. If you need to tweak these things,
|
15
15
|
refer to the variable documentation.
|
16
16
|
|
17
|
+
* If you want a multi-config environment, change your config like so:
|
18
|
+
|
19
|
+
set :application, "project"
|
20
|
+
set :repository, 'http://svn.example.com/project/branches/stable/'
|
21
|
+
|
22
|
+
task :beta do
|
23
|
+
set :domain, "beta.example.com"
|
24
|
+
set :deploy_to, "/path/to/install-beta"
|
25
|
+
end
|
26
|
+
|
27
|
+
task :dev do
|
28
|
+
set :domain, "dev.example.com"
|
29
|
+
set :deploy_to, "/path/to/install-dev"
|
30
|
+
end
|
31
|
+
|
32
|
+
task :prod do
|
33
|
+
set :domain, "example.com"
|
34
|
+
set :deploy_to, "/path/to/install"
|
35
|
+
end
|
36
|
+
|
17
37
|
* Add the following to your Rakefile:
|
18
38
|
|
19
39
|
begin
|
data/lib/rake_remote_task.rb
CHANGED
@@ -7,123 +7,14 @@ $TESTING ||= false
|
|
7
7
|
$TRACE = Rake.application.options.trace
|
8
8
|
$-w = true if $TRACE # asshat, don't mess with my warn.
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
def host host_name, *roles
|
14
|
-
Rake::RemoteTask.host host_name, *roles
|
15
|
-
end
|
16
|
-
|
17
|
-
##
|
18
|
-
# Copy a (usually generated) file to +remote_path+. Contents of block
|
19
|
-
# are copied to +remote_path+ and you may specify an optional
|
20
|
-
# base_name for the tempfile (aids in debugging).
|
21
|
-
|
22
|
-
def put remote_path, base_name = 'vlad.unknown'
|
23
|
-
require 'tempfile'
|
24
|
-
Tempfile.open base_name do |fp|
|
25
|
-
fp.puts yield
|
26
|
-
fp.flush
|
27
|
-
rsync fp.path, remote_path
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
##
|
32
|
-
# Declare a Vlad task that will execute on all hosts by default. To
|
33
|
-
# limit that task to specific roles, use:
|
34
|
-
#
|
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
|
38
|
-
end
|
39
|
-
|
40
|
-
##
|
41
|
-
# Declare a role and assign a remote host to it. Equivalent to the
|
42
|
-
# <tt>host</tt> method; provided for capistrano compatibility.
|
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
|
57
|
-
end
|
58
|
-
|
59
|
-
##
|
60
|
-
# Execute the given command on the <tt>target_host</tt> for the
|
61
|
-
# current task.
|
62
|
-
def run *args, &b
|
63
|
-
Thread.current[:task].run(*args, &b)
|
64
|
-
end
|
65
|
-
|
66
|
-
# rsync the given files to <tt>target_host</tt>.
|
67
|
-
def rsync local, remote
|
68
|
-
Thread.current[:task].rsync local, remote
|
69
|
-
end
|
70
|
-
|
71
|
-
# run the command w/ sudo
|
72
|
-
def sudo command
|
73
|
-
Thread.current[:task].sudo(command)
|
74
|
-
end
|
75
|
-
|
76
|
-
# Declare a variable called +name+ and assign it a value. A
|
77
|
-
# globally-visible method with the name of the variable is defined.
|
78
|
-
# If a block is given, it will be called when the variable is first
|
79
|
-
# accessed. Subsequent references to the variable will always return
|
80
|
-
# the same value. Raises <tt>ArgumentError</tt> if the +name+ would
|
81
|
-
# conflict with an existing method.
|
82
|
-
def set name, val = nil, &b
|
83
|
-
Rake::RemoteTask.set name, val, &b
|
84
|
-
end
|
85
|
-
|
86
|
-
# Returns the name of the host that the current task is executing on.
|
87
|
-
# <tt>target_host</tt> can uniquely identify a particular task/host
|
88
|
-
# combination.
|
89
|
-
def target_host
|
90
|
-
Thread.current[:task].target_host
|
91
|
-
end
|
92
|
-
|
93
|
-
if Gem::Version.new(RAKEVERSION) < Gem::Version.new('0.8') then
|
94
|
-
class Rake::Task
|
95
|
-
alias vlad_original_execute execute
|
96
|
-
|
97
|
-
def execute(args = nil)
|
98
|
-
vlad_original_execute
|
99
|
-
end
|
10
|
+
def export receiver, *methods
|
11
|
+
methods.each do |method|
|
12
|
+
eval "def #{method} *args, █ #{receiver}.#{method}(*args, &block);end"
|
100
13
|
end
|
101
14
|
end
|
102
15
|
|
103
|
-
|
104
|
-
|
105
|
-
##
|
106
|
-
# This gives us access to the tasks already defined in rake.
|
107
|
-
def all_tasks
|
108
|
-
@tasks
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
##
|
113
|
-
# Hooks into rake and allows us to clear out a task by name or
|
114
|
-
# regexp. Use this if you want to completely override a task instead
|
115
|
-
# of extend it.
|
116
|
-
def self.clear_tasks(*tasks)
|
117
|
-
tasks.flatten.each do |name|
|
118
|
-
case name
|
119
|
-
when Regexp then
|
120
|
-
Rake.application.all_tasks.delete_if { |k,_| k =~ name }
|
121
|
-
else
|
122
|
-
Rake.application.all_tasks.delete(name)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
16
|
+
export "Thread.current[:task]", :get, :put, :rsync, :run, :sudo, :target_host
|
17
|
+
export "Rake::RemoteTask", :host, :remote_task, :role, :set
|
127
18
|
|
128
19
|
##
|
129
20
|
# Rake::RemoteTask is a subclass of Rake::Task that adds
|
@@ -160,7 +51,9 @@ class Rake::RemoteTask < Rake::Task
|
|
160
51
|
|
161
52
|
def initialize(task_name, app)
|
162
53
|
super
|
54
|
+
|
163
55
|
@remote_actions = []
|
56
|
+
@happy = false # used for deprecation warnings on get/put/rsync
|
164
57
|
end
|
165
58
|
|
166
59
|
##
|
@@ -194,19 +87,53 @@ class Rake::RemoteTask < Rake::Task
|
|
194
87
|
end
|
195
88
|
|
196
89
|
##
|
197
|
-
#
|
90
|
+
# Pull +files+ from the remote +host+ using rsync to +local_dir+.
|
91
|
+
# TODO: what if role has multiple hosts & the files overlap? subdirs?
|
92
|
+
|
93
|
+
def get local_dir, *files
|
94
|
+
@happy = true
|
95
|
+
host = target_host
|
96
|
+
rsync files.map { |f| "#{host}:#{f}" }, local_dir
|
97
|
+
@happy = false
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Copy a (usually generated) file to +remote_path+. Contents of block
|
102
|
+
# are copied to +remote_path+ and you may specify an optional
|
103
|
+
# base_name for the tempfile (aids in debugging).
|
104
|
+
|
105
|
+
def put remote_path, base_name = File.basename(remote_path)
|
106
|
+
require 'tempfile'
|
107
|
+
Tempfile.open base_name do |fp|
|
108
|
+
fp.puts yield
|
109
|
+
fp.flush
|
110
|
+
@happy = true
|
111
|
+
rsync fp.path, "#{target_host}:#{remote_path}"
|
112
|
+
@happy = false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Execute rsync with +args+. Tacks on pre-specified +rsync_cmd+ and
|
118
|
+
# +rsync_flags+.
|
119
|
+
#
|
120
|
+
# Favor #get and #put for most tasks. Old-style direct use where the
|
121
|
+
# target_host was implicit is now deprecated.
|
122
|
+
|
123
|
+
def rsync *args
|
124
|
+
unless @happy || args[-1] =~ /:/ then
|
125
|
+
warn "rsync deprecation: pass target_host:remote_path explicitly"
|
126
|
+
args[-1] = "#{target_host}:#{args[-1]}"
|
127
|
+
end
|
198
128
|
|
199
|
-
|
200
|
-
|
201
|
-
cmd = cmd.flatten.compact
|
129
|
+
cmd = [rsync_cmd, rsync_flags, args].flatten.compact
|
130
|
+
cmdstr = cmd.join ' '
|
202
131
|
|
203
|
-
warn
|
132
|
+
warn cmdstr if $TRACE
|
204
133
|
|
205
134
|
success = system(*cmd)
|
206
135
|
|
207
|
-
unless success
|
208
|
-
raise Vlad::CommandFailedError, "execution failed: #{cmd.join ' '}"
|
209
|
-
end
|
136
|
+
raise Vlad::CommandFailedError, "execution failed: #{cmdstr}" unless success
|
210
137
|
end
|
211
138
|
|
212
139
|
##
|
@@ -311,7 +238,7 @@ class Rake::RemoteTask < Rake::Task
|
|
311
238
|
v = v.call if Proc === v
|
312
239
|
v
|
313
240
|
end
|
314
|
-
elsif default
|
241
|
+
elsif default || default == false
|
315
242
|
v = @@env[name] = default
|
316
243
|
else
|
317
244
|
raise Vlad::FetchError
|
@@ -407,13 +334,29 @@ class Rake::RemoteTask < Rake::Task
|
|
407
334
|
|
408
335
|
##
|
409
336
|
# Adds role +role_name+ with +host+ and +args+ for that host.
|
337
|
+
# TODO: merge:
|
338
|
+
# Declare a role and assign a remote host to it. Equivalent to the
|
339
|
+
# <tt>host</tt> method; provided for capistrano compatibility.
|
410
340
|
|
411
|
-
def self.role role_name, host, args = {}
|
412
|
-
|
413
|
-
raise ArgumentError,
|
341
|
+
def self.role role_name, host = nil, args = {}
|
342
|
+
if block_given? then
|
343
|
+
raise ArgumentError, 'host not allowed with block' unless host.nil?
|
344
|
+
|
345
|
+
begin
|
346
|
+
current_roles << role_name
|
347
|
+
yield
|
348
|
+
ensure
|
349
|
+
current_roles.delete role_name
|
350
|
+
end
|
351
|
+
else
|
352
|
+
raise ArgumentError, 'host required' if host.nil?
|
353
|
+
|
354
|
+
[*host].each do |hst|
|
355
|
+
raise ArgumentError, "invalid host: #{hst}" if hst.nil? or hst.empty?
|
356
|
+
end
|
357
|
+
@@roles[role_name] = {} if @@def_role_hash.eql? @@roles[role_name]
|
358
|
+
@@roles[role_name][host] = args
|
414
359
|
end
|
415
|
-
@@roles[role_name] = {} if @@def_role_hash.eql? @@roles[role_name]
|
416
|
-
@@roles[role_name][host] = args
|
417
360
|
end
|
418
361
|
|
419
362
|
##
|
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.4.0'
|
24
24
|
|
25
25
|
##
|
26
26
|
# Base error class for all Vlad errors.
|
@@ -42,7 +42,7 @@ module Vlad
|
|
42
42
|
# Loads tasks file +tasks_file+ and various recipe styles as a hash
|
43
43
|
# of category/style pairs. Recipes default to:
|
44
44
|
#
|
45
|
-
# :app => :
|
45
|
+
# :app => :passenger
|
46
46
|
# :config => 'config/deploy.rb'
|
47
47
|
# :core => :core
|
48
48
|
# :scm => :subversion
|
@@ -62,7 +62,7 @@ module Vlad
|
|
62
62
|
order += options.keys - order
|
63
63
|
|
64
64
|
recipes = {
|
65
|
-
:app => :
|
65
|
+
:app => :passenger,
|
66
66
|
:config => 'config/deploy.rb',
|
67
67
|
:core => :core,
|
68
68
|
:scm => :subversion,
|
data/lib/vlad/maintenance.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
require 'vlad'
|
2
2
|
|
3
|
+
##
|
4
|
+
# See the following documents for recipes:
|
5
|
+
#
|
6
|
+
# * http://clarkware.com/cgi/blosxom/2007/01/05/CustomMaintenancePages
|
7
|
+
# * http://blog.nodeta.fi/2009/03/11/stopping-your-rails-application-with-phusion-passenger/
|
8
|
+
#
|
9
|
+
|
3
10
|
namespace :vlad do
|
4
11
|
namespace :maintenance do
|
5
12
|
remote_task :on, :roles => [:web] do
|
data/lib/vlad/passenger.rb
CHANGED
@@ -2,6 +2,16 @@ require 'test/vlad_test_case'
|
|
2
2
|
require 'vlad'
|
3
3
|
|
4
4
|
class TestRakeRemoteTask < VladTestCase
|
5
|
+
# TODO: move to minitest
|
6
|
+
def assert_silent
|
7
|
+
out, err = capture_io do
|
8
|
+
yield
|
9
|
+
end
|
10
|
+
|
11
|
+
assert_empty err
|
12
|
+
assert_empty out
|
13
|
+
end
|
14
|
+
|
5
15
|
def test_enhance
|
6
16
|
util_set_hosts
|
7
17
|
body = Proc.new { 5 }
|
@@ -29,6 +39,21 @@ class TestRakeRemoteTask < VladTestCase
|
|
29
39
|
assert_equal 7, x
|
30
40
|
end
|
31
41
|
|
42
|
+
def test_set_false
|
43
|
+
set :can_set_nil, nil
|
44
|
+
set :lies_are, false
|
45
|
+
|
46
|
+
assert_equal nil, task.can_set_nil
|
47
|
+
|
48
|
+
assert_equal false, task.lies_are
|
49
|
+
assert_equal false, Rake::RemoteTask.fetch(:lies_are)
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def test_fetch_false
|
54
|
+
assert_equal false, Rake::RemoteTask.fetch(:unknown, false)
|
55
|
+
end
|
56
|
+
|
32
57
|
def test_execute_exposes_target_host
|
33
58
|
host "app.example.com", :app
|
34
59
|
task = remote_task(:target_task) { set(:test_target_host, target_host) }
|
@@ -39,14 +64,14 @@ class TestRakeRemoteTask < VladTestCase
|
|
39
64
|
def test_execute_with_no_hosts
|
40
65
|
@vlad.host "app.example.com", :app
|
41
66
|
t = @vlad.remote_task(:flunk, :roles => :db) { flunk "should not have run" }
|
42
|
-
e =
|
67
|
+
e = assert_raises(Vlad::ConfigurationError) { t.execute nil }
|
43
68
|
assert_equal "No target hosts specified on task flunk for roles [:db]",
|
44
69
|
e.message
|
45
70
|
end
|
46
71
|
|
47
72
|
def test_execute_with_no_roles
|
48
73
|
t = @vlad.remote_task(:flunk, :roles => :junk) { flunk "should not have run" }
|
49
|
-
e =
|
74
|
+
e = assert_raises(Vlad::ConfigurationError) { t.execute nil }
|
50
75
|
assert_equal "No target hosts specified on task flunk for roles [:junk]",
|
51
76
|
e.message
|
52
77
|
end
|
@@ -65,13 +90,15 @@ class TestRakeRemoteTask < VladTestCase
|
|
65
90
|
util_setup_task
|
66
91
|
@task.target_host = "app.example.com"
|
67
92
|
|
68
|
-
|
93
|
+
assert_silent do
|
94
|
+
@task.rsync 'localfile', 'host:remotefile'
|
95
|
+
end
|
69
96
|
|
70
97
|
commands = @task.commands
|
71
98
|
|
72
99
|
assert_equal 1, commands.size, 'not enough commands'
|
73
|
-
assert_equal
|
74
|
-
commands.first
|
100
|
+
assert_equal(%w[rsync -azP --delete localfile host:remotefile],
|
101
|
+
commands.first)
|
75
102
|
end
|
76
103
|
|
77
104
|
def test_rsync_fail
|
@@ -79,8 +106,68 @@ class TestRakeRemoteTask < VladTestCase
|
|
79
106
|
@task.target_host = "app.example.com"
|
80
107
|
@task.action = lambda { false }
|
81
108
|
|
82
|
-
e =
|
83
|
-
|
109
|
+
e = assert_raises Vlad::CommandFailedError do
|
110
|
+
assert_silent do
|
111
|
+
@task.rsync 'local', 'host:remote'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
exp = "execution failed: rsync -azP --delete local host:remote"
|
115
|
+
assert_equal exp, e.message
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_rsync_deprecation
|
119
|
+
util_setup_task
|
120
|
+
@task.target_host = "app.example.com"
|
121
|
+
|
122
|
+
out, err = capture_io do
|
123
|
+
@task.rsync 'localfile', 'remotefile'
|
124
|
+
end
|
125
|
+
|
126
|
+
commands = @task.commands
|
127
|
+
|
128
|
+
assert_equal 1, commands.size, 'not enough commands'
|
129
|
+
assert_equal(%w[rsync -azP --delete localfile app.example.com:remotefile],
|
130
|
+
commands.first)
|
131
|
+
|
132
|
+
assert_equal("rsync deprecation: pass target_host:remote_path explicitly\n",
|
133
|
+
err)
|
134
|
+
assert_empty out
|
135
|
+
# flunk "not yet"
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_get
|
139
|
+
util_setup_task
|
140
|
+
@task.target_host = "app.example.com"
|
141
|
+
|
142
|
+
assert_silent do
|
143
|
+
@task.get 'tmp', "remote1", "remote2"
|
144
|
+
end
|
145
|
+
|
146
|
+
commands = @task.commands
|
147
|
+
|
148
|
+
expected = %w[rsync -azP --delete app.example.com:remote1 app.example.com:remote2 tmp]
|
149
|
+
|
150
|
+
assert_equal 1, commands.size
|
151
|
+
assert_equal expected, commands.first
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_put
|
155
|
+
util_setup_task
|
156
|
+
@task.target_host = "app.example.com"
|
157
|
+
|
158
|
+
assert_silent do
|
159
|
+
@task.put 'dest' do
|
160
|
+
"whatever"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
commands = @task.commands
|
165
|
+
|
166
|
+
expected = %w[rsync -azP --delete HAPPY app.example.com:dest]
|
167
|
+
commands.first[3] = 'HAPPY'
|
168
|
+
|
169
|
+
assert_equal 1, commands.size
|
170
|
+
assert_equal expected, commands.first
|
84
171
|
end
|
85
172
|
|
86
173
|
def test_run
|
@@ -89,7 +176,7 @@ class TestRakeRemoteTask < VladTestCase
|
|
89
176
|
@task.target_host = "app.example.com"
|
90
177
|
result = nil
|
91
178
|
|
92
|
-
out, err =
|
179
|
+
out, err = capture_io do
|
93
180
|
result = @task.run("ls")
|
94
181
|
end
|
95
182
|
|
@@ -100,8 +187,8 @@ class TestRakeRemoteTask < VladTestCase
|
|
100
187
|
commands.first, 'app'
|
101
188
|
assert_equal "file1\nfile2\n", result
|
102
189
|
|
103
|
-
assert_equal "file1\nfile2\n", out
|
104
|
-
assert_equal '', err
|
190
|
+
assert_equal "file1\nfile2\n", out
|
191
|
+
assert_equal '', err
|
105
192
|
end
|
106
193
|
|
107
194
|
def test_run_failing_command
|
@@ -111,7 +198,7 @@ class TestRakeRemoteTask < VladTestCase
|
|
111
198
|
@task.target_host = 'app.example.com'
|
112
199
|
@task.action = lambda { 1 }
|
113
200
|
|
114
|
-
e =
|
201
|
+
e = assert_raises(Vlad::CommandFailedError) { @task.run("ls") }
|
115
202
|
assert_equal "execution failed with status 1: ssh app.example.com ls", e.message
|
116
203
|
|
117
204
|
assert_equal 1, @task.commands.size
|
@@ -125,7 +212,7 @@ class TestRakeRemoteTask < VladTestCase
|
|
125
212
|
def @task.sudo_password() "my password" end # gets defined by set
|
126
213
|
result = nil
|
127
214
|
|
128
|
-
out, err =
|
215
|
+
out, err = capture_io do
|
129
216
|
result = @task.run("sudo ls")
|
130
217
|
end
|
131
218
|
|
@@ -143,14 +230,14 @@ class TestRakeRemoteTask < VladTestCase
|
|
143
230
|
# testing model.
|
144
231
|
assert_equal "file1\nfile2\nPassword:\n", result
|
145
232
|
|
146
|
-
assert_equal "file1\nfile2\n", out
|
147
|
-
assert_equal "Password:\n", err
|
233
|
+
assert_equal "file1\nfile2\n", out
|
234
|
+
assert_equal "Password:\n", err
|
148
235
|
end
|
149
236
|
|
150
237
|
def test_sudo
|
151
238
|
util_setup_task
|
152
239
|
@task.target_host = "app.example.com"
|
153
|
-
@task.sudo "ls"
|
240
|
+
@task.sudo "ls"
|
154
241
|
|
155
242
|
commands = @task.commands
|
156
243
|
|
@@ -159,23 +246,6 @@ class TestRakeRemoteTask < VladTestCase
|
|
159
246
|
commands.first, 'app'
|
160
247
|
end
|
161
248
|
|
162
|
-
def util_capture
|
163
|
-
require 'stringio'
|
164
|
-
orig_stdout = $stdout.dup
|
165
|
-
orig_stderr = $stderr.dup
|
166
|
-
captured_stdout = StringIO.new
|
167
|
-
captured_stderr = StringIO.new
|
168
|
-
$stdout = captured_stdout
|
169
|
-
$stderr = captured_stderr
|
170
|
-
yield
|
171
|
-
captured_stdout.rewind
|
172
|
-
captured_stderr.rewind
|
173
|
-
return captured_stdout, captured_stderr
|
174
|
-
ensure
|
175
|
-
$stdout = orig_stdout
|
176
|
-
$stderr = orig_stderr
|
177
|
-
end
|
178
|
-
|
179
249
|
def util_setup_task(options = {})
|
180
250
|
@task = @vlad.remote_task :test_task, options
|
181
251
|
@task.commands = []
|
data/test/test_vlad.rb
CHANGED
@@ -26,7 +26,7 @@ class TestVlad < VladTestCase
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_host_invalid
|
29
|
-
|
29
|
+
assert_raises(ArgumentError) { @vlad.host nil, :web }
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_host_multiple_hosts
|
@@ -40,8 +40,8 @@ class TestVlad < VladTestCase
|
|
40
40
|
|
41
41
|
assert_equal expected, @vlad.roles[:app]
|
42
42
|
assert_equal expected, @vlad.roles[:db]
|
43
|
-
|
44
|
-
|
43
|
+
refute_equal(@vlad.roles[:db]["test.example.com"].object_id,
|
44
|
+
@vlad.roles[:app]["test.example.com"].object_id)
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_hosts_for_array_of_roles
|
@@ -68,9 +68,9 @@ class TestVlad < VladTestCase
|
|
68
68
|
|
69
69
|
def test_initialize
|
70
70
|
@vlad.set_defaults # ensure these three are virginal
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
assert_raises(Vlad::ConfigurationError) { @vlad.repository }
|
72
|
+
assert_raises(Vlad::ConfigurationError) { @vlad.deploy_to }
|
73
|
+
assert_raises(Vlad::ConfigurationError) { @vlad.domain }
|
74
74
|
end
|
75
75
|
|
76
76
|
def test_role
|
@@ -160,21 +160,21 @@ class TestVlad < VladTestCase
|
|
160
160
|
end
|
161
161
|
|
162
162
|
def test_set
|
163
|
-
set :
|
164
|
-
assert_equal 5, @vlad.
|
163
|
+
set :win, 5
|
164
|
+
assert_equal 5, @vlad.win
|
165
165
|
end
|
166
166
|
|
167
167
|
def test_set_lazy_block_evaluation
|
168
|
-
set(:
|
169
|
-
|
168
|
+
set(:lose) { raise "lose" }
|
169
|
+
assert_raises(RuntimeError) { @vlad.lose }
|
170
170
|
end
|
171
171
|
|
172
172
|
def test_set_with_block
|
173
173
|
x = 1
|
174
|
-
set(:
|
174
|
+
set(:win) { x += 2 }
|
175
175
|
|
176
|
-
assert_equal 3, @vlad.
|
177
|
-
assert_equal 3, @vlad.
|
176
|
+
assert_equal 3, @vlad.win
|
177
|
+
assert_equal 3, @vlad.win
|
178
178
|
end
|
179
179
|
|
180
180
|
def test_set_with_reference
|
@@ -188,20 +188,20 @@ class TestVlad < VladTestCase
|
|
188
188
|
end
|
189
189
|
|
190
190
|
def test_set_with_block_and_value
|
191
|
-
e =
|
192
|
-
set(:
|
191
|
+
e = assert_raises(ArgumentError) do
|
192
|
+
set(:loser, 5) { 6 }
|
193
193
|
end
|
194
194
|
assert_equal "cannot provide both a value and a block", e.message
|
195
195
|
end
|
196
196
|
|
197
197
|
def test_set_with_nil
|
198
|
-
set(:
|
199
|
-
assert_equal nil, @vlad.
|
198
|
+
set(:win, nil)
|
199
|
+
assert_equal nil, @vlad.win
|
200
200
|
end
|
201
201
|
|
202
202
|
def test_set_with_reserved_name
|
203
203
|
$TESTING = false
|
204
|
-
e =
|
204
|
+
e = assert_raises(ArgumentError) { set(:all_hosts, []) }
|
205
205
|
assert_equal "cannot set reserved name: 'all_hosts'", e.message
|
206
206
|
ensure
|
207
207
|
$TESTING = true
|
data/test/test_vlad_mercurial.rb
CHANGED
data/test/vlad_test_case.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'minitest/autorun'
|
2
2
|
require 'stringio'
|
3
3
|
require 'vlad'
|
4
4
|
|
@@ -21,7 +21,6 @@ module Process
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
24
|
class Rake::RemoteTask
|
26
25
|
attr_accessor :commands, :action, :input, :output, :error
|
27
26
|
|
@@ -57,9 +56,7 @@ class Rake::RemoteTask
|
|
57
56
|
|
58
57
|
end
|
59
58
|
|
60
|
-
class VladTestCase <
|
61
|
-
undef_method :default_test
|
62
|
-
|
59
|
+
class VladTestCase < MiniTest::Unit::TestCase
|
63
60
|
def setup
|
64
61
|
@vlad = Rake::RemoteTask
|
65
62
|
@vlad.reset
|
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.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
@@ -32,7 +32,7 @@ cert_chain:
|
|
32
32
|
FBHgymkyj/AOSqKRIpXPhjC6
|
33
33
|
-----END CERTIFICATE-----
|
34
34
|
|
35
|
-
date: 2009-
|
35
|
+
date: 2009-06-23 00:00:00 -07:00
|
36
36
|
default_executable:
|
37
37
|
dependencies:
|
38
38
|
- !ruby/object:Gem::Dependency
|
@@ -63,9 +63,15 @@ dependencies:
|
|
63
63
|
requirements:
|
64
64
|
- - ">="
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version:
|
66
|
+
version: 2.3.0
|
67
67
|
version:
|
68
|
-
description:
|
68
|
+
description: |-
|
69
|
+
Vlad the Deployer is pragmatic application deployment automation,
|
70
|
+
without mercy. Much like Capistrano, but with 1/10th the
|
71
|
+
complexity. Vlad integrates seamlessly with Rake, and uses familiar
|
72
|
+
and standard tools like ssh and rsync.
|
73
|
+
|
74
|
+
Impale your application on the heartless spike of the Deployer.
|
69
75
|
email:
|
70
76
|
- ryand-ruby@zenspider.com
|
71
77
|
- drbrain@segment7.net
|
@@ -87,6 +93,7 @@ extra_rdoc_files:
|
|
87
93
|
- doco/perforce.txt
|
88
94
|
- doco/variables.txt
|
89
95
|
files:
|
96
|
+
- .autotest
|
90
97
|
- History.txt
|
91
98
|
- Manifest.txt
|
92
99
|
- README.txt
|
@@ -126,6 +133,8 @@ files:
|
|
126
133
|
- vladdemo.sh
|
127
134
|
has_rdoc: true
|
128
135
|
homepage: http://rubyhitsquad.com/
|
136
|
+
licenses: []
|
137
|
+
|
129
138
|
post_install_message:
|
130
139
|
rdoc_options:
|
131
140
|
- --main
|
@@ -147,9 +156,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
156
|
requirements: []
|
148
157
|
|
149
158
|
rubyforge_project: hitsquad
|
150
|
-
rubygems_version: 1.3.
|
159
|
+
rubygems_version: 1.3.4
|
151
160
|
signing_key:
|
152
|
-
specification_version:
|
161
|
+
specification_version: 3
|
153
162
|
summary: Vlad the Deployer is pragmatic application deployment automation, without mercy
|
154
163
|
test_files:
|
155
164
|
- test/test_rake_remote_task.rb
|
metadata.gz.sig
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
J��8�']1��$���P@����݅����� ��^�z�$�`el�~ׄe�Y]��d�8��&��
|
1
|
+
��R0�¾8Qi��2����(pJ+\u�O_��sdq���)ڶ6��Oh#F3��� h�r�b�J���l�[��� ��A=��0�o�o�kPep�]�P�/��"Z�o��,�e�� ��I_��i�sa�W�^�p������a��x�h��|O�P~ഁ������
|
2
|
+
:�'��|�)�v7�^��:����Ψ��0�r e�<cT0��Ǭ�#Bjt���)ث�ON�@O���uѺ6Uy�X��w7��-%B(��
|