capistrano-mb 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +114 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +173 -0
  7. data/Rakefile +5 -0
  8. data/capistrano-mb.gemspec +34 -0
  9. data/lib/capistrano/fiftyfive.rb +6 -0
  10. data/lib/capistrano/mb.rb +29 -0
  11. data/lib/capistrano/mb/compatibility.rb +17 -0
  12. data/lib/capistrano/mb/dsl.rb +187 -0
  13. data/lib/capistrano/mb/recipe.rb +48 -0
  14. data/lib/capistrano/mb/templates/crontab.erb +1 -0
  15. data/lib/capistrano/mb/templates/csr_config.erb +10 -0
  16. data/lib/capistrano/mb/templates/delayed_job_init.erb +36 -0
  17. data/lib/capistrano/mb/templates/logrotate.erb +9 -0
  18. data/lib/capistrano/mb/templates/maintenance.html.erb +26 -0
  19. data/lib/capistrano/mb/templates/nginx.erb +64 -0
  20. data/lib/capistrano/mb/templates/nginx_unicorn.erb +109 -0
  21. data/lib/capistrano/mb/templates/pgpass.erb +1 -0
  22. data/lib/capistrano/mb/templates/postgresql-backup-logrotate.erb +11 -0
  23. data/lib/capistrano/mb/templates/rbenv_bashrc +4 -0
  24. data/lib/capistrano/mb/templates/sidekiq_init.erb +100 -0
  25. data/lib/capistrano/mb/templates/ssl_setup +43 -0
  26. data/lib/capistrano/mb/templates/unicorn.rb.erb +71 -0
  27. data/lib/capistrano/mb/templates/unicorn_init.erb +84 -0
  28. data/lib/capistrano/mb/templates/version.rb.erb +3 -0
  29. data/lib/capistrano/mb/version.rb +5 -0
  30. data/lib/capistrano/tasks/aptitude.rake +101 -0
  31. data/lib/capistrano/tasks/crontab.rake +14 -0
  32. data/lib/capistrano/tasks/defaults.rake +122 -0
  33. data/lib/capistrano/tasks/delayed_job.rake +33 -0
  34. data/lib/capistrano/tasks/dotenv.rake +57 -0
  35. data/lib/capistrano/tasks/fiftyfive.rake +59 -0
  36. data/lib/capistrano/tasks/logrotate.rake +16 -0
  37. data/lib/capistrano/tasks/maintenance.rake +28 -0
  38. data/lib/capistrano/tasks/migrate.rake +29 -0
  39. data/lib/capistrano/tasks/nginx.rake +31 -0
  40. data/lib/capistrano/tasks/postgresql.rake +177 -0
  41. data/lib/capistrano/tasks/provision.rake +18 -0
  42. data/lib/capistrano/tasks/rake.rake +20 -0
  43. data/lib/capistrano/tasks/rbenv.rake +93 -0
  44. data/lib/capistrano/tasks/seed.rake +16 -0
  45. data/lib/capistrano/tasks/sidekiq.rake +39 -0
  46. data/lib/capistrano/tasks/ssl.rake +57 -0
  47. data/lib/capistrano/tasks/ufw.rake +32 -0
  48. data/lib/capistrano/tasks/unicorn.rake +42 -0
  49. data/lib/capistrano/tasks/user.rake +32 -0
  50. data/lib/capistrano/tasks/version.rake +34 -0
  51. metadata +165 -0
@@ -0,0 +1,59 @@
1
+ # Provides backward compatibility with the old "fiftyfive" task names.
2
+
3
+ tasks = %w(
4
+ fiftyfive:aptitude:change_postgres_packages
5
+ fiftyfive:aptitude:install
6
+ fiftyfive:aptitude:install_postgres_repo
7
+ fiftyfive:aptitude:upgrade
8
+ fiftyfive:crontab
9
+ fiftyfive:delayed_job:init_d
10
+ fiftyfive:delayed_job:restart
11
+ fiftyfive:delayed_job:start
12
+ fiftyfive:delayed_job:stop
13
+ fiftyfive:dotenv:replace
14
+ fiftyfive:dotenv:update
15
+ fiftyfive:logrotate
16
+ fiftyfive:maintenance:disable
17
+ fiftyfive:maintenance:enable
18
+ fiftyfive:migrate:deploy
19
+ fiftyfive:nginx:configure
20
+ fiftyfive:nginx:restart
21
+ fiftyfive:nginx:start
22
+ fiftyfive:nginx:stop
23
+ fiftyfive:postgresql:create_database
24
+ fiftyfive:postgresql:create_user
25
+ fiftyfive:postgresql:database_yml
26
+ fiftyfive:postgresql:dump
27
+ fiftyfive:postgresql:logrotate_backup
28
+ fiftyfive:postgresql:pgpass
29
+ fiftyfive:postgresql:restore
30
+ fiftyfive:postgresql:tune
31
+ fiftyfive:rake
32
+ fiftyfive:rbenv:install
33
+ fiftyfive:rbenv:upgrade
34
+ fiftyfive:seed
35
+ fiftyfive:sidekiq:init_d
36
+ fiftyfive:sidekiq:restart
37
+ fiftyfive:sidekiq:start
38
+ fiftyfive:sidekiq:stop
39
+ fiftyfive:ssl:generate_csr
40
+ fiftyfive:ssl:generate_dh
41
+ fiftyfive:ssl:generate_self_signed_crt
42
+ fiftyfive:ufw:configure
43
+ fiftyfive:unicorn:config_rb
44
+ fiftyfive:unicorn:init_d
45
+ fiftyfive:unicorn:restart
46
+ fiftyfive:unicorn:start
47
+ fiftyfive:unicorn:stop
48
+ fiftyfive:user:add
49
+ fiftyfive:user:install_public_key
50
+ fiftyfive:version:write_initializer
51
+ )
52
+
53
+ tasks.each do |name|
54
+ task(name) do
55
+ mb_name = name.gsub(/^fiftyfive:/, "mb:")
56
+ compatibility_warning("The #{name} task has been renamed to #{mb_name}.")
57
+ invoke(mb_name)
58
+ end
59
+ end
@@ -0,0 +1,16 @@
1
+ mb_recipe :logrotate do
2
+ during :provision, "mb:logrotate"
3
+ end
4
+
5
+ namespace :mb do
6
+ desc "Configure logrotate for Rails logs"
7
+ task :logrotate do
8
+ privileged_on release_roles(:all) do
9
+ template "logrotate.erb",
10
+ "/etc/logrotate.d/#{application_basename}-logs",
11
+ :mode => 644,
12
+ :owner => "root:root",
13
+ :sudo => true
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ mb_recipe :maintenance do
2
+ # No hooks for this recipe
3
+ end
4
+
5
+ namespace :mb do
6
+ namespace :maintenance do
7
+ desc "Tell nginx to display a 503 page for all web requests, using the "\
8
+ "maintenance.html.erb template"
9
+ task :enable do
10
+ on roles(:web) do
11
+ reason = ENV["REASON"]
12
+ deadline = ENV["DEADLINE"]
13
+
14
+ template "maintenance.html.erb",
15
+ "#{current_path}/public/system/maintenance.html",
16
+ :binding => binding,
17
+ :mode => "644"
18
+ end
19
+ end
20
+
21
+ desc "Remove the 503 page"
22
+ task :disable do
23
+ on roles(:web) do
24
+ execute :rm, "-f", "#{current_path}/public/system/maintenance.html"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ mb_recipe :migrate do
2
+ during "deploy:migrate_and_restart", "deploy"
3
+ prior_to "deploy:migrate", "enable_maintenance_before"
4
+ during "deploy:published", "disable_maintenance_after"
5
+ end
6
+
7
+ namespace :mb do
8
+ namespace :migrate do
9
+ desc "Deploy the app, stopping it and showing a 503 maintenance page "\
10
+ "while database migrations are being performed; then start the app"
11
+ task :deploy do
12
+ set(:mb_restart_during_migrate, true)
13
+ invoke :deploy
14
+ end
15
+
16
+ task :enable_maintenance_before do
17
+ if fetch(:mb_restart_during_migrate)
18
+ invoke_if_defined "mb:maintenance:enable"
19
+ invoke_if_defined "deploy:stop"
20
+ end
21
+ end
22
+
23
+ task :disable_maintenance_after do
24
+ if fetch(:mb_restart_during_migrate)
25
+ invoke_if_defined "mb:maintenance:disable"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ mb_recipe :nginx do
2
+ during :provision, "configure"
3
+ end
4
+
5
+ namespace :mb do
6
+ namespace :nginx do
7
+ desc "Install nginx.conf files and restart nginx"
8
+ task :configure do
9
+ privileged_on roles(:web) do
10
+ template("nginx.erb", "/etc/nginx/nginx.conf", :sudo => true)
11
+
12
+ template "nginx_unicorn.erb",
13
+ "/etc/nginx/sites-enabled/#{application_basename}",
14
+ :sudo => true
15
+
16
+ execute "sudo rm -f /etc/nginx/sites-enabled/default"
17
+ execute "sudo mkdir -p /etc/nginx/#{application_basename}-locations"
18
+ execute "sudo service nginx restart"
19
+ end
20
+ end
21
+
22
+ %w(start stop restart).each do |command|
23
+ desc "#{command} nginx"
24
+ task command.intern do
25
+ privileged_on roles(:web) do
26
+ execute "sudo service nginx #{command}"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,177 @@
1
+ mb_recipe :postgresql do
2
+ during :provision, %w(
3
+ create_user
4
+ create_database
5
+ database_yml
6
+ pgpass
7
+ logrotate_backup
8
+ )
9
+ end
10
+
11
+ namespace :mb do
12
+ namespace :postgresql do
13
+ desc "Update postgresql.conf using pgtune"
14
+ task :tune do
15
+ privileged_on primary(:db), :in => :sequence do
16
+ pgtune_dir = "/tmp/pgtune"
17
+ pgtune_output = "/tmp/postgresql.conf.pgtune"
18
+ pg_conf = "/etc/postgresql/9.1/main/postgresql.conf"
19
+
20
+ execute :sudo, "rm", "-rf", pgtune_dir
21
+ execute :sudo, "git",
22
+ "clone",
23
+ "-q",
24
+ "https://github.com/gregs1104/pgtune.git",
25
+ pgtune_dir
26
+
27
+ execute "sudo #{pgtune_dir}/pgtune",
28
+ "--input-config", pg_conf,
29
+ "--output-config", pgtune_output,
30
+ "--type", "Web",
31
+ "--connections", fetch(:mb_postgresql_max_connections)
32
+
33
+ # Log diff for informational purposes
34
+ execute :sudo, "diff", pg_conf, pgtune_output, "|| true"
35
+
36
+ execute :sudo, "cp", pgtune_output, pg_conf
37
+ execute :sudo, "service", "postgresql", "restart"
38
+ end
39
+ end
40
+
41
+ desc "Create user if it doesn't already exist"
42
+ task :create_user do
43
+ privileged_on primary(:db) do
44
+ user = fetch(:mb_postgresql_user)
45
+
46
+ unless test("sudo -u postgres psql -c '\\du' | grep -q #{user}")
47
+ passwd = fetch(:mb_postgresql_password)
48
+ md5 = Digest::MD5.hexdigest(passwd + user)
49
+ execute "sudo -u postgres psql -c " +
50
+ %Q["CREATE USER #{user} PASSWORD 'md5#{md5}';"]
51
+ end
52
+ end
53
+ end
54
+
55
+ desc "Create database if it doesn't already exist"
56
+ task :create_database do
57
+ privileged_on primary(:db) do
58
+ user = fetch(:mb_postgresql_user)
59
+ db = fetch(:mb_postgresql_database)
60
+
61
+ unless test("sudo -u postgres psql -l | grep -w -q #{db}")
62
+ execute "sudo -u postgres createdb -O #{user} #{db}"
63
+ end
64
+ end
65
+ end
66
+
67
+ desc "Generate database.yml"
68
+ task :database_yml do
69
+ yaml = {
70
+ fetch(:rails_env).to_s => {
71
+ "adapter" => "postgresql",
72
+ "encoding" => "unicode",
73
+ "database" => fetch(:mb_postgresql_database).to_s,
74
+ "pool" => fetch(:mb_postgresql_pool_size).to_i,
75
+ "username" => fetch(:mb_postgresql_user).to_s,
76
+ "password" => fetch(:mb_postgresql_password).to_s,
77
+ "host" => fetch(:mb_postgresql_host).to_s
78
+ }
79
+ }
80
+ fetch(:mb_postgresql_password)
81
+ on release_roles(:all) do
82
+ put YAML.dump(yaml),
83
+ "#{shared_path}/config/database.yml",
84
+ :mode => "600"
85
+ end
86
+ end
87
+
88
+ desc "Generate pgpass file (needed by backup scripts)"
89
+ task :pgpass do
90
+ fetch(:mb_postgresql_password)
91
+ on release_roles(:all) do
92
+ template "pgpass.erb",
93
+ fetch(:mb_postgresql_pgpass_path),
94
+ :mode => "600"
95
+ end
96
+ end
97
+
98
+ desc "Configure logrotate to back up the database daily"
99
+ task :logrotate_backup do
100
+ on roles(:backup) do
101
+ backup_path = fetch(:mb_postgresql_backup_path)
102
+ execute :mkdir, "-p", File.dirname(backup_path)
103
+ execute :touch, backup_path
104
+ end
105
+
106
+ privileged_on roles(:backup) do |host, user|
107
+ template\
108
+ "postgresql-backup-logrotate.erb",
109
+ "/etc/logrotate.d/postgresql-backup-#{application_basename}",
110
+ :owner => "root:root",
111
+ :mode => "644",
112
+ :binding => binding,
113
+ :sudo => true
114
+ end
115
+ end
116
+
117
+ desc "Dump the database to FILE"
118
+ task :dump do
119
+ on primary(:db) do
120
+ with_pgpassfile do
121
+ execute :pg_dump,
122
+ "-Fc -Z9 -O",
123
+ "-x", fetch(:mb_postgresql_dump_options),
124
+ "-f", remote_dump_file,
125
+ connection_flags,
126
+ fetch(:mb_postgresql_database)
127
+ end
128
+
129
+ download!(remote_dump_file, local_dump_file)
130
+
131
+ info(
132
+ "Exported #{fetch(:mb_postgresql_database)} "\
133
+ "to #{local_dump_file}."
134
+ )
135
+ end
136
+ end
137
+
138
+ desc "Restore database from FILE"
139
+ task :restore do
140
+ on primary(:db) do
141
+ exit 1 unless agree(
142
+ "\nErase existing #{fetch(:rails_env)} database "\
143
+ "and restore from local file: #{local_dump_file}? "
144
+ )
145
+
146
+ upload!(local_dump_file, remote_dump_file)
147
+
148
+ with_pgpassfile do
149
+ execute :pg_restore,
150
+ "-O -c",
151
+ connection_flags,
152
+ "-d", fetch(:mb_postgresql_database),
153
+ remote_dump_file
154
+ end
155
+ end
156
+ end
157
+
158
+ def local_dump_file
159
+ ENV.fetch("FILE", "#{fetch(:mb_postgresql_database)}.dmp")
160
+ end
161
+
162
+ def remote_dump_file
163
+ "/tmp/#{fetch(:mb_postgresql_database)}.dmp"
164
+ end
165
+
166
+ def connection_flags
167
+ [
168
+ "-U", fetch(:mb_postgresql_user),
169
+ "-h", fetch(:mb_postgresql_host)
170
+ ].join(" ")
171
+ end
172
+
173
+ def with_pgpassfile(&block)
174
+ with(:pgpassfile => fetch(:mb_postgresql_pgpass_path), &block)
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,18 @@
1
+ # Define empty provision tasks.
2
+ # These will be filled in by other recipes that contribute additional
3
+ # `before` and `during` tasks.
4
+
5
+ desc "Install and set up all app prerequisites (assumes Ubuntu 12.04)"
6
+ task :provision
7
+
8
+ namespace :provision do
9
+ desc "Install and set up all app prerequisites for Ubuntu 12.04"
10
+ task :"12_04" do
11
+ invoke "provision"
12
+ end
13
+
14
+ desc "Install and set up all app prerequisites for Ubuntu 14.04"
15
+ task :"14_04" do
16
+ invoke "provision"
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ mb_recipe :rake do
2
+ # No hooks
3
+ end
4
+
5
+ namespace :mb do
6
+ desc "Remotely execute a rake task"
7
+ task :rake do
8
+ if ENV['COMMAND'].nil?
9
+ raise "USAGE: cap #{fetch(:stage)} mb:rake COMMAND=my:task"
10
+ end
11
+
12
+ on primary(:app) do
13
+ within current_path do
14
+ with :rails_env => fetch(:rails_env) do
15
+ execute :rake, ENV['COMMAND']
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,93 @@
1
+ mb_recipe :rbenv do
2
+ during :provision, %w(install write_vars)
3
+ end
4
+
5
+ namespace :mb do
6
+ namespace :rbenv do
7
+ desc "Install rbenv and compile ruby"
8
+ task :install do
9
+ invoke "mb:rbenv:run_installer"
10
+ invoke "mb:rbenv:modify_bashrc"
11
+ invoke "mb:rbenv:bootstrap_ubuntu_for_ruby_compile"
12
+ invoke "mb:rbenv:compile_ruby"
13
+ end
14
+
15
+ desc "Install the latest version of Ruby"
16
+ task :upgrade do
17
+ invoke "mb:rbenv:update_rbenv"
18
+ invoke "mb:rbenv:bootstrap_ubuntu_for_ruby_compile"
19
+ invoke "mb:rbenv:compile_ruby"
20
+ end
21
+
22
+ task :write_vars do
23
+ on release_roles(:all) do
24
+ execute :mkdir, "-p ~/.rbenv"
25
+ execute :touch, "~/.rbenv/vars"
26
+ execute :chmod, "0600 ~/.rbenv/vars"
27
+
28
+ vars = ""
29
+
30
+ fetch(:mb_rbenv_vars).each do |name, value|
31
+ execute :sed, "--in-place '/^#{name}=/d' ~/.rbenv/vars"
32
+ vars << "#{name}=#{value}\n"
33
+ end
34
+
35
+ tmp_file = "/tmp/rbenv_vars"
36
+ put vars, tmp_file
37
+ execute :cat, tmp_file, ">> ~/.rbenv/vars"
38
+ execute :rm, tmp_file
39
+ end
40
+ end
41
+
42
+ task :run_installer do
43
+ on release_roles(:all) do
44
+ execute :curl,
45
+ "-L https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer",
46
+ "|", :bash
47
+ end
48
+ end
49
+
50
+ task :modify_bashrc do
51
+ on release_roles(:all) do
52
+ unless test("grep -qs 'rbenv init' ~/.bashrc")
53
+ template("rbenv_bashrc", "/tmp/rbenvrc")
54
+ execute :cat, "/tmp/rbenvrc ~/.bashrc > /tmp/bashrc"
55
+ execute :mv, "/tmp/bashrc ~/.bashrc"
56
+ execute %q{export PATH="$HOME/.rbenv/bin:$PATH"}
57
+ execute %q{eval "$(rbenv init -)"}
58
+ end
59
+ end
60
+ end
61
+
62
+ task :bootstrap_ubuntu_for_ruby_compile do
63
+ privileged_on release_roles(:all) do |host, user|
64
+ with :debian_frontend => "noninteractive" do
65
+ execute "sudo ~#{user}/.rbenv/plugins/rbenv-bootstrap/bin/rbenv-bootstrap-ubuntu-12-04"
66
+ execute "sudo aptitude -y -q install libffi-dev"
67
+ end
68
+ end
69
+ end
70
+
71
+ task :compile_ruby do
72
+ ruby_version = fetch(:mb_rbenv_ruby_version)
73
+ on release_roles(:all) do
74
+ force = ENV["RBENV_FORCE_INSTALL"] || begin
75
+ ! test("rbenv versions | grep -q '#{ruby_version}'")
76
+ end
77
+
78
+ if force
79
+ execute "CFLAGS=-O3 rbenv install --force #{ruby_version}"
80
+ execute "rbenv global #{ruby_version}"
81
+ execute "gem install bundler psych --no-document"
82
+ execute "rbenv rehash"
83
+ end
84
+ end
85
+ end
86
+
87
+ task :update_rbenv do
88
+ on release_roles(:all) do
89
+ execute "rbenv update"
90
+ end
91
+ end
92
+ end
93
+ end