brightbox-server-tools 2.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.
@@ -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 }