isst-vlad 2.0.1
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/.autotest +25 -0
- data/History.txt +173 -0
- data/PATCHES.txt +39 -0
- data/README.txt +78 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/considerations.txt +91 -0
- data/doco/deploying-merb-with-vlad.txt +155 -0
- data/doco/deploying-sinatra-with-vlad.txt +119 -0
- data/doco/faq.txt +136 -0
- data/doco/getting_started.txt +61 -0
- data/doco/migration.txt +43 -0
- data/doco/perforce.txt +5 -0
- data/doco/variables.txt +84 -0
- data/isst-vlad.gemspec +89 -0
- data/lib/remote_task.rb +641 -0
- data/lib/test_case.rb +73 -0
- data/lib/vlad.rb +78 -0
- data/lib/vlad/apache.rb +37 -0
- data/lib/vlad/core.rb +163 -0
- data/lib/vlad/git.rb +86 -0
- data/lib/vlad/maintenance.rb +20 -0
- data/lib/vlad/merb.rb +51 -0
- data/lib/vlad/nginx.rb +37 -0
- data/lib/vlad/passenger.rb +8 -0
- data/lib/vlad/rails.rb +34 -0
- data/lib/vlad/sequel.rb +28 -0
- data/lib/vlad/sinatra.rb +7 -0
- data/lib/vlad/subversion.rb +35 -0
- data/lib/vlad/thin.rb +63 -0
- data/test/test_remote_task.rb +316 -0
- data/test/test_vlad.rb +209 -0
- data/test/test_vlad_git.rb +65 -0
- data/test/test_vlad_subversion.rb +26 -0
- data/vladdemo.sh +97 -0
- metadata +151 -0
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/nginx.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'vlad'
|
2
|
+
|
3
|
+
namespace :vlad do
|
4
|
+
##
|
5
|
+
# Nginx web server
|
6
|
+
|
7
|
+
set :web_command, "/sbin/service nginx"
|
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
|
data/lib/vlad/rails.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
namespace :vlad do
|
2
|
+
set :rails_env, "production"
|
3
|
+
set :migrate_args, ""
|
4
|
+
set :migrate_target, :latest
|
5
|
+
set :mkdirs, %w(tmp db)
|
6
|
+
set :shared_paths, {
|
7
|
+
'log' => 'log',
|
8
|
+
'system' => 'public/system',
|
9
|
+
'pids' => 'tmp/pids',
|
10
|
+
}
|
11
|
+
|
12
|
+
desc "Run the migrate rake task for the the app. By default this is run in
|
13
|
+
the latest app directory. You can run migrations for the current app
|
14
|
+
directory by setting :migrate_target to :current. Additional environment
|
15
|
+
variables can be passed to rake via the migrate_env variable.".cleanup
|
16
|
+
|
17
|
+
# No application files are on the DB machine, also migrations should only be
|
18
|
+
# run once.
|
19
|
+
remote_task :migrate, :roles => :app do
|
20
|
+
break unless target_host == Rake::RemoteTask.hosts_for(:app).first
|
21
|
+
|
22
|
+
directory = case migrate_target.to_sym
|
23
|
+
when :current then current_path
|
24
|
+
when :latest then current_release
|
25
|
+
else
|
26
|
+
raise(ArgumentError,
|
27
|
+
"unknown migration target #{migrate_target.inspect}")
|
28
|
+
end
|
29
|
+
|
30
|
+
run ["cd #{directory}",
|
31
|
+
"#{rake_cmd} RAILS_ENV=#{rails_env} db:migrate #{migrate_args}"
|
32
|
+
].join(" ")
|
33
|
+
end
|
34
|
+
end
|
data/lib/vlad/sequel.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
namespace :vlad do
|
2
|
+
set :rack_env, "production"
|
3
|
+
set :migrate_args, ""
|
4
|
+
set :migrate_target, :latest
|
5
|
+
|
6
|
+
desc "Run the sq:migrate rake task for the the app. By default this is run in
|
7
|
+
the latest app directory. You can run migrations for the current app
|
8
|
+
directory by setting :migrate_target to :current. Additional environment
|
9
|
+
variables can be passed to rake via the migrate_env variable.".cleanup
|
10
|
+
|
11
|
+
# No application files are on the DB machine, also migrations should only be
|
12
|
+
# run once.
|
13
|
+
remote_task :migrate, :roles => :app do
|
14
|
+
break unless target_host == Rake::RemoteTask.hosts_for(:app).first
|
15
|
+
|
16
|
+
directory = case migrate_target.to_sym
|
17
|
+
when :current then current_path
|
18
|
+
when :latest then current_release
|
19
|
+
else
|
20
|
+
raise(ArgumentError,
|
21
|
+
"unknown migration target #{migrate_target.inspect}")
|
22
|
+
end
|
23
|
+
|
24
|
+
run ["cd #{directory}",
|
25
|
+
"#{rake_cmd} RACK_ENV=#{rack_env} sq:db:migrate #{migrate_args}"
|
26
|
+
].join(" ")
|
27
|
+
end
|
28
|
+
end
|
data/lib/vlad/sinatra.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class Vlad::Subversion
|
2
|
+
|
3
|
+
set :source, Vlad::Subversion.new
|
4
|
+
set :svn_cmd, "svn"
|
5
|
+
|
6
|
+
##
|
7
|
+
# Returns the command that will check out +revision+ from the repository
|
8
|
+
# into directory +destination+
|
9
|
+
|
10
|
+
def checkout(revision, destination)
|
11
|
+
"#{svn_cmd} co -r #{revision} #{repository} #{destination}"
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Returns the command that will export +revision+ from the repository into
|
16
|
+
# the directory +destination+.
|
17
|
+
|
18
|
+
def export(revision_or_source, destination)
|
19
|
+
"#{svn_cmd} #{deploy_via} " +
|
20
|
+
if revision_or_source =~ /^(\d+|head)$/i then
|
21
|
+
"-r #{revision_or_source} #{repository} #{destination}"
|
22
|
+
else
|
23
|
+
"#{revision_or_source} #{destination}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Returns a command that maps human-friendly revision identifier +revision+
|
29
|
+
# into a subversion revision specification.
|
30
|
+
|
31
|
+
def revision(revision)
|
32
|
+
"`#{svn_cmd} info #{repository} | grep 'Revision:' | cut -f2 -d\\ `"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
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
|
@@ -0,0 +1,316 @@
|
|
1
|
+
require 'test_case'
|
2
|
+
|
3
|
+
class TestRakeRemoteTask < Rake::TestCase
|
4
|
+
# TODO: move to minitest
|
5
|
+
def assert_silent
|
6
|
+
out, err = capture_io do
|
7
|
+
yield
|
8
|
+
end
|
9
|
+
|
10
|
+
assert_empty err
|
11
|
+
assert_empty out
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_enhance
|
15
|
+
util_set_hosts
|
16
|
+
body = Proc.new { 5 }
|
17
|
+
task = @rake.remote_task(:some_task => :foo, &body)
|
18
|
+
action = Rake::RemoteTask::Action.new(task, body)
|
19
|
+
assert_equal [action], task.remote_actions
|
20
|
+
assert_equal task, action.task
|
21
|
+
assert_equal ["foo"], task.prerequisites
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_enhance_with_no_task_body
|
25
|
+
util_set_hosts
|
26
|
+
util_setup_task
|
27
|
+
assert_equal [], @task.remote_actions
|
28
|
+
assert_equal [], @task.prerequisites
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_execute
|
32
|
+
util_set_hosts
|
33
|
+
set :some_variable, 1
|
34
|
+
set :can_set_nil, nil
|
35
|
+
set :lies_are, false
|
36
|
+
x = 5
|
37
|
+
task = @rake.remote_task(:some_task) { x += some_variable }
|
38
|
+
task.execute nil
|
39
|
+
assert_equal 1, task.some_variable
|
40
|
+
assert_equal 7, x
|
41
|
+
assert task.can_set_nil.nil?
|
42
|
+
assert_equal false, task.lies_are
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_set_false
|
46
|
+
set :can_set_nil, nil
|
47
|
+
set :lies_are, false
|
48
|
+
|
49
|
+
assert_equal nil, task.can_set_nil
|
50
|
+
|
51
|
+
assert_equal false, task.lies_are
|
52
|
+
assert_equal false, Rake::RemoteTask.fetch(:lies_are)
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def test_fetch_false
|
57
|
+
assert_equal false, Rake::RemoteTask.fetch(:unknown, false)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_execute_exposes_target_host
|
61
|
+
host "app.example.com", :app
|
62
|
+
task = remote_task(:target_task) { set(:test_target_host, target_host) }
|
63
|
+
task.execute nil
|
64
|
+
assert_equal "app.example.com", Rake::RemoteTask.fetch(:test_target_host)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_execute_with_no_hosts
|
68
|
+
@rake.host "app.example.com", :app
|
69
|
+
t = @rake.remote_task(:flunk, :roles => :db) { flunk "should not have run" }
|
70
|
+
e = assert_raises(Rake::ConfigurationError) { t.execute nil }
|
71
|
+
assert_equal "No target hosts specified on task flunk for roles [:db]",
|
72
|
+
e.message
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_execute_with_no_roles
|
76
|
+
t = @rake.remote_task(:flunk, :roles => :junk) { flunk "should not have run" }
|
77
|
+
e = assert_raises(Rake::ConfigurationError) { t.execute nil }
|
78
|
+
assert_equal "No target hosts specified on task flunk for roles [:junk]",
|
79
|
+
e.message
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_execute_with_roles
|
83
|
+
util_set_hosts
|
84
|
+
set :some_variable, 1
|
85
|
+
x = 5
|
86
|
+
task = @rake.remote_task(:some_task, :roles => :db) { x += some_variable }
|
87
|
+
task.execute nil
|
88
|
+
assert_equal 1, task.some_variable
|
89
|
+
assert_equal 6, x
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_rsync
|
93
|
+
util_setup_task
|
94
|
+
@task.target_host = "app.example.com"
|
95
|
+
|
96
|
+
assert_silent do
|
97
|
+
@task.rsync 'localfile', 'host:remotefile'
|
98
|
+
end
|
99
|
+
|
100
|
+
commands = @task.commands
|
101
|
+
|
102
|
+
assert_equal 1, commands.size, 'not enough commands'
|
103
|
+
assert_equal(%w[rsync -azP --delete localfile host:remotefile],
|
104
|
+
commands.first)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_rsync_fail
|
108
|
+
util_setup_task
|
109
|
+
@task.target_host = "app.example.com"
|
110
|
+
@task.action = lambda { false }
|
111
|
+
|
112
|
+
e = assert_raises Rake::CommandFailedError do
|
113
|
+
assert_silent do
|
114
|
+
@task.rsync 'local', 'host:remote'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
exp = "execution failed: rsync -azP --delete local host:remote"
|
118
|
+
assert_equal exp, e.message
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_rsync_deprecation
|
122
|
+
util_setup_task
|
123
|
+
@task.target_host = "app.example.com"
|
124
|
+
|
125
|
+
out, err = capture_io do
|
126
|
+
@task.rsync 'localfile', 'remotefile'
|
127
|
+
end
|
128
|
+
|
129
|
+
commands = @task.commands
|
130
|
+
|
131
|
+
assert_equal 1, commands.size, 'not enough commands'
|
132
|
+
assert_equal(%w[rsync -azP --delete localfile app.example.com:remotefile],
|
133
|
+
commands.first)
|
134
|
+
|
135
|
+
assert_equal("rsync deprecation: pass target_host:remote_path explicitly\n",
|
136
|
+
err)
|
137
|
+
assert_empty out
|
138
|
+
# flunk "not yet"
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_get
|
142
|
+
util_setup_task
|
143
|
+
@task.target_host = "app.example.com"
|
144
|
+
|
145
|
+
assert_silent do
|
146
|
+
@task.get 'tmp', "remote1", "remote2"
|
147
|
+
end
|
148
|
+
|
149
|
+
commands = @task.commands
|
150
|
+
|
151
|
+
expected = %w[rsync -azP --delete app.example.com:remote1 app.example.com:remote2 tmp]
|
152
|
+
|
153
|
+
assert_equal 1, commands.size
|
154
|
+
assert_equal expected, commands.first
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_put
|
158
|
+
util_setup_task
|
159
|
+
@task.target_host = "app.example.com"
|
160
|
+
|
161
|
+
assert_silent do
|
162
|
+
@task.put 'dest' do
|
163
|
+
"whatever"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
commands = @task.commands
|
168
|
+
|
169
|
+
expected = %w[rsync -azP --delete HAPPY app.example.com:dest]
|
170
|
+
commands.first[3] = 'HAPPY'
|
171
|
+
|
172
|
+
assert_equal 1, commands.size
|
173
|
+
assert_equal expected, commands.first
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_run
|
177
|
+
util_setup_task
|
178
|
+
@task.output << "file1\nfile2\n"
|
179
|
+
@task.target_host = "app.example.com"
|
180
|
+
result = nil
|
181
|
+
|
182
|
+
out, err = capture_io do
|
183
|
+
result = @task.run("ls")
|
184
|
+
end
|
185
|
+
|
186
|
+
commands = @task.commands
|
187
|
+
|
188
|
+
assert_equal 1, commands.size, 'not enough commands'
|
189
|
+
assert_equal ["ssh", "app.example.com", "ls"],
|
190
|
+
commands.first, 'app'
|
191
|
+
assert_equal "file1\nfile2\n", result
|
192
|
+
|
193
|
+
assert_equal "file1\nfile2\n", out
|
194
|
+
assert_equal '', err
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_run_dir
|
198
|
+
util_setup_task
|
199
|
+
@task.target_host = "app.example.com:/www/dir1"
|
200
|
+
|
201
|
+
@task.run("ls")
|
202
|
+
|
203
|
+
commands = @task.commands
|
204
|
+
|
205
|
+
assert_equal 1, commands.size, 'not enough commands'
|
206
|
+
assert_equal [["ssh", "app.example.com", "cd /www/dir1 && ls"]], commands
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_run_failing_command
|
210
|
+
util_set_hosts
|
211
|
+
util_setup_task
|
212
|
+
@task.input = StringIO.new "file1\nfile2\n"
|
213
|
+
@task.target_host = 'app.example.com'
|
214
|
+
@task.action = lambda { 1 }
|
215
|
+
|
216
|
+
e = assert_raises(Rake::CommandFailedError) { @task.run("ls") }
|
217
|
+
assert_equal "execution failed with status 1: ssh app.example.com ls", e.message
|
218
|
+
|
219
|
+
assert_equal 1, @task.commands.size
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_run_with_prefix_output
|
223
|
+
util_setup_task
|
224
|
+
@task.output << "file1\nfile2\n"
|
225
|
+
@task.target_host = "app.example.com"
|
226
|
+
result = nil
|
227
|
+
|
228
|
+
set :prefix_output, true
|
229
|
+
|
230
|
+
out, err = capture_io do
|
231
|
+
result = @task.run("ls")
|
232
|
+
end
|
233
|
+
|
234
|
+
assert_equal "app.example.com: file1\napp.example.com: file2\n", result
|
235
|
+
assert_equal "app.example.com: file1\napp.example.com: file2\n", out
|
236
|
+
# Reset to false
|
237
|
+
set :prefix_output, false
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_run_with_prepend_command
|
241
|
+
util_setup_task
|
242
|
+
@task.output << "file1\nfile2\n"
|
243
|
+
@task.target_host = "app.example.com"
|
244
|
+
result = nil
|
245
|
+
|
246
|
+
set :prepend_cmd, "sudo bash -cl"
|
247
|
+
|
248
|
+
out, err = capture_io do
|
249
|
+
result = @task.run("ls")
|
250
|
+
end
|
251
|
+
|
252
|
+
commands = @task.commands
|
253
|
+
|
254
|
+
assert_equal 1, commands.size, 'not enough commands'
|
255
|
+
assert_equal ["ssh", "app.example.com", "sudo bash -cl 'ls'"],
|
256
|
+
commands.first, 'app'
|
257
|
+
assert_equal "file1\nfile2\n", result
|
258
|
+
|
259
|
+
assert_equal "file1\nfile2\n", out
|
260
|
+
assert_equal '', err
|
261
|
+
|
262
|
+
# Reset to false
|
263
|
+
set :prepend_cmd, false
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_run_sudo
|
267
|
+
util_setup_task
|
268
|
+
@task.output << "file1\nfile2\n"
|
269
|
+
@task.error << 'Password:'
|
270
|
+
@task.target_host = "app.example.com"
|
271
|
+
def @task.sudo_password() "my password" end # gets defined by set
|
272
|
+
result = nil
|
273
|
+
|
274
|
+
out, err = capture_io do
|
275
|
+
result = @task.run("sudo ls")
|
276
|
+
end
|
277
|
+
|
278
|
+
commands = @task.commands
|
279
|
+
|
280
|
+
assert_equal 1, commands.size, 'not enough commands'
|
281
|
+
assert_equal ['ssh', 'app.example.com', 'sudo ls'],
|
282
|
+
commands.first
|
283
|
+
|
284
|
+
assert_equal "my password\n", @task.input.string
|
285
|
+
|
286
|
+
# WARN: Technically incorrect, the password line should be
|
287
|
+
# first... this is an artifact of changes to the IO code in run
|
288
|
+
# and the fact that we have a very simplistic (non-blocking)
|
289
|
+
# testing model.
|
290
|
+
assert_equal "file1\nfile2\nPassword:\n", result
|
291
|
+
|
292
|
+
assert_equal "file1\nfile2\n", out
|
293
|
+
assert_equal "Password:\n", err
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_sudo
|
297
|
+
util_setup_task
|
298
|
+
@task.target_host = "app.example.com"
|
299
|
+
@task.sudo "ls"
|
300
|
+
|
301
|
+
commands = @task.commands
|
302
|
+
|
303
|
+
assert_equal 1, commands.size, 'wrong number of commands'
|
304
|
+
assert_equal ["ssh", "app.example.com", "sudo -p Password: ls"],
|
305
|
+
commands.first, 'app'
|
306
|
+
end
|
307
|
+
|
308
|
+
def util_setup_task(options = {})
|
309
|
+
@task = @rake.remote_task :test_task, options
|
310
|
+
@task.commands = []
|
311
|
+
@task.output = []
|
312
|
+
@task.error = []
|
313
|
+
@task.action = nil
|
314
|
+
@task
|
315
|
+
end
|
316
|
+
end
|