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.
@@ -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