badger-rails 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. data/BadgerGit.png +0 -0
  2. data/COPYING +674 -0
  3. data/LICENSING +30 -0
  4. data/Manifest +112 -0
  5. data/README.md +80 -0
  6. data/Rakefile +36 -0
  7. data/badger-rails.gemspec +34 -0
  8. data/bin/badger +486 -0
  9. data/lib/badger/Capfile +1 -0
  10. data/lib/badger/config/deploy.rb +211 -0
  11. data/lib/badger/config/rails-app.yml +6 -0
  12. data/lib/badger/config/rails-app.yml.bk +6 -0
  13. data/lib/badger/core/claws/app.claw +112 -0
  14. data/lib/badger/core/claws/db-app.claw +59 -0
  15. data/lib/badger/core/claws/rails-app.claw +125 -0
  16. data/lib/badger/core/files/badger/info +0 -0
  17. data/lib/badger/core/files/cap/Capfile +4 -0
  18. data/lib/badger/core/files/cap/deploy/production-app.rb +139 -0
  19. data/lib/badger/core/files/cap/deploy/production.rb +136 -0
  20. data/lib/badger/core/files/cap/deploy/staging-app.rb +139 -0
  21. data/lib/badger/core/files/cap/deploy/staging.rb +134 -0
  22. data/lib/badger/core/files/cap/deploy.rb +6 -0
  23. data/lib/badger/core/files/git/git +0 -0
  24. data/lib/badger/core/files/god/angel/resque-dev.god +54 -0
  25. data/lib/badger/core/files/god/angel/resque-stg.god +54 -0
  26. data/lib/badger/core/files/god/angel/resque.god +55 -0
  27. data/lib/badger/core/files/god/angel/unicorn-stg.god +62 -0
  28. data/lib/badger/core/files/god/angel/unicorn.god +62 -0
  29. data/lib/badger/core/files/god/god +108 -0
  30. data/lib/badger/core/files/god/unicorn-stg.rb +70 -0
  31. data/lib/badger/core/files/god/unicorn.rb +70 -0
  32. data/lib/badger/core/files/logrotate/logrotate.conf +23 -0
  33. data/lib/badger/core/files/logrotate/logrotate.cron +8 -0
  34. data/lib/badger/core/files/mysql/database.yml.bk +18 -0
  35. data/lib/badger/core/files/mysql/db_stats +0 -0
  36. data/lib/badger/core/files/mysql/my.cnf +11 -0
  37. data/lib/badger/core/files/nginx/nginx +106 -0
  38. data/lib/badger/core/files/nginx/nginx.conf +30 -0
  39. data/lib/badger/core/files/nginx/sites/port443.btl +42 -0
  40. data/lib/badger/core/files/nginx/sites/port80.btl +39 -0
  41. data/lib/badger/core/files/nginx/sites/production-web +117 -0
  42. data/lib/badger/core/files/nginx/sites/staging-web +41 -0
  43. data/lib/badger/core/files/postfix/main.cf +678 -0
  44. data/lib/badger/core/files/postfix/master.cf +81 -0
  45. data/lib/badger/core/files/redis/redis-server +59 -0
  46. data/lib/badger/core/files/redis/redis.conf +444 -0
  47. data/lib/badger/core/files/resque/resque.rb +5 -0
  48. data/lib/badger/core/files/resque/resque.yml +19 -0
  49. data/lib/badger/core/files/resque/resque_web.rb +2 -0
  50. data/lib/badger/core/files/ssh/authorized_keys +0 -0
  51. data/lib/badger/core/functions +174 -0
  52. data/lib/badger/core/scripts/app_info +40 -0
  53. data/lib/badger/core/scripts/app_scale +15 -0
  54. data/lib/badger/core/scripts/remove_app +25 -0
  55. data/lib/badger/core/scripts/remove_app_db +30 -0
  56. data/lib/badger/core/scripts/remove_gems +2 -0
  57. data/lib/badger/core/teeth/automake.th +9 -0
  58. data/lib/badger/core/teeth/badger.th +27 -0
  59. data/lib/badger/core/teeth/bison.th +20 -0
  60. data/lib/badger/core/teeth/bundler.th +4 -0
  61. data/lib/badger/core/teeth/capistrano-ext.th +37 -0
  62. data/lib/badger/core/teeth/chkconfig.th +4 -0
  63. data/lib/badger/core/teeth/curl.th +24 -0
  64. data/lib/badger/core/teeth/faac.th +11 -0
  65. data/lib/badger/core/teeth/ffmpeg.th +28 -0
  66. data/lib/badger/core/teeth/firewall.th +70 -0
  67. data/lib/badger/core/teeth/gcc-c++.th +9 -0
  68. data/lib/badger/core/teeth/gcc.th +9 -0
  69. data/lib/badger/core/teeth/git.th +23 -0
  70. data/lib/badger/core/teeth/god.th +17 -0
  71. data/lib/badger/core/teeth/lame.th +9 -0
  72. data/lib/badger/core/teeth/libffi.th +4 -0
  73. data/lib/badger/core/teeth/libid3tag.th +10 -0
  74. data/lib/badger/core/teeth/libmad.th +11 -0
  75. data/lib/badger/core/teeth/libogg.th +9 -0
  76. data/lib/badger/core/teeth/libtool.th +9 -0
  77. data/lib/badger/core/teeth/libxml2.th +19 -0
  78. data/lib/badger/core/teeth/libxslt.th +19 -0
  79. data/lib/badger/core/teeth/libyaml.th +19 -0
  80. data/lib/badger/core/teeth/logrotate.th +19 -0
  81. data/lib/badger/core/teeth/madplay.th +10 -0
  82. data/lib/badger/core/teeth/make.th +9 -0
  83. data/lib/badger/core/teeth/mysql-config.th +40 -0
  84. data/lib/badger/core/teeth/mysql-server.th +16 -0
  85. data/lib/badger/core/teeth/mysql.th +14 -0
  86. data/lib/badger/core/teeth/nginx.th +56 -0
  87. data/lib/badger/core/teeth/ntp.th +15 -0
  88. data/lib/badger/core/teeth/openssl.th +19 -0
  89. data/lib/badger/core/teeth/pcre.th +9 -0
  90. data/lib/badger/core/teeth/plugins.th +14 -0
  91. data/lib/badger/core/teeth/postfix.th +11 -0
  92. data/lib/badger/core/teeth/pwgen.th +9 -0
  93. data/lib/badger/core/teeth/rake.th +12 -0
  94. data/lib/badger/core/teeth/readline.th +19 -0
  95. data/lib/badger/core/teeth/redis.th +18 -0
  96. data/lib/badger/core/teeth/resque.th +12 -0
  97. data/lib/badger/core/teeth/ruby.th +52 -0
  98. data/lib/badger/core/teeth/rubygems.th +17 -0
  99. data/lib/badger/core/teeth/san_juan.th +4 -0
  100. data/lib/badger/core/teeth/sox.th +12 -0
  101. data/lib/badger/core/teeth/speex.th +12 -0
  102. data/lib/badger/core/teeth/sqlite3.th +14 -0
  103. data/lib/badger/core/teeth/ssh_keys.th +10 -0
  104. data/lib/badger/core/teeth/sshpass.th +9 -0
  105. data/lib/badger/core/teeth/sudo.th +9 -0
  106. data/lib/badger/core/teeth/syslog-ng.th +16 -0
  107. data/lib/badger/core/teeth/sysv-rc-conf.th +4 -0
  108. data/lib/badger/core/teeth/x264.th +11 -0
  109. data/lib/badger/core/teeth/xvid.th +11 -0
  110. data/lib/badger/core/teeth/yasm.th +11 -0
  111. data/lib/badger/core/teeth/zlib.th +9 -0
  112. data/lib/core.rb +313 -0
  113. data/lib/errors.rb +202 -0
  114. metadata +297 -0
@@ -0,0 +1,139 @@
1
+ load "deploy"
2
+ load "deploy/assets"
3
+ require 'rubygems'
4
+ require 'yaml'
5
+ require 'bundler/capistrano'
6
+ require './lib/badger_plugin.rb' if File.exists?("lib/badger_plugin.rb")
7
+
8
+ `git pull origin master`
9
+ YAML::ENGINE.yamler = 'syck'
10
+ yml = YAML.load_file "/opt/tmp/web/config/badger.yml"
11
+ name = yml[app_domain]['project_name']
12
+
13
+ yml.keys.each do |k|
14
+ if k.include?("app")
15
+ host_server = true
16
+ end
17
+ end
18
+
19
+ begin
20
+ database_yml = YAML.load_file "/opt/tmp/web/config/database_example.yml"
21
+ rescue
22
+ host_server = false
23
+ raise LoadError, "could not read from database_example.yml"
24
+ end
25
+
26
+ set :bundle_dir, ""
27
+ set :bundle_flags, ""
28
+ set :bundle_without, [:development, :test]
29
+ set :bundle_path, "/home/badger/.bundler"
30
+
31
+ set :application, "web"
32
+
33
+ set :repository, "git@#{yml['domain']}:/opt/git/#{name}.git"
34
+ set :rails_env, "staging"
35
+
36
+ set :scm, :git
37
+ set :branch, "master"
38
+ set :git_enable_submodules, 1
39
+ set :git_shallow_clone, 1
40
+
41
+ default_run_options[:pty] = true #fix for teamcity
42
+ ssh_options[:auth_methods] = %w(publickey)
43
+ ssh_options[:keys] = %w(/root/.ssh/id_rsa)
44
+
45
+ set :user, "badger"
46
+ set :domain, yml[app_domain]['domain']
47
+
48
+ set :deploy_to, "/opt/#{application}"
49
+
50
+ set :use_sudo, true
51
+ set :keep_releases, 30
52
+
53
+ require 'san_juan'
54
+ role :app, domain
55
+ role :web, domain
56
+ role :db, domain, :primary => true
57
+
58
+ san_juan.role :web, %w(nginx)
59
+ set :app_port, 4001
60
+
61
+ set :rake, "/opt/ruby/bin/rake"
62
+ set :default_environment, {
63
+ 'PATH' => '/opt/ruby/bin:/opt/rubygems/bin:$PATH',
64
+ 'GEM_HOME' => '/opt/rubygems'
65
+ }
66
+
67
+ namespace :configuration do
68
+ task :db do
69
+ run "cp #{release_path}/config/database_example.yml #{release_path}/config/database.yml"
70
+ end
71
+ end
72
+
73
+ namespace :resque do
74
+ task :prepare_resque, :roles => :app do
75
+ if host_server
76
+ resque_rake = "begin\n require 'resque'\n require 'resque/tasks'\n task \"resque:setup\" => :environment\nrescue LoadError\nend"
77
+ file = File.open("/opt/tmp/web/Rakefile")
78
+ rakefile = file.read
79
+ unless rakefile.include?(resque_rake)
80
+ file = File.open("#{release_path}/Rakefile", "a+") {|f| f.write("\n\n" + resque_rake) }
81
+ end
82
+ run "/bin/bash -c 'source /etc/badger/core/teeth/resque.th; dbResque=#{database_yml['staging']['host']}; source /etc/badger/core/files/resque/resque.yml; resque_yml #{release_path}; config_resque #{release_path}'"
83
+ end
84
+ end
85
+
86
+ task :load_config, :roles => :app do
87
+ run "mkdir -p #{release_path}/config/god"
88
+ run "rsync /etc/badger/core/files/god/angel/resque-dev.god #{release_path}/config/god/resque-dev.god"
89
+ run "rsync /etc/badger/core/files/god/angel/resque-stg.god #{release_path}/config/god/resque-stg.god"
90
+ run "rsync /etc/badger/core/files/god/angel/resque.god #{release_path}/config/god/resque.god"
91
+ if File.exists?('/home/badger/resque-stg.god')
92
+ run "sudo /opt/rubygems/bin/god load /home/badger/resque-stg.god"
93
+ else
94
+ run "sudo /opt/rubygems/bin/god load /etc/badger/core/files/god/angel/resque-stg.god"
95
+ end
96
+ end
97
+
98
+ task :restart, :roles => :app do
99
+ run "sudo /opt/rubygems/bin/god restart resque"
100
+ end
101
+ end
102
+
103
+ namespace :deploy do
104
+ desc "Restarting services using"
105
+ task :restart, :roles => :app, :except => { :no_release => true } do
106
+ resque.prepare_resque
107
+ resque.load_config
108
+ #resque.restart
109
+ end
110
+
111
+ [:start, :stop].each do |t|
112
+ desc "#{t} task is a no-op with passenger"
113
+ task t, :roles => :app do ; end
114
+ end
115
+
116
+ task :badger_plugin do
117
+ BadgerPlugin.new() if File.exists?("lib/badger_plugin.rb")
118
+ end
119
+
120
+ task :migrations do
121
+ run "cd #{release_path} && #{rake} db:migrate RAILS_ENV=staging"
122
+ end
123
+
124
+ task :seeds do
125
+ run "cd #{release_path} && #{rake} db:seed_fu RAILS_ENV=staging"
126
+ end
127
+
128
+ task :link_audio do
129
+ run "ln -sf /opt/recordings #{release_path}/public/recordings"
130
+ end
131
+ end
132
+
133
+ after 'deploy:finalize_update', :roles => :app do
134
+ configuration.db
135
+ deploy.migrations
136
+ #deploy.seeds
137
+ #deploy.link_audio
138
+ deploy.cleanup
139
+ end
@@ -0,0 +1,134 @@
1
+ load "deploy"
2
+ load "deploy/assets"
3
+ require 'rubygems'
4
+ require 'yaml'
5
+ require 'bundler/capistrano'
6
+ require './lib/badger_plugin.rb' if File.exists?("lib/badger_plugin.rb")
7
+
8
+ `git pull origin master`
9
+ YAML::ENGINE.yamler = 'syck'
10
+ yml = YAML.load_file "/opt/tmp/web/config/badger.yml"
11
+ name = `cat /etc/badger/core/files/badger/info`
12
+
13
+ yml.keys.each do |k|
14
+ if k.include?("app")
15
+ host_server = true
16
+ end
17
+ end
18
+ begin
19
+ database_yml = YAML.load_file "/opt/tmp/web/config/database_example.yml"
20
+ rescue
21
+ host_server = false
22
+ end
23
+
24
+ set :bundle_dir, ""
25
+ set :bundle_flags, ""
26
+ set :bundle_without, [:development, :test]
27
+ set :bundle_path, "/home/badger/.bundler"
28
+
29
+ set :application, "web"
30
+
31
+ set :repository, "git@#{yml['domain']}:/opt/git/#{name.chomp}.git"
32
+ set :rails_env, "staging"
33
+
34
+ set :scm, :git
35
+ set :branch, "master"
36
+ set :git_enable_submodules, 1
37
+ set :git_shallow_clone, 1
38
+
39
+ default_run_options[:pty] = true #fix for teamcity
40
+ ssh_options[:auth_methods] = %w(publickey)
41
+ ssh_options[:keys] = %w(/root/.ssh/id_rsa)
42
+
43
+ set :user, "badger"
44
+ set :domain, "#{yml['domain']}"
45
+
46
+ set :deploy_to, "/opt/#{application}"
47
+
48
+ set :use_sudo, true
49
+ set :keep_releases, 30
50
+
51
+ require 'san_juan'
52
+ role :app, domain
53
+ role :web, domain
54
+ role :db, domain, :primary => true
55
+
56
+ san_juan.role :web, %w(nginx)
57
+ set :app_port, 4001
58
+
59
+ set :rake, "bundle exec /opt/rubygems/bin/rake"
60
+ set :default_environment, {
61
+ 'PATH' => '/usr/bin:/bin/bash:/opt/ruby/bin:/opt/rubygems/bin:$PATH',
62
+ 'GEM_HOME' => '/opt/rubygems'
63
+ }
64
+
65
+ namespace :configuration do
66
+ task :resque, :roles => :app do
67
+ if host_server == true
68
+ run "/bin/bash -c 'source /etc/badger/core/teeth/resque.th; dbResque=#{database_yml['staging']['host']}; source /etc/badger/core/files/resque/resque.yml; resque_yml #{release_path}; config_resque #{release_path}'"
69
+ end
70
+ end
71
+
72
+ task :db do
73
+ if yml['local_db'] == false
74
+ run "cp -rf #{release_path}/config/database_example.yml #{release_path}/config/database.yml"
75
+ else
76
+ run "cp -rf /etc/badger/core/files/mysql/database.yml #{release_path}/config/database.yml"
77
+ end
78
+ run "cp -rf /etc/badger/core/files/god/unicorn-stg.rb #{release_path}/config/unicorn-stg.rb"
79
+ run "cp -rf /etc/badger/core/files/god/unicorn.rb #{release_path}/config/unicorn.rb"
80
+ end
81
+ end
82
+
83
+ namespace :unicorn do
84
+ task :load_config, :roles => :app do
85
+ run "mkdir -p #{release_path}/config/god"
86
+ run "rsync /etc/badger/core/files/god/angel/resque-dev.god #{release_path}/config/god/resque-dev.god"
87
+ run "rsync /etc/badger/core/files/god/angel/resque-stg.god #{release_path}/config/god/resque-stg.god"
88
+ run "rsync /etc/badger/core/files/god/angel/resque.god #{release_path}/config/god/resque.god"
89
+ run "sudo /opt/rubygems/bin/god load /etc/badger/core/files/god/angel/unicorn-stg.god"
90
+ end
91
+
92
+ task :restart, :roles => :app do
93
+ run "sudo /opt/rubygems/bin/god restart unicorn"
94
+ end
95
+ end
96
+
97
+ namespace :deploy do
98
+ desc "Restarting unicorn using"
99
+ task :restart, :roles => :app, :except => { :no_release => true } do
100
+ unicorn.load_config
101
+ unicorn.restart
102
+ end
103
+
104
+ [:start, :stop].each do |t|
105
+ desc "#{t} task is a no-op with passenger"
106
+ task t, :roles => :app do ; end
107
+ end
108
+
109
+ task :badger_plugin do
110
+ BadgerPlugin.new() if File.exists?("lib/badger_plugin.rb")
111
+ end
112
+
113
+ task :migrations do
114
+ run "cd #{release_path} && #{rake} db:migrate RAILS_ENV=staging --trace"
115
+ end
116
+
117
+ task :seeds do
118
+ run "cd #{release_path} && #{rake} db:seed_fu RAILS_ENV=staging"
119
+ end
120
+
121
+ task :link_audio do
122
+ run "ln -sf /opt/recordings #{release_path}/public/recordings"
123
+ end
124
+ end
125
+
126
+ after 'deploy:finalize_update', :roles => :app do
127
+ configuration.resque
128
+ configuration.db
129
+ deploy.badger_plugin
130
+ deploy.migrations
131
+ #deploy.seeds
132
+ #deploy.link_audio
133
+ deploy.cleanup
134
+ end
@@ -0,0 +1,6 @@
1
+ set :default_stage, "production"
2
+ set :stages, %w(staging production staging-app production-app)
3
+ require 'capistrano/ext/multistage'
4
+
5
+ set :rake, "env rake"
6
+
File without changes
@@ -0,0 +1,54 @@
1
+ path = '/opt/ruby/bin:/opt/rubygems/bin:/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin'
2
+ rails_env = ENV['RAILS_ENV'] || "development"
3
+ rails_root = "/opt/web/current"
4
+ shared_dir = "/opt/web/shared"
5
+ num_of_workers = 3
6
+
7
+ num_of_workers.times do |num|
8
+ God.watch do |w|
9
+ w.name = "resque-#{num}"
10
+ w.group = 'resque'
11
+ w.interval = 30.seconds # default
12
+ w.env = { 'PATH' => path, 'GEM_HOME' => '/opt/rubygems', 'RAILS_ENV' => rails_env, 'QUEUE' => 'default', 'VERBOSE' => 'true' }
13
+ w.start = "/opt/rubygems/bin/rake -f #{rails_root}/Rakefile -I #{rails_root} resque:work"
14
+ w.log = "#{shared_dir}/log/god_resque_#{num}.log"
15
+
16
+ w.start_grace = 60.seconds
17
+ w.restart_grace = 60.seconds
18
+
19
+ w.uid = 'badger'
20
+ w.gid = 'badger'
21
+
22
+ w.start_if do |start|
23
+ start.condition(:process_running) do |c|
24
+ c.interval = 5.seconds
25
+ c.running = false
26
+ end
27
+ end
28
+
29
+ w.restart_if do |restart|
30
+ restart.condition(:memory_usage) do |c|
31
+ c.above = 200.megabytes
32
+ c.times = [3, 5] # 3 out of 5 intervals
33
+ end
34
+
35
+ restart.condition(:cpu_usage) do |c|
36
+ c.above = 75.percent
37
+ c.times = 5
38
+ end
39
+ end
40
+
41
+ # lifecycle
42
+ w.lifecycle do |on|
43
+ on.condition(:flapping) do |c|
44
+ c.to_state = [:start, :restart]
45
+ c.times = 5
46
+ c.within = 5.minute
47
+ c.transition = :unmonitored
48
+ c.retry_in = 10.minutes
49
+ c.retry_times = 5
50
+ c.retry_within = 2.hours
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,54 @@
1
+ path = '/opt/ruby/bin:/opt/rubygems/bin:/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin'
2
+ rails_env = ENV['RAILS_ENV'] || "staging"
3
+ rails_root = "/opt/web/current"
4
+ shared_dir = "/opt/web/shared"
5
+ num_of_workers = 3
6
+
7
+ num_of_workers.times do |num|
8
+ God.watch do |w|
9
+ w.name = "resque-#{num}"
10
+ w.group = 'resque'
11
+ w.interval = 30.seconds # default
12
+ w.env = { 'PATH' => path, 'GEM_HOME' => '/opt/rubygems', 'RAILS_ENV' => rails_env, 'QUEUE' => 'default', 'VERBOSE' => 'true' }
13
+ w.start = "/opt/rubygems/bin/rake -f #{rails_root}/Rakefile -I #{rails_root} resque:work"
14
+ w.log = "#{shared_dir}/log/god_resque_#{num}.log"
15
+
16
+ w.start_grace = 60.seconds
17
+ w.restart_grace = 60.seconds
18
+
19
+ w.uid = 'badger'
20
+ w.gid = 'badger'
21
+
22
+ w.start_if do |start|
23
+ start.condition(:process_running) do |c|
24
+ c.interval = 5.seconds
25
+ c.running = false
26
+ end
27
+ end
28
+
29
+ w.restart_if do |restart|
30
+ restart.condition(:memory_usage) do |c|
31
+ c.above = 200.megabytes
32
+ c.times = [3, 5] # 3 out of 5 intervals
33
+ end
34
+
35
+ restart.condition(:cpu_usage) do |c|
36
+ c.above = 75.percent
37
+ c.times = 5
38
+ end
39
+ end
40
+
41
+ # lifecycle
42
+ w.lifecycle do |on|
43
+ on.condition(:flapping) do |c|
44
+ c.to_state = [:start, :restart]
45
+ c.times = 5
46
+ c.within = 5.minute
47
+ c.transition = :unmonitored
48
+ c.retry_in = 10.minutes
49
+ c.retry_times = 5
50
+ c.retry_within = 2.hours
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,55 @@
1
+ path = '/opt/ruby/bin:/opt/rubygems/bin:/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin'
2
+ rails_env = ENV['RAILS_ENV'] || "production"
3
+ rails_root = "/opt/web/current"
4
+ shared_dir = "/opt/web/shared"
5
+ num_of_workers = 3
6
+
7
+ num_of_workers.times do |num|
8
+ God.watch do |w|
9
+ w.name = "resque-#{num}"
10
+ w.group = 'resque'
11
+ w.interval = 30.seconds # default
12
+ w.env = { 'PATH' => path, 'GEM_HOME' => '/opt/rubygems', 'RAILS_ENV' => rails_env, 'QUEUE' => 'default', 'VERBOSE' => 'true' }
13
+ w.pid_file "#{SHARED_DIR}/pids/unicorn.pid"
14
+ w.start = "/opt/rubygems/bin/rake -f #{rails_root}/Rakefile -I #{rails_root} resque:work"
15
+ w.log = "#{shared_dir}/log/god_resque_#{num}.log"
16
+
17
+ w.start_grace = 60.seconds
18
+ w.restart_grace = 60.seconds
19
+
20
+ w.uid = 'badger'
21
+ w.gid = 'badger'
22
+
23
+ w.start_if do |start|
24
+ start.condition(:process_running) do |c|
25
+ c.interval = 5.seconds
26
+ c.running = false
27
+ end
28
+ end
29
+
30
+ w.restart_if do |restart|
31
+ restart.condition(:memory_usage) do |c|
32
+ c.above = 200.megabytes
33
+ c.times = [3, 5] # 3 out of 5 intervals
34
+ end
35
+
36
+ restart.condition(:cpu_usage) do |c|
37
+ c.above = 75.percent
38
+ c.times = 5
39
+ end
40
+ end
41
+
42
+ # lifecycle
43
+ w.lifecycle do |on|
44
+ on.condition(:flapping) do |c|
45
+ c.to_state = [:start, :restart]
46
+ c.times = 5
47
+ c.within = 5.minute
48
+ c.transition = :unmonitored
49
+ c.retry_in = 10.minutes
50
+ c.retry_times = 5
51
+ c.retry_within = 2.hours
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,62 @@
1
+ # http://unicorn.bogomips.org/SIGNALS.html
2
+
3
+ RAILS_ENV = ENV['RAILS_ENV'] || 'staging'
4
+ RAILS_ROOT = ENV['RAILS_ROOT'] || "/opt/web/current"
5
+ SHARED_DIR = "/opt/web/shared"
6
+
7
+ God.watch do |w|
8
+ w.name = "unicorn"
9
+ w.interval = 30.seconds # default
10
+ w.env = { 'PATH' => '/opt/ruby/bin:/opt/rubygems/bin:/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin', 'GEM_HOME' => '/opt/rubygems' }
11
+
12
+ # unicorn needs to be run from the rails root
13
+ w.start = "cd #{RAILS_ROOT} && /opt/rubygems/bin/unicorn_rails -c #{RAILS_ROOT}/config/unicorn-stg.rb -E #{RAILS_ENV} -D"
14
+
15
+ # QUIT gracefully shuts down workers
16
+ w.stop = "kill -QUIT `cat #{SHARED_DIR}/pids/unicorn.pid`"
17
+
18
+ # USR2 causes the master to re-create itself and spawn a new worker pool
19
+ w.restart = "kill -USR2 `cat #{SHARED_DIR}/pids/unicorn.pid`"
20
+
21
+ w.start_grace = 45.seconds
22
+ w.restart_grace = 45.seconds
23
+ w.pid_file = "#{SHARED_DIR}/pids/unicorn.pid"
24
+ w.log = "#{SHARED_DIR}/log/god_unicorn.log"
25
+
26
+ w.uid = 'badger'
27
+ w.gid = 'badger'
28
+
29
+ w.behavior(:clean_pid_file)
30
+
31
+ w.start_if do |start|
32
+ start.condition(:process_running) do |c|
33
+ c.interval = 5.seconds
34
+ c.running = false
35
+ end
36
+ end
37
+
38
+ w.restart_if do |restart|
39
+ restart.condition(:memory_usage) do |c|
40
+ c.above = 2000.megabytes
41
+ c.times = [3, 5] # 3 out of 5 intervals
42
+ end
43
+
44
+ restart.condition(:cpu_usage) do |c|
45
+ c.above = 99.percent
46
+ c.times = 5
47
+ end
48
+ end
49
+
50
+ # lifecycle
51
+ w.lifecycle do |on|
52
+ on.condition(:flapping) do |c|
53
+ c.to_state = [:start, :restart]
54
+ c.times = 5
55
+ c.within = 5.minute
56
+ c.transition = :unmonitored
57
+ c.retry_in = 10.minutes
58
+ c.retry_times = 5
59
+ c.retry_within = 2.hours
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,62 @@
1
+ # http://unicorn.bogomips.org/SIGNALS.html
2
+
3
+ RAILS_ENV = ENV['RAILS_ENV'] || 'production'
4
+ RAILS_ROOT = ENV['RAILS_ROOT'] || "/opt/web/current"
5
+ SHARED_DIR = "/opt/web/shared"
6
+
7
+ God.watch do |w|
8
+ w.name = "unicorn"
9
+ w.interval = 15.seconds # default
10
+ w.env = { 'PATH' => '/opt/ruby/bin:/opt/rubygems/bin:/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin', 'GEM_HOME' => '/opt/rubygems' }
11
+
12
+ # unicorn needs to be run from the rails root
13
+ w.start = "cd #{RAILS_ROOT} && /opt/rubygems/bin/unicorn -c #{RAILS_ROOT}/config/unicorn.rb -E #{RAILS_ENV} -D"
14
+
15
+ # QUIT gracefully shuts down workers
16
+ w.stop = "kill -QUIT `cat #{SHARED_DIR}/pids/unicorn.pid`"
17
+
18
+ # USR2 causes the master to re-create itself and spawn a new worker pool
19
+ w.restart = "kill -USR2 `cat #{SHARED_DIR}/pids/unicorn.pid`"
20
+
21
+ w.start_grace = 45.seconds
22
+ w.restart_grace = 45.seconds
23
+ w.pid_file = "#{SHARED_DIR}/pids/unicorn.pid"
24
+ w.log = "#{SHARED_DIR}/log/god_unicorn.log"
25
+
26
+ w.uid = 'badger'
27
+ w.gid = 'badger'
28
+
29
+ w.behavior(:clean_pid_file)
30
+
31
+ w.start_if do |start|
32
+ start.condition(:process_running) do |c|
33
+ c.interval = 5.seconds
34
+ c.running = false
35
+ end
36
+ end
37
+
38
+ w.restart_if do |restart|
39
+ restart.condition(:memory_usage) do |c|
40
+ c.above = 500.megabytes
41
+ c.times = [3, 5] # 3 out of 5 intervals
42
+ end
43
+
44
+ restart.condition(:cpu_usage) do |c|
45
+ c.above = 50.percent
46
+ c.times = 5
47
+ end
48
+ end
49
+
50
+ # lifecycle
51
+ w.lifecycle do |on|
52
+ on.condition(:flapping) do |c|
53
+ c.to_state = [:start, :restart]
54
+ c.times = 5
55
+ c.within = 5.minute
56
+ c.transition = :unmonitored
57
+ c.retry_in = 10.minutes
58
+ c.retry_times = 5
59
+ c.retry_within = 2.hours
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,108 @@
1
+ #!/opt/ruby/bin/ruby
2
+
3
+ DESC="god daemon"
4
+ NAME="god"
5
+ DAEMON="#{NAME}"
6
+ PIDFILE="/var/run/#{NAME}.pid"
7
+ LOGFILE="/var/log/#{NAME}.log"
8
+ SCRIPTNAME="/etc/init.d/#{NAME}"
9
+ START_FLAGS="-l #{LOGFILE} -P #{PIDFILE}"
10
+
11
+ ENV["PATH"] = "/opt/ruby/bin:/opt/rubygems/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
12
+ ENV["GEM_HOME"] = "/opt/rubygems"
13
+
14
+ def read_pid
15
+ begin
16
+ @pid = File.read(PIDFILE).to_i
17
+ @pid = nil if @pid == 0
18
+ rescue
19
+ @pid = nil
20
+ end
21
+ end
22
+
23
+ def kill(code)
24
+ Process.kill(code, @pid)
25
+ true
26
+ rescue
27
+ false
28
+ end
29
+
30
+ def running?
31
+ @pid && kill(0)
32
+ end
33
+
34
+ def dead?
35
+ @pid && !kill(0)
36
+ end
37
+
38
+ def start
39
+ if running?
40
+ puts "already running (#{@pid})"
41
+ exit
42
+ end
43
+
44
+ if dead?
45
+ clean_pid
46
+ end
47
+
48
+ puts "starting #{NAME}"
49
+ system("#{DAEMON} #{START_FLAGS}")
50
+ end
51
+
52
+ def stop
53
+ if not running?
54
+ puts "not running"
55
+ exit
56
+ end
57
+
58
+ puts "stopping #{NAME}"
59
+ system("#{DAEMON} quit")
60
+ end
61
+
62
+ def restart
63
+ if running?
64
+ stop
65
+ read_pid
66
+ end
67
+ start
68
+ end
69
+
70
+ def force_reload
71
+ if running?
72
+ restart
73
+ end
74
+ end
75
+
76
+ def clean_pid
77
+ File.delete(PIDFILE)
78
+ end
79
+
80
+ read_pid
81
+ case ARGV[0]
82
+ when 'start'
83
+ start
84
+ when 'stop'
85
+ stop
86
+ when 'restart'
87
+ if not running?
88
+ start
89
+ else
90
+ restart
91
+ end
92
+ when 'force-reload'
93
+ force_reload
94
+ when 'status'
95
+ if running?
96
+ puts "running (#{@pid})"
97
+ elsif dead?
98
+ puts "dead (#{@pid})"
99
+ exit!(1)
100
+ else
101
+ puts "not running"
102
+ exit!(3)
103
+ end
104
+ else
105
+ puts "Usage: #{SCRIPTNAME} start|stop|restart|force-reload|status"
106
+ end
107
+
108
+ exit