brightbox-server-tools 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ require 'rake/gempackagetask'
2
+ require "brightbox-gemspec.rb"
3
+
4
+ namespace :client do
5
+ Rake::GemPackageTask.new(@client).define
6
+
7
+ task :default => [:reinstall, :clobber_package]
8
+
9
+ desc "Reinstall the client gem locally"
10
+ task :reinstall => [:repackage] do
11
+ sh %Q{sudo gem uninstall -x -v #{@client.version} #{@client.name} }
12
+ sh %q{sudo gem install pkg/*.gem}
13
+ end
14
+
15
+ end
16
+
17
+ namespace :server do
18
+ Rake::GemPackageTask.new(@server).define
19
+ end
20
+
21
+ task :clobber_package => "client:clobber_package"
22
+ task :package => ["client:package", "server:package"]
23
+ task :repackage => ["client:repackage", "server:package"]
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env ruby
2
+ # Brightbox - Easy Ruby Web Application Deployment
3
+ # Copyright (C) 2008, Neil Wilson, Brightbox Systems
4
+ #
5
+ # This file is part of the Brightbox deployment system
6
+ #
7
+ # Brightbox gem is free software: you can redistribute it and/or modify it
8
+ # under the terms of the GNU Affero General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License,
10
+ # or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General
18
+ # Public License along with this program. If not, see
19
+ # <http://www.gnu.org/licenses/>.
20
+ #
21
+ WEBSERVER="apache2"
22
+ require "brightbox/webserver-common"
23
+
24
+ def ssl_certificate_key
25
+ if @key_file
26
+ " SSLCertificateKeyFile #{key_file}"
27
+ end
28
+ end
29
+
30
+ def http_config
31
+ %Q{
32
+ #{config_time_stamp}
33
+ <VirtualHost *:80>
34
+ ServerName #{@domain}
35
+ ServerAlias #{local_app_alias} #{@aliases}
36
+ DocumentRoot #{@webroot}
37
+
38
+ <Directory "#{@webroot}">
39
+ Options FollowSymLinks
40
+ AllowOverride None
41
+ Order allow,deny
42
+ Allow from all
43
+ </Directory>
44
+
45
+ # Configure mongrel_cluster
46
+ <Proxy balancer://mongrel_cluster>
47
+ #{balancer_members}
48
+ </Proxy>
49
+
50
+ ErrorLog /var/log/web/#{@application}.err
51
+ CustomLog /var/log/web/#{@application}.log combined
52
+
53
+ # Rails specific rewrite rules
54
+ Include /etc/apache2/brightbox-common
55
+
56
+ # Add any access limit directives here
57
+ <Location />
58
+ Allow from all
59
+ </Location>
60
+ </VirtualHost>
61
+ }
62
+ end
63
+
64
+ def https_config
65
+ %Q{
66
+ #{config_time_stamp}
67
+ <VirtualHost _default_:443>
68
+ SSLEngine On
69
+ SSLCertificateFile #{@certificate_file}
70
+ #{ssl_certificate_key}
71
+ RequestHeader set X_FORWARDED_PROTO "https"
72
+ ServerName #{@domain}
73
+ ServerAlias #{local_app_alias} #{@aliases}
74
+ DocumentRoot #{@webroot}
75
+
76
+ <Directory "#{@webroot}">
77
+ Options FollowSymLinks
78
+ AllowOverride None
79
+ Order allow,deny
80
+ Allow from all
81
+ </Directory>
82
+
83
+ # Configure mongrel_cluster
84
+ <Proxy balancer://mongrel_cluster>
85
+ #{balancer_members}
86
+ </Proxy>
87
+
88
+ ErrorLog /var/log/web/#{@application}.err
89
+ CustomLog /var/log/web/#{@application}.log combined
90
+
91
+ # Rails specific rewrite rules
92
+ Include /etc/apache2/brightbox-common
93
+
94
+ # Add any access limit directives here
95
+ <Location />
96
+ Allow from all
97
+ </Location>
98
+ </VirtualHost>
99
+ }
100
+ end
101
+
102
+
103
+ def activate_modules(modules)
104
+ modules.each do |mod|
105
+ system %Q{/usr/sbin/a2enmod "#{mod}"}
106
+ end
107
+ end
108
+
109
+ def configure_ports
110
+ File.open("/etc/apache2/ports.conf", "w") do |f|
111
+ f.puts "Listen 80"
112
+ f.puts "Listen 443" if File.file?("/etc/apache2/sites-enabled/rails-default-ssl")
113
+ end
114
+ end
115
+
116
+ def balancer_members
117
+ (@port..@port+@mongrels-1).collect do |i|
118
+ " BalancerMember http://#{@mongrelhost}:#{i} retry=5"
119
+ end.join("\n")
120
+ end
121
+
122
+ #MAIN PROGRAM
123
+ @apache_http_modules = %w(proxy_balancer proxy_http rewrite)
124
+ @apache_https_modules = %w(ssl headers)
125
+
126
+ #Create a normal HTTP config
127
+ @config=http_config
128
+ configure_site(@application)
129
+ activate_modules(@apache_http_modules)
130
+
131
+ #Create an SSL site if requested
132
+ if @certificate
133
+ @config=https_config
134
+ configure_site("default-ssl")
135
+ activate_modules(@apache_https_modules)
136
+ end
137
+
138
+ # Make apache listen on the right ports
139
+ configure_ports
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+ # Brightbox - Easy Ruby Web Application Deployment
3
+ # Copyright (C) 2008, Neil Wilson, Brightbox Systems
4
+ #
5
+ # This file is part of the Brightbox deployment system
6
+ #
7
+ # Brightbox gem is free software: you can redistribute it and/or modify it
8
+ # under the terms of the GNU Affero General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License,
10
+ # or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General
18
+ # Public License along with this program. If not, see
19
+ # <http://www.gnu.org/licenses/>.
20
+ #
21
+
22
+ require 'rubygems'
23
+ require 'optparse'
24
+ require 'erb'
25
+ require 'fileutils'
26
+
27
+ @size = '100M'
28
+ @keep = '10'
29
+
30
+ OptionParser.new do |opts|
31
+ opts.banner = "brightbox-logrotate creates a logrotate config for a Rails app\n"
32
+ opts.banner << "Usage: #{$0} [options] [args]"
33
+
34
+ opts.on("-nAPPLICATION_NAME", "--name APPLICATION_NAME",
35
+ "Name of application (a short useful name for the app such as 'myforum')"
36
+ ) { |value| @application = value }
37
+ opts.on("-lLOG_DIR", "--logdir LOG_DIR",
38
+ "Full path to the directory containing the rails logs (e.g: /home/rails/myforum/current/log)"
39
+ ) { |value| @logdir = value }
40
+ opts.on("-sMAX_LOG_SIZE", "--size MAX_LOG_SIZE",
41
+ "When the current log file reaches this size, rotate it (e.g: 100M, 1G). Default: #{@size}"
42
+ ) { |value| @size = value }
43
+ opts.on("-kPERIOD_TO_KEEP", "--keep PERIOD_TO_KEEP",
44
+ "Number of previous compressed logs to keep (default: #{@keep})"
45
+ ) { |value| @keep = value }
46
+
47
+ if ARGV.empty?
48
+ puts opts
49
+ exit 1
50
+ else
51
+ opts.parse!(ARGV)
52
+ if @logdir.nil? or @application.nil?
53
+ puts "required option missing"
54
+ exit 1
55
+ end
56
+ end
57
+ end
58
+
59
+
60
+ TEMPLATE = <<EOT
61
+ # Created by brightbox-logrotate at <%= Time.now %>
62
+ <%= @logdir %>/*.log {
63
+ compress
64
+ size <%= @size %>
65
+ rotate <%= @keep %>
66
+ missingok
67
+ compress
68
+ copytruncate
69
+ }
70
+ EOT
71
+
72
+ template = ERB.new(TEMPLATE)
73
+ config = template.result
74
+ filename = "/etc/logrotate.d/rails-#{@application}"
75
+
76
+ File.open(filename, "w") { |f| f.write config }
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+ # Brightbox - Easy Ruby Web Application Deployment
3
+ # Copyright (C) 2008, Neil Wilson, Brightbox Systems
4
+ #
5
+ # This file is part of the Brightbox deployment system
6
+ #
7
+ # Brightbox gem is free software: you can redistribute it and/or modify it
8
+ # under the terms of the GNU Affero General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License,
10
+ # or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General
18
+ # Public License along with this program. If not, see
19
+ # <http://www.gnu.org/licenses/>.
20
+ #
21
+
22
+ require 'rubygems'
23
+ require 'optparse'
24
+ require 'fileutils'
25
+ require 'erb'
26
+
27
+ @mongrelhost = "127.0.0.1"
28
+ @mongrels = 2
29
+ @railsenv = "production"
30
+ @pidfile = "log/mongrel.pid"
31
+
32
+ def has_required_options?
33
+ [@application, @config, @pidfile, @port, @mongrels, @railsenv, @railsroot, @mongrelhost].all?
34
+ end
35
+
36
+ OptionParser.new do |opts|
37
+ opts.banner = "brightbox-mongrel creates a Mongrel config for a Rails app\n"
38
+ opts.banner << "Usage: #{$0} [options] [args]"
39
+
40
+ opts.on("-n", "--name APPLICATION_NAME",
41
+ "Name of application (a short useful name for the app such as: myforum)"
42
+ ) { |value| @application = value }
43
+ opts.on("-r", "--railsroot RAILS_ROOT",
44
+ "Full path to rails root (e.g: /home/rails/myforum/current)"
45
+ ) { |value| @railsroot = value }
46
+ opts.on("-C", "--config MONGREL_CONFIG_FILE",
47
+ "Location of this application's mongrel config file"
48
+ ) { |value| @config = value }
49
+ opts.on("-e", "--railsenv RAILS_ENV",
50
+ "rails environment (default: #{@railsenv})"
51
+ ) { |value| @railsenv = value }
52
+ opts.on("-p", "--port MONGREL_PORT",
53
+ "Port of the first mongrel service (e.g: 9200)"
54
+ ) { |value| @port = value.to_i }
55
+ opts.on("-s", "--servers MONGRELS",
56
+ "Number of mongrel servers running (default: #{@mongrels})"
57
+ ) { |value| @mongrels = value.to_i }
58
+ opts.on("-h", "--mongrelhost MONGREL_HOST",
59
+ "IP/host where mongrel is running (default: #{@mongrelhost})"
60
+ ) { |value| @mongrelhost = value }
61
+ opts.on("-P", "--pidfile MONGREL_PID_FILE",
62
+ "Name of Mongrel PID file template (default: #{@pidfile})"
63
+ ) { |value| @pidfile = value }
64
+
65
+ begin
66
+ opts.parse(ARGV)
67
+ raise OptionParser::ParseError,
68
+ "You must supply the required arguments" unless has_required_options?
69
+ rescue OptionParser::ParseError => e
70
+ warn e.message
71
+ puts opts
72
+ exit 1
73
+ end
74
+ end
75
+
76
+ command = %Q{ mongrel_rails cluster::configure -N #{@mongrels} -p #{@port} -e #{@railsenv} -a #{@mongrelhost} -c #{@railsroot} -P "#{@pidfile}" -C "#{@config}"}
77
+ puts command
78
+ exec command
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env ruby
2
+ # Brightbox - Easy Ruby Web Application Deployment
3
+ # Copyright (C) 2008, Neil Wilson, Brightbox Systems
4
+ #
5
+ # This file is part of the Brightbox deployment system
6
+ #
7
+ # Brightbox gem is free software: you can redistribute it and/or modify it
8
+ # under the terms of the GNU Affero General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License,
10
+ # or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General
18
+ # Public License along with this program. If not, see
19
+ # <http://www.gnu.org/licenses/>.
20
+ #
21
+
22
+ require 'rubygems'
23
+ require 'optparse'
24
+ require 'fileutils'
25
+ require 'erb'
26
+
27
+ @mongrelhost = "127.0.0.1"
28
+ @mongrels = 2
29
+ @railsenv = "production"
30
+ @railsuser = "rails"
31
+ @railsgroup = "rails"
32
+ @pidfile = "log/mongrel.pid"
33
+
34
+ def has_required_options?
35
+ [@railsuser, @railsgroup, @application, @config, @pidfile, @port, @mongrels, @railsenv, @railsroot, @mongrelhost].all?
36
+ end
37
+
38
+ OptionParser.new do |opts|
39
+ opts.banner = "brightbox-monit creates a Monit config for a Rails app\n"
40
+ opts.banner << "Usage: #{$0} [options] [args]"
41
+
42
+ opts.on("-n", "--name APPLICATION_NAME",
43
+ "Name of application (a short useful name for the app such as: myforum)"
44
+ ) { |value| @application = value }
45
+ opts.on("-r", "--railsroot RAILS_ROOT",
46
+ "Full path to rails root (e.g: /home/rails/myforum/current)"
47
+ ) { |value| @railsroot = value }
48
+ opts.on("-C", "--config MONGREL_CONFIG_FILE",
49
+ "Location of this application's mongrel config file"
50
+ ) { |value| @config = value }
51
+ opts.on("-e", "--railsenv RAILS_ENV",
52
+ "rails environment (default: #{@railsenv})"
53
+ ) { |value| @railsenv = value }
54
+ opts.on("-p", "--port MONGREL_PORT",
55
+ "Port of the first mongrel service (e.g: 9200)"
56
+ ) { |value| @port = value.to_i }
57
+ opts.on("-s", "--servers MONGRELS",
58
+ "Number of mongrel servers running (default: #{@mongrels})"
59
+ ) { |value| @mongrels = value.to_i }
60
+ opts.on("-h", "--mongrelhost MONGREL_HOST",
61
+ "IP/host where mongrel is running (default: #{@mongrelhost})"
62
+ ) { |value| @mongrelhost = value }
63
+ opts.on("-u", "--user USERNAME",
64
+ "The unix username the mongrel process should be started as (default: #{@railsuser})"
65
+ ) { |value| @railsuser = value }
66
+ opts.on("-g", "--group USERNAME",
67
+ "The unix group the mongrel process should be started as (default: #{@railsgroup})"
68
+ ) { |value| @railsgroup = value }
69
+ opts.on("-P", "--pidfile MONGREL_PID_FILE",
70
+ "Name of Mongrel PID file template (default: #{@pidfile})"
71
+ ) { |value| @pidfile = value }
72
+
73
+ begin
74
+ opts.parse(ARGV)
75
+ raise OptionParser::ParseError,
76
+ "You must supply the required arguments" unless has_required_options?
77
+ rescue OptionParser::ParseError => e
78
+ warn e.message
79
+ puts opts
80
+ exit 1
81
+ end
82
+ end
83
+
84
+ def process_pid_file
85
+ @pid_file_ext = File.extname(@pidfile)
86
+ @pid_file_base = File.basename(@pidfile, @pid_file_ext)
87
+ @pid_file_dir = File.dirname(@pidfile)
88
+ end
89
+
90
+ def port_pid_file(port)
91
+ pid_file = [@pid_file_base, port].join(".") + @pid_file_ext
92
+ File.join(@pid_file_dir, pid_file)
93
+ end
94
+
95
+ def mongrel_ports
96
+ @port..(@port + @mongrels - 1)
97
+ end
98
+
99
+ process_pid_file
100
+ @mongrel_instances = mongrel_ports.collect do |port|
101
+ [port, File.join(@railsroot, port_pid_file(port))]
102
+ end
103
+
104
+ TEMPLATE = <<EOT
105
+ # Created by brightbox-monit at <%= Time.now %>
106
+ <% @mongrel_instances.each do |port, pidfile| %>
107
+ check process mongrel_<%= @application %>_<%= port %> with pidfile <%= pidfile %>
108
+ group <%= @application %>
109
+ start program = "/usr/bin/mongrel_rails cluster::start -C <%= @config %> --clean --only <%= port %>"
110
+ as uid #{@railsuser} and gid #{@railsgroup}
111
+ stop program = "/usr/bin/mongrel_rails cluster::stop -C <%= @config %> --clean --only <%= port %>"
112
+ as uid #{@railsuser} and gid #{@railsgroup}
113
+
114
+ if failed host <%= @mongrelhost %> port <%= port %> protocol http
115
+ with timeout 30 seconds
116
+ then restart
117
+
118
+ if totalmem > 110 Mb for 3 cycles then restart
119
+ if cpu > 80% for 5 cycles then restart
120
+ #if loadavg(5min) greater than 10 for 8 cycles then restart
121
+ if 20 restarts within 20 cycles then timeout
122
+ <% end %>
123
+ EOT
124
+
125
+ template = ERB.new(TEMPLATE)
126
+ config = template.result
127
+ filename = "/etc/monit/conf.d/rails-#{@application}.monitrc"
128
+ if File.exists?(filename)
129
+ FileUtils.mkdir_p("/etc/monit/archived-configs")
130
+ FileUtils.cp filename, "/etc/monit/archived-configs/rails-#{@application}.monitrc.#{Time.now.strftime('%y%m%d%H%M%S')}"
131
+ end
132
+
133
+ File.open(filename, "w") { |f| f.write config }