foreman 0.29.0 → 0.37.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.
- data/README.md +39 -0
- data/bin/runner +35 -1
- data/data/export/bluepill/master.pill.erb +1 -1
- data/lib/foreman/cli.rb +30 -23
- data/lib/foreman/engine.rb +35 -20
- data/lib/foreman/export/base.rb +12 -5
- data/lib/foreman/export/bluepill.rb +5 -7
- data/lib/foreman/export/inittab.rb +10 -12
- data/lib/foreman/export/runit.rb +10 -11
- data/lib/foreman/export/upstart.rb +8 -10
- data/lib/foreman/export.rb +21 -0
- data/lib/foreman/helpers.rb +45 -0
- data/lib/foreman/process.rb +52 -15
- data/lib/foreman/utils.rb +4 -1
- data/lib/foreman/version.rb +1 -1
- data/lib/foreman.rb +8 -1
- data/man/foreman.1 +5 -1
- data/spec/foreman/cli_spec.rb +77 -7
- data/spec/foreman/engine_spec.rb +5 -5
- data/spec/foreman/export/base_spec.rb +22 -0
- data/spec/foreman/export/bluepill_spec.rb +22 -5
- data/spec/foreman/export/inittab_spec.rb +40 -0
- data/spec/foreman/export/runit_spec.rb +18 -12
- data/spec/foreman/export/upstart_spec.rb +40 -8
- data/spec/foreman/export_spec.rb +22 -0
- data/spec/foreman/helpers_spec.rb +26 -0
- data/spec/foreman/process_spec.rb +131 -2
- data/spec/foreman_spec.rb +8 -7
- data/spec/helper_spec.rb +18 -0
- data/spec/resources/export/bluepill/app-concurrency.pill +47 -0
- data/spec/resources/export/bluepill/app.pill +0 -21
- data/spec/resources/export/inittab/inittab.concurrency +4 -0
- data/spec/resources/export/inittab/inittab.default +4 -0
- data/spec/spec_helper.rb +31 -3
- metadata +17 -15
- data/README.markdown +0 -49
|
@@ -1,2 +1,131 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'foreman/process'
|
|
3
|
+
require 'ostruct'
|
|
4
|
+
require 'timeout'
|
|
5
|
+
require 'tmpdir'
|
|
6
|
+
|
|
7
|
+
describe Foreman::Process do
|
|
8
|
+
subject { described_class.new entry, number, port }
|
|
9
|
+
|
|
10
|
+
let(:number) { 1 }
|
|
11
|
+
let(:port) { 777 }
|
|
12
|
+
let(:command) { "script" }
|
|
13
|
+
let(:name) { "foobar" }
|
|
14
|
+
let(:entry) { OpenStruct.new :name => name, :command => command }
|
|
15
|
+
|
|
16
|
+
its(:entry) { entry }
|
|
17
|
+
its(:num) { number }
|
|
18
|
+
its(:port) { port }
|
|
19
|
+
its(:name) { "#{name}.#{port}" }
|
|
20
|
+
its(:pid) { nil }
|
|
21
|
+
|
|
22
|
+
describe '#run' do
|
|
23
|
+
let(:pipe) { :pipe }
|
|
24
|
+
let(:basedir) { Dir.mktmpdir }
|
|
25
|
+
let(:env) {{ 'foo' => 'bar' }}
|
|
26
|
+
let(:init_delta) { 0.1 }
|
|
27
|
+
|
|
28
|
+
after { FileUtils.remove_entry_secure basedir }
|
|
29
|
+
|
|
30
|
+
def run(cmd=command)
|
|
31
|
+
entry.command = cmd
|
|
32
|
+
subject.run pipe, basedir, env
|
|
33
|
+
subject.detach && sleep(init_delta)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def run_file(executable, code)
|
|
37
|
+
file = File.open("#{basedir}/script", 'w') {|it| it << code }
|
|
38
|
+
run "#{executable} #{file.path}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'options' do
|
|
42
|
+
it 'should set PORT for environment' do
|
|
43
|
+
mock(subject).run_process(basedir, command, pipe) do
|
|
44
|
+
ENV['PORT'].should == port.to_s
|
|
45
|
+
end
|
|
46
|
+
run
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'should set custom variables for environment' do
|
|
50
|
+
mock(subject).run_process(basedir, command, pipe) do
|
|
51
|
+
ENV['foo'].should == 'bar'
|
|
52
|
+
end
|
|
53
|
+
run
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'should restore environment afterwards' do
|
|
57
|
+
mock(subject).run_process(basedir, command, pipe)
|
|
58
|
+
run
|
|
59
|
+
ENV.should_not include('PORT', 'foo')
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context 'process' do
|
|
64
|
+
around do |spec|
|
|
65
|
+
IO.pipe do |reader, writer|
|
|
66
|
+
@reader, @writer = reader, writer
|
|
67
|
+
spec.run
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
let(:pipe) { @writer }
|
|
72
|
+
let(:output) { @reader.read_nonblock 1024 }
|
|
73
|
+
|
|
74
|
+
it 'should not block' do
|
|
75
|
+
expect {
|
|
76
|
+
Timeout.timeout(2*init_delta) { run 'sleep 2' }
|
|
77
|
+
}.should_not raise_exception
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'should be alive' do
|
|
81
|
+
run 'sleep 1'
|
|
82
|
+
subject.should be_alive
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'should be dead' do
|
|
86
|
+
run 'exit'
|
|
87
|
+
subject.should be_dead
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'should be killable' do
|
|
91
|
+
run 'sleep 1'
|
|
92
|
+
subject.kill 'TERM'
|
|
93
|
+
subject.should be_dead
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'should send different signals' do
|
|
97
|
+
run_file 'ruby', <<-CODE
|
|
98
|
+
trap "TERM", "IGNORE"
|
|
99
|
+
loop { sleep 1 }
|
|
100
|
+
CODE
|
|
101
|
+
sleep 1 # wait for ruby to start
|
|
102
|
+
subject.should be_alive
|
|
103
|
+
subject.kill 'TERM'
|
|
104
|
+
subject.should be_alive
|
|
105
|
+
subject.kill 'KILL'
|
|
106
|
+
subject.should be_dead
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'should redirect stdout' do
|
|
110
|
+
run 'echo hey'
|
|
111
|
+
output.should include('hey')
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'should redirect stderr' do
|
|
115
|
+
run 'echo hey >2'
|
|
116
|
+
output.should include('hey')
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'should handle variables' do
|
|
120
|
+
run 'echo $PORT'
|
|
121
|
+
output.should include('777')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'should handle arguments' do
|
|
125
|
+
pending
|
|
126
|
+
run %{ sh -c "trap '' TERM; sleep 10" }
|
|
127
|
+
subject.should be_alive
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
data/spec/foreman_spec.rb
CHANGED
|
@@ -8,13 +8,8 @@ describe Foreman do
|
|
|
8
8
|
it { should be_a String }
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
describe "::load_env!(env_file)" do
|
|
12
|
-
before do
|
|
13
|
-
FakeFS.activate!
|
|
14
|
-
end
|
|
15
|
-
|
|
11
|
+
describe "::load_env!(env_file)", :fakefs do
|
|
16
12
|
after do
|
|
17
|
-
FakeFS.deactivate!
|
|
18
13
|
ENV['FOO'] = nil
|
|
19
14
|
end
|
|
20
15
|
|
|
@@ -22,7 +17,7 @@ describe Foreman do
|
|
|
22
17
|
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
|
|
23
18
|
Foreman.load_env!("/tmp/env1")
|
|
24
19
|
ENV['FOO'].should == 'bar'
|
|
25
|
-
end
|
|
20
|
+
end
|
|
26
21
|
|
|
27
22
|
it "should assume env_file in ./.env" do
|
|
28
23
|
File.open("./.env", "w") { |f| f.puts("FOO=bar") }
|
|
@@ -30,4 +25,10 @@ describe Foreman do
|
|
|
30
25
|
ENV['FOO'].should == 'bar'
|
|
31
26
|
end
|
|
32
27
|
end
|
|
28
|
+
|
|
29
|
+
describe "runner" do
|
|
30
|
+
it "should exist" do
|
|
31
|
+
File.exists?(Foreman.runner).should == true
|
|
32
|
+
end
|
|
33
|
+
end
|
|
33
34
|
end
|
data/spec/helper_spec.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "spec helpers" do
|
|
4
|
+
describe "#preserving_env" do
|
|
5
|
+
after { ENV.delete "FOO" }
|
|
6
|
+
|
|
7
|
+
it "should remove added environment vars" do
|
|
8
|
+
preserving_env { ENV["FOO"] = "baz" }
|
|
9
|
+
ENV["FOO"].should == nil
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should reset modified environment vars" do
|
|
13
|
+
ENV["FOO"] = "bar"
|
|
14
|
+
preserving_env { ENV["FOO"] = "baz"}
|
|
15
|
+
ENV["FOO"].should == "bar"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Bluepill.application("app", :foreground => false, :log_file => "/var/log/bluepill.log") do |app|
|
|
2
|
+
|
|
3
|
+
app.uid = "app"
|
|
4
|
+
app.gid = "app"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
app.process("alpha-1") do |process|
|
|
10
|
+
process.start_command = "./alpha"
|
|
11
|
+
|
|
12
|
+
process.working_dir = "/tmp/app"
|
|
13
|
+
process.daemonize = true
|
|
14
|
+
process.environment = {"PORT" => "5000"}
|
|
15
|
+
process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
|
|
16
|
+
|
|
17
|
+
process.stdout = process.stderr = "/var/log/app/app-alpha-1.log"
|
|
18
|
+
|
|
19
|
+
process.monitor_children do |children|
|
|
20
|
+
children.stop_command "kill -QUIT {{PID}}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
process.group = "app-alpha"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
app.process("alpha-2") do |process|
|
|
28
|
+
process.start_command = "./alpha"
|
|
29
|
+
|
|
30
|
+
process.working_dir = "/tmp/app"
|
|
31
|
+
process.daemonize = true
|
|
32
|
+
process.environment = {"PORT" => "5001"}
|
|
33
|
+
process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
|
|
34
|
+
|
|
35
|
+
process.stdout = process.stderr = "/var/log/app/app-alpha-2.log"
|
|
36
|
+
|
|
37
|
+
process.monitor_children do |children|
|
|
38
|
+
children.stop_command "kill -QUIT {{PID}}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
process.group = "app-alpha"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
end
|
|
@@ -23,27 +23,6 @@ Bluepill.application("app", :foreground => false, :log_file => "/var/log/bluepil
|
|
|
23
23
|
process.group = "app-alpha"
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
app.process("alpha-2") do |process|
|
|
28
|
-
process.start_command = "./alpha"
|
|
29
|
-
|
|
30
|
-
process.working_dir = "/tmp/app"
|
|
31
|
-
process.daemonize = true
|
|
32
|
-
process.environment = {"PORT" => "5001"}
|
|
33
|
-
process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
|
|
34
|
-
|
|
35
|
-
process.stdout = process.stderr = "/var/log/app/app-alpha-2.log"
|
|
36
|
-
|
|
37
|
-
process.monitor_children do |children|
|
|
38
|
-
children.stop_command "kill -QUIT {{PID}}"
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
process.group = "app-alpha"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
26
|
app.process("bravo-1") do |process|
|
|
48
27
|
process.start_command = "./bravo"
|
|
49
28
|
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
require "rubygems"
|
|
2
|
+
|
|
3
|
+
require "simplecov"
|
|
4
|
+
SimpleCov.start do
|
|
5
|
+
add_filter "/spec/"
|
|
6
|
+
end
|
|
7
|
+
|
|
2
8
|
require "rspec"
|
|
3
9
|
require "fakefs/safe"
|
|
4
10
|
require "fakefs/spec_helpers"
|
|
5
11
|
|
|
6
12
|
$:.unshift File.expand_path("../../lib", __FILE__)
|
|
7
13
|
|
|
14
|
+
def mock_export_error(message)
|
|
15
|
+
lambda { yield }.should raise_error(Foreman::Export::Exception, message)
|
|
16
|
+
end
|
|
17
|
+
|
|
8
18
|
def mock_error(subject, message)
|
|
9
19
|
mock_exit do
|
|
10
20
|
mock(subject).puts("ERROR: #{message}")
|
|
@@ -37,9 +47,11 @@ def write_procfile(procfile="Procfile", alpha_env="")
|
|
|
37
47
|
File.expand_path(procfile)
|
|
38
48
|
end
|
|
39
49
|
|
|
40
|
-
def write_env(env=".env")
|
|
50
|
+
def write_env(env=".env", options={"FOO"=>"bar"})
|
|
41
51
|
File.open(env, "w") do |file|
|
|
42
|
-
|
|
52
|
+
options.each do |key, val|
|
|
53
|
+
file.puts "#{key}=#{val}"
|
|
54
|
+
end
|
|
43
55
|
end
|
|
44
56
|
end
|
|
45
57
|
|
|
@@ -63,8 +75,24 @@ def example_export_file(filename)
|
|
|
63
75
|
data
|
|
64
76
|
end
|
|
65
77
|
|
|
78
|
+
def preserving_env
|
|
79
|
+
old_env = ENV.to_hash
|
|
80
|
+
begin
|
|
81
|
+
yield
|
|
82
|
+
ensure
|
|
83
|
+
ENV.clear
|
|
84
|
+
ENV.update(old_env)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def normalize_space(s)
|
|
89
|
+
s.gsub(/\n[\n\s]*/, "\n")
|
|
90
|
+
end
|
|
91
|
+
|
|
66
92
|
RSpec.configure do |config|
|
|
93
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
67
94
|
config.color_enabled = true
|
|
68
|
-
config.
|
|
95
|
+
config.order = 'rand'
|
|
96
|
+
config.include FakeFS::SpecHelpers, :fakefs
|
|
69
97
|
config.mock_with :rr
|
|
70
98
|
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.
|
|
4
|
+
version: 0.37.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,22 +9,22 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2012-01-29 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: term-ansicolor
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &70149919501700 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ~>
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.0.
|
|
21
|
+
version: 1.0.7
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *70149919501700
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: thor
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &70149919500700 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
30
|
- - ! '>='
|
|
@@ -32,7 +32,7 @@ dependencies:
|
|
|
32
32
|
version: 0.13.6
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *70149919500700
|
|
36
36
|
description: Process manager for applications with multiple components
|
|
37
37
|
email: ddollar@gmail.com
|
|
38
38
|
executables:
|
|
@@ -62,22 +62,30 @@ files:
|
|
|
62
62
|
- lib/foreman/export/runit.rb
|
|
63
63
|
- lib/foreman/export/upstart.rb
|
|
64
64
|
- lib/foreman/export.rb
|
|
65
|
+
- lib/foreman/helpers.rb
|
|
65
66
|
- lib/foreman/process.rb
|
|
66
67
|
- lib/foreman/procfile.rb
|
|
67
68
|
- lib/foreman/procfile_entry.rb
|
|
68
69
|
- lib/foreman/utils.rb
|
|
69
70
|
- lib/foreman/version.rb
|
|
70
71
|
- lib/foreman.rb
|
|
71
|
-
- README.
|
|
72
|
+
- README.md
|
|
72
73
|
- spec/foreman/cli_spec.rb
|
|
73
74
|
- spec/foreman/engine_spec.rb
|
|
75
|
+
- spec/foreman/export/base_spec.rb
|
|
74
76
|
- spec/foreman/export/bluepill_spec.rb
|
|
77
|
+
- spec/foreman/export/inittab_spec.rb
|
|
75
78
|
- spec/foreman/export/runit_spec.rb
|
|
76
79
|
- spec/foreman/export/upstart_spec.rb
|
|
77
80
|
- spec/foreman/export_spec.rb
|
|
81
|
+
- spec/foreman/helpers_spec.rb
|
|
78
82
|
- spec/foreman/process_spec.rb
|
|
79
83
|
- spec/foreman_spec.rb
|
|
84
|
+
- spec/helper_spec.rb
|
|
85
|
+
- spec/resources/export/bluepill/app-concurrency.pill
|
|
80
86
|
- spec/resources/export/bluepill/app.pill
|
|
87
|
+
- spec/resources/export/inittab/inittab.concurrency
|
|
88
|
+
- spec/resources/export/inittab/inittab.default
|
|
81
89
|
- spec/resources/export/runit/app-alpha-1-log-run
|
|
82
90
|
- spec/resources/export/runit/app-alpha-1-run
|
|
83
91
|
- spec/resources/export/runit/app-alpha-2-log-run
|
|
@@ -104,21 +112,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
104
112
|
- - ! '>='
|
|
105
113
|
- !ruby/object:Gem::Version
|
|
106
114
|
version: '0'
|
|
107
|
-
segments:
|
|
108
|
-
- 0
|
|
109
|
-
hash: -705079765555919501
|
|
110
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
116
|
none: false
|
|
112
117
|
requirements:
|
|
113
118
|
- - ! '>='
|
|
114
119
|
- !ruby/object:Gem::Version
|
|
115
120
|
version: '0'
|
|
116
|
-
segments:
|
|
117
|
-
- 0
|
|
118
|
-
hash: -705079765555919501
|
|
119
121
|
requirements: []
|
|
120
122
|
rubyforge_project:
|
|
121
|
-
rubygems_version: 1.8.
|
|
123
|
+
rubygems_version: 1.8.15
|
|
122
124
|
signing_key:
|
|
123
125
|
specification_version: 3
|
|
124
126
|
summary: Process manager for applications with multiple components
|
data/README.markdown
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# Foreman
|
|
2
|
-
|
|
3
|
-
## Installation
|
|
4
|
-
|
|
5
|
-
* Rubygems
|
|
6
|
-
|
|
7
|
-
gem install foreman
|
|
8
|
-
|
|
9
|
-
* OSX
|
|
10
|
-
|
|
11
|
-
http://assets.foreman.io/foreman/foreman.pkg
|
|
12
|
-
|
|
13
|
-
* Standalone Tarball
|
|
14
|
-
|
|
15
|
-
http://assets.foreman.io/foreman/foreman.tgz
|
|
16
|
-
|
|
17
|
-
## Description
|
|
18
|
-
|
|
19
|
-
http://blog.daviddollar.org/2011/05/06/introducing-foreman.html
|
|
20
|
-
|
|
21
|
-
## Manual
|
|
22
|
-
|
|
23
|
-
See the [man page](http://ddollar.github.com/foreman) for usage.
|
|
24
|
-
|
|
25
|
-
## Authorship
|
|
26
|
-
|
|
27
|
-
Created by David Dollar
|
|
28
|
-
|
|
29
|
-
Patches contributed by:
|
|
30
|
-
|
|
31
|
-
* Adam Wiggins
|
|
32
|
-
* Dan Peterson
|
|
33
|
-
* Hunter Nield
|
|
34
|
-
* Jay Zeschin
|
|
35
|
-
* Keith Rarick
|
|
36
|
-
* Khaja Minhajuddin
|
|
37
|
-
* Matt Haynes
|
|
38
|
-
* Michael van Rooijen
|
|
39
|
-
* Mike Javorski
|
|
40
|
-
* Nathan L Smith
|
|
41
|
-
* Nick Zadrozny
|
|
42
|
-
* Ricardo Chimal, Jr
|
|
43
|
-
* Thom May
|
|
44
|
-
* clifff
|
|
45
|
-
* Greg Reinacker
|
|
46
|
-
|
|
47
|
-
## License
|
|
48
|
-
|
|
49
|
-
MIT
|