diff --git a/data/export/upstart/process.conf.erb b/data/export/upstart/process.conf.erb index fb7560c..e16ed3a 100644 --- a/data/export/upstart/process.conf.erb +++ b/data/export/upstart/process.conf.erb @@ -2,4 +2,4 @@ start on starting <%= app %>-<%= process.name %> stop on stopping <%= app %>-<%= process.name %> respawn -exec su - <%= user %> -c 'cd <%= engine.directory %>; export PORT=<%= port %>; <%= process.command %> >> <%= log_root %>/<%=process.name%>-<%=num%>.log 2>&1' +exec su - <%= user %> -c 'cd <%= engine.directory %>; export PORT=<%= port %>;<% engine.environment.each_pair do |var,env| %> export <%= var.upcase %>=<%= env %>; <% end %> <%= process.command %> >> <%= log_root %>/<%=process.name%>-<%=num%>.log 2>&1' diff --git a/lib/foreman/cli.rb b/lib/foreman/cli.rb index 042212b..e36d3b9 100644 --- a/lib/foreman/cli.rb +++ b/lib/foreman/cli.rb @@ -18,9 +18,9 @@ class Foreman::CLI < Thor check_procfile! if process - engine.execute(process, options) + engine.execute(process) else - engine.start(options) + engine.start end end @@ -64,7 +64,7 @@ private ###################################################################### end def engine - @engine ||= Foreman::Engine.new(procfile) + @engine ||= Foreman::Engine.new(procfile, options) end def procfile diff --git a/lib/foreman/engine.rb b/lib/foreman/engine.rb index 9e5eb1e..5cf82f3 100644 --- a/lib/foreman/engine.rb +++ b/lib/foreman/engine.rb @@ -11,14 +11,18 @@ class Foreman::Engine attr_reader :procfile attr_reader :directory + attr_reader :environment + attr_reader :options extend Term::ANSIColor COLORS = [ cyan, yellow, green, magenta, red ] - def initialize(procfile) + def initialize(procfile, options={}) @procfile = read_procfile(procfile) @directory = File.expand_path(File.dirname(procfile)) + @options = options + @environment = read_environment(options[:env]) end def processes @@ -50,13 +54,11 @@ class Foreman::Engine end end - def start(options={}) - environment = read_environment(options[:env]) - + def start proctitle "ruby: foreman master" processes_in_order.each do |name, process| - fork process, options, environment + fork process end trap("TERM") { puts "SIGTERM received"; terminate_gracefully } @@ -65,10 +67,9 @@ class Foreman::Engine watch_for_termination end - def execute(name, options={}) - environment = read_environment(options[:env]) + def execute(name) - fork processes[name], options, environment + fork processes[name] trap("TERM") { puts "SIGTERM received"; terminate_gracefully } trap("INT") { puts "SIGINT received"; terminate_gracefully } @@ -84,16 +85,16 @@ class Foreman::Engine private ###################################################################### - def fork(process, options={}, environment={}) - concurrency = Foreman::Utils.parse_concurrency(options[:concurrency]) + def fork(process) + concurrency = Foreman::Utils.parse_concurrency(@options[:concurrency]) 1.upto(concurrency[process.name]) do |num| - fork_individual(process, num, port_for(process, num, options[:port]), environment) + fork_individual(process, num, port_for(process, num, @options[:port])) end end - def fork_individual(process, num, port, environment) - environment.each { |k,v| ENV[k] = v } + def fork_individual(process, num, port) + @environment.each { |k,v| ENV[k] = v } ENV["PORT"] = port.to_s ENV["PS"] = "#{process.name}.#{num}" diff --git a/spec/foreman/cli_spec.rb b/spec/foreman/cli_spec.rb index 8858ee3..7663a12 100644 --- a/spec/foreman/cli_spec.rb +++ b/spec/foreman/cli_spec.rb @@ -19,7 +19,7 @@ describe "Foreman::CLI" do it "runs successfully" do dont_allow(subject).error - mock.instance_of(Foreman::Engine).start({}) + mock.instance_of(Foreman::Engine).start subject.start end end diff --git a/spec/foreman/engine_spec.rb b/spec/foreman/engine_spec.rb index 7e76f59..17273de 100644 --- a/spec/foreman/engine_spec.rb +++ b/spec/foreman/engine_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" require "foreman/engine" describe "Foreman::Engine" do - subject { Foreman::Engine.new("Procfile") } + subject { Foreman::Engine.new("Procfile", {}) } describe "initialize" do describe "without an existing Procfile" do @@ -37,53 +37,61 @@ describe "Foreman::Engine" do describe "start" do it "forks the processes" do write_procfile - mock(subject).fork(subject.processes["alpha"], {}, {}) - mock(subject).fork(subject.processes["bravo"], {}, {}) + mock(subject).fork(subject.processes["alpha"]) + mock(subject).fork(subject.processes["bravo"]) mock(subject).watch_for_termination subject.start end it "handles concurrency" do write_procfile - mock(subject).fork_individual(subject.processes["alpha"], 1, 5000, {}) - mock(subject).fork_individual(subject.processes["alpha"], 2, 5001, {}) - mock(subject).fork_individual(subject.processes["bravo"], 1, 5100, {}) - mock(subject).watch_for_termination - subject.start(:concurrency => "alpha=2") + engine = Foreman::Engine.new("Procfile",:concurrency => "alpha=2") + mock(engine).fork_individual(engine.processes["alpha"], 1, 5000) + mock(engine).fork_individual(engine.processes["alpha"], 2, 5001) + mock(engine).fork_individual(engine.processes["bravo"], 1, 5100) + mock(engine).watch_for_termination + engine.start end end describe "execute" do it "runs the processes" do write_procfile - mock(subject).fork(subject.processes["alpha"], {}, {}) + mock(subject).fork(subject.processes["alpha"]) mock(subject).watch_for_termination subject.execute("alpha") end end describe "environment" do + before(:each) do write_procfile stub(Process).fork - stub(subject).info - mock(subject).watch_for_termination end it "should read if specified" do File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") } - subject.execute("alpha", :env => "/tmp/env") + engine = Foreman::Engine.new("Procfile", :env => "/tmp/env") + stub(engine).info + mock(engine).watch_for_termination + engine.environment.should == {"FOO"=>"baz"} + engine.execute("alpha") end it "should fail if specified and doesnt exist" do - mock(subject).error("No such file: /tmp/env") - subject.execute("alpha", :env => "/tmp/env") + mock.instance_of(Foreman::Engine).error("No such file: /tmp/env") + engine = Foreman::Engine.new("Procfile", :env => "/tmp/env") end it "should read .env if none specified" do File.open(".env", "w") { |f| f.puts("FOO=qoo") } - mock(subject).fork_individual(anything, anything, anything, { "FOO" => "qoo" }) - subject.execute("bravo") + engine = Foreman::Engine.new("Procfile") + stub(engine).info + mock(engine).watch_for_termination + mock(engine).fork_individual(anything, anything, anything) + engine.environment.should == {"FOO"=>"qoo"} + engine.execute("bravo") end end end