crossroads_capistrano 1.4.0 → 1.4.5
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/crossroads_capistrano.gemspec +1 -1
- data/lib/crossroads_capistrano.rb +3 -3
- data/lib/crossroads_capistrano/recipes/base.rb +57 -0
- data/lib/crossroads_capistrano/recipes/config.rb +50 -0
- data/lib/crossroads_capistrano/recipes/helper_methods.rb +46 -0
- data/lib/crossroads_capistrano/recipes/ldap.rb +2 -2
- data/lib/crossroads_capistrano/recipes/log.rb +1 -3
- data/lib/crossroads_capistrano/recipes/mysql.rb +45 -0
- data/lib/crossroads_capistrano/recipes/newrelic.rb +1 -1
- data/lib/crossroads_capistrano/recipes/passenger.rb +26 -9
- data/lib/crossroads_capistrano/recipes/postgresql.rb +45 -27
- data/lib/crossroads_capistrano/recipes/rvm.rb +1 -1
- data/lib/crossroads_capistrano/recipes/stack.rb +60 -18
- data/lib/crossroads_capistrano/recipes/thinking_sphinx.rb +4 -4
- data/lib/crossroads_capistrano/recipes/{deploy_permissions.rb → user_permissions.rb} +0 -9
- data/lib/crossroads_capistrano/recipes/whenever.rb +2 -0
- data/lib/crossroads_capistrano/recipes/yum.rb +9 -5
- metadata +7 -6
- data/lib/crossroads_capistrano/recipes/defaults.rb +0 -27
- data/lib/crossroads_capistrano/recipes/prompt.rb +0 -12
- data/lib/crossroads_capistrano/recipes/shared_config.rb +0 -9
|
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "crossroads_capistrano"
|
|
6
|
-
s.version = "1.4.
|
|
6
|
+
s.version = "1.4.5"
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
|
8
8
|
s.authors = ["Steve Kenworthy", "Ben Tillman", "Nathan Broadbent"]
|
|
9
9
|
s.email = ["it_dept@crossroads.org.hk"]
|
|
@@ -8,9 +8,9 @@ if defined?(Capistrano::Configuration) && Capistrano::Configuration.instance
|
|
|
8
8
|
Capistrano::Configuration.instance(:must_exist).load do
|
|
9
9
|
set :rails_root, Dir.pwd # For tasks that need the root directory
|
|
10
10
|
|
|
11
|
-
# Load defaults unless explicitly told not to.
|
|
12
|
-
unless $
|
|
13
|
-
load File.join(File.dirname(__FILE__), "crossroads_capistrano/recipes/
|
|
11
|
+
# Load base defaults unless explicitly told not to.
|
|
12
|
+
unless $no_base
|
|
13
|
+
load File.join(File.dirname(__FILE__), "crossroads_capistrano/recipes/base.rb")
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def load_crossroads_recipes(recipes)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#
|
|
2
|
+
# These base defaults are always loaded unless otherwise specified.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
# Recipes
|
|
6
|
+
# ---------------------------------------------------------
|
|
7
|
+
load File.join(File.dirname(__FILE__), "helper_methods.rb")
|
|
8
|
+
load File.join(File.dirname(__FILE__), "config.rb")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Settings
|
|
12
|
+
# ---------------------------------------------------------
|
|
13
|
+
set :default_stage, "preview"
|
|
14
|
+
set :rails_env, "production"
|
|
15
|
+
|
|
16
|
+
set :scm, :git
|
|
17
|
+
set :branch, "master"
|
|
18
|
+
set :deploy_via, :remote_cache
|
|
19
|
+
set :keep_releases, 3
|
|
20
|
+
|
|
21
|
+
set :bundle_without, [:cucumber, :development, :test]
|
|
22
|
+
|
|
23
|
+
set :httpd_user, "apache"
|
|
24
|
+
set :httpd_group, "apache"
|
|
25
|
+
set :http_port, "80"
|
|
26
|
+
set :https_port, "443"
|
|
27
|
+
|
|
28
|
+
default_run_options[:pty] = true
|
|
29
|
+
|
|
30
|
+
def needs_netrc?; repository.include?("svn.globalhand.org"); end
|
|
31
|
+
def needs_ssh_key?; repository.include?("github.com"); end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Hooks
|
|
35
|
+
# ---------------------------------------------------------
|
|
36
|
+
before "deploy:symlink", "deploy:symlink_config"
|
|
37
|
+
after "deploy:restart", "deploy:cleanup"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Misc. Tasks
|
|
41
|
+
# ---------------------------------------------------------
|
|
42
|
+
namespace :deploy do
|
|
43
|
+
desc "Symlink Shared config files into release path."
|
|
44
|
+
task :symlink_config do
|
|
45
|
+
run "ln -sf #{shared_path}/config/*.yml #{release_path}/config/"
|
|
46
|
+
end
|
|
47
|
+
desc "Check for project dependencies"
|
|
48
|
+
task :check_dependencies, :roles => :db, :only => { :primary => true } do
|
|
49
|
+
sudo "cd #{current_path} && RAILS_ENV=production rake check_dependencies"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# Capistrano Fixes
|
|
55
|
+
# ---------------------------------------------------------
|
|
56
|
+
set(:current_release) { File.join(releases_path, releases.last.to_s) }
|
|
57
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
namespace :config do
|
|
2
|
+
desc "Prompt for values for all '*.yml.example' and '*.yml.<<stage>>.example' files, and upload to shared/config"
|
|
3
|
+
task :setup do
|
|
4
|
+
puts "\n ** Setting up shared/config files ('*.yml.example')."
|
|
5
|
+
puts " - In order to skip a file, you just need to leave any prompt blank."
|
|
6
|
+
puts " - You will need to edit the '.yml.example' files to change any hard-coded values."
|
|
7
|
+
|
|
8
|
+
(Dir.glob("config/*.yml.example") +
|
|
9
|
+
Dir.glob("config/*.yml.#{stage}.example")).each do |config_file|
|
|
10
|
+
unless config_file.include?("database.yml")
|
|
11
|
+
skip_file = false
|
|
12
|
+
filename = File.basename(config_file).gsub(/.example$/,'')
|
|
13
|
+
puts "\n ** == Configuring #{filename} ...\n\n"
|
|
14
|
+
config = File.open(config_file).read
|
|
15
|
+
# Substitute <%=...%> with evaluated expression. (Very simple ERB)
|
|
16
|
+
config.gsub!(/<%=(.+)%>/) do |string|
|
|
17
|
+
eval($1)
|
|
18
|
+
end
|
|
19
|
+
# Substitute {{...}} with user input.
|
|
20
|
+
config.gsub!(/\{\{(.+)\}\}/) do |string|
|
|
21
|
+
prompt = $1
|
|
22
|
+
# Keep passwords hidden.
|
|
23
|
+
if prompt.downcase.include?('password')
|
|
24
|
+
answer = Capistrano::CLI.password_prompt(" #{prompt}: ").strip
|
|
25
|
+
else
|
|
26
|
+
answer = Capistrano::CLI.ui.ask(" #{prompt}: ").strip
|
|
27
|
+
end
|
|
28
|
+
if answer == ""
|
|
29
|
+
skip_file = true
|
|
30
|
+
break
|
|
31
|
+
end
|
|
32
|
+
answer
|
|
33
|
+
end
|
|
34
|
+
if skip_file
|
|
35
|
+
puts "*** ! Skipping #{filename} !"
|
|
36
|
+
else
|
|
37
|
+
put config, "#{shared_path}/config/#{filename}"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
desc "Pull server config to local machine (excld. database.yml)"
|
|
44
|
+
task :pull do
|
|
45
|
+
system("mv -f config/database.yml config/database.yml.backup")
|
|
46
|
+
get_with_status "#{shared_path}/config/", ".", :via => :scp, :hosts => first_db_host, :recursive => true
|
|
47
|
+
system("rm -f config/database.yml && mv -f config/database.yml.backup config/database.yml")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Capistrano Helper Methods
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
# Returns the first host with the 'db' role. (useful for :pull commands)
|
|
6
|
+
def first_db_host
|
|
7
|
+
@db_host ||= find_servers(:roles => :db).map(&:to_s).first
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Adds file status to 'get' commands
|
|
11
|
+
def get_with_status(file, dest, options={})
|
|
12
|
+
last = nil
|
|
13
|
+
get file, dest, options do |channel, name, received, total|
|
|
14
|
+
print "\r #{name}: #{(Float(received)/total*100).to_i}%"
|
|
15
|
+
print "\n" if received == total
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Test for presence of file on remote server.
|
|
20
|
+
def remote_file_exists?(full_path)
|
|
21
|
+
capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip == 'true'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Replaces strings in a file, i.e. @SOME_STRING@ is replaced with 'replacement'
|
|
25
|
+
def sed(file, args, char="@")
|
|
26
|
+
sudo "sed -i #{file} " << args.map{|k,v|"-e 's%#{char}#{k}#{char}%#{v}%g'"}.join(" ")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Helper function which prompts for user input.
|
|
30
|
+
# If user enters nothing, variable is set to the default.
|
|
31
|
+
def prompt_with_default(prompt, var, default=nil)
|
|
32
|
+
set(var) do
|
|
33
|
+
# Append default in brackets to prompt if default is not blank.
|
|
34
|
+
if default != "" && !default.nil?
|
|
35
|
+
prompt << " [#{default}]"
|
|
36
|
+
end
|
|
37
|
+
# Keep passwords hidden.
|
|
38
|
+
if prompt.downcase.include?('password')
|
|
39
|
+
Capistrano::CLI.password_prompt(" #{prompt}: ")
|
|
40
|
+
else
|
|
41
|
+
Capistrano::CLI.ui.ask(" #{prompt}: ")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
set var, default if eval("#{var.to_s}.empty?")
|
|
45
|
+
end
|
|
46
|
+
|
|
@@ -19,11 +19,11 @@ password: #{ldap_bind_password}
|
|
|
19
19
|
EOF
|
|
20
20
|
|
|
21
21
|
put ldap_yml, "/tmp/ldap.yml"
|
|
22
|
-
sudo "mv /tmp/ldap.yml #{
|
|
22
|
+
sudo "mv /tmp/ldap.yml #{shared_path}/config/ldap.yml"
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
task :symlink do
|
|
26
|
-
sudo "ln -sf #{
|
|
26
|
+
sudo "ln -sf #{shared_path}/config/ldap.yml #{release_path}/config/ldap.yml"
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
end
|
|
@@ -22,9 +22,7 @@ namespace :log do
|
|
|
22
22
|
run "gzip -c #{shared_path}/log/production.log > #{shared_path}/log/production.log.gz"
|
|
23
23
|
`rm -f /tmp/production.log.gz`
|
|
24
24
|
puts "Downloading #{shared_path}/log/production.log...\n"
|
|
25
|
-
|
|
26
|
-
print "\r #{name}: #{(Float(received)/total*100).to_i}% complete..."
|
|
27
|
-
end
|
|
25
|
+
get_with_status "#{shared_path}/log/production.log.gz", "/tmp/production.log.gz", :via => :scp
|
|
28
26
|
run "rm -f #{shared_path}/log/production.log.gz"
|
|
29
27
|
`gzip -fd /tmp/production.log.gz`
|
|
30
28
|
puts "File can be accessed at /tmp/production.log"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
namespace :db do
|
|
2
|
+
namespace :config do
|
|
3
|
+
desc "Create shared/config/database.yml"
|
|
4
|
+
task :setup do
|
|
5
|
+
puts "\n ** == Configuring config/database.yml (mysql) ...\n\n"
|
|
6
|
+
prompt_with_default("Database name", :db_name, "#{application}_#{stage}")
|
|
7
|
+
prompt_with_default("Database username", :db_username, "#{application}_#{stage}")
|
|
8
|
+
prompt_with_default("Database password", :db_password)
|
|
9
|
+
prompt_with_default("Database host", :db_host, "localhost")
|
|
10
|
+
prompt_with_default("Database port", :db_port, "3306")
|
|
11
|
+
database_yml = <<-EOF
|
|
12
|
+
production:
|
|
13
|
+
adapter: mysql
|
|
14
|
+
encoding: utf8
|
|
15
|
+
database: #{db_name}
|
|
16
|
+
username: #{db_username}
|
|
17
|
+
password: #{db_password}
|
|
18
|
+
host: #{db_host}
|
|
19
|
+
port: #{db_port}
|
|
20
|
+
pool: 10
|
|
21
|
+
timeout: 5
|
|
22
|
+
EOF
|
|
23
|
+
put database_yml, "#{shared_path}/config/database.yml"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
desc "Download production database to local machine"
|
|
28
|
+
task :pull do
|
|
29
|
+
prompt_with_default("Database name", :database_name, "#{application}_#{stage}")
|
|
30
|
+
prompt_with_default("Local role", :local_role, "root")
|
|
31
|
+
prompt_with_default("Overwrite local development db? (y/n)", :overwrite, "y")
|
|
32
|
+
|
|
33
|
+
# Dump database
|
|
34
|
+
sudo "mysqldump #{database_name} > /tmp/db_dump.sql", :hosts => first_db_host
|
|
35
|
+
# Download dumped database
|
|
36
|
+
get_with_status "/tmp/db_dump.sql", "tmp/#{application}_#{stage}_dump.sql", :via => :scp, :hosts => first_db_host
|
|
37
|
+
# Delete dumped database from server
|
|
38
|
+
sudo "rm -rf /tmp/dump.sql", :hosts => first_db_host
|
|
39
|
+
if overwrite.to_s.downcase[0,1] == "y"
|
|
40
|
+
# Import data
|
|
41
|
+
system "mysql -u #{local_role} #{application}_development < tmp/#{application}_#{stage}_dump.sql"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
@@ -19,6 +19,15 @@ namespace :deploy do
|
|
|
19
19
|
sudo "/etc/init.d/httpd #{t}"
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
+
|
|
23
|
+
desc "Apache permissions (for passenger)"
|
|
24
|
+
task :apache_permissions do
|
|
25
|
+
unless $apache_permissions
|
|
26
|
+
sudo "chown -R #{httpd_user}:#{httpd_group} #{current_path}/"
|
|
27
|
+
sudo "chown -R #{httpd_user}:#{httpd_group} #{shared_path}/"
|
|
28
|
+
$apache_permissions = true
|
|
29
|
+
end
|
|
30
|
+
end
|
|
22
31
|
end
|
|
23
32
|
|
|
24
33
|
namespace :passenger do
|
|
@@ -26,7 +35,7 @@ namespace :passenger do
|
|
|
26
35
|
task :install, :roles => :web do
|
|
27
36
|
install_deps
|
|
28
37
|
run "if ! (gem list | grep passenger | grep #{passenger_version}); then gem install passenger --no-rdoc --no-ri --version #{passenger_version} && passenger-install-apache2-module --auto; fi"
|
|
29
|
-
sudo "rvm wrapper #{rvm_ruby_string} passenger" if
|
|
38
|
+
sudo "rvm wrapper #{rvm_ruby_string} passenger" if respond_to?(:rvm_ruby_string) # sets up wrapper for passenger so it can find bundler etc...
|
|
30
39
|
end
|
|
31
40
|
|
|
32
41
|
task :install_deps, :roles => :web do
|
|
@@ -37,30 +46,38 @@ namespace :passenger do
|
|
|
37
46
|
desc "Apache config files: uses special variables @DEPLOY_TO@ @IP_ADDR@ @SERVER_NAME@ @PASSENGER_ROOT@ @RUBY_ROOT@"
|
|
38
47
|
task :config, :roles => :web do
|
|
39
48
|
# You can set the following paths from your deploy.rb file, if needed.
|
|
40
|
-
unless
|
|
49
|
+
unless respond_to?(:httpd_site_conf_path)
|
|
41
50
|
httpd_site_conf_path = "/etc/httpd/sites-enabled/010-#{application}-#{stage}.conf"
|
|
42
51
|
end
|
|
43
|
-
unless
|
|
52
|
+
unless respond_to?(:passenger_conf_path)
|
|
44
53
|
passenger_conf_path = "/etc/httpd/mods-enabled/passenger.conf"
|
|
45
54
|
end
|
|
46
55
|
|
|
47
56
|
if respond_to?(:rvm_ruby_string) # Deploying with RVM
|
|
48
|
-
ruby_root
|
|
57
|
+
ruby_root = "/usr/local/rvm/wrappers/#{rvm_ruby_string}/ruby"
|
|
49
58
|
passenger_root = "/usr/local/rvm/gems/#{rvm_ruby_string}/gems/passenger-#{passenger_version}"
|
|
50
59
|
else # System Ruby
|
|
51
|
-
ruby_root
|
|
52
|
-
|
|
60
|
+
ruby_root = capture("which ruby").strip
|
|
61
|
+
gem_path = capture("ruby -r rubygems -e 'p Gem.path.detect{|p|p.include? \"/usr\"}'").strip.gsub('"','')
|
|
62
|
+
passenger_root = "#{gem_path}/gems/passenger-#{passenger_version}"
|
|
53
63
|
end
|
|
54
|
-
sed_args = "-e 's%@PASSENGER_ROOT@%#{passenger_root.strip}%g' -e 's%@RUBY_ROOT@%#{ruby_root.strip}%g'"
|
|
55
64
|
# httpd conf
|
|
56
65
|
sudo "cp -f #{release_path}/config/httpd-rails.conf #{httpd_site_conf_path}"
|
|
57
|
-
|
|
66
|
+
sed httpd_site_conf_path, {"DEPLOY_TO" => deploy_to,
|
|
67
|
+
"IP_ADDR" => ip_address,
|
|
68
|
+
"SERVER_NAME" => site_domain_name,
|
|
69
|
+
"SITE_DOMAIN_NAME" => site_domain_name,
|
|
70
|
+
"HTTP_PORT" => http_port,
|
|
71
|
+
"HTTPS_PORT" => https_port}
|
|
58
72
|
# passenger conf
|
|
59
73
|
sudo "cp -f #{release_path}/config/passenger.conf #{passenger_conf_path}"
|
|
60
|
-
|
|
74
|
+
sed passenger_conf_path, {"PASSENGER_ROOT" => passenger_root,
|
|
75
|
+
"RUBY_ROOT" => ruby_root}
|
|
61
76
|
end
|
|
62
77
|
end
|
|
63
78
|
|
|
64
79
|
before "deploy:cold", "passenger:install"
|
|
65
80
|
after "deploy:update_code", "passenger:config"
|
|
81
|
+
before "deploy:start", "deploy:apache_permissions"
|
|
82
|
+
before "deploy:restart", "deploy:apache_permissions"
|
|
66
83
|
|
|
@@ -1,6 +1,48 @@
|
|
|
1
|
-
namespace :
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
namespace :db do
|
|
2
|
+
namespace :config do
|
|
3
|
+
desc "Create shared/config/database.yml"
|
|
4
|
+
task :setup do
|
|
5
|
+
puts "\n ** == Configuring config/database.yml (postgres) ...\n\n"
|
|
6
|
+
prompt_with_default("Database name", :db_name, "#{application}_#{stage}")
|
|
7
|
+
prompt_with_default("Database username", :db_username, application)
|
|
8
|
+
prompt_with_default("Database password", :db_password)
|
|
9
|
+
prompt_with_default("Database host", :db_host, "localhost")
|
|
10
|
+
prompt_with_default("Database port", :db_port, "5432")
|
|
11
|
+
database_yml = <<-EOF
|
|
12
|
+
production:
|
|
13
|
+
adapter: postgresql
|
|
14
|
+
host: #{db_host}
|
|
15
|
+
port: #{db_port}
|
|
16
|
+
database: #{db_name}
|
|
17
|
+
username: #{db_username}
|
|
18
|
+
password: #{db_password}
|
|
19
|
+
schema_search_path: public
|
|
20
|
+
encoding: utf8
|
|
21
|
+
template: template0
|
|
22
|
+
EOF
|
|
23
|
+
put database_yml, "#{shared_path}/config/database.yml"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
desc "Download production database to local machine"
|
|
28
|
+
task :pull do
|
|
29
|
+
prompt_with_default("Database name", :dbname, "#{application}_#{stage}")
|
|
30
|
+
prompt_with_default("Database user", :username, "postgres")
|
|
31
|
+
prompt_with_default("Local role", :local_role, "postgres")
|
|
32
|
+
prompt_with_default("Overwrite local development db? (y/n)", :overwrite, "y")
|
|
33
|
+
|
|
34
|
+
# Dump database
|
|
35
|
+
sudo "pg_dump -U #{username} #{dbname} > /tmp/dump.sql", :hosts => first_db_host
|
|
36
|
+
# Download dumped database
|
|
37
|
+
get_with_status "/tmp/db_dump.sql", "tmp/#{application}_#{stage}_dump.sql", :via => :scp, :hosts => first_db_host
|
|
38
|
+
# Delete dumped database from server
|
|
39
|
+
sudo "rm -rf /tmp/db_dump.sql", :hosts => first_db_host
|
|
40
|
+
# Replace server db role with local role
|
|
41
|
+
system("sed -i s/#{application}/#{local_role}/g tmp/#{application}_#{stage}_dump.sql")
|
|
42
|
+
if overwrite.to_s.downcase[0,1] == "y"
|
|
43
|
+
# Import data
|
|
44
|
+
system("psql -d #{application}_development < tmp/#{application}_#{stage}_dump.sql")
|
|
45
|
+
end
|
|
4
46
|
end
|
|
5
47
|
|
|
6
48
|
desc "Start PostgreSQL"
|
|
@@ -24,27 +66,3 @@ namespace :postgresql do
|
|
|
24
66
|
end
|
|
25
67
|
end
|
|
26
68
|
|
|
27
|
-
namespace :db do
|
|
28
|
-
desc "Download production database to local machine"
|
|
29
|
-
task :pull do
|
|
30
|
-
prompt_with_default("Database", :dbname, "#{application}_#{default_stage}")
|
|
31
|
-
prompt_with_default("Database user", :username, "postgres")
|
|
32
|
-
prompt_with_default("Local role", :local_role, "postgres")
|
|
33
|
-
prompt_with_default("Overwrite local db? (y/n)", :overwrite, "y")
|
|
34
|
-
host = find_servers(:roles => :db).map(&:to_s).first
|
|
35
|
-
run "pg_dump -U #{username} #{dbname} > /tmp/dump.sql", :hosts => host
|
|
36
|
-
get "/tmp/dump.sql", "tmp/dump.sql", :via => :scp, :hosts => host do |channel, name, received, total|
|
|
37
|
-
print "\r#{name}: #{(Float(received)/total*100).to_i}% complete"
|
|
38
|
-
end
|
|
39
|
-
run "rm -rf /tmp/dump.sql", :hosts => host
|
|
40
|
-
`sed -i s/stockit/#{local_role}/g tmp/dump.sql`
|
|
41
|
-
# Import data.
|
|
42
|
-
if overwrite.to_s.downcase[0,1] == "y"
|
|
43
|
-
`psql -d stockit_development < tmp/dump.sql`
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
after "deploy:update_code", "postgresql:symlink"
|
|
50
|
-
|
|
@@ -5,7 +5,7 @@ namespace :rvm do
|
|
|
5
5
|
desc "Install rvm"
|
|
6
6
|
task :install, :roles => :web do
|
|
7
7
|
install_deps
|
|
8
|
-
sudo "if ! (which rvm); then bash < <(
|
|
8
|
+
sudo "if ! (which rvm); then bash < <(curl -s https://rvm.beginrescueend.com/install/rvm) ); fi", :shell => 'sh'
|
|
9
9
|
sudo "if ! (rvm list | grep #{rvm_ruby_string}); then rvm install #{rvm_ruby_string}; fi", :shell => 'sh'
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -1,46 +1,88 @@
|
|
|
1
|
-
|
|
1
|
+
load File.join(File.dirname(__FILE__), 'yum.rb')
|
|
2
2
|
|
|
3
|
-
# Installs minimal system software stack. Runs before
|
|
3
|
+
# Installs minimal system software stack. Runs before deploy:cold
|
|
4
|
+
|
|
5
|
+
before "deploy:cold", "stack:setup"
|
|
4
6
|
|
|
5
7
|
namespace :stack do
|
|
6
8
|
desc "Setup operating system and rails environment"
|
|
7
|
-
task :
|
|
9
|
+
task :setup do
|
|
8
10
|
yum.update
|
|
9
|
-
yum.install(
|
|
10
|
-
|
|
11
|
+
yum.install({:base => yum_packages}, :stable ) if respond_to?(:yum_packages)
|
|
12
|
+
gemrc.setup
|
|
13
|
+
bundler.setup
|
|
11
14
|
deploy.setup
|
|
12
15
|
shared.setup
|
|
16
|
+
config.setup
|
|
17
|
+
db.config.setup if respond_to?(:db)
|
|
13
18
|
shared.permissions
|
|
19
|
+
netrc.setup if needs_netrc?
|
|
20
|
+
ssh_key.setup if needs_ssh_key?
|
|
14
21
|
end
|
|
15
|
-
|
|
22
|
+
|
|
23
|
+
namespace :bundler do
|
|
16
24
|
desc "Install Bundler"
|
|
17
|
-
task :
|
|
18
|
-
run "gem install bundler
|
|
25
|
+
task :setup do
|
|
26
|
+
run "gem install bundler"
|
|
19
27
|
end
|
|
20
28
|
end
|
|
21
29
|
end
|
|
22
30
|
|
|
23
|
-
namespace
|
|
31
|
+
namespace :shared do
|
|
24
32
|
# This task can be extended by the application via an :after hook.
|
|
25
33
|
desc "Setup shared directory"
|
|
26
34
|
task :setup do
|
|
27
|
-
sudo "mkdir -p #{
|
|
35
|
+
sudo "mkdir -p #{shared_path}/config"
|
|
28
36
|
end
|
|
29
37
|
|
|
30
38
|
desc "Set permissions on shared directory"
|
|
31
39
|
task :permissions do
|
|
32
|
-
sudo "chown -R #{httpd_user}:#{httpd_group} #{
|
|
33
|
-
sudo "chmod -R 755 #{
|
|
40
|
+
sudo "chown -R #{httpd_user}:#{httpd_group} #{shared_path}/"
|
|
41
|
+
sudo "chmod -R 755 #{shared_path}/"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
namespace :gemrc do
|
|
46
|
+
desc "Setup ~/.gemrc file to avoid rdoc and ri generation"
|
|
47
|
+
task :setup do
|
|
48
|
+
puts "\n ** == Configuring ~/.gemrc ...\n\n"
|
|
49
|
+
home_dir = capture("#{sudo} echo ~").strip
|
|
50
|
+
put "gem: --no-ri --no-rdoc", "#{home_dir}/.gemrc"
|
|
34
51
|
end
|
|
35
52
|
end
|
|
36
53
|
|
|
37
|
-
namespace :
|
|
38
|
-
desc "
|
|
39
|
-
task :
|
|
40
|
-
|
|
54
|
+
namespace :netrc do
|
|
55
|
+
desc "Setup ~/.netrc file for internal git https auth"
|
|
56
|
+
task :setup do
|
|
57
|
+
if capture("ls ~/.netrc").strip == ""
|
|
58
|
+
puts "\n ** == Configuring ~/.netrc ..."
|
|
59
|
+
puts " ** (Enter 's' to skip this file.)\n\n"
|
|
60
|
+
prompt_with_default("Netrc Machine", :netrc_machine, "svn.globalhand.org")
|
|
61
|
+
if netrc_machine == "s"
|
|
62
|
+
puts "\n ** ! Skipping ~/.netrc\n\n"
|
|
63
|
+
else
|
|
64
|
+
prompt_with_default("Netrc Login", :netrc_login, "")
|
|
65
|
+
prompt_with_default("Netrc Password", :netrc_password, "")
|
|
66
|
+
netrc = <<-EOF
|
|
67
|
+
machine #{netrc_machine}
|
|
68
|
+
login #{netrc_login}
|
|
69
|
+
password #{netrc_password}
|
|
70
|
+
EOF
|
|
71
|
+
home_dir = capture("#{sudo} echo ~").strip
|
|
72
|
+
put netrc, "#{home_dir}/.netrc"
|
|
73
|
+
end
|
|
74
|
+
else
|
|
75
|
+
puts "\n ** == ~/.netrc already exists!\n\n"
|
|
76
|
+
end
|
|
41
77
|
end
|
|
42
78
|
end
|
|
43
79
|
|
|
44
|
-
|
|
45
|
-
|
|
80
|
+
namespace :ssh_key do
|
|
81
|
+
desc "Generate ssh key for adding to GitHub public keys, etc."
|
|
82
|
+
task :setup do
|
|
83
|
+
puts "\n If capistrano stops here then paste the following key into GitHub and"
|
|
84
|
+
puts " run \"cap deploy:cold\" again\n\n"
|
|
85
|
+
run " if ! (ls $HOME/.ssh/id_rsa); then (ssh-keygen -N '' -t rsa -q -f $HOME/.ssh/id_rsa && cat $HOME/.ssh/id_rsa.pub) && exit 1; fi"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
46
88
|
|
|
@@ -2,7 +2,7 @@ namespace :ts do
|
|
|
2
2
|
|
|
3
3
|
desc "Links the sphinx database files by inserting magic code"
|
|
4
4
|
task :symlink do
|
|
5
|
-
|
|
5
|
+
sed "#{release_path}/script/link_sphinx.rb", {"DEPLOY_TO" => "shared"}
|
|
6
6
|
run "#{release_path}/script/runner -e production #{release_path}/script/link_sphinx.rb"
|
|
7
7
|
end
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ namespace :ts do
|
|
|
19
19
|
desc "Start sphinx"
|
|
20
20
|
task :start do
|
|
21
21
|
run "cd #{current_path} && RAILS_ENV=production rake ts:start"
|
|
22
|
-
run "chown #{httpd_user}:#{httpd_group} #{
|
|
22
|
+
run "chown #{httpd_user}:#{httpd_group} #{shared_path}/log/searchd.production.pid"
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
desc "Restart sphinx"
|
|
@@ -31,7 +31,7 @@ namespace :ts do
|
|
|
31
31
|
desc "Stop sphinx, delete index files, reindex, and restart sphinx (last resort)"
|
|
32
32
|
task :recover do
|
|
33
33
|
stop
|
|
34
|
-
run "cd #{
|
|
34
|
+
run "cd #{shared_path}/db/sphinx/ && rm -rf production"
|
|
35
35
|
run "cd #{current_path} && RAILS_ENV=production rake ts:in"
|
|
36
36
|
start
|
|
37
37
|
end
|
|
@@ -42,7 +42,7 @@ are stale and need removing with ts:recover. Run this command a few times over a
|
|
|
42
42
|
a minute to determine if the files disappear - indicating a successfully completed rotation \
|
|
43
43
|
and no need for recovery."""
|
|
44
44
|
task :recovery_required? do
|
|
45
|
-
run "if [ x`find #{
|
|
45
|
+
run "if [ x`find #{shared_path}/db/sphinx/production/ -name \*.new.\* | wc -l` == x\"0\" ]; then echo \"Sphinx indexes look intact. Run ts:in to regenerate.\"; else echo \"Sphinx index files *may* be stale. Wait 1 minute and run this command again. Consider running ts:recover if this message appears again\"; fi"
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
end
|
|
@@ -14,14 +14,6 @@ namespace :deploy do
|
|
|
14
14
|
sudo "chown -R #{user} #{deploy_to}"
|
|
15
15
|
$apache_permissions = false
|
|
16
16
|
end
|
|
17
|
-
desc "Apache permissions (for passenger)"
|
|
18
|
-
task :apache_permissions do
|
|
19
|
-
unless $apache_permissions
|
|
20
|
-
sudo "chown -R #{httpd_user}:#{httpd_group} #{current_path}/"
|
|
21
|
-
sudo "chown -R #{httpd_user}:#{httpd_group} #{deploy_to}/shared/"
|
|
22
|
-
$apache_permissions = true
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
17
|
|
|
26
18
|
desc "Set permissions on releases directory so old releases can be removed"
|
|
27
19
|
task :release_permissions do
|
|
@@ -36,6 +28,5 @@ end
|
|
|
36
28
|
after t, "deploy:apache_permissions"
|
|
37
29
|
end
|
|
38
30
|
|
|
39
|
-
before "deploy:restart", "deploy:apache_permissions"
|
|
40
31
|
before "deploy:cleanup", "deploy:release_permissions"
|
|
41
32
|
|
|
@@ -6,14 +6,9 @@ require 'capistrano'
|
|
|
6
6
|
#
|
|
7
7
|
# Installs within Capistrano as the plugin _yum_.
|
|
8
8
|
#
|
|
9
|
-
# =Usage
|
|
10
|
-
#
|
|
11
|
-
# require 'recipes/yum'
|
|
12
|
-
#
|
|
13
9
|
# Prefix all calls to the library with <tt>yum.</tt>
|
|
14
10
|
#
|
|
15
11
|
module Yum
|
|
16
|
-
|
|
17
12
|
# Default yum command - reduces any interactivity to the minimum.
|
|
18
13
|
YUM_COMMAND="yum -y"
|
|
19
14
|
|
|
@@ -64,3 +59,12 @@ private
|
|
|
64
59
|
end
|
|
65
60
|
|
|
66
61
|
Capistrano.plugin :yum, Yum
|
|
62
|
+
|
|
63
|
+
desc "Takes a list of yum packages and determines if they need updating. This is useful for determining whether to apply security updates."
|
|
64
|
+
task :list_installed_yum_packages do
|
|
65
|
+
prompt_with_default("Enter comma seperated list of yum pacakges (e.g. qspice, lftp).\nIf you leave this blank then it will list all installed packages:", :packages, "")
|
|
66
|
+
packages.gsub!(/,\s*/, "\\|")
|
|
67
|
+
sudo "yum -C list | grep '#{packages}' | grep installed"
|
|
68
|
+
puts "The packages listed above are installed on the system"
|
|
69
|
+
end
|
|
70
|
+
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: crossroads_capistrano
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.5
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -11,7 +11,7 @@ authors:
|
|
|
11
11
|
autorequire:
|
|
12
12
|
bindir: bin
|
|
13
13
|
cert_chain: []
|
|
14
|
-
date: 2011-05-
|
|
14
|
+
date: 2011-05-25 00:00:00.000000000 +08:00
|
|
15
15
|
default_executable:
|
|
16
16
|
dependencies: []
|
|
17
17
|
description: A Crossroads Foundation collection of generic capistrano recipes.
|
|
@@ -27,22 +27,23 @@ files:
|
|
|
27
27
|
- Rakefile
|
|
28
28
|
- crossroads_capistrano.gemspec
|
|
29
29
|
- lib/crossroads_capistrano.rb
|
|
30
|
+
- lib/crossroads_capistrano/recipes/base.rb
|
|
30
31
|
- lib/crossroads_capistrano/recipes/cache.rb
|
|
31
|
-
- lib/crossroads_capistrano/recipes/
|
|
32
|
+
- lib/crossroads_capistrano/recipes/config.rb
|
|
32
33
|
- lib/crossroads_capistrano/recipes/delayed_job.rb
|
|
33
|
-
- lib/crossroads_capistrano/recipes/
|
|
34
|
+
- lib/crossroads_capistrano/recipes/helper_methods.rb
|
|
34
35
|
- lib/crossroads_capistrano/recipes/hoptoad.rb
|
|
35
36
|
- lib/crossroads_capistrano/recipes/ldap.rb
|
|
36
37
|
- lib/crossroads_capistrano/recipes/log.rb
|
|
38
|
+
- lib/crossroads_capistrano/recipes/mysql.rb
|
|
37
39
|
- lib/crossroads_capistrano/recipes/newrelic.rb
|
|
38
40
|
- lib/crossroads_capistrano/recipes/passenger.rb
|
|
39
41
|
- lib/crossroads_capistrano/recipes/postgresql.rb
|
|
40
|
-
- lib/crossroads_capistrano/recipes/prompt.rb
|
|
41
42
|
- lib/crossroads_capistrano/recipes/revisions.rb
|
|
42
43
|
- lib/crossroads_capistrano/recipes/rvm.rb
|
|
43
|
-
- lib/crossroads_capistrano/recipes/shared_config.rb
|
|
44
44
|
- lib/crossroads_capistrano/recipes/stack.rb
|
|
45
45
|
- lib/crossroads_capistrano/recipes/thinking_sphinx.rb
|
|
46
|
+
- lib/crossroads_capistrano/recipes/user_permissions.rb
|
|
46
47
|
- lib/crossroads_capistrano/recipes/whenever.rb
|
|
47
48
|
- lib/crossroads_capistrano/recipes/yum.rb
|
|
48
49
|
has_rdoc: true
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# These default recipes are always loaded unless otherwise specified
|
|
2
|
-
|
|
3
|
-
# Default recipes
|
|
4
|
-
# ---------------------------------------------------------
|
|
5
|
-
load File.join(File.dirname(__FILE__), "prompt.rb")
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# Default settings
|
|
9
|
-
# ---------------------------------------------------------
|
|
10
|
-
set :default_stage, "preview"
|
|
11
|
-
|
|
12
|
-
set :scm, :git
|
|
13
|
-
set :deploy_via, :remote_cache
|
|
14
|
-
set :keep_releases, 3
|
|
15
|
-
|
|
16
|
-
set :bundle_without, [:cucumber, :development, :test]
|
|
17
|
-
|
|
18
|
-
set :httpd_user, "apache"
|
|
19
|
-
set :httpd_group, "apache"
|
|
20
|
-
|
|
21
|
-
default_run_options[:pty] = true
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# Default hooks
|
|
25
|
-
# ---------------------------------------------------------
|
|
26
|
-
after "deploy:restart", "deploy:cleanup"
|
|
27
|
-
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# Helper function which prompts for user input, if none selected the returned
|
|
2
|
-
# variable is set to the default.
|
|
3
|
-
# 'prompt' -> user prompt
|
|
4
|
-
# 'var' -> variable
|
|
5
|
-
# 'default' -> default value set if no user input is received.
|
|
6
|
-
|
|
7
|
-
def prompt_with_default(prompt, var, default)
|
|
8
|
-
set(var) do
|
|
9
|
-
Capistrano::CLI.ui.ask "#{prompt} [#{default}]: "
|
|
10
|
-
end
|
|
11
|
-
set var, default if eval("#{var.to_s}.empty?")
|
|
12
|
-
end
|