capistrano-mb 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +114 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +173 -0
  7. data/Rakefile +5 -0
  8. data/capistrano-mb.gemspec +34 -0
  9. data/lib/capistrano/fiftyfive.rb +6 -0
  10. data/lib/capistrano/mb.rb +29 -0
  11. data/lib/capistrano/mb/compatibility.rb +17 -0
  12. data/lib/capistrano/mb/dsl.rb +187 -0
  13. data/lib/capistrano/mb/recipe.rb +48 -0
  14. data/lib/capistrano/mb/templates/crontab.erb +1 -0
  15. data/lib/capistrano/mb/templates/csr_config.erb +10 -0
  16. data/lib/capistrano/mb/templates/delayed_job_init.erb +36 -0
  17. data/lib/capistrano/mb/templates/logrotate.erb +9 -0
  18. data/lib/capistrano/mb/templates/maintenance.html.erb +26 -0
  19. data/lib/capistrano/mb/templates/nginx.erb +64 -0
  20. data/lib/capistrano/mb/templates/nginx_unicorn.erb +109 -0
  21. data/lib/capistrano/mb/templates/pgpass.erb +1 -0
  22. data/lib/capistrano/mb/templates/postgresql-backup-logrotate.erb +11 -0
  23. data/lib/capistrano/mb/templates/rbenv_bashrc +4 -0
  24. data/lib/capistrano/mb/templates/sidekiq_init.erb +100 -0
  25. data/lib/capistrano/mb/templates/ssl_setup +43 -0
  26. data/lib/capistrano/mb/templates/unicorn.rb.erb +71 -0
  27. data/lib/capistrano/mb/templates/unicorn_init.erb +84 -0
  28. data/lib/capistrano/mb/templates/version.rb.erb +3 -0
  29. data/lib/capistrano/mb/version.rb +5 -0
  30. data/lib/capistrano/tasks/aptitude.rake +101 -0
  31. data/lib/capistrano/tasks/crontab.rake +14 -0
  32. data/lib/capistrano/tasks/defaults.rake +122 -0
  33. data/lib/capistrano/tasks/delayed_job.rake +33 -0
  34. data/lib/capistrano/tasks/dotenv.rake +57 -0
  35. data/lib/capistrano/tasks/fiftyfive.rake +59 -0
  36. data/lib/capistrano/tasks/logrotate.rake +16 -0
  37. data/lib/capistrano/tasks/maintenance.rake +28 -0
  38. data/lib/capistrano/tasks/migrate.rake +29 -0
  39. data/lib/capistrano/tasks/nginx.rake +31 -0
  40. data/lib/capistrano/tasks/postgresql.rake +177 -0
  41. data/lib/capistrano/tasks/provision.rake +18 -0
  42. data/lib/capistrano/tasks/rake.rake +20 -0
  43. data/lib/capistrano/tasks/rbenv.rake +93 -0
  44. data/lib/capistrano/tasks/seed.rake +16 -0
  45. data/lib/capistrano/tasks/sidekiq.rake +39 -0
  46. data/lib/capistrano/tasks/ssl.rake +57 -0
  47. data/lib/capistrano/tasks/ufw.rake +32 -0
  48. data/lib/capistrano/tasks/unicorn.rake +42 -0
  49. data/lib/capistrano/tasks/user.rake +32 -0
  50. data/lib/capistrano/tasks/version.rake +34 -0
  51. metadata +165 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 636468db9344486d693871a6cd9f863ae6adaa4b
4
+ data.tar.gz: cc71034d8dedf94388b96ad5c254f08ee1a67ecd
5
+ SHA512:
6
+ metadata.gz: 109be86d154b0e2d8eed01a3d79ac9deae7f2d246733d036773330c49d12e926ccb249e87c8223cac35b99702fe5db1eb9cee0dfc1a19d565ba6c555d9368c80
7
+ data.tar.gz: 52879fa492ce9ac58c5b98c7a4a0f3b1f9d34f5ad3d088d170c6ac837cc42fc24ecb0f8998fb848467a025be0e02d0fb9e02ef4d0596fbef87fb7be5fc793542
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,114 @@
1
+ ## Next release
2
+
3
+ * Your contribution here!
4
+
5
+ ## 0.22.0 (2015-06-22)
6
+
7
+ **THIS GEM HAS A NEW NAME! It is now `capistrano-mb`.**
8
+
9
+ * All settings now use the `mb_` prefix. E.g. if you are using `set(:fiftyfive_recipies, ...)`, change it to `set(:mb_recipes, ...)`.
10
+ * All tasks now use the `mb` namespace. E.g. `cap fiftyfive:crontab` is now `cap mb:crontab`.
11
+ * For backwards compatibility, you can still use the `fiftyfive` versions, but a deprecation warning will be printed. This compatibility will be removed in capistrano-mb 1.0.
12
+
13
+ ## 0.21.0 (2015-06-22)
14
+
15
+ * Add a post-install message explaining the rename of `capistrano-fiftyfive` to `capistrano-mb`.
16
+
17
+ ## 0.20.1 (2015-05-29)
18
+
19
+ * An internal change in Capistrano 3.4.0 caused `fiftyfive:aptitude:install` to fail to install packages. This is now fixed.
20
+
21
+ ## 0.20.0 (2015-05-29)
22
+
23
+ * Increase SSL/TLS security of the generated nginx configuration by following the suggestions of [weakdh.org](https://weakdh.org/sysadmin.html).
24
+
25
+ ## 0.19.0 (2015-04-10)
26
+
27
+ * Add `--retry=3` to bundle install options. This will help prevent deployment failures in case that a gem initially fails to download during the `bundle install` step.
28
+ * Ensure that `--dry-run` works without crashing. This involved working around Capistrano's `download!` behavior (it returns a String normally, but an entirely different object during a dry run).
29
+
30
+ ## 0.18.0
31
+
32
+ * **The abbreviated log formatter has been removed and is now available in a new gem: `airbrussh`.** With this change, capistrano-fiftyfive no longer automatically changes the logging format of capistrano. To opt into the prettier, more concise format, add the airbrussh gem to your project as explained in the [airbrussh README](https://github.com/mattbrictson/airbrussh#readme).
33
+ * The version initializer that capistrano-fiftyfive adds during deployment sets a new value: `Rails.application.config.version_time`. You can use this value within your app for the date and time of the last commit that produced the version that is currently deployed.
34
+
35
+
36
+ ## 0.17.2
37
+
38
+ * Default self-signed SSL certificate is now more generic (for real this time).
39
+
40
+ ## 0.17.1
41
+
42
+ * Cosmetic changes to the gemspec.
43
+
44
+ ## 0.17.0
45
+
46
+ * Write a banner message into `capistrano.log` at the start of each cap run, to aid in troubleshooting.
47
+ * Default self-signed SSL certificate is now more generic.
48
+
49
+ ## 0.16.0
50
+
51
+ * capistrano-fiftyfive now requires capistrano >= 3.3.5 and sshkit => 1.6.1
52
+ * `ask_secretly` has been removed in favor of Capistrano's built-in `ask ..., :echo => false`
53
+ * `agree` no longer takes an optional second argument
54
+ * highline dependency removed
55
+ * Install libffi-dev so that Ruby 2.2.0 can be compiled
56
+
57
+ ## 0.15.2
58
+
59
+ * The capistrano-fiftyfive GitHub repository has changed: it is now <https://github.com/mattbrictson/capistrano-fiftyfive>.
60
+
61
+ ## 0.15.1
62
+
63
+ * Remove `-j4` bundler flag
64
+
65
+ ## 0.15.0
66
+
67
+ * Dump useful troubleshooting information when a deploy fails.
68
+ * Nginx/unicorn: fix syntax errors introduced by changes in 0.14.0, ensuring that gzip and far-future expires headers are sent as expected.
69
+
70
+ ## 0.14.0
71
+
72
+ * The `highline` gem is now a dependency ([#3](https://github.com/mattbrictson/capistrano-fiftyfive/pull/3) from [@ahmozkya](https://github.com/ahmozkya)).
73
+ * Dotenv: only mask input when prompting for keys containing the words "key", "secret", "token", or "password". Input for other keys is echoed for easier data entry.
74
+ * Dotenv: update `.env` files in sequence rather than in parallel, to avoid parallel command output clobbering the input prompt.
75
+ * Nginx/unicorn: tweak reverse-proxy cache settings to prevent cache stampede.
76
+ * Nginx/unicorn: apply far-future expires cache headers only for assets that have fingerprints.
77
+
78
+ ## 0.13.0
79
+
80
+ The provisioning tasks now work for a non-root user that has password-less sudo privileges. Assuming a user named `matt` that can sudo without being prompted for a password ([instructions here](http://askubuntu.com/questions/192050/how-to-run-sudo-command-with-no-password)), simply modify `deploy.rb` with:
81
+
82
+ ```ruby
83
+ set :fiftyfive_privileged_user, "matt"
84
+ ```
85
+
86
+ Now all provisioning tasks that would normally run as root will instead run as `matt` using `sudo`.
87
+
88
+ ## 0.12.0
89
+
90
+ * capistrano-fiftyfive's abbreviated format now honors the new `SSHKIT_COLOR` environment variable. Set `SSHKIT_COLOR=1` to force ANSI color even on non-ttys (e.g. Jenkins).
91
+ * The generated nginx config now enables reverse proxy caching by default.
92
+ * INFO messages printed by sshkit are now printed to console under the appropriate rake task heading.
93
+
94
+ ## 0.11.1
95
+
96
+ Fixes errors caused by PostgreSQL password containing shell-unsafe characters. Passwords are now safely hashed with MD5 before being used in the `CREATE USER` command.
97
+
98
+ ## 0.11.0
99
+
100
+ * INFO log messages are now included in abbreviated output (e.g. upload/download progress).
101
+ * Add `agree()` method to the DSL, which delegates to `HighLine.new.agree`.
102
+ * Add `fiftyfive:postgresql:dump`/`restore` tasks.
103
+
104
+ ## 0.10.0
105
+
106
+ Add support for Ubuntu 14.04 LTS. To provision a 14.04 server, use the new `provision:14_04` task.
107
+
108
+ ## 0.9.1
109
+
110
+ Flush console output after each line is printed. This allows deployment progress to be monitored in e.g. Jenkins.
111
+
112
+ ## 0.9.0
113
+
114
+ Initial Rubygems release!
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-mb.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 55 Minutes Inc
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,173 @@
1
+ # capistrano-mb
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/capistrano-mb.svg)](http://badge.fury.io/rb/capistrano-mb)
4
+
5
+ Capistrano is great for deploying Rails applications, but what about all the prerequisites, like Nginx and PostgreSQL? Do you have a firewall configured on your VPS? Have you installed the latest OS security updates? Is HTTPS working right?
6
+
7
+ The capistrano-mb gem adds a `cap <stage> provision` task to Capistrano that takes care of all that. Out of the box, `provision` will:
8
+
9
+ * Install the latest `postgresql`, `node.js`, and `nginx` apt packages
10
+ * Install all libraries needed to build Ruby
11
+ * Lock down your VPS using `ufw` (a simple front-end to iptables)
12
+ * Set up `logrotated` for your Rails logs
13
+ * Schedule an automatic daily backup of your Rails database
14
+ * Generate a self-signed SSL certificate if you need one
15
+ * Set up ngnix with the latest SSL practices and integrate it with Unicorn for your Rails app
16
+ * Create the `deployer` user and install an SSH public key
17
+ * Install `rbenv` and use `ruby-build` to compile the version of Ruby required by your app (by inspecting your `.ruby-version` file)
18
+ * And more!
19
+
20
+ The gem is named "capistrano-mb" because it is prescribes my ([@mattbrictson](https://github.com/mattbrictson)) personal preferences for automating deployments of Rails projects. I'm a freelance developer juggling lots of Rails codebases, so its important for me to have a good, consistent server configuration. You'll notice that capistrano-mb is opinionated and strictly uses the following stack:
21
+
22
+ * Ubuntu 12.04 LTS or 14.04 LTS
23
+ * PostgreSQL
24
+ * Unicorn
25
+ * Nginx
26
+ * rbenv
27
+ * dotenv
28
+
29
+ In addition, capistrano-mb changes many of Capistrano's defaults, including the deployment location, Bundler behavior, and SSH keep-alive settings. (See [defaults.rake][] for details.)
30
+
31
+ Not quite to your liking? Consider forking the project to meet your needs.
32
+
33
+
34
+ ## Installation
35
+
36
+ Please note that this project requires **Capistrano 3.x**, which is a complete
37
+ rewrite of Capistrano 2.x. The two major versions are not compatible.
38
+
39
+ ### 1. Gemfile
40
+
41
+ Add these gems to the development group of your Rails application's Gemfile:
42
+
43
+ group :development do
44
+ gem 'capistrano-bundler', :require => false
45
+ gem 'capistrano-rails', :require => false
46
+ gem 'capistrano', '~> 3.4.0', :require => false
47
+ gem 'capistrano-mb' :require => false
48
+ end
49
+
50
+ And then execute:
51
+
52
+ $ bundle
53
+
54
+
55
+ ### 2. cap install
56
+
57
+ If your project doesn't yet have a `Capfile`, run `cap install` with the list
58
+ of desired stages (environments):
59
+
60
+ cap install STAGES=staging,production
61
+
62
+
63
+ ### 3. Capfile
64
+
65
+ Add these lines to the **bottom** of your app's `Capfile`
66
+ (order is important!):
67
+
68
+ require 'capistrano/bundler'
69
+ require 'capistrano/rails'
70
+ require 'capistrano/mb'
71
+
72
+
73
+ ### 4. Choose which recipes to auto-run
74
+
75
+ Most of the capistrano-mb recipes are designed to run automatically as part of `cap <stage> provision`, for installing and setting up various bits of the Rails infrastructure, like nginx, unicorn, and postgres. Some recipes also contribute to the `cap <stage> deploy` process.
76
+
77
+ *This auto-run behavior is fully under your control.* In your `deploy.rb`,
78
+ set `:mb_recipes` to an array of the desired recipes.
79
+ If you don't want a recipe to execute as part of `deploy`/`provision`, simply omit it from
80
+ the list.
81
+
82
+ The following list will suffice for most out-of-the-box Rails apps. The order of the list is not important.
83
+
84
+ set :mb_recipes, %w(
85
+ aptitude
86
+ crontab
87
+ dotenv
88
+ logrotate
89
+ migrate
90
+ nginx
91
+ postgresql
92
+ rbenv
93
+ seed
94
+ ssl
95
+ ufw
96
+ unicorn
97
+ user
98
+ version
99
+ )
100
+
101
+ Even if you don't include a recipe in the auto-run list, you can still invoke
102
+ the tasks of those recipes manually at your discretion.
103
+
104
+
105
+ ### 5. Configuration
106
+
107
+ Many of the recipes have default settings that can be overridden. Use your
108
+ `deploy.rb` file to specify these overrides. Or, you can override per stage.
109
+ Here is an example override:
110
+
111
+ set :mb_unicorn_workers, 8
112
+
113
+ For the full list of settings and their default values, refer to
114
+ [defaults.rake][].
115
+
116
+
117
+ ### A working example
118
+
119
+ Check out our [rails-starter][] project for a sample Capfile and deploy.rb.
120
+
121
+ ## Usage
122
+
123
+ The power of the capistrano-mb recipes is that they take care of the
124
+ entire setup of a bare Ubuntu 12.04 or 14.04 server, all the way to a fully configured
125
+ and running Rails app on top up Unicorn, Nginx, rbenv, and PostgreSQL.
126
+
127
+ ### Deploying to a new server from scratch
128
+
129
+ These steps assume you have loaded the full set of capistrano-mb
130
+ recipes in your Capfile.
131
+
132
+ 1. Provision an Ubuntu 12.04 or 14.04 VPS at your hosting provider of choice.
133
+ 2. Install your public SSH key for the root user. Some providers (e.g. DigitalOcean) can do this for you automatically when you provision a new VPS.
134
+ 3. Repeat steps 1-2 for all the servers in your cluster, if you are using
135
+ a multi-server setup (e.g. separate web, app, and database servers).
136
+ 4. Let capistrano-mb take it from here:
137
+
138
+ cap staging provision # for 12.04 LTS
139
+ cap staging provision:14_04 # for 14.04 LTS
140
+ cap staging deploy
141
+
142
+ ### Running individual tasks
143
+
144
+ For a full description of all available tasks, run:
145
+
146
+ cap -T
147
+
148
+ All tasks from capistrano-mb will be prefixed with `mb:`. You
149
+ can run these tasks just like any other capistrano task, like so:
150
+
151
+ cap staging mb:seed
152
+
153
+
154
+ ## History
155
+
156
+ This gem used to be called capistrano-fiftyfive, because it was initially built by [55 Minutes](http://55minutes.com) to automate its Rails deployments. I have since taken over ownership of the gem and renamed it to capistrano-mb to avoid any confusion.
157
+
158
+ If you are upgrading from `capistrano-fiftyfive`, refer to the [CHANGELOG entry for v0.22.0](CHANGELOG.md#0220-2015-06-22) for migration instructions.
159
+
160
+ ## Contributing
161
+
162
+ 1. Fork it
163
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
164
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
165
+ 4. Push to the branch (`git push origin my-new-feature`)
166
+ 5. Create new Pull Request
167
+
168
+
169
+ [Postmark]:https://postmarkapp.com
170
+ [cast337]:http://railscasts.com/episodes/337-capistrano-recipes
171
+ [cast373]:http://railscasts.com/episodes/373-zero-downtime-deployment
172
+ [defaults.rake]:lib/capistrano/tasks/defaults.rake
173
+ [rails-starter]:https://github.com/mattbrictson/rails-starter/tree/master/config
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require "chandler/tasks"
3
+
4
+ # Add chandler as a prerequisite for `rake release`
5
+ task "release:rubygem_push" => "chandler:push"
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "capistrano/mb/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "capistrano-mb"
8
+ spec.version = Capistrano::MB::VERSION
9
+ spec.author = "Matt Brictson"
10
+ spec.email = "matt@mattbrictson.com"
11
+ spec.description = \
12
+ "Production-ready provisioning and deployment recipes for the full "\
13
+ "Rails 4 stack. Installs and configures Ruby, Nginx, Unicorn, "\
14
+ "PostgreSQL, dotenv, and more onto Ubuntu 14.04 LTS using Capistrano. "\
15
+ "(Note: this gem was formerly called capistrano-fiftyfive.)"
16
+ spec.summary = "Additional Capistrano 3 recipes"
17
+ spec.homepage = "https://github.com/mattbrictson/capistrano-mb"
18
+ spec.license = "MIT"
19
+
20
+ spec.post_install_message = "capistrano-fiftyfive has been renamed to "\
21
+ "capistrano-mb. Please update your Gemfile."
22
+
23
+ spec.files = `git ls-files`.split($/)
24
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
25
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_dependency "capistrano", ">= 3.3.5"
29
+ spec.add_dependency "sshkit", ">= 1.6.1"
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.3"
32
+ spec.add_development_dependency "chandler"
33
+ spec.add_development_dependency "rake"
34
+ end
@@ -0,0 +1,6 @@
1
+ require "capistrano/mb"
2
+
3
+ compatibility_warning(
4
+ "The capistrano-fiftyfive gem has been renamed to capistrano-mb. "\
5
+ 'Use `require "capistrano/mb"` to ensure compatibility with future versions.'
6
+ )
@@ -0,0 +1,29 @@
1
+ require "digest"
2
+ require "monitor"
3
+ require "capistrano/mb/version"
4
+ require "capistrano/mb/compatibility"
5
+ require "capistrano/mb/dsl"
6
+ require "capistrano/mb/recipe"
7
+ include Capistrano::MB::DSL
8
+
9
+ load File.expand_path("../tasks/provision.rake", __FILE__)
10
+ load File.expand_path("../tasks/defaults.rake", __FILE__)
11
+ load File.expand_path("../tasks/user.rake", __FILE__)
12
+ load File.expand_path("../tasks/aptitude.rake", __FILE__)
13
+ load File.expand_path("../tasks/ufw.rake", __FILE__)
14
+ load File.expand_path("../tasks/ssl.rake", __FILE__)
15
+ load File.expand_path("../tasks/dotenv.rake", __FILE__)
16
+ load File.expand_path("../tasks/postgresql.rake", __FILE__)
17
+ load File.expand_path("../tasks/nginx.rake", __FILE__)
18
+ load File.expand_path("../tasks/unicorn.rake", __FILE__)
19
+ load File.expand_path("../tasks/delayed_job.rake", __FILE__)
20
+ load File.expand_path("../tasks/crontab.rake", __FILE__)
21
+ load File.expand_path("../tasks/logrotate.rake", __FILE__)
22
+ load File.expand_path("../tasks/rbenv.rake", __FILE__)
23
+ load File.expand_path("../tasks/maintenance.rake", __FILE__)
24
+ load File.expand_path("../tasks/migrate.rake", __FILE__)
25
+ load File.expand_path("../tasks/seed.rake", __FILE__)
26
+ load File.expand_path("../tasks/version.rake", __FILE__)
27
+ load File.expand_path("../tasks/rake.rake", __FILE__)
28
+ load File.expand_path("../tasks/sidekiq.rake", __FILE__)
29
+ load File.expand_path("../tasks/fiftyfive.rake", __FILE__)
@@ -0,0 +1,17 @@
1
+ require 'colorize'
2
+
3
+ unless defined?(Capistrano) && defined?(:namespace)
4
+ $stderr.puts\
5
+ "WARNING: capistrano/mb must be loaded by Capistrano in order "\
6
+ "to work.\nRequire this gem by using Capistrano's Capfile, "\
7
+ "as described here:\n"\
8
+ "https://github.com/mattbrictson/capistrano-mb#installation"\
9
+ .colorize(:red)
10
+ end
11
+
12
+ if Capistrano::VERSION == "3.2.0"
13
+ $stderr.puts\
14
+ "WARNING: Capistrano 3.2.0 has a critical bug that prevents "\
15
+ "capistrano-mb from working as intended:\n"\
16
+ "https://github.com/capistrano/capistrano/issues/1004".colorize(:red)
17
+ end
@@ -0,0 +1,187 @@
1
+ module Capistrano
2
+ module MB
3
+ module DSL
4
+
5
+ # Invoke the given task. If a task with that name is not defined,
6
+ # silently skip it.
7
+ #
8
+ def invoke_if_defined(task)
9
+ invoke(task) if Rake::Task.task_defined?(task)
10
+ end
11
+
12
+ # Used internally by capistrano-mb to register tasks such that
13
+ # those tasks are executed conditionally based on the presence of the
14
+ # recipe name in fetch(:mb_recipes).
15
+ #
16
+ # mb_recipe :aptitude do
17
+ # during :provision, %w(task1 task2 ...)
18
+ # end
19
+ #
20
+ def mb_recipe(recipe_name, &block)
21
+ Recipe.new(recipe_name).instance_exec(&block)
22
+ end
23
+
24
+ def compatibility_warning(warning)
25
+ warning = "WARNING: #{warning}"
26
+ warning = warning.colorize(:red) if $stderr.tty?
27
+ $stderr.puts(warning)
28
+ end
29
+
30
+ # Helper for calling fetch(:application) and making the value safe for
31
+ # using in filenames, usernames, etc. Replaces non-word characters with
32
+ # underscores.
33
+ #
34
+ def application_basename
35
+ fetch(:application).to_s.gsub(/[^a-zA-Z0-9_]/, "_")
36
+ end
37
+
38
+ # Prints a question and returns truthy if the user answers "y" or "yes".
39
+ def agree(yes_or_no_question)
40
+ $stdout.print(yes_or_no_question)
41
+ $stdin.gets.to_s =~ /^y(es)?/i
42
+ end
43
+
44
+ # Like capistrano's built-in on(), but connects to the server as root.
45
+ # To use a user other than root, set :mb_privileged_user or
46
+ # specify :privileged_user as a server property.
47
+ #
48
+ # task :reboot do
49
+ # privileged_on roles(:all) do
50
+ # execute :shutdown, "-r", "now"
51
+ # end
52
+ # end
53
+ #
54
+ def privileged_on(*args, &block)
55
+ on(*args) do |host|
56
+ if host.nil?
57
+ instance_exec(nil, nil, &block)
58
+ else
59
+ original_user = host.user
60
+
61
+ begin
62
+ host.user = host.properties.privileged_user ||
63
+ fetch(:mb_privileged_user)
64
+ instance_exec(host, original_user, &block)
65
+ ensure
66
+ host.user = original_user
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ # Uploads the given string or file-like object to the current host
73
+ # context. Intended to be used within an on() or privileged_on() block.
74
+ # Accepts :owner and :mode options that affect the permissions of the
75
+ # remote file.
76
+ #
77
+ def put(string_or_io, remote_path, opts={})
78
+ sudo_exec = ->(*cmd) {
79
+ cmd = [:sudo] + cmd if opts[:sudo]
80
+ execute *cmd
81
+ }
82
+
83
+ tmp_path = "/tmp/#{SecureRandom.uuid}"
84
+
85
+ owner = opts[:owner]
86
+ mode = opts[:mode]
87
+
88
+ source = if string_or_io.respond_to?(:read)
89
+ string_or_io
90
+ else
91
+ StringIO.new(string_or_io.to_s)
92
+ end
93
+
94
+ sudo_exec.call :mkdir, "-p", File.dirname(remote_path)
95
+
96
+ upload!(source, tmp_path)
97
+
98
+ sudo_exec.call(:mv, "-f", tmp_path, remote_path)
99
+ sudo_exec.call(:chown, owner, remote_path) if owner
100
+ sudo_exec.call(:chmod, mode, remote_path) if mode
101
+ end
102
+
103
+
104
+ # Read the specified file from the local system, interpret it as ERb,
105
+ # and upload it to the current host context. Intended to be used with an
106
+ # on() or privileged_on() block. Accepts :owner, :mode, and :binding
107
+ # options.
108
+ #
109
+ # Templates with relative paths are first searched for in
110
+ # lib/capistrano/mb/templates in the current project. This gives
111
+ # applications a chance to override. If an override is not found, the
112
+ # default template within the capistrano-mb gem is used.
113
+ #
114
+ # task :create_database_yml do
115
+ # on roles(:app, :db) do
116
+ # within(shared_path) do
117
+ # template fetch(:database_yml_template_path),
118
+ # "config/database.yml",
119
+ # :mode => "600"
120
+ # end
121
+ # end
122
+ # end
123
+ #
124
+ def template(local_path, remote_path, opts={})
125
+ binding = opts[:binding] || binding
126
+
127
+ unless local_path.start_with?("/")
128
+ override_path = \
129
+ File.join("lib/capistrano/mb/templates", local_path)
130
+
131
+ local_path = if File.exist?(override_path)
132
+ override_path
133
+ else
134
+ File.expand_path(File.join("../templates", local_path), __FILE__)
135
+ end
136
+ end
137
+
138
+ erb = File.read(local_path)
139
+ rendered_template = ERB.new(erb).result(binding)
140
+
141
+ put(rendered_template, remote_path, opts)
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ require "capistrano/dsl/env"
148
+
149
+ module Capistrano
150
+ module DSL
151
+ module Env
152
+ # Overrides capistrano's default `set` to assist developers that are
153
+ # migrating from the `fiftyfive_*` to `mb_*` variable names. This will
154
+ # be removed in a future version of capistrano-mb.
155
+ alias_method :_orig_capistrano_set, :set
156
+ def set(name, *args, &block)
157
+ if name.to_s =~ /^fiftyfive_/
158
+ mb_name = name.to_s.gsub(/^fiftyfive_/, "mb_")
159
+ compatibility_warning(
160
+ "Use `set :#{mb_name}` instead of `set :#{name}` to ensure "\
161
+ "compatibility with future versions of capistrano-mb. The "\
162
+ "fiftyfive_* names have been deprecated."
163
+ )
164
+ name = mb_name.intern
165
+ end
166
+ _orig_capistrano_set(name, *args, &block)
167
+ end
168
+
169
+ # Overrides capistrano's default `fetch` to assist developers that are
170
+ # migrating from the `fiftyfive_*` to `mb_*` variable names. This will
171
+ # be removed in a future version of capistrano-mb.
172
+ alias_method :_orig_capistrano_fetch, :fetch
173
+ def fetch(name, *args, &block)
174
+ if name.to_s =~ /^fiftyfive_/
175
+ mb_name = name.to_s.gsub(/^fiftyfive_/, "mb_")
176
+ compatibility_warning(
177
+ "Use `fetch :#{mb_name}` instead of `fetch :#{name}` to ensure "\
178
+ "compatibility with future versions of capistrano-mb. The "\
179
+ "fiftyfive_* names have been deprecated."
180
+ )
181
+ name = mb_name.intern
182
+ end
183
+ _orig_capistrano_fetch(name, *args, &block)
184
+ end
185
+ end
186
+ end
187
+ end