2006-06-30 16:42:12 -04:00
|
|
|
# Copyright (c) 2005 Zed A. Shaw
|
|
|
|
# You can redistribute it and/or modify it under the same terms as Ruby.
|
|
|
|
#
|
|
|
|
# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
|
|
|
|
# for more information.
|
2006-05-21 10:46:42 -04:00
|
|
|
|
2006-03-08 22:05:11 -05:00
|
|
|
require 'rubygems'
|
2006-02-11 20:38:04 -05:00
|
|
|
require 'singleton'
|
|
|
|
require 'optparse'
|
2006-03-08 22:05:11 -05:00
|
|
|
require 'gem_plugin'
|
2006-02-11 20:38:04 -05:00
|
|
|
|
|
|
|
module Mongrel
|
2006-02-11 22:37:38 -05:00
|
|
|
|
|
|
|
# Contains all of the various commands that are used with
|
|
|
|
# Mongrel servers.
|
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
module Command
|
2006-02-11 22:37:38 -05:00
|
|
|
|
2006-05-13 17:54:05 -04:00
|
|
|
BANNER = "Usage: mongrel_rails <command> [options]"
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# A Command pattern implementation used to create the set of command available to the user
|
|
|
|
# from Mongrel. The script uses objects which implement this interface to do the
|
|
|
|
# user's bidding.
|
2006-03-01 22:54:32 -05:00
|
|
|
module Base
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-03-26 15:01:50 -05:00
|
|
|
attr_reader :valid, :done_validating, :original_args
|
2006-02-11 20:38:04 -05:00
|
|
|
|
|
|
|
# Called by the implemented command to set the options for that command.
|
|
|
|
# Every option has a short and long version, a description, a variable to
|
|
|
|
# set, and a default value. No exceptions.
|
|
|
|
def options(opts)
|
|
|
|
# process the given options array
|
|
|
|
opts.each do |short, long, help, variable, default|
|
|
|
|
self.instance_variable_set(variable, default)
|
|
|
|
@opt.on(short, long, help) do |arg|
|
|
|
|
self.instance_variable_set(variable, arg)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Called by the subclass to setup the command and parse the argv arguments.
|
|
|
|
# The call is destructive on argv since it uses the OptionParser#parse! function.
|
2006-03-01 22:54:32 -05:00
|
|
|
def initialize(options={})
|
2006-03-05 14:28:52 -05:00
|
|
|
argv = options[:argv] || []
|
2006-02-11 20:38:04 -05:00
|
|
|
@opt = OptionParser.new
|
2006-05-13 17:54:05 -04:00
|
|
|
@opt.banner = Mongrel::Command::BANNER
|
2006-02-11 20:38:04 -05:00
|
|
|
@valid = true
|
|
|
|
# this is retarded, but it has to be done this way because -h and -v exit
|
|
|
|
@done_validating = false
|
2006-02-26 16:39:40 -05:00
|
|
|
@original_args = argv.dup
|
2006-02-11 20:38:04 -05:00
|
|
|
|
|
|
|
configure
|
|
|
|
|
|
|
|
# I need to add my own -h definition to prevent the -h by default from exiting.
|
|
|
|
@opt.on_tail("-h", "--help", "Show this message") do
|
|
|
|
@done_validating = true
|
|
|
|
puts @opt
|
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-05-13 17:25:53 -04:00
|
|
|
# I need to add my own -v definition to prevent the -v from exiting by default as well.
|
2006-02-11 20:38:04 -05:00
|
|
|
@opt.on_tail("--version", "Show version") do
|
|
|
|
@done_validating = true
|
2006-02-11 22:37:38 -05:00
|
|
|
if VERSION
|
2006-05-13 17:25:53 -04:00
|
|
|
puts "Version #{Mongrel::Const::MONGREL_VERSION}"
|
2006-02-11 22:37:38 -05:00
|
|
|
end
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-03-05 14:28:52 -05:00
|
|
|
@opt.parse! argv
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
2006-05-04 12:07:56 -04:00
|
|
|
|
|
|
|
def configure
|
|
|
|
options []
|
|
|
|
end
|
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Returns true/false depending on whether the command is configured properly.
|
|
|
|
def validate
|
|
|
|
return @valid
|
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Returns a help message. Defaults to OptionParser#help which should be good.
|
|
|
|
def help
|
|
|
|
@opt.help
|
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Runs the command doing it's job. You should implement this otherwise it will
|
|
|
|
# throw a NotImplementedError as a reminder.
|
|
|
|
def run
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Validates the given expression is true and prints the message if not, exiting.
|
|
|
|
def valid?(exp, message)
|
|
|
|
if not @done_validating and (not exp)
|
2006-02-11 22:37:38 -05:00
|
|
|
failure message
|
2006-02-11 20:38:04 -05:00
|
|
|
@valid = false
|
|
|
|
@done_validating = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Validates that a file exists and if not displays the message
|
|
|
|
def valid_exists?(file, message)
|
|
|
|
valid?(file != nil && File.exist?(file), message)
|
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Validates that the file is a file and not a directory or something else.
|
|
|
|
def valid_file?(file, message)
|
|
|
|
valid?(file != nil && File.file?(file), message)
|
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Validates that the given directory exists
|
|
|
|
def valid_dir?(file, message)
|
|
|
|
valid?(file != nil && File.directory?(file), message)
|
|
|
|
end
|
2006-02-11 22:37:38 -05:00
|
|
|
|
2006-06-05 04:54:06 -04:00
|
|
|
def valid_user?(user)
|
|
|
|
valid?(@group, "You must also specify a group.")
|
|
|
|
begin
|
|
|
|
Etc.getpwnam(user)
|
|
|
|
rescue
|
|
|
|
failure "User does not exist: #{user}"
|
|
|
|
@valid = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def valid_group?(group)
|
|
|
|
valid?(@user, "You must also specify a user.")
|
|
|
|
begin
|
|
|
|
Etc.getgrnam(group)
|
|
|
|
rescue
|
|
|
|
failure "Group does not exist: #{group}"
|
|
|
|
@valid = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2006-02-11 22:37:38 -05:00
|
|
|
# Just a simple method to display failure until something better is developed.
|
|
|
|
def failure(message)
|
|
|
|
STDERR.puts "!!! #{message}"
|
|
|
|
end
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# A Singleton class that manages all of the available commands
|
|
|
|
# and handles running them.
|
|
|
|
class Registry
|
|
|
|
include Singleton
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Builds a list of possible commands from the Command derivates list
|
|
|
|
def commands
|
2006-03-06 00:31:39 -05:00
|
|
|
pmgr = GemPlugin::Manager.instance
|
2006-03-11 16:23:37 -05:00
|
|
|
list = pmgr.plugins["/commands"].keys
|
2006-02-28 02:04:41 -05:00
|
|
|
return list.sort
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Prints a list of available commands.
|
|
|
|
def print_command_list
|
2006-05-13 17:54:05 -04:00
|
|
|
puts "#{Mongrel::Command::BANNER}\nAvailable commands are:\n\n"
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
self.commands.each do |name|
|
2006-09-22 04:16:54 -04:00
|
|
|
if /mongrel::/ =~ name
|
|
|
|
name = name[9 .. -1]
|
|
|
|
end
|
|
|
|
|
2006-02-28 02:04:41 -05:00
|
|
|
puts " - #{name[1 .. -1]}\n"
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 22:37:38 -05:00
|
|
|
puts "\nEach command takes -h as an option to get help."
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Runs the args against the first argument as the command name.
|
|
|
|
# If it has any errors it returns a false, otherwise it return true.
|
|
|
|
def run(args)
|
2006-02-26 16:39:40 -05:00
|
|
|
# find the command
|
2006-02-11 20:38:04 -05:00
|
|
|
cmd_name = args.shift
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-16 01:41:47 -05:00
|
|
|
if !cmd_name or cmd_name == "?" or cmd_name == "help"
|
2006-02-11 20:38:04 -05:00
|
|
|
print_command_list
|
|
|
|
return true
|
2006-06-15 14:14:07 -04:00
|
|
|
elsif cmd_name == "--version"
|
2007-10-11 03:06:02 -04:00
|
|
|
puts "Mongrel Web Server #{Mongrel::Const::MONGREL_VERSION}"
|
2006-06-15 14:14:07 -04:00
|
|
|
return true
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
begin
|
2006-09-22 04:16:54 -04:00
|
|
|
# quick hack so that existing commands will keep working but the Mongrel:: ones can be moved
|
|
|
|
if ["start", "stop", "restart"].include? cmd_name
|
|
|
|
cmd_name = "mongrel::" + cmd_name
|
|
|
|
end
|
|
|
|
|
2006-03-06 00:31:39 -05:00
|
|
|
command = GemPlugin::Manager.instance.create("/commands/#{cmd_name}", :argv => args)
|
2006-08-08 05:23:26 -04:00
|
|
|
rescue OptionParser::InvalidOption
|
|
|
|
STDERR.puts "#$! for command '#{cmd_name}'"
|
|
|
|
STDERR.puts "Try #{cmd_name} -h to get help."
|
|
|
|
return false
|
2006-02-28 02:04:41 -05:00
|
|
|
rescue
|
2006-08-08 05:23:26 -04:00
|
|
|
STDERR.puts "ERROR RUNNING '#{cmd_name}': #$!"
|
|
|
|
STDERR.puts "Use help command to get help"
|
2006-06-15 14:14:07 -04:00
|
|
|
return false
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
# Normally the command is NOT valid right after being created
|
|
|
|
# but sometimes (like with -h or -v) there's no further processing
|
|
|
|
# needed so the command is already valid so we can skip it.
|
|
|
|
if not command.done_validating
|
|
|
|
if not command.validate
|
2006-05-13 17:54:05 -04:00
|
|
|
STDERR.puts "#{cmd_name} reported an error. Use mongrel_rails #{cmd_name} -h to get help."
|
2006-02-11 20:38:04 -05:00
|
|
|
return false
|
|
|
|
else
|
|
|
|
command.run
|
|
|
|
end
|
|
|
|
end
|
2006-06-15 14:14:07 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
return true
|
|
|
|
end
|
2006-06-05 04:54:06 -04:00
|
|
|
|
2006-02-11 20:38:04 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|