yad 0.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/.gitignore +9 -0
- data/LICENSE +20 -0
- data/README.rdoc +110 -0
- data/Rakefile +87 -0
- data/VERSION.yml +4 -0
- data/doc/faq.rdoc +9 -0
- data/features/step_definitions/yad_steps.rb +0 -0
- data/features/support/env.rb +9 -0
- data/features/yad.feature +9 -0
- data/lib/ext/rake.rb +66 -0
- data/lib/ext/rake/remote_task.rb +521 -0
- data/lib/ext/string.rb +6 -0
- data/lib/yad.rb +46 -0
- data/lib/yad/app/passenger.rb +28 -0
- data/lib/yad/core.rb +199 -0
- data/lib/yad/db/rails.rb +62 -0
- data/lib/yad/framework/rails.rb +64 -0
- data/lib/yad/maintenance/shared_system.rb +39 -0
- data/lib/yad/scm/git.rb +62 -0
- data/lib/yad/web/apache.rb +62 -0
- data/spec/ext/rake/remote_task_spec.rb +394 -0
- data/spec/spec_helper.rb +79 -0
- data/spec/yad/app/passenger_spec.rb +10 -0
- data/spec/yad/core_spec.rb +69 -0
- data/spec/yad/db/rails_spec.rb +15 -0
- data/spec/yad/framework/rails_spec.rb +25 -0
- data/spec/yad/maintenance/shared_system_spec.rb +15 -0
- data/spec/yad/scm/git_spec.rb +30 -0
- data/spec/yad/web/apache_spec.rb +25 -0
- data/yad.gemspec +87 -0
- metadata +132 -0
data/lib/yad/scm/git.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module Yad
|
2
|
+
module Scm
|
3
|
+
class Git
|
4
|
+
def self.build_checkout_command(repository, destination_directory, options = {})
|
5
|
+
default_options = { :revision => 'origin/master', :enable_submodules => true }
|
6
|
+
options = default_options.merge(options)
|
7
|
+
|
8
|
+
commands = ["([ -d #{destination_directory}/cached-copy/.git ] && echo 'Existing repository found' || git clone #{repository} #{destination_directory}/cached-copy)",
|
9
|
+
"cd #{destination_directory}/cached-copy",
|
10
|
+
"git fetch",
|
11
|
+
"git reset --hard #{options[:revision]}"
|
12
|
+
]
|
13
|
+
|
14
|
+
if options[:enable_submodules]
|
15
|
+
commands << [ "git submodule -q init",
|
16
|
+
"git submodule -q update"
|
17
|
+
]
|
18
|
+
end
|
19
|
+
commands.join(" && ")
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.build_export_command(source_directory, destination_directory)
|
23
|
+
"mkdir -p #{destination_directory} && rsync -a -f '- .git' #{source_directory}/cached-copy/ #{destination_directory}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.build_inline_revision_identifier_command(scm_directory, options = {})
|
27
|
+
default_options = { :revision => 'origin/master' }
|
28
|
+
options = default_options.merge(options)
|
29
|
+
"`cd #{scm_directory}/cached-copy && git rev-parse #{options[:revision]}`"
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.define_tasks
|
33
|
+
return if @tasks_already_defined
|
34
|
+
@tasks_already_defined = true
|
35
|
+
namespace :yad do
|
36
|
+
namespace :scm do
|
37
|
+
|
38
|
+
desc "Updates the source code on the application servers and exports it as the latest release"
|
39
|
+
remote_task :update, :roles => :app do
|
40
|
+
begin
|
41
|
+
options = Rake::RemoteTask.get_options_hash(:revision, :enable_submodules)
|
42
|
+
checkout_command = Yad::Scm::Git.build_checkout_command(repository, scm_path, options)
|
43
|
+
export_command = Yad::Scm::Git.build_export_command(scm_path, release_path)
|
44
|
+
cmd = Yad::Core.build_update_source_code_command(checkout_command, export_command, release_path)
|
45
|
+
run(cmd)
|
46
|
+
puts("source code updated on #{target_host}")
|
47
|
+
rescue => e
|
48
|
+
cmd = Yad::Core.build_remove_directory_command(release_path)
|
49
|
+
run(cmd)
|
50
|
+
raise e
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end # class Git
|
60
|
+
|
61
|
+
end # module Scm
|
62
|
+
end # module Yad
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Yad
|
2
|
+
module Web
|
3
|
+
class Apache
|
4
|
+
def self.build_start_command(options = {})
|
5
|
+
default_options = { :apache_command => 'apachectl' }
|
6
|
+
options = default_options.merge(options)
|
7
|
+
"#{options[:apache_command]} start"
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.build_stop_command(options = {})
|
11
|
+
default_options = { :apache_command => 'apachectl' }
|
12
|
+
options = default_options.merge(options)
|
13
|
+
"#{options[:apache_command]} stop"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.build_restart_command(options = {})
|
17
|
+
default_options = { :apache_command => 'apachectl' }
|
18
|
+
options = default_options.merge(options)
|
19
|
+
"#{options[:apache_command]} restart"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.define_tasks
|
23
|
+
return if @tasks_already_defined
|
24
|
+
@tasks_already_defined = true
|
25
|
+
namespace :yad do
|
26
|
+
namespace :web do
|
27
|
+
|
28
|
+
desc "Starts the web server"
|
29
|
+
remote_task :start, :roles => :web do
|
30
|
+
options = Rake::RemoteTask.get_options_hash(:apache_command)
|
31
|
+
cmd = Yad::Web::Apache.build_start_command(options)
|
32
|
+
use_sudo_for_apache = Rake::RemoteTask.fetch(:use_sudo_for_apache, true)
|
33
|
+
if use_sudo_for_apache
|
34
|
+
sudo(cmd)
|
35
|
+
else
|
36
|
+
run(cmd)
|
37
|
+
end
|
38
|
+
puts("Apache started on #{target_host}")
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Stops the web server"
|
42
|
+
remote_task :stop, :roles => :web do
|
43
|
+
options = Rake::RemoteTask.get_options_hash(:apache_command)
|
44
|
+
cmd = Yad::Web::Apache.build_stop_command(options)
|
45
|
+
use_sudo_for_apache = Rake::RemoteTask.fetch(:use_sudo_for_apache, true)
|
46
|
+
if use_sudo_for_apache
|
47
|
+
sudo(cmd)
|
48
|
+
else
|
49
|
+
run(cmd)
|
50
|
+
end
|
51
|
+
puts("Apache stopped on #{target_host}")
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end # class Apache
|
60
|
+
|
61
|
+
end # module Web
|
62
|
+
end # module Yad
|
@@ -0,0 +1,394 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Rake::RemoteTask do
|
4
|
+
def create_example_task(options = {})
|
5
|
+
task = Rake::RemoteTask.remote_task(:test_task, options)
|
6
|
+
task.commands = []
|
7
|
+
task.output = []
|
8
|
+
task.error = []
|
9
|
+
task.action = nil
|
10
|
+
task
|
11
|
+
end
|
12
|
+
|
13
|
+
def capture_output
|
14
|
+
require 'stringio'
|
15
|
+
orig_stdout = $stdout.dup
|
16
|
+
orig_stderr = $stderr.dup
|
17
|
+
captured_stdout = StringIO.new
|
18
|
+
captured_stderr = StringIO.new
|
19
|
+
$stdout = captured_stdout
|
20
|
+
$stderr = captured_stderr
|
21
|
+
yield
|
22
|
+
captured_stdout.rewind
|
23
|
+
captured_stderr.rewind
|
24
|
+
return captured_stdout, captured_stderr
|
25
|
+
ensure
|
26
|
+
$stdout = orig_stdout
|
27
|
+
$stderr = orig_stderr
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should list all remote hosts" do
|
31
|
+
set_example_hosts
|
32
|
+
Rake::RemoteTask.all_hosts.should eql(%w[app.example.com db.example.com])
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should fetch variables that have been set" do
|
36
|
+
set :foo, 5
|
37
|
+
Rake::RemoteTask.fetch(:foo).should eql(5)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should fetch the given default when a variable is not set" do
|
41
|
+
Rake::RemoteTask.fetch(:not_here, 5).should eql(5)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should assign multiple roles to one remote host" do
|
45
|
+
Rake::RemoteTask.host "test.example.com", :app, :db
|
46
|
+
Rake::RemoteTask.roles[:app].should == { "test.example.com" => {} }
|
47
|
+
Rake::RemoteTask.roles[:db].should == { "test.example.com" => {} }
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should error when the host name is invalid" do
|
51
|
+
lambda { Rake::RemoteTask.host nil, :web }.should raise_error(ArgumentError)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should assign multiple roles to multiple remote hosts" do
|
55
|
+
Rake::RemoteTask.host "test.example.com", :app, :db
|
56
|
+
Rake::RemoteTask.host "yarr.example.com", :app, :db, :no_release => true
|
57
|
+
|
58
|
+
expected = {
|
59
|
+
"test.example.com" => {},
|
60
|
+
"yarr.example.com" => {:no_release => true}
|
61
|
+
}
|
62
|
+
|
63
|
+
Rake::RemoteTask.roles[:app].should == expected
|
64
|
+
Rake::RemoteTask.roles[:db].should == expected
|
65
|
+
Rake::RemoteTask.roles[:app]["test.example.com"].object_id.should_not eql(Rake::RemoteTask.roles[:db]["test.example.com"].object_id)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should get remote hosts for an array of roles" do
|
69
|
+
set_example_hosts
|
70
|
+
Rake::RemoteTask.hosts_for([:app, :db]).should eql(%w[app.example.com db.example.com])
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should get remote hosts for one role" do
|
74
|
+
set_example_hosts
|
75
|
+
Rake::RemoteTask.host "app2.example.com", :app
|
76
|
+
Rake::RemoteTask.hosts_for(:app).should eql(%w[app.example.com app2.example.com])
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should get remote hosts for multiple roles" do
|
80
|
+
set_example_hosts
|
81
|
+
Rake::RemoteTask.hosts_for(:app, :db).should eql(%w[app.example.com db.example.com])
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should get a unique list of remote hosts for given roles" do
|
85
|
+
set_example_hosts
|
86
|
+
Rake::RemoteTask.host "app.example.com", :web
|
87
|
+
Rake::RemoteTask.hosts_for(:app, :db, :web).should eql(%w[app.example.com db.example.com])
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should not set defaults for required configuration variables" do
|
91
|
+
Rake::RemoteTask.set_defaults
|
92
|
+
lambda { Rake::RemoteTask.repository }.should raise_error(Rake::RemoteTask::ConfigurationError)
|
93
|
+
lambda { Rake::RemoteTask.deploy_to }.should raise_error(Rake::RemoteTask::ConfigurationError)
|
94
|
+
lambda { Rake::RemoteTask.domain }.should raise_error(Rake::RemoteTask::ConfigurationError)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should assign a role for one remote host" do
|
98
|
+
Rake::RemoteTask.role :app, "test.example.com"
|
99
|
+
Rake::RemoteTask.roles[:app].should == { "test.example.com" => {} }
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should assign a role for multiple remote hosts" do
|
103
|
+
Rake::RemoteTask.role :app, "test.example.com", :primary => true
|
104
|
+
Rake::RemoteTask.role :db, "yarr.example.com", :no_release => true
|
105
|
+
Rake::RemoteTask.roles[:db].should == { "yarr.example.com" => { :no_release => true } }
|
106
|
+
Rake::RemoteTask.roles[:app].should == { "test.example.com" => { :primary => true } }
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should increase the number of tasks when created" do
|
110
|
+
task = Rake::RemoteTask.remote_task(:test_task) { 5 }
|
111
|
+
Rake.application.tasks.size.should eql(@task_count + 1)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should assign an empty set of roles if none are supplied" do
|
115
|
+
task = Rake::RemoteTask.remote_task(:test_task) { 5 }
|
116
|
+
task.options.should == { :roles => [] }
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should assign all remote hosts to a task by default" do
|
120
|
+
set_example_hosts
|
121
|
+
task = Rake::RemoteTask.remote_task(:test_task) { 5 }
|
122
|
+
task.target_hosts.should eql(%w[app.example.com db.example.com])
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should override hosts from environment" do
|
126
|
+
old_env_hosts = ENV["HOSTS"]
|
127
|
+
ENV["HOSTS"] = 'other1.example.com, other2.example.com'
|
128
|
+
set_example_hosts
|
129
|
+
task = Rake::RemoteTask.remote_task(:test_task) { 5 }
|
130
|
+
task.target_hosts.should eql(%w[other1.example.com other2.example.com])
|
131
|
+
ENV["HOSTS"] = old_env_hosts
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should have access set variables within task body" do
|
135
|
+
set(:some_variable, 5)
|
136
|
+
Rake::RemoteTask.host 'www.example.com', :app
|
137
|
+
Rake::RemoteTask.remote_task(:some_task) do $some_task_result = some_variable end
|
138
|
+
Rake::Task['some_task'].execute nil
|
139
|
+
Rake::RemoteTask.fetch(:some_variable).should eql($some_task_result)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should assign roles when creating a task" do
|
143
|
+
task = Rake::RemoteTask.remote_task :test_task, :roles => [:app, :db] do
|
144
|
+
fail "should not run"
|
145
|
+
end
|
146
|
+
task.options.should == { :roles => [:app, :db] }
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should allow hosts to be assigned to a role after a task for a role has been created" do
|
150
|
+
task = Rake::RemoteTask.remote_task :test_task, :roles => :web do 5 end
|
151
|
+
Rake::RemoteTask.host 'www.example.com', :web
|
152
|
+
task.target_hosts.should eql(%w[www.example.com])
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should allow for roles to be overridden" do
|
156
|
+
host "db1", :db
|
157
|
+
host "db2", :db
|
158
|
+
host "db3", :db
|
159
|
+
host "master", :master_db
|
160
|
+
|
161
|
+
remote_task(:migrate_the_db, :roles => [:db]) { fail "bad!" }
|
162
|
+
task = Rake::Task["migrate_the_db"]
|
163
|
+
task.target_hosts.should eql(%w[db1 db2 db3])
|
164
|
+
|
165
|
+
task.options[:roles] = :master_db
|
166
|
+
task.target_hosts.should eql(%w[master])
|
167
|
+
|
168
|
+
task.options[:roles] = [:master_db]
|
169
|
+
task.target_hosts.should eql(%w[master])
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should set variables" do
|
173
|
+
set :test, 5
|
174
|
+
Rake::RemoteTask.test.should eql(5)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should do lazy evaluation of set blocks" do
|
178
|
+
set(:test) { fail "lose" }
|
179
|
+
lambda { Rake::RemoteTask.test }.should raise_error(RuntimeError)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should evaluate a set block the first time" do
|
183
|
+
x = 1
|
184
|
+
set(:test) { x += 2 }
|
185
|
+
Rake::RemoteTask.test.should eql(3)
|
186
|
+
Rake::RemoteTask.test.should eql(3)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should have access to set variables within set blocks" do
|
190
|
+
Rake::RemoteTask.instance_eval do
|
191
|
+
set(:var_one) { var_two }
|
192
|
+
set(:var_two) { var_three }
|
193
|
+
set(:var_three) { 5 }
|
194
|
+
end
|
195
|
+
|
196
|
+
Rake::RemoteTask.var_one.should eql(5)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should error when a value and a block is supplied with set" do
|
200
|
+
lambda { set(:test, 5) { 6 } }.should raise_error(ArgumentError, "cannot provide both a value and a block")
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should allow a variable to be set to nil" do
|
204
|
+
set(:test, nil)
|
205
|
+
Rake::RemoteTask.test.should be_nil
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should not allow variables with reserved names to be set" do
|
209
|
+
$TESTING = false
|
210
|
+
lambda { set(:all_hosts, []) }.should raise_error(ArgumentError, "cannot set reserved name: 'all_hosts'")
|
211
|
+
$TESTING = true
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should allow a variable to be set to false" do
|
215
|
+
set(:can_set_nil, nil)
|
216
|
+
set(:lies_are, false)
|
217
|
+
|
218
|
+
Rake::RemoteTask.can_set_nil.should be_nil
|
219
|
+
Rake::RemoteTask.lies_are.should be_false
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should fetch false as a default for a variable" do
|
223
|
+
Rake::RemoteTask.fetch(:unknown, false).should be_false
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should be enhanced with prerequisites and actions when it has been created with a body" do
|
227
|
+
set_example_hosts
|
228
|
+
body = Proc.new { 5 }
|
229
|
+
task = Rake::RemoteTask.remote_task(:some_task => :foo, &body)
|
230
|
+
action = Rake::RemoteTask::Action.new(task, body)
|
231
|
+
task.remote_actions.should == [action]
|
232
|
+
action.task.should eql(task)
|
233
|
+
task.prerequisites.should eql(["foo"])
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should not be enhanced with prerequisites or actions when it has been created without a body" do
|
237
|
+
set_example_hosts
|
238
|
+
task = create_example_task
|
239
|
+
task.remote_actions.should be_empty
|
240
|
+
task.prerequisites.should be_empty
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should execute on all remote hosts when no role is given" do
|
244
|
+
set_example_hosts
|
245
|
+
set :some_variable, 1
|
246
|
+
x = 5
|
247
|
+
task = Rake::RemoteTask.remote_task(:some_task) { x += some_variable }
|
248
|
+
task.execute nil
|
249
|
+
task.some_variable.should eql(1)
|
250
|
+
x.should eql(7)
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should allow variables to be set inside of the body" do
|
254
|
+
host "app.example.com", :app
|
255
|
+
task = Rake::RemoteTask.remote_task(:target_task) { set(:test_target_host, target_host) }
|
256
|
+
task.execute nil
|
257
|
+
Rake::RemoteTask.fetch(:test_target_host).should eql("app.example.com")
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should not excute with no remote hosts set" do
|
261
|
+
Rake::RemoteTask.host "app.example.com", :app
|
262
|
+
task = Rake::RemoteTask.remote_task(:flunk, :roles => :db) { fail "should not have run" }
|
263
|
+
lambda { task.execute nil }.should raise_error(Rake::RemoteTask::ConfigurationError,
|
264
|
+
"No target hosts specified on task flunk for roles [:db]")
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should not execute with no remote hosts for a given role" do
|
268
|
+
task = Rake::RemoteTask.remote_task(:flunk, :roles => :junk) { fail "should not have run" }
|
269
|
+
lambda { task.execute nil }.should raise_error(Rake::RemoteTask::ConfigurationError,
|
270
|
+
"No target hosts specified on task flunk for roles [:junk]")
|
271
|
+
end
|
272
|
+
|
273
|
+
it "should execute on remote hosts with a given role" do
|
274
|
+
set_example_hosts
|
275
|
+
set :some_variable, 1
|
276
|
+
x = 5
|
277
|
+
task = Rake::RemoteTask.remote_task(:some_task, :roles => :db) { x += some_variable }
|
278
|
+
task.execute nil
|
279
|
+
task.some_variable.should eql(1)
|
280
|
+
x.should eql(6)
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should build rsync commands" do
|
284
|
+
task = create_example_task
|
285
|
+
task.rsync 'localfile', 'app.example.com:remotefile'
|
286
|
+
task.commands.size.should eql(1)
|
287
|
+
task.commands.first.should eql(%w[rsync -azP --delete localfile app.example.com:remotefile])
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should error when an rsync command fails" do
|
291
|
+
task = create_example_task
|
292
|
+
task.action = lambda { false }
|
293
|
+
lambda { task.rsync 'local', 'app.example.com:remote' }.should raise_error(Rake::RemoteTask::CommandFailedError,
|
294
|
+
"execution failed: rsync -azP --delete local app.example.com:remote")
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should build get commands" do
|
298
|
+
task = create_example_task
|
299
|
+
task.target_host = 'app.example.com'
|
300
|
+
lambda { task.get('tmp', 'remote1', 'remote2') }.should_not raise_error
|
301
|
+
task.commands.size.should eql(1)
|
302
|
+
task.commands.first.should eql(%w[rsync -azP --delete app.example.com:remote1 app.example.com:remote2 tmp])
|
303
|
+
end
|
304
|
+
|
305
|
+
it "should build put commands" do
|
306
|
+
task = create_example_task
|
307
|
+
task.target_host = 'app.example.com'
|
308
|
+
lambda { task.put('dest') { 'whatever' } }.should_not raise_error
|
309
|
+
task.commands.size.should eql(1)
|
310
|
+
task.commands.first[3] = 'some_temp_file_name'
|
311
|
+
task.commands.first.should eql( %w[rsync -azP --delete some_temp_file_name app.example.com:dest])
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should run remote commands" do
|
315
|
+
task = create_example_task
|
316
|
+
task.output << "file1\nfile2\n"
|
317
|
+
task.target_host = "app.example.com"
|
318
|
+
result = nil
|
319
|
+
|
320
|
+
out, err = capture_output do
|
321
|
+
result = task.run("ls")
|
322
|
+
end
|
323
|
+
|
324
|
+
task.commands.size.should eql(1)
|
325
|
+
task.commands.first.should eql(["ssh", "app.example.com", "ls"])
|
326
|
+
|
327
|
+
result.should eql("file1\nfile2\n")
|
328
|
+
out.read.should eql("file1\nfile2\n")
|
329
|
+
err.read.should eql('')
|
330
|
+
end
|
331
|
+
|
332
|
+
it "should error when a remote command fails" do
|
333
|
+
set_example_hosts
|
334
|
+
task = create_example_task
|
335
|
+
task.input = StringIO.new "file1\nfile2\n"
|
336
|
+
task.target_host = 'app.example.com'
|
337
|
+
task.action = lambda { 1 }
|
338
|
+
lambda { task.run("ls") }.should raise_error(Rake::RemoteTask::CommandFailedError,
|
339
|
+
"execution failed with status 1: ssh app.example.com ls")
|
340
|
+
task.commands.size.should eql(1)
|
341
|
+
end
|
342
|
+
|
343
|
+
it "should build remote sudo commands" do
|
344
|
+
task = create_example_task
|
345
|
+
task.target_host = "app.example.com"
|
346
|
+
task.sudo "ls"
|
347
|
+
task.commands.size.should eql(1)
|
348
|
+
task.commands.first.should eql(["ssh", "app.example.com", "sudo -p Password: ls"])
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should run remote sudo commands" do
|
352
|
+
task = create_example_task
|
353
|
+
task.output << "file1\nfile2\n"
|
354
|
+
task.error << 'Password:'
|
355
|
+
task.target_host = "app.example.com"
|
356
|
+
def task.sudo_password() "my password" end # gets defined by set
|
357
|
+
result = nil
|
358
|
+
|
359
|
+
out, err = capture_output do
|
360
|
+
result = task.run("sudo ls")
|
361
|
+
end
|
362
|
+
|
363
|
+
task.commands.size.should eql(1)
|
364
|
+
task.commands.first.should eql(['ssh', 'app.example.com', 'sudo ls'])
|
365
|
+
task.input.string.should eql("my password\n")
|
366
|
+
|
367
|
+
# WARN: Technically incorrect, the password line should be
|
368
|
+
# first... this is an artifact of changes to the IO code in run
|
369
|
+
# and the fact that we have a very simplistic (non-blocking)
|
370
|
+
# testing model.
|
371
|
+
result.should eql("file1\nfile2\nPassword:\n")
|
372
|
+
out.read.should eql("file1\nfile2\n")
|
373
|
+
err.read.should eql("Password:\n")
|
374
|
+
end
|
375
|
+
|
376
|
+
it "should get an options hash for a single option" do
|
377
|
+
set :my_option, 10
|
378
|
+
options = Rake::RemoteTask.get_options_hash(:my_option)
|
379
|
+
options.should ==({ :my_option => 10 })
|
380
|
+
end
|
381
|
+
|
382
|
+
it "should get an options hash for multiple options" do
|
383
|
+
set :my_option, 10
|
384
|
+
set :my_other_option, 'my other option value'
|
385
|
+
options = Rake::RemoteTask.get_options_hash(:my_option, :my_other_option)
|
386
|
+
options.should ==({ :my_option => 10, :my_other_option => 'my other option value' })
|
387
|
+
end
|
388
|
+
|
389
|
+
it "should an empty options hash for an undefined option" do
|
390
|
+
options = Rake::RemoteTask.get_options_hash(:my_undefined_option)
|
391
|
+
options.should ==({})
|
392
|
+
end
|
393
|
+
|
394
|
+
end
|