activerain-mongrel_runit 0.2.3

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.
Files changed (66) hide show
  1. data/CHANGELOG.txt +8 -0
  2. data/History.txt +0 -0
  3. data/LICENSE +339 -0
  4. data/Manifest.txt +11 -0
  5. data/README.txt +123 -0
  6. data/Rakefile +58 -0
  7. data/bin/mongrel_runit +9 -0
  8. data/lib/mongrel_runit.rb +25 -0
  9. data/lib/mongrel_runit/base.rb +58 -0
  10. data/lib/mongrel_runit/cli.rb +60 -0
  11. data/lib/mongrel_runit/config.rb +184 -0
  12. data/lib/mongrel_runit/service.rb +253 -0
  13. data/lib/mongrel_runit/servicerunner.rb +91 -0
  14. data/lib/mongrel_runit/version.rb +9 -0
  15. data/test/config/mongrel_runit.yml +21 -0
  16. data/test/config/mongrel_runit_service.yml +12 -0
  17. data/test/tc_config.rb +93 -0
  18. data/test/tc_service.rb +153 -0
  19. data/test/tc_servicerunner.rb +74 -0
  20. data/test/test_helper.rb +2 -0
  21. data/test/test_mongrel_runit.rb +9 -0
  22. data/test/testapp/README +182 -0
  23. data/test/testapp/Rakefile +10 -0
  24. data/test/testapp/app/controllers/application.rb +7 -0
  25. data/test/testapp/app/helpers/application_helper.rb +3 -0
  26. data/test/testapp/config/boot.rb +45 -0
  27. data/test/testapp/config/database.yml +36 -0
  28. data/test/testapp/config/environment.rb +60 -0
  29. data/test/testapp/config/environments/development.rb +21 -0
  30. data/test/testapp/config/environments/production.rb +18 -0
  31. data/test/testapp/config/environments/test.rb +19 -0
  32. data/test/testapp/config/routes.rb +23 -0
  33. data/test/testapp/doc/README_FOR_APP +2 -0
  34. data/test/testapp/log/development.log +0 -0
  35. data/test/testapp/log/production.log +3010 -0
  36. data/test/testapp/log/server.log +0 -0
  37. data/test/testapp/log/test.log +0 -0
  38. data/test/testapp/public/404.html +30 -0
  39. data/test/testapp/public/500.html +30 -0
  40. data/test/testapp/public/dispatch.cgi +10 -0
  41. data/test/testapp/public/dispatch.fcgi +24 -0
  42. data/test/testapp/public/dispatch.rb +10 -0
  43. data/test/testapp/public/favicon.ico +0 -0
  44. data/test/testapp/public/images/rails.png +0 -0
  45. data/test/testapp/public/index.html +277 -0
  46. data/test/testapp/public/javascripts/application.js +2 -0
  47. data/test/testapp/public/javascripts/controls.js +833 -0
  48. data/test/testapp/public/javascripts/dragdrop.js +942 -0
  49. data/test/testapp/public/javascripts/effects.js +1088 -0
  50. data/test/testapp/public/javascripts/prototype.js +2515 -0
  51. data/test/testapp/public/robots.txt +1 -0
  52. data/test/testapp/script/about +3 -0
  53. data/test/testapp/script/breakpointer +3 -0
  54. data/test/testapp/script/console +3 -0
  55. data/test/testapp/script/destroy +3 -0
  56. data/test/testapp/script/generate +3 -0
  57. data/test/testapp/script/performance/benchmarker +3 -0
  58. data/test/testapp/script/performance/profiler +3 -0
  59. data/test/testapp/script/plugin +3 -0
  60. data/test/testapp/script/process/inspector +3 -0
  61. data/test/testapp/script/process/reaper +3 -0
  62. data/test/testapp/script/process/spawner +3 -0
  63. data/test/testapp/script/runner +3 -0
  64. data/test/testapp/script/server +3 -0
  65. data/test/testapp/test/test_helper.rb +28 -0
  66. metadata +157 -0
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ require "delegate"
12
+ include FileUtils
13
+ require File.join(File.dirname(__FILE__), 'lib', 'mongrel_runit', 'version')
14
+
15
+ AUTHOR = "Adam Jacob" # can also be an array of Authors
16
+ EMAIL = "adam@hjksolutions.com"
17
+ DESCRIPTION = "Use runit to manage a mongrel cluster"
18
+ GEM_NAME = "mongrel_runit" # what ppl will type to install your gem
19
+ RUBYFORGE_PROJECT = "mongrel_runit" # The unix name for your project
20
+ HOMEPATH = "https://wiki.hjksolutions.com/display/MR/Home"
21
+
22
+ NAME = "mongrel_runit"
23
+ REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
+ VERS = ENV['VERSION'] || (MongrelRunit::VERSION::STRING + (REV ? ".#{REV}" : ""))
25
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
26
+ RDOC_OPTS = ['--quiet', '--title', "mongrel_runit documentation",
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source"]
31
+
32
+ class Hoe
33
+ def extra_deps
34
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
35
+ end
36
+ end
37
+
38
+ # Generate all the Rake tasks
39
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
40
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
41
+ p.author = AUTHOR
42
+ p.description = DESCRIPTION
43
+ p.email = EMAIL
44
+ p.summary = DESCRIPTION
45
+ p.url = HOMEPATH
46
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
47
+ p.test_globs = ["test/**/*_test.rb"]
48
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
49
+
50
+ # == Optional
51
+ #p.changes - A description of the release's latest changes.
52
+ #p.extra_deps - An array of rubygem dependencies.
53
+ p.spec_extras = {
54
+ "files" => FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a,
55
+ "executables" => [ "mongrel_runit" ],
56
+ } # - A hash of extra values to set in the gemspec.
57
+ end
58
+
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Adam Jacob on 2007-03-22.
4
+ # Copyright (c) 2007. All rights reserved.
5
+
6
+ require 'mongrel_runit/cli'
7
+
8
+ cli = MongrelRunit::CLI.new(ARGV)
9
+ cli.execute
@@ -0,0 +1,25 @@
1
+ #
2
+ # Mongrel Runit takes a yaml config file and automatically sets up a
3
+ # group of mongrels for you. It is functionally equivilant to
4
+ # mongrel_cluster, but relies on runit for the fairly complex daemon
5
+ # management tasks.
6
+ #
7
+ # Author:: Adam Jacob (<adam@hjksolutions.com>)
8
+ # Copyright:: Copyright (c) 2007 HJK Solutions, LLC
9
+ # License:: GNU General Public License version 2.1
10
+ #
11
+ # This program is free software; you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License version 2
13
+ # as published by the Free Software Foundation.
14
+ #
15
+ # This program is distributed in the hope that it will be useful,
16
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ # GNU General Public License for more details.
19
+ #
20
+ # You should have received a copy of the GNU General Public License along
21
+ # with this program; if not, write to the Free Software Foundation, Inc.,
22
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
+
24
+
25
+ Dir[File.join(File.dirname(__FILE__), 'mongrel_runit/**/*.rb')].sort.each { |lib| require lib }
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Author:: Adam Jacob (<adam@hjksolutions.com>)
4
+ # Copyright:: Copyright (c) 2007 HJK Solutions, LLC
5
+ # License:: GNU General Public License version 2
6
+ #---
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License version 2
9
+ # as published by the Free Software Foundation.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with this program; if not, write to the Free Software Foundation, Inc.,
18
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ #+++
20
+
21
+
22
+ module MongrelRunit
23
+
24
+ # A simple base class, that defines a list of allowed commands.
25
+ class Base
26
+ ALLOWEDCOMMANDS = [
27
+ "up",
28
+ "down",
29
+ "status",
30
+ "once",
31
+ "pause",
32
+ "cont",
33
+ "hup",
34
+ "alarm",
35
+ "interrupt",
36
+ "1",
37
+ "2",
38
+ "term",
39
+ "kill",
40
+ "exit",
41
+ "start",
42
+ "stop",
43
+ "restart",
44
+ "shut-down",
45
+ "force-stop",
46
+ "force-reload",
47
+ "force-restart",
48
+ "force-shutdown",
49
+ ]
50
+
51
+ # Returns a given command if it's found in the allowed commands
52
+ # list.
53
+ def has_command?(command)
54
+ ALLOWEDCOMMANDS.detect { |cmd| cmd == command }
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Author:: Adam Jacob (<adam@hjksolutions.com>)
4
+ # Copyright:: Copyright (c) 2007 HJK Solutions, LLC
5
+ # License:: GNU General Public License version 2
6
+ #
7
+ #--
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License version 2
10
+ # as published by the Free Software Foundation.
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
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with this program; if not, write to the Free Software Foundation, Inc.,
19
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ #++
21
+
22
+ require 'optparse'
23
+ require 'mongrel_runit/servicerunner'
24
+ require 'mongrel_runit/config'
25
+ require 'yaml'
26
+
27
+ module MongrelRunit
28
+
29
+ # The command line interface.
30
+ #
31
+ # Example:
32
+ #
33
+ # cli = MongrelRunit::CLI.new(ARGV)
34
+ # cli.execute
35
+ #
36
+
37
+ class CLI
38
+
39
+ # Takes a list of command line arguments, passing them to
40
+ # MongrelRunit::Config and MongrelRunit::ServiceRunner.
41
+ def initialize(args)
42
+ @config = MongrelRunit::Config.load_args(args)
43
+ @servicerunner = MongrelRunit::ServiceRunner.new(@config.config)
44
+ end
45
+
46
+ # Executes the command (start/stop/restart; see MongrelRunit::Base for the
47
+ # list) specified by the arguments passed to MongrelRunit::CLI. The
48
+ # command is executed by calling MongrelRunit::ServiceRunner.run.
49
+ def execute
50
+ response, status = @servicerunner.run(@config.command)
51
+ if @config.verbose || status == false
52
+ response.sort.each do |key, value|
53
+ puts "#{key}: #{value[1]}: #{value[0]}"
54
+ end
55
+ end
56
+ exit 1 if status == false
57
+ exit 0 if status == true
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,184 @@
1
+ # Author:: Adam Jacob (<adam@hjksolutions.com>)
2
+ # Copyright:: Copyright (c) 2007 HJK Solutions, LLC
3
+ # License:: GNU General Public License version 2
4
+ #---
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License version 2
7
+ # as published by the Free Software Foundation.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along
15
+ # with this program; if not, write to the Free Software Foundation, Inc.,
16
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
+ #+++
18
+
19
+ require 'yaml'
20
+ require 'optparse'
21
+ require 'mongrel_runit/base'
22
+
23
+ module MongrelRunit
24
+
25
+ # Takes a YAML config file and a list of command line arguments, and
26
+ # populates itself with the resulting combined configuration.
27
+ #
28
+ # Example:
29
+ #
30
+ # config = MongrelRunit::Config('monkey', '/etc/sv/monkey.yml', ARGV)
31
+ # puts config["application_name"] # monkey
32
+ #
33
+ class Config < Base
34
+ attr_accessor :config, :command, :verbose
35
+
36
+ # Takes an application name, a YAML file, and command line arguments
37
+ # and spits out a working configuration. The YAML file and arguments
38
+ # can optionally be nil.
39
+ #
40
+ # Unless otherwise specified, the following default values are
41
+ # set:
42
+ #
43
+ # environment: ENV["RAILS_ENV"] or development
44
+ # port: 3000
45
+ # servers: 2
46
+ # runit_svdir: /etc/sv
47
+ # runit_service_dir: /var/service
48
+ def initialize(appname, yamlfile, args)
49
+ @config = Hash.new
50
+ load_args(args) if args
51
+ load_yaml(yamlfile) if yamlfile
52
+ @config["environment"] ||= ENV["RAILS_ENV"] || 'development'
53
+ @config["port"] ||= "3000"
54
+ @config["servers"] ||= 2
55
+ @config["application_name"] ||= appname
56
+ @config["runit_svdir"] ||= '/etc/sv'
57
+ @config["runit_service_dir"] ||= '/var/service'
58
+ @config["address"] ||= '127.0.0.1'
59
+
60
+ raise ArgumentError, "Must supply an application_name!" unless @config["application_name"]
61
+
62
+ end
63
+
64
+ # Returns the value from the config hash.
65
+ def [](arg)
66
+ @config[arg]
67
+ end
68
+
69
+ # Load options from a config file alone
70
+ def Config.load_file(yamlfile)
71
+ MongrelRunit::Config.new(nil, yamlfile, nil)
72
+ end
73
+
74
+ # Load options from command line arguments alone
75
+ def Config.load_args(*args)
76
+ MongrelRunit::Config.new(nil, nil, *args)
77
+ end
78
+
79
+ private
80
+
81
+ def load_yaml(yamlfile)
82
+ @config = YAML.load_file(File.expand_path(yamlfile))
83
+ end
84
+
85
+ def load_from_path(path)
86
+ path.strip!
87
+ epath = File.expand_path(path)
88
+ @path = epath
89
+ mr_conf = File.expand_path(File.join(epath, "config", "mongrel_runit.yml"))
90
+ mc_conf = File.expand_path(File.join(epath, "config", "mongrel_cluster.yml"))
91
+ if File.file?(mr_conf)
92
+ load_yaml(mr_conf)
93
+ elsif File.file?(mc_conf)
94
+ load_yaml(mc_conf)
95
+ else
96
+ puts "#{path} must have a ./config/mongrel_runit.yml or ./config/mongrel_cluster.yml"
97
+ return nil
98
+ end
99
+ return true
100
+ end
101
+
102
+ def load_args(args)
103
+
104
+ loaded_config = nil
105
+
106
+ opts = OptionParser.new do |opts|
107
+ opts.banner = "Usage: #{$0} (options) (#{ALLOWEDCOMMANDS.join('|')})"
108
+
109
+ opts.on("-p PATH", "--path PATH", "Path to a Rails app to start") do |p|
110
+ loaded_config = load_from_path(p)
111
+ end
112
+
113
+ opts.on("-a NAME", "--application NAME", "The name of your Application. (Used for the service directories)") do |a|
114
+ @config["application_name"] = a
115
+ end
116
+
117
+ opts.on("-c FILE", "--config FILE", "A mongrel_runit.yml config file") do |c|
118
+ c.strip!
119
+ file = File.expand_path(c)
120
+ if File.file?(file)
121
+ load_yaml(file)
122
+ loaded_config = true
123
+ else
124
+ puts "I could not find config file: #{file}"
125
+ exit 1
126
+ end
127
+ end
128
+
129
+ opts.on_tail("-v", "--verbose", "Be verbose") do
130
+ @verbose = true
131
+ end
132
+
133
+ opts.on_tail("-h", "--help", "Show this message") do
134
+ puts opts
135
+ exit
136
+ end
137
+ end
138
+ opts.parse!(args)
139
+
140
+ unless loaded_config
141
+ path = Dir.getwd
142
+ loaded_config = load_from_path(path)
143
+ end
144
+
145
+ if loaded_config && ! @config["application_name"]
146
+ if @path
147
+ appname = File.basename(@path)
148
+ @config["application_name"] = appname
149
+ else
150
+ puts "You need application_name defined in your config!"
151
+ YAML.dump @config
152
+ exit 1
153
+ end
154
+ end
155
+
156
+ unless loaded_config
157
+ puts "Configuration Dump:\n\n"
158
+ puts YAML.dump(@config)
159
+ puts "I could not find a way to configure myself properly!\n"
160
+ puts opts.help
161
+ exit 1
162
+ end
163
+
164
+ if args.length > 1
165
+ puts "You specified more command line arguments than I can handle:"
166
+ puts args.join(" ")
167
+ puts opts.help
168
+ exit 1
169
+ end
170
+
171
+ if self.has_command?(args[0]) || args[0] == "create"
172
+ @command = args[0]
173
+ else
174
+ if args[0]
175
+ puts "#{args[0]} is not an allowed command"
176
+ else
177
+ puts "You must provide a command!"
178
+ end
179
+ puts opts.help
180
+ exit 1
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,253 @@
1
+ # Created by Adam Jacob on 2007-03-21.
2
+ # Copyright (c) 2007. All rights reserved.
3
+
4
+ require 'mongrel_runit/base'
5
+
6
+ module MongrelRunit
7
+
8
+ # Represents a runit service directory for a particular mongrel.
9
+ #
10
+ # Example:
11
+ #
12
+ # service = MongrelRunit::Service.new(config)
13
+ # service.stop
14
+ # service.start
15
+ # service.create
16
+ #
17
+
18
+ class Service < Base
19
+ attr_reader :runfile, :logrunfile, :logconfig, :checkfile, :svdir, :config
20
+
21
+ # Takes a configuration hash as it's argument, ensures the
22
+ # runit_service_dir exists, and creates the runit_sv_dir.
23
+ def initialize(config)
24
+ @config = config
25
+
26
+ raise ArgumentError, "Must have an application_name!" unless @config.has_key?("application_name")
27
+ raise ArgumentError, "Must have a port!" unless @config.has_key?("port")
28
+ raise ArgumentError, "Must have a runit_sv_dir!" unless @config.has_key?("runit_sv_dir")
29
+ raise ArgumentError, "Must have a runit_service_dir!" unless @config.has_key?("runit_service_dir")
30
+
31
+ check_service_dir
32
+ make_sv_dir
33
+ end
34
+
35
+ # Catch-all for the common service commands. See MongrelRunit::Base for
36
+ # a list.
37
+ def method_missing(status)
38
+ if self.has_command?(status.id2name)
39
+ run(status.id2name)
40
+ else
41
+ Kernel.method_missing
42
+ end
43
+ end
44
+
45
+ # Returns true if the process is running, nil if it's not.
46
+ def is_running?
47
+ output, success = run("status")
48
+ output =~ /^run:/ ? true : nil
49
+ end
50
+
51
+ # Run a given command through sv.
52
+ def run(status)
53
+ cmd = "sv "
54
+ cmd += " -w #{@config['svwait']}" if @config.has_key?('svwait')
55
+ cmd += " #{status} #{@svdir}"
56
+ output = `#{cmd}`
57
+ return output, $?.success?
58
+ end
59
+
60
+ # Create the service directory for this mongrel. This includes the
61
+ # run script, log script, check script, and log config file. This
62
+ # should run any time there is a change to the configruation.
63
+ def create
64
+ make_run
65
+ make_check
66
+ make_log
67
+ make_log_config
68
+ link = make_service_link
69
+ return link, true
70
+ end
71
+
72
+ # Raises an exception if the runit_service_dir does not exist.
73
+ def check_service_dir
74
+ dir_exists = File.directory?(@config["runit_service_dir"])
75
+ raise ArgumentError, "runit_service_dir does not exist: #{@config["runit_service_dir"]}" unless dir_exists
76
+ dir_exists
77
+ end
78
+
79
+ # Creates the symlink between the mongrel's sv directory and the
80
+ # runit_service_dir.
81
+ def make_service_link
82
+ servicename = File.basename(@svdir)
83
+ link = File.expand_path(File.join(@config["runit_service_dir"], servicename))
84
+ unless File.symlink?(link)
85
+ `ln -s #{@svdir} #{@config["runit_service_dir"]}`
86
+ end
87
+ link
88
+ end
89
+
90
+ # Populates the check file, either with the contents of the checkfile
91
+ # configuration option, or:
92
+ #
93
+ # #!/usr/bin/env ruby
94
+ #
95
+ # require 'net/http'
96
+ #
97
+ # http = Net::HTTP.new('#{address}', #{@config["port"].to_i})
98
+ # begin
99
+ # response = http.options('/')
100
+ # if [Net::HTTPSuccess, Net::HTTPRedirection].any? {|klass| response = klass}
101
+ # exit 0
102
+ # else
103
+ # exit 1
104
+ # end
105
+ # rescue Errno::ECONNREFUSED
106
+ # exit 1
107
+ # end
108
+ def make_check
109
+ if @config.has_key?("checkfile")
110
+ @checkfile = interpret_line(@config["checkfile"])
111
+ else
112
+ @checkfile = <<EOH
113
+ #!/usr/bin/env ruby
114
+
115
+ require 'net/http'
116
+
117
+ http = Net::HTTP.new('#{@config['address']}', #{@config["port"].to_i})
118
+ begin
119
+ response = http.options('/')
120
+ if [Net::HTTPSuccess, Net::HTTPRedirection].any? {|klass| response = klass}
121
+ exit 0
122
+ else
123
+ exit 1
124
+ end
125
+ rescue Errno::ECONNREFUSED
126
+ exit 1
127
+ end
128
+ EOH
129
+ end
130
+ path_to_checkfile = File.expand_path(File.join(@svdir, "check"))
131
+ create_or_update_file(path_to_checkfile, @checkfile)
132
+ File.chmod(0755, path_to_checkfile)
133
+ path_to_checkfile
134
+ end
135
+
136
+ # Creates the sv direrectory for this mongrel. (From runit_sv_dir)
137
+ def make_sv_dir
138
+ @svdir = File.expand_path(File.join(
139
+ @config["runit_sv_dir"],
140
+ "mongrel-#{@config["application_name"]}-#{@config["port"]}"
141
+ ))
142
+ @svlogdir = File.expand_path(File.join(
143
+ @svdir, "log"
144
+ ))
145
+ `mkdir -p #{@svlogdir}`
146
+ raise "Cannot create #{@svlogdir}" unless $?.success?
147
+ @svlogdir
148
+ end
149
+
150
+ # If svlogd_config is defined, creates the log config file.
151
+ def make_log_config
152
+ path_to_file = nil
153
+ if @config.has_key?("svlogd_config")
154
+ path_to_file = File.expand_path(File.join(@svlogdir, "config"))
155
+ @logconfig = @config["svlogd_config"]
156
+ create_or_update_file(path_to_file, @logconfig)
157
+ end
158
+ path_to_file
159
+ end
160
+
161
+ # Makes the log run script.
162
+ def make_log
163
+ logdir = File.expand_path(File.join(@svlogdir, "main"))
164
+ if @config.has_key?("base_log_directory")
165
+ logdir = File.expand_path(File.join(
166
+ @config["base_log_directory"],
167
+ "#{@config[application_name]}-#{@config[port]}"
168
+ ))
169
+ end
170
+ `mkdir -p #{logdir}`
171
+ raise "Cannot create #{logdir}" unless $?.success?
172
+ @logrunfile = "#!/bin/sh\n"
173
+ @logrunfile << "exec svlogd -tt #{logdir}"
174
+ path_to_logrunfile = File.expand_path(File.join(@svlogdir, "run"))
175
+ create_or_update_file(path_to_logrunfile, @logrunfile)
176
+ File.chmod(0755, path_to_logrunfile)
177
+ path_to_logrunfile
178
+ end
179
+
180
+ # Makes the run script, which calls mongrel directly. The command
181
+ # line assembly code for mongrel_rails is taken verbatim from mongrel_cluster.
182
+ def make_run
183
+ cmd = if @config["command_line"]
184
+ interpret_line(@config["command_line"])
185
+ else
186
+ argv = [ "mongrel_rails" ]
187
+ argv << "start"
188
+ argv << "-e #{@config["environment"]}" if @config["environment"]
189
+ argv << "-p #{@config["port"]}"
190
+ argv << "-a #{@config["address"]}" if @config["address"]
191
+ argv << "-l #{@config["log_file"]}" if @config["log_file"]
192
+ argv << "-c #{File.expand_path(@config["cwd"])}" if @config["cwd"]
193
+ argv << "-t #{@config["timeout"]}" if @config["timeout"]
194
+ argv << "-m #{@config["mime_map"]}" if @config["mime_map"]
195
+ argv << "-r #{@config["docroot"]}" if @config["docroot"]
196
+ argv << "-n #{@config["num_procs"]}" if @config["num_procs"]
197
+ argv << "-B" if @config["debug"]
198
+ argv << "-S #{@config["config_script"]}" if @config["config_script"]
199
+ argv << "--user #{@config["user"]}" if @config["user"]
200
+ argv << "--group #{@config["group"]}" if @config["group"]
201
+ argv << "--prefix #{@config["prefix"]}" if @config["prefix"]
202
+ argv.join(" ")
203
+ end
204
+ env = nil
205
+ if @config.has_key?("env_vars")
206
+ env = "env"
207
+ @config["env_vars"].each do |key, value|
208
+ env << " #{key.upcase}=#{value}"
209
+ end
210
+ end
211
+ chpst = nil
212
+ if @config.has_key?("chpst")
213
+ chpst_command = `which chpst`.chomp
214
+ chpst = "#{chpst_command} #{@config['chpst']}"
215
+ end
216
+ @runfile = "#!/bin/sh\n"
217
+ @runfile << "exec \\\n"
218
+ @runfile << " #{env} \\\n" if env
219
+ @runfile << " #{chpst} \\\n" if chpst
220
+ @runfile << " #{cmd} 2>&1\n"
221
+
222
+ path_to_runfile = File.expand_path(File.join(@svdir, "run"))
223
+ create_or_update_file(path_to_runfile, @runfile)
224
+ File.chmod(0755, path_to_runfile)
225
+ path_to_runfile
226
+ end
227
+
228
+ private
229
+
230
+ def interpret_line(cmd)
231
+ begin
232
+ eval("\"#{cmd}\"")
233
+ rescue SyntaxError
234
+ puts "You have a syntax error in your string; perhaps you included a double quote without escaping it?"
235
+ raise
236
+ end
237
+ end
238
+
239
+ def create_or_update_file(file, new_contents)
240
+ write = 1
241
+ if File.file?(file)
242
+ current_contents = IO.read(file)
243
+ if current_contents == new_contents
244
+ write = nil
245
+ end
246
+ end
247
+
248
+ File.open(file, "w") do |file|
249
+ file.print(new_contents)
250
+ end if write
251
+ end
252
+ end
253
+ end