capistrano-custom-maintenance 0.0.2 → 0.1.0

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/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
@@ -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 :
OSZAR »