mana 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 (44) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +2 -0
  6. data/cookbooks/monit/attributes/default.rb +13 -0
  7. data/cookbooks/monit/files/ubuntu/monit.default +11 -0
  8. data/cookbooks/monit/libraries/monitrc.rb +21 -0
  9. data/cookbooks/monit/recipes/default.rb +34 -0
  10. data/cookbooks/monit/recipes/ssh.rb +3 -0
  11. data/cookbooks/monit/templates/default/monitrc.erb +31 -0
  12. data/cookbooks/monit/templates/default/ssh.monit.conf.erb +7 -0
  13. data/cookbooks/nginx/attributes/default.rb +3 -0
  14. data/cookbooks/nginx/definitions/nginx_site.rb +15 -0
  15. data/cookbooks/nginx/recipes/default.rb +44 -0
  16. data/cookbooks/nginx/templates/default/default.conf.erb +11 -0
  17. data/cookbooks/nginx/templates/default/nginx.conf.erb +32 -0
  18. data/cookbooks/nginx/templates/default/nginx.monit.conf.erb +8 -0
  19. data/cookbooks/nginx/templates/default/nxdissite.erb +29 -0
  20. data/cookbooks/nginx/templates/default/nxensite.erb +38 -0
  21. data/cookbooks/postgresql/attributes/default.rb +5 -0
  22. data/cookbooks/postgresql/recipes/client.rb +5 -0
  23. data/cookbooks/postgresql/recipes/default.rb +2 -0
  24. data/cookbooks/postgresql/recipes/server.rb +25 -0
  25. data/cookbooks/postgresql/templates/default/pg_hba.conf.erb +4 -0
  26. data/cookbooks/postgresql/templates/default/postgresql.conf.erb +505 -0
  27. data/cookbooks/postgresql/templates/default/postgresql.monit.conf.erb +11 -0
  28. data/cookbooks/railsapp/attributes/default.rb +22 -0
  29. data/cookbooks/railsapp/recipes/default.rb +65 -0
  30. data/cookbooks/railsapp/templates/default/master.monit.conf.erb +8 -0
  31. data/cookbooks/railsapp/templates/default/site.conf.erb +62 -0
  32. data/cookbooks/railsapp/templates/default/unicorn-init.sh.erb +64 -0
  33. data/cookbooks/railsapp/templates/default/unicorn.rb.erb +37 -0
  34. data/cookbooks/railsapp/templates/default/worker.monit.conf.erb +8 -0
  35. data/lib/mana.rb +5 -0
  36. data/lib/mana/capistrano.rb +93 -0
  37. data/lib/mana/railtie.rb +7 -0
  38. data/lib/mana/version.rb +3 -0
  39. data/lib/tasks/mana.rake +9 -0
  40. data/mana.gemspec +21 -0
  41. data/templates/Vagrantfile +4 -0
  42. data/templates/config/deploy.rb +24 -0
  43. data/templates/config/deploy/vagrant.rb +7 -0
  44. metadata +136 -0
@@ -0,0 +1,11 @@
1
+ # managed by chef, changes will be overwritten
2
+ check process postgresql with pidfile /var/run/postgresql/<%= node.postgresql.version -%>-main.pid
3
+ start program "/etc/init.d/postgresql start"
4
+ stop program "/etc/init.d/postgresql stop"
5
+ if failed unixsocket /var/run/postgresql/.s.PGSQL.5432 protocol pgsql then alert
6
+ if failed unixsocket /var/run/postgresql/.s.PGSQL.5432 protocol pgsql then restart
7
+ <% if node.postgresql.listen_all -%>
8
+ if failed host localhost port 5432 protocol pgsql then alert
9
+ if failed host localhost port 5432 protocol pgsql then restart
10
+ <% end -%>
11
+ if 5 restarts within 5 cycles then timeout
@@ -0,0 +1,22 @@
1
+ default[:railsapp][:server_names] = "_"
2
+
3
+ default[:railsapp][:ssl] = false
4
+ default[:railsapp][:ssl_crt_path] = nil
5
+ default[:railsapp][:ssl_key_path] = nil
6
+
7
+ default[:railsapp][:db_name] = "#{node[:application]}_#{node[:rails_env]}"
8
+
9
+ default[:railsapp][:worker_processes] = 4
10
+ default[:railsapp][:request_timeout] = 60
11
+ default[:railsapp][:worker_user] = 'nobody'
12
+ default[:railsapp][:worker_group] = 'nogroup'
13
+
14
+ default[:railsapp][:before_fork] = <<-RUBY
15
+ ActiveRecord::Base.connection.disconnect! if defined?(ActiveRecord::Base)
16
+ Resque.redis.quit if defined?(Resque)
17
+ RUBY
18
+
19
+ default[:railsapp][:after_fork] = <<-RUBY
20
+ ActiveRecord::Base.establish_connection if defined?(ActiveRecord::Base)
21
+ Resque.redis = Redis.connect if defined?(Resque)
22
+ RUBY
@@ -0,0 +1,65 @@
1
+ directory node[:deploy_to] do
2
+ mode 0775
3
+ owner node[:user]
4
+ action :create
5
+ end
6
+
7
+ directory node[:shared_path] do
8
+ mode 0775
9
+ owner node[:user]
10
+ action :create
11
+ end
12
+
13
+ directory "#{node[:shared_path]}/sockets" do
14
+ mode 0775
15
+ owner node[:user]
16
+ action :create
17
+ end
18
+
19
+ template "#{node[:shared_path]}/unicorn.rb" do
20
+ source "unicorn.rb.erb"
21
+ owner "root"
22
+ group "root"
23
+ mode 0644
24
+ end
25
+
26
+ gem_package "bundler"
27
+
28
+ bash "create_database" do
29
+ code "psql -U postgres -c \"create database #{node[:railsapp][:db_name]}\""
30
+ only_if "test `psql -At -U postgres -c \"select count(*) from pg_database where datname = '#{node[:railsapp][:db_name]}';\"` -eq 0"
31
+ end
32
+
33
+ template "#{node[:nginx][:dir]}/sites-available/#{node[:application]}" do
34
+ source "site.conf.erb"
35
+ owner "root"
36
+ group "root"
37
+ mode 0644
38
+ notifies :reload, "service[nginx]"
39
+ end
40
+
41
+ template "/etc/init.d/#{node[:application]}-web" do
42
+ source "unicorn-init.sh.erb"
43
+ owner "root"
44
+ group "root"
45
+ mode 0755
46
+ end
47
+
48
+ nginx_site 'default' do
49
+ enable false
50
+ end
51
+
52
+ nginx_site node[:application] do
53
+ enable true
54
+ end
55
+
56
+ monitrc "#{node[:application]}-web" do
57
+ source "master.monit.conf.erb"
58
+ end
59
+
60
+ node[:railsapp][:worker_processes].times do |i|
61
+ monitrc "#{node[:application]}-web-#{i}" do
62
+ source "worker.monit.conf.erb"
63
+ variables nr: i
64
+ end
65
+ end
@@ -0,0 +1,8 @@
1
+ check process <%= node[:application] -%>-web
2
+ with pidfile <%= node[:shared_path] -%>/pids/unicorn.pid
3
+ start program = "/etc/init.d/<%= node[:application] -%>-web start"
4
+ stop program = "/etc/init.d/<%= node[:application] -%>-web stop"
5
+ if mem is greater than 300.0 MB for 1 cycles then restart
6
+ if cpu is greater than 50% for 2 cycles then alert
7
+ if cpu is greater than 80% for 3 cycles then restart
8
+ group <%= node[:application] -%>-web
@@ -0,0 +1,62 @@
1
+ upstream unicorn_<%= node[:application] %> {
2
+ # This is the socket we configured in unicorn.rb
3
+ server unix:<%= node[:shared_path] %>/sockets/unicorn.sock
4
+ fail_timeout=0;
5
+ }
6
+
7
+ server {
8
+ server_name <%= node[:railsapp][:server_names] %>;
9
+ listen 80;
10
+
11
+ root <%= node[:current_path] %>/public;
12
+
13
+ location / {
14
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
15
+ proxy_set_header Host $http_host;
16
+ proxy_redirect off;
17
+
18
+ # If you don't find the filename in the static files
19
+ # Then request it from the unicorn server
20
+ if (!-f $request_filename) {
21
+ proxy_pass http://unicorn_<%= node[:application] %>;
22
+ break;
23
+ }
24
+ }
25
+
26
+ location ~* \.(js|css|png|jpg|gif)$ {
27
+ if ($query_string ~ "^[0-9]+$") {
28
+ access_log off;
29
+ expires max;
30
+ add_header Cache-Control public;
31
+ }
32
+ }
33
+ }
34
+
35
+ <% if node[:railsapp][:ssl] %>
36
+ server {
37
+ listen 443;
38
+ server_name <%= node[:railsapp][:server_names] %>;
39
+
40
+ ssl on;
41
+ ssl_protocols SSLv3 TLSv1;
42
+ ssl_certificate <%= node[:current_path] %>/<%= node[:railsapp][:ssl_crt_path] %>;
43
+ ssl_certificate_key <%= node[:current_path] %>/<%= node[:railsapp][:ssl_key_path] %>;
44
+
45
+ proxy_set_header X-FORWARDED_PROTO https;
46
+
47
+ root <%= node[:current_path] %>/public;
48
+
49
+ location / {
50
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
51
+ proxy_set_header Host $http_host;
52
+ proxy_redirect off;
53
+
54
+ # If you don't find the filename in the static files
55
+ # Then request it from the unicorn server
56
+ if (!-f $request_filename) {
57
+ proxy_pass http://unicorn_<%= node[:application] %>;
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ <% end %>
@@ -0,0 +1,64 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ <%
6
+ cmd = <<-SHELL
7
+ cd #{node[:current_path]}
8
+ /usr/bin/env RAILS_ENV=#{node[:rails_env]} bundle exec unicorn -D -c #{node[:shared_path]}/unicorn.rb
9
+ SHELL
10
+ pid = "#{node[:shared_path]}/pids/unicorn.pid"
11
+ old_pid = "#{pid}.oldbin"
12
+ %>
13
+
14
+ PATH=/usr/local/sbin:/usr/local/bin:$PATH
15
+
16
+ action="$1"
17
+
18
+ set -u
19
+
20
+ sig () {
21
+ test -s "<%= pid %>" && kill -$1 `cat <%= pid %>`
22
+ }
23
+
24
+ case $action in
25
+ start)
26
+ sig 0 && echo >&2 "Already running" && exit 0
27
+ <%= cmd %>
28
+ ;;
29
+ stop)
30
+ sig QUIT && exit 0
31
+ echo >&2 "Not running"
32
+ ;;
33
+ force-stop)
34
+ sig TERM && exit 0
35
+ echo >&2 "Not running"
36
+ ;;
37
+ restart|reload)
38
+ if sig USR2 && sleep 5 && sig 0
39
+ then
40
+ n=60
41
+ while test -s <%= old_pid %> && test $n -ge 0
42
+ do
43
+ printf '.' && sleep 1 && n=$(( $n - 1 ))
44
+ done
45
+ echo
46
+
47
+ if test $n -lt 0 && test -s <%= old_pid %>
48
+ then
49
+ echo >&2 "Old process still exists after 60 seconds"
50
+ exit 1
51
+ fi
52
+ exit 0
53
+ fi
54
+ echo >&2 "Couldn't reload, starting '<%= cmd %>' instead"
55
+ <%= cmd %>
56
+ ;;
57
+ reopen-logs)
58
+ sig USR1
59
+ ;;
60
+ *)
61
+ echo >&2 "Usage: $0 <start|stop|restart|force-stop|reopen-logs>"
62
+ exit 1
63
+ ;;
64
+ esac
@@ -0,0 +1,37 @@
1
+ worker_processes <%= node[:railsapp][:worker_processes] %>
2
+
3
+ timeout <%= node[:railsapp][:request_timeout] %>
4
+
5
+ user '<%= node[:railsapp][:worker_user] %>',
6
+ '<%= node[:railsapp][:worker_group] %>'
7
+
8
+ listen "<%= node[:shared_path] %>/sockets/unicorn.sock"
9
+ pid "<%= node[:shared_path] %>/pids/unicorn.pid"
10
+
11
+ working_directory File.readlink("<%= node[:current_path] %>")
12
+
13
+ stderr_path "<%= node[:shared_path] %>/log/unicorn.log"
14
+ stdout_path "<%= node[:shared_path] %>/log/unicorn.log"
15
+
16
+ preload_app true
17
+ GC.copy_on_write_friendly = true if GC.respond_to?(:copy_on_write_friendly=)
18
+
19
+ before_fork do |server, worker|
20
+ old_pid = "#{server.config[:pid]}.oldbin"
21
+ if File.exists?(old_pid) && server.pid != old_pid
22
+ begin
23
+ Process.kill(:QUIT, File.read(old_pid).to_i)
24
+ rescue Errno::ENOENT, Errno::ESRCH
25
+ # someone else did our job for us
26
+ end
27
+ end
28
+ # Application-specific
29
+ <%= node[:railsapp][:before_fork] %>
30
+ end
31
+
32
+ after_fork do |server, worker|
33
+ child_pid = server.config[:pid].sub('.pid', ".#{worker.nr}.pid")
34
+ system("echo #{Process.pid} > #{child_pid}")
35
+ # Application-specific
36
+ <%= node[:railsapp][:after_fork] %>
37
+ end
@@ -0,0 +1,8 @@
1
+ check process <%= node[:application] -%>-web-worker-<%= @nr -%>
2
+ with pidfile <%= node[:shared_path] -%>/pids/unicorn.<%= @nr -%>.pid
3
+ start program = "/bin/true"
4
+ stop program = "/bin/sh -c 'kill `cat <%= node[:shared_path] -%>/pids/unicorn.<%= @nr -%>.pid`'"
5
+ if mem is greater than 200.0 MB for 1 cycles then restart
6
+ if cpu is greater than 25% for 2 cycles then alert
7
+ if cpu is greater than 50% for 5 cycles then restart
8
+ group <%= node[:application] -%>-web
data/lib/mana.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "mana/version"
2
+ require "mana/railtie"
3
+
4
+ module Mana
5
+ end
@@ -0,0 +1,93 @@
1
+ require 'roundsman/capistrano'
2
+ require 'capistrano_colors'
3
+ require 'capistrano/ext/multistage'
4
+
5
+ Capistrano::Configuration.instance(:must_exist).load do
6
+
7
+ # Convinient defaults
8
+
9
+ set(:deploy_to) { "/opt/#{fetch(:application)}" }
10
+ set :scm, 'git'
11
+ set :deploy_via, :remote_cache
12
+ set :use_sudo, false
13
+
14
+ default_run_options[:pty] = true
15
+ ssh_options[:forward_agent] = true
16
+
17
+ # Roundsman fine-tuning
18
+
19
+ set :chef_version, '0.10.10'
20
+ set :cookbooks_directory, 'config/deploy/cookbooks'
21
+ set :stream_roundsman_output, false
22
+ set :ruby_install_script do
23
+ %Q{
24
+ set -e
25
+ cd #{roundsman_working_dir}
26
+ rm -rf ruby-build
27
+ git clone -q git://github.com/sstephenson/ruby-build.git
28
+ cd ruby-build
29
+ ./install.sh
30
+ CONFIGURE_OPTS='--disable-install-rdoc' ruby-build #{fetch(:ruby_version)} #{fetch(:ruby_install_dir)}
31
+ }
32
+ end
33
+
34
+ # Mana
35
+
36
+ namespace :mana do
37
+ desc 'Complete setup of all software'
38
+ task :default do
39
+ if roundsman.install.install_ruby?
40
+ abort "Node is not boostrapped yet. Please run 'cap mana:setup' instead"
41
+ end
42
+ install
43
+ deploy.migrations
44
+ end
45
+
46
+ desc 'Bootstrap chef and ruby'
47
+ task :bootstrap do
48
+ roundsman.install.default
49
+ roundsman.chef.install
50
+ end
51
+
52
+ desc 'Install & update software'
53
+ task :install do
54
+ roundsman.chef.default
55
+ end
56
+
57
+ desc 'Show install log'
58
+ task :log do
59
+ sudo "cat /tmp/roundsman/cache/chef-stacktrace.out"
60
+ end
61
+
62
+ desc 'Complete setup'
63
+ task :setup do
64
+ upgrade
65
+ bootstrap
66
+ install
67
+ deploy.setup
68
+ deploy.cold
69
+ deploy.seed
70
+ sudo 'monit reload'
71
+ end
72
+
73
+ desc 'Upgrade software'
74
+ task :upgrade do
75
+ sudo "#{fetch(:package_manager)} -yq update"
76
+ sudo "#{fetch(:package_manager)} -yq upgrade"
77
+ end
78
+ end
79
+
80
+ # More convinience
81
+
82
+ namespace :deploy do
83
+ desc 'Update the database with seed data'
84
+ task :seed, roles: :db, only: {primary: true} do
85
+ run "cd #{current_path}; rake db:seed RAILS_ENV=#{rails_env}"
86
+ end
87
+
88
+ desc "Restart unicorn"
89
+ task :restart_unicorn, roles: :app, except: {no_release: true} do
90
+ sudo "service #{fetch(:application)}-web restart"
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,7 @@
1
+ module Mana
2
+ class ManaRailtie < Rails::Railtie
3
+ rake_tasks do
4
+ load 'tasks/mana.rake'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Mana
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ namespace :mana do
2
+ desc "Install mana configs"
3
+ task :install do
4
+ templates_path = File.expand_path(File.join(File.dirname(__FILE__), '../../templates')) + '/.'
5
+ cookbooks_path = File.expand_path(File.join(File.dirname(__FILE__), '../../cookbooks'))
6
+ FileUtils.cp_r templates_path, '.'
7
+ FileUtils.cp_r cookbooks_path, './config/deploy'
8
+ end
9
+ end
data/mana.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mana/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ilia Ablamonov, Cloud Castle Inc."]
6
+ gem.email = ["ilia@flamefork.ru"]
7
+ gem.description = "Configuration management with Chef & Capistrano"
8
+ gem.summary = "Configuration management with Chef & Capistrano"
9
+ gem.homepage = "https://github.com/cloudcastle/mana"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "mana"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mana::VERSION
17
+
18
+ gem.add_dependency "capistrano"
19
+ gem.add_dependency "roundsman"
20
+ gem.add_dependency "capistrano_colors"
21
+ end
@@ -0,0 +1,4 @@
1
+ Vagrant::Config.run do |config|
2
+ config.vm.box = "precise64"
3
+ config.vm.network :hostonly, "10.10.10.10"
4
+ end