From f668b87660eedc18ceec4419e37492cd13f8f5a6 Mon Sep 17 00:00:00 2001 From: David Dollar Date: Thu, 8 Dec 2011 14:04:29 -0800 Subject: [PATCH 1/5] wip --- lib/foreman/engine.rb | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/foreman/engine.rb b/lib/foreman/engine.rb index b4140d5..9d794ee 100644 --- a/lib/foreman/engine.rb +++ b/lib/foreman/engine.rb @@ -96,14 +96,23 @@ private ###################################################################### begin Dir.chdir directory do - PTY.spawn(process.command) do |stdin, stdout, pid| - trap("SIGTERM") { Process.kill("SIGTERM", pid) } - until stdin.eof? - info stdin.gets, process + IO.popen(process.command, "w+") do |pipe| + trap("SIGTERM") do + Thread.new do + begin + Process.kill("SIGTERM", pipe.pid) + Timeout.timeout(3) { Process.waitall } + rescue Timeout::Error + Process.kill("SIGKILL", pipe.pid) + end + end + end + until pipe.eof? + info pipe.gets, process end end end - rescue PTY::ChildExited, Interrupt, Errno::EIO, Errno::ENOENT + rescue Interrupt, Errno::EIO, Errno::ENOENT begin info "process exiting", process rescue Interrupt @@ -120,7 +129,7 @@ private ###################################################################### def terminate_gracefully info "sending SIGTERM to all processes" kill_all "SIGTERM" - Timeout.timeout(3) { Process.waitall } + Timeout.timeout(5) { Process.waitall } rescue Timeout::Error info "sending SIGKILL to all processes" kill_all "SIGKILL" From c5548a345ed9df05996d11b7e4ce79e314b4833b Mon Sep 17 00:00:00 2001 From: David Dollar Date: Thu, 8 Dec 2011 16:19:19 -0800 Subject: [PATCH 2/5] wip --- lib/foreman/engine.rb | 141 ++++++++++++++++------------------ lib/foreman/process.rb | 46 +++++++++-- lib/foreman/procfile.rb | 17 ++-- lib/foreman/procfile_entry.rb | 22 ++++++ 4 files changed, 138 insertions(+), 88 deletions(-) create mode 100644 lib/foreman/procfile_entry.rb diff --git a/lib/foreman/engine.rb b/lib/foreman/engine.rb index 9d794ee..991e2cc 100644 --- a/lib/foreman/engine.rb +++ b/lib/foreman/engine.rb @@ -23,6 +23,7 @@ class Foreman::Engine @directory = File.expand_path(File.dirname(procfile)) @options = options @environment = read_environment_files(options[:env]) + @output_mutex = Mutex.new end def self.load_env!(env_file) @@ -32,34 +33,17 @@ class Foreman::Engine def start proctitle "ruby: foreman master" - termtitle "#{File.basename(@directory)} - foreman (#{processes.size} processes)" - - processes.each do |process| - process.color = next_color - fork process - end + termtitle "#{File.basename(@directory)} - foreman" trap("TERM") { puts "SIGTERM received"; terminate_gracefully } trap("INT") { puts "SIGINT received"; terminate_gracefully } + assign_colors + spawn_processes + watch_for_output watch_for_termination end - def execute(name) - error "no such process: #{name}" unless process = procfile[name] - process.color = next_color - fork process - - trap("TERM") { puts "SIGTERM received"; terminate_gracefully } - trap("INT") { puts "SIGINT received"; terminate_gracefully } - - watch_for_termination - end - - def processes - procfile.processes - end - def port_for(process, num, base_port=nil) base_port ||= 5000 offset = procfile.process_names.index(process.name) * 100 @@ -68,60 +52,22 @@ class Foreman::Engine private ###################################################################### - def fork(process) + def spawn_processes concurrency = Foreman::Utils.parse_concurrency(@options[:concurrency]) - 1.upto(concurrency[process.name]) do |num| - fork_individual(process, num, port_for(process, num, @options[:port])) - end - end - - def fork_individual(process, num, port) - apply_environment! - - ENV["PORT"] = port.to_s - ENV["PS"] = "#{process.name}.#{num}" - - pid = Process.fork do - run(process) - end - - info "started with pid #{pid}", process - running_processes[pid] = process - end - - def run(process) - proctitle "ruby: foreman #{process.name}" - trap("SIGINT", "IGNORE") - - begin - Dir.chdir directory do - IO.popen(process.command, "w+") do |pipe| - trap("SIGTERM") do - Thread.new do - begin - Process.kill("SIGTERM", pipe.pid) - Timeout.timeout(3) { Process.waitall } - rescue Timeout::Error - Process.kill("SIGKILL", pipe.pid) - end - end - end - until pipe.eof? - info pipe.gets, process - end - end - end - rescue Interrupt, Errno::EIO, Errno::ENOENT - begin - info "process exiting", process - rescue Interrupt + procfile.entries.each do |entry| + reader, writer = IO.pipe + entry.spawn(concurrency[entry.name], writer, @directory, @environment).each do |process| + running_processes[process.pid] = process + readers[process] = reader end end end def kill_all(signal="SIGTERM") + p [:ff] running_processes.each do |pid, process| + p [:pid, pid] Process.kill(signal, pid) rescue Errno::ESRCH end end @@ -135,23 +81,53 @@ private ###################################################################### kill_all "SIGKILL" end + def watch_for_output + Thread.new do + begin + loop do + rs, ws = IO.select(readers.values, [], [], 1) + (rs || []).each do |r| + ps, message = r.gets.split(",", 2) + color = colors[ps.split(".").first] + info message, ps, color + end + end + rescue Exception => ex + puts ex.message + puts ex.backtrace + end + end + end + def watch_for_termination pid, status = Process.wait2 process = running_processes.delete(pid) - info "process terminated", process + info "process terminated", process.name terminate_gracefully kill_all rescue Errno::ECHILD end - def info(message, process=nil) - print process.color if process - print "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(process)} | " + def info(message, name="system", color=Term::ANSIColor.white) + print color + print "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | " print Term::ANSIColor.reset print message.chomp puts end + def print(message=nil) + @output_mutex.synchronize do + $stdout.print message + end + end + + def puts(message=nil) + @output_mutex.synchronize do + $stdout.puts message + end + end + def error(message) puts "ERROR: #{message}" exit 1 @@ -165,9 +141,8 @@ private ###################################################################### end end - def pad_process_name(process) - name = process ? "#{ENV["PS"]}" : "system" - name.ljust(longest_process_name + 3) # add 3 for process number padding + def pad_process_name(name="system") + name.to_s.ljust(longest_process_name + 3) # add 3 for process number padding end def proctitle(title) @@ -182,6 +157,24 @@ private ###################################################################### @running_processes ||= {} end + def readers + @readers ||= {} + end + + def colors + @colors ||= {} + end + + def assign_colors + procfile.entries.each do |entry| + colors[entry.name] = next_color + end + end + + def process_by_reader(reader) + readers.invert[reader] + end + def next_color @current_color ||= -1 @current_color += 1 diff --git a/lib/foreman/process.rb b/lib/foreman/process.rb index 939924f..8a3f6ab 100644 --- a/lib/foreman/process.rb +++ b/lib/foreman/process.rb @@ -2,13 +2,47 @@ require "foreman" class Foreman::Process - attr_reader :name - attr_reader :command - attr_accessor :color + attr_reader :entry + attr_reader :num + attr_reader :pid - def initialize(name, command) - @name = name - @command = command + def initialize(entry, num) + @entry = entry + @num = num + end + + def run(pipe, basedir, environment) + Dir.chdir(basedir) do + with_environment(environment) do + io = IO.popen("#{entry.command} 2>&1", "w+") + @pid = io.pid + output pipe, "started with pid %d" + Thread.new do + until io.eof? + output pipe, io.gets + end + end + end + end + end + + def name + "%s.%s" % [ entry.name, num ] + end + +private + + def output(pipe, message) + pipe.puts "%s,%s" % [ name, message ] + end + + def with_environment(environment) + old_env = ENV.each_pair.inject({}) { |h,(k,v)| h.update(k => v) } + environment.each { |k,v| ENV[k] = v } + ret = yield + ENV.clear + old_env.each { |k,v| ENV[k] = v} + ret end end diff --git a/lib/foreman/procfile.rb b/lib/foreman/procfile.rb index f169e4a..e630275 100644 --- a/lib/foreman/procfile.rb +++ b/lib/foreman/procfile.rb @@ -1,4 +1,5 @@ require "foreman" +require "foreman/procfile_entry" # A valid Procfile entry is captured by this regex. # All other lines are ignored. @@ -10,18 +11,18 @@ require "foreman" # class Foreman::Procfile - attr_reader :processes + attr_reader :entries def initialize(filename) - @processes = parse_procfile(filename) - end - - def process_names - processes.map(&:name) + @entries = parse_procfile(filename) end def [](name) - processes.detect { |process| process.name == name } + entries.detect { |entry| entry.name == name } + end + + def process_names + entries.map(&:name) end private @@ -29,7 +30,7 @@ private def parse_procfile(filename) File.read(filename).split("\n").map do |line| if line =~ /^([A-Za-z0-9_]+):\s*(.+)$/ - Foreman::Process.new($1, $2) + Foreman::ProcfileEntry.new($1, $2) end end.compact end diff --git a/lib/foreman/procfile_entry.rb b/lib/foreman/procfile_entry.rb new file mode 100644 index 0000000..a7fd4f1 --- /dev/null +++ b/lib/foreman/procfile_entry.rb @@ -0,0 +1,22 @@ +require "foreman" + +class Foreman::ProcfileEntry + + attr_reader :name + attr_reader :command + attr_accessor :color + + def initialize(name, command) + @name = name + @command = command + end + + def spawn(num, pipe, basedir, environment) + (1..num).to_a.map do |n| + process = Foreman::Process.new(self, n) + process.run(pipe, basedir, environment) + process + end + end + +end From 6e95d1ce9486eef6a5de6a02eb3f6cc8747a3d81 Mon Sep 17 00:00:00 2001 From: David Dollar Date: Thu, 8 Dec 2011 16:57:33 -0800 Subject: [PATCH 3/5] wip --- lib/foreman/engine.rb | 3 +-- lib/foreman/process.rb | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/foreman/engine.rb b/lib/foreman/engine.rb index 991e2cc..5d0d75e 100644 --- a/lib/foreman/engine.rb +++ b/lib/foreman/engine.rb @@ -65,9 +65,8 @@ private ###################################################################### end def kill_all(signal="SIGTERM") - p [:ff] running_processes.each do |pid, process| - p [:pid, pid] + p [:killing, pid] Process.kill(signal, pid) rescue Errno::ESRCH end end diff --git a/lib/foreman/process.rb b/lib/foreman/process.rb index 8a3f6ab..fc75f32 100644 --- a/lib/foreman/process.rb +++ b/lib/foreman/process.rb @@ -14,9 +14,9 @@ class Foreman::Process def run(pipe, basedir, environment) Dir.chdir(basedir) do with_environment(environment) do - io = IO.popen("#{entry.command} 2>&1", "w+") + io = IO.popen("#{entry.command} $FOO 2>&1", "w+") @pid = io.pid - output pipe, "started with pid %d" + output pipe, "started with pid %d" % @pid Thread.new do until io.eof? output pipe, io.gets From c9411cd2b14a4269cdbeaa62c83cb23cc1348c53 Mon Sep 17 00:00:00 2001 From: David Dollar Date: Thu, 8 Dec 2011 17:18:21 -0800 Subject: [PATCH 4/5] wip --- bin/runner | 5 +++++ lib/foreman/process.rb | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100755 bin/runner diff --git a/bin/runner b/bin/runner new file mode 100755 index 0000000..80fabc9 --- /dev/null +++ b/bin/runner @@ -0,0 +1,5 @@ +#!/bin/sh + +echo "command[$*][$1]" + +exec $1 2>&1 diff --git a/lib/foreman/process.rb b/lib/foreman/process.rb index fc75f32..71b8e74 100644 --- a/lib/foreman/process.rb +++ b/lib/foreman/process.rb @@ -14,8 +14,9 @@ class Foreman::Process def run(pipe, basedir, environment) Dir.chdir(basedir) do with_environment(environment) do - io = IO.popen("#{entry.command} $FOO 2>&1", "w+") + 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? @@ -36,6 +37,9 @@ private pipe.puts "%s,%s" % [ name, message ] end + def replace_command + end + def with_environment(environment) old_env = ENV.each_pair.inject({}) { |h,(k,v)| h.update(k => v) } environment.each { |k,v| ENV[k] = v } From 5436b68cf158ee2a8209399d669847fda4c5f336 Mon Sep 17 00:00:00 2001 From: David Dollar Date: Thu, 8 Dec 2011 17:53:13 -0800 Subject: [PATCH 5/5] wip --- bin/runner | 3 -- data/export/bluepill/master.pill.erb | 4 +-- lib/foreman.rb | 5 ++++ lib/foreman/cli.rb | 15 ++++------ lib/foreman/engine.rb | 7 +++-- lib/foreman/export/inittab.rb | 2 +- lib/foreman/export/runit.rb | 32 ++++++++++----------- lib/foreman/export/upstart.rb | 2 +- lib/foreman/process.rb | 31 +++++++++++++-------- lib/foreman/procfile_entry.rb | 4 +-- spec/foreman/engine_spec.rb | 37 ++++++++----------------- spec/foreman/export/bluepill_spec.rb | 3 +- spec/resources/export/bluepill/app.pill | 6 ++-- 13 files changed, 72 insertions(+), 79 deletions(-) diff --git a/bin/runner b/bin/runner index 80fabc9..69011a5 100755 --- a/bin/runner +++ b/bin/runner @@ -1,5 +1,2 @@ #!/bin/sh - -echo "command[$*][$1]" - exec $1 2>&1 diff --git a/data/export/bluepill/master.pill.erb b/data/export/bluepill/master.pill.erb index fbe11e1..2b56d9d 100644 --- a/data/export/bluepill/master.pill.erb +++ b/data/export/bluepill/master.pill.erb @@ -3,7 +3,7 @@ Bluepill.application("<%= app %>", :foreground => false, :log_file => "/var/log/ app.uid = "<%= user %>" app.gid = "<%= user %>" -<% engine.processes.each do |process| %> +<% engine.procfile.entries.each do |process| %> <% 1.upto(concurrency[process.name]) do |num| %> <% port = engine.port_for(process, num, options[:port]) %> app.process("<%= process.name %>-<%=num%>") do |process| @@ -19,7 +19,7 @@ Bluepill.application("<%= app %>", :foreground => false, :log_file => "/var/log/ process.monitor_children do |children| children.stop_command "kill -QUIT {{PID}}" end - + process.group = "<%= app %>-<%= process.name %>" end <% end %> diff --git a/lib/foreman.rb b/lib/foreman.rb index 422bdd4..3c8f011 100644 --- a/lib/foreman.rb +++ b/lib/foreman.rb @@ -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 diff --git a/lib/foreman/cli.rb b/lib/foreman/cli.rb index a32e156..0e82a04 100644 --- a/lib/foreman/cli.rb +++ b/lib/foreman/cli.rb @@ -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 ###################################################################### diff --git a/lib/foreman/engine.rb b/lib/foreman/engine.rb index 5d0d75e..1e622dc 100644 --- a/lib/foreman/engine.rb +++ b/lib/foreman/engine.rb @@ -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 diff --git a/lib/foreman/export/inittab.rb b/lib/foreman/export/inittab.rb index 8dd4811..e8fb7a8 100644 --- a/lib/foreman/export/inittab.rb +++ b/lib/foreman/export/inittab.rb @@ -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]) diff --git a/lib/foreman/export/runit.rb b/lib/foreman/export/runit.rb index 43807ab..bc7a5f5 100644 --- a/lib/foreman/export/runit.rb +++ b/lib/foreman/export/runit.rb @@ -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 \ No newline at end of file +end diff --git a/lib/foreman/export/upstart.rb b/lib/foreman/export/upstart.rb index 47f8df4..9ae9717 100644 --- a/lib/foreman/export/upstart.rb +++ b/lib/foreman/export/upstart.rb @@ -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) diff --git a/lib/foreman/process.rb b/lib/foreman/process.rb index 71b8e74..f505584 100644 --- a/lib/foreman/process.rb +++ b/lib/foreman/process.rb @@ -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) diff --git a/lib/foreman/procfile_entry.rb b/lib/foreman/procfile_entry.rb index a7fd4f1..1d2223d 100644 --- a/lib/foreman/procfile_entry.rb +++ b/lib/foreman/procfile_entry.rb @@ -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 diff --git a/spec/foreman/engine_spec.rb b/spec/foreman/engine_spec.rb index 7e60100..42dc939 100644 --- a/spec/foreman/engine_spec.rb +++ b/spec/foreman/engine_spec.rb @@ -24,8 +24,9 @@ describe "Foreman::Engine" do describe "start" do it "forks the processes" do write_procfile - mock(subject).fork(subject.procfile["alpha"]) - mock(subject).fork(subject.procfile["bravo"]) + mock.instance_of(Foreman::Process).run_process("./alpha") + mock.instance_of(Foreman::Process).run_process("./bravo") + mock(subject).watch_for_output mock(subject).watch_for_termination subject.start end @@ -33,29 +34,14 @@ describe "Foreman::Engine" do it "handles concurrency" do write_procfile engine = Foreman::Engine.new("Procfile",:concurrency => "alpha=2") - mock(engine).fork_individual(engine.procfile["alpha"], 1, 5000) - mock(engine).fork_individual(engine.procfile["alpha"], 2, 5001) - mock(engine).fork_individual(engine.procfile["bravo"], 1, 5100) + mock.instance_of(Foreman::Process).run_process("./alpha").twice + mock.instance_of(Foreman::Process).run_process("./bravo") + mock(engine).watch_for_output mock(engine).watch_for_termination engine.start end end - describe "execute" do - it "runs the processes" do - write_procfile - mock(subject).fork(subject.procfile["alpha"]) - mock(subject).watch_for_termination - subject.execute("alpha") - end - - it "shows an error running a process that doesnt exist" do - write_procfile - mock(subject).puts("ERROR: no such process: foo") - lambda { subject.execute("foo") }.should raise_error(SystemExit) - end - end - describe "environment" do before(:each) do write_procfile @@ -66,9 +52,10 @@ describe "Foreman::Engine" do File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") } engine = Foreman::Engine.new("Procfile", :env => "/tmp/env") stub(engine).info + mock(engine).spawn_processes mock(engine).watch_for_termination engine.environment.should == {"FOO"=>"baz"} - engine.execute("alpha") + engine.start end it "should read more than one if specified" do @@ -76,9 +63,10 @@ describe "Foreman::Engine" do File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") } engine = Foreman::Engine.new("Procfile", :env => "/tmp/env1,/tmp/env2") stub(engine).info + mock(engine).spawn_processes mock(engine).watch_for_termination engine.environment.should == { "FOO"=>"bar", "BAZ"=>"qux" } - engine.execute("alpha") + engine.start end it "should fail if specified and doesnt exist" do @@ -89,11 +77,10 @@ describe "Foreman::Engine" do it "should read .env if none specified" do File.open(".env", "w") { |f| f.puts("FOO=qoo") } engine = Foreman::Engine.new("Procfile") - stub(engine).info + mock(engine).spawn_processes mock(engine).watch_for_termination - mock(engine).fork_individual(anything, anything, anything) engine.environment.should == {"FOO"=>"qoo"} - engine.execute("bravo") + engine.start end end end diff --git a/spec/foreman/export/bluepill_spec.rb b/spec/foreman/export/bluepill_spec.rb index dd71d87..b90536c 100644 --- a/spec/foreman/export/bluepill_spec.rb +++ b/spec/foreman/export/bluepill_spec.rb @@ -13,8 +13,7 @@ describe Foreman::Export::Bluepill do it "exports to the filesystem" do bluepill.export("/tmp/init", :concurrency => "alpha=2") - File.read("/tmp/init/app.pill").should == example_export_file("bluepill/app.pill") end -end \ No newline at end of file +end diff --git a/spec/resources/export/bluepill/app.pill b/spec/resources/export/bluepill/app.pill index bef2f13..6916f9e 100644 --- a/spec/resources/export/bluepill/app.pill +++ b/spec/resources/export/bluepill/app.pill @@ -19,7 +19,7 @@ Bluepill.application("app", :foreground => false, :log_file => "/var/log/bluepil process.monitor_children do |children| children.stop_command "kill -QUIT {{PID}}" end - + process.group = "app-alpha" end @@ -37,7 +37,7 @@ Bluepill.application("app", :foreground => false, :log_file => "/var/log/bluepil process.monitor_children do |children| children.stop_command "kill -QUIT {{PID}}" end - + process.group = "app-alpha" end @@ -57,7 +57,7 @@ Bluepill.application("app", :foreground => false, :log_file => "/var/log/bluepil process.monitor_children do |children| children.stop_command "kill -QUIT {{PID}}" end - + process.group = "app-bravo" end