mana 0.0.1

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