capistrano-atlas 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +215 -0
- data/Rakefile +5 -0
- data/capistrano-atlas.gemspec +32 -0
- data/lib/capistrano/atlas.rb +27 -0
- data/lib/capistrano/atlas/compatibility.rb +37 -0
- data/lib/capistrano/atlas/dsl.rb +157 -0
- data/lib/capistrano/atlas/recipe.rb +49 -0
- data/lib/capistrano/atlas/templates/crontab.erb +1 -0
- data/lib/capistrano/atlas/templates/csr_config.erb +10 -0
- data/lib/capistrano/atlas/templates/logrotate.erb +9 -0
- data/lib/capistrano/atlas/templates/maintenance.html.erb +26 -0
- data/lib/capistrano/atlas/templates/nginx.erb +64 -0
- data/lib/capistrano/atlas/templates/nginx_site.erb +97 -0
- data/lib/capistrano/atlas/templates/pgpass.erb +1 -0
- data/lib/capistrano/atlas/templates/postgresql-backup-logrotate.erb +11 -0
- data/lib/capistrano/atlas/templates/puma.rb.erb +22 -0
- data/lib/capistrano/atlas/templates/puma_init.erb +43 -0
- data/lib/capistrano/atlas/templates/rbenv_bashrc +4 -0
- data/lib/capistrano/atlas/templates/sidekiq_init.erb +100 -0
- data/lib/capistrano/atlas/templates/ssl_setup +43 -0
- data/lib/capistrano/atlas/templates/version.rb.erb +3 -0
- data/lib/capistrano/atlas/version.rb +5 -0
- data/lib/capistrano/tasks/aptitude.rake +111 -0
- data/lib/capistrano/tasks/bundler.rake +31 -0
- data/lib/capistrano/tasks/crontab.rake +14 -0
- data/lib/capistrano/tasks/defaults.rake +137 -0
- data/lib/capistrano/tasks/dotenv.rake +57 -0
- data/lib/capistrano/tasks/logrotate.rake +16 -0
- data/lib/capistrano/tasks/maintenance.rake +28 -0
- data/lib/capistrano/tasks/migrate.rake +29 -0
- data/lib/capistrano/tasks/nginx.rake +25 -0
- data/lib/capistrano/tasks/postgresql.rake +149 -0
- data/lib/capistrano/tasks/provision.rake +18 -0
- data/lib/capistrano/tasks/puma.rake +67 -0
- data/lib/capistrano/tasks/rake.rake +20 -0
- data/lib/capistrano/tasks/rbenv.rake +104 -0
- data/lib/capistrano/tasks/seed.rake +16 -0
- data/lib/capistrano/tasks/sidekiq.rake +42 -0
- data/lib/capistrano/tasks/ssl.rake +57 -0
- data/lib/capistrano/tasks/ufw.rake +32 -0
- data/lib/capistrano/tasks/user.rake +32 -0
- data/lib/capistrano/tasks/version.rake +34 -0
- metadata +161 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0fdb1cb92c6e823effad36625a49db5dccb2ea5b
|
4
|
+
data.tar.gz: 3858ea7c0f6e411411fe880d502428686cafc8a5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e6b7c06a79714867e4c37e7fe2aa83756793b2f47467eea82f6d2d9afd25c629e58921882c0b532466a8f89b25afab8e082c6cb6af680819dc2e3691e66b4c9b
|
7
|
+
data.tar.gz: f4a9a75485061d6f79045384de70b2e020577b29ac7af225028637627eacbd1fb37ebc753366070ea30d0d26898d65a44363e83a8689da1f114468b7089c053f
|
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
## [Unreleased][]
|
2
|
+
|
3
|
+
* Your contribution here!
|
4
|
+
|
5
|
+
## [0.0.1][] (2017-11-01)
|
6
|
+
|
7
|
+
* Fork, and starting to change things for Puma and Let's Encrypt support in production.
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
[Unreleased]: https://github.com/mattbrictson/capistrano-atlas/compare/v0.32.0...HEAD
|
12
|
+
[0.32.0]: https://github.com/mattbrictson/capistrano-atlas/compare/v0.31.0...v0.32.0
|
13
|
+
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 John McDowall & Matt Brictson
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
# capistrano-atlas
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/capistrano-atlas)
|
4
|
+
|
5
|
+
**This is a fork of `capistrano-mb` by the excellent Matt Brictson and FiftyFive. I've changed things to use Puma and Let's Encrypt in production.**
|
6
|
+
|
7
|
+
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?
|
8
|
+
|
9
|
+
The capistrano-atlas gem adds a `cap <stage> provision` task to Capistrano that takes care of all that. Out of the box, `provision` will:
|
10
|
+
|
11
|
+
* Install the latest `postgresql`, `node.js`, and `nginx` apt packages
|
12
|
+
* Install all libraries needed to build Ruby
|
13
|
+
* Lock down your VPS using `ufw` (a simple front-end to iptables)
|
14
|
+
* Set up `logrotated` for your Rails logs
|
15
|
+
* Schedule an automatic daily backup of your Rails database
|
16
|
+
* Generate a self-signed SSL certificate if you need one
|
17
|
+
* Set up ngnix with the latest SSL practices and integrate it with Puma for your Rails app
|
18
|
+
* Create the `deployer` user and install an SSH public key
|
19
|
+
* Install `rbenv` and use `ruby-build` to compile the version of Ruby required by your app (by inspecting your `.ruby-version` file)
|
20
|
+
* And more!
|
21
|
+
|
22
|
+
The gem is named "capistrano-atlas" because it does the heavy lifting of setting up a VPS to be ready for modern Rails 5.1+ applications.
|
23
|
+
|
24
|
+
You'll notice that capistrano-atlas is opinionated and strictly uses the following stack:
|
25
|
+
|
26
|
+
* Ubuntu 14.04 LTS
|
27
|
+
* PostgreSQL
|
28
|
+
* Puma
|
29
|
+
* Nginx
|
30
|
+
* rbenv
|
31
|
+
* dotenv
|
32
|
+
|
33
|
+
In addition, capistrano-atlas changes many of Capistrano's defaults, including the deployment location, Bundler behavior, and SSH keep-alive settings. (See [defaults.rake][] for details.)
|
34
|
+
|
35
|
+
Not quite to your liking? Consider forking the project to meet your needs.
|
36
|
+
|
37
|
+
|
38
|
+
## Quick start
|
39
|
+
|
40
|
+
Please note that this project requires **Capistrano 3.x**, which is a complete rewrite of Capistrano 2.x. The two major versions are not compatible.
|
41
|
+
|
42
|
+
### 1. Purchase an Ubuntu 14.04 VPS
|
43
|
+
|
44
|
+
To use capistrano-atlas, you'll need a clean Ubuntu server to deploy to. The only special requirement is that your public SSH key must be installed on the server for the `root` user.
|
45
|
+
|
46
|
+
Test that you can SSH to the server as `root` without being prompted for a password. If that works, capistrano-atlas can take care of the rest. You're ready to proceed!
|
47
|
+
|
48
|
+
### 2. .ruby-version
|
49
|
+
|
50
|
+
capistrano-atlas needs to know the version of Ruby that your app requires, so that it can install Ruby during the provisioning process. Place a `.ruby-version` file in the root of your project containing the desired version, like this:
|
51
|
+
|
52
|
+
```
|
53
|
+
2.2.3
|
54
|
+
```
|
55
|
+
|
56
|
+
*If you are using `rbenv`, just run `rbenv local 2.2.3` and it will create this file for you.*
|
57
|
+
|
58
|
+
### 3. Gemfile
|
59
|
+
|
60
|
+
capistrano-atlas makes certain assumptions about your Rails app, namely that it uses [dotenv][] to manage Rails secrets via environment variables, and that it runs on top of PostgreSQL and [Puma][]. Make sure they are specified in the Gemfile:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
gem "dotenv-rails", ">= 2.0.0"
|
64
|
+
gem "pg", "~> 0.18"
|
65
|
+
gem "Puma"
|
66
|
+
```
|
67
|
+
|
68
|
+
Then for the capistrano-atlas tools themselves, add these gems to the development group:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
group :development do
|
72
|
+
gem "capistrano-bundler", :require => false
|
73
|
+
gem "capistrano-rails", :require => false
|
74
|
+
gem "capistrano", "~> 3.4.0", :require => false
|
75
|
+
gem "capistrano-atlas", :require => false
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
And then execute:
|
80
|
+
|
81
|
+
```
|
82
|
+
$ bundle
|
83
|
+
```
|
84
|
+
|
85
|
+
### 4. cap install
|
86
|
+
|
87
|
+
If your project doesn't yet have a `Capfile`, run `cap install` with the list of desired stages (environments). For simplicity, this installation guide will assume a single production stage:
|
88
|
+
|
89
|
+
```
|
90
|
+
cap install STAGES=production
|
91
|
+
```
|
92
|
+
|
93
|
+
### 5. Capfile
|
94
|
+
|
95
|
+
Add these lines to the **bottom** of your app's `Capfile` (order is important!):
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
require "capistrano/bundler"
|
99
|
+
require "capistrano/rails"
|
100
|
+
require "capistrano/atlas"
|
101
|
+
```
|
102
|
+
|
103
|
+
### 6. deploy.rb
|
104
|
+
|
105
|
+
Modify `config/deploy.rb` to set the specifics of your Rails app. At the minimum, you'll need to set these two options:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
set :application, "my_app_name"
|
109
|
+
set :repo_url, "git@github.com:username/repository.git"
|
110
|
+
```
|
111
|
+
|
112
|
+
### 7. production.rb
|
113
|
+
|
114
|
+
Modify `config/deploy/production.rb` to specify the IP address of your production server. In this example, I have a single 1GB VPS (e.g. at DigitalOcean) that plays all the roles:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
server "my.production.ip",
|
118
|
+
:user => "deployer",
|
119
|
+
:roles => %w(app backup cron db web)
|
120
|
+
```
|
121
|
+
|
122
|
+
*Note that you must include the `backup` and `cron` roles if you want to make use of capistrano-atlas's database backups and crontab features.*
|
123
|
+
|
124
|
+
### 8. secrets.yml
|
125
|
+
|
126
|
+
By default, Rails 4.2 apps have a `config/secrets.yml` file that specifies the Rails secret key. capistrano-atlas configures dotenv to provide this secret in a `RAILS_SECRET_KEY_BASE` environment variable. You'll therefore need to modify `secrets.yml` as follows:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
production:
|
130
|
+
secret_key_base: <%= ENV["RAILS_SECRET_KEY_BASE"] %>
|
131
|
+
```
|
132
|
+
|
133
|
+
### 9. Provision and deploy!
|
134
|
+
|
135
|
+
Run capistrano-atlas's `provision:14_04` task (named for Ubuntu 14.04). This will ask you a few questions, install Ruby, PostgreSQL, Nginx, etc., and set everything up. The entire process takes about 10 minutes (mostly due to compiling Ruby from source).
|
136
|
+
|
137
|
+
```
|
138
|
+
bundle exec cap production provision:14_04
|
139
|
+
```
|
140
|
+
|
141
|
+
Once that's done, your app is now ready to deploy!
|
142
|
+
|
143
|
+
```
|
144
|
+
bundle exec cap production deploy
|
145
|
+
```
|
146
|
+
|
147
|
+
## Advanced usage
|
148
|
+
|
149
|
+
### Choosing which recipes to auto-run
|
150
|
+
|
151
|
+
Most of the capistrano-atlas 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, Puma, and postgres. Some recipes also contribute to the `cap <stage> deploy` process.
|
152
|
+
|
153
|
+
*This auto-run behavior is fully under your control.* In your `deploy.rb`, set `:atlas_recipes` to an array of the desired recipes. If you don't want a recipe to execute as part of `deploy`/`provision`, simply omit it from the list.
|
154
|
+
|
155
|
+
The following list will suffice for most out-of-the-box Rails apps. The order of the list is not important.
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
set :atlas_recipes, %w(
|
159
|
+
aptitude
|
160
|
+
crontab
|
161
|
+
dotenv
|
162
|
+
logrotate
|
163
|
+
migrate
|
164
|
+
nginx
|
165
|
+
postgresql
|
166
|
+
rbenv
|
167
|
+
seed
|
168
|
+
ssl
|
169
|
+
ufw
|
170
|
+
Puma
|
171
|
+
user
|
172
|
+
version
|
173
|
+
)
|
174
|
+
```
|
175
|
+
|
176
|
+
Even if you don't include a recipe in the auto-run list, you can still invoke the tasks of those recipes manually at your discretion. Run `bundle exec cap -T` to see the full list of tasks.
|
177
|
+
|
178
|
+
### Configuration
|
179
|
+
|
180
|
+
Many of the recipes have default settings that can be overridden. Use your
|
181
|
+
`deploy.rb` file to specify these overrides. Or, you can override per stage.
|
182
|
+
Here is an example override:
|
183
|
+
|
184
|
+
set :atlas_Puma_workers, 8
|
185
|
+
|
186
|
+
For the full list of settings and their default values, refer to [defaults.rake][].
|
187
|
+
|
188
|
+
|
189
|
+
## Further reading
|
190
|
+
|
191
|
+
Check out my [rails-template][] project, which generates Rails applications with capistrano-atlas pre-configured and ready to go.
|
192
|
+
|
193
|
+
|
194
|
+
## History
|
195
|
+
|
196
|
+
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-atlas to avoid any confusion.
|
197
|
+
|
198
|
+
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.
|
199
|
+
|
200
|
+
## Contributing
|
201
|
+
|
202
|
+
1. Fork it
|
203
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
204
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
205
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
206
|
+
5. Create new Pull Request
|
207
|
+
|
208
|
+
|
209
|
+
[Postmark]:https://postmarkapp.com
|
210
|
+
[cast337]:http://railscasts.com/episodes/337-capistrano-recipes
|
211
|
+
[cast373]:http://railscasts.com/episodes/373-zero-downtime-deployment
|
212
|
+
[defaults.rake]:lib/capistrano/tasks/defaults.rake
|
213
|
+
[rails-template]:https://github.com/mattbrictson/rails-template/
|
214
|
+
[dotenv]:https://github.com/bkeepers/dotenv
|
215
|
+
[Puma]:http://Puma.bogomips.org/
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "capistrano/atlas/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "capistrano-atlas"
|
8
|
+
spec.version = Capistrano::Atlas::VERSION
|
9
|
+
spec.author = "John McDowall"
|
10
|
+
spec.email = "john@kantan.io"
|
11
|
+
spec.description = \
|
12
|
+
"Does all the heavy lifting for production-ready provisioning "\
|
13
|
+
"and deployment for the full Rails 5.1 stack. Installs and "\
|
14
|
+
"configures Ruby, Nginx, Puma, PostgreSQL, dotenv, Let's Encrypt and "\
|
15
|
+
"more onto Ubuntu 14.04 LTS using Capistrano. "
|
16
|
+
|
17
|
+
spec.summary = "Additional Capistrano 3 recipes"
|
18
|
+
spec.homepage = "https://github.com/johnmcdowall/capistrano-atlas"
|
19
|
+
spec.license = "MIT"
|
20
|
+
|
21
|
+
spec.files = `git ls-files`.split($/)
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_dependency "capistrano", ">= 3.3.5"
|
27
|
+
spec.add_dependency "sshkit", ">= 1.6.1"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
30
|
+
spec.add_development_dependency "chandler"
|
31
|
+
spec.add_development_dependency "rake"
|
32
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "digest"
|
2
|
+
require "monitor"
|
3
|
+
require "capistrano/atlas/version"
|
4
|
+
require "capistrano/atlas/compatibility"
|
5
|
+
require "capistrano/atlas/dsl"
|
6
|
+
require "capistrano/atlas/recipe"
|
7
|
+
include Capistrano::Atlas::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/crontab.rake", __FILE__)
|
19
|
+
load File.expand_path("../tasks/logrotate.rake", __FILE__)
|
20
|
+
load File.expand_path("../tasks/rbenv.rake", __FILE__)
|
21
|
+
load File.expand_path("../tasks/maintenance.rake", __FILE__)
|
22
|
+
load File.expand_path("../tasks/migrate.rake", __FILE__)
|
23
|
+
load File.expand_path("../tasks/seed.rake", __FILE__)
|
24
|
+
load File.expand_path("../tasks/version.rake", __FILE__)
|
25
|
+
load File.expand_path("../tasks/rake.rake", __FILE__)
|
26
|
+
load File.expand_path("../tasks/sidekiq.rake", __FILE__)
|
27
|
+
load File.expand_path("../tasks/bundler.rake", __FILE__)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Atlas
|
3
|
+
module Compatibility
|
4
|
+
def self.check
|
5
|
+
check_capistrano_and_rake_are_loaded
|
6
|
+
check_blacklisted_capistrano_version
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.check_capistrano_and_rake_are_loaded
|
10
|
+
return if defined?(Capistrano::VERSION) && defined?(Rake)
|
11
|
+
|
12
|
+
warn "capistrano/atlas must be loaded by Capistrano in order "\
|
13
|
+
"to work.\nRequire this gem by using Capistrano's Capfile, "\
|
14
|
+
"as described here:\n"\
|
15
|
+
"https://github.com/mattbrictson/capistrano-atlas#installation"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.check_blacklisted_capistrano_version
|
19
|
+
return unless defined?(Capistrano::VERSION)
|
20
|
+
return unless Capistrano::VERSION == "3.2.0"
|
21
|
+
|
22
|
+
warn "Capistrano 3.2.0 has a critical bug that prevents "\
|
23
|
+
"capistrano-atlas from working as intended:\n"\
|
24
|
+
"https://github.com/capistrano/capistrano/issues/1004"
|
25
|
+
end
|
26
|
+
|
27
|
+
# We can't really rely on anything being loaded at this point, so define
|
28
|
+
# our own basic colorizing helper.
|
29
|
+
def self.warn(message)
|
30
|
+
return $stderr.puts("WARNING: #{message}") unless $stderr.tty?
|
31
|
+
$stderr.puts("\e[0;31;49mWARNING: #{message}\e[0m")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Capistrano::Atlas::Compatibility.check
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Atlas
|
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-atlas to register tasks such that
|
13
|
+
# those tasks are executed conditionally based on the presence of the
|
14
|
+
# recipe name in fetch(:atlas_recipes).
|
15
|
+
#
|
16
|
+
# atlas_recipe :aptitude do
|
17
|
+
# during :provision, %w(task1 task2 ...)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
def atlas_recipe(recipe_name, &block)
|
21
|
+
Recipe.new(recipe_name).instance_exec(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def compatibility_warning(warning)
|
25
|
+
Capistrano::Atlas::Compatibility.warn(warning)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Helper for calling fetch(:application) and making the value safe for
|
29
|
+
# using in filenames, usernames, etc. Replaces non-word characters with
|
30
|
+
# underscores.
|
31
|
+
#
|
32
|
+
def application_basename
|
33
|
+
fetch(:application).to_s.gsub(/[^a-zA-Z0-9_]/, "_")
|
34
|
+
end
|
35
|
+
|
36
|
+
# Prints a question and returns truthy if the user answers "y" or "yes".
|
37
|
+
def agree(yes_or_no_question)
|
38
|
+
$stdout.print(yes_or_no_question)
|
39
|
+
$stdin.gets.to_s =~ /^y(es)?/i
|
40
|
+
end
|
41
|
+
|
42
|
+
# Like capistrano's built-in on(), but connects to the server as root.
|
43
|
+
# To use a user other than root, set :atlas_privileged_user or
|
44
|
+
# specify :privileged_user as a server property.
|
45
|
+
#
|
46
|
+
# task :reboot do
|
47
|
+
# privileged_on roles(:all) do
|
48
|
+
# execute :shutdown, "-r", "now"
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
def privileged_on(*args, &block)
|
53
|
+
on(*args) do |host|
|
54
|
+
if host.nil?
|
55
|
+
instance_exec(nil, nil, &block)
|
56
|
+
else
|
57
|
+
original_user = host.user
|
58
|
+
|
59
|
+
begin
|
60
|
+
host.user = host.properties.privileged_user ||
|
61
|
+
fetch(:atlas_privileged_user)
|
62
|
+
instance_exec(host, original_user, &block)
|
63
|
+
ensure
|
64
|
+
host.user = original_user
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Uploads the given string or file-like object to the current host
|
71
|
+
# context. Intended to be used within an on() or privileged_on() block.
|
72
|
+
# Accepts :owner and :mode options that affect the permissions of the
|
73
|
+
# remote file.
|
74
|
+
#
|
75
|
+
def put(string_or_io, remote_path, opts={})
|
76
|
+
sudo_exec = ->(*cmd) {
|
77
|
+
cmd = [:sudo] + cmd if opts[:sudo]
|
78
|
+
execute *cmd
|
79
|
+
}
|
80
|
+
|
81
|
+
tmp_path = "/tmp/#{SecureRandom.uuid}"
|
82
|
+
|
83
|
+
owner = opts[:owner]
|
84
|
+
mode = opts[:mode]
|
85
|
+
|
86
|
+
source = if string_or_io.respond_to?(:read)
|
87
|
+
string_or_io
|
88
|
+
else
|
89
|
+
StringIO.new(string_or_io.to_s)
|
90
|
+
end
|
91
|
+
|
92
|
+
sudo_exec.call :mkdir, "-p", File.dirname(remote_path)
|
93
|
+
|
94
|
+
upload!(source, tmp_path)
|
95
|
+
|
96
|
+
sudo_exec.call(:mv, "-f", tmp_path, remote_path)
|
97
|
+
sudo_exec.call(:chown, owner, remote_path) if owner
|
98
|
+
sudo_exec.call(:chmod, mode, remote_path) if mode
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# Read the specified file from the local system, interpret it as ERb,
|
103
|
+
# and upload it to the current host context. Intended to be used with an
|
104
|
+
# on() or privileged_on() block. Accepts :owner, :mode, and :binding
|
105
|
+
# options.
|
106
|
+
#
|
107
|
+
# Templates with relative paths are first searched for in
|
108
|
+
# lib/capistrano/atlas/templates in the current project. This gives
|
109
|
+
# applications a chance to override. If an override is not found, the
|
110
|
+
# default template within the capistrano-atlas gem is used.
|
111
|
+
#
|
112
|
+
# task :create_database_yml do
|
113
|
+
# on roles(:app, :db) do
|
114
|
+
# within(shared_path) do
|
115
|
+
# template fetch(:database_yml_template_path),
|
116
|
+
# "config/database.yml",
|
117
|
+
# :mode => "600"
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
def template(local_path, remote_path, opts={})
|
123
|
+
binding = opts[:binding] || binding
|
124
|
+
|
125
|
+
unless local_path.start_with?("/")
|
126
|
+
override_path = File.join("lib/capistrano/atlas/templates", local_path)
|
127
|
+
|
128
|
+
unless File.exist?(override_path)
|
129
|
+
override_path = File.join(
|
130
|
+
"lib/capistrano/atlas/templates",
|
131
|
+
local_path
|
132
|
+
)
|
133
|
+
if File.exist?(override_path)
|
134
|
+
compatibility_warning(
|
135
|
+
"Please move #{override_path} from lib/capistrano/atlas "\
|
136
|
+
"to lib/capistrano/atlas to ensure future compatibility with "\
|
137
|
+
"capistrano-atlas."
|
138
|
+
)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
local_path = if File.exist?(override_path)
|
143
|
+
override_path
|
144
|
+
else
|
145
|
+
File.expand_path(File.join("../templates", local_path), __FILE__)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
erb = File.read(local_path)
|
150
|
+
rendered_template = ERB.new(erb).result(binding)
|
151
|
+
|
152
|
+
put(rendered_template, remote_path, opts)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|