foreman 0.78.0 → 0.80.0
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.
- checksums.yaml +4 -4
- data/README.md +7 -3
- data/data/export/supervisord/app.conf.erb +5 -1
- data/data/export/systemd/master.target.erb +0 -1
- data/data/export/systemd/process.service.erb +1 -1
- data/data/export/systemd/process_master.target.erb +1 -1
- data/lib/foreman/cli.rb +7 -8
- data/lib/foreman/engine.rb +65 -21
- data/lib/foreman/process.rb +2 -2
- data/lib/foreman/procfile.rb +3 -1
- data/lib/foreman/version.rb +1 -1
- data/man/foreman.1 +11 -5
- data/spec/foreman/cli_spec.rb +5 -1
- data/spec/foreman/engine_spec.rb +10 -8
- data/spec/foreman/export/supervisord_spec.rb +2 -0
- data/spec/foreman/procfile_spec.rb +7 -0
- data/spec/resources/Procfile.bad +2 -0
- data/spec/resources/export/supervisord/app-alpha-1.conf +4 -4
- data/spec/resources/export/systemd/concurrency/app-alpha-1.service +1 -1
- data/spec/resources/export/systemd/concurrency/app-alpha-2.service +1 -1
- data/spec/resources/export/systemd/concurrency/app-alpha.target +1 -1
- data/spec/resources/export/systemd/concurrency/app.target +0 -1
- data/spec/resources/export/systemd/standard/app-alpha-1.service +1 -1
- data/spec/resources/export/systemd/standard/app-alpha.target +1 -1
- data/spec/resources/export/systemd/standard/app-bravo-1.service +1 -1
- data/spec/resources/export/systemd/standard/app-bravo.target +1 -1
- data/spec/resources/export/systemd/standard/app.target +0 -1
- data/spec/spec_helper.rb +14 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a02fb10bc795cf8fabe42ae18d886dae4a4c9b0a
|
4
|
+
data.tar.gz: bf241e10966f47a51f4108eb049cba9107bc3930
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
41
|
-
* [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/
|
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
|
-
|
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
|
-%>
|
data/lib/foreman/cli.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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.
|
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
|
data/lib/foreman/engine.rb
CHANGED
@@ -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
|
-
|
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::
|
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
|
-
|
115
|
-
|
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
|
-
|
122
|
-
|
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
|
-
|
129
|
-
|
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
|
414
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
434
|
-
|
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
|
-
|
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
|
data/lib/foreman/process.rb
CHANGED
@@ -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
|
54
|
+
Process.spawn(env, expanded_command(env), :out => output, :err => output, :pgroup => true)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
data/lib/foreman/procfile.rb
CHANGED
@@ -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 }
|
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
|
data/lib/foreman/version.rb
CHANGED
data/man/foreman.1
CHANGED
@@ -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" "
|
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\-
|
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\-
|
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
|
-
|
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 \-
|
277
|
+
$ foreman start \-m all=1,worker=0
|
272
278
|
.
|
273
279
|
.fi
|
274
280
|
.
|
data/spec/foreman/cli_spec.rb
CHANGED
@@ -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
|
data/spec/foreman/engine_spec.rb
CHANGED
@@ -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).
|
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).
|
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
|
-
|
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
|
-
|
72
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
data/spec/spec_helper.rb
CHANGED
@@ -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.
|
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:
|
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.
|
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
|