capistrano-mb 0.22.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.
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