capistrano-atlas 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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