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.
- data/CHANGELOG.txt +8 -0
- data/History.txt +0 -0
- data/LICENSE +339 -0
- data/Manifest.txt +11 -0
- data/README.txt +123 -0
- data/Rakefile +58 -0
- data/bin/mongrel_runit +9 -0
- data/lib/mongrel_runit.rb +25 -0
- data/lib/mongrel_runit/base.rb +58 -0
- data/lib/mongrel_runit/cli.rb +60 -0
- data/lib/mongrel_runit/config.rb +184 -0
- data/lib/mongrel_runit/service.rb +253 -0
- data/lib/mongrel_runit/servicerunner.rb +91 -0
- data/lib/mongrel_runit/version.rb +9 -0
- data/test/config/mongrel_runit.yml +21 -0
- data/test/config/mongrel_runit_service.yml +12 -0
- data/test/tc_config.rb +93 -0
- data/test/tc_service.rb +153 -0
- data/test/tc_servicerunner.rb +74 -0
- data/test/test_helper.rb +2 -0
- data/test/test_mongrel_runit.rb +9 -0
- data/test/testapp/README +182 -0
- data/test/testapp/Rakefile +10 -0
- data/test/testapp/app/controllers/application.rb +7 -0
- data/test/testapp/app/helpers/application_helper.rb +3 -0
- data/test/testapp/config/boot.rb +45 -0
- data/test/testapp/config/database.yml +36 -0
- data/test/testapp/config/environment.rb +60 -0
- data/test/testapp/config/environments/development.rb +21 -0
- data/test/testapp/config/environments/production.rb +18 -0
- data/test/testapp/config/environments/test.rb +19 -0
- data/test/testapp/config/routes.rb +23 -0
- data/test/testapp/doc/README_FOR_APP +2 -0
- data/test/testapp/log/development.log +0 -0
- data/test/testapp/log/production.log +3010 -0
- data/test/testapp/log/server.log +0 -0
- data/test/testapp/log/test.log +0 -0
- data/test/testapp/public/404.html +30 -0
- data/test/testapp/public/500.html +30 -0
- data/test/testapp/public/dispatch.cgi +10 -0
- data/test/testapp/public/dispatch.fcgi +24 -0
- data/test/testapp/public/dispatch.rb +10 -0
- data/test/testapp/public/favicon.ico +0 -0
- data/test/testapp/public/images/rails.png +0 -0
- data/test/testapp/public/index.html +277 -0
- data/test/testapp/public/javascripts/application.js +2 -0
- data/test/testapp/public/javascripts/controls.js +833 -0
- data/test/testapp/public/javascripts/dragdrop.js +942 -0
- data/test/testapp/public/javascripts/effects.js +1088 -0
- data/test/testapp/public/javascripts/prototype.js +2515 -0
- data/test/testapp/public/robots.txt +1 -0
- data/test/testapp/script/about +3 -0
- data/test/testapp/script/breakpointer +3 -0
- data/test/testapp/script/console +3 -0
- data/test/testapp/script/destroy +3 -0
- data/test/testapp/script/generate +3 -0
- data/test/testapp/script/performance/benchmarker +3 -0
- data/test/testapp/script/performance/profiler +3 -0
- data/test/testapp/script/plugin +3 -0
- data/test/testapp/script/process/inspector +3 -0
- data/test/testapp/script/process/reaper +3 -0
- data/test/testapp/script/process/spawner +3 -0
- data/test/testapp/script/runner +3 -0
- data/test/testapp/script/server +3 -0
- data/test/testapp/test/test_helper.rb +28 -0
- metadata +157 -0
data/Rakefile
ADDED
@@ -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
|
+
|
data/bin/mongrel_runit
ADDED
@@ -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
|