This commit is contained in:
David Dollar
2011-12-08 17:53:13 -08:00
parent c9411cd2b1
commit 5436b68cf1
13 changed files with 72 additions and 79 deletions
+5
View File
@@ -9,5 +9,10 @@ module Foreman
require 'foreman/engine'
Foreman::Engine.load_env!(env_file)
end
def self.runner
File.expand_path("../../bin/runner", __FILE__)
end
end
+5 -10
View File
@@ -8,20 +8,15 @@ class Foreman::CLI < Thor
class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
desc "start [PROCESS]", "Start the application, or a specific process"
desc "start", "Start the application"
method_option :env, :type => :string, :aliases => "-e", :desc => "Specify an environment file to load, defaults to .env"
method_option :port, :type => :numeric, :aliases => "-p"
method_option :concurrency, :type => :string, :aliases => "-c", :banner => '"alpha=5,bar=3"'
def start(process=nil)
def start
check_procfile!
if process
engine.execute(process)
else
engine.start
end
engine.start
end
desc "export FORMAT LOCATION", "Export the application to another process management format"
@@ -55,8 +50,8 @@ class Foreman::CLI < Thor
desc "check", "Validate your application's Procfile"
def check
error "no processes defined" unless engine.processes.length > 0
display "valid procfile detected (#{engine.processes.map(&:name).join(', ')})"
error "no processes defined" unless engine.procfile.entries.length > 0
display "valid procfile detected (#{engine.procfile.process_names.join(', ')})"
end
private ######################################################################
+5 -2
View File
@@ -57,16 +57,19 @@ private ######################################################################
procfile.entries.each do |entry|
reader, writer = IO.pipe
entry.spawn(concurrency[entry.name], writer, @directory, @environment).each do |process|
entry.spawn(concurrency[entry.name], writer, @directory, @environment, base_port).each do |process|
running_processes[process.pid] = process
readers[process] = reader
end
end
end
def base_port
options[:port] || 5000
end
def kill_all(signal="SIGTERM")
running_processes.each do |pid, process|
p [:killing, pid]
Process.kill(signal, pid) rescue Errno::ESRCH
end
end
+1 -1
View File
@@ -12,7 +12,7 @@ class Foreman::Export::Inittab < Foreman::Export::Base
inittab = []
inittab << "# ----- foreman #{app} processes -----"
engine.processes.inject(1) do |index, process|
engine.procfile.entries.inject(1) do |index, process|
1.upto(concurrency[process.name]) do |num|
id = app.slice(0, 2).upcase + sprintf("%02d", index)
port = engine.port_for(process, num, options[:port])
+16 -16
View File
@@ -3,58 +3,58 @@ require "foreman/export"
class Foreman::Export::Runit < Foreman::Export::Base
ENV_VARIABLE_REGEX = /([a-zA-Z_]+[a-zA-Z0-9_]*)=(\S+)/
def export(location, options={})
error("Must specify a location") unless location
app = options[:app] || File.basename(engine.directory)
user = options[:user] || app
log_root = options[:log] || "/var/log/#{app}"
template_root = options[:template]
concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
run_template = export_template('runit', 'run.erb', template_root)
log_run_template = export_template('runit', 'log_run.erb', template_root)
engine.processes.each do |process|
engine.procfile.entries.each do |process|
1.upto(concurrency[process.name]) do |num|
process_directory = "#{location}/#{app}-#{process.name}-#{num}"
process_env_directory = "#{process_directory}/env"
process_log_directory = "#{process_directory}/log"
create_directory process_directory
create_directory process_env_directory
create_directory process_log_directory
run = ERB.new(run_template).result(binding)
write_file "#{process_directory}/run", run
port = engine.port_for(process, num, options[:port])
environment_variables = {'PORT' => port}.
merge(engine.environment).
merge(inline_variables(process.command))
environment_variables.each_pair do |var, env|
write_file "#{process_env_directory}/#{var.upcase}", env
end
log_run = ERB.new(log_run_template).result(binding)
write_file "#{process_log_directory}/run", log_run
end
end
end
private
def create_directory(location)
say "creating: #{location}"
FileUtils.mkdir(location)
end
def inline_variables(command)
variable_name_regex =
variable_name_regex =
Hash[*command.scan(ENV_VARIABLE_REGEX).flatten]
end
end
end
+1 -1
View File
@@ -26,7 +26,7 @@ class Foreman::Export::Upstart < Foreman::Export::Base
process_template = export_template("upstart", "process.conf.erb", template_root)
engine.processes.each do |process|
engine.procfile.entries.each do |process|
next if (conc = concurrency[process.name]) < 1
process_master_template = export_template("upstart", "process_master.conf.erb", template_root)
process_master_config = ERB.new(process_master_template).result(binding)
+19 -12
View File
@@ -5,24 +5,18 @@ class Foreman::Process
attr_reader :entry
attr_reader :num
attr_reader :pid
attr_reader :port
def initialize(entry, num)
def initialize(entry, num, port)
@entry = entry
@num = num
@port = port
end
def run(pipe, basedir, environment)
Dir.chdir(basedir) do
with_environment(environment) do
io = IO.popen(["/Users/david/Code/foreman/bin/runner", "#{entry.command}"], "w+")
@pid = io.pid
trap("SIGTERM") { "got sigterm for %d" % @pid }
output pipe, "started with pid %d" % @pid
Thread.new do
until io.eof?
output pipe, io.gets
end
end
with_environment(environment.merge("PORT" => port.to_s)) do
run_process entry.command
end
end
end
@@ -33,11 +27,24 @@ class Foreman::Process
private
def run_process(command)
io = IO.popen([Foreman.runner, replace_command_env(command)], "w+")
@pid = io.pid
trap("SIGTERM") { "got sigterm for %d" % @pid }
output pipe, "started with pid %d" % @pid
Thread.new do
until io.eof?
output pipe, io.gets
end
end
end
def output(pipe, message)
pipe.puts "%s,%s" % [ name, message ]
end
def replace_command
def replace_command_env(command)
command.gsub(/\$(\w+)/) { |e| ENV[e[1..-1]] }
end
def with_environment(environment)
+2 -2
View File
@@ -11,9 +11,9 @@ class Foreman::ProcfileEntry
@command = command
end
def spawn(num, pipe, basedir, environment)
def spawn(num, pipe, basedir, environment, base_port)
(1..num).to_a.map do |n|
process = Foreman::Process.new(self, n)
process = Foreman::Process.new(self, n, base_port + (n-1))
process.run(pipe, basedir, environment)
process
end