1 # Copyright (c) 2005 Zed A. Shaw
2 # You can redistribute it and/or modify it under the same terms as Ruby.
4 # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5 # for more information.
10 $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
12 require 'mongrel/rails'
14 Mongrel::Gems.require 'gem_plugin'
16 # require 'ruby-debug'
20 class Start < GemPlugin::Plugin "/commands"
21 include Mongrel::Command::Base
25 ["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
26 ["-d", "--daemonize", "Run daemonized in the background", :@daemon, false],
27 ['-p', '--port PORT', "Which port to bind to", :@port, 3000],
28 ['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
29 ['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"],
30 ['-P', '--pid FILE', "Where to write the PID", :@pid_file, "log/mongrel.pid"],
31 ['-n', '--num-processors INT', "Number of processors active before clients denied", :@num_processors, 1024],
32 ['-o', '--timeout TIME', "Time to wait (in seconds) before killing a stalled thread", :@timeout, 60],
33 ['-t', '--throttle TIME', "Time to pause (in hundredths of a second) between accepting clients", :@throttle, 0],
34 ['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
35 ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
36 ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
37 ['-B', '--debug', "Enable debugging mode", :@debug, false],
38 ['-C', '--config PATH', "Use a config file", :@config_file, nil],
39 ['-S', '--script PATH', "Load the given file as an extra config script", :@config_script, nil],
40 ['-G', '--generate PATH', "Generate a config file for use with -C", :@generate, nil],
41 ['', '--user USER', "User to run as", :@user, nil],
42 ['', '--group GROUP', "Group to run as", :@group, nil],
43 ['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil]
49 valid_exists?(@config_file, "Config file not there: #@config_file")
50 return false unless @valid
51 @config_file = File.expand_path(@config_file)
53 return false unless @valid
56 @cwd = File.expand_path(@cwd)
57 valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
59 # Change there to start, then we'll have to come back after daemonize
62 valid?(@prefix[0] == ?/ && @prefix[-1] != ?/, "Prefix must begin with / and not end in /") if @prefix
63 valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
64 valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
65 valid_dir? @docroot, "Path to docroot not valid: #@docroot"
66 valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
67 valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
68 valid_dir? File.dirname(@generate), "Problem accessing directory to #@generate" if @generate
69 valid_user? @user if @user
70 valid_group? @group if @group
77 @generate = File.expand_path(@generate)
78 STDERR.puts "** Writing config to \"#@generate\"."
79 open(@generate, "w") {|f| f.write(settings.to_yaml) }
80 STDERR.puts "** Finished. Run \"mongrel_rails start -C #@generate\" to use the config file."
84 config = Mongrel::Rails::RailsConfigurator.new(settings) do
86 if File.exist? defaults[:pid_file]
87 log "!!! PID file #{defaults[:pid_file]} already exists. Mongrel could be running already. Check your #{defaults[:log_file]} for errors."
88 log "!!! Exiting with error. You must stop mongrel and clear the .pid before I'll attempt a start."
93 log "Daemonized, any open files are closed. Look at #{defaults[:pid_file]} and #{defaults[:log_file]} for info."
94 log "Settings loaded from #{@config_file} (they override command line)." if @config_file
97 log "Starting Mongrel listening at #{defaults[:host]}:#{defaults[:port]}"
101 if defaults[:mime_map]
102 log "Loading additional MIME types from #{defaults[:mime_map]}"
103 mime = load_mime_map(defaults[:mime_map], mime)
107 log "Installing debugging prefixed filters. Look in log/mongrel_debug for the files."
111 if defaults[:config_script]
112 log "Loading #{defaults[:config_script]} external config script"
113 run_config(defaults[:config_script])
116 log "Starting Rails with #{defaults[:environment]} environment..."
117 log "Mounting Rails at #{defaults[:prefix]}..." if defaults[:prefix]
118 uri defaults[:prefix] || "/", :handler => rails(:mime => mime, :prefix => defaults[:prefix])
121 log "Loading any Rails specific GemPlugins"
129 config.log "Mongrel #{Mongrel::Const::MONGREL_VERSION} available at #{@address}:#{@port}"
131 if config.defaults[:daemon]
132 config.write_pid_file
134 config.log "Use CTRL-C to stop."
139 if config.needs_restart
140 if RUBY_PLATFORM !~ /mswin/
141 cmd = "ruby #{__FILE__} start #{original_args.join(' ')}"
142 config.log "Restarting with arguments: #{cmd}"
143 config.stop(false, true)
144 config.remove_pid_file
146 if config.defaults[:daemon]
149 STDERR.puts "Can't restart unless in daemon mode."
153 config.log "Win32 does not support restarts. Exiting."
161 settings = YAML.load_file(@config_file)
163 STDERR.puts "** Loading settings from #{@config_file} (they override command line)." unless @daemon || settings[:daemon]
166 settings[:includes] ||= ["mongrel"]
168 # Config file settings will override command line settings
169 settings.each do |key, value|
171 if config_keys.include?(key)
172 key = 'address' if key == 'host'
173 self.instance_variable_set("@#{key}", value)
175 failure "Unknown configuration setting: #{key}"
183 %w(address host port cwd log_file pid_file environment docroot mime_map daemon debug includes config_script num_processors timeout throttle user group prefix)
187 config_keys.inject({}) do |hash, key|
188 value = self.instance_variable_get("@#{key}")
189 key = 'host' if key == 'address'
190 hash[key.to_sym] ||= value
196 def Mongrel::send_signal(signal, pid_file)
197 pid = open(pid_file).read.to_i
198 print "Sending #{signal} to Mongrel at PID #{pid}..."
200 Process.kill(signal, pid)
202 puts "Process does not exist. Not running."
209 class Stop < GemPlugin::Plugin "/commands"
210 include Mongrel::Command::Base
214 ['-c', '--chdir PATH', "Change to dir before starting (will be expanded).", :@cwd, "."],
215 ['-f', '--force', "Force the shutdown (kill -9).", :@force, false],
216 ['-w', '--wait SECONDS', "Wait SECONDS before forcing shutdown", :@wait, "0"],
217 ['-P', '--pid FILE', "Where the PID file is located.", :@pid_file, "log/mongrel.pid"]
222 @cwd = File.expand_path(@cwd)
223 valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
227 valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
233 @wait.to_i.times do |waiting|
234 exit(0) if not File.exist? @pid_file
238 Mongrel::send_signal("KILL", @pid_file) if File.exist? @pid_file
240 Mongrel::send_signal("TERM", @pid_file)
246 class Restart < GemPlugin::Plugin "/commands"
247 include Mongrel::Command::Base
251 ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, '.'],
252 ['-s', '--soft', "Do a soft restart rather than a process exit restart", :@soft, false],
253 ['-P', '--pid FILE', "Where the PID file is located", :@pid_file, "log/mongrel.pid"]
258 @cwd = File.expand_path(@cwd)
259 valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
263 valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
269 Mongrel::send_signal("HUP", @pid_file)
271 Mongrel::send_signal("USR2", @pid_file)
278 GemPlugin::Manager.instance.load "mongrel" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE
281 if not Mongrel::Command::Registry.instance.run ARGV