foreman 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/foreman.rb +1 -1
- data/lib/foreman/cli.rb +1 -0
- data/lib/foreman/engine.rb +26 -27
- data/lib/foreman/export/base.rb +0 -6
- data/lib/foreman/export/inittab.rb +2 -2
- data/lib/foreman/export/upstart.rb +2 -2
- data/spec/foreman/engine_spec.rb +12 -3
- metadata +4 -4
data/lib/foreman.rb
CHANGED
data/lib/foreman/cli.rb
CHANGED
@@ -9,6 +9,7 @@ class Foreman::CLI < Thor
|
|
9
9
|
|
10
10
|
desc "start [PROCESS]", "Start the application, or a specific process"
|
11
11
|
|
12
|
+
method_option :port, :type => :numeric, :aliases => "-p"
|
12
13
|
method_option :concurrency, :type => :string, :aliases => "-c",
|
13
14
|
:banner => '"alpha=5,bar=3"'
|
14
15
|
|
data/lib/foreman/engine.rb
CHANGED
@@ -20,27 +20,14 @@ class Foreman::Engine
|
|
20
20
|
@directory = File.expand_path(File.dirname(procfile))
|
21
21
|
end
|
22
22
|
|
23
|
-
def processes
|
23
|
+
def processes
|
24
24
|
@processes ||= begin
|
25
|
-
concurrency = Foreman::Utils.parse_concurrency(concurrency)
|
26
|
-
|
27
25
|
procfile.split("\n").inject({}) do |hash, line|
|
28
26
|
next if line.strip == ""
|
29
27
|
name, command = line.split(" ", 2)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
process = Foreman::Process.new("#{name}.#{num}", command)
|
34
|
-
process.color = next_color
|
35
|
-
hash[process.name] = process
|
36
|
-
end
|
37
|
-
else
|
38
|
-
process = Foreman::Process.new(name, command)
|
39
|
-
process.color = next_color
|
40
|
-
hash[process.name] = process
|
41
|
-
end
|
42
|
-
|
43
|
-
hash
|
28
|
+
process = Foreman::Process.new(name, command)
|
29
|
+
process.color = next_color
|
30
|
+
hash.update(process.name => process)
|
44
31
|
end
|
45
32
|
end
|
46
33
|
end
|
@@ -48,8 +35,8 @@ class Foreman::Engine
|
|
48
35
|
def start(options={})
|
49
36
|
proctitle "ruby: foreman master"
|
50
37
|
|
51
|
-
processes
|
52
|
-
fork process
|
38
|
+
processes.each do |name, process|
|
39
|
+
fork process, options
|
53
40
|
end
|
54
41
|
|
55
42
|
trap("TERM") { kill_and_exit("TERM") }
|
@@ -59,11 +46,7 @@ class Foreman::Engine
|
|
59
46
|
end
|
60
47
|
|
61
48
|
def execute(name, options={})
|
62
|
-
processes
|
63
|
-
process.name =~ /\A#{name}\.?\d*\Z/
|
64
|
-
end.each do |process|
|
65
|
-
fork process
|
66
|
-
end
|
49
|
+
fork processes[name], options
|
67
50
|
|
68
51
|
trap("TERM") { kill_and_exit("TERM") }
|
69
52
|
trap("INT") { kill_and_exit("INT") }
|
@@ -71,9 +54,25 @@ class Foreman::Engine
|
|
71
54
|
watch_for_termination
|
72
55
|
end
|
73
56
|
|
57
|
+
def port_for(process, num, base_port=nil)
|
58
|
+
base_port ||= 5000
|
59
|
+
offset = processes.keys.sort.index(process.name) * 100
|
60
|
+
base_port.to_i + offset + num - 1
|
61
|
+
end
|
62
|
+
|
74
63
|
private ######################################################################
|
75
64
|
|
76
|
-
def fork(process)
|
65
|
+
def fork(process, options={})
|
66
|
+
concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
|
67
|
+
|
68
|
+
1.upto(concurrency[process.name]) do |num|
|
69
|
+
fork_individual(process, port_for(process, num, options[:port]))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def fork_individual(process, port)
|
74
|
+
ENV["PORT"] = port.to_s
|
75
|
+
|
77
76
|
pid = Process.fork do
|
78
77
|
run(process)
|
79
78
|
end
|
@@ -127,8 +126,8 @@ private ######################################################################
|
|
127
126
|
end
|
128
127
|
|
129
128
|
def pad_process_name(process)
|
130
|
-
name = process ? process.name : "system"
|
131
|
-
name.ljust(longest_process_name)
|
129
|
+
name = process ? "#{process.name}:#{ENV["PORT"]}" : "system"
|
130
|
+
name.ljust(longest_process_name + 6) # add 6 for port padding
|
132
131
|
end
|
133
132
|
|
134
133
|
def print_info
|
data/lib/foreman/export/base.rb
CHANGED
@@ -27,12 +27,6 @@ private ######################################################################
|
|
27
27
|
File.read(File.expand_path("../../../../export/#{name}", __FILE__))
|
28
28
|
end
|
29
29
|
|
30
|
-
def port_for(base_port, app, num)
|
31
|
-
base_port ||= 5000
|
32
|
-
offset = engine.processes.keys.sort.index(app) * 100
|
33
|
-
base_port.to_i + offset + num - 1
|
34
|
-
end
|
35
|
-
|
36
30
|
def write_file(filename, contents)
|
37
31
|
say "writing: #{filename}"
|
38
32
|
|
@@ -7,7 +7,7 @@ class Foreman::Export::Inittab < Foreman::Export::Base
|
|
7
7
|
user = options[:user] || app
|
8
8
|
log_root = options[:log] || "/var/log/#{app}"
|
9
9
|
|
10
|
-
concurrency = parse_concurrency(options[:concurrency])
|
10
|
+
concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
|
11
11
|
|
12
12
|
inittab = []
|
13
13
|
inittab << "# ----- foreman #{app} processes -----"
|
@@ -15,7 +15,7 @@ class Foreman::Export::Inittab < Foreman::Export::Base
|
|
15
15
|
engine.processes.values.inject(1) do |index, process|
|
16
16
|
1.upto(concurrency[process.name]) do |num|
|
17
17
|
id = app.slice(0, 2).upcase + sprintf("%02d", index)
|
18
|
-
port = port_for(options[:port]
|
18
|
+
port = engine.port_for(process, num, options[:port])
|
19
19
|
inittab << "#{id}:4:respawn:/bin/su - #{user} -c 'PORT=#{port} #{process.command} >> #{log_root}/#{process.name}-#{num}.log 2>&1'"
|
20
20
|
index += 1
|
21
21
|
end
|
@@ -17,7 +17,7 @@ class Foreman::Export::Upstart < Foreman::Export::Base
|
|
17
17
|
FileUtils.rm(file)
|
18
18
|
end
|
19
19
|
|
20
|
-
concurrency = parse_concurrency(options[:concurrency])
|
20
|
+
concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
|
21
21
|
|
22
22
|
master_template = export_template("upstart/master.conf.erb")
|
23
23
|
master_config = ERB.new(master_template).result(binding)
|
@@ -31,7 +31,7 @@ class Foreman::Export::Upstart < Foreman::Export::Base
|
|
31
31
|
write_file "#{location}/#{app}-#{process.name}.conf", process_master_config
|
32
32
|
|
33
33
|
1.upto(concurrency[process.name]) do |num|
|
34
|
-
port = port_for(options[:port]
|
34
|
+
port = engine.port_for(process, num, options[:port])
|
35
35
|
process_config = ERB.new(process_template).result(binding)
|
36
36
|
write_file "#{location}/#{app}-#{process.name}-#{num}.conf", process_config
|
37
37
|
end
|
data/spec/foreman/engine_spec.rb
CHANGED
@@ -23,17 +23,26 @@ describe "Foreman::Engine" do
|
|
23
23
|
describe "start" do
|
24
24
|
it "forks the processes" do
|
25
25
|
write_procfile
|
26
|
-
mock(subject).fork(subject.processes["alpha"])
|
27
|
-
mock(subject).fork(subject.processes["bravo"])
|
26
|
+
mock(subject).fork(subject.processes["alpha"], {})
|
27
|
+
mock(subject).fork(subject.processes["bravo"], {})
|
28
28
|
mock(subject).watch_for_termination
|
29
29
|
subject.start
|
30
30
|
end
|
31
|
+
|
32
|
+
it "handles concurrency" do
|
33
|
+
write_procfile
|
34
|
+
mock(subject).fork_individual(subject.processes["alpha"], 5000)
|
35
|
+
mock(subject).fork_individual(subject.processes["alpha"], 5001)
|
36
|
+
mock(subject).fork_individual(subject.processes["bravo"], 5100)
|
37
|
+
mock(subject).watch_for_termination
|
38
|
+
subject.start(:concurrency => "alpha=2")
|
39
|
+
end
|
31
40
|
end
|
32
41
|
|
33
42
|
describe "execute" do
|
34
43
|
it "runs the processes" do
|
35
44
|
write_procfile
|
36
|
-
mock(subject).fork(subject.processes["alpha"])
|
45
|
+
mock(subject).fork(subject.processes["alpha"], {})
|
37
46
|
mock(subject).watch_for_termination
|
38
47
|
subject.execute("alpha")
|
39
48
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 7
|
9
|
-
-
|
10
|
-
version: 0.7.
|
9
|
+
- 1
|
10
|
+
version: 0.7.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- David Dollar
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-07-
|
18
|
+
date: 2010-07-20 00:00:00 -07:00
|
19
19
|
default_executable: foreman
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|