foreman 0.20.0 → 0.21.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.
@@ -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