mongrel2 0.53.0 → 0.54.0
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.
- 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
|
|