capistrano-exts 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Guardfile +13 -0
- data/Rakefile +9 -0
- data/capistrano-exts.gemspec +35 -0
- data/examples/php_fpm/deploy/development.rb +121 -0
- data/examples/php_fpm/deploy/production.rb +121 -0
- data/examples/php_fpm/deploy/staging.rb +121 -0
- data/examples/php_fpm/deploy.rb +38 -0
- data/examples/rails_passenger/deploy/development.rb +121 -0
- data/examples/rails_passenger/deploy/production.rb +121 -0
- data/examples/rails_passenger/deploy/staging.rb +121 -0
- data/examples/rails_passenger/deploy.rb +38 -0
- data/examples/rails_reverse_proxy/deploy/development.rb +121 -0
- data/examples/rails_reverse_proxy/deploy/production.rb +121 -0
- data/examples/rails_reverse_proxy/deploy/staging.rb +121 -0
- data/examples/rails_reverse_proxy/deploy.rb +38 -0
- data/lib/capistrano-exts/core_ext/string/filters.rb +12 -0
- data/lib/capistrano-exts/core_ext.rb +10 -0
- data/lib/capistrano-exts/receipts/base.rb +22 -0
- data/lib/capistrano-exts/receipts/contao.rb +81 -0
- data/lib/capistrano-exts/receipts/functions.rb +55 -0
- data/lib/capistrano-exts/receipts/git.rb +37 -0
- data/lib/capistrano-exts/receipts/god.rb +30 -0
- data/lib/capistrano-exts/receipts/multistage.rb +90 -0
- data/lib/capistrano-exts/receipts/mysql.rb +214 -0
- data/lib/capistrano-exts/receipts/rails.rb +45 -0
- data/lib/capistrano-exts/receipts/servers/db_server.rb +19 -0
- data/lib/capistrano-exts/receipts/servers/web_server/apache.rb +55 -0
- data/lib/capistrano-exts/receipts/servers/web_server/nginx.rb +81 -0
- data/lib/capistrano-exts/receipts/servers/web_server.rb +112 -0
- data/lib/capistrano-exts/receipts/servers.rb +51 -0
- data/lib/capistrano-exts/receipts/unicorn.rb +27 -0
- data/lib/capistrano-exts/receipts.rb +17 -0
- data/lib/capistrano-exts/servers/utils/erb.rb +16 -0
- data/lib/capistrano-exts/servers/utils/variables.rb +25 -0
- data/lib/capistrano-exts/servers/web_server/nginx.rb +20 -0
- data/lib/capistrano-exts/servers/web_server.rb +69 -0
- data/lib/capistrano-exts/templates/multistage.rb +118 -0
- data/lib/capistrano-exts/templates/web_servers/nginx.conf.erb +95 -0
- data/lib/capistrano-exts/version.rb +12 -0
- data/lib/capistrano-exts.rb +14 -0
- data/spec/rendered_templates/nginx_php_fpm.conf +58 -0
- data/spec/requests/nginx_spec.rb +38 -0
- data/spec/servers/web_server/nginx_spec.rb +179 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/factories.rb +1 -0
- metadata +220 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Require active_support core extensions
|
4
|
+
require 'active_support/core_ext'
|
5
|
+
|
6
|
+
# Active Support's core_ext define capture, remove it in favor of capistrano's capture function
|
7
|
+
alias :__capture__ :capture
|
8
|
+
undef :capture
|
9
|
+
|
10
|
+
Dir["#{File.dirname(__FILE__)}/core_ext/**/*.rb"].each { |f| require f }
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
|
3
|
+
# Verify that Capistrano is version 2
|
4
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
5
|
+
abort "This extension requires Capistrano 2"
|
6
|
+
end
|
7
|
+
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
namespace :deploy do
|
10
|
+
desc "Check if the remote is ready, should we run cap deploy:setup?"
|
11
|
+
task :check_if_remote_ready, :roles => :web do
|
12
|
+
unless remote_file_exists?("#{shared_path}")
|
13
|
+
puts "ERROR: The project is not ready for deployment."
|
14
|
+
puts "please run `cap deploy:setup"
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Dependencies
|
21
|
+
before "deploy", "deploy:check_if_remote_ready"
|
22
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'capistrano-exts/receipts/base'
|
3
|
+
require 'capistrano-exts/receipts/mysql'
|
4
|
+
|
5
|
+
# Verify that Capistrano is version 2
|
6
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
7
|
+
abort "This extension requires Capistrano 2"
|
8
|
+
end
|
9
|
+
|
10
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
11
|
+
namespace :deploy do
|
12
|
+
desc "Empty task, overriden by #{__FILE__}"
|
13
|
+
task :finalize_update do
|
14
|
+
# Empty task, we do not want to delete the system folder.
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
namespace :contao do
|
19
|
+
desc "[internal] Setup contao shared contents"
|
20
|
+
task :setup, :roles => :app, :except => { :no_release => true } do
|
21
|
+
run <<-CMD
|
22
|
+
#{try_sudo} mkdir -p #{shared_path}/log &&
|
23
|
+
#{try_sudo} mkdir -p #{shared_path}/contenu &&
|
24
|
+
#{try_sudo} mkdir -p #{shared_path}/contenu/images &&
|
25
|
+
#{try_sudo} mkdir -p #{shared_path}/contenu/videos &&
|
26
|
+
#{try_sudo} mkdir -p #{shared_path}/contenu/son &&
|
27
|
+
#{try_sudo} mkdir -p #{shared_path}/contenu/pdfs
|
28
|
+
CMD
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "[internal] Setup contao's localconfig"
|
32
|
+
task :setup_localconfig, :roles => :app, :except => { :no_release => true } do
|
33
|
+
localconfig = File.read("public/system/config/localconfig.php.sample")
|
34
|
+
mysql_credentials = fetch :mysql_credentials
|
35
|
+
|
36
|
+
# localconfig
|
37
|
+
if mysql_credentials.blank?
|
38
|
+
puts "WARNING: The mysql credential file can't be found, localconfig has just been copied from the sample file"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Add MySQL credentials
|
42
|
+
unless localconfig.blank? or mysql_credentials.blank?
|
43
|
+
localconfig.gsub!(/#DB_USER#/, mysql_credentials[:user])
|
44
|
+
localconfig.gsub!(/#DB_PASS#/, mysql_credentials[:pass])
|
45
|
+
localconfig.gsub!(/#DB_NAME#/, mysql_db_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
put localconfig, "#{shared_path}/localconfig.php"
|
49
|
+
end
|
50
|
+
|
51
|
+
task :fix_links, :roles => :app, :except => { :no_release => true } do
|
52
|
+
run <<-CMD
|
53
|
+
#{try_sudo} rm -rf #{fetch :latest_release}/public/tl_files/durable/contenu &&
|
54
|
+
#{try_sudo} rm -rf #{fetch :latest_release}/log &&
|
55
|
+
#{try_sudo} ln -nsf #{fetch :shared_path}/contenu #{fetch :latest_release}/public/tl_files/durable/contenu &&
|
56
|
+
#{try_sudo} ln -nsf #{fetch :shared_path}/htaccess.txt #{fetch :latest_release}/public/.htaccess &&
|
57
|
+
#{try_sudo} ln -nsf #{fetch :shared_path}/localconfig.php #{fetch :latest_release}/public/system/config/localconfig.php &&
|
58
|
+
#{try_sudo} ln -nsf #{fetch :shared_path}/log #{fetch :latest_release}/log
|
59
|
+
CMD
|
60
|
+
end
|
61
|
+
|
62
|
+
task :fix_permissions, :roles => :app, :except => { :no_release => true } do
|
63
|
+
run <<-CMD
|
64
|
+
#{try_sudo} chown -R www-data:www-data #{deploy_to} &&
|
65
|
+
#{try_sudo} chmod -R g+w #{latest_release}
|
66
|
+
CMD
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Dependencies
|
71
|
+
after "deploy:setup", "contao:setup"
|
72
|
+
after "contao:setup", "contao:setup_localconfig"
|
73
|
+
after "contao:setup_localconfig", "mysql:create_db"
|
74
|
+
after "deploy:finalize_update", "contao:fix_links"
|
75
|
+
after "contao:fix_links", "deploy:cleanup"
|
76
|
+
after "deploy:restart", "contao:fix_permissions"
|
77
|
+
|
78
|
+
# Mysql Credentials
|
79
|
+
before "contao:setup_localconfig", "mysql:credentials"
|
80
|
+
before "contao:setup_db", "mysql:credentials"
|
81
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'highline'
|
3
|
+
|
4
|
+
# Verify that Capistrano is version 2
|
5
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
6
|
+
abort "This extension requires Capistrano 2"
|
7
|
+
end
|
8
|
+
|
9
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
10
|
+
# Taken from Stackoverflow
|
11
|
+
# http://stackoverflow.com/questions/1661586/how-can-you-check-to-see-if-a-file-exists-on-the-remote-server-in-capistrano
|
12
|
+
def remote_file_exists?(full_path)
|
13
|
+
'true' == capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
|
14
|
+
end
|
15
|
+
|
16
|
+
def link_file(source_file, destination_file)
|
17
|
+
if remote_file_exists?(source_file)
|
18
|
+
run "#{try_sudo} ln -nsf #{source_file} #{destination_file}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def link_config_file(config_file, config_path = nil)
|
23
|
+
config_path ||= "#{File.join release_path, 'config'}"
|
24
|
+
link_file("#{File.join shared_path, 'config', config_file}", "#{File.join config_path, config_file}")
|
25
|
+
end
|
26
|
+
|
27
|
+
def gen_pass( len = 8 )
|
28
|
+
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
29
|
+
newpass = ""
|
30
|
+
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
|
31
|
+
return newpass
|
32
|
+
end
|
33
|
+
|
34
|
+
def ask(what, options)
|
35
|
+
default = options[:default]
|
36
|
+
validate = options[:validate] || /(y(es)?)|(no?)|(a(bort)?|\n)/i
|
37
|
+
echo = (options[:echo].nil?) ? true : options[:echo]
|
38
|
+
|
39
|
+
ui = HighLine.new
|
40
|
+
ui.ask("#{what}? ") do |q|
|
41
|
+
q.overwrite = false
|
42
|
+
q.default = default
|
43
|
+
q.validate = validate
|
44
|
+
q.responses[:not_valid] = what
|
45
|
+
unless echo
|
46
|
+
q.echo = "*"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def mysql_db_name(local_branch = nil)
|
52
|
+
local_branch ||= fetch :branch
|
53
|
+
"#{fetch :application}_co_#{local_branch}"
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'highline'
|
3
|
+
require 'capistrano-exts/receipts/base'
|
4
|
+
|
5
|
+
# Verify that Capistrano is version 2
|
6
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
7
|
+
abort "This extension requires Capistrano 2"
|
8
|
+
end
|
9
|
+
|
10
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
11
|
+
namespace :deploy do
|
12
|
+
desc "Check if the branch is ready"
|
13
|
+
task :check_if_branch_is_ready, :roles => :app, :except => { :no_release => true } do
|
14
|
+
unless `git rev-parse #{branch}` == `git rev-parse origin/#{branch}`
|
15
|
+
puts "ERROR: #{branch} is not the same as origin/#{branch}"
|
16
|
+
puts "Run `git push` to sync changes."
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Check if this revision has already been deployed."
|
22
|
+
task :check_revision, :roles => :app, :except => { :no_release => true } do
|
23
|
+
if remote_file_exists?("#{deploy_to}/current/REVISION")
|
24
|
+
if `git rev-parse #{branch}`.strip == capture("cat #{deploy_to}/current/REVISION").strip
|
25
|
+
response = ask("The verison you are trying to deploy is already deployed, should I continue (Yes, [No], Abort)", default: 'No')
|
26
|
+
if response =~ /(no?)|(a(bort)?|\n)/i
|
27
|
+
abort "Canceled by the user."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Dependencies
|
35
|
+
before "deploy", "deploy:check_if_branch_is_ready"
|
36
|
+
after "deploy:check_if_branch_is_ready", "deploy:check_revision"
|
37
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
|
3
|
+
# Verify that Capistrano is version 2
|
4
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
5
|
+
abort "This extension requires Capistrano 2"
|
6
|
+
end
|
7
|
+
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
namespace :god do
|
10
|
+
desc "start god, this starts up unicorn server"
|
11
|
+
task :start, :roles => :web, :except => {:no_release => true} do
|
12
|
+
run "cd #{current_path} && #{god_binary} -c #{god_config} --log /var/log/god.log --no-syslog --log-level warn"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "stop god, this shutdowns unicorn server"
|
16
|
+
task :stop, :roles => :web, :except => {:no_release => true} do
|
17
|
+
run "cd #{current_path} && #{god_binary} terminate"
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "restart god, this restarts the unicorn server"
|
21
|
+
task :restart, :roles => :web, :except => {:no_release => true} do
|
22
|
+
run "cd #{current_path} && #{god_binary} restart"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "check if god is already running"
|
26
|
+
task :check_if_running, :roles => :web, :except => {:no_release => true} do
|
27
|
+
'true' == capture("if #{god_binary} status; then echo 'true'; fi").strip
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# This files has been copied over from capistrano-ext
|
2
|
+
# https://github.com/capistrano/capistrano-ext and has been modified
|
3
|
+
# To allow configuration in either seperate files or in-line configurations
|
4
|
+
|
5
|
+
require 'capistrano'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
9
|
+
abort "This extension requires Capistrano 2"
|
10
|
+
end
|
11
|
+
|
12
|
+
Capistrano::Configuration.instance.load do
|
13
|
+
location = fetch(:stage_dir, "config/deploy")
|
14
|
+
|
15
|
+
unless exists?(:stages)
|
16
|
+
if exists?(:multistages)
|
17
|
+
set :stages, fetch(:multistages).keys
|
18
|
+
else
|
19
|
+
set :stages, Dir["#{location}/*.rb"].map { |f| File.basename(f, ".rb") }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
stages.each do |name|
|
24
|
+
desc "Set the target stage to `#{name}'."
|
25
|
+
task(name) do
|
26
|
+
set :stage, name.to_sym
|
27
|
+
begin
|
28
|
+
load "#{location}/#{stage}" unless exists?(:multistages)
|
29
|
+
rescue LoadError
|
30
|
+
abort "The file #{location}/#{stage} does not exist please run 'cap multistage:prepare'"
|
31
|
+
end
|
32
|
+
find_and_execute_task('multistage:parse_multistages') if exists?(:multistages)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
on :load do
|
37
|
+
if stages.include?(ARGV.first)
|
38
|
+
# Execute the specified stage so that recipes required in stage can contribute to task list
|
39
|
+
find_and_execute_task(ARGV.first) if ARGV.any?{ |option| option =~ /-T|--tasks|-e|--explain/ }
|
40
|
+
else
|
41
|
+
# Execute the default stage so that recipes required in stage can contribute tasks
|
42
|
+
find_and_execute_task(default_stage) if exists?(:default_stage)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
namespace :multistage do
|
47
|
+
desc "[internal] Ensure that a stage has been selected."
|
48
|
+
task :ensure do
|
49
|
+
if !exists?(:stage)
|
50
|
+
if exists?(:default_stage)
|
51
|
+
logger.important "Defaulting to `#{default_stage}'"
|
52
|
+
find_and_execute_task(default_stage)
|
53
|
+
else
|
54
|
+
abort "No stage specified. Please specify one of: #{stages.join(', ')} (e.g. `cap #{stages.first} #{ARGV.last}')"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "Stub out the staging config files."
|
60
|
+
task :prepare do
|
61
|
+
FileUtils.mkdir_p(location)
|
62
|
+
stages.each do |name|
|
63
|
+
file = File.join(location, name.to_s + ".rb")
|
64
|
+
unless File.exists?(file)
|
65
|
+
File.open(file, "w") do |f|
|
66
|
+
f.puts "# #{name.to_s.upcase}-specific deployment configuration"
|
67
|
+
f.puts "# please put general deployment config in config/deploy.rb"
|
68
|
+
f.puts ""
|
69
|
+
f.write File.read(File.expand_path(File.join File.dirname(__FILE__), '..', 'templates', 'multistage.rb'))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "[internal] Parse the configuration"
|
76
|
+
task :parse_multistages do
|
77
|
+
multistages = fetch :multistages
|
78
|
+
stage = fetch :stage
|
79
|
+
|
80
|
+
if multistages[stage].nil?
|
81
|
+
abort "ERROR: '#{stage.to_s}' has not been configured yet, please open up 'config/deploy.rb' and configure it"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Parse multistages
|
85
|
+
multistages[stage].each { |config, value| set config, value }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
on :start, "multistage:ensure", :except => stages + ['multistage:prepare', 'multistage:parse_multistages']
|
90
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'capistrano-exts/receipts/base'
|
3
|
+
|
4
|
+
# Verify that Capistrano is version 2
|
5
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
6
|
+
abort "This extension requires Capistrano 2"
|
7
|
+
end
|
8
|
+
|
9
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
10
|
+
namespace :mysql do
|
11
|
+
desc "Backup database"
|
12
|
+
task :backup_db, :roles => :db, :except => { :no_release => true } do
|
13
|
+
mysql_credentials = fetch :mysql_credentials
|
14
|
+
MYSQL_DB_BACKUP_PATH = "#{deploy_to}/backups/#{mysql_db_name}_#{Time.now.strftime('%d-%m-%Y_%H-%M-%S')}.sql"
|
15
|
+
|
16
|
+
if exists?(:mysql_credentials)
|
17
|
+
begin
|
18
|
+
run <<-CMD
|
19
|
+
#{try_sudo} mysqldump \
|
20
|
+
--host='#{mysql_credentials[:host]}'\
|
21
|
+
--user='#{mysql_credentials[:user]}' \
|
22
|
+
--password='#{mysql_credentials[:pass]}' \
|
23
|
+
--default-character-set=utf8 \
|
24
|
+
'#{mysql_db_name}' > \
|
25
|
+
'#{MYSQL_DB_BACKUP_PATH}'
|
26
|
+
CMD
|
27
|
+
|
28
|
+
run <<-CMD
|
29
|
+
#{try_sudo} bzip2 -9 '#{MYSQL_DB_BACKUP_PATH}'
|
30
|
+
CMD
|
31
|
+
rescue
|
32
|
+
puts "WARNING: The database doesn't exist."
|
33
|
+
end
|
34
|
+
else
|
35
|
+
abort "MySQL credentials are empty"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "drop database"
|
40
|
+
task :drop_db, :roles => :db, :except => { :no_release => true } do
|
41
|
+
mysql_credentials = fetch :mysql_credentials
|
42
|
+
|
43
|
+
unless mysql_credentials.blank?
|
44
|
+
begin
|
45
|
+
run <<-CMD
|
46
|
+
mysqladmin \
|
47
|
+
--host='#{mysql_credentials[:host]}' \
|
48
|
+
--user='#{mysql_credentials[:user]}' \
|
49
|
+
--password='#{mysql_credentials[:pass]}' \
|
50
|
+
drop --force \
|
51
|
+
'#{mysql_db_name}'
|
52
|
+
CMD
|
53
|
+
rescue
|
54
|
+
puts "WARNING: The database doesn't exist."
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "create database"
|
60
|
+
task :create_db, :roles => :db, :except => { :no_release => true } do
|
61
|
+
mysql_credentials = fetch :mysql_credentials
|
62
|
+
|
63
|
+
unless mysql_credentials.blank?
|
64
|
+
begin
|
65
|
+
run <<-CMD
|
66
|
+
mysqladmin \
|
67
|
+
--host='#{mysql_credentials[:host]}' \
|
68
|
+
--user='#{mysql_credentials[:user]}' \
|
69
|
+
--password='#{mysql_credentials[:pass]}' \
|
70
|
+
create '#{mysql_db_name}'
|
71
|
+
CMD
|
72
|
+
rescue
|
73
|
+
puts "WARNING: The database already exists, it hasn't been modified, drop it manually if necessary."
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
desc "Import a database dump"
|
79
|
+
task :import_db_dump, :roles => :db, :except => { :no_release => true } do
|
80
|
+
mysql_credentials = fetch :mysql_credentials
|
81
|
+
|
82
|
+
unless ARGV.size >=2 and File.exists?(ARGV[1])
|
83
|
+
puts "ERROR: please run 'cap mysql:import_db_dump <sql dump>'"
|
84
|
+
exit 1
|
85
|
+
else
|
86
|
+
# The database dump name
|
87
|
+
dump_sql_file = ARGV.delete_at(1)
|
88
|
+
|
89
|
+
if mysql_credentials.present?
|
90
|
+
drop_db
|
91
|
+
create_db
|
92
|
+
put File.read(dump_sql_file), "/tmp/#{mysql_db_name}_dump.sql"
|
93
|
+
|
94
|
+
run <<-CMD
|
95
|
+
mysql \
|
96
|
+
--host='#{mysql_credentials[:host]}' \
|
97
|
+
--user='#{mysql_credentials[:user]}' \
|
98
|
+
--password='#{mysql_credentials[:pass]}' \
|
99
|
+
--default-character-set=utf8 \
|
100
|
+
'#{mysql_db_name}' < \
|
101
|
+
/tmp/#{mysql_db_name}_dump.sql
|
102
|
+
CMD
|
103
|
+
|
104
|
+
run <<-CMD
|
105
|
+
rm -f '/tmp/#{mysql_db_name}_dump.sql'
|
106
|
+
CMD
|
107
|
+
|
108
|
+
exit 0
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
desc "Export a database dump"
|
114
|
+
task :export_db_dump, :roles => :db, :except => { :no_release => true } do
|
115
|
+
mysql_credentials = fetch :mysql_credentials
|
116
|
+
|
117
|
+
unless ARGV.size >=2 or File.exists?(ARGV[1])
|
118
|
+
puts "ERROR: please run 'cap mysql:import_db_dump <sql dump>'"
|
119
|
+
puts " <sql dump> should not exist"
|
120
|
+
exit 1
|
121
|
+
else
|
122
|
+
# The database dump name
|
123
|
+
dump_sql_file = ARGV.delete_at(1)
|
124
|
+
|
125
|
+
if mysql_credentials.present?
|
126
|
+
run <<-CMD
|
127
|
+
cp #{MYSQL_DB_BACKUP_PATH}.bz2 /tmp &&
|
128
|
+
bunzip2 /tmp/#{File.basename MYSQL_DB_BACKUP_PATH}.bz2
|
129
|
+
CMD
|
130
|
+
|
131
|
+
get "/tmp/#{File.basename MYSQL_DB_BACKUP_PATH}", dump_sql_file
|
132
|
+
|
133
|
+
run <<-CMD
|
134
|
+
rm -f /tmp/#{File.basename MYSQL_DB_BACKUP_PATH}
|
135
|
+
CMD
|
136
|
+
|
137
|
+
exit 0
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
desc "Get Mysql credentials"
|
143
|
+
task :credentials, :roles => :app, :except => { :no_release => true } do
|
144
|
+
mysql_credentials_file = fetch :mysql_credentials_file
|
145
|
+
|
146
|
+
unless exists?(:mysql_credentials)
|
147
|
+
# We haven't got the credentials yet, look for them
|
148
|
+
if exists?(:mysql_credentials_file) and remote_file_exists?(mysql_credentials_file)
|
149
|
+
begin
|
150
|
+
set :mysql_credentials_file_contents, capture("cat #{mysql_credentials_file}")
|
151
|
+
rescue
|
152
|
+
set :mysql_credentials, false
|
153
|
+
end
|
154
|
+
|
155
|
+
if exists?(:mysql_credentials_file_contents)
|
156
|
+
set :mysql_credentials, {
|
157
|
+
host: mysql_credentials_file_contents.match(mysql_credentials_host_regex)[mysql_credentials_host_regex_match].chomp,
|
158
|
+
user: mysql_credentials_file_contents.match(mysql_credentials_user_regex)[mysql_credentials_user_regex_match].chomp,
|
159
|
+
pass: mysql_credentials_file_contents.match(mysql_credentials_pass_regex)[mysql_credentials_pass_regex_match].chomp,
|
160
|
+
}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Verify that we got them!
|
165
|
+
if !exists?(:mysql_credentials)
|
166
|
+
set :mysql_credentials, {
|
167
|
+
host: ask("What is the hostname used to access the database", default: 'localhost', validate: /.+/),
|
168
|
+
user: ask("What is the username used to access the database", default: nil, validate: /.+/),
|
169
|
+
pass: ask("What is the password used to access the database", default: nil, validate: /.+/, echo: false),
|
170
|
+
}
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
desc "Get Mysql root credentials"
|
176
|
+
task :root_credentials, :roles => :app, :except => { :no_release => true } do
|
177
|
+
mysql_root_credentials_file = fetch :mysql_root_credentials_file
|
178
|
+
|
179
|
+
unless exists?(:mysql_root_credentials)
|
180
|
+
# We haven't got the credentials yet, look for them
|
181
|
+
if exists?(:mysql_root_credentials_file) and remote_file_exists?(mysql_root_credentials_file)
|
182
|
+
begin
|
183
|
+
set :mysql_root_credentials_file_contents, capture("cat #{mysql_root_credentials_file}")
|
184
|
+
rescue
|
185
|
+
set :mysql_root_credentials, false
|
186
|
+
end
|
187
|
+
|
188
|
+
if exists?(:mysql_root_credentials_file_contents)
|
189
|
+
set :mysql_root_credentials, {
|
190
|
+
host: mysql_root_credentials_file_contents.match(mysql_root_credentials_host_regex)[mysql_root_credentials_host_regex_match].chomp,
|
191
|
+
user: mysql_root_credentials_file_contents.match(mysql_root_credentials_user_regex)[mysql_root_credentials_user_regex_match].chomp,
|
192
|
+
pass: mysql_root_credentials_file_contents.match(mysql_root_credentials_pass_regex)[mysql_root_credentials_pass_regex_match].chomp,
|
193
|
+
}
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Verify that we got them!
|
198
|
+
if !exists?(:mysql_root_credentials)
|
199
|
+
set :mysql_root_credentials, {
|
200
|
+
host: ask("What is the hostname used to access the database", default: 'localhost', validate: /.+/),
|
201
|
+
user: ask("What is the username used to access the database", default: nil, validate: /.+/),
|
202
|
+
pass: ask("What is the password used to access the database", default: nil, validate: /.+/, echo: false),
|
203
|
+
}
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
before "mysql:backup_db", "mysql:credentials"
|
210
|
+
before "mysql:drop_db", "mysql:credentials"
|
211
|
+
before "mysql:create_db", "mysql:credentials"
|
212
|
+
before "mysql:import_db_dump", "mysql:backup_db"
|
213
|
+
before "mysql:export_db_dump", "mysql:backup_db"
|
214
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'capistrano-exts/receipts/base'
|
3
|
+
|
4
|
+
# Verify that Capistrano is version 2
|
5
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
6
|
+
abort "This extension requires Capistrano 2"
|
7
|
+
end
|
8
|
+
|
9
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
10
|
+
|
11
|
+
namespace :rails do
|
12
|
+
desc "Install configuration files"
|
13
|
+
task :install_configuration_files, :roles => :app do
|
14
|
+
unless configuration_files.blank?
|
15
|
+
configuration_files.each { |configuration_file| link_config_file(configuration_file) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Install rvm config file"
|
20
|
+
task :install_rvmrc_file, :roles => :app do
|
21
|
+
link_file(File.join(shared_path, 'rvmrc'), File.join(release_path, '.rvmrc'))
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Fix permissions"
|
25
|
+
task :fix_permissions, :roles => :app do
|
26
|
+
unless app_owner.blank? or app_group.blank?
|
27
|
+
run "#{try_sudo} chown -R #{app_owner}:#{app_group} #{deploy_to}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace :deploy do
|
33
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
34
|
+
run "#{try_sudo} touch #{File.join(current_path, 'tmp', 'restart.txt')}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
after "deploy:finalize_update", "rails:install_configuration_files"
|
39
|
+
after "rails:install_configuration_files", "rails:install_rvmrc_file"
|
40
|
+
after "deploy:restart", "rails:fix_permissions"
|
41
|
+
|
42
|
+
# Capistrano is broken
|
43
|
+
# See: https://github.com/capistrano/capistrano/issues/81
|
44
|
+
before "deploy:assets:precompile", "bundle:install"
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Verify that Capistrano is version 2
|
4
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
5
|
+
abort "This extension requires Capistrano 2"
|
6
|
+
end
|
7
|
+
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
namespace :deploy do
|
10
|
+
namespace :server do
|
11
|
+
namespace :db_server do
|
12
|
+
desc "Setup db server"
|
13
|
+
task :setup, :roles => :db do
|
14
|
+
# Empty task, server preparation goes into callbacks
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'capistrano'
|
4
|
+
|
5
|
+
# Verify that Capistrano is version 2
|
6
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
7
|
+
abort "This extension requires Capistrano 2"
|
8
|
+
end
|
9
|
+
|
10
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
11
|
+
namespace :deploy do
|
12
|
+
namespace :server do
|
13
|
+
namespace :web_server do
|
14
|
+
namespace :apache do
|
15
|
+
|
16
|
+
_cset :apache_init_path, "/etc/init.d/apache2"
|
17
|
+
|
18
|
+
desc "[internal] Generate Apache configuration"
|
19
|
+
task :generate_configuration do
|
20
|
+
# TODO: Write this task
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Start apache web server"
|
24
|
+
task :start do
|
25
|
+
run <<-CMD
|
26
|
+
#{try_sudo} #{fetch :apache_init_path} start
|
27
|
+
CMD
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Stop apache web server"
|
31
|
+
task :stop do
|
32
|
+
run <<-CMD
|
33
|
+
#{try_sudo} #{fetch :apache_init_path} stop
|
34
|
+
CMD
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Restart apache web server"
|
38
|
+
task :restart do
|
39
|
+
run <<-CMD
|
40
|
+
#{try_sudo} #{apache_init_path} restart
|
41
|
+
CMD
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Resload apache web server"
|
45
|
+
task :reload do
|
46
|
+
run <<-CMD
|
47
|
+
#{try_sudo} #{apache_init_path} reload
|
48
|
+
CMD
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|