pvcglue 0.1.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.
Files changed (65) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +91 -0
  6. data/Rakefile +1 -0
  7. data/bin/pvc +13 -0
  8. data/lib/pvcglue.rb +43 -0
  9. data/lib/pvcglue/all_the_things.rb +7 -0
  10. data/lib/pvcglue/bootstrap.rb +8 -0
  11. data/lib/pvcglue/capistrano.rb +35 -0
  12. data/lib/pvcglue/cli.rb +150 -0
  13. data/lib/pvcglue/cloud.rb +278 -0
  14. data/lib/pvcglue/configuration.rb +157 -0
  15. data/lib/pvcglue/db.rb +145 -0
  16. data/lib/pvcglue/deploy.rb +4 -0
  17. data/lib/pvcglue/env.rb +141 -0
  18. data/lib/pvcglue/manager.rb +137 -0
  19. data/lib/pvcglue/nodes.rb +29 -0
  20. data/lib/pvcglue/packages.rb +47 -0
  21. data/lib/pvcglue/packages/bootstrap.rb +92 -0
  22. data/lib/pvcglue/packages/env.rb +80 -0
  23. data/lib/pvcglue/packages/firewall.rb +48 -0
  24. data/lib/pvcglue/packages/manager.rb +102 -0
  25. data/lib/pvcglue/packages/nginx.rb +10 -0
  26. data/lib/pvcglue/packages/nodejs.rb +17 -0
  27. data/lib/pvcglue/packages/passenger.rb +28 -0
  28. data/lib/pvcglue/packages/postgresql.rb +10 -0
  29. data/lib/pvcglue/packages/role_db.rb +47 -0
  30. data/lib/pvcglue/packages/role_lb.rb +64 -0
  31. data/lib/pvcglue/packages/role_memcached.rb +14 -0
  32. data/lib/pvcglue/packages/role_web.rb +60 -0
  33. data/lib/pvcglue/packages/rvm.rb +75 -0
  34. data/lib/pvcglue/packages/timezone.rb +17 -0
  35. data/lib/pvcglue/packages/ubuntu.rb +100 -0
  36. data/lib/pvcglue/railtie.rb +11 -0
  37. data/lib/pvcglue/ssl.rb +37 -0
  38. data/lib/pvcglue/templates/20auto-upgrades.erb +2 -0
  39. data/lib/pvcglue/templates/authorized_keys.erb +3 -0
  40. data/lib/pvcglue/templates/capfile.erb +20 -0
  41. data/lib/pvcglue/templates/database.yml.erb +57 -0
  42. data/lib/pvcglue/templates/denial_of_service.erb +3 -0
  43. data/lib/pvcglue/templates/deploy.rb.erb +81 -0
  44. data/lib/pvcglue/templates/gemrc.erb +1 -0
  45. data/lib/pvcglue/templates/hosts.erb +9 -0
  46. data/lib/pvcglue/templates/lb.nginx.conf.erb +88 -0
  47. data/lib/pvcglue/templates/lb.sites-enabled.erb +74 -0
  48. data/lib/pvcglue/templates/maintenance_mode.erb +46 -0
  49. data/lib/pvcglue/templates/memcached.conf.erb +55 -0
  50. data/lib/pvcglue/templates/passenger.list.erb +2 -0
  51. data/lib/pvcglue/templates/pg_hba.conf.erb +101 -0
  52. data/lib/pvcglue/templates/postgresql.conf.erb +557 -0
  53. data/lib/pvcglue/templates/sshd_config.erb +91 -0
  54. data/lib/pvcglue/templates/stage-deploy.rb.erb +33 -0
  55. data/lib/pvcglue/templates/timezone.erb +1 -0
  56. data/lib/pvcglue/templates/ufw.rules.erb +42 -0
  57. data/lib/pvcglue/templates/ufw.rules6.erb +25 -0
  58. data/lib/pvcglue/templates/web.bashrc.erb +120 -0
  59. data/lib/pvcglue/templates/web.env.erb +3 -0
  60. data/lib/pvcglue/templates/web.nginx.conf.erb +82 -0
  61. data/lib/pvcglue/templates/web.sites-enabled.erb +8 -0
  62. data/lib/pvcglue/toml_pvc_dumper.rb +53 -0
  63. data/lib/pvcglue/version.rb +3 -0
  64. data/pvcglue.gemspec +33 -0
  65. metadata +296 -0
@@ -0,0 +1,11 @@
1
+ require 'pvcglue'
2
+ require 'rails'
3
+ module Pvcglue
4
+ class Railtie < Rails::Railtie
5
+ railtie_name :pvcglue
6
+
7
+ rake_tasks do
8
+ load "tasks/pvc_db_utils.rake"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,37 @@
1
+ module Pvcglue
2
+ class Ssl < Thor
3
+
4
+ desc "csr", "create new csr"
5
+
6
+ def csr
7
+ name = Pvcglue.cloud.app_and_stage_name
8
+ system("openssl req -new -newkey rsa:2048 -nodes -keyout #{name}.key -out #{name}.csr")
9
+ end
10
+
11
+
12
+ desc "import", "import .key or .crt or both if no extension given (.crt must be 'prepared' for nginx)"
13
+
14
+ def import(file_name)
15
+ cloud_data = Pvcglue.cloud.data
16
+
17
+ ext = File.extname(file_name)
18
+
19
+ case ext
20
+ when ".crt", ".key"
21
+ cloud_data[Pvcglue.cloud.app_name][:stages][Pvcglue.cloud.stage_name]["ssl_#{ext[1..-1]}"] = File.read(file_name)
22
+ when ""
23
+ cloud_data[Pvcglue.cloud.app_name][:stages][Pvcglue.cloud.stage_name]["ssl_key"] = File.read("#{file_name}.key")
24
+ cloud_data[Pvcglue.cloud.app_name][:stages][Pvcglue.cloud.stage_name]["ssl_crt"] = File.read("#{file_name}.crt")
25
+ else
26
+ raise(Thor::Error, "Unknown file extension: #{ext}.")
27
+ end
28
+
29
+ # File.write(::Pvcglue.cloud.local_file_name, TOML.dump(cloud_data))
30
+ File.write(::Pvcglue.cloud.local_file_name, TOML::PvcDumper.new(cloud_data).toml_str)
31
+
32
+ Pvcglue::Manager.push_configuration
33
+ end
34
+
35
+
36
+ end
37
+ end
@@ -0,0 +1,2 @@
1
+ APT::Periodic::Update-Package-Lists "1";
2
+ APT::Periodic::Unattended-Upgrade "1";
@@ -0,0 +1,3 @@
1
+ <% Pvcglue.cloud.authorized_keys.each do |_, ssh_key| %>
2
+ <%= "#{ssh_key}\n" %>
3
+ <% end %>
@@ -0,0 +1,20 @@
1
+ # This is a generated file. Do not modify...or else! :)
2
+
3
+ # Load DSL and Setup Up Stages
4
+ require 'capistrano/setup'
5
+
6
+ # Includes default deployment tasks
7
+ require 'capistrano/deploy'
8
+
9
+ require 'capistrano/rvm'
10
+ set :rvm_type, :user
11
+
12
+ require 'capistrano/bundler'
13
+ require 'capistrano/rails/assets'
14
+ require 'capistrano/rails/migrations'
15
+ <% if Pvcglue.cloud.gems[:whenever] %>
16
+ require 'whenever/capistrano'
17
+ <% end %>
18
+
19
+ # Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
20
+ Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
@@ -0,0 +1,57 @@
1
+ # This is a generated file. Do not modify...or else! :)
2
+ #
3
+ # Add your username and password to your `.bash_profile` or equivalent, if needed.
4
+ # (If you don't need a username or password locally for postgresql, you can skip this.)
5
+ #
6
+ # Example
7
+ # export DB_USER_POSTGRES_USERNAME=andrew
8
+ # export DB_USER_POSTGRES_PASSWORD=andrew
9
+ #
10
+ # Note: This will use (or create) a new database for each branch in the project.
11
+ # Just run `rake db:rebuild` after creating or switching to a new branch.
12
+ # After that you won't need to rebuild the db when switching branches! :)
13
+ #
14
+ # You can disable this with the following if you think this is a bug, instead of a feature. ;)
15
+ #
16
+ # export DB_USER_POSTGRES_DISABLE_BRANCHES=true
17
+
18
+ server_common: &default_settings
19
+ adapter: postgresql
20
+ encoding: utf8
21
+ username: <%= %{<%= ENV['DB_USER_POSTGRES_USERNAME'] %}+'>' %>
22
+ password: <%= %{<%= ENV['DB_USER_POSTGRES_PASSWORD'] %}+'>' %>
23
+ host: <%= %{<%= ENV['DB_USER_POSTGRES_HOST'] || 'localhost' %}+'>' %>
24
+ port: <%= %{<%= ENV['DB_USER_POSTGRES_PORT'] || '5432' %}+'>' %>
25
+
26
+ development:
27
+ <<: *default_settings
28
+ database: <%= %{<%= ['#{Pvcglue.cloud.app_name}_dev', ENV['DB_USER_POSTGRES_DISABLE_BRANCHES'] == 'true' ? nil : `git rev-parse --abbrev-ref HEAD`.strip].compact.join('_').downcase %}+'>' %>
29
+
30
+ test:
31
+ <<: *default_settings
32
+ database: <%= %{<%= ['#{Pvcglue.cloud.app_name}_test', ENV['DB_USER_POSTGRES_DISABLE_BRANCHES'] == 'true' ? nil : `git rev-parse --abbrev-ref HEAD`.strip].compact.join('_').downcase %}+'>' %>
33
+
34
+
35
+ alpha:
36
+ <<: *default_settings
37
+ database: <%= Pvcglue.cloud.app_name + '_alpha' %>
38
+
39
+ beta:
40
+ <<: *default_settings
41
+ database: <%= Pvcglue.cloud.app_name + '_beta' %>
42
+
43
+ gamma:
44
+ <<: *default_settings
45
+ database: <%= Pvcglue.cloud.app_name + '_gamma' %>
46
+
47
+ delta:
48
+ <<: *default_settings
49
+ database: <%= Pvcglue.cloud.app_name + '_delta' %>
50
+
51
+ preview:
52
+ <<: *default_settings
53
+ database: <%= Pvcglue.cloud.app_name + '_preview' %>
54
+
55
+ production:
56
+ <<: *default_settings
57
+ database: <%= Pvcglue.cloud.app_name + '_production' %>
@@ -0,0 +1,3 @@
1
+
2
+ limit_conn conn_limit_per_ip 10;
3
+ limit_req zone=req_limit_per_ip burst=30 nodelay;
@@ -0,0 +1,81 @@
1
+ # This is a generated file. Do not modify...or else! :)
2
+
3
+ set :application, '<%= Pvcglue.configuration.application_name %>'
4
+ set :repo_url, '<%= Pvcglue.cloud.repo_url %>'
5
+
6
+ set :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
7
+
8
+ set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets}
9
+
10
+ set :bundle_flags, '--deployment' # Remove the `--quiet` flag
11
+
12
+ namespace :deploy do
13
+ <% if Pvcglue.cloud.gems[:delayed_job] %>
14
+ def args
15
+ fetch(:delayed_job_args, "")
16
+ end
17
+
18
+ def delayed_job_roles
19
+ fetch(:delayed_job_server_role, :app)
20
+ end
21
+
22
+ desc 'Stop the delayed_job process'
23
+ task :delayed_job_stop do
24
+ on roles(delayed_job_roles) do
25
+ within release_path do
26
+ with rails_env: fetch(:rails_env) do
27
+ execute :'script/delayed_job', :stop
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ desc 'Start the delayed_job process'
34
+ task :delayed_job_start do
35
+ on roles(delayed_job_roles) do
36
+ within release_path do
37
+ with rails_env: fetch(:rails_env) do
38
+ execute :'script/delayed_job', args, :start
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ desc 'Restart the delayed_job process'
45
+ task :delayed_job_restart do
46
+ on roles(delayed_job_roles) do
47
+ within release_path do
48
+ with rails_env: fetch(:rails_env) do
49
+ execute :'script/delayed_job', args, :restart
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ #desc 'Restart Delayed Job'
56
+ #task :restart_delayed_job do
57
+ # on roles(:app), in: :sequence, wait: 5 do
58
+ # invoke 'delayed_job_restart'
59
+ # end
60
+ #end
61
+
62
+ #task :restart_delayed_job do
63
+ # invoke 'delayed_job:restart'
64
+ #end
65
+
66
+
67
+ after :publishing, :delayed_job_restart # calling this directly is a work-around due to "NoMethodError: undefined method `verbosity'" error when calling task from a task in capistrano 3.1.0 and SSHKit 1.3.0
68
+ <% end %>
69
+
70
+ desc 'Restart passenger app'
71
+ task :restart_passenger do
72
+ on roles(:app), in: :sequence, wait: 5 do
73
+ execute :touch, release_path.join('tmp/restart.txt')
74
+ #invoke 'delayed_job_restart'
75
+ end
76
+ end
77
+
78
+ after :publishing, :restart_passenger
79
+
80
+ after :finishing, 'deploy:cleanup'
81
+ end
@@ -0,0 +1 @@
1
+ gem: --no-ri --no-rdoc
@@ -0,0 +1,9 @@
1
+ 127.0.0.1 localhost
2
+ 127.0.1.1 <%= Pvcglue.cloud.current_hostname %>
3
+
4
+ # The following lines are desirable for IPv6 capable hosts
5
+ ::1 ip6-localhost ip6-loopback
6
+ fe00::0 ip6-localnet
7
+ ff00::0 ip6-mcastprefix
8
+ ff02::1 ip6-allnodes
9
+ ff02::2 ip6-allrouters
@@ -0,0 +1,88 @@
1
+ user www-data;
2
+
3
+ # TODO: Should be set to the same as `grep processor /proc/cpuinfo | wc -l`
4
+ worker_processes 1;
5
+
6
+ pid /var/run/nginx.pid;
7
+
8
+ events {
9
+ worker_connections 768;
10
+ # multi_accept on;
11
+ }
12
+
13
+ http {
14
+
15
+ ##
16
+ # Basic Settings
17
+ ##
18
+
19
+ sendfile on;
20
+ tcp_nopush on;
21
+ tcp_nodelay on;
22
+ keepalive_timeout 65;
23
+ types_hash_max_size 2048;
24
+ # server_tokens off;
25
+
26
+ server_names_hash_bucket_size 64;
27
+ # server_name_in_redirect off;
28
+
29
+ include /etc/nginx/mime.types;
30
+ default_type application/octet-stream;
31
+
32
+ ##
33
+ # Logging Settings
34
+ ##
35
+
36
+ access_log /var/log/nginx/access.log;
37
+ error_log /var/log/nginx/error.log;
38
+
39
+ ##
40
+ # Gzip Settings
41
+ ##
42
+
43
+ gzip on;
44
+ gzip_disable "msie6";
45
+
46
+ # gzip_vary on;
47
+ # gzip_proxied any;
48
+ # gzip_comp_level 6;
49
+ # gzip_buffers 16 8k;
50
+ # gzip_http_version 1.1;
51
+ # gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
52
+
53
+ ##
54
+ # nginx-naxsi config
55
+ ##
56
+ # Uncomment it if you installed nginx-naxsi
57
+ ##
58
+
59
+ # include /etc/nginx/naxsi_core.rules;
60
+
61
+ ##
62
+ # Phusion Passenger config
63
+ ##
64
+ # Uncomment it if you installed passenger or passenger-enterprise
65
+ ##
66
+
67
+ # passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
68
+ # passenger_ruby /home/deploy/.rvm/gems/ruby-2.0.0-p353/wrappers/ruby;
69
+ # passenger_ruby /usr/bin/ruby;
70
+
71
+ ##
72
+ # Virtual Host Configs
73
+ ##
74
+
75
+ # disable the default server
76
+ #server {
77
+ # listen 80;
78
+ # server_name _;
79
+ # return 444;
80
+ #}
81
+
82
+ # DoS prevention
83
+ limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
84
+ limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=1r/s;
85
+
86
+ include /etc/nginx/conf.d/*.conf;
87
+ include /etc/nginx/sites-enabled/*;
88
+ }
@@ -0,0 +1,74 @@
1
+ upstream <%= Pvcglue.cloud.app_and_stage_name %>_application {
2
+ <% Pvcglue.cloud.nodes_in_stage('web').each do |_, node_config| %>
3
+ server <%= node_config[:private_ip] %> max_fails=1 fail_timeout=10s;
4
+ <% end %>
5
+ }
6
+
7
+ server {
8
+ listen 80;
9
+ server_name <%= Pvcglue.cloud.domains.join(' ') %>;
10
+
11
+ access_log /var/log/nginx/<%= Pvcglue.cloud.app_and_stage_name %>.access.log;
12
+ error_log /var/log/nginx/<%= Pvcglue.cloud.app_and_stage_name %>.error.log;
13
+
14
+ root <%= Pvcglue.cloud.deploy_to_app_dir %>;
15
+
16
+ <%= Pvcglue.render_template('denial_of_service.erb') %>
17
+ <%= Pvcglue.render_template('maintenance_mode.erb') %>
18
+
19
+ <% case Pvcglue.cloud.ssl_mode
20
+ when :none %>
21
+ location / {
22
+ proxy_set_header Host $host;
23
+ proxy_set_header X-Real-IP $remote_addr;
24
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
25
+ proxy_set_header X-Maintenance-Bypass $maintenance_bypass;
26
+
27
+ proxy_pass http://<%= Pvcglue.cloud.app_and_stage_name %>_application;
28
+ }
29
+ <% when :load_balancer_force_ssl %>
30
+ location / {
31
+ # According to http://serverfault.com/a/401632/156820 this is the correct way to redirect all http to https
32
+ return 301 https://$host$request_uri;
33
+ }
34
+ <% else
35
+ raise "Unsupported SSL option '#{Pvcglue.cloud.ssl_mode}'" %>
36
+ <% end %>
37
+ }
38
+
39
+ <% unless Pvcglue.cloud.ssl_mode == :none %>
40
+ server {
41
+ listen 443 ssl;
42
+ server_name <%= Pvcglue.cloud.domains.join(' ') %>;
43
+
44
+ access_log /var/log/nginx/<%= Pvcglue.cloud.app_and_stage_name %>.ssl.access.log;
45
+ error_log /var/log/nginx/<%= Pvcglue.cloud.app_and_stage_name %>.ssl.error.log;
46
+
47
+ root <%= Pvcglue.cloud.deploy_to_app_dir %>;
48
+
49
+ <%= Pvcglue.render_template('denial_of_service.erb') %>
50
+ <%= Pvcglue.render_template('maintenance_mode.erb') %>
51
+
52
+ <% case Pvcglue.cloud.ssl_mode
53
+ when :none %>
54
+ # ssl_mode: none
55
+ <% when :load_balancer_force_ssl %>
56
+ ssl on;
57
+ ssl_certificate <%= Pvcglue.cloud.nginx_ssl_crt_file_name %>;
58
+ ssl_certificate_key <%= Pvcglue.cloud.nginx_ssl_key_file_name %>;
59
+ <% else
60
+ raise "Unsupported SSL option '#{Pvcglue.cloud.ssl_mode}'" %>
61
+ <% end %>
62
+
63
+ location / {
64
+
65
+ proxy_set_header Host $host;
66
+ proxy_set_header X-Real-IP $remote_addr;
67
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
68
+ proxy_set_header X-Maintenance-Bypass $maintenance_bypass;
69
+ proxy_set_header X-Forwarded-Proto https;
70
+
71
+ proxy_pass http://<%= Pvcglue.cloud.app_and_stage_name %>_application;
72
+ }
73
+ }
74
+ <% end %>
@@ -0,0 +1,46 @@
1
+
2
+ # partially based on https://onehub.com/blog/2009/03/06/rails-maintenance-pages-done-right/
3
+ recursive_error_pages on;
4
+
5
+ set $maintenance off;
6
+ set $maintenance_bypass off;
7
+ # https://blog.ed.gs/2013/01/25/nginx-multiple-if-statements/
8
+ set $bypass_test no;
9
+
10
+ if (-f $document_root/maintenance/maintenance.on) {
11
+ set $maintenance on;
12
+ set $bypass_test yes;
13
+ }
14
+
15
+ if ($remote_addr ~ <%= Pvcglue.cloud.dev_ip_addresses.join('|').gsub('.', '\.') %>) {
16
+ set $maintenance off;
17
+ set $bypass_test "${bypass_test}yes";
18
+ }
19
+
20
+ if ($bypass_test = yesyes) {
21
+ set $maintenance_bypass on; # only add header when maintenance is on and the remote address is a dev ip address
22
+ }
23
+
24
+ if ($uri ~ ^/maintenance/.*) {
25
+ set $maintenance off;
26
+ }
27
+
28
+ if ($maintenance = on) {
29
+ return 503; # 503 - Service unavailable
30
+ }
31
+
32
+ location /maintenance {
33
+ }
34
+
35
+ #error_page 404 /404.html;
36
+ #error_page 500 502 504 /500.html;
37
+ error_page 503 @503;
38
+
39
+ location @503 {
40
+
41
+ error_page 405 = /maintenance/maintenance.html;
42
+
43
+ # Serve static assets if found.
44
+ rewrite ^(.*)$ /maintenance/maintenance.html break;
45
+ }
46
+