capistrano-atlas 0.0.1

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 (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +13 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +215 -0
  7. data/Rakefile +5 -0
  8. data/capistrano-atlas.gemspec +32 -0
  9. data/lib/capistrano/atlas.rb +27 -0
  10. data/lib/capistrano/atlas/compatibility.rb +37 -0
  11. data/lib/capistrano/atlas/dsl.rb +157 -0
  12. data/lib/capistrano/atlas/recipe.rb +49 -0
  13. data/lib/capistrano/atlas/templates/crontab.erb +1 -0
  14. data/lib/capistrano/atlas/templates/csr_config.erb +10 -0
  15. data/lib/capistrano/atlas/templates/logrotate.erb +9 -0
  16. data/lib/capistrano/atlas/templates/maintenance.html.erb +26 -0
  17. data/lib/capistrano/atlas/templates/nginx.erb +64 -0
  18. data/lib/capistrano/atlas/templates/nginx_site.erb +97 -0
  19. data/lib/capistrano/atlas/templates/pgpass.erb +1 -0
  20. data/lib/capistrano/atlas/templates/postgresql-backup-logrotate.erb +11 -0
  21. data/lib/capistrano/atlas/templates/puma.rb.erb +22 -0
  22. data/lib/capistrano/atlas/templates/puma_init.erb +43 -0
  23. data/lib/capistrano/atlas/templates/rbenv_bashrc +4 -0
  24. data/lib/capistrano/atlas/templates/sidekiq_init.erb +100 -0
  25. data/lib/capistrano/atlas/templates/ssl_setup +43 -0
  26. data/lib/capistrano/atlas/templates/version.rb.erb +3 -0
  27. data/lib/capistrano/atlas/version.rb +5 -0
  28. data/lib/capistrano/tasks/aptitude.rake +111 -0
  29. data/lib/capistrano/tasks/bundler.rake +31 -0
  30. data/lib/capistrano/tasks/crontab.rake +14 -0
  31. data/lib/capistrano/tasks/defaults.rake +137 -0
  32. data/lib/capistrano/tasks/dotenv.rake +57 -0
  33. data/lib/capistrano/tasks/logrotate.rake +16 -0
  34. data/lib/capistrano/tasks/maintenance.rake +28 -0
  35. data/lib/capistrano/tasks/migrate.rake +29 -0
  36. data/lib/capistrano/tasks/nginx.rake +25 -0
  37. data/lib/capistrano/tasks/postgresql.rake +149 -0
  38. data/lib/capistrano/tasks/provision.rake +18 -0
  39. data/lib/capistrano/tasks/puma.rake +67 -0
  40. data/lib/capistrano/tasks/rake.rake +20 -0
  41. data/lib/capistrano/tasks/rbenv.rake +104 -0
  42. data/lib/capistrano/tasks/seed.rake +16 -0
  43. data/lib/capistrano/tasks/sidekiq.rake +42 -0
  44. data/lib/capistrano/tasks/ssl.rake +57 -0
  45. data/lib/capistrano/tasks/ufw.rake +32 -0
  46. data/lib/capistrano/tasks/user.rake +32 -0
  47. data/lib/capistrano/tasks/version.rake +34 -0
  48. metadata +161 -0
@@ -0,0 +1,29 @@
1
+ atlas_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 :atlas 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(:atlas_restart_during_migrate, true)
13
+ invoke :deploy
14
+ end
15
+
16
+ task :enable_maintenance_before do
17
+ if fetch(:atlas_restart_during_migrate)
18
+ invoke_if_defined "atlas:maintenance:enable"
19
+ invoke_if_defined "deploy:stop"
20
+ end
21
+ end
22
+
23
+ task :disable_maintenance_after do
24
+ if fetch(:atlas_restart_during_migrate)
25
+ invoke_if_defined "atlas:maintenance:disable"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ atlas_recipe :nginx do
2
+ during :provision, "configure"
3
+ end
4
+
5
+ namespace :atlas 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
+ execute "sudo service nginx restart"
13
+ end
14
+ end
15
+
16
+ %w(start stop restart).each do |command|
17
+ desc "#{command} nginx"
18
+ task command.intern do
19
+ privileged_on roles(:web) do
20
+ execute "sudo service nginx #{command}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,149 @@
1
+ atlas_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 :atlas do
12
+ namespace :postgresql do
13
+ desc "Create user if it doesn't already exist"
14
+ task :create_user do
15
+ privileged_on primary(:db) do
16
+ user = fetch(:atlas_postgresql_user)
17
+
18
+ unless test("sudo -u postgres psql -c '\\du' | grep -q #{user}")
19
+ passwd = fetch(:atlas_postgresql_password)
20
+ md5 = Digest::MD5.hexdigest(passwd + user)
21
+ execute "sudo -u postgres psql -c " +
22
+ %Q["CREATE USER #{user} PASSWORD 'md5#{md5}';"]
23
+ end
24
+ end
25
+ end
26
+
27
+ desc "Create database if it doesn't already exist"
28
+ task :create_database do
29
+ privileged_on primary(:db) do
30
+ user = fetch(:atlas_postgresql_user)
31
+ db = fetch(:atlas_postgresql_database)
32
+
33
+ unless test("sudo -u postgres psql -l | grep -w -q #{db}")
34
+ execute "sudo -u postgres createdb -O #{user} #{db}"
35
+ end
36
+ end
37
+ end
38
+
39
+ desc "Generate database.yml"
40
+ task :database_yml do
41
+ yaml = {
42
+ fetch(:rails_env).to_s => {
43
+ "adapter" => "postgresql",
44
+ "encoding" => "unicode",
45
+ "database" => fetch(:atlas_postgresql_database).to_s,
46
+ "pool" => fetch(:atlas_postgresql_pool_size).to_i,
47
+ "username" => fetch(:atlas_postgresql_user).to_s,
48
+ "password" => fetch(:atlas_postgresql_password).to_s,
49
+ "host" => fetch(:atlas_postgresql_host).to_s
50
+ }
51
+ }
52
+ fetch(:atlas_postgresql_password)
53
+ on release_roles(:all) do
54
+ put YAML.dump(yaml),
55
+ "#{shared_path}/config/database.yml",
56
+ :mode => "600"
57
+ end
58
+ end
59
+
60
+ desc "Generate pgpass file (needed by backup scripts)"
61
+ task :pgpass do
62
+ fetch(:atlas_postgresql_password)
63
+ on release_roles(:all) do
64
+ template "pgpass.erb",
65
+ fetch(:atlas_postgresql_pgpass_path),
66
+ :mode => "600"
67
+ end
68
+ end
69
+
70
+ desc "Configure logrotate to back up the database daily"
71
+ task :logrotate_backup do
72
+ on roles(:backup) do
73
+ backup_path = fetch(:atlas_postgresql_backup_path)
74
+ execute :mkdir, "-p", File.dirname(backup_path)
75
+ execute :touch, backup_path
76
+ end
77
+
78
+ privileged_on roles(:backup) do |host, user|
79
+ template\
80
+ "postgresql-backup-logrotate.erb",
81
+ "/etc/logrotate.d/postgresql-backup-#{application_basename}",
82
+ :owner => "root:root",
83
+ :mode => "644",
84
+ :binding => binding,
85
+ :sudo => true
86
+ end
87
+ end
88
+
89
+ desc "Dump the database to FILE"
90
+ task :dump do
91
+ on primary(:db) do
92
+ with_pgpassfile do
93
+ execute :pg_dump,
94
+ "-Fc -Z9 -O",
95
+ "-x", fetch(:atlas_postgresql_dump_options),
96
+ "-f", remote_dump_file,
97
+ connection_flags,
98
+ fetch(:atlas_postgresql_database)
99
+ end
100
+
101
+ download!(remote_dump_file, local_dump_file)
102
+
103
+ info(
104
+ "Exported #{fetch(:atlas_postgresql_database)} "\
105
+ "to #{local_dump_file}."
106
+ )
107
+ end
108
+ end
109
+
110
+ desc "Restore database from FILE"
111
+ task :restore do
112
+ on primary(:db) do
113
+ exit 1 unless agree(
114
+ "\nErase existing #{fetch(:rails_env)} database "\
115
+ "and restore from local file: #{local_dump_file}? "
116
+ )
117
+
118
+ upload!(local_dump_file, remote_dump_file)
119
+
120
+ with_pgpassfile do
121
+ execute :pg_restore,
122
+ "-O -c",
123
+ connection_flags,
124
+ "-d", fetch(:atlas_postgresql_database),
125
+ remote_dump_file
126
+ end
127
+ end
128
+ end
129
+
130
+ def local_dump_file
131
+ ENV.fetch("FILE", "#{fetch(:atlas_postgresql_database)}.dmp")
132
+ end
133
+
134
+ def remote_dump_file
135
+ "/tmp/#{fetch(:atlas_postgresql_database)}.dmp"
136
+ end
137
+
138
+ def connection_flags
139
+ [
140
+ "-U", fetch(:atlas_postgresql_user),
141
+ "-h", fetch(:atlas_postgresql_host)
142
+ ].join(" ")
143
+ end
144
+
145
+ def with_pgpassfile(&block)
146
+ with(:pgpassfile => fetch(:atlas_postgresql_pgpass_path), &block)
147
+ end
148
+ end
149
+ 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,67 @@
1
+ atlas_recipe :puma do
2
+ during "deploy:starting", "starting"
3
+ during :provision, %w(init_d nginx_site config_rb)
4
+ during "deploy:start", "start"
5
+ during "deploy:stop", "stop"
6
+ during "deploy:restart", "restart"
7
+ during "deploy:publishing", "restart"
8
+ end
9
+
10
+ namespace :atlas do
11
+ namespace :puma do
12
+ task :starting do
13
+ fetch(:linked_files, []) << "config/puma.rb"
14
+ end
15
+
16
+ desc "Install service script for puma"
17
+ task :init_d do
18
+ privileged_on roles(:app) do |host, user|
19
+ puma_user = fetch(:atlas_puma_user) || user
20
+
21
+ template "puma_init.erb",
22
+ "/etc/init.d/puma_#{application_basename}",
23
+ :mode => "a+rx",
24
+ :binding => binding
25
+
26
+ execute "update-rc.d -f puma_#{application_basename} defaults"
27
+ end
28
+ end
29
+
30
+ desc "Install puma proxy into nginx sites and restart nginx"
31
+ task :nginx_site do
32
+ set(:atlas_server_name, "puma")
33
+
34
+ privileged_on roles(:web) do
35
+ template "nginx_site.erb",
36
+ "/etc/nginx/sites-enabled/#{application_basename}"
37
+ execute "rm -f /etc/nginx/sites-enabled/default"
38
+ execute "mkdir -p /etc/nginx/#{application_basename}-locations"
39
+ execute "service nginx restart"
40
+ end
41
+ end
42
+
43
+ desc "Create config/puma.rb"
44
+ task :config_rb do
45
+ on release_roles(:all) do
46
+ template "puma.rb.erb", "#{shared_path}/config/puma.rb"
47
+ end
48
+ end
49
+
50
+ %w[start stop].each do |command|
51
+ desc "#{command} puma"
52
+ task command do
53
+ on roles(:app) do
54
+ execute "service puma_#{application_basename} #{command}"
55
+ end
56
+ end
57
+ end
58
+
59
+ desc "restart puma"
60
+ task :restart do
61
+ on roles(:app) do
62
+ execute "service puma_#{application_basename} restart || "\
63
+ "service puma_#{application_basename} start"
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,20 @@
1
+ atlas_recipe :rake do
2
+ # No hooks
3
+ end
4
+
5
+ namespace :atlas do
6
+ desc "Remotely execute a rake task"
7
+ task :rake do
8
+ if ENV['COMMAND'].nil?
9
+ raise "USAGE: cap #{fetch(:stage)} atlas: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,104 @@
1
+ atlas_recipe :rbenv do
2
+ during :provision, %w(install write_vars)
3
+ end
4
+
5
+ namespace :atlas do
6
+ namespace :rbenv do
7
+ desc "Install rbenv and compile ruby"
8
+ task :install do
9
+ invoke "atlas:rbenv:run_installer"
10
+ invoke "atlas:rbenv:add_plugins"
11
+ invoke "atlas:rbenv:modify_bashrc"
12
+ invoke "atlas:rbenv:compile_ruby"
13
+ end
14
+
15
+ desc "Install the latest version of Ruby"
16
+ task :upgrade do
17
+ invoke "atlas:rbenv:add_plugins"
18
+ invoke "atlas:rbenv:update_rbenv"
19
+ invoke "atlas: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(:atlas_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
+ installer_url = \
44
+ "https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer"
45
+
46
+ on release_roles(:all) do
47
+ with :path => "$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH" do
48
+ execute :curl, "-fsSL", installer_url, "| bash"
49
+ end
50
+ end
51
+ end
52
+
53
+ task :add_plugins do
54
+ plugins = %w(
55
+ sstephenson/rbenv-vars
56
+ sstephenson/ruby-build
57
+ rkh/rbenv-update
58
+ )
59
+ plugins.each do |plugin|
60
+ git_repo = "https://github.com/#{plugin}.git"
61
+ plugin_dir = "$HOME/.rbenv/plugins/#{plugin.split('/').last}"
62
+
63
+ on release_roles(:all) do
64
+ unless test("[ -d #{plugin_dir} ]")
65
+ execute :git, "clone", git_repo, plugin_dir
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ task :modify_bashrc do
72
+ on release_roles(:all) do
73
+ unless test("grep -qs 'rbenv init' ~/.bashrc")
74
+ template("rbenv_bashrc", "/tmp/rbenvrc")
75
+ execute :cat, "/tmp/rbenvrc ~/.bashrc > /tmp/bashrc"
76
+ execute :mv, "/tmp/bashrc ~/.bashrc"
77
+ execute %q{export PATH="$HOME/.rbenv/bin:$PATH"}
78
+ execute %q{eval "$(rbenv init -)"}
79
+ end
80
+ end
81
+ end
82
+
83
+ task :compile_ruby do
84
+ ruby_version = fetch(:atlas_rbenv_ruby_version)
85
+ on release_roles(:all) do
86
+ force = ENV["RBENV_FORCE_INSTALL"] || begin
87
+ ! test("rbenv versions | grep -q '#{ruby_version}'")
88
+ end
89
+
90
+ if force
91
+ execute "CFLAGS=-O3 rbenv install --force #{ruby_version}"
92
+ execute "rbenv global #{ruby_version}"
93
+ execute "gem install bundler --no-document"
94
+ end
95
+ end
96
+ end
97
+
98
+ task :update_rbenv do
99
+ on release_roles(:all) do
100
+ execute "rbenv update"
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,16 @@
1
+ atlas_recipe :seed do
2
+ prior_to "deploy:publishing", "atlas:seed"
3
+ end
4
+
5
+ namespace :atlas do
6
+ desc "Run rake db:seed"
7
+ task :seed do
8
+ on primary(:app) do
9
+ within release_path do
10
+ with :rails_env => fetch(:rails_env) do
11
+ execute :rake, "db:seed"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,42 @@
1
+ atlas_recipe :sidekiq do
2
+ during :provision, "init_d"
3
+ during "deploy:start", "start"
4
+ during "deploy:stop", "stop"
5
+ during "deploy:restart", "restart"
6
+ during "deploy:publishing", "restart"
7
+ end
8
+
9
+ namespace :atlas do
10
+ namespace :sidekiq do
11
+ desc "Install sidekiq service script"
12
+ task :init_d do
13
+ privileged_on roles(fetch(:atlas_sidekiq_role)) do |host, user|
14
+ template "sidekiq_init.erb",
15
+ "/etc/init.d/sidekiq_#{application_basename}",
16
+ :mode => "a+rx",
17
+ :binding => binding,
18
+ :sudo => true
19
+
20
+ execute "sudo update-rc.d -f sidekiq_#{application_basename} defaults"
21
+ end
22
+ end
23
+
24
+ %w[start stop].each do |command|
25
+ desc "#{command} sidekiq"
26
+ task command do
27
+ on roles(fetch(:atlas_sidekiq_role)) do
28
+ execute "service sidekiq_#{application_basename} #{command}"
29
+ end
30
+ end
31
+ end
32
+
33
+ desc "restart sidekiq"
34
+ task :restart do
35
+ # Re-enable the "stop" task, just in case we called it once already
36
+ # (as would happen during deploy:migrate_and_restart).
37
+ Rake::Task["atlas:sidekiq:stop"].reenable
38
+ invoke "atlas:sidekiq:stop"
39
+ invoke "atlas:sidekiq:start"
40
+ end
41
+ end
42
+ end