foreman 0.78.0 → 0.80.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 61aa36818c7a0458ef2d9c2036bd212a82e2d7d1
4
- data.tar.gz: 99520a0b2ddbeb2d1fb598889d6e872eb92d1e09
3
+ metadata.gz: a02fb10bc795cf8fabe42ae18d886dae4a4c9b0a
4
+ data.tar.gz: bf241e10966f47a51f4108eb049cba9107bc3930
5
5
  SHA512:
6
- metadata.gz: f6087790b0cd0f11bdde14756b74caba08458bd199e59674a1a2e850dc81a6042c17758b6fc5c6e914c7d1144f7a34eab2cd7229b5d7496eb8904625bb0f014e
7
- data.tar.gz: 6233777b4f9f42fd29bbbe63967e790095faa9c797b69a16c478d3ce22a5f784ecf6f4afdbb4596fba7bb840dbae4b45f2e20f95a4d9ac1db196fd4fb1e922f0
6
+ metadata.gz: 7224d69def523e03d69dae6c100454724fb7749fab05e612041703debaab11ef34f464a29266ccd77d795ee9e7116ff5d743619f9be3bc4c26c87bb292bbb4a8
7
+ data.tar.gz: cb3900e18f9769c304e39414f5e3fc7679e252c78bf516a98e7c084e04d3df2224cc40ff5f78694963333386ff4a32376616e83f863492043771bcea4be93e51
data/README.md CHANGED
@@ -37,17 +37,21 @@ See [.travis.yml](.travis.yml) for a list of Ruby versions against which Foreman
37
37
 
38
38
  ## Documentation
39
39
 
40
- * [man page](http://ddollar.github.com/foreman)
41
- * [wiki](http://github.com/ddollar/foreman/wiki)
40
+ * [man page](http://ddollar.github.io/foreman/)
41
+ * [wiki](https://github.com/ddollar/foreman/wiki)
42
42
  * [changelog](https://github.com/ddollar/foreman/blob/master/Changelog.md)
43
43
 
44
44
  ## Ports
45
45
 
46
46
  * [forego](https://github.com/ddollar/forego) - Go
47
+ * [node-foreman](https://github.com/strongloop/node-foreman) - Node.js
47
48
  * [gaffer](https://github.com/jingweno/gaffer) - Java/JVM
49
+ * [goreman](https://github.com/mattn/goreman) - Go
48
50
  * [honcho](https://github.com/nickstenning/honcho) - python
49
51
  * [proclet](https://github.com/kazeburo/Proclet) - Perl
50
- * [shoreman](https://github.com/hecticjeff/shoreman) - shell
52
+ * [shoreman](https://github.com/chrismytton/shoreman) - shell
53
+ * [crank](https://github.com/arktisklada/crank) - Crystal
54
+ * [houseman](https://github.com/fujimura/houseman) - Haskell
51
55
 
52
56
  ## Authors
53
57
 
@@ -5,7 +5,11 @@ engine.each_process do |name, process|
5
5
  port = engine.port_for(process, num)
6
6
  full_name = "#{app}-#{name}-#{num}"
7
7
  environment = engine.env.merge("PORT" => port.to_s).map do |key, value|
8
- "#{key}=\"#{shell_quote(value)}\""
8
+ value = shell_quote(value)
9
+ value = value.gsub('\=', '=')
10
+ value = value.gsub('\&', '&')
11
+ value = value.gsub('\?', '?')
12
+ "#{key}=\"#{value}\""
9
13
  end
10
14
  app_names << full_name
11
15
  -%>
@@ -1,5 +1,4 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
3
2
  Wants=<%= process_master_names.join(' ') %>
4
3
 
5
4
  [Install]
@@ -1,5 +1,5 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=<%= app %>-<%= name %>.target
3
3
 
4
4
  [Service]
5
5
  User=<%= user %>
@@ -1,3 +1,3 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=<%= app %>.target
3
3
  Wants=<%= process_names.join(' ') %>
@@ -21,7 +21,7 @@ class Foreman::CLI < Thor
21
21
 
22
22
  method_option :color, :type => :boolean, :aliases => "-c", :desc => "Force color to be enabled"
23
23
  method_option :env, :type => :string, :aliases => "-e", :desc => "Specify an environment file to load, defaults to .env"
24
- method_option :formation, :type => :string, :aliases => "-m", :banner => '"alpha=5,bar=3"'
24
+ method_option :formation, :type => :string, :aliases => "-m", :banner => '"alpha=5,bar=3"', :desc => 'Specify what processes will run and how many. Default: "all=1"'
25
25
  method_option :port, :type => :numeric, :aliases => "-p"
26
26
  method_option :timeout, :type => :numeric, :aliases => "-t", :desc => "Specify the amount of time (in seconds) processes have to shutdown gracefully before receiving a SIGKILL, defaults to 5."
27
27
 
@@ -50,7 +50,7 @@ class Foreman::CLI < Thor
50
50
  method_option :port, :type => :numeric, :aliases => "-p"
51
51
  method_option :user, :type => :string, :aliases => "-u"
52
52
  method_option :template, :type => :string, :aliases => "-t"
53
- method_option :concurrency, :type => :string, :aliases => "-c", :banner => '"alpha=5,bar=3"'
53
+ method_option :concurrency, :type => :string, :aliases => "-c", :banner => '"alpha=5,bar=3"', :desc => 'Specify what processes will run and how many. Default: "all=1"'
54
54
 
55
55
  def export(format, location=nil)
56
56
  check_procfile!
@@ -79,7 +79,7 @@ class Foreman::CLI < Thor
79
79
  def run(*args)
80
80
  load_environment!
81
81
 
82
- if File.exist?(procfile)
82
+ if File.file?(procfile)
83
83
  engine.load_procfile(procfile)
84
84
  end
85
85
 
@@ -101,7 +101,7 @@ class Foreman::CLI < Thor
101
101
  Process.kill(:INT, pid)
102
102
  end
103
103
  Process.wait(pid)
104
- exit $?.exitstatus
104
+ exit $?.exitstatus || 0
105
105
  rescue Interrupt
106
106
  end
107
107
 
@@ -129,7 +129,7 @@ private ######################################################################
129
129
  end
130
130
 
131
131
  def check_procfile!
132
- error("#{procfile} does not exist.") unless File.exist?(procfile)
132
+ error("#{procfile} does not exist.") unless File.file?(procfile)
133
133
  end
134
134
 
135
135
  def load_environment!
@@ -139,7 +139,7 @@ private ######################################################################
139
139
  end
140
140
  else
141
141
  default_env = File.join(engine.root, ".env")
142
- engine.load_env default_env if File.exists?(default_env)
142
+ engine.load_env default_env if File.file?(default_env)
143
143
  end
144
144
  end
145
145
 
@@ -153,9 +153,8 @@ private ######################################################################
153
153
 
154
154
  def options
155
155
  original_options = super
156
- return original_options unless File.exists?(".foreman")
156
+ return original_options unless File.file?(".foreman")
157
157
  defaults = ::YAML::load_file(".foreman") || {}
158
158
  Thor::CoreExt::HashWithIndifferentAccess.new(defaults.merge(original_options))
159
159
  end
160
-
161
160
  end
@@ -3,7 +3,6 @@ require "foreman/env"
3
3
  require "foreman/process"
4
4
  require "foreman/procfile"
5
5
  require "tempfile"
6
- require "timeout"
7
6
  require "fileutils"
8
7
  require "thread"
9
8
 
@@ -37,6 +36,7 @@ class Foreman::Engine
37
36
  @processes = []
38
37
  @running = {}
39
38
  @readers = {}
39
+ @shutdown = false
40
40
 
41
41
  # Self-pipe for deferred signal-handling (ala djb: http://cr.yp.to/docs/selfpipe.html)
42
42
  reader, writer = create_pipe
@@ -57,8 +57,9 @@ class Foreman::Engine
57
57
  spawn_processes
58
58
  watch_for_output
59
59
  sleep 0.1
60
- watch_for_termination { terminate_gracefully }
60
+ wait_for_shutdown_or_child_termination
61
61
  shutdown
62
+ exit(@exitstatus) if @exitstatus
62
63
  end
63
64
 
64
65
  # Set up deferred signal handlers
@@ -85,7 +86,7 @@ class Foreman::Engine
85
86
  @selfpipe[:writer].write_nonblock( '.' )
86
87
  rescue Errno::EAGAIN
87
88
  # Ignore writes that would block
88
- rescue Errno::EINT
89
+ rescue Errno::EINTR
89
90
  # Retry if another signal arrived while writing
90
91
  retry
91
92
  end
@@ -111,22 +112,22 @@ class Foreman::Engine
111
112
  # Handle a TERM signal
112
113
  #
113
114
  def handle_term_signal
114
- puts "SIGTERM received"
115
- terminate_gracefully
115
+ system "SIGTERM received, starting shutdown"
116
+ @shutdown = true
116
117
  end
117
118
 
118
119
  # Handle an INT signal
119
120
  #
120
121
  def handle_interrupt
121
- puts "SIGINT received"
122
- terminate_gracefully
122
+ system "SIGINT received, starting shutdown"
123
+ @shutdown = true
123
124
  end
124
125
 
125
126
  # Handle a HUP signal
126
127
  #
127
128
  def handle_hangup
128
- puts "SIGHUP received"
129
- terminate_gracefully
129
+ system "SIGHUP received, starting shutdown"
130
+ @shutdown = true
130
131
  end
131
132
 
132
133
  # Register a process to be run by this +Engine+
@@ -371,7 +372,7 @@ private
371
372
 
372
373
  def read_self_pipe
373
374
  @selfpipe[:reader].read_nonblock(11)
374
- rescue Errno::EAGAIN, Errno::EINTR, Errno::EBADF
375
+ rescue Errno::EAGAIN, Errno::EINTR, Errno::EBADF, Errno::EWOULDBLOCK
375
376
  # ignore
376
377
  end
377
378
 
@@ -410,19 +411,51 @@ private
410
411
  end
411
412
  end
412
413
 
413
- def watch_for_termination
414
- pid, status = Process.wait2
414
+ def wait_for_shutdown_or_child_termination
415
+ loop do
416
+ # Stop if it is time to shut down (asked via a signal)
417
+ break if @shutdown
418
+
419
+ # Stop if any of the children died
420
+ break if check_for_termination
421
+
422
+ # Sleep for a moment and do not blow up if any signals are coming our way
423
+ begin
424
+ sleep(1)
425
+ rescue Exception
426
+ # noop
427
+ end
428
+ end
429
+
430
+ # Ok, we have exited from the main loop, time to shut down gracefully
431
+ terminate_gracefully
432
+ end
433
+
434
+ def check_for_termination
435
+ # Check if any of the children have died off
436
+ pid, status = begin
437
+ Process.wait2(-1, Process::WNOHANG)
438
+ rescue Errno::ECHILD
439
+ return nil
440
+ end
441
+
442
+ @exitstatus ||= status.exitstatus
443
+
444
+ # If no childred have died, nothing to do here
445
+ return nil unless pid
446
+
447
+ # Log the information about the process that exited
415
448
  output_with_mutex name_for(pid), termination_message_for(status)
449
+
450
+ # Delete it from the list of running processes and return its pid
416
451
  @running.delete(pid)
417
- yield if block_given?
418
- pid
419
- rescue Errno::ECHILD
452
+ return pid
420
453
  end
421
454
 
422
455
  def terminate_gracefully
423
- return if @terminating
424
456
  restore_default_signal_handlers
425
- @terminating = true
457
+
458
+ # Tell all children to stop gracefully
426
459
  if Foreman.windows?
427
460
  system "sending SIGKILL to all processes"
428
461
  kill_children "SIGKILL"
@@ -430,12 +463,23 @@ private
430
463
  system "sending SIGTERM to all processes"
431
464
  kill_children "SIGTERM"
432
465
  end
433
- Timeout.timeout(options[:timeout]) do
434
- watch_for_termination while @running.length > 0
466
+
467
+ # Wait for all children to stop or until the time comes to kill them all
468
+ start_time = Time.now
469
+ while Time.now - start_time <= options[:timeout]
470
+ return if @running.empty?
471
+ check_for_termination
472
+
473
+ # Sleep for a moment and do not blow up if more signals are coming our way
474
+ begin
475
+ sleep(0.1)
476
+ rescue Exception
477
+ # noop
478
+ end
435
479
  end
436
- rescue Timeout::Error
480
+
481
+ # Ok, we have no other option than to kill all of our children
437
482
  system "sending SIGKILL to all processes"
438
483
  kill_children "SIGKILL"
439
484
  end
440
-
441
485
  end
@@ -49,9 +49,9 @@ class Foreman::Process
49
49
  env = @options[:env].merge(options[:env] || {})
50
50
  output = options[:output] || $stdout
51
51
  runner = "#{Foreman.runner}".shellescape
52
-
52
+
53
53
  Dir.chdir(cwd) do
54
- Process.spawn env, expanded_command(env), :out => output, :err => output
54
+ Process.spawn(env, expanded_command(env), :out => output, :err => output, :pgroup => true)
55
55
  end
56
56
  end
57
57
 
@@ -32,7 +32,9 @@ class Foreman::Procfile
32
32
  # @param [String] name The name of the Procfile entry to retrieve
33
33
  #
34
34
  def [](name)
35
- @entries.detect { |n,c| name == n }.last
35
+ if entry = @entries.detect { |n,c| name == n }
36
+ entry.last
37
+ end
36
38
  end
37
39
 
38
40
  # Create a +Procfile+ entry
@@ -1,5 +1,5 @@
1
1
  module Foreman
2
2
 
3
- VERSION = "0.78.0"
3
+ VERSION = "0.80.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" "January 2015" "Foreman 0.78.0" "Foreman Manual"
4
+ .TH "FOREMAN" "1" "April 2016" "Foreman 0.80.0" "Foreman Manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBforeman\fR \- manage Procfile\-based applications
@@ -31,7 +31,7 @@ If a parameter is passed, foreman will run one instance of the specified applica
31
31
  The following options control how the application is run:
32
32
  .
33
33
  .TP
34
- \fB\-c\fR, \fB\-\-concurrency\fR
34
+ \fB\-m\fR, \fB\-\-formation\fR
35
35
  Specify the number of each process type to run\. The value passed in should be in the format \fBprocess=num,process=num\fR
36
36
  .
37
37
  .TP
@@ -67,7 +67,7 @@ The following options control how the application is run:
67
67
  Use this name rather than the application\'s root directory name as the name of the application when exporting\.
68
68
  .
69
69
  .TP
70
- \fB\-c\fR, \fB\-\-concurrency\fR
70
+ \fB\-m\fR, \fB\-\-formation\fR
71
71
  Specify the number of each process type to run\. The value passed in should be in the format \fBprocess=num,process=num\fR
72
72
  .
73
73
  .TP
@@ -194,6 +194,12 @@ $ foreman check
194
194
  .
195
195
  .IP "" 0
196
196
  .
197
+ .P
198
+ The special environment variables \fB$PORT\fR and \fB$PS\fR are available within the Procfile\. \fB$PORT\fR is the port selected for that process\. \fB$PS\fR is the name of the process for the line\.
199
+ .
200
+ .P
201
+ The \fB$PORT\fR value starts as the base port as specified by \fB\-p\fR, then increments by 100 for each new process line\. Multiple instances of the same process are assigned \fB$PORT\fR values that increment by 1\.
202
+ .
197
203
  .SH "ENVIRONMENT"
198
204
  If a \fB\.env\fR file exists in the current directory, the default environment will be read from it\. This file should contain key/value pairs, separated by \fB=\fR, with one key/value pair per line\.
199
205
  .
@@ -215,7 +221,7 @@ If a \fB\.foreman\fR file exists in the current directory, default options will
215
221
  .
216
222
  .nf
217
223
 
218
- concurrency: alpha=0,bravo=1
224
+ formation: alpha=0,bravo=1
219
225
  port: 15000
220
226
  .
221
227
  .fi
@@ -268,7 +274,7 @@ Start all processes except the one named worker:
268
274
  .
269
275
  .nf
270
276
 
271
- $ foreman start \-c all=1,worker=0
277
+ $ foreman start \-m all=1,worker=0
272
278
  .
273
279
  .fi
274
280
  .
@@ -51,6 +51,11 @@ describe "Foreman::CLI", :fakefs do
51
51
  expect(output).to match(/ps.1 \| PS env var is ps.1/)
52
52
  end
53
53
  end
54
+
55
+ it "fails if process fails" do
56
+ output = `bundle exec foreman start -f #{resource_path "Procfile.bad"} && echo success`
57
+ expect(output).not_to include 'success'
58
+ end
54
59
  end
55
60
  end
56
61
 
@@ -66,7 +71,6 @@ describe "Foreman::CLI", :fakefs do
66
71
  end
67
72
 
68
73
  it "without a Procfile displays an error" do
69
- FileUtils.rm_f "Procfile"
70
74
  expect(foreman("check")).to eq("ERROR: Procfile does not exist.\n")
71
75
  end
72
76
  end
@@ -38,7 +38,7 @@ describe "Foreman::Engine", :fakefs do
38
38
  mock(subject.process("alpha")).run(anything)
39
39
  mock(subject.process("bravo")).run(anything)
40
40
  mock(subject).watch_for_output
41
- mock(subject).watch_for_termination
41
+ mock(subject).wait_for_shutdown_or_child_termination
42
42
  subject.start
43
43
  end
44
44
 
@@ -47,7 +47,7 @@ describe "Foreman::Engine", :fakefs do
47
47
  mock(subject.process("alpha")).run(anything).twice
48
48
  mock(subject.process("bravo")).run(anything).never
49
49
  mock(subject).watch_for_output
50
- mock(subject).watch_for_termination
50
+ mock(subject).wait_for_shutdown_or_child_termination
51
51
  subject.start
52
52
  end
53
53
  end
@@ -62,14 +62,14 @@ describe "Foreman::Engine", :fakefs do
62
62
 
63
63
  describe "environment" do
64
64
  it "should read env files" do
65
- File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
65
+ write_file("/tmp/env") { |f| f.puts("FOO=baz") }
66
66
  subject.load_env("/tmp/env")
67
67
  expect(subject.env["FOO"]).to eq("baz")
68
68
  end
69
69
 
70
70
  it "should read more than one if specified" do
71
- File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
72
- File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
71
+ write_file("/tmp/env1") { |f| f.puts("FOO=bar") }
72
+ write_file("/tmp/env2") { |f| f.puts("BAZ=qux") }
73
73
  subject.load_env "/tmp/env1"
74
74
  subject.load_env "/tmp/env2"
75
75
  expect(subject.env["FOO"]).to eq("bar")
@@ -77,21 +77,23 @@ describe "Foreman::Engine", :fakefs do
77
77
  end
78
78
 
79
79
  it "should handle quoted values" do
80
- File.open("/tmp/env", "w") do |f|
80
+ write_file("/tmp/env") do |f|
81
81
  f.puts 'FOO=bar'
82
82
  f.puts 'BAZ="qux"'
83
83
  f.puts "FRED='barney'"
84
84
  f.puts 'OTHER="escaped\"quote"'
85
+ f.puts 'URL="http://example.com/api?foo=bar&baz=1"'
85
86
  end
86
87
  subject.load_env "/tmp/env"
87
88
  expect(subject.env["FOO"]).to eq("bar")
88
89
  expect(subject.env["BAZ"]).to eq("qux")
89
90
  expect(subject.env["FRED"]).to eq("barney")
90
91
  expect(subject.env["OTHER"]).to eq('escaped"quote')
92
+ expect(subject.env["URL"]).to eq("http://example.com/api?foo=bar&baz=1")
91
93
  end
92
94
 
93
95
  it "should handle multiline strings" do
94
- File.open("/tmp/env", "w") do |f|
96
+ write_file("/tmp/env") do |f|
95
97
  f.puts 'FOO="bar\nbaz"'
96
98
  end
97
99
  subject.load_env "/tmp/env"
@@ -103,7 +105,7 @@ describe "Foreman::Engine", :fakefs do
103
105
  end
104
106
 
105
107
  it "should set port from .env if specified" do
106
- File.open("/tmp/env", "w") { |f| f.puts("PORT=9000") }
108
+ write_file("/tmp/env") { |f| f.puts("PORT=9000") }
107
109
  subject.load_env "/tmp/env"
108
110
  expect(subject.send(:base_port)).to eq(9000)
109
111
  end
@@ -14,6 +14,8 @@ describe Foreman::Export::Supervisord, :fakefs do
14
14
  before(:each) { stub(supervisord).say }
15
15
 
16
16
  it "exports to the filesystem" do
17
+ write_env(".env", "FOO"=>"bar", "URL"=>"http://example.com/api?foo=bar&baz=1")
18
+ supervisord.engine.load_env('.env')
17
19
  supervisord.export
18
20
  expect(File.read("/tmp/init/app.conf")).to eq(example_export_file("supervisord/app-alpha-1.conf"))
19
21
  end
@@ -22,6 +22,12 @@ describe Foreman::Procfile, :fakefs do
22
22
  expect(procfile["foo_bar"]).to eq("./foo_bar")
23
23
  end
24
24
 
25
+ it "returns nil when attempting to retrieve an non-existing entry" do
26
+ write_procfile
27
+ procfile = Foreman::Procfile.new("Procfile")
28
+ expect(procfile["unicorn"]).to eq(nil)
29
+ end
30
+
25
31
  it "can have a process appended to it" do
26
32
  subject["charlie"] = "./charlie"
27
33
  expect(subject["charlie"]).to eq("./charlie")
@@ -36,6 +42,7 @@ describe Foreman::Procfile, :fakefs do
36
42
  it "can write to a file" do
37
43
  subject["foo"] = "./foo"
38
44
  subject["bar"] = "./bar"
45
+ Dir.mkdir('/tmp')
39
46
  subject.save "/tmp/proc"
40
47
  expect(File.read("/tmp/proc")).to eq("foo: ./foo\nbar: ./bar\n")
41
48
  end
@@ -0,0 +1,2 @@
1
+ good: sleep 1
2
+ bad: false
@@ -7,7 +7,7 @@ stdout_logfile=/var/log/app/alpha-1.log
7
7
  stderr_logfile=/var/log/app/alpha-1.error.log
8
8
  user=app
9
9
  directory=/tmp/app
10
- environment=PORT="5000"
10
+ environment=FOO="bar",URL="http://example.com/api?foo=bar&baz=1",PORT="5000"
11
11
 
12
12
  [program:app-bravo-1]
13
13
  command=./bravo
@@ -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=FOO="bar",URL="http://example.com/api?foo=bar&baz=1",PORT="5100"
22
22
 
23
23
  [program:app-foo_bar-1]
24
24
  command=./foo_bar
@@ -29,7 +29,7 @@ stdout_logfile=/var/log/app/foo_bar-1.log
29
29
  stderr_logfile=/var/log/app/foo_bar-1.error.log
30
30
  user=app
31
31
  directory=/tmp/app
32
- environment=PORT="5200"
32
+ environment=FOO="bar",URL="http://example.com/api?foo=bar&baz=1",PORT="5200"
33
33
 
34
34
  [program:app-foo-bar-1]
35
35
  command=./foo-bar
@@ -40,7 +40,7 @@ stdout_logfile=/var/log/app/foo-bar-1.log
40
40
  stderr_logfile=/var/log/app/foo-bar-1.error.log
41
41
  user=app
42
42
  directory=/tmp/app
43
- environment=PORT="5300"
43
+ environment=FOO="bar",URL="http://example.com/api?foo=bar&baz=1",PORT="5300"
44
44
 
45
45
  [group:app]
46
46
  programs=app-alpha-1,app-bravo-1,app-foo_bar-1,app-foo-bar-1
@@ -1,5 +1,5 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=app-alpha.target
3
3
 
4
4
  [Service]
5
5
  User=app
@@ -1,5 +1,5 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=app-alpha.target
3
3
 
4
4
  [Service]
5
5
  User=app
@@ -1,3 +1,3 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=app.target
3
3
  Wants=app-alpha-1.service app-alpha-2.service
@@ -1,5 +1,4 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
3
2
  Wants=app-alpha.target
4
3
 
5
4
  [Install]
@@ -1,5 +1,5 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=app-alpha.target
3
3
 
4
4
  [Service]
5
5
  User=app
@@ -1,3 +1,3 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=app.target
3
3
  Wants=app-alpha-1.service
@@ -1,5 +1,5 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=app-bravo.target
3
3
 
4
4
  [Service]
5
5
  User=app
@@ -1,3 +1,3 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
2
+ PartOf=app.target
3
3
  Wants=app-bravo-1.service
@@ -1,5 +1,4 @@
1
1
  [Unit]
2
- StopWhenUnneeded=true
3
2
  Wants=app-alpha.target app-bravo.target app-foo_bar.target app-foo-bar.target
4
3
 
5
4
  [Install]
@@ -82,6 +82,7 @@ def write_foreman_config(app)
82
82
  end
83
83
 
84
84
  def write_procfile(procfile="Procfile", alpha_env="")
85
+ FileUtils.mkdir_p(File.dirname(procfile))
85
86
  File.open(procfile, "w") do |file|
86
87
  file.puts "alpha: ./alpha" + " #{alpha_env}".rstrip
87
88
  file.puts "\n"
@@ -92,6 +93,13 @@ def write_procfile(procfile="Procfile", alpha_env="")
92
93
  File.expand_path(procfile)
93
94
  end
94
95
 
96
+ def write_file(file)
97
+ FileUtils.mkdir_p(File.dirname(file))
98
+ File.open(file, 'w') do |f|
99
+ yield(f)
100
+ end
101
+ end
102
+
95
103
  def write_env(env=".env", options={"FOO"=>"bar"})
96
104
  File.open(env, "w") do |file|
97
105
  options.each do |key, val|
@@ -163,4 +171,10 @@ RSpec.configure do |config|
163
171
  config.order = 'rand'
164
172
  config.include FakeFS::SpecHelpers, :fakefs
165
173
  config.mock_with :rr
174
+ config.before(:each) do
175
+ FileUtils.mkdir_p('/tmp')
176
+ end
177
+ config.after(:each) do
178
+ FileUtils.rm_rf('/tmp')
179
+ end
166
180
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.78.0
4
+ version: 0.80.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Dollar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-13 00:00:00.000000000 Z
11
+ date: 2016-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -95,6 +95,7 @@ files:
95
95
  - spec/foreman_spec.rb
96
96
  - spec/helper_spec.rb
97
97
  - spec/resources/Procfile
98
+ - spec/resources/Procfile.bad
98
99
  - spec/resources/bin/echo
99
100
  - spec/resources/bin/env
100
101
  - spec/resources/bin/test
@@ -156,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
156
157
  version: '0'
157
158
  requirements: []
158
159
  rubyforge_project:
159
- rubygems_version: 2.2.2
160
+ rubygems_version: 2.5.1
160
161
  signing_key:
161
162
  specification_version: 4
162
163
  summary: Process manager for applications with multiple components