capistrano-mb 0.22.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.
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