mongrel2 0.53.0 → 0.54.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +56 -2
- data/History.rdoc +7 -0
- data/Manifest.txt +17 -0
- data/Rakefile +21 -18
- data/bin/m2sh.rb +3 -738
- data/gem.deps.rb +2 -0
- data/lib/mongrel2.rb +1 -1
- data/lib/mongrel2/cli.rb +496 -0
- data/lib/mongrel2/cli/access.rb +29 -0
- data/lib/mongrel2/cli/bootstrap.rb +39 -0
- data/lib/mongrel2/cli/commit.rb +34 -0
- data/lib/mongrel2/cli/hosts.rb +51 -0
- data/lib/mongrel2/cli/init.rb +29 -0
- data/lib/mongrel2/cli/load.rb +41 -0
- data/lib/mongrel2/cli/log.rb +27 -0
- data/lib/mongrel2/cli/quickstart.rb +52 -0
- data/lib/mongrel2/cli/reload.rb +33 -0
- data/lib/mongrel2/cli/routes.rb +51 -0
- data/lib/mongrel2/cli/running.rb +44 -0
- data/lib/mongrel2/cli/servers.rb +34 -0
- data/lib/mongrel2/cli/settings.rb +26 -0
- data/lib/mongrel2/cli/start.rb +72 -0
- data/lib/mongrel2/cli/stop.rb +33 -0
- data/lib/mongrel2/config.rb +1 -0
- data/lib/mongrel2/config/directory.rb +11 -0
- data/lib/mongrel2/config/dsl.rb +13 -20
- data/lib/mongrel2/config/handler.rb +12 -0
- data/lib/mongrel2/config/host.rb +1 -1
- data/lib/mongrel2/config/proxy.rb +6 -0
- data/lib/mongrel2/config/server.rb +3 -2
- data/spec/mongrel2/config/dsl_spec.rb +6 -0
- metadata +73 -14
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '078af1a5d9ded05f97bdc0f0ffb9491480ee1102372e454ffbd3af91326f2206'
|
4
|
+
data.tar.gz: 8203090de25b79b5cbee3a8d57c64f4b3d9336e4bb5ab3739008d53c5a217e26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50e7fff95804311a9f1aae03916b5b6d2a0910ce440696b006c942783b0be2d6cd1bd32ac5546e57ec5a2023529b69ef636b866e8f84c91cff2f69edbad8f046
|
7
|
+
data.tar.gz: 8d3c22401d5ea408ae3415bf5c8af8512d5bf58418c46fb8497d9aadba4aa33967ab06aca29b8f43151c8e39afe52731caf0ab92c9c828196f75a792d92273a6
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/ChangeLog
CHANGED
@@ -1,9 +1,63 @@
|
|
1
|
+
2019-09-04 Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
@ * lib/mongrel2/cli/_.rb:
|
4
|
+
| Remove the temporary command template
|
5
|
+
| [a45595593fe9] [tip]
|
6
|
+
|
|
7
|
+
o * .hgignore, Gemfile, Rakefile, gem.deps.rb, mongrel2.gemspec:
|
8
|
+
| Move deps to Rubygems style
|
9
|
+
| [3394aa0fb6d7]
|
10
|
+
|
|
11
|
+
2019-08-30 Michael Granger <ged@FaerieMUD.org>
|
12
|
+
|
13
|
+
o * bin/m2sh.rb:
|
14
|
+
| Convert the `version` command
|
15
|
+
| [f0e8cc815f35]
|
16
|
+
|
|
17
|
+
o * bin/m2sh.rb, lib/mongrel2/cli/settings.rb:
|
18
|
+
| Add the `settings` command
|
19
|
+
| [3318e96c026c]
|
20
|
+
|
|
21
|
+
o * .gems, bin/m2sh.rb, example.rb, lib/mongrel2/cli.rb,
|
22
|
+
| lib/mongrel2/cli/_.rb, lib/mongrel2/cli/access.rb,
|
23
|
+
| lib/mongrel2/cli/bootstrap.rb, lib/mongrel2/cli/commit.rb,
|
24
|
+
| lib/mongrel2/cli/hosts.rb, lib/mongrel2/cli/init.rb,
|
25
|
+
| lib/mongrel2/cli/load.rb, lib/mongrel2/cli/log.rb,
|
26
|
+
| lib/mongrel2/cli/quickstart.rb, lib/mongrel2/cli/reload.rb,
|
27
|
+
| lib/mongrel2/cli/routes.rb, lib/mongrel2/cli/running.rb,
|
28
|
+
| lib/mongrel2/cli/servers.rb, lib/mongrel2/cli/start.rb,
|
29
|
+
| lib/mongrel2/cli/stop.rb, lib/mongrel2/config/directory.rb,
|
30
|
+
| lib/mongrel2/config/handler.rb, lib/mongrel2/config/proxy.rb,
|
31
|
+
| mongrel2.gemspec:
|
32
|
+
| Convert a bunch more commands to GLI
|
33
|
+
| [a3e36d56b290]
|
34
|
+
|
|
35
|
+
2019-08-14 Michael Granger <ged@FaerieMUD.org>
|
36
|
+
|
37
|
+
o * certs/ged.pem:
|
38
|
+
| Update my gem-signing cert
|
39
|
+
| [3ace11b97f05]
|
40
|
+
|
|
41
|
+
o * lib/mongrel2/config.rb, lib/mongrel2/config/dsl.rb,
|
42
|
+
| lib/mongrel2/config/host.rb, lib/mongrel2/config/server.rb,
|
43
|
+
| spec/mongrel2/config/dsl_spec.rb:
|
44
|
+
| Fixed create vs. re-create in config DSL
|
45
|
+
| [62a155659470]
|
46
|
+
|
|
1
47
|
2019-06-26 Michael Granger <ged@FaerieMUD.org>
|
2
48
|
|
3
|
-
|
49
|
+
o * .hgtags:
|
50
|
+
| Added tag v0.53.0 for changeset 9a0ef111c743
|
51
|
+
| [f2fa2ed85e26]
|
52
|
+
|
|
53
|
+
o * .hgsigs:
|
54
|
+
| Added signature for changeset cfedd3805c13
|
55
|
+
| [9a0ef111c743] [v0.53.0]
|
56
|
+
|
|
57
|
+
o * History.rdoc, Rakefile, lib/mongrel2.rb:
|
4
58
|
| Bump the minor version, update history, bump minimum Ruby version to
|
5
59
|
| 2.4.x
|
6
|
-
| [cfedd3805c13]
|
60
|
+
| [cfedd3805c13]
|
7
61
|
|
|
8
62
|
o * Manifest.txt, lib/mongrel2/table.rb, lib/mongrel2/testing.rb,
|
9
63
|
| spec/mongrel2/testing_spec.rb:
|
data/History.rdoc
CHANGED
data/Manifest.txt
CHANGED
@@ -11,7 +11,24 @@ bin/m2sh.rb
|
|
11
11
|
data/mongrel2/config.rb.in
|
12
12
|
data/mongrel2/config.sql
|
13
13
|
data/mongrel2/mimetypes.sql
|
14
|
+
gem.deps.rb
|
14
15
|
lib/mongrel2.rb
|
16
|
+
lib/mongrel2/cli.rb
|
17
|
+
lib/mongrel2/cli/access.rb
|
18
|
+
lib/mongrel2/cli/bootstrap.rb
|
19
|
+
lib/mongrel2/cli/commit.rb
|
20
|
+
lib/mongrel2/cli/hosts.rb
|
21
|
+
lib/mongrel2/cli/init.rb
|
22
|
+
lib/mongrel2/cli/load.rb
|
23
|
+
lib/mongrel2/cli/log.rb
|
24
|
+
lib/mongrel2/cli/quickstart.rb
|
25
|
+
lib/mongrel2/cli/reload.rb
|
26
|
+
lib/mongrel2/cli/routes.rb
|
27
|
+
lib/mongrel2/cli/running.rb
|
28
|
+
lib/mongrel2/cli/servers.rb
|
29
|
+
lib/mongrel2/cli/settings.rb
|
30
|
+
lib/mongrel2/cli/start.rb
|
31
|
+
lib/mongrel2/cli/stop.rb
|
15
32
|
lib/mongrel2/config.rb
|
16
33
|
lib/mongrel2/config/directory.rb
|
17
34
|
lib/mongrel2/config/dsl.rb
|
data/Rakefile
CHANGED
@@ -25,24 +25,27 @@ hoespec = Hoe.spec 'mongrel2' do
|
|
25
25
|
|
26
26
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
27
27
|
|
28
|
-
self.dependency 'cztop',
|
29
|
-
self.dependency 'cztop-reactor',
|
30
|
-
self.dependency '
|
31
|
-
self.dependency '
|
32
|
-
self.dependency '
|
33
|
-
self.dependency '
|
34
|
-
self.dependency '
|
35
|
-
self.dependency '
|
36
|
-
self.dependency '
|
37
|
-
self.dependency '
|
38
|
-
|
39
|
-
self.dependency '
|
40
|
-
self.dependency '
|
41
|
-
|
42
|
-
self.dependency '
|
43
|
-
self.dependency '
|
44
|
-
|
45
|
-
self.
|
28
|
+
self.dependency 'cztop', '~> 0.11'
|
29
|
+
self.dependency 'cztop-reactor', '~> 0.6'
|
30
|
+
self.dependency 'gli', '~> 2.19'
|
31
|
+
self.dependency 'libxml-ruby', '~> 3.1'
|
32
|
+
self.dependency 'loggability', '~> 0.14'
|
33
|
+
self.dependency 'pastel', '~> 0.7'
|
34
|
+
self.dependency 'sequel', '~> 5.2'
|
35
|
+
self.dependency 'sqlite3', '~> 1.3'
|
36
|
+
self.dependency 'sysexits', '~> 1.1'
|
37
|
+
self.dependency 'tnetstring', '~> 0.3'
|
38
|
+
self.dependency 'tty-prompt', '~> 0.19'
|
39
|
+
self.dependency 'tty-table', '~> 0.11'
|
40
|
+
self.dependency 'yajl-ruby', '~> 1.4'
|
41
|
+
|
42
|
+
self.dependency 'amalgalite', '~> 1.5', :developer
|
43
|
+
self.dependency 'configurability', '~> 3.4', :developer
|
44
|
+
self.dependency 'hoe-deveiate', '~> 0.10', :developer
|
45
|
+
self.dependency 'simplecov', '~> 0.12', :developer
|
46
|
+
self.dependency 'rdoc-generator-fivefish', '~> 0', :developer
|
47
|
+
|
48
|
+
self.require_ruby_version( '>=2.5.0' )
|
46
49
|
self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
|
47
50
|
self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
|
48
51
|
self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
|
data/bin/m2sh.rb
CHANGED
@@ -1,744 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'uri'
|
4
|
-
require 'pathname'
|
5
|
-
require 'fileutils'
|
6
|
-
require 'tnetstring'
|
7
3
|
require 'loggability'
|
8
|
-
|
4
|
+
Loggability.level = :fatal
|
9
5
|
|
10
|
-
require '
|
11
|
-
|
6
|
+
require 'mongrel2/cli'
|
7
|
+
exit Mongrel2::CLI.run( ARGV )
|
12
8
|
|
13
|
-
# Have to do it this way to avoid the vendored 'sysexits' under OSX.
|
14
|
-
gem 'sysexits'
|
15
|
-
require 'sysexits'
|
16
|
-
|
17
|
-
require 'mongrel2'
|
18
|
-
require 'mongrel2/config'
|
19
|
-
|
20
|
-
|
21
|
-
# A tool for interacting with a Mongrel2 config database and server. This isn't
|
22
|
-
# quite a replacement for the real m2sh yet; here's what I have working so far:
|
23
|
-
#
|
24
|
-
# [√] load Load a config.
|
25
|
-
# [√] config Alias for load.
|
26
|
-
# [-] shell Starts an interactive shell.
|
27
|
-
# [√] access Prints the access log.
|
28
|
-
# [√] servers Lists the servers in a config database.
|
29
|
-
# [√] hosts Lists the hosts in a server.
|
30
|
-
# [√] routes Lists the routes in a host.
|
31
|
-
# [√] commit Adds a message to the log.
|
32
|
-
# [√] log Prints the commit log.
|
33
|
-
# [√] start Starts a server.
|
34
|
-
# [√] stop Stops a server.
|
35
|
-
# [√] reload Reloads a server.
|
36
|
-
# [√] running Tells you what's running.
|
37
|
-
# [-] control Connects to the control port.
|
38
|
-
# [√] version Prints the Mongrel2 and m2sh version.
|
39
|
-
# [√] help Get help, lists commands.
|
40
|
-
# [-] uuid Prints out a randomly generated UUID.
|
41
|
-
#
|
42
|
-
# I just use 'uuidgen' to generate uuids (which is all m2sh does, as
|
43
|
-
# well), so I don't plan to implement that. The 'control' command is more-easily
|
44
|
-
# accessed via pry+Mongrel2::Control, so I'm not going to implement that, either.
|
45
|
-
# Everything else should be analagous to (or better than) the m2sh that comes with
|
46
|
-
# mongrel2. I implemented the 'shell' mode, but I found I never used it, and it
|
47
|
-
# introduced a dependency on the Termios library, so I removed it.
|
48
|
-
#
|
49
|
-
class Mongrel2::M2SHCommand
|
50
|
-
extend ::Sysexits,
|
51
|
-
Loggability
|
52
|
-
include Sysexits,
|
53
|
-
Mongrel2::Constants
|
54
|
-
|
55
|
-
# Loggability API -- set up logging under the 'strelka' log host
|
56
|
-
log_to :mongrel2
|
57
|
-
|
58
|
-
|
59
|
-
# Make a HighLine color scheme
|
60
|
-
COLOR_SCHEME = HighLine::ColorScheme.new do |scheme|
|
61
|
-
scheme[:header] = [ :bold, :yellow ]
|
62
|
-
scheme[:subheader] = [ :bold, :white ]
|
63
|
-
scheme[:key] = [ :white ]
|
64
|
-
scheme[:value] = [ :bold, :white ]
|
65
|
-
scheme[:error] = [ :red ]
|
66
|
-
scheme[:warning] = [ :yellow ]
|
67
|
-
scheme[:message] = [ :reset ]
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
|
-
# Number of items to store in history by default
|
72
|
-
DEFAULT_HISTORY_SIZE = 100
|
73
|
-
|
74
|
-
|
75
|
-
# Class instance variables
|
76
|
-
@command_help = Hash.new {|h,k| h[k] = { :desc => nil, :usage => ''} }
|
77
|
-
@prompt = @option_parser = nil
|
78
|
-
|
79
|
-
|
80
|
-
### Add a help string for the given +command+.
|
81
|
-
def self::help( command, helpstring=nil )
|
82
|
-
if helpstring
|
83
|
-
@command_help[ command.to_sym ][:desc] = helpstring
|
84
|
-
end
|
85
|
-
|
86
|
-
return @command_help[ command.to_sym ][:desc]
|
87
|
-
end
|
88
|
-
|
89
|
-
|
90
|
-
### Add/fetch the +usagestring+ for +command+.
|
91
|
-
def self::usage( command, usagestring=nil )
|
92
|
-
if usagestring
|
93
|
-
prefix = usagestring[ /\A(\s+)/, 1 ]
|
94
|
-
usagestring.gsub!( /^#{prefix}/m, '' ) if prefix
|
95
|
-
|
96
|
-
@command_help[ command.to_sym ][:usage] = usagestring
|
97
|
-
end
|
98
|
-
|
99
|
-
return @command_help[ command.to_sym ][:usage]
|
100
|
-
end
|
101
|
-
|
102
|
-
|
103
|
-
### Return the global Highline prompt object, creating it if necessary.
|
104
|
-
def self::prompt
|
105
|
-
unless @prompt
|
106
|
-
@prompt = HighLine.new
|
107
|
-
# @prompt.wrap_at = @prompt.output_cols - 3
|
108
|
-
end
|
109
|
-
|
110
|
-
return @prompt
|
111
|
-
end
|
112
|
-
|
113
|
-
|
114
|
-
### Run the utility with the given +args+.
|
115
|
-
def self::run( args )
|
116
|
-
HighLine.color_scheme = COLOR_SCHEME
|
117
|
-
|
118
|
-
oparser = self.make_option_parser
|
119
|
-
opts = Trollop.with_standard_exception_handling( oparser ) do
|
120
|
-
oparser.parse( args )
|
121
|
-
end
|
122
|
-
|
123
|
-
command = oparser.leftovers.shift
|
124
|
-
self.new( opts ).run( command, *oparser.leftovers )
|
125
|
-
exit :ok
|
126
|
-
|
127
|
-
rescue => err
|
128
|
-
self.log.fatal "Oops: %s: %s" % [ err.class.name, err.message ]
|
129
|
-
self.log.debug { ' ' + err.backtrace.join("\n ") }
|
130
|
-
|
131
|
-
exit :software_error
|
132
|
-
end
|
133
|
-
|
134
|
-
|
135
|
-
### Return a String that describes the available commands, e.g., for the 'help'
|
136
|
-
### command.
|
137
|
-
def self::make_command_table
|
138
|
-
commands = self.available_commands
|
139
|
-
|
140
|
-
# Build the command table
|
141
|
-
col1len = commands.map( &:length ).max
|
142
|
-
return commands.collect do |cmd|
|
143
|
-
helptext = self.help( cmd.to_sym ) or next # no help == invisible command
|
144
|
-
"%s %s" % [
|
145
|
-
self.prompt.color(cmd.rjust(col1len), :key),
|
146
|
-
self.prompt.color(helptext, :value)
|
147
|
-
]
|
148
|
-
end.compact
|
149
|
-
end
|
150
|
-
|
151
|
-
|
152
|
-
### Return an Array of the available commands.
|
153
|
-
def self::available_commands
|
154
|
-
return self.public_instance_methods( false ).
|
155
|
-
map( &:to_s ).
|
156
|
-
grep( /_command$/ ).
|
157
|
-
map {|methodname| methodname.sub(/_command$/, '') }.
|
158
|
-
sort
|
159
|
-
end
|
160
|
-
|
161
|
-
|
162
|
-
### Create and configure a command-line option parser for the command.
|
163
|
-
### Returns a Trollop::Parser.
|
164
|
-
def self::make_option_parser
|
165
|
-
unless @option_parser
|
166
|
-
progname = File.basename( $0 )
|
167
|
-
default_configdb = Mongrel2::DEFAULT_CONFIG_URI
|
168
|
-
|
169
|
-
# Make a list of the log level names and the available commands
|
170
|
-
loglevels = Loggability::LOG_LEVELS.
|
171
|
-
sort_by {|name,lvl| lvl }.
|
172
|
-
collect {|name,lvl| name.to_s }.
|
173
|
-
join( ', ' )
|
174
|
-
command_table = self.make_command_table
|
175
|
-
|
176
|
-
@option_parser = Trollop::Parser.new do
|
177
|
-
banner "Mongrel2 (Ruby) Shell has these commands available:"
|
178
|
-
|
179
|
-
text ''
|
180
|
-
command_table.each {|line| text(line) }
|
181
|
-
text ''
|
182
|
-
|
183
|
-
text 'Global Options'
|
184
|
-
opt :config, "Specify the config database to use.",
|
185
|
-
:default => DEFAULT_CONFIG_URI
|
186
|
-
opt :sudo, "Use 'sudo' to run the mongrel2 server."
|
187
|
-
opt :port, "Reset the server port to <i> before starting it.",
|
188
|
-
:type => :integer
|
189
|
-
opt :why, "Specify the reason for an action for the event log.",
|
190
|
-
:type => :string
|
191
|
-
text ''
|
192
|
-
|
193
|
-
text 'Other Options:'
|
194
|
-
opt :debug, "Turn debugging on. Also sets the --loglevel to 'debug'."
|
195
|
-
opt :loglevel, "Set the logging level. Must be one of: #{loglevels}",
|
196
|
-
:default => Mongrel2.logger.level.to_s
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
return @option_parser
|
201
|
-
end
|
202
|
-
|
203
|
-
|
204
|
-
#################################################################
|
205
|
-
### I N S T A N C E M E T H O D S
|
206
|
-
#################################################################
|
207
|
-
|
208
|
-
### Create a new instance of the command and set it up with the given
|
209
|
-
### +options+.
|
210
|
-
def initialize( options )
|
211
|
-
Loggability.format_as( :color ) if $stderr.tty?
|
212
|
-
@options = options
|
213
|
-
|
214
|
-
if @options.debug
|
215
|
-
$DEBUG = true
|
216
|
-
$VERBOSE = true
|
217
|
-
Loggability.level = Logger::DEBUG
|
218
|
-
elsif @options.loglevel
|
219
|
-
Loggability.level = @options.loglevel
|
220
|
-
end
|
221
|
-
|
222
|
-
Mongrel2::Config.configure( :configdb => @options.config )
|
223
|
-
end
|
224
|
-
|
225
|
-
|
226
|
-
######
|
227
|
-
public
|
228
|
-
######
|
229
|
-
|
230
|
-
# The Trollop options hash the command will read its configuration from
|
231
|
-
attr_reader :options
|
232
|
-
|
233
|
-
|
234
|
-
# Delegate the instance #prompt method to the class method instead
|
235
|
-
define_method( :prompt, &self.method(:prompt) )
|
236
|
-
|
237
|
-
|
238
|
-
### Run the command with the specified +command+ and +args+.
|
239
|
-
def run( command, *args )
|
240
|
-
command ||= 'help'
|
241
|
-
cmd_method = nil
|
242
|
-
|
243
|
-
begin
|
244
|
-
cmd_method = self.method( "#{command}_command" )
|
245
|
-
rescue NoMethodError => err
|
246
|
-
error "No such command"
|
247
|
-
exit :usage
|
248
|
-
end
|
249
|
-
|
250
|
-
cmd_method.call( *args )
|
251
|
-
end
|
252
|
-
|
253
|
-
|
254
|
-
#
|
255
|
-
# Commands
|
256
|
-
#
|
257
|
-
|
258
|
-
### The 'help' command
|
259
|
-
def help_command( *args )
|
260
|
-
|
261
|
-
# Subcommand help
|
262
|
-
if !args.empty?
|
263
|
-
command = args.shift
|
264
|
-
|
265
|
-
if self.class.available_commands.include?( command )
|
266
|
-
header( self.class.help(command) )
|
267
|
-
desc = "\n" + 'Usage: ' + command + ' ' + self.class.usage(command) + "\n"
|
268
|
-
message( desc )
|
269
|
-
else
|
270
|
-
error "No such command %p" % [ command ]
|
271
|
-
end
|
272
|
-
|
273
|
-
# Help by itself show the table of available commands
|
274
|
-
else
|
275
|
-
command_table = self.class.make_command_table
|
276
|
-
header "Available Commands"
|
277
|
-
message( *command_table )
|
278
|
-
end
|
279
|
-
|
280
|
-
end
|
281
|
-
help :help, "Show help for a single COMMAND if given, or list available commands if not"
|
282
|
-
usage :help, "[COMMAND]"
|
283
|
-
|
284
|
-
|
285
|
-
### The 'load' command
|
286
|
-
def load_command( *args )
|
287
|
-
configfile = args.shift or
|
288
|
-
raise "No configfile specified."
|
289
|
-
|
290
|
-
runspace = Module.new do
|
291
|
-
extend Mongrel2::Config::DSL, FileUtils::Verbose
|
292
|
-
end
|
293
|
-
|
294
|
-
header "Loading config from #{configfile}"
|
295
|
-
source = File.read( configfile )
|
296
|
-
|
297
|
-
runspace.module_eval( source, configfile, 1 )
|
298
|
-
Mongrel2::Config.log_action( "Loaded config from #{configfile}", self.options.why )
|
299
|
-
end
|
300
|
-
help :load, "Overwrite the config database with the values from the speciifed CONFIGFILE."
|
301
|
-
usage :load, <<-END_USAGE
|
302
|
-
CONFIGFILE
|
303
|
-
Note: the CONFIGFILE should contain a configuration described using the
|
304
|
-
Ruby config DSL, not a Python-ish normal one. m2sh already works perfectly
|
305
|
-
fine for loading those.
|
306
|
-
END_USAGE
|
307
|
-
|
308
|
-
|
309
|
-
### The 'config' command
|
310
|
-
alias_method :config_command, :load_command
|
311
|
-
help :config, "Alias for 'load'."
|
312
|
-
|
313
|
-
|
314
|
-
### The 'init' command
|
315
|
-
def init_command( * )
|
316
|
-
if Mongrel2::Config.database_initialized?
|
317
|
-
abort "Okay, aborting." unless
|
318
|
-
self.prompt.agree( "Are you sure you want to destroy the current config? " )
|
319
|
-
end
|
320
|
-
|
321
|
-
header "Initializing #{self.options.config}"
|
322
|
-
Mongrel2::Config.init_database!
|
323
|
-
end
|
324
|
-
help :init, "Initialize a new empty config database."
|
325
|
-
|
326
|
-
|
327
|
-
### The 'access' command
|
328
|
-
def access_command( logfile='logs/access.log', * )
|
329
|
-
# 1$ 2$ 3$ 4$ 5$ 6$ 7$ 8$ 9$
|
330
|
-
# ["localhost", "127.0.0.1", 53420, 1315533812, "GET", "/favicon.ico", "HTTP/1.1", 404, 0]
|
331
|
-
# -> [1315533812] 127.0.0.1:53420 localhost "GET /favicon.ico HTTP/1.1" 404 0
|
332
|
-
IO.foreach( logfile ) do |line|
|
333
|
-
row, _ = TNetstring.parse( line )
|
334
|
-
message %{[%4$d] %2$s:%3$d %1$s "%5$s %6$s %7$s" %8$03d %9$d} % row
|
335
|
-
end
|
336
|
-
end
|
337
|
-
help :access, "Dump the access log."
|
338
|
-
usage :access, "[logfile]\nThe logfile defaults to 'logs/access.log'."
|
339
|
-
|
340
|
-
|
341
|
-
### The 'servers' command
|
342
|
-
def servers_command( * )
|
343
|
-
header 'SERVERS:'
|
344
|
-
Mongrel2::Config.servers.each do |server|
|
345
|
-
message "%s [%s]: %s" % [
|
346
|
-
self.prompt.color( server.name, :key ),
|
347
|
-
server.default_host,
|
348
|
-
server.uuid,
|
349
|
-
]
|
350
|
-
end
|
351
|
-
end
|
352
|
-
help :servers, "Lists the servers in a config database."
|
353
|
-
|
354
|
-
|
355
|
-
### The 'hosts' command
|
356
|
-
def hosts_command( *args )
|
357
|
-
servername = args.shift
|
358
|
-
|
359
|
-
# Start with all servers, then narrow it down if they specified a server name.
|
360
|
-
servers = Mongrel2::Config::Server.dataset
|
361
|
-
servers = servers.filter( :name => servername ) if servername
|
362
|
-
|
363
|
-
# Output a section for each server
|
364
|
-
servers.each do |server|
|
365
|
-
header "HOSTS for server #{server.name}:"
|
366
|
-
server.hosts.each do |host|
|
367
|
-
line = "%d: %s" % [ host.id, host.name ]
|
368
|
-
line << " /%s/" % [ host.matching ] if host.matching != host.name
|
369
|
-
|
370
|
-
message( line )
|
371
|
-
end
|
372
|
-
|
373
|
-
$stdout.puts
|
374
|
-
end
|
375
|
-
end
|
376
|
-
help :hosts, "Lists the hosts in a server, or in all servers if none is specified."
|
377
|
-
usage :hosts, "[server]"
|
378
|
-
|
379
|
-
|
380
|
-
### The 'routes' command
|
381
|
-
def routes_command( *args )
|
382
|
-
servername = args.shift
|
383
|
-
hostname = args.shift
|
384
|
-
|
385
|
-
# Start with all hosts, then narrow it down if a server and/or host was given.
|
386
|
-
hosts = Mongrel2::Config::Host.dataset
|
387
|
-
if servername
|
388
|
-
server = Mongrel2::Config::Server[ servername ] or
|
389
|
-
raise "No such server '#{servername}'"
|
390
|
-
hosts = server.hosts_dataset
|
391
|
-
end
|
392
|
-
hosts = hosts.filter( :name => hostname ) if hostname
|
393
|
-
|
394
|
-
# Output a section for each host
|
395
|
-
hosts.each do |host|
|
396
|
-
header "ROUTES for host #{host.server.name}/#{host.name}:"
|
397
|
-
|
398
|
-
host.routes.each do |route|
|
399
|
-
message( route.path )
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
end
|
404
|
-
help :routes, "Show the routes under a host."
|
405
|
-
usage :routes, "[server [host]]"
|
406
|
-
|
407
|
-
|
408
|
-
### The 'commit' command
|
409
|
-
def commit_command( *args )
|
410
|
-
what, where, why, how = *args
|
411
|
-
what ||= ''
|
412
|
-
|
413
|
-
log = Mongrel2::Config::Log.log_action( what, where, why, how )
|
414
|
-
|
415
|
-
header "Okay, logged."
|
416
|
-
message( log.to_s )
|
417
|
-
end
|
418
|
-
help :commit, "Add a message to the commit log."
|
419
|
-
usage :commit, "[WHAT [WHERE [WHY [HOW]]]]"
|
420
|
-
|
421
|
-
|
422
|
-
### The 'log' command
|
423
|
-
def log_command( *args )
|
424
|
-
header "Log Messages"
|
425
|
-
Mongrel2::Config::Log.order_by( :happened_at ).each do |log|
|
426
|
-
message( log.to_s )
|
427
|
-
end
|
428
|
-
end
|
429
|
-
help :log, "Prints the commit log."
|
430
|
-
|
431
|
-
|
432
|
-
### The 'start' command
|
433
|
-
def start_command( *args )
|
434
|
-
server = find_server( args.shift )
|
435
|
-
mongrel2 = find_mongrel2()
|
436
|
-
|
437
|
-
if options.port
|
438
|
-
message "Resetting %s server's port to %d" % [ server.name, options.port ]
|
439
|
-
server.port = options.port
|
440
|
-
server.save
|
441
|
-
end
|
442
|
-
|
443
|
-
cmd = [ mongrel2.to_s, Mongrel2::Config.dbname.to_s, server.uuid ]
|
444
|
-
cmd.unshift( 'sudo' ) if self.options.sudo
|
445
|
-
|
446
|
-
url = "http%s://%s:%d" % [
|
447
|
-
server.use_ssl? ? 's' : '',
|
448
|
-
server.bind_addr,
|
449
|
-
server.port,
|
450
|
-
]
|
451
|
-
|
452
|
-
# Change into the server's chroot directory so paths line up whether or not
|
453
|
-
# it's started as root
|
454
|
-
|
455
|
-
message '*' * 70
|
456
|
-
header "Starting mongrel2 at: #{url}"
|
457
|
-
message '*' * 70
|
458
|
-
|
459
|
-
if server.chroot && server.chroot != '' && server.chroot != '.'
|
460
|
-
Dir.chdir( server.chroot )
|
461
|
-
message " changed PWD to: #{Dir.pwd}"
|
462
|
-
end
|
463
|
-
|
464
|
-
Mongrel2::Config.log_action( "Starting server: #{server}", self.options.why )
|
465
|
-
self.log.debug " command is: #{Shellwords.shelljoin(cmd)}"
|
466
|
-
exec( *cmd )
|
467
|
-
end
|
468
|
-
help :start, "Starts a server."
|
469
|
-
usage :start, <<-END_USAGE
|
470
|
-
[SERVER]
|
471
|
-
If not specified, SERVER is assumed to be the only server entry in the
|
472
|
-
current config. If there are more than one, you must specify a SERVER.
|
473
|
-
|
474
|
-
The SERVER can be a uuid, hostname, or server name, and are searched for
|
475
|
-
in that order.
|
476
|
-
END_USAGE
|
477
|
-
|
478
|
-
|
479
|
-
### The 'reload' command
|
480
|
-
def reload_command( *args )
|
481
|
-
server = find_server( args.shift )
|
482
|
-
control = server.control_socket
|
483
|
-
|
484
|
-
header "Reloading '%s'" % [ server.name ]
|
485
|
-
control.reload
|
486
|
-
control.close
|
487
|
-
message "done."
|
488
|
-
|
489
|
-
Mongrel2::Config.log_action( "Restarted server #{server}", self.options.why )
|
490
|
-
end
|
491
|
-
help :reload, "Reload the specified server's configuration"
|
492
|
-
usage :reload, "[server]"
|
493
|
-
|
494
|
-
|
495
|
-
### The 'stop' command
|
496
|
-
def stop_command( *args )
|
497
|
-
server = find_server( args.shift )
|
498
|
-
control = server.control_socket
|
499
|
-
|
500
|
-
header "Stopping '%s' gracefully." % [ server.name ]
|
501
|
-
control.stop
|
502
|
-
control.close
|
503
|
-
message "done."
|
504
|
-
|
505
|
-
Mongrel2::Config.log_action( "Stopped server #{server}", self.options.why )
|
506
|
-
end
|
507
|
-
help :stop, "Stop the specified server gracefully"
|
508
|
-
usage :stop, "[server]"
|
509
|
-
|
510
|
-
|
511
|
-
### The 'running' command
|
512
|
-
def running_command( *args )
|
513
|
-
server = find_server( args.shift )
|
514
|
-
pidfile = server.pid_file_path
|
515
|
-
|
516
|
-
header "Checking the status of the '%s' server." % [ server.name ]
|
517
|
-
unless pidfile.exist?
|
518
|
-
message "Not running: PID file (%s) doesn't exist." % [ pidfile ]
|
519
|
-
exit :noinput
|
520
|
-
end
|
521
|
-
|
522
|
-
pid = Integer( pidfile.read )
|
523
|
-
begin
|
524
|
-
Process.kill( 0, pid )
|
525
|
-
rescue Errno::ESRCH
|
526
|
-
message " mongrel2 at PID %d is NOT running" % [ pid ]
|
527
|
-
exit :unavailable
|
528
|
-
rescue => err
|
529
|
-
error " %p while signalling PID %d: %s" % [ err.class, pid, err.message ]
|
530
|
-
end
|
531
|
-
|
532
|
-
message " mongrel2 at PID %d is running." % [ pid ]
|
533
|
-
end
|
534
|
-
help :running, "Show the status of a server."
|
535
|
-
usage :running, "[server]"
|
536
|
-
|
537
|
-
|
538
|
-
### The 'bootstrap' command.
|
539
|
-
def bootstrap_command( *args )
|
540
|
-
scriptname = args.shift || DEFAULT_CONFIG_SCRIPT
|
541
|
-
template = Mongrel2::DATA_DIR + 'config.rb.in'
|
542
|
-
|
543
|
-
# Read the config DSL template
|
544
|
-
data = template.read
|
545
|
-
data.gsub!( /%% PWD %%/, Dir.pwd )
|
546
|
-
|
547
|
-
# Write it out
|
548
|
-
header "Writing a config-generation script to %s" % [ scriptname ]
|
549
|
-
File.open( scriptname, File::WRONLY|File::EXCL|File::CREAT, 0755, encoding: 'utf-8' ) do |fh|
|
550
|
-
fh.print( data )
|
551
|
-
end
|
552
|
-
message "Done."
|
553
|
-
end
|
554
|
-
help :bootstrap, "Generate a basic config-generation script."
|
555
|
-
usage :boostrap, "[scriptname]"
|
556
|
-
|
557
|
-
|
558
|
-
### The 'quickstart' command.
|
559
|
-
def quickstart_command( *args )
|
560
|
-
idx_template = Mongrel2::DATA_DIR + 'index.html.in'
|
561
|
-
configfile = 'config.rb'
|
562
|
-
|
563
|
-
header "Quickstart!"
|
564
|
-
self.bootstrap_command( configfile )
|
565
|
-
edit( configfile )
|
566
|
-
self.load_command( configfile )
|
567
|
-
|
568
|
-
# Now load the new config DB and fetch the configured server
|
569
|
-
host = Mongrel2::Config.servers.first.hosts.first
|
570
|
-
hello_route = host.routes_dataset.filter( target_type: 'handler' ).first
|
571
|
-
|
572
|
-
# Read the index page template
|
573
|
-
data = idx_template.read
|
574
|
-
data.gsub!( /%% VERSION %%/, Mongrel2.version_string(true) )
|
575
|
-
data.gsub!( /%% HELLOWORLD_SEND_SPEC %%/, hello_route.target.send_spec )
|
576
|
-
data.gsub!( /%% HELLOWORLD_RECV_SPEC %%/, hello_route.target.recv_spec )
|
577
|
-
data.gsub!( /%% HELLOWORLD_URI %%/, hello_route.path[ /([^\(]*)/ ] )
|
578
|
-
|
579
|
-
# Write it out to the public directory
|
580
|
-
header "Writing an index file to public/index.html"
|
581
|
-
Dir.mkdir( 'public' ) unless File.directory?( 'public' )
|
582
|
-
File.open( 'public/index.html', File::WRONLY|File::EXCL|File::CREAT, 0755,
|
583
|
-
encoding: 'utf-8' ) do |fh|
|
584
|
-
fh.print( data )
|
585
|
-
end
|
586
|
-
message "Done."
|
587
|
-
|
588
|
-
self.start_command()
|
589
|
-
end
|
590
|
-
help :quickstart, "Set up a basic mongrel2 server and run it."
|
591
|
-
usage :quickstart
|
592
|
-
|
593
|
-
|
594
|
-
### The 'settings' command
|
595
|
-
def settings_command( *args )
|
596
|
-
header "Advanced Server Settings"
|
597
|
-
Mongrel2::Config.settings.each do |key,val|
|
598
|
-
message( %{<%= color "#{key}:", :subheader %> #{val}} )
|
599
|
-
end
|
600
|
-
end
|
601
|
-
help :settings, "Show the 'advanced' server settings."
|
602
|
-
usage :settings
|
603
|
-
|
604
|
-
|
605
|
-
### The 'version' command
|
606
|
-
def version_command( *args )
|
607
|
-
message( "<%= color 'Version:', :header %> " + Mongrel2.version_string(true) )
|
608
|
-
end
|
609
|
-
help :version, "Prints the Ruby-Mongrel2 version."
|
610
|
-
|
611
|
-
|
612
|
-
#
|
613
|
-
# Utility methods
|
614
|
-
#
|
615
|
-
|
616
|
-
#######
|
617
|
-
private
|
618
|
-
#######
|
619
|
-
|
620
|
-
### Output normal output
|
621
|
-
def message( *parts )
|
622
|
-
self.prompt.say( parts.map(&:to_s).join($/) )
|
623
|
-
end
|
624
|
-
|
625
|
-
|
626
|
-
### Output the given +text+ highlighted as a header.
|
627
|
-
def header( text )
|
628
|
-
message( self.prompt.color(text, :header) )
|
629
|
-
end
|
630
|
-
|
631
|
-
|
632
|
-
### Output the given +text+ highlighted as an error.
|
633
|
-
def error( text )
|
634
|
-
message( self.prompt.color(text, :error) )
|
635
|
-
end
|
636
|
-
|
637
|
-
|
638
|
-
### Read command line history from HISTORY_FILE
|
639
|
-
def read_history
|
640
|
-
histfile = HISTORY_FILE.expand_path
|
641
|
-
|
642
|
-
if histfile.exist?
|
643
|
-
lines = histfile.readlines.collect {|line| line.chomp }
|
644
|
-
self.log.debug "Read %d saved history commands from %s." % [ lines.length, histfile ]
|
645
|
-
Readline::HISTORY.push( *lines )
|
646
|
-
else
|
647
|
-
self.log.debug "History file '%s' was empty or non-existant." % [ histfile ]
|
648
|
-
end
|
649
|
-
end
|
650
|
-
|
651
|
-
|
652
|
-
### Save command line history to HISTORY_FILE
|
653
|
-
def save_history
|
654
|
-
histfile = HISTORY_FILE.expand_path
|
655
|
-
|
656
|
-
lines = Readline::HISTORY.to_a.reverse.uniq.reverse
|
657
|
-
lines = lines[ -DEFAULT_HISTORY_SIZE, DEFAULT_HISTORY_SIZE ] if
|
658
|
-
lines.length > DEFAULT_HISTORY_SIZE
|
659
|
-
|
660
|
-
self.log.debug "Saving %d history lines to %s." % [ lines.length, histfile ]
|
661
|
-
|
662
|
-
histfile.open( File::WRONLY|File::CREAT|File::TRUNC ) do |ofh|
|
663
|
-
ofh.puts( *lines )
|
664
|
-
end
|
665
|
-
end
|
666
|
-
|
667
|
-
|
668
|
-
### Search the current mongrel2 config for a server matching +serverspec+ and
|
669
|
-
### return it as a Mongrel2::Config::Server object.
|
670
|
-
def find_server( serverspec=nil )
|
671
|
-
server = nil
|
672
|
-
servers = Mongrel2::Config.servers
|
673
|
-
|
674
|
-
raise "No servers are configured." if servers.empty?
|
675
|
-
|
676
|
-
# If there's only one configured server, just make sure if a serverspec was given
|
677
|
-
# that it would have matched.
|
678
|
-
if servers.length == 1
|
679
|
-
server = servers.first if !serverspec ||
|
680
|
-
servers.first.values.values_at( :uuid, :default_host, :name ).include?( serverspec )
|
681
|
-
|
682
|
-
# Otherwise, require an argument and search for the desired server if there is one
|
683
|
-
else
|
684
|
-
raise "You must specify a server uuid/hostname/name when more " +
|
685
|
-
"than one server is configured." if servers.length > 1 && !serverspec
|
686
|
-
|
687
|
-
server = servers.find {|s| s.uuid == serverspec } ||
|
688
|
-
servers.find {|s| s.default_host == serverspec } ||
|
689
|
-
servers.find {|s| s.name == serverspec }
|
690
|
-
end
|
691
|
-
|
692
|
-
raise "No servers match '#{serverspec}'" unless server
|
693
|
-
|
694
|
-
return server
|
695
|
-
end
|
696
|
-
|
697
|
-
|
698
|
-
### Invoke the user's editor on the given +filename+ and return the exit code
|
699
|
-
### from doing so.
|
700
|
-
def edit( filename )
|
701
|
-
editor = ENV['EDITOR'] || ENV['VISUAL'] || DEFAULT_EDITOR
|
702
|
-
system editor, filename.to_s
|
703
|
-
unless $?.success? || editor =~ /vim/i
|
704
|
-
raise "Editor exited with an error status (%d)" % [ $?.exitstatus ]
|
705
|
-
end
|
706
|
-
end
|
707
|
-
|
708
|
-
|
709
|
-
### Search the PATH for a mongrel2 binary, returning the absolute Pathname to it if found, and
|
710
|
-
### outputting a warning and describing how to set ENV['MONGREL2'] if not.
|
711
|
-
def find_mongrel2
|
712
|
-
if ENV['MONGREL2']
|
713
|
-
m2 = Pathname( ENV['MONGREL2'] )
|
714
|
-
error = nil
|
715
|
-
if !m2.file?
|
716
|
-
error = "but it isn't a plain file."
|
717
|
-
elsif !m2.executable?
|
718
|
-
error = "but it isn't executable."
|
719
|
-
end
|
720
|
-
|
721
|
-
raise "MONGREL2 was set to #{m2}, #{error}" if error
|
722
|
-
|
723
|
-
return m2
|
724
|
-
else
|
725
|
-
m2 = ENV['PATH'].split( File::PATH_SEPARATOR ).
|
726
|
-
map {|dir| Pathname(dir) + 'mongrel2' }.
|
727
|
-
find {|path| path.executable? }
|
728
|
-
|
729
|
-
return m2 if m2
|
730
|
-
|
731
|
-
raise "The 'mongrel2' binary doesn't seem to be in your PATH. Either " +
|
732
|
-
"add the appropriate directory to your PATH or set the MONGREL2 " +
|
733
|
-
"environment variable to the full path."
|
734
|
-
end
|
735
|
-
|
736
|
-
end
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
end # class Mongrel2::M2SHCommand
|
741
|
-
|
742
|
-
|
743
|
-
Mongrel2::M2SHCommand.run( ARGV.dup )
|
744
9
|
|