capistrano_recipes 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +89 -0
- data/Rakefile +7 -0
- data/capistrano_recipes.gemspec +24 -0
- data/lib/capistrano/recipes/bundle.rb +9 -0
- data/lib/capistrano/recipes/bundler.rb +2 -0
- data/lib/capistrano/recipes/git.rb +119 -0
- data/lib/capistrano/recipes/multistage.rb +73 -0
- data/lib/capistrano/recipes/mysql.rb +134 -0
- data/lib/capistrano/recipes/nginx.rb +75 -0
- data/lib/capistrano/recipes/rails_assets.rb +7 -0
- data/lib/capistrano/recipes/templates/mysql.yml.erb +7 -0
- data/lib/capistrano/recipes/templates/nginx.vhost.erb +139 -0
- data/lib/capistrano/recipes/templates/unicorn.rb.erb +47 -0
- data/lib/capistrano/recipes/templates/unicorn_init.erb +84 -0
- data/lib/capistrano/recipes/unicorn.rb +71 -0
- data/lib/capistrano/recipes.rb +1 -0
- data/lib/capistrano_recipes.rb +129 -0
- data/spec/bundle_spec.rb +15 -0
- data/spec/bundler_spec.rb +14 -0
- data/spec/git_spec.rb +57 -0
- data/spec/multistage_spec.rb +66 -0
- data/spec/mysql_spec.rb +14 -0
- data/spec/nginx_spec.rb +16 -0
- data/spec/rails_assets.rb +37 -0
- data/spec/spec_helper.rb +108 -0
- data/spec/unicorn_spec.rb +16 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YmM2MzhjY2ZhZjY2ZTc4ODhjYzJjY2Q3NWYxZjFkZjZiZjczYWZkMQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YmU5OGQ3NjRkMDhmNTczNTQwZjE5MzZhNTlkMjg4MzE2OTY1NjRhZA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NzRiNDhjZGRmNTRkY2JmNjhjYTBjYWFmZWFmOWY5MjA1Yzc0NmE2Yjc0NGQ1
|
10
|
+
MDgzMzY1Nzg3OGMyZjg0MGE5ZWUwMjBhZDE0NDQ1NTZjNWZlMzM2OTZjYzE1
|
11
|
+
NzcyODljNWRmYTBkMjZjNTM0NDBlNjc4OWRjZDI5NmJkYjFmNDY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MmE1ZDlhYmZiZDAwMmMzYWU0ZmYyM2ZmNDVkMTRlNWI1ZDNlNmRhNjBmM2Ux
|
14
|
+
MzRmYTUzNDhiOTk3ZTYzODcyODQxZjRjYjgyZTNkN2QyZjgzMDZhYWNiNzZk
|
15
|
+
ZGEyYTE3NDE1ZWFjYmMzMmVkMmU5MTdmZjE0ZGRkMTdiNjMzZmY=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Fernando Aleman
|
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,89 @@
|
|
1
|
+
# Capistrano Recipes [![Build Status](https://travis-ci.org/fernandoaleman/capistrano_recipes.png?branch=master)](https://travis-ci.org/fernandoaleman/capistrano_recipes) [![Dependency Status](https://gemnasium.com/fernandoaleman/capistrano_recipes.png)](https://gemnasium.com/fernandoaleman/capistrano_recipes)
|
2
|
+
|
3
|
+
Powerful capistrano recipes to make your rails deployments fast and easy.
|
4
|
+
|
5
|
+
## Quickstart Guide
|
6
|
+
|
7
|
+
Create a file called 'Capfile' in your application's root directory.
|
8
|
+
|
9
|
+
For a single environment add:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'capistrano/recipes'
|
13
|
+
|
14
|
+
use_recipes :bundler, :git, :rails_assets
|
15
|
+
|
16
|
+
server 'Add your web server domain or ip here', :app, :web, :db, :primary => true
|
17
|
+
|
18
|
+
set :application, "Set application name here"
|
19
|
+
set :deploy_to, "/path/to/your/app/here"
|
20
|
+
set :repository, "Set repository location here"
|
21
|
+
set :domain, "Set domain name here"
|
22
|
+
```
|
23
|
+
|
24
|
+
For a multistage environment add:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
require 'capistrano/recipes'
|
28
|
+
|
29
|
+
use_recipes :bundler, :git, :multistage, :rails_assets
|
30
|
+
|
31
|
+
stage :staging, :branch => :dev, :default => true do
|
32
|
+
server 'Add your web server domain or ip here', :app, :web, :db, :primary => true
|
33
|
+
end
|
34
|
+
|
35
|
+
stage :production, :branch => :master do
|
36
|
+
server 'Add your web server domain or ip here', :app, :web, :db, :primary => true
|
37
|
+
end
|
38
|
+
|
39
|
+
set :application, "Set application name here"
|
40
|
+
set :deploy_to, "/path/to/your/app/here"
|
41
|
+
set :repository, "Set repository location here"
|
42
|
+
set :domain, "Set domain name here"
|
43
|
+
```
|
44
|
+
|
45
|
+
To add a single recipe:
|
46
|
+
```ruby
|
47
|
+
use_recipe :bundle
|
48
|
+
```
|
49
|
+
|
50
|
+
To add multiple recipes:
|
51
|
+
```ruby
|
52
|
+
use_recipes :bundle, :git, :multistage, :rails_assets
|
53
|
+
```
|
54
|
+
|
55
|
+
## Recipes
|
56
|
+
| Recipe | Documentation |
|
57
|
+
| ------------ | ------------- |
|
58
|
+
| :bundle | [Bundle recipe documentation](https://github.com/fernandoaleman/capistrano_recipes/wiki/Bundle) |
|
59
|
+
| :git | [Git recipe documentation](https://github.com/fernandoaleman/capistrano_recipes/wiki/Git) |
|
60
|
+
| :multistage | [Multistage recipe documentation](https://github.com/fernandoaleman/capistrano_recipes/wiki/Multistage) |
|
61
|
+
| :mysql | [Mysql](https://github.com/fernandoaleman/capistrano_recipes/wiki/Mysql) |
|
62
|
+
| :nginx | [Nginx](https://github.com/fernandoaleman/capistrano_recipes/wiki/Nginx) |
|
63
|
+
| :rails_assets | [Rails assets recipe documentation](https://github.com/fernandoaleman/capistrano_recipes/wiki/Rails-Assets) |
|
64
|
+
| :unicorn | [Unicorn](https://github.com/fernandoaleman/capistrano_recipes/wiki/Unicorn) |
|
65
|
+
|
66
|
+
## Installation
|
67
|
+
|
68
|
+
Add this line to your application's Gemfile:
|
69
|
+
|
70
|
+
gem 'capistrano_recipes'
|
71
|
+
|
72
|
+
And then execute:
|
73
|
+
|
74
|
+
$ bundle
|
75
|
+
|
76
|
+
Or install it yourself as:
|
77
|
+
|
78
|
+
$ gem install capistrano_recipes
|
79
|
+
|
80
|
+
## Documentation
|
81
|
+
For more detailed information, visit the [wiki](https://github.com/fernandoaleman/capistrano_recipes/wiki).
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'capistrano_recipes'
|
7
|
+
s.version = '1.0.0'
|
8
|
+
s.authors = ['Fernando Aleman']
|
9
|
+
s.email = ['fernandoaleman@mac.com']
|
10
|
+
s.description = 'Capistrano recipes to make your deployments fast and easy'
|
11
|
+
s.summary = 'Capistrano deployment recipes'
|
12
|
+
s.homepage = 'https://github.com/fernandoaleman/capistrano_recipes'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split($/)
|
16
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency 'capistrano', '~> 2.12'
|
21
|
+
s.add_dependency 'bundler', '~> 1.3'
|
22
|
+
|
23
|
+
s.add_development_dependency 'rspec', '~> 2.5'
|
24
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module CapistranoRecipes
|
2
|
+
module Git
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
default_run_options[:pty] = true
|
6
|
+
ssh_options[:forward_agent] = true
|
7
|
+
|
8
|
+
set(:repository) { abort "Please specify repository, set :repository, 'foo'" }
|
9
|
+
|
10
|
+
_cset :branch, 'master'
|
11
|
+
_cset :use_sudo, false
|
12
|
+
_cset :check_repo, true
|
13
|
+
|
14
|
+
set :migrate_target, :current
|
15
|
+
|
16
|
+
set(:latest_release) { fetch(:current_path) }
|
17
|
+
set(:release_path) { fetch(:current_path) }
|
18
|
+
set(:releases_path) { fetch(:current_path) }
|
19
|
+
set(:current_release) { fetch(:current_path) }
|
20
|
+
set(:current_revision) { capture("cd #{deploy_to} && git rev-parse --short HEAD").strip }
|
21
|
+
set(:latest_revision) { capture("cd #{deploy_to} && git rev-parse --short HEAD").strip }
|
22
|
+
set(:previous_revision) { capture("cd #{deploy_to} && git rev-parse --short HEAD@{1}").strip }
|
23
|
+
|
24
|
+
set :local_branch do
|
25
|
+
`git symbolic-ref HEAD 2> /dev/null`.strip.sub('refs/heads/', '')
|
26
|
+
end
|
27
|
+
|
28
|
+
after 'deploy:setup' do
|
29
|
+
run "git clone --no-checkout #{repository} #{current_path}"
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace :deploy do
|
33
|
+
desc 'Deploy and start a cold application'
|
34
|
+
task :cold do
|
35
|
+
update
|
36
|
+
migrate
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'Update the deployed code through transaction to rollback if it has errors'
|
40
|
+
task :update do
|
41
|
+
transaction do
|
42
|
+
update_code
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'Update the deployed code'
|
47
|
+
task :update_code, :except => { :no_release => true } do
|
48
|
+
run "cd #{deploy_to} && git fetch origin && git reset --hard origin/#{branch}"
|
49
|
+
finalize_update
|
50
|
+
end
|
51
|
+
|
52
|
+
desc 'Run migrations'
|
53
|
+
task :migrate, :roles => :db, :only => { :primary => true } do
|
54
|
+
run "cd #{deploy_to} && RAILS_ENV=#{rails_env} #{rake} db:migrate"
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'Deploy and run migrations'
|
58
|
+
task :migrations do
|
59
|
+
update
|
60
|
+
migrate
|
61
|
+
restart
|
62
|
+
end
|
63
|
+
|
64
|
+
namespace :rollback do
|
65
|
+
desc 'Move repo back to the previous version of HEAD'
|
66
|
+
task :repo, :except => { :no_release => true } do
|
67
|
+
set :branch, "HEAD@{1}"
|
68
|
+
deploy.default
|
69
|
+
end
|
70
|
+
|
71
|
+
desc 'Rewrite reflog so HEAD@{1} will continue to point to the next previous release'
|
72
|
+
task :cleanup, :except => { :no_release => true } do
|
73
|
+
run "cd #{deploy_to}; git reflog delete --rewrite HEAD@{1}; git reflog delete --rewrite HEAD@{1}"
|
74
|
+
end
|
75
|
+
|
76
|
+
desc 'Roll back to the previously deployed version'
|
77
|
+
task :default do
|
78
|
+
rollback.repo
|
79
|
+
rollback.cleanup
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
namespace :pending do
|
84
|
+
task :diff, :except => { :no_release => true } do
|
85
|
+
# nothing
|
86
|
+
end
|
87
|
+
|
88
|
+
desc 'Show pending commits'
|
89
|
+
task :default do
|
90
|
+
system("git log --pretty=medium --stat #{current_revision}..origin/#{branch}")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
desc 'Check that local git repo is in sync with remote'
|
95
|
+
task :check_repo do
|
96
|
+
unless `git rev-parse HEAD` == `git rev-parse origin/#{branch}`
|
97
|
+
puts "WARNING: HEAD is not the same as origin/#{branch}"
|
98
|
+
puts "Run `git push origin #{branch}` to sync changes."
|
99
|
+
exit
|
100
|
+
end if fetch(:check_repo)
|
101
|
+
end
|
102
|
+
%w[deploy deploy:cold deploy:migrations].each do |task|
|
103
|
+
before "#{task}", "deploy:check_repo"
|
104
|
+
end
|
105
|
+
|
106
|
+
task :symlink do
|
107
|
+
# nothing
|
108
|
+
# if task is not being used, it will not appear in `cap -T`
|
109
|
+
end
|
110
|
+
|
111
|
+
task :create_symlink do
|
112
|
+
# nothing
|
113
|
+
# if task is not being used, it will not appear in `cap -T`
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module CapistranoRecipes
|
2
|
+
module Multistage
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
set :multistage_config, Config.new(configuration)
|
6
|
+
|
7
|
+
def stage(name, options={}, &block)
|
8
|
+
set :default_stage, name.to_sym if options.delete(:default)
|
9
|
+
multistage_config.stage(name, options)
|
10
|
+
callbacks[:start].detect { |c| c.source == 'multistage:ensure' }.except << name.to_s
|
11
|
+
|
12
|
+
task(name) do
|
13
|
+
set :current_stage, name.to_s
|
14
|
+
set :rails_env, name.to_s
|
15
|
+
options.each do |k, v|
|
16
|
+
set k, v if v
|
17
|
+
end
|
18
|
+
block.call if block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
namespace :multistage do
|
23
|
+
task :ensure do
|
24
|
+
unless exists?(:current_stage)
|
25
|
+
if stage = multistage_config.inferred_stage
|
26
|
+
find_and_execute_task(stage.name)
|
27
|
+
elsif exists?(:default_stage)
|
28
|
+
find_and_execute_task(default_stage)
|
29
|
+
else
|
30
|
+
stage_names = multistage_config.stages.map(&:name)
|
31
|
+
abort "No stage specified. Please specify one of: #{stage_names.join(', ')} (e.g. `cap #{stage_names.first} #{ARGV.last}')"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
on :start, 'multistage:ensure'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Handles multistage configuration
|
42
|
+
class Config
|
43
|
+
attr_reader :config
|
44
|
+
attr_reader :stages
|
45
|
+
|
46
|
+
def initialize(config)
|
47
|
+
@config = config
|
48
|
+
@stages = []
|
49
|
+
end
|
50
|
+
|
51
|
+
def stage(name, options={})
|
52
|
+
stages << Stage.new(name, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def inferred_stage
|
56
|
+
if config.using_recipe?(:git)
|
57
|
+
branch = config.local_branch
|
58
|
+
stages.find { |stage| stage.options[:branch].to_s == branch }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Stage
|
64
|
+
attr_reader :name
|
65
|
+
attr_reader :options
|
66
|
+
|
67
|
+
def initialize(name, options={})
|
68
|
+
@name = name
|
69
|
+
@options = options
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module CapistranoRecipes
|
2
|
+
module Mysql
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
# MySQL admin user with access to create databases and grant permissions
|
6
|
+
_cset :mysql_admin_user, lambda { ask "Enter #{rails_env} database username with access to create database" }
|
7
|
+
|
8
|
+
# Application database adapter
|
9
|
+
_cset :mysql_adapter, lambda { 'mysql2' }
|
10
|
+
|
11
|
+
# Application database name
|
12
|
+
_cset :mysql_database, lambda { "#{application}_#{rails_env}" }
|
13
|
+
|
14
|
+
# Application database user
|
15
|
+
_cset :mysql_user, lambda { ask "Enter #{rails_env} database username" }
|
16
|
+
|
17
|
+
# Application database password
|
18
|
+
_cset(:mysql_password) { password_prompt "Enter #{rails_env} database password" }
|
19
|
+
|
20
|
+
# Application database host
|
21
|
+
_cset :mysql_host, lambda { 'localhost' }
|
22
|
+
|
23
|
+
# Application database encoding
|
24
|
+
_cset :mysql_encoding, lambda { 'utf8' }
|
25
|
+
|
26
|
+
# Path to local database config template
|
27
|
+
_cset :mysql_local_config_template, lambda { "#{templates_path}/mysql.yml.erb" }
|
28
|
+
|
29
|
+
# Path to remote database config file
|
30
|
+
_cset :mysql_remote_config_file, lambda { "#{config_path}/database.yml" }
|
31
|
+
|
32
|
+
# Application database backup file
|
33
|
+
_cset :mysql_backup_file, lambda { "#{application}-backup.sql.bz2" }
|
34
|
+
|
35
|
+
# Path to local database backup file
|
36
|
+
_cset :mysql_local_backup_file, lambda { "tmp/#{mysql_backup_file}" }
|
37
|
+
|
38
|
+
# Path to remote database backup file
|
39
|
+
_cset :mysql_remote_backup_file, lambda { "#{backup_path}/#{mysql_backup_file}" }
|
40
|
+
|
41
|
+
namespace :mysql do
|
42
|
+
desc 'Generate the database.yml configuration file'
|
43
|
+
task :setup, :roles => :app, :except => { :no_release => true } do
|
44
|
+
upload_template mysql_local_config_template, mysql_remote_config_file
|
45
|
+
end
|
46
|
+
after 'deploy:setup' do
|
47
|
+
mysql.setup if agree? 'Setup database.yml?'
|
48
|
+
mysql.create if agree? 'Create database?'
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'Create mysql database'
|
52
|
+
task :create, :roles => :db, :only => { :primary => true } do
|
53
|
+
sql = <<-SQL.gsub(/^ {14}/, '')
|
54
|
+
"CREATE DATABASE #{mysql_database};
|
55
|
+
GRANT ALL PRIVILEGES ON #{mysql_database}.* TO #{mysql_user}@localhost IDENTIFIED BY '#{mysql_password}';"
|
56
|
+
SQL
|
57
|
+
|
58
|
+
mysql_admin = mysql_admin_user
|
59
|
+
|
60
|
+
run "mysql --user=#{mysql_user} -p --execute=#{sql}" do |channel, stream, data|
|
61
|
+
if data =~ /^Enter password:/
|
62
|
+
pass = password_prompt "Enter database password for '#{mysql_admin}'"
|
63
|
+
channel.send_data "#{pass}\n"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Symlink the database.yml file into the latest deploy'
|
69
|
+
task :symlink, :roles => :app, :except => { :no_release => true } do
|
70
|
+
run "ln -nfs #{mysql_remote_config} #{release_path}/config/database.yml"
|
71
|
+
end
|
72
|
+
after 'deploy:finalize_update', 'mysql:symlink'
|
73
|
+
|
74
|
+
desc 'Populate the database with seed data'
|
75
|
+
task :seed do
|
76
|
+
run "cd #{current_path} && #{rake} RAILS_ENV=#{rails_env} db:seed"
|
77
|
+
end
|
78
|
+
after 'deploy:cold' do
|
79
|
+
mysql.seed if agree? 'Load seed data into database?'
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'Performs a mysqldump of the database'
|
83
|
+
task :dump, :roles => :db, :only => { :primary => true } do
|
84
|
+
prepare_from_yaml
|
85
|
+
|
86
|
+
run "mysqldump --user=#{db_user} -p --host=#{db_host} #{db_name} | bzip2 -z9 > #{mysql_remote_backup_file}" do |channel, stream, out|
|
87
|
+
channel.send_data "#{db_pass}\n" if out =~ /^Enter password:/
|
88
|
+
puts out
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
desc "Download compressed database dump"
|
93
|
+
task :fetch_dump, :roles => :db, :only => { :primary => true } do
|
94
|
+
download mysql_remote_backup_file, mysql_local_backup_file, :via => :scp
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "Restore the database from the latest compressed dump"
|
98
|
+
task :restore, :roles => :db, :only => { :primary => true } do
|
99
|
+
prepare_from_yaml
|
100
|
+
|
101
|
+
run "bzcat #{mysql_remote_backup_file} | mysql --user=#{db_user} -p --host=#{db_host} #{db_name}" do |channel, stream, out|
|
102
|
+
channel.send_data "#{db_pass}\n" if out =~ /^Enter password:/
|
103
|
+
puts out
|
104
|
+
end if agree? 'Are you sure you want to restore your database?'
|
105
|
+
end
|
106
|
+
|
107
|
+
%w[start stop restart status].each do |command|
|
108
|
+
desc "#{command.capitalize} mysql"
|
109
|
+
task command, :roles => :db, :only => { :primary => true } do
|
110
|
+
run "#{sudo} service mysqld #{command}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def prepare_from_yaml
|
116
|
+
set(:db_user) { db_config[rails_env]["username"] }
|
117
|
+
set(:db_pass) { db_config[rails_env]["password"] }
|
118
|
+
set(:db_host) { db_config[rails_env]["host"] }
|
119
|
+
set(:db_name) { db_config[rails_env]["database"] }
|
120
|
+
end
|
121
|
+
|
122
|
+
def db_config
|
123
|
+
@db_config ||= fetch_db_config
|
124
|
+
end
|
125
|
+
|
126
|
+
def fetch_db_config
|
127
|
+
require 'yaml'
|
128
|
+
file = capture "cat #{mysql_remote_config_file}"
|
129
|
+
db_config = YAML.load(file)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module CapistranoRecipes
|
2
|
+
module Nginx
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
# Nginx path on server
|
6
|
+
_cset :nginx_path, '/etc/nginx'
|
7
|
+
|
8
|
+
# Nginx http port
|
9
|
+
_cset :nginx_port, '80'
|
10
|
+
|
11
|
+
# Path to local nginx vhost template
|
12
|
+
_cset(:nginx_local_site_available_template) { "#{templates_path}/nginx.vhost.erb" }
|
13
|
+
|
14
|
+
# Path to remote sites-available location
|
15
|
+
_cset :nginx_remote_site_available_file, lambda { "#{nginx_path}/sites-available/#{application}" }
|
16
|
+
|
17
|
+
# Path to remote sites-enabled location
|
18
|
+
_cset :nginx_remote_site_enabled_link, lambda { "#{nginx_path}/sites-enabled/#{application}" }
|
19
|
+
|
20
|
+
# Whether or not to use ssl
|
21
|
+
_cset :use_ssl, false
|
22
|
+
|
23
|
+
# Nginx https port
|
24
|
+
_cset :nginx_ssl_port, '443'
|
25
|
+
|
26
|
+
# Nginx ssl directory on server
|
27
|
+
_cset :nginx_ssl_dir, 'ssl'
|
28
|
+
|
29
|
+
# Nginx ssl path on server
|
30
|
+
_cset :nginx_ssl_path, lambda { File.join nginx_path, nginx_ssl_dir }
|
31
|
+
|
32
|
+
# Nginx ssl certificates directory on server
|
33
|
+
_cset :nginx_ssl_certs_dir, 'certs'
|
34
|
+
|
35
|
+
# Nginx ssl private keys directory on server
|
36
|
+
_cset :nginx_ssl_private_dir, 'private'
|
37
|
+
|
38
|
+
# Nginx ssl certificates path on server
|
39
|
+
_cset :nginx_ssl_certs_path, lambda { File.join nginx_ssl_path, nginx_ssl_certs_dir }
|
40
|
+
|
41
|
+
# Nginx ssl private keys path on server
|
42
|
+
_cset :nginx_ssl_private_path, lambda { File.join nginx_ssl_path, nginx_ssl_private_dir }
|
43
|
+
|
44
|
+
# Nginx ssl certificate file
|
45
|
+
_cset :nginx_ssl_cert, lambda { "#{application}.crt" }
|
46
|
+
|
47
|
+
# Nginx ssl key file
|
48
|
+
_cset :nginx_ssl_key, lambda { "#{application}.key" }
|
49
|
+
|
50
|
+
def using_ssl?
|
51
|
+
fetch(:use_ssl)
|
52
|
+
end
|
53
|
+
|
54
|
+
namespace :nginx do
|
55
|
+
desc 'Create and upload nginx vhost'
|
56
|
+
task :setup, :roles => :web, :except => { :no_release => true } do
|
57
|
+
upload_template nginx_local_site_available_template, nginx_remote_site_available_file
|
58
|
+
run "#{sudo} ln -nfs #{nginx_remote_site_available_file} #{nginx_remote_site_enabled_link}"
|
59
|
+
restart
|
60
|
+
end
|
61
|
+
after 'deploy:setup' do
|
62
|
+
nginx.setup if agree?("Create and upload nginx vhost for #{application}?")
|
63
|
+
end
|
64
|
+
|
65
|
+
%w[start stop restart status].each do |command|
|
66
|
+
desc "#{command.capitalize} nginx"
|
67
|
+
task command, :roles => :app, :except => { :no_release => true } do
|
68
|
+
run "#{sudo} service nginx #{command}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|