foreman-capistrano 0.51.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +46 -0
- data/bin/foreman +7 -0
- data/bin/foreman-runner +32 -0
- data/bin/taskman +8 -0
- data/data/example/Procfile +4 -0
- data/data/example/Procfile.without_colon +2 -0
- data/data/example/error +7 -0
- data/data/example/log/neverdie.log +4 -0
- data/data/example/spawnee +14 -0
- data/data/example/spawner +7 -0
- data/data/example/ticker +14 -0
- data/data/example/utf8 +11 -0
- data/data/export/bluepill/master.pill.erb +28 -0
- data/data/export/launchd/launchd.plist.erb +22 -0
- data/data/export/runit/log/run.erb +7 -0
- data/data/export/runit/run.erb +3 -0
- data/data/export/supervisord/app.conf.erb +27 -0
- data/data/export/upstart/master.conf.erb +8 -0
- data/data/export/upstart/process.conf.erb +7 -0
- data/data/export/upstart/process_master.conf.erb +2 -0
- data/lib/foreman/capistrano.rb +55 -0
- data/lib/foreman/cli.rb +140 -0
- data/lib/foreman/distribution.rb +9 -0
- data/lib/foreman/engine/cli.rb +104 -0
- data/lib/foreman/engine.rb +313 -0
- data/lib/foreman/env.rb +27 -0
- data/lib/foreman/export/base.rb +146 -0
- data/lib/foreman/export/bluepill.rb +12 -0
- data/lib/foreman/export/inittab.rb +33 -0
- data/lib/foreman/export/launchd.rb +15 -0
- data/lib/foreman/export/runit.rb +34 -0
- data/lib/foreman/export/supervisord.rb +16 -0
- data/lib/foreman/export/upstart.rb +25 -0
- data/lib/foreman/export.rb +34 -0
- data/lib/foreman/helpers.rb +45 -0
- data/lib/foreman/process.rb +102 -0
- data/lib/foreman/procfile.rb +92 -0
- data/lib/foreman/version.rb +5 -0
- data/lib/foreman.rb +23 -0
- data/man/foreman.1 +244 -0
- data/spec/foreman/cli_spec.rb +87 -0
- data/spec/foreman/engine_spec.rb +104 -0
- data/spec/foreman/export/base_spec.rb +19 -0
- data/spec/foreman/export/bluepill_spec.rb +37 -0
- data/spec/foreman/export/inittab_spec.rb +40 -0
- data/spec/foreman/export/launchd_spec.rb +21 -0
- data/spec/foreman/export/runit_spec.rb +36 -0
- data/spec/foreman/export/supervisord_spec.rb +36 -0
- data/spec/foreman/export/upstart_spec.rb +88 -0
- data/spec/foreman/export_spec.rb +24 -0
- data/spec/foreman/helpers_spec.rb +26 -0
- data/spec/foreman/process_spec.rb +48 -0
- data/spec/foreman/procfile_spec.rb +41 -0
- data/spec/foreman_spec.rb +16 -0
- data/spec/helper_spec.rb +18 -0
- data/spec/resources/Procfile +4 -0
- data/spec/resources/bin/echo +2 -0
- data/spec/resources/bin/env +2 -0
- data/spec/resources/bin/test +2 -0
- data/spec/resources/bin/utf8 +2 -0
- data/spec/resources/export/bluepill/app-concurrency.pill +49 -0
- data/spec/resources/export/bluepill/app.pill +46 -0
- data/spec/resources/export/inittab/inittab.concurrency +4 -0
- data/spec/resources/export/inittab/inittab.default +4 -0
- data/spec/resources/export/launchd/launchd-a.default +22 -0
- data/spec/resources/export/launchd/launchd-b.default +22 -0
- data/spec/resources/export/runit/app-alpha-1/log/run +7 -0
- data/spec/resources/export/runit/app-alpha-1/run +3 -0
- data/spec/resources/export/runit/app-alpha-2/log/run +7 -0
- data/spec/resources/export/runit/app-alpha-2/run +3 -0
- data/spec/resources/export/runit/app-bravo-1/log/run +7 -0
- data/spec/resources/export/runit/app-bravo-1/run +3 -0
- data/spec/resources/export/supervisord/app-alpha-1.conf +24 -0
- data/spec/resources/export/supervisord/app-alpha-2.conf +24 -0
- data/spec/resources/export/upstart/app-alpha-1.conf +5 -0
- data/spec/resources/export/upstart/app-alpha-2.conf +5 -0
- data/spec/resources/export/upstart/app-alpha.conf +2 -0
- data/spec/resources/export/upstart/app-bravo-1.conf +5 -0
- data/spec/resources/export/upstart/app-bravo.conf +2 -0
- data/spec/resources/export/upstart/app.conf +8 -0
- data/spec/spec_helper.rb +153 -0
- metadata +145 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman/engine"
|
3
|
+
require "foreman/export/bluepill"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
describe Foreman::Export::Bluepill, :fakefs do
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
8
|
+
let(:formation) { nil }
|
9
|
+
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
10
|
+
let(:options) { Hash.new }
|
11
|
+
let(:bluepill) { Foreman::Export::Bluepill.new("/tmp/init", engine, options) }
|
12
|
+
|
13
|
+
before(:each) { load_export_templates_into_fakefs("bluepill") }
|
14
|
+
before(:each) { stub(bluepill).say }
|
15
|
+
|
16
|
+
it "exports to the filesystem" do
|
17
|
+
bluepill.export
|
18
|
+
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app.pill"))
|
19
|
+
end
|
20
|
+
|
21
|
+
it "cleans up if exporting into an existing dir" do
|
22
|
+
mock(FileUtils).rm("/tmp/init/app.pill")
|
23
|
+
|
24
|
+
bluepill.export
|
25
|
+
bluepill.export
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with a process formation" do
|
29
|
+
let(:formation) { "alpha=2" }
|
30
|
+
|
31
|
+
it "exports to the filesystem with concurrency" do
|
32
|
+
bluepill.export
|
33
|
+
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app-concurrency.pill"))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman/engine"
|
3
|
+
require "foreman/export/inittab"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
describe Foreman::Export::Inittab, :fakefs do
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
8
|
+
let(:location) { "/tmp/inittab" }
|
9
|
+
let(:formation) { nil }
|
10
|
+
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
11
|
+
let(:options) { Hash.new }
|
12
|
+
let(:inittab) { Foreman::Export::Inittab.new(location, engine, options) }
|
13
|
+
|
14
|
+
before(:each) { load_export_templates_into_fakefs("inittab") }
|
15
|
+
before(:each) { stub(inittab).say }
|
16
|
+
|
17
|
+
it "exports to the filesystem" do
|
18
|
+
inittab.export
|
19
|
+
File.read("/tmp/inittab").should == example_export_file("inittab/inittab.default")
|
20
|
+
end
|
21
|
+
|
22
|
+
context "to stdout" do
|
23
|
+
let(:location) { "-" }
|
24
|
+
|
25
|
+
it "exports to stdout" do
|
26
|
+
mock(inittab).puts example_export_file("inittab/inittab.default")
|
27
|
+
inittab.export
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with concurrency" do
|
32
|
+
let(:formation) { "alpha=2" }
|
33
|
+
|
34
|
+
it "exports to the filesystem with concurrency" do
|
35
|
+
inittab.export
|
36
|
+
File.read("/tmp/inittab").should == example_export_file("inittab/inittab.concurrency")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman/engine"
|
3
|
+
require "foreman/export/launchd"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
describe Foreman::Export::Launchd, :fakefs do
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
8
|
+
let(:options) { Hash.new }
|
9
|
+
let(:engine) { Foreman::Engine.new().load_procfile(procfile) }
|
10
|
+
let(:launchd) { Foreman::Export::Launchd.new("/tmp/init", engine, options) }
|
11
|
+
|
12
|
+
before(:each) { load_export_templates_into_fakefs("launchd") }
|
13
|
+
before(:each) { stub(launchd).say }
|
14
|
+
|
15
|
+
it "exports to the filesystem" do
|
16
|
+
launchd.export
|
17
|
+
File.read("/tmp/init/app-alpha-1.plist").should == example_export_file("launchd/launchd-a.default")
|
18
|
+
File.read("/tmp/init/app-bravo-1.plist").should == example_export_file("launchd/launchd-b.default")
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman/engine"
|
3
|
+
require "foreman/export/runit"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
describe Foreman::Export::Runit, :fakefs do
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", 'bar=baz') }
|
8
|
+
let(:engine) { Foreman::Engine.new(:formation => "alpha=2,bravo=1").load_procfile(procfile) }
|
9
|
+
let(:options) { Hash.new }
|
10
|
+
let(:runit) { Foreman::Export::Runit.new('/tmp/init', engine, options) }
|
11
|
+
|
12
|
+
before(:each) { load_export_templates_into_fakefs("runit") }
|
13
|
+
before(:each) { stub(runit).say }
|
14
|
+
before(:each) { stub(FakeFS::FileUtils).chmod }
|
15
|
+
|
16
|
+
it "exports to the filesystem" do
|
17
|
+
engine.env["BAR"] = "baz"
|
18
|
+
runit.export
|
19
|
+
|
20
|
+
File.read("/tmp/init/app-alpha-1/run").should == example_export_file('runit/app-alpha-1/run')
|
21
|
+
File.read("/tmp/init/app-alpha-1/log/run").should == example_export_file('runit/app-alpha-1/log/run')
|
22
|
+
File.read("/tmp/init/app-alpha-1/env/PORT").should == "5000\n"
|
23
|
+
File.read("/tmp/init/app-alpha-1/env/BAR").should == "baz\n"
|
24
|
+
File.read("/tmp/init/app-alpha-2/run").should == example_export_file('runit/app-alpha-2/run')
|
25
|
+
File.read("/tmp/init/app-alpha-2/log/run").should == example_export_file('runit/app-alpha-2/log/run')
|
26
|
+
File.read("/tmp/init/app-alpha-2/env/PORT").should == "5001\n"
|
27
|
+
File.read("/tmp/init/app-alpha-2/env/BAR").should == "baz\n"
|
28
|
+
File.read("/tmp/init/app-bravo-1/run").should == example_export_file('runit/app-bravo-1/run')
|
29
|
+
File.read("/tmp/init/app-bravo-1/log/run").should == example_export_file('runit/app-bravo-1/log/run')
|
30
|
+
File.read("/tmp/init/app-bravo-1/env/PORT").should == "5100\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "creates a full path to the export directory" do
|
34
|
+
expect { runit.export }.to_not raise_error(Errno::ENOENT)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman/engine"
|
3
|
+
require "foreman/export/supervisord"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
describe Foreman::Export::Supervisord, :fakefs do
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
8
|
+
let(:formation) { nil }
|
9
|
+
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
10
|
+
let(:options) { Hash.new }
|
11
|
+
let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, options) }
|
12
|
+
|
13
|
+
before(:each) { load_export_templates_into_fakefs("supervisord") }
|
14
|
+
before(:each) { stub(supervisord).say }
|
15
|
+
|
16
|
+
it "exports to the filesystem" do
|
17
|
+
supervisord.export
|
18
|
+
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-1.conf")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "cleans up if exporting into an existing dir" do
|
22
|
+
mock(FileUtils).rm("/tmp/init/app.conf")
|
23
|
+
supervisord.export
|
24
|
+
supervisord.export
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with concurrency" do
|
28
|
+
let(:formation) { "alpha=2" }
|
29
|
+
|
30
|
+
it "exports to the filesystem with concurrency" do
|
31
|
+
supervisord.export
|
32
|
+
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-2.conf")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman/engine"
|
3
|
+
require "foreman/export/upstart"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
describe Foreman::Export::Upstart, :fakefs do
|
7
|
+
let(:procfile) { write_procfile("/tmp/app/Procfile") }
|
8
|
+
let(:formation) { nil }
|
9
|
+
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
10
|
+
let(:options) { Hash.new }
|
11
|
+
let(:upstart) { Foreman::Export::Upstart.new("/tmp/init", engine, options) }
|
12
|
+
|
13
|
+
before(:each) { load_export_templates_into_fakefs("upstart") }
|
14
|
+
before(:each) { stub(upstart).say }
|
15
|
+
|
16
|
+
it "exports to the filesystem" do
|
17
|
+
upstart.export
|
18
|
+
|
19
|
+
File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
|
20
|
+
File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
|
21
|
+
File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
|
22
|
+
File.read("/tmp/init/app-bravo.conf").should == example_export_file("upstart/app-bravo.conf")
|
23
|
+
File.read("/tmp/init/app-bravo-1.conf").should == example_export_file("upstart/app-bravo-1.conf")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "cleans up if exporting into an existing dir" do
|
27
|
+
mock(FileUtils).rm("/tmp/init/app.conf")
|
28
|
+
mock(FileUtils).rm("/tmp/init/app-alpha.conf")
|
29
|
+
mock(FileUtils).rm("/tmp/init/app-alpha-1.conf")
|
30
|
+
mock(FileUtils).rm("/tmp/init/app-bravo.conf")
|
31
|
+
mock(FileUtils).rm("/tmp/init/app-bravo-1.conf")
|
32
|
+
|
33
|
+
upstart.export
|
34
|
+
upstart.export
|
35
|
+
end
|
36
|
+
|
37
|
+
it "quotes and escapes environment variables" do
|
38
|
+
engine.env['KEY'] = 'd"\|d'
|
39
|
+
upstart.export
|
40
|
+
"foobarfoo".should include "bar"
|
41
|
+
File.read("/tmp/init/app-alpha-1.conf").should =~ /KEY="d\\"\\\\\\\|d/
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with a formation" do
|
45
|
+
let(:formation) { "alpha=2" }
|
46
|
+
|
47
|
+
it "exports to the filesystem with concurrency" do
|
48
|
+
upstart.export
|
49
|
+
|
50
|
+
File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
|
51
|
+
File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
|
52
|
+
File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
|
53
|
+
File.read("/tmp/init/app-alpha-2.conf").should == example_export_file("upstart/app-alpha-2.conf")
|
54
|
+
File.exists?("/tmp/init/app-bravo-1.conf").should == false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with alternate templates" do
|
59
|
+
let(:template) { "/tmp/alternate" }
|
60
|
+
let(:options) { { :app => "app", :template => template } }
|
61
|
+
|
62
|
+
before do
|
63
|
+
FileUtils.mkdir_p template
|
64
|
+
File.open("#{template}/master.conf.erb", "w") { |f| f.puts "alternate_template" }
|
65
|
+
end
|
66
|
+
|
67
|
+
it "can export with alternate template files" do
|
68
|
+
upstart.export
|
69
|
+
File.read("/tmp/init/app.conf").should == "alternate_template\n"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "with alternate templates from home dir" do
|
74
|
+
|
75
|
+
before do
|
76
|
+
FileUtils.mkdir_p File.expand_path("~/.foreman/templates/upstart")
|
77
|
+
File.open(File.expand_path("~/.foreman/templates/upstart/master.conf.erb"), "w") do |file|
|
78
|
+
file.puts "default_alternate_template"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "can export with alternate template files" do
|
83
|
+
upstart.export
|
84
|
+
File.read("/tmp/init/app.conf").should == "default_alternate_template\n"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman/export"
|
3
|
+
|
4
|
+
describe "Foreman::Export" do
|
5
|
+
subject { Foreman::Export }
|
6
|
+
|
7
|
+
describe "with a formatter that doesn't declare the appropriate class" do
|
8
|
+
it "prints an error" do
|
9
|
+
mock(subject).require("foreman/export/invalidformatter")
|
10
|
+
mock_export_error("Unknown export format: invalidformatter (no class Foreman::Export::Invalidformatter).") do
|
11
|
+
subject.formatter("invalidformatter")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "with an invalid formatter" do
|
17
|
+
|
18
|
+
it "prints an error" do
|
19
|
+
mock_export_error("Unknown export format: invalidformatter (unable to load file 'foreman/export/invalidformatter').") do
|
20
|
+
subject.formatter("invalidformatter")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman/helpers"
|
3
|
+
|
4
|
+
describe "Foreman::Helpers" do
|
5
|
+
before do
|
6
|
+
module Foo
|
7
|
+
class Bar; end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
Object.send(:remove_const, :Foo)
|
13
|
+
end
|
14
|
+
|
15
|
+
subject { o = Object.new; o.extend(Foreman::Helpers); o }
|
16
|
+
|
17
|
+
it "should classify words" do
|
18
|
+
subject.classify("foo").should == "Foo"
|
19
|
+
subject.classify("foo-bar").should == "FooBar"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should constantize words" do
|
23
|
+
subject.constantize("Object").should == Object
|
24
|
+
subject.constantize("Foo::Bar").should == Foo::Bar
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'foreman/process'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'timeout'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
describe Foreman::Process do
|
8
|
+
|
9
|
+
def run(process, options={})
|
10
|
+
rd, wr = IO.method(:pipe).arity.zero? ? IO.pipe : IO.pipe("BINARY")
|
11
|
+
process.run(options.merge(:output => wr))
|
12
|
+
rd.gets
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#run" do
|
16
|
+
|
17
|
+
it "runs the process" do
|
18
|
+
process = Foreman::Process.new(resource_path("bin/test"))
|
19
|
+
run(process).should == "testing\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can set environment" do
|
23
|
+
process = Foreman::Process.new(resource_path("bin/env FOO"), :env => { "FOO" => "bar" })
|
24
|
+
run(process).should == "bar\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "can set per-run environment" do
|
28
|
+
process = Foreman::Process.new(resource_path("bin/env FOO"))
|
29
|
+
run(process, :env => { "FOO" => "bar "}).should == "bar\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can handle env vars in the command" do
|
33
|
+
process = Foreman::Process.new(resource_path("bin/echo $FOO"), :env => { "FOO" => "bar" })
|
34
|
+
run(process).should == "bar\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can handle per-run env vars in the command" do
|
38
|
+
process = Foreman::Process.new(resource_path("bin/echo $FOO"))
|
39
|
+
run(process, :env => { "FOO" => "bar" }).should == "bar\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should output utf8 properly" do
|
43
|
+
process = Foreman::Process.new(resource_path("bin/utf8"))
|
44
|
+
run(process).should == "\xFF\x03\n"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'foreman/procfile'
|
3
|
+
require 'pathname'
|
4
|
+
require 'tmpdir'
|
5
|
+
|
6
|
+
describe Foreman::Procfile, :fakefs do
|
7
|
+
subject { Foreman::Procfile.new }
|
8
|
+
|
9
|
+
it "can load from a file" do
|
10
|
+
write_procfile
|
11
|
+
subject.load "Procfile"
|
12
|
+
subject["alpha"].should == "./alpha"
|
13
|
+
subject["bravo"].should == "./bravo"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "loads a passed-in Procfile" do
|
17
|
+
write_procfile
|
18
|
+
procfile = Foreman::Procfile.new("Procfile")
|
19
|
+
procfile["alpha"].should == "./alpha"
|
20
|
+
procfile["bravo"].should == "./bravo"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can have a process appended to it" do
|
24
|
+
subject["charlie"] = "./charlie"
|
25
|
+
subject["charlie"].should == "./charlie"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can write to a string" do
|
29
|
+
subject["foo"] = "./foo"
|
30
|
+
subject["bar"] = "./bar"
|
31
|
+
subject.to_s.should == "foo: ./foo\nbar: ./bar"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can write to a file" do
|
35
|
+
subject["foo"] = "./foo"
|
36
|
+
subject["bar"] = "./bar"
|
37
|
+
subject.save "/tmp/proc"
|
38
|
+
File.read("/tmp/proc").should == "foo: ./foo\nbar: ./bar\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "foreman"
|
3
|
+
|
4
|
+
describe Foreman do
|
5
|
+
|
6
|
+
describe "VERSION" do
|
7
|
+
subject { Foreman::VERSION }
|
8
|
+
it { should be_a String }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "runner" do
|
12
|
+
it "should exist" do
|
13
|
+
File.exists?(Foreman.runner).should == true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
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,49 @@
|
|
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
|
+
process.stop_grace_time = 45.seconds
|
17
|
+
|
18
|
+
process.stdout = process.stderr = "/var/log/app/app-alpha-1.log"
|
19
|
+
|
20
|
+
process.monitor_children do |children|
|
21
|
+
children.stop_command "kill {{PID}}"
|
22
|
+
end
|
23
|
+
|
24
|
+
process.group = "app-alpha"
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
app.process("alpha-2") do |process|
|
29
|
+
process.start_command = "./alpha"
|
30
|
+
|
31
|
+
process.working_dir = "/tmp/app"
|
32
|
+
process.daemonize = true
|
33
|
+
process.environment = {"PORT"=>"5001"}
|
34
|
+
process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
|
35
|
+
process.stop_grace_time = 45.seconds
|
36
|
+
|
37
|
+
process.stdout = process.stderr = "/var/log/app/app-alpha-2.log"
|
38
|
+
|
39
|
+
process.monitor_children do |children|
|
40
|
+
children.stop_command "kill {{PID}}"
|
41
|
+
end
|
42
|
+
|
43
|
+
process.group = "app-alpha"
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,46 @@
|
|
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
|
+
process.stop_grace_time = 45.seconds
|
17
|
+
|
18
|
+
process.stdout = process.stderr = "/var/log/app/app-alpha-1.log"
|
19
|
+
|
20
|
+
process.monitor_children do |children|
|
21
|
+
children.stop_command "kill {{PID}}"
|
22
|
+
end
|
23
|
+
|
24
|
+
process.group = "app-alpha"
|
25
|
+
end
|
26
|
+
|
27
|
+
app.process("bravo-1") do |process|
|
28
|
+
process.start_command = "./bravo"
|
29
|
+
|
30
|
+
process.working_dir = "/tmp/app"
|
31
|
+
process.daemonize = true
|
32
|
+
process.environment = {"PORT"=>"5100"}
|
33
|
+
process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
|
34
|
+
process.stop_grace_time = 45.seconds
|
35
|
+
|
36
|
+
process.stdout = process.stderr = "/var/log/app/app-bravo-1.log"
|
37
|
+
|
38
|
+
process.monitor_children do |children|
|
39
|
+
children.stop_command "kill {{PID}}"
|
40
|
+
end
|
41
|
+
|
42
|
+
process.group = "app-bravo"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,22 @@
|
|
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>ProgramArguments</key>
|
8
|
+
<array>
|
9
|
+
<string>./alpha</string>
|
10
|
+
</array>
|
11
|
+
<key>KeepAlive</key>
|
12
|
+
<true/>
|
13
|
+
<key>RunAtLoad</key>
|
14
|
+
<true/>
|
15
|
+
<key>StandardErrorPath</key>
|
16
|
+
<string>/var/log/app/app-alpha-1.log</string>
|
17
|
+
<key>UserName</key>
|
18
|
+
<string>app</string>
|
19
|
+
<key>WorkingDirectory</key>
|
20
|
+
<string>/tmp/app</string>
|
21
|
+
</dict>
|
22
|
+
</plist>
|
@@ -0,0 +1,22 @@
|
|
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-bravo-1</string>
|
7
|
+
<key>ProgramArguments</key>
|
8
|
+
<array>
|
9
|
+
<string>./bravo</string>
|
10
|
+
</array>
|
11
|
+
<key>KeepAlive</key>
|
12
|
+
<true/>
|
13
|
+
<key>RunAtLoad</key>
|
14
|
+
<true/>
|
15
|
+
<key>StandardErrorPath</key>
|
16
|
+
<string>/var/log/app/app-bravo-1.log</string>
|
17
|
+
<key>UserName</key>
|
18
|
+
<string>app</string>
|
19
|
+
<key>WorkingDirectory</key>
|
20
|
+
<string>/tmp/app</string>
|
21
|
+
</dict>
|
22
|
+
</plist>
|