foreman 0.20.0 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ Bluepill.application("<%= app %>", :foreground => false, :log_file => "/var/log/bluepill.log") do |app|
2
+
3
+ app.uid = "<%= user %>"
4
+ app.gid = "<%= user %>"
5
+
6
+ <% engine.processes.values.each do |process| %>
7
+ <% 1.upto(concurrency[process.name]) do |num| %>
8
+ <% port = engine.port_for(process, num, options[:port]) %>
9
+ app.process("<%= process.name %>-<%=num%>") do |process|
10
+ process.start_command = "<%= process.command.gsub("$PORT", port.to_s) %>"
11
+
12
+ process.working_dir = "<%= engine.directory %>"
13
+ process.daemonize = true
14
+ process.environment = {"PORT" => "<%= port %>"}
15
+ process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
16
+
17
+ process.stdout = process.stderr = "<%= log_root %>/<%= app %>-<%= process.name %>-<%=num%>.log"
18
+
19
+ process.monitor_children do |children|
20
+ children.stop_command "kill -QUIT {{PID}}"
21
+ end
22
+
23
+ process.group = "<%= app %>-<%= process.name %>"
24
+ end
25
+ <% end %>
26
+ <% end %>
27
+ end
@@ -2,4 +2,4 @@ start on starting <%= app %>-<%= process.name %>
2
2
  stop on stopping <%= app %>-<%= process.name %>
3
3
  respawn
4
4
 
5
- exec su - <%= user %> -c 'cd <%= engine.directory %>; export PORT=<%= port %>; <%= process.command %> >> <%= log_root %>/<%=process.name%>-<%=num%>.log 2>&1'
5
+ exec su - <%= user %> -c 'cd <%= engine.directory %>; export PORT=<%= port %>;<% engine.environment.each_pair do |var,env| %> export <%= var.upcase %>=<%= env %>; <% end %> <%= process.command %> >> <%= log_root %>/<%=process.name%>-<%=num%>.log 2>&1'
data/lib/foreman/cli.rb CHANGED
@@ -18,9 +18,9 @@ class Foreman::CLI < Thor
18
18
  check_procfile!
19
19
 
20
20
  if process
21
- engine.execute(process, options)
21
+ engine.execute(process)
22
22
  else
23
- engine.start(options)
23
+ engine.start
24
24
  end
25
25
  end
26
26
 
@@ -40,6 +40,7 @@ class Foreman::CLI < Thor
40
40
  formatter = case format
41
41
  when "inittab" then Foreman::Export::Inittab
42
42
  when "upstart" then Foreman::Export::Upstart
43
+ when "bluepill" then Foreman::Export::Bluepill
43
44
  else error "Unknown export format: #{format}."
44
45
  end
45
46
 
@@ -64,7 +65,7 @@ private ######################################################################
64
65
  end
65
66
 
66
67
  def engine
67
- @engine ||= Foreman::Engine.new(procfile)
68
+ @engine ||= Foreman::Engine.new(procfile, options)
68
69
  end
69
70
 
70
71
  def procfile
@@ -11,14 +11,18 @@ class Foreman::Engine
11
11
 
12
12
  attr_reader :procfile
13
13
  attr_reader :directory
14
+ attr_reader :environment
15
+ attr_reader :options
14
16
 
15
17
  extend Term::ANSIColor
16
18
 
17
19
  COLORS = [ cyan, yellow, green, magenta, red ]
18
20
 
19
- def initialize(procfile)
21
+ def initialize(procfile, options={})
20
22
  @procfile = read_procfile(procfile)
21
23
  @directory = File.expand_path(File.dirname(procfile))
24
+ @options = options
25
+ @environment = read_environment(options[:env])
22
26
  end
23
27
 
24
28
  def processes
@@ -50,13 +54,11 @@ class Foreman::Engine
50
54
  end
51
55
  end
52
56
 
53
- def start(options={})
54
- environment = read_environment(options[:env])
55
-
57
+ def start
56
58
  proctitle "ruby: foreman master"
57
59
 
58
60
  processes_in_order.each do |name, process|
59
- fork process, options, environment
61
+ fork process
60
62
  end
61
63
 
62
64
  trap("TERM") { puts "SIGTERM received"; terminate_gracefully }
@@ -65,10 +67,9 @@ class Foreman::Engine
65
67
  watch_for_termination
66
68
  end
67
69
 
68
- def execute(name, options={})
69
- environment = read_environment(options[:env])
70
+ def execute(name)
70
71
 
71
- fork processes[name], options, environment
72
+ fork processes[name]
72
73
 
73
74
  trap("TERM") { puts "SIGTERM received"; terminate_gracefully }
74
75
  trap("INT") { puts "SIGINT received"; terminate_gracefully }
@@ -84,16 +85,16 @@ class Foreman::Engine
84
85
 
85
86
  private ######################################################################
86
87
 
87
- def fork(process, options={}, environment={})
88
- concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
88
+ def fork(process)
89
+ concurrency = Foreman::Utils.parse_concurrency(@options[:concurrency])
89
90
 
90
91
  1.upto(concurrency[process.name]) do |num|
91
- fork_individual(process, num, port_for(process, num, options[:port]), environment)
92
+ fork_individual(process, num, port_for(process, num, @options[:port]))
92
93
  end
93
94
  end
94
95
 
95
- def fork_individual(process, num, port, environment)
96
- environment.each { |k,v| ENV[k] = v }
96
+ def fork_individual(process, num, port)
97
+ @environment.each { |k,v| ENV[k] = v }
97
98
 
98
99
  ENV["PORT"] = port.to_s
99
100
  ENV["PS"] = "#{process.name}.#{num}"
@@ -7,3 +7,4 @@ end
7
7
  require "foreman/export/base"
8
8
  require "foreman/export/inittab"
9
9
  require "foreman/export/upstart"
10
+ require "foreman/export/bluepill"
@@ -0,0 +1,29 @@
1
+ require "erb"
2
+ require "foreman/export"
3
+
4
+ class Foreman::Export::Bluepill < Foreman::Export::Base
5
+
6
+ def export(location, options={})
7
+ error("Must specify a location") unless location
8
+
9
+ FileUtils.mkdir_p location
10
+
11
+ app = options[:app] || File.basename(engine.directory)
12
+ user = options[:user] || app
13
+ log_root = options[:log] || "/var/log/#{app}"
14
+ template_root = options[:template]
15
+
16
+ Dir["#{location}/#{app}.pill"].each do |file|
17
+ say "cleaning up: #{file}"
18
+ FileUtils.rm(file)
19
+ end
20
+
21
+ concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
22
+
23
+ master_template = export_template("bluepill", "master.pill.erb", template_root)
24
+ master_config = ERB.new(master_template).result(binding)
25
+ write_file "#{location}/#{app}.pill", master_config
26
+
27
+ end
28
+
29
+ end
@@ -1,5 +1,5 @@
1
1
  module Foreman
2
2
 
3
- VERSION = "0.20.0"
3
+ VERSION = "0.21.0"
4
4
 
5
5
  end
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" "August 2011" "Foreman 0.19.0" "Foreman Manual"
4
+ .TH "FOREMAN" "1" "September 2011" "Foreman 0.21.0" "Foreman Manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBforeman\fR \- manage Procfile\-based applications
@@ -79,6 +79,9 @@ Specify an alternate location for the application\'s Procfile\. This file\'s con
79
79
  foreman currently supports the following output formats:
80
80
  .
81
81
  .IP "\(bu" 4
82
+ bluepill
83
+ .
84
+ .IP "\(bu" 4
82
85
  inittab
83
86
  .
84
87
  .IP "\(bu" 4
@@ -19,7 +19,7 @@ describe "Foreman::CLI" do
19
19
 
20
20
  it "runs successfully" do
21
21
  dont_allow(subject).error
22
- mock.instance_of(Foreman::Engine).start({})
22
+ mock.instance_of(Foreman::Engine).start
23
23
  subject.start
24
24
  end
25
25
  end
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
  require "foreman/engine"
3
3
 
4
4
  describe "Foreman::Engine" do
5
- subject { Foreman::Engine.new("Procfile") }
5
+ subject { Foreman::Engine.new("Procfile", {}) }
6
6
 
7
7
  describe "initialize" do
8
8
  describe "without an existing Procfile" do
@@ -37,53 +37,61 @@ describe "Foreman::Engine" do
37
37
  describe "start" do
38
38
  it "forks the processes" do
39
39
  write_procfile
40
- mock(subject).fork(subject.processes["alpha"], {}, {})
41
- mock(subject).fork(subject.processes["bravo"], {}, {})
40
+ mock(subject).fork(subject.processes["alpha"])
41
+ mock(subject).fork(subject.processes["bravo"])
42
42
  mock(subject).watch_for_termination
43
43
  subject.start
44
44
  end
45
45
 
46
46
  it "handles concurrency" do
47
47
  write_procfile
48
- mock(subject).fork_individual(subject.processes["alpha"], 1, 5000, {})
49
- mock(subject).fork_individual(subject.processes["alpha"], 2, 5001, {})
50
- mock(subject).fork_individual(subject.processes["bravo"], 1, 5100, {})
51
- mock(subject).watch_for_termination
52
- subject.start(:concurrency => "alpha=2")
48
+ engine = Foreman::Engine.new("Procfile",:concurrency => "alpha=2")
49
+ mock(engine).fork_individual(engine.processes["alpha"], 1, 5000)
50
+ mock(engine).fork_individual(engine.processes["alpha"], 2, 5001)
51
+ mock(engine).fork_individual(engine.processes["bravo"], 1, 5100)
52
+ mock(engine).watch_for_termination
53
+ engine.start
53
54
  end
54
55
  end
55
56
 
56
57
  describe "execute" do
57
58
  it "runs the processes" do
58
59
  write_procfile
59
- mock(subject).fork(subject.processes["alpha"], {}, {})
60
+ mock(subject).fork(subject.processes["alpha"])
60
61
  mock(subject).watch_for_termination
61
62
  subject.execute("alpha")
62
63
  end
63
64
  end
64
65
 
65
66
  describe "environment" do
67
+
66
68
  before(:each) do
67
69
  write_procfile
68
70
  stub(Process).fork
69
- stub(subject).info
70
- mock(subject).watch_for_termination
71
71
  end
72
72
 
73
73
  it "should read if specified" do
74
74
  File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
75
- subject.execute("alpha", :env => "/tmp/env")
75
+ engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
76
+ stub(engine).info
77
+ mock(engine).watch_for_termination
78
+ engine.environment.should == {"FOO"=>"baz"}
79
+ engine.execute("alpha")
76
80
  end
77
81
 
78
82
  it "should fail if specified and doesnt exist" do
79
- mock(subject).error("No such file: /tmp/env")
80
- subject.execute("alpha", :env => "/tmp/env")
83
+ mock.instance_of(Foreman::Engine).error("No such file: /tmp/env")
84
+ engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
81
85
  end
82
86
 
83
87
  it "should read .env if none specified" do
84
88
  File.open(".env", "w") { |f| f.puts("FOO=qoo") }
85
- mock(subject).fork_individual(anything, anything, anything, { "FOO" => "qoo" })
86
- subject.execute("bravo")
89
+ engine = Foreman::Engine.new("Procfile")
90
+ stub(engine).info
91
+ mock(engine).watch_for_termination
92
+ mock(engine).fork_individual(anything, anything, anything)
93
+ engine.environment.should == {"FOO"=>"qoo"}
94
+ engine.execute("bravo")
87
95
  end
88
96
  end
89
97
  end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/bluepill"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Bluepill do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
8
+ let(:engine) { Foreman::Engine.new(procfile) }
9
+ let(:bluepill) { Foreman::Export::Bluepill.new(engine) }
10
+
11
+ before(:each) { load_export_templates_into_fakefs("bluepill") }
12
+ before(:each) { stub(bluepill).say }
13
+
14
+ it "exports to the filesystem" do
15
+ bluepill.export("/tmp/init")
16
+
17
+ File.read("/tmp/init/app.pill").should == example_export_file("bluepill/app.pill")
18
+ end
19
+
20
+ end
@@ -0,0 +1,65 @@
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
+ app.process("bravo-1") do |process|
48
+ process.start_command = "./bravo"
49
+
50
+ process.working_dir = "/tmp/app"
51
+ process.daemonize = true
52
+ process.environment = {"PORT" => "5100"}
53
+ process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
54
+
55
+ process.stdout = process.stderr = "/var/log/app/app-bravo-1.log"
56
+
57
+ process.monitor_children do |children|
58
+ children.stop_command "kill -QUIT {{PID}}"
59
+ end
60
+
61
+ process.group = "app-bravo"
62
+ end
63
+
64
+
65
+ 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.20.0
4
+ version: 0.21.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-22 00:00:00.000000000 -04:00
13
- default_executable:
12
+ date: 2011-09-09 00:00:00.000000000Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: term-ansicolor
17
- requirement: &70126646392860 !ruby/object:Gem::Requirement
16
+ requirement: &70144026259620 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ~>
@@ -22,10 +21,10 @@ dependencies:
22
21
  version: 1.0.5
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *70126646392860
24
+ version_requirements: *70144026259620
26
25
  - !ruby/object:Gem::Dependency
27
26
  name: thor
28
- requirement: &70126646392380 !ruby/object:Gem::Requirement
27
+ requirement: &70144026258680 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
30
  - - ! '>='
@@ -33,10 +32,10 @@ dependencies:
33
32
  version: 0.13.6
34
33
  type: :runtime
35
34
  prerelease: false
36
- version_requirements: *70126646392380
35
+ version_requirements: *70144026258680
37
36
  - !ruby/object:Gem::Dependency
38
37
  name: parka
39
- requirement: &70126646392000 !ruby/object:Gem::Requirement
38
+ requirement: &70144026257860 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
42
41
  - - ! '>='
@@ -44,10 +43,10 @@ dependencies:
44
43
  version: '0'
45
44
  type: :development
46
45
  prerelease: false
47
- version_requirements: *70126646392000
46
+ version_requirements: *70144026257860
48
47
  - !ruby/object:Gem::Dependency
49
48
  name: rake
50
- requirement: &70126646391520 !ruby/object:Gem::Requirement
49
+ requirement: &70144026257080 !ruby/object:Gem::Requirement
51
50
  none: false
52
51
  requirements:
53
52
  - - ! '>='
@@ -55,10 +54,10 @@ dependencies:
55
54
  version: '0'
56
55
  type: :development
57
56
  prerelease: false
58
- version_requirements: *70126646391520
57
+ version_requirements: *70144026257080
59
58
  - !ruby/object:Gem::Dependency
60
59
  name: ronn
61
- requirement: &70126646391100 !ruby/object:Gem::Requirement
60
+ requirement: &70144026256460 !ruby/object:Gem::Requirement
62
61
  none: false
63
62
  requirements:
64
63
  - - ! '>='
@@ -66,10 +65,10 @@ dependencies:
66
65
  version: '0'
67
66
  type: :development
68
67
  prerelease: false
69
- version_requirements: *70126646391100
68
+ version_requirements: *70144026256460
70
69
  - !ruby/object:Gem::Dependency
71
70
  name: fakefs
72
- requirement: &70126646390600 !ruby/object:Gem::Requirement
71
+ requirement: &70144026255820 !ruby/object:Gem::Requirement
73
72
  none: false
74
73
  requirements:
75
74
  - - ~>
@@ -77,10 +76,10 @@ dependencies:
77
76
  version: 0.2.1
78
77
  type: :development
79
78
  prerelease: false
80
- version_requirements: *70126646390600
79
+ version_requirements: *70144026255820
81
80
  - !ruby/object:Gem::Dependency
82
81
  name: rcov
83
- requirement: &70126646389740 !ruby/object:Gem::Requirement
82
+ requirement: &70144026255120 !ruby/object:Gem::Requirement
84
83
  none: false
85
84
  requirements:
86
85
  - - ~>
@@ -88,10 +87,10 @@ dependencies:
88
87
  version: 0.9.8
89
88
  type: :development
90
89
  prerelease: false
91
- version_requirements: *70126646389740
90
+ version_requirements: *70144026255120
92
91
  - !ruby/object:Gem::Dependency
93
92
  name: rr
94
- requirement: &70126646389100 !ruby/object:Gem::Requirement
93
+ requirement: &70144026254400 !ruby/object:Gem::Requirement
95
94
  none: false
96
95
  requirements:
97
96
  - - ~>
@@ -99,10 +98,10 @@ dependencies:
99
98
  version: 1.0.2
100
99
  type: :development
101
100
  prerelease: false
102
- version_requirements: *70126646389100
101
+ version_requirements: *70144026254400
103
102
  - !ruby/object:Gem::Dependency
104
103
  name: rspec
105
- requirement: &70126646388400 !ruby/object:Gem::Requirement
104
+ requirement: &70144026253300 !ruby/object:Gem::Requirement
106
105
  none: false
107
106
  requirements:
108
107
  - - ~>
@@ -110,7 +109,7 @@ dependencies:
110
109
  version: 2.6.0
111
110
  type: :development
112
111
  prerelease: false
113
- version_requirements: *70126646388400
112
+ version_requirements: *70144026253300
114
113
  description: Process manager for applications with multiple components
115
114
  email: ddollar@gmail.com
116
115
  executables:
@@ -125,12 +124,14 @@ files:
125
124
  - data/example/Procfile
126
125
  - data/example/Procfile.without_colon
127
126
  - data/example/ticker
127
+ - data/export/bluepill/master.pill.erb
128
128
  - data/export/upstart/master.conf.erb
129
129
  - data/export/upstart/process.conf.erb
130
130
  - data/export/upstart/process_master.conf.erb
131
131
  - lib/foreman/cli.rb
132
132
  - lib/foreman/engine.rb
133
133
  - lib/foreman/export/base.rb
134
+ - lib/foreman/export/bluepill.rb
134
135
  - lib/foreman/export/inittab.rb
135
136
  - lib/foreman/export/upstart.rb
136
137
  - lib/foreman/export.rb
@@ -141,10 +142,12 @@ files:
141
142
  - README.markdown
142
143
  - spec/foreman/cli_spec.rb
143
144
  - spec/foreman/engine_spec.rb
145
+ - spec/foreman/export/bluepill_spec.rb
144
146
  - spec/foreman/export/upstart_spec.rb
145
147
  - spec/foreman/export_spec.rb
146
148
  - spec/foreman/process_spec.rb
147
149
  - spec/foreman_spec.rb
150
+ - spec/resources/export/bluepill/app.pill
148
151
  - spec/resources/export/upstart/app-alpha-1.conf
149
152
  - spec/resources/export/upstart/app-alpha-2.conf
150
153
  - spec/resources/export/upstart/app-alpha.conf
@@ -153,7 +156,6 @@ files:
153
156
  - spec/resources/export/upstart/app.conf
154
157
  - spec/spec_helper.rb
155
158
  - man/foreman.1
156
- has_rdoc: true
157
159
  homepage: http://github.com/ddollar/foreman
158
160
  licenses: []
159
161
  post_install_message:
@@ -174,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
176
  version: '0'
175
177
  requirements: []
176
178
  rubyforge_project:
177
- rubygems_version: 1.6.2
179
+ rubygems_version: 1.8.10
178
180
  signing_key:
179
181
  specification_version: 3
180
182
  summary: Process manager for applications with multiple components