mana 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/cookbooks/monit/attributes/default.rb +13 -0
- data/cookbooks/monit/files/ubuntu/monit.default +11 -0
- data/cookbooks/monit/libraries/monitrc.rb +21 -0
- data/cookbooks/monit/recipes/default.rb +34 -0
- data/cookbooks/monit/recipes/ssh.rb +3 -0
- data/cookbooks/monit/templates/default/monitrc.erb +31 -0
- data/cookbooks/monit/templates/default/ssh.monit.conf.erb +7 -0
- data/cookbooks/nginx/attributes/default.rb +3 -0
- data/cookbooks/nginx/definitions/nginx_site.rb +15 -0
- data/cookbooks/nginx/recipes/default.rb +44 -0
- data/cookbooks/nginx/templates/default/default.conf.erb +11 -0
- data/cookbooks/nginx/templates/default/nginx.conf.erb +32 -0
- data/cookbooks/nginx/templates/default/nginx.monit.conf.erb +8 -0
- data/cookbooks/nginx/templates/default/nxdissite.erb +29 -0
- data/cookbooks/nginx/templates/default/nxensite.erb +38 -0
- data/cookbooks/postgresql/attributes/default.rb +5 -0
- data/cookbooks/postgresql/recipes/client.rb +5 -0
- data/cookbooks/postgresql/recipes/default.rb +2 -0
- data/cookbooks/postgresql/recipes/server.rb +25 -0
- data/cookbooks/postgresql/templates/default/pg_hba.conf.erb +4 -0
- data/cookbooks/postgresql/templates/default/postgresql.conf.erb +505 -0
- data/cookbooks/postgresql/templates/default/postgresql.monit.conf.erb +11 -0
- data/cookbooks/railsapp/attributes/default.rb +22 -0
- data/cookbooks/railsapp/recipes/default.rb +65 -0
- data/cookbooks/railsapp/templates/default/master.monit.conf.erb +8 -0
- data/cookbooks/railsapp/templates/default/site.conf.erb +62 -0
- data/cookbooks/railsapp/templates/default/unicorn-init.sh.erb +64 -0
- data/cookbooks/railsapp/templates/default/unicorn.rb.erb +37 -0
- data/cookbooks/railsapp/templates/default/worker.monit.conf.erb +8 -0
- data/lib/mana.rb +5 -0
- data/lib/mana/capistrano.rb +93 -0
- data/lib/mana/railtie.rb +7 -0
- data/lib/mana/version.rb +3 -0
- data/lib/tasks/mana.rake +9 -0
- data/mana.gemspec +21 -0
- data/templates/Vagrantfile +4 -0
- data/templates/config/deploy.rb +24 -0
- data/templates/config/deploy/vagrant.rb +7 -0
- 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,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
|
data/lib/mana/railtie.rb
ADDED
data/lib/mana/version.rb
ADDED
data/lib/tasks/mana.rake
ADDED
@@ -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
|