capistrano-custom-maintenance 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -47,7 +47,6 @@ Following options are available to manage your maintenance.
47
47
  * `:maintenance_document_path` - the path to the maintenance page on httpd.
48
48
  * `:maintenance_system_path` - the path to the maintenance page.
49
49
  * `:maintenance_template_path` - the path to the maintenance templates.
50
- * `:maintenance_template` - the path to the template of maintenance page.
51
50
  * `:maintenance_input_encoding` - encoding of maintenance page template. use system encoding by default.
52
51
  * `:maintenance_output_encoding` - encoding of result maintenance page. use system encoding by default.
53
52
 
@@ -16,6 +16,11 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Capistrano::CustomMaintenance::VERSION
17
17
 
18
18
  gem.add_dependency("capistrano")
19
+ gem.add_dependency("capistrano-file-resources", ">= 0.1.1")
19
20
  gem.add_dependency("json")
20
21
  gem.add_dependency("mime-types")
22
+ gem.add_development_dependency("capistrano-platform-resources", ">= 0.1.0")
23
+ gem.add_development_dependency("net-scp", "~> 1.0.4")
24
+ gem.add_development_dependency("net-ssh", "~> 2.2.2")
25
+ gem.add_development_dependency("vagrant", "~> 1.0.6")
21
26
  end
@@ -1,8 +1,60 @@
1
- require "capistrano-custom-maintenance/deploy"
2
- require "capistrano-custom-maintenance/version"
1
+ require "capistrano/configuration/resources/file_resources"
2
+ require "erb"
3
+ require "json"
4
+ require "mime/types"
3
5
 
4
6
  module Capistrano
5
7
  module CustomMaintenance
6
- # Your code goes here...
8
+ def self.extended(configuration)
9
+ configuration.load {
10
+ namespace(:maintenance) {
11
+ _cset(:maintenance_template_path, File.expand_path("templates", File.dirname(__FILE__)))
12
+ _cset(:maintenance_content_type, "text/html")
13
+ _cset(:maintenance_suffix) { # suffix of maintenance document. guessed from content-type by default.
14
+ MIME::Types[maintenance_content_type].map { |type| type.extensions }.flatten.first
15
+ }
16
+ _cset(:maintenance_basename, "maintenance")
17
+ _cset(:maintenance_filename) { "#{maintenance_basename}.#{maintenance_suffix}" } # filename of maintenance document, not including path part
18
+ _cset(:maintenance_system_path) { File.join(shared_path, maintenance_document_path) } # actual path
19
+ _cset(:maintenance_document_path) { File.join("/system", maintenance_filename) } # virtual path on httpd
20
+ _cset(:maintenance_timestamp) { Time.now }
21
+ _cset(:maintenance_reason) { ENV.fetch("REASON", "maintenance") }
22
+ _cset(:maintenance_deadline) { ENV.fetch("UNTIL", "shortly") }
23
+
24
+ def template(name, options={})
25
+ reason = fetch(:maintenance_reason)
26
+ deadline = fetch(:maintenance_deadline)
27
+ options = {
28
+ :path => maintenance_template_path,
29
+ :binding => binding,
30
+ }.merge(options)
31
+ options[:external_encoding] = fetch(:maintenance_input_encoding) if exists?(:maintenance_input_encoding)
32
+ result = top.template(name, options)
33
+ exists?(:maintenance_output_encoding) ? result.encode(fetch(:maintenance_output_encoding)) : result
34
+ end
35
+ }
36
+
37
+ namespace(:deploy) {
38
+ namespace(:web) {
39
+ task(:disable, :roles => :web, :except => { :no_release => true }) {
40
+ on_rollback do
41
+ find_and_execute_task("deploy:web:enable")
42
+ end
43
+ top.put(maintenance.template(maintenance_filename), maintenance_system_path, :mode => "644")
44
+ }
45
+
46
+ task(:enable, :roles => :web, :except => { :no_release => true }) {
47
+ run("rm -f #{maintenance_system_path.dump}")
48
+ }
49
+ }
50
+ }
51
+ }
52
+ end
7
53
  end
8
54
  end
55
+
56
+ if Capistrano::Configuration.instance
57
+ Capistrano::Configuration.instance.extend(Capistrano::CustomMaintenance)
58
+ end
59
+
60
+ # vim:set ft=ruby :
@@ -1,5 +1,5 @@
1
1
  module Capistrano
2
2
  module CustomMaintenance
3
- VERSION = "0.0.2"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -0,0 +1,5 @@
1
+ /.bundle
2
+ /.vagrant
3
+ /known_hosts
4
+ /tmp
5
+ /vendor
@@ -0,0 +1,2 @@
1
+ load "deploy"
2
+ load "../config/deploy"
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec(:path => "../..")
@@ -0,0 +1,99 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant::Config.run do |config|
5
+ # All Vagrant configuration is done here. The most common configuration
6
+ # options are documented and commented below. For a complete reference,
7
+ # please see the online documentation at vagrantup.com.
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = "centos6-64"
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ config.vm.box_url = "http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.3-x86_64-v20130101.box"
15
+
16
+ # Boot with a GUI so you can see the screen. (Default is headless)
17
+ # config.vm.boot_mode = :gui
18
+
19
+ # Assign this VM to a host-only network IP, allowing you to access it
20
+ # via the IP. Host-only networks can talk to the host machine as well as
21
+ # any other machines on the same network, but cannot be accessed (through this
22
+ # network interface) by any external networks.
23
+ config.vm.network :hostonly, "192.168.33.10"
24
+
25
+ # Assign this VM to a bridged network, allowing you to connect directly to a
26
+ # network using the host's network device. This makes the VM appear as another
27
+ # physical device on your network.
28
+ # config.vm.network :bridged
29
+
30
+ # Forward a port from the guest to the host, which allows for outside
31
+ # computers to access the VM, whereas host only networking does not.
32
+ # config.vm.forward_port 80, 8080
33
+
34
+ # Share an additional folder to the guest VM. The first argument is
35
+ # an identifier, the second is the path on the guest to mount the
36
+ # folder, and the third is the path on the host to the actual folder.
37
+ # config.vm.share_folder "v-data", "/vagrant_data", "../data"
38
+
39
+ # Enable provisioning with Puppet stand alone. Puppet manifests
40
+ # are contained in a directory path relative to this Vagrantfile.
41
+ # You will need to create the manifests directory and a manifest in
42
+ # the file precise-amd64.pp in the manifests_path directory.
43
+ #
44
+ # An example Puppet manifest to provision the message of the day:
45
+ #
46
+ # # group { "puppet":
47
+ # # ensure => "present",
48
+ # # }
49
+ # #
50
+ # # File { owner => 0, group => 0, mode => 0644 }
51
+ # #
52
+ # # file { '/etc/motd':
53
+ # # content => "Welcome to your Vagrant-built virtual machine!
54
+ # # Managed by Puppet.\n"
55
+ # # }
56
+ #
57
+ # config.vm.provision :puppet do |puppet|
58
+ # puppet.manifests_path = "manifests"
59
+ # puppet.manifest_file = "precise-amd64.pp"
60
+ # end
61
+
62
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
63
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
64
+ # some recipes and/or roles.
65
+ #
66
+ # config.vm.provision :chef_solo do |chef|
67
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
68
+ # chef.roles_path = "../my-recipes/roles"
69
+ # chef.data_bags_path = "../my-recipes/data_bags"
70
+ # chef.add_recipe "mysql"
71
+ # chef.add_role "web"
72
+ #
73
+ # # You may also specify custom JSON attributes:
74
+ # chef.json = { :mysql_password => "foo" }
75
+ # end
76
+
77
+ # Enable provisioning with chef server, specifying the chef server URL,
78
+ # and the path to the validation key (relative to this Vagrantfile).
79
+ #
80
+ # The Opscode Platform uses HTTPS. Substitute your organization for
81
+ # ORGNAME in the URL and validation key.
82
+ #
83
+ # If you have your own Chef Server, use the appropriate URL, which may be
84
+ # HTTP instead of HTTPS depending on your configuration. Also change the
85
+ # validation key to validation.pem.
86
+ #
87
+ # config.vm.provision :chef_client do |chef|
88
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
89
+ # chef.validation_key_path = "ORGNAME-validator.pem"
90
+ # end
91
+ #
92
+ # If you're using the Opscode platform, your validator client is
93
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
94
+ #
95
+ # IF you have your own Chef Server, the default validation client name is
96
+ # chef-validator, unless you changed the configuration.
97
+ #
98
+ # chef.validation_client_name = "ORGNAME-validator"
99
+ end
@@ -0,0 +1,7 @@
1
+ #!/bin/sh -e
2
+
3
+ bundle exec vagrant up
4
+ bundle exec cap test_all
5
+ bundle exec vagrant halt
6
+
7
+ # vim:set ft=sh :
@@ -0,0 +1,337 @@
1
+ set :application, "capistrano-custom-maintenance"
2
+ set :repository, "."
3
+ set :deploy_to do
4
+ File.join("/home", user, application)
5
+ end
6
+ set :deploy_via, :copy
7
+ set :scm, :none
8
+ set :use_sudo, false
9
+ set :user, "vagrant"
10
+ set :password, "vagrant"
11
+ set :ssh_options, {:user_known_hosts_file => "/dev/null"}
12
+
13
+ role :web, "192.168.33.10"
14
+ role :app, "192.168.33.10"
15
+ role :db, "192.168.33.10", :primary => true
16
+
17
+ $LOAD_PATH.push(File.expand_path("../../lib", File.dirname(__FILE__)))
18
+ require "capistrano-custom-maintenance"
19
+ require "capistrano/configuration/resources/platform_resources"
20
+ require "tempfile"
21
+
22
+ def assert_file_exists(file, options={})
23
+ begin
24
+ invoke_command("test -f #{file.dump}", options)
25
+ rescue
26
+ logger.debug("assert_file_exists(#{file}) failed.")
27
+ invoke_command("ls #{File.dirname(file).dump}", options)
28
+ raise
29
+ end
30
+ end
31
+
32
+ def assert_file_not_exists(file, options={})
33
+ begin
34
+ invoke_command("test \! -f #{file.dump}", options)
35
+ rescue
36
+ logger.debug("assert_file_not_exists(#{file}) failed.")
37
+ invoke_command("ls #{File.dirname(file).dump}", options)
38
+ raise
39
+ end
40
+ end
41
+
42
+ def assert_file_content(file, content, options={})
43
+ begin
44
+ tempfile = Tempfile.new("capistrano-custom-maintenance")
45
+ download(file, tempfile.path)
46
+ tempfile.seek(0)
47
+ raise if content != tempfile.read
48
+ rescue
49
+ logger.debug("assert_file_content_type(#{file}, #{content.dump}) failed.")
50
+ raise
51
+ end
52
+ end
53
+
54
+ def assert_file_encoding(file, encoding, options={})
55
+ begin
56
+ invoke_command("test $(nkf -g #{file.dump}) = #{encoding.dump}")
57
+ rescue
58
+ logger.debug("assert_file_encoding(#{file}, #{encoding.dump} failed.")
59
+ raise
60
+ end
61
+ end
62
+
63
+ def assert_command(cmdline, options={})
64
+ begin
65
+ invoke_command(cmdline, options)
66
+ rescue
67
+ logger.debug("assert_command(#{cmdline}) failed.")
68
+ raise
69
+ end
70
+ end
71
+
72
+ def assert_command_fails(cmdline, options={})
73
+ failed = false
74
+ begin
75
+ invoke_command(cmdline, options)
76
+ rescue
77
+ logger.debug("assert_command_fails(#{cmdline}) failed.")
78
+ failed = true
79
+ ensure
80
+ abort unless failed
81
+ end
82
+ end
83
+
84
+ def reset_maintenance!
85
+ variables.each_key do |key|
86
+ reset!(key) if /^maintenance_/ =~ key
87
+ end
88
+ end
89
+
90
+ task(:test_all) {
91
+ find_and_execute_task("test_default")
92
+ find_and_execute_task("test_with_html")
93
+ find_and_execute_task("test_with_javascript")
94
+ find_and_execute_task("test_with_json")
95
+ }
96
+
97
+ on(:start) {
98
+ run("rm -rf #{deploy_to.dump}")
99
+ }
100
+
101
+ namespace(:test_default) {
102
+ task(:default) {
103
+ methods.grep(/^test_/).each do |m|
104
+ send(m)
105
+ end
106
+ }
107
+ before "test_default", "test_default:setup"
108
+ after "test_default", "test_default:teardown"
109
+
110
+ task(:setup) {
111
+ # set(:maintenance_template_path, File.expand_path("tmp/maintenance"))
112
+ set(:maintenance_content_type, "text/html")
113
+ unset(:maintenance_input_encoding)
114
+ unset(:maintenance_output_encoding)
115
+ reset_maintenance!
116
+ find_and_execute_task("deploy:setup")
117
+ find_and_execute_task("deploy")
118
+ }
119
+
120
+ task(:teardown) {
121
+ find_and_execute_task("deploy:web:enable")
122
+ }
123
+
124
+ task(:test_disable_enable) {
125
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.html"))
126
+ find_and_execute_task("deploy:web:disable")
127
+ assert_file_exists(File.join(current_path, "public", "system", "maintenance.html"))
128
+ find_and_execute_task("deploy:web:enable")
129
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.html"))
130
+ }
131
+ }
132
+
133
+ namespace(:test_with_encoding) {
134
+ task(:default) {
135
+ methods.grep(/^test_/).each do |m|
136
+ send(m)
137
+ end
138
+ }
139
+ before "test_with_encoding", "test_with_encoding:setup"
140
+ after "test_with_encoding", "test_with_encoding:teardown"
141
+
142
+ task(:setup) {
143
+ set(:maintenance_template_path, File.expand_path("templates", File.dirname(__FILE__)))
144
+ set(:maintenance_content_type, "text/html")
145
+ unset(:maintenance_input_encoding)
146
+ unset(:maintenance_output_encoding)
147
+ reset_maintenance!
148
+ find_and_execute_task("deploy:setup")
149
+ find_and_execute_task("deploy")
150
+ platform.packages.install("nkf") unless platform.packages.installed?("nkf")
151
+ }
152
+
153
+ task(:teardown) {
154
+ find_and_execute_task("deploy:web:enable")
155
+ }
156
+
157
+ task(:test_with_utf8) {
158
+ set(:maintenance_input_encoding, "utf-8")
159
+ set(:maintenance_output_encoding, "utf-8")
160
+ reset_maintenance!
161
+ find_and_execute_task("deploy:web:disable")
162
+ assert_file_encoding(File.join(current_path, "public", "system", "maintenance.html"), "UTF-8")
163
+ }
164
+
165
+ task(:test_with_eucjp) {
166
+ set(:maintenance_input_encoding, "utf-8")
167
+ set(:maintenance_output_encoding, "euc-jp")
168
+ reset_maintenance!
169
+ find_and_execute_task("deploy:web:disable")
170
+ assert_file_encoding(File.join(current_path, "public", "system", "maintenance.html"), "EUC-JP")
171
+ }
172
+ }
173
+
174
+ def prepare_templates(path, &block)
175
+ run_locally("rm -rf #{path.dump}; mkdir -p #{path.dump}")
176
+ templates = Object.new
177
+ templates.instance_eval { @path = path }
178
+ def templates.create(name, body)
179
+ File.write(File.join(@path, name), body)
180
+ end
181
+ templates.instance_eval(&block)
182
+ # run_locally("rm -rf #{path.dump}")
183
+ end
184
+
185
+ namespace(:test_with_html) {
186
+ task(:default) {
187
+ methods.grep(/^test_/).each do |m|
188
+ send(m)
189
+ end
190
+ }
191
+ before "test_with_html", "test_with_html:setup"
192
+ after "test_with_html", "test_with_html:teardown"
193
+
194
+ task(:setup) {
195
+ set(:maintenance_template_path, File.expand_path("tmp/maintenance"))
196
+ set(:maintenance_content_type, "text/html")
197
+ unset(:maintenance_input_encoding)
198
+ unset(:maintenance_output_encoding)
199
+ reset_maintenance!
200
+ find_and_execute_task("deploy:setup")
201
+ find_and_execute_task("deploy")
202
+ }
203
+
204
+ task(:teardown) {
205
+ find_and_execute_task("deploy:web:enable")
206
+ }
207
+
208
+ task(:test_maintenance_with_erb) {
209
+ reset_maintenance!
210
+ prepare_templates(maintenance_template_path) do
211
+ create("maintenance.html", "html")
212
+ create("maintenance.html.erb", "html.erb")
213
+ end
214
+ find_and_execute_task("deploy:web:disable")
215
+ assert_file_content(File.join(current_path, "public", "system", "maintenance.html"), "html.erb")
216
+ find_and_execute_task("deploy:web:enable")
217
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.html"))
218
+ }
219
+
220
+ task(:test_maintenance_without_erb) {
221
+ reset_maintenance!
222
+ prepare_templates(maintenance_template_path) do
223
+ create("maintenance.html", "html")
224
+ end
225
+ find_and_execute_task("deploy:web:disable")
226
+ assert_file_content(File.join(current_path, "public", "system", "maintenance.html"), "html")
227
+ find_and_execute_task("deploy:web:enable")
228
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.html"))
229
+ }
230
+
231
+ task(:test_maintenance_with_rhtml) {
232
+ reset_maintenance!
233
+ prepare_templates(maintenance_template_path) do
234
+ create("maintenance.rhtml", "rhtml")
235
+ end
236
+ find_and_execute_task("deploy:web:disable")
237
+ assert_file_content(File.join(current_path, "public", "system", "maintenance.html"), "rhtml")
238
+ find_and_execute_task("deploy:web:enable")
239
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.html"))
240
+ }
241
+ }
242
+
243
+ namespace(:test_with_javascript) {
244
+ task(:default) {
245
+ methods.grep(/^test_/).each do |m|
246
+ send(m)
247
+ end
248
+ }
249
+ before "test_with_javascript", "test_with_javascript:setup"
250
+ after "test_with_javascript", "test_with_javascript:teardown"
251
+
252
+ task(:setup) {
253
+ set(:maintenance_template_path, File.expand_path("tmp/maintenance"))
254
+ set(:maintenance_content_type, "application/javascript")
255
+ unset(:maintenance_input_encoding)
256
+ unset(:maintenance_output_encoding)
257
+ reset_maintenance!
258
+ find_and_execute_task("deploy:setup")
259
+ find_and_execute_task("deploy")
260
+ }
261
+
262
+ task(:teardown) {
263
+ find_and_execute_task("deploy:web:enable")
264
+ }
265
+
266
+ task(:test_maintenance_with_erb) {
267
+ reset_maintenance!
268
+ prepare_templates(maintenance_template_path) do
269
+ create("maintenance.js", "js")
270
+ create("maintenance.js.erb", "js.erb")
271
+ end
272
+ find_and_execute_task("deploy:web:disable")
273
+ assert_file_content(File.join(current_path, "public", "system", "maintenance.js"), "js.erb")
274
+ find_and_execute_task("deploy:web:enable")
275
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.js"))
276
+ }
277
+
278
+ task(:test_maintenance_without_erb) {
279
+ reset_maintenance!
280
+ prepare_templates(maintenance_template_path) do
281
+ create("maintenance.js", "js")
282
+ end
283
+ find_and_execute_task("deploy:web:disable")
284
+ assert_file_content(File.join(current_path, "public", "system", "maintenance.js"), "js")
285
+ find_and_execute_task("deploy:web:enable")
286
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.js"))
287
+ }
288
+ }
289
+
290
+ namespace(:test_with_json) {
291
+ task(:default) {
292
+ methods.grep(/^test_/).each do |m|
293
+ send(m)
294
+ end
295
+ }
296
+ before "test_with_json", "test_with_json:setup"
297
+ after "test_with_json", "test_with_json:teardown"
298
+
299
+ task(:setup) {
300
+ set(:maintenance_template_path, File.expand_path("tmp/maintenance"))
301
+ set(:maintenance_content_type, "application/json")
302
+ unset(:maintenance_input_encoding)
303
+ unset(:maintenance_output_encoding)
304
+ reset_maintenance!
305
+ find_and_execute_task("deploy:setup")
306
+ find_and_execute_task("deploy")
307
+ }
308
+
309
+ task(:teardown) {
310
+ find_and_execute_task("deploy:web:enable")
311
+ }
312
+
313
+ task(:test_maintenance_with_erb) {
314
+ reset_maintenance!
315
+ prepare_templates(maintenance_template_path) do
316
+ create("maintenance.json", "json")
317
+ create("maintenance.json.erb", "json.erb")
318
+ end
319
+ find_and_execute_task("deploy:web:disable")
320
+ assert_file_content(File.join(current_path, "public", "system", "maintenance.json"), "json.erb")
321
+ find_and_execute_task("deploy:web:enable")
322
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.json"))
323
+ }
324
+
325
+ task(:test_maintenance_without_erb) {
326
+ reset_maintenance!
327
+ prepare_templates(maintenance_template_path) do
328
+ create("maintenance.json", "json")
329
+ end
330
+ find_and_execute_task("deploy:web:disable")
331
+ assert_file_content(File.join(current_path, "public", "system", "maintenance.json"), "json")
332
+ find_and_execute_task("deploy:web:enable")
333
+ assert_file_not_exists(File.join(current_path, "public", "system", "maintenance.json"))
334
+ }
335
+ }
336
+
337
+ # vim:set ft=ruby sw=2 ts=2 :
@@ -0,0 +1,3 @@
1
+ こんにちは
2
+ こんにちは
3
+ こんにちは
@@ -0,0 +1,5 @@
1
+ /.bundle
2
+ /.vagrant
3
+ /known_hosts
4
+ /tmp
5
+ /vendor
@@ -0,0 +1,2 @@
1
+ load "deploy"
2
+ load "../config/deploy"
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec(:path => "../..")
@@ -0,0 +1,99 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant::Config.run do |config|
5
+ # All Vagrant configuration is done here. The most common configuration
6
+ # options are documented and commented below. For a complete reference,
7
+ # please see the online documentation at vagrantup.com.
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = "precise64"
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
15
+
16
+ # Boot with a GUI so you can see the screen. (Default is headless)
17
+ # config.vm.boot_mode = :gui
18
+
19
+ # Assign this VM to a host-only network IP, allowing you to access it
20
+ # via the IP. Host-only networks can talk to the host machine as well as
21
+ # any other machines on the same network, but cannot be accessed (through this
22
+ # network interface) by any external networks.
23
+ config.vm.network :hostonly, "192.168.33.10"
24
+
25
+ # Assign this VM to a bridged network, allowing you to connect directly to a
26
+ # network using the host's network device. This makes the VM appear as another
27
+ # physical device on your network.
28
+ # config.vm.network :bridged
29
+
30
+ # Forward a port from the guest to the host, which allows for outside
31
+ # computers to access the VM, whereas host only networking does not.
32
+ # config.vm.forward_port 80, 8080
33
+
34
+ # Share an additional folder to the guest VM. The first argument is
35
+ # an identifier, the second is the path on the guest to mount the
36
+ # folder, and the third is the path on the host to the actual folder.
37
+ # config.vm.share_folder "v-data", "/vagrant_data", "../data"
38
+
39
+ # Enable provisioning with Puppet stand alone. Puppet manifests
40
+ # are contained in a directory path relative to this Vagrantfile.
41
+ # You will need to create the manifests directory and a manifest in
42
+ # the file precise-amd64.pp in the manifests_path directory.
43
+ #
44
+ # An example Puppet manifest to provision the message of the day:
45
+ #
46
+ # # group { "puppet":
47
+ # # ensure => "present",
48
+ # # }
49
+ # #
50
+ # # File { owner => 0, group => 0, mode => 0644 }
51
+ # #
52
+ # # file { '/etc/motd':
53
+ # # content => "Welcome to your Vagrant-built virtual machine!
54
+ # # Managed by Puppet.\n"
55
+ # # }
56
+ #
57
+ # config.vm.provision :puppet do |puppet|
58
+ # puppet.manifests_path = "manifests"
59
+ # puppet.manifest_file = "precise-amd64.pp"
60
+ # end
61
+
62
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
63
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
64
+ # some recipes and/or roles.
65
+ #
66
+ # config.vm.provision :chef_solo do |chef|
67
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
68
+ # chef.roles_path = "../my-recipes/roles"
69
+ # chef.data_bags_path = "../my-recipes/data_bags"
70
+ # chef.add_recipe "mysql"
71
+ # chef.add_role "web"
72
+ #
73
+ # # You may also specify custom JSON attributes:
74
+ # chef.json = { :mysql_password => "foo" }
75
+ # end
76
+
77
+ # Enable provisioning with chef server, specifying the chef server URL,
78
+ # and the path to the validation key (relative to this Vagrantfile).
79
+ #
80
+ # The Opscode Platform uses HTTPS. Substitute your organization for
81
+ # ORGNAME in the URL and validation key.
82
+ #
83
+ # If you have your own Chef Server, use the appropriate URL, which may be
84
+ # HTTP instead of HTTPS depending on your configuration. Also change the
85
+ # validation key to validation.pem.
86
+ #
87
+ # config.vm.provision :chef_client do |chef|
88
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
89
+ # chef.validation_key_path = "ORGNAME-validator.pem"
90
+ # end
91
+ #
92
+ # If you're using the Opscode platform, your validator client is
93
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
94
+ #
95
+ # IF you have your own Chef Server, the default validation client name is
96
+ # chef-validator, unless you changed the configuration.
97
+ #
98
+ # chef.validation_client_name = "ORGNAME-validator"
99
+ end
@@ -0,0 +1,7 @@
1
+ #!/bin/sh -e
2
+
3
+ bundle exec vagrant up
4
+ bundle exec cap test_all
5
+ bundle exec vagrant halt
6
+
7
+ # vim:set ft=sh :
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-custom-maintenance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-04 00:00:00.000000000 Z
12
+ date: 2013-03-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: capistrano-file-resources
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.1.1
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.1.1
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: json
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -59,6 +75,70 @@ dependencies:
59
75
  - - ! '>='
60
76
  - !ruby/object:Gem::Version
61
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: capistrano-platform-resources
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 0.1.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 0.1.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: net-scp
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.0.4
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.0.4
110
+ - !ruby/object:Gem::Dependency
111
+ name: net-ssh
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 2.2.2
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 2.2.2
126
+ - !ruby/object:Gem::Dependency
127
+ name: vagrant
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 1.0.6
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 1.0.6
62
142
  description: a customizable capistrano maintenance recipe.
63
143
  email:
64
144
  - yamashita@geishatokyo.com
@@ -73,10 +153,21 @@ files:
73
153
  - Rakefile
74
154
  - capistrano-custom-maintenance.gemspec
75
155
  - lib/capistrano-custom-maintenance.rb
76
- - lib/capistrano-custom-maintenance/deploy.rb
77
- - lib/capistrano-custom-maintenance/templates/maintenance.html.erb
78
- - lib/capistrano-custom-maintenance/templates/maintenance.json.erb
79
156
  - lib/capistrano-custom-maintenance/version.rb
157
+ - lib/templates/maintenance.html.erb
158
+ - lib/templates/maintenance.json.erb
159
+ - test/centos6-64/.gitignore
160
+ - test/centos6-64/Capfile
161
+ - test/centos6-64/Gemfile
162
+ - test/centos6-64/Vagrantfile
163
+ - test/centos6-64/run.sh
164
+ - test/config/deploy.rb
165
+ - test/config/templates/maintenance.html.erb
166
+ - test/precise64/.gitignore
167
+ - test/precise64/Capfile
168
+ - test/precise64/Gemfile
169
+ - test/precise64/Vagrantfile
170
+ - test/precise64/run.sh
80
171
  homepage: https://github.com/yyuu/capistrano-custom-maintenance
81
172
  licenses: []
82
173
  post_install_message:
@@ -101,4 +192,16 @@ rubygems_version: 1.8.23
101
192
  signing_key:
102
193
  specification_version: 3
103
194
  summary: a customizable capistrano maintenance recipe.
104
- test_files: []
195
+ test_files:
196
+ - test/centos6-64/.gitignore
197
+ - test/centos6-64/Capfile
198
+ - test/centos6-64/Gemfile
199
+ - test/centos6-64/Vagrantfile
200
+ - test/centos6-64/run.sh
201
+ - test/config/deploy.rb
202
+ - test/config/templates/maintenance.html.erb
203
+ - test/precise64/.gitignore
204
+ - test/precise64/Capfile
205
+ - test/precise64/Gemfile
206
+ - test/precise64/Vagrantfile
207
+ - test/precise64/run.sh
@@ -1,91 +0,0 @@
1
-
2
- require 'erb'
3
- require 'json'
4
- require 'mime/types'
5
-
6
- module Capistrano
7
- module CustomMaintenance
8
- def self.extended(configuration)
9
- configuration.load {
10
- namespace(:deploy) {
11
- _cset(:maintenance_template_path, File.dirname(__FILE__), 'templates')
12
- _cset(:maintenance_template) {
13
- ts = [
14
- File.join(maintenance_template_path, "#{maintenance_basename}.#{maintenance_suffix}.erb"),
15
- File.join(maintenance_template_path, "#{maintenance_basename}.erb"),
16
- ]
17
- ts << File.join(maintenance_template_path, "#{maintenance_basename}.rhtml") if maintenance_suffix == 'html'
18
- xs = ts.select { |t| File.exist?(t) }
19
- unless xs.empty?
20
- xs.first
21
- else
22
- abort("No such template found: #{ts.join(', ')}")
23
- end
24
- }
25
- _cset(:maintenance_content_type, 'text/html')
26
- _cset(:maintenance_suffix) { # suffix of maintenance document. guessed from content-type by default.
27
- type, = MIME::Types[maintenance_content_type]
28
- type.extensions.first
29
- }
30
- _cset(:maintenance_filename) { # filename of maintenance document, not including path part
31
- "#{maintenance_basename}.#{maintenance_suffix}"
32
- }
33
- _cset(:maintenance_system_path) { # actual path
34
- File.join(shared_path, maintenance_document_path)
35
- }
36
- _cset(:maintenance_document_path) { # virtual path on httpd
37
- File.join('/system', maintenance_filename)
38
- }
39
-
40
- _cset(:maintenance_timestamp) {
41
- Time.now
42
- }
43
- _cset(:maintenance_reason) {
44
- ENV.fetch('REASON', "maintenance")
45
- }
46
- _cset(:maintenance_deadline) {
47
- ENV.fetch('UNTIL', "shortly")
48
- }
49
-
50
- namespace(:web) {
51
- task(:disable, :roles => :web, :except => { :no_release => true }) {
52
- on_rollback {
53
- run("rm -f #{maintenance_system_path}")
54
- }
55
-
56
- reason = maintenance_reason
57
- deadline = maintenance_deadline
58
-
59
- begin
60
- ic = fetch(:maintenance_input_encoding, nil)
61
- template = File.read(maintenance_template, :external_encoding => ic)
62
- rescue
63
- template = File.read(maintenance_template)
64
- end
65
-
66
- _result = ERB.new(template).result(binding)
67
- begin
68
- oc = fetch(:maintenance_output_encoding, nil)
69
- result = oc ? _result.encode(oc) : _result
70
- rescue
71
- result = _result
72
- end
73
-
74
- put(result, maintenance_system_path, :mode => 0644)
75
- }
76
-
77
- task(:enable, :roles => :web, :except => { :no_release => true }) {
78
- run("rm -f #{maintenance_system_path}")
79
- }
80
- }
81
- }
82
- }
83
- end
84
- end
85
- end
86
-
87
- if Capistrano::Configuration.instance
88
- Capistrano::Configuration.instance.extend(Capistrano::CustomMaintenance)
89
- end
90
-
91
- # vim:set ft=ruby :