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.
- 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
|