foreman 0.50.0-mingw32 → 0.61.0-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  #!/bin/sh
2
2
  #
3
- #/ Usage: foreman-runner [-d <dir>] <command> [<args>...]
3
+ #/ Usage: foreman-runner [-d <dir>] [-p] <command> [<args>...]
4
4
  #/
5
5
  #/ Run a command with exec, optionally changing directory first
6
6
 
@@ -16,9 +16,12 @@ usage() {
16
16
  exit
17
17
  }
18
18
 
19
- while getopts ":hd:" OPT; do
19
+ read_profile=""
20
+
21
+ while getopts ":hd:p" OPT; do
20
22
  case $OPT in
21
23
  d) cd "$OPTARG" ;;
24
+ p) read_profile="1" ;;
22
25
  h) usage ;;
23
26
  \?) error "invalid option: -$OPTARG" ;;
24
27
  :) error "option -$OPTARG requires an argument" ;;
@@ -29,4 +32,10 @@ shift $((OPTIND-1))
29
32
 
30
33
  [ -z "$1" ] && usage
31
34
 
35
+ if [ "$read_profile" = "1" ]; then
36
+ if [ -f .profile ]; then
37
+ . .profile
38
+ fi
39
+ fi
40
+
32
41
  exec "$@"
@@ -4,14 +4,25 @@
4
4
  <dict>
5
5
  <key>Label</key>
6
6
  <string><%= "#{app}-#{name}-#{num}" %></string>
7
+ <key>EnvironmentVariables</key>
8
+ <dict>
9
+ <%- engine.env.merge("PORT" => port).each_pair do |var,env| -%>
10
+ <key><%= var.upcase %></key>
11
+ <string><%= env %></string>
12
+ <%- end -%>
13
+ </dict>
7
14
  <key>ProgramArguments</key>
8
15
  <array>
9
- <string><%= process.command %></string>
16
+ <%- command_args.each do |command| -%>
17
+ <string><%= command %></string>
18
+ <%- end -%>
10
19
  </array>
11
20
  <key>KeepAlive</key>
12
21
  <true/>
13
22
  <key>RunAtLoad</key>
14
23
  <true/>
24
+ <key>StandardOutPath</key>
25
+ <string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
15
26
  <key>StandardErrorPath</key>
16
27
  <string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
17
28
  <key>UserName</key>
@@ -6,3 +6,11 @@ bash << "EOF"
6
6
  EOF
7
7
 
8
8
  end script
9
+
10
+ start on (started network-interface
11
+ or started network-manager
12
+ or started networking)
13
+
14
+ stop on (stopping network-interface
15
+ or stopping network-manager
16
+ or stopping networking)
@@ -8,8 +8,8 @@ module Foreman
8
8
  File.expand_path("../../bin/foreman-runner", __FILE__)
9
9
  end
10
10
 
11
- def self.jruby?
12
- defined?(RUBY_PLATFORM) and RUBY_PLATFORM == "java"
11
+ def self.jruby_18?
12
+ defined?(RUBY_PLATFORM) and RUBY_PLATFORM == "java" and ruby_18?
13
13
  end
14
14
 
15
15
  def self.ruby_18?
@@ -0,0 +1,54 @@
1
+ if defined?(Capistrano)
2
+ Capistrano::Configuration.instance(:must_exist).load do
3
+
4
+ namespace :foreman do
5
+ desc <<-DESC
6
+ Export the Procfile to upstart. Will use sudo if available.
7
+
8
+ You can override any of these defaults by setting the variables shown below.
9
+
10
+ set :foreman_format, "upstart"
11
+ set :foreman_location, "/etc/init"
12
+ set :foreman_procfile, "Procfile"
13
+ set :foreman_app, application
14
+ set :foreman_user, user
15
+ set :foreman_log, 'shared_path/log'
16
+ set :foreman_concurrency, false
17
+ DESC
18
+ task :export, :roles => :app do
19
+ bundle_cmd = fetch(:bundle_cmd, "bundle")
20
+ foreman_format = fetch(:foreman_format, "upstart")
21
+ foreman_location = fetch(:foreman_location, "/etc/init")
22
+ foreman_procfile = fetch(:foreman_procfile, "Procfile")
23
+ foreman_app = fetch(:foreman_app, application)
24
+ foreman_user = fetch(:foreman_user, user)
25
+ foreman_log = fetch(:foreman_log, "#{shared_path}/log")
26
+ foreman_concurrency = fetch(:foreman_concurrency, false)
27
+
28
+ args = ["#{foreman_format} #{foreman_location}"]
29
+ args << "-f #{foreman_procfile}"
30
+ args << "-a #{foreman_app}"
31
+ args << "-u #{foreman_user}"
32
+ args << "-l #{foreman_log}"
33
+ args << "-c #{foreman_concurrency}" if foreman_concurrency
34
+ run "cd #{release_path} && #{sudo} #{bundle_cmd} exec foreman export #{args.join(' ')}"
35
+ end
36
+
37
+ desc "Start the application services"
38
+ task :start, :roles => :app do
39
+ run "#{sudo} start #{application}"
40
+ end
41
+
42
+ desc "Stop the application services"
43
+ task :stop, :roles => :app do
44
+ run "#{sudo} stop #{application}"
45
+ end
46
+
47
+ desc "Restart the application services"
48
+ task :restart, :roles => :app do
49
+ run "#{sudo} start #{application} || #{sudo} restart #{application}"
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -23,6 +23,7 @@ class Foreman::CLI < Thor
23
23
  method_option :env, :type => :string, :aliases => "-e", :desc => "Specify an environment file to load, defaults to .env"
24
24
  method_option :formation, :type => :string, :aliases => "-m", :banner => '"alpha=5,bar=3"'
25
25
  method_option :port, :type => :numeric, :aliases => "-p"
26
+ method_option :timeout, :type => :numeric, :aliases => "-t", :desc => "Specify the amount of time (in seconds) processes have to shudown gracefully before receiving a SIGKILL, defaults to 5."
26
27
 
27
28
  class << self
28
29
  # Hackery. Take the run method away from Thor so that we can redefine it.
@@ -75,13 +76,27 @@ class Foreman::CLI < Thor
75
76
 
76
77
  def run(*args)
77
78
  load_environment!
78
- begin
79
- exec engine.env, args.shelljoin
80
- rescue Errno::EACCES
81
- error "not executable: #{args.first}"
82
- rescue Errno::ENOENT
83
- error "command not found: #{args.first}"
79
+
80
+ if File.exist?(procfile)
81
+ engine.load_procfile(procfile)
82
+ end
83
+
84
+ pid = fork do
85
+ begin
86
+ engine.env.each { |k,v| ENV[k] = v }
87
+ if args.size == 1 && process = engine.process(args.first)
88
+ process.exec(:env => engine.env)
89
+ else
90
+ exec args.shelljoin
91
+ end
92
+ rescue Errno::EACCES
93
+ error "not executable: #{args.first}"
94
+ rescue Errno::ENOENT
95
+ error "command not found: #{args.first}"
96
+ end
84
97
  end
98
+ Process.wait(pid)
99
+ exit $?.exitstatus
85
100
  end
86
101
 
87
102
  desc "version", "Display Foreman gem version"
@@ -125,7 +140,7 @@ private ######################################################################
125
140
  def procfile
126
141
  case
127
142
  when options[:procfile] then options[:procfile]
128
- when options[:root] then File.expand_path(File.join(options[:app_root], "Procfile"))
143
+ when options[:root] then File.expand_path(File.join(options[:root], "Procfile"))
129
144
  else "Procfile"
130
145
  end
131
146
  end
@@ -25,6 +25,7 @@ class Foreman::Engine
25
25
  @options = options.dup
26
26
 
27
27
  @options[:formation] ||= (options[:concurrency] || "all=1")
28
+ @options[:timeout] ||= 5
28
29
 
29
30
  @env = {}
30
31
  @mutex = Mutex.new
@@ -37,6 +38,9 @@ class Foreman::Engine
37
38
  # Start the processes registered to this +Engine+
38
39
  #
39
40
  def start
41
+ # Make sure foreman is the process group leader.
42
+ Process.setpgrp unless Foreman.windows?
43
+
40
44
  trap("TERM") { puts "SIGTERM received"; terminate_gracefully }
41
45
  trap("INT") { puts "SIGINT received"; terminate_gracefully }
42
46
  trap("HUP") { puts "SIGHUP received"; terminate_gracefully } if ::Signal.list.keys.include? 'HUP'
@@ -109,7 +113,7 @@ class Foreman::Engine
109
113
  end
110
114
  else
111
115
  begin
112
- Process.kill "-#{signal}", Process.pid
116
+ Process.kill "-#{signal}", Process.getpgrp
113
117
  rescue Errno::ESRCH, Errno::EPERM
114
118
  end
115
119
  end
@@ -256,7 +260,9 @@ private
256
260
  1.upto(formation[@names[process]]) do |n|
257
261
  reader, writer = create_pipe
258
262
  begin
259
- pid = process.run(:output => writer, :env => { "PORT" => port_for(process, n).to_s })
263
+ pid = process.run(:output => writer, :env => {
264
+ "PORT" => port_for(process, n).to_s
265
+ })
260
266
  writer.puts "started with pid #{pid}"
261
267
  rescue Errno::ENOENT
262
268
  writer.puts "unknown command: #{process.command}"
@@ -271,9 +277,14 @@ private
271
277
  Thread.new do
272
278
  begin
273
279
  loop do
274
- (IO.select(@readers.values).first || []).each do |reader|
275
- data = reader.gets
276
- output_with_mutex name_for(@readers.invert[reader]), data
280
+ io = IO.select(@readers.values, nil, nil, 30)
281
+ (io.nil? ? [] : io.first).each do |reader|
282
+ if reader.eof?
283
+ @readers.delete_if { |key, value| value == reader }
284
+ else
285
+ data = reader.gets
286
+ output_with_mutex name_for(@readers.invert[reader]), data
287
+ end
277
288
  end
278
289
  end
279
290
  rescue Exception => ex
@@ -302,7 +313,7 @@ private
302
313
  system "sending SIGTERM to all processes"
303
314
  killall "SIGTERM"
304
315
  end
305
- Timeout.timeout(5) do
316
+ Timeout.timeout(options[:timeout]) do
306
317
  watch_for_termination while @running.length > 0
307
318
  end
308
319
  rescue Timeout::Error
@@ -31,7 +31,7 @@ class Foreman::Engine::CLI < Foreman::Engine
31
31
 
32
32
  def color?
33
33
  return true if @@color_force
34
- return true if Foreman.windows?
34
+ return false if Foreman.windows?
35
35
  return false unless self.respond_to?(:isatty)
36
36
  self.isatty && ENV["TERM"]
37
37
  end
@@ -44,18 +44,17 @@ class Foreman::Engine::CLI < Foreman::Engine
44
44
 
45
45
  end
46
46
 
47
- FOREMAN_COLORS = %w( cyan yellow green magenta red blue intense_cyan intense_yellow
48
- intense_green intense_magenta intense_red, intense_blue )
47
+ FOREMAN_COLORS = %w( cyan yellow green magenta red blue bright_cyan bright_yellow
48
+ bright_green bright_magenta bright_red bright_blue )
49
49
 
50
50
  def startup
51
51
  @colors = map_colors
52
- proctitle "foreman: master"
53
- require "win32console" if Foreman.windows?
54
- Color.enable($stdout, options[:color]) unless $stdout.respond_to?(:color?)
52
+ proctitle "foreman: master" unless Foreman.windows?
53
+ Color.enable($stdout, options[:color])
55
54
  end
56
55
 
57
56
  def output(name, data)
58
- data.to_s.chomp.split("\n").each do |message|
57
+ data.to_s.lines.map(&:chomp).each do |message|
59
58
  output = ""
60
59
  output += $stdout.color(@colors[name.split(".").first].to_sym)
61
60
  output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
@@ -90,7 +89,7 @@ private
90
89
  @names.values.each_with_index do |name, index|
91
90
  colors[name] = FOREMAN_COLORS[index % FOREMAN_COLORS.length]
92
91
  end
93
- colors["system"] = "intense_white"
92
+ colors["system"] = "bright_white"
94
93
  colors
95
94
  end
96
95
 
@@ -5,12 +5,14 @@ class Foreman::Env
5
5
  attr_reader :entries
6
6
 
7
7
  def initialize(filename)
8
- @entries = File.read(filename).split("\n").inject({}) do |ax, line|
8
+ @entries = File.read(filename).gsub("\r\n","\n").split("\n").inject({}) do |ax, line|
9
9
  if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
10
10
  key = $1
11
11
  case val = $2
12
+ # Remove single quotes
12
13
  when /\A'(.*)'\z/ then ax[key] = $1
13
- when /\A"(.*)"\z/ then ax[key] = $1.gsub(/\\(.)/, '\1')
14
+ # Remove double quotes and unescape string preserving newline characters
15
+ when /\A"(.*)"\z/ then ax[key] = $1.gsub('\n', "\n").gsub(/\\(.)/, '\1')
14
16
  else ax[key] = val
15
17
  end
16
18
  end
@@ -91,7 +91,7 @@ private ######################################################################
91
91
  end
92
92
 
93
93
  def shell_quote(value)
94
- '"' + Shellwords.escape(value) + '"'
94
+ Shellwords.escape(value)
95
95
  end
96
96
 
97
97
  # deprecated
@@ -119,7 +119,7 @@ private ######################################################################
119
119
  end
120
120
 
121
121
  def write_template(name, target, binding)
122
- compiled = ERB.new(export_template(name)).result(binding)
122
+ compiled = ERB.new(export_template(name), nil, '-').result(binding)
123
123
  write_file target, compiled
124
124
  end
125
125
 
@@ -13,7 +13,16 @@ class Foreman::Export::Inittab < Foreman::Export::Base
13
13
  1.upto(engine.formation[name]) do |num|
14
14
  id = app.slice(0, 2).upcase + sprintf("%02d", index)
15
15
  port = engine.port_for(process, num)
16
- inittab << "#{id}:4:respawn:/bin/su - #{user} -c 'PORT=#{port} #{process.command} >> #{log}/#{name}-#{num}.log 2>&1'"
16
+
17
+ commands = []
18
+ commands << "cd #{engine.root}"
19
+ commands << "export PORT=#{port}"
20
+ engine.env.each_pair do |var, env|
21
+ commands << "export #{var.upcase}=#{shell_quote(env)}"
22
+ end
23
+ commands << "#{process.command} >> #{log}/#{name}-#{num}.log 2>&1"
24
+
25
+ inittab << "#{id}:4:respawn:/bin/su - #{user} -c '#{commands.join(";")}'"
17
26
  index += 1
18
27
  end
19
28
  end
@@ -7,6 +7,8 @@ class Foreman::Export::Launchd < Foreman::Export::Base
7
7
  super
8
8
  engine.each_process do |name, process|
9
9
  1.upto(engine.formation[name]) do |num|
10
+ port = engine.port_for(process, num)
11
+ command_args = process.command.split(" ")
10
12
  write_template "launchd/launchd.plist.erb", "#{app}-#{name}-#{num}.plist", binding
11
13
  end
12
14
  end
@@ -1,5 +1,4 @@
1
1
  require "foreman"
2
- require "rubygems"
3
2
 
4
3
  class Foreman::Process
5
4
 
@@ -21,6 +20,21 @@ class Foreman::Process
21
20
  @options[:env] ||= {}
22
21
  end
23
22
 
23
+ # Get environment-expanded command for a +Process+
24
+ #
25
+ # @param [Hash] custom_env ({}) Environment variables to merge with defaults
26
+ #
27
+ # @return [String] The expanded command
28
+ #
29
+ def expanded_command(custom_env={})
30
+ env = @options[:env].merge(custom_env)
31
+ expanded_command = command.dup
32
+ env.each do |key, val|
33
+ expanded_command.gsub!("$#{key}", val)
34
+ end
35
+ expanded_command
36
+ end
37
+
24
38
  # Run a +Process+
25
39
  #
26
40
  # @param [Hash] options
@@ -31,38 +45,45 @@ class Foreman::Process
31
45
  # @returns [Fixnum] pid The +pid+ of the process
32
46
  #
33
47
  def run(options={})
34
- env = options[:env] ? @options[:env].merge(options[:env]) : @options[:env]
48
+ env = @options[:env].merge(options[:env] || {})
35
49
  output = options[:output] || $stdout
36
50
 
37
51
  if Foreman.windows?
38
52
  Dir.chdir(cwd) do
39
- expanded_command = command.dup
40
- env.each do |key, val|
41
- expanded_command.gsub!("$#{key}", val)
42
- end
43
- Process.spawn env, expanded_command, :out => output, :err => output
44
- end
45
- elsif Foreman.jruby?
46
- Dir.chdir(cwd) do
47
- require "posix/spawn"
48
- POSIX::Spawn.spawn env, command, :out => output, :err => output
53
+ Process.spawn env, expanded_command(env), :out => output, :err => output
49
54
  end
55
+ elsif Foreman.jruby_18?
56
+ require "posix/spawn"
57
+ wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
58
+ POSIX::Spawn.spawn env, wrapped_command, :out => output, :err => output
50
59
  elsif Foreman.ruby_18?
51
- Dir.chdir(cwd) do
52
- fork do
53
- $stdout.reopen output
54
- $stderr.reopen output
55
- env.each { |k,v| ENV[k] = v }
56
- exec command
57
- end
60
+ fork do
61
+ $stdout.reopen output
62
+ $stderr.reopen output
63
+ env.each { |k,v| ENV[k] = v }
64
+ wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
65
+ Kernel.exec wrapped_command
58
66
  end
59
67
  else
60
- Dir.chdir(cwd) do
61
- Process.spawn env, command, :out => output, :err => output
62
- end
68
+ wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
69
+ Process.spawn env, wrapped_command, :out => output, :err => output
63
70
  end
64
71
  end
65
72
 
73
+ # Exec a +Process+
74
+ #
75
+ # @param [Hash] options
76
+ #
77
+ # @option options :env ({}) Environment variables to set for this execution
78
+ #
79
+ # @return Does not return
80
+ def exec(options={})
81
+ env = @options[:env].merge(options[:env] || {})
82
+ env.each { |k, v| ENV[k] = v }
83
+ Dir.chdir(cwd)
84
+ Kernel.exec expanded_command(env)
85
+ end
86
+
66
87
  # Send a signal to this +Process+
67
88
  #
68
89
  # @param [String] signal The signal to send
@@ -93,10 +114,12 @@ class Foreman::Process
93
114
  !alive?
94
115
  end
95
116
 
96
- private
97
-
117
+ # Returns the working directory for this +Process+
118
+ #
119
+ # @returns [String]
120
+ #
98
121
  def cwd
99
- @options[:cwd] || "."
122
+ File.expand_path(@options[:cwd] || ".")
100
123
  end
101
124
 
102
125
  end
@@ -82,7 +82,7 @@ class Foreman::Procfile
82
82
  private
83
83
 
84
84
  def parse(filename)
85
- File.read(filename).split("\n").map do |line|
85
+ File.read(filename).gsub("\r\n","\n").split("\n").map do |line|
86
86
  if line =~ /^([A-Za-z0-9_]+):\s*(.+)$/
87
87
  [$1, $2]
88
88
  end
@@ -1,5 +1,5 @@
1
1
  module Foreman
2
2
 
3
- VERSION = "0.50.0"
3
+ VERSION = "0.61.0"
4
4
 
5
5
  end
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "FOREMAN" "1" "July 2012" "Foreman 0.50.0" "Foreman Manual"
4
+ .TH "FOREMAN" "1" "January 2013" "Foreman 0.61.0" "Foreman Manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBforeman\fR \- manage Procfile\-based applications
@@ -90,7 +90,7 @@ Specify the user the application should be run as\. Defaults to the app name
90
90
  These options control all modes of foreman\'s operation\.
91
91
  .
92
92
  .TP
93
- \fB\-d\fR, \fB\-\-directory\fR
93
+ \fB\-d\fR, \fB\-\-root\fR
94
94
  Specify an alternate application root\. This defaults to the directory containing the Procfile\.
95
95
  .
96
96
  .TP
@@ -72,6 +72,15 @@ describe "Foreman::CLI", :fakefs do
72
72
  it "includes the environment" do
73
73
  forked_foreman("run #{resource_path("bin/env FOO")} -e #{resource_path(".env")}").should == "bar\n"
74
74
  end
75
+
76
+ it "can run a command from the Procfile" do
77
+ forked_foreman("run -f #{resource_path("Procfile")} test").should == "testing\n"
78
+ end
79
+
80
+ it "exits with the same exit code as the command" do
81
+ fork_and_get_exitstatus("run echo 1").should == 0
82
+ fork_and_get_exitstatus("run date 'invalid_date'").should == 1
83
+ end
75
84
  end
76
85
 
77
86
  describe "version" do
@@ -90,6 +90,14 @@ describe "Foreman::Engine", :fakefs do
90
90
  subject.env["OTHER"].should == 'escaped"quote'
91
91
  end
92
92
 
93
+ it "should handle multiline strings" do
94
+ File.open("/tmp/env", "w") do |f|
95
+ f.puts 'FOO="bar\nbaz"'
96
+ end
97
+ subject.load_env "/tmp/env"
98
+ subject.env["FOO"].should == "bar\nbaz"
99
+ end
100
+
93
101
  it "should fail if specified and doesnt exist" do
94
102
  lambda { subject.load_env "/tmp/env" }.should raise_error(Errno::ENOENT)
95
103
  end
@@ -18,4 +18,14 @@ describe Foreman::Export::Launchd, :fakefs do
18
18
  File.read("/tmp/init/app-bravo-1.plist").should == example_export_file("launchd/launchd-b.default")
19
19
  end
20
20
 
21
+ context "with multiple command arguments" do
22
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", "charlie") }
23
+
24
+ it "splits each command argument" do
25
+ launchd.export
26
+ File.read("/tmp/init/app-alpha-1.plist").should == example_export_file("launchd/launchd-c.default")
27
+ end
28
+
29
+ end
30
+
21
31
  end
@@ -38,7 +38,7 @@ describe Foreman::Export::Upstart, :fakefs do
38
38
  engine.env['KEY'] = 'd"\|d'
39
39
  upstart.export
40
40
  "foobarfoo".should include "bar"
41
- File.read("/tmp/init/app-alpha-1.conf").should =~ /KEY="d\\"\\\\\\\|d/
41
+ File.read("/tmp/init/app-alpha-1.conf").should =~ /KEY=d\\"\\\\\\\|d/
42
42
  end
43
43
 
44
44
  context "with a formation" do
@@ -1,4 +1,4 @@
1
1
  # ----- foreman app processes -----
2
- AP01:4:respawn:/bin/su - app -c 'PORT=5000 ./alpha >> /var/log/app/alpha-1.log 2>&1'
3
- AP02:4:respawn:/bin/su - app -c 'PORT=5001 ./alpha >> /var/log/app/alpha-2.log 2>&1'
2
+ AP01:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5000;./alpha >> /var/log/app/alpha-1.log 2>&1'
3
+ AP02:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5001;./alpha >> /var/log/app/alpha-2.log 2>&1'
4
4
  # ----- end foreman app processes -----
@@ -1,4 +1,4 @@
1
1
  # ----- foreman app processes -----
2
- AP01:4:respawn:/bin/su - app -c 'PORT=5000 ./alpha >> /var/log/app/alpha-1.log 2>&1'
3
- AP02:4:respawn:/bin/su - app -c 'PORT=5100 ./bravo >> /var/log/app/bravo-1.log 2>&1'
2
+ AP01:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5000;./alpha >> /var/log/app/alpha-1.log 2>&1'
3
+ AP02:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5100;./bravo >> /var/log/app/bravo-1.log 2>&1'
4
4
  # ----- end foreman app processes -----
@@ -4,6 +4,11 @@
4
4
  <dict>
5
5
  <key>Label</key>
6
6
  <string>app-alpha-1</string>
7
+ <key>EnvironmentVariables</key>
8
+ <dict>
9
+ <key>PORT</key>
10
+ <string>5000</string>
11
+ </dict>
7
12
  <key>ProgramArguments</key>
8
13
  <array>
9
14
  <string>./alpha</string>
@@ -12,6 +17,8 @@
12
17
  <true/>
13
18
  <key>RunAtLoad</key>
14
19
  <true/>
20
+ <key>StandardOutPath</key>
21
+ <string>/var/log/app/app-alpha-1.log</string>
15
22
  <key>StandardErrorPath</key>
16
23
  <string>/var/log/app/app-alpha-1.log</string>
17
24
  <key>UserName</key>
@@ -4,6 +4,11 @@
4
4
  <dict>
5
5
  <key>Label</key>
6
6
  <string>app-bravo-1</string>
7
+ <key>EnvironmentVariables</key>
8
+ <dict>
9
+ <key>PORT</key>
10
+ <string>5100</string>
11
+ </dict>
7
12
  <key>ProgramArguments</key>
8
13
  <array>
9
14
  <string>./bravo</string>
@@ -12,6 +17,8 @@
12
17
  <true/>
13
18
  <key>RunAtLoad</key>
14
19
  <true/>
20
+ <key>StandardOutPath</key>
21
+ <string>/var/log/app/app-bravo-1.log</string>
15
22
  <key>StandardErrorPath</key>
16
23
  <string>/var/log/app/app-bravo-1.log</string>
17
24
  <key>UserName</key>
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Label</key>
6
+ <string>app-alpha-1</string>
7
+ <key>EnvironmentVariables</key>
8
+ <dict>
9
+ <key>PORT</key>
10
+ <string>5000</string>
11
+ </dict>
12
+ <key>ProgramArguments</key>
13
+ <array>
14
+ <string>./alpha</string>
15
+ <string>charlie</string>
16
+ </array>
17
+ <key>KeepAlive</key>
18
+ <true/>
19
+ <key>RunAtLoad</key>
20
+ <true/>
21
+ <key>StandardOutPath</key>
22
+ <string>/var/log/app/app-alpha-1.log</string>
23
+ <key>StandardErrorPath</key>
24
+ <string>/var/log/app/app-alpha-1.log</string>
25
+ <key>UserName</key>
26
+ <string>app</string>
27
+ <key>WorkingDirectory</key>
28
+ <string>/tmp/app</string>
29
+ </dict>
30
+ </plist>
@@ -8,7 +8,7 @@ stdout_logfile=/var/log/app/alpha-1.log
8
8
  stderr_logfile=/var/log/app/alpha-1.error.log
9
9
  user=app
10
10
  directory=/tmp/app
11
- environment=PORT="5000"
11
+ environment=PORT=5000
12
12
  [program:app-bravo-1]
13
13
  command=./bravo
14
14
  autostart=true
@@ -18,7 +18,7 @@ stdout_logfile=/var/log/app/bravo-1.log
18
18
  stderr_logfile=/var/log/app/bravo-1.error.log
19
19
  user=app
20
20
  directory=/tmp/app
21
- environment=PORT="5100"
21
+ environment=PORT=5100
22
22
 
23
23
  [group:app]
24
24
  programs=app-alpha-1,app-bravo-1
@@ -8,7 +8,7 @@ stdout_logfile=/var/log/app/alpha-1.log
8
8
  stderr_logfile=/var/log/app/alpha-1.error.log
9
9
  user=app
10
10
  directory=/tmp/app
11
- environment=PORT="5000"
11
+ environment=PORT=5000
12
12
  [program:app-alpha-2]
13
13
  command=./alpha
14
14
  autostart=true
@@ -18,7 +18,7 @@ stdout_logfile=/var/log/app/alpha-2.log
18
18
  stderr_logfile=/var/log/app/alpha-2.error.log
19
19
  user=app
20
20
  directory=/tmp/app
21
- environment=PORT="5001"
21
+ environment=PORT=5001
22
22
 
23
23
  [group:app]
24
24
  programs=app-alpha-1,app-alpha-2
@@ -6,3 +6,11 @@ bash << "EOF"
6
6
  EOF
7
7
 
8
8
  end script
9
+
10
+ start on (started network-interface
11
+ or started network-manager
12
+ or started networking)
13
+
14
+ stop on (stopping network-interface
15
+ or stopping network-manager
16
+ or stopping networking)
@@ -1,5 +1,3 @@
1
- require "rubygems"
2
-
3
1
  require "simplecov"
4
2
  SimpleCov.start do
5
3
  add_filter "/spec/"
@@ -58,6 +56,12 @@ def fork_and_capture(&blk)
58
56
  end
59
57
  end
60
58
 
59
+ def fork_and_get_exitstatus(args)
60
+ pid = Process.spawn("bundle exec bin/foreman #{args}", :out => "/dev/null", :err => "/dev/null")
61
+ Process.wait(pid)
62
+ $?.exitstatus
63
+ end
64
+
61
65
  def mock_exit(&block)
62
66
  block.should raise_error(SystemExit)
63
67
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.50.0
4
+ version: 0.61.0
5
5
  prerelease:
6
6
  platform: mingw32
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-11 00:00:00.000000000 Z
12
+ date: 2013-01-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &70204077470000 !ruby/object:Gem::Requirement
16
+ requirement: &70171274222360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.13.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70204077470000
24
+ version_requirements: *70171274222360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: win32console
27
- requirement: &70204077467940 !ruby/object:Gem::Requirement
27
+ requirement: &70171274248800 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: 1.3.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70204077467940
35
+ version_requirements: *70171274248800
36
36
  description: Process manager for applications with multiple components
37
37
  email: ddollar@gmail.com
38
38
  executables:
@@ -59,6 +59,7 @@ files:
59
59
  - data/export/upstart/master.conf.erb
60
60
  - data/export/upstart/process.conf.erb
61
61
  - data/export/upstart/process_master.conf.erb
62
+ - lib/foreman/capistrano.rb
62
63
  - lib/foreman/cli.rb
63
64
  - lib/foreman/distribution.rb
64
65
  - lib/foreman/engine/cli.rb
@@ -103,6 +104,7 @@ files:
103
104
  - spec/resources/export/inittab/inittab.default
104
105
  - spec/resources/export/launchd/launchd-a.default
105
106
  - spec/resources/export/launchd/launchd-b.default
107
+ - spec/resources/export/launchd/launchd-c.default
106
108
  - spec/resources/export/runit/app-alpha-1/log/run
107
109
  - spec/resources/export/runit/app-alpha-1/run
108
110
  - spec/resources/export/runit/app-alpha-2/log/run
@@ -121,7 +123,8 @@ files:
121
123
  - spec/spec_helper.rb
122
124
  - man/foreman.1
123
125
  homepage: http://github.com/ddollar/foreman
124
- licenses: []
126
+ licenses:
127
+ - MIT
125
128
  post_install_message:
126
129
  rdoc_options: []
127
130
  require_paths: