isst-vlad 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -0,0 +1,8 @@
1
+ require 'vlad'
2
+
3
+ namespace :vlad do
4
+ desc 'Restart Passenger'
5
+ remote_task :start_app, :roles => :app do
6
+ run "touch #{current_release}/tmp/restart.txt"
7
+ end
8
+ end
@@ -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
@@ -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
@@ -0,0 +1,7 @@
1
+ namespace :vlad do
2
+ set :rack_env, "production"
3
+ set :mkdirs, %w(tmp db)
4
+ set :shared_paths, {
5
+ 'log' => 'log',
6
+ }
7
+ end
@@ -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
+
@@ -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