foreman 0.8.0 → 0.9.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ ticker ./ticker $PORT
2
+ error ./error
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ puts "will error in 10s"
4
+ sleep 5
5
+ raise "Dying"
@@ -0,0 +1,4 @@
1
+ tick
2
+ tick
3
+ ./never_die:6:in `sleep': Interrupt
4
+ from ./never_die:6
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ while true
4
+ puts "tick: #{ARGV.inspect}"
5
+ sleep 1
6
+ end
@@ -1,6 +1,6 @@
1
1
  module Foreman
2
2
 
3
- VERSION = "0.8.0"
3
+ VERSION = "0.9.0.beta.1"
4
4
 
5
5
  class AppDoesNotExist < Exception; end
6
6
 
@@ -5,7 +5,7 @@ require "thor"
5
5
 
6
6
  class Foreman::CLI < Thor
7
7
 
8
- class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: ./Procfile"
8
+ class_option :pstypes, :type => :string, :aliases => "-f", :desc => "Default: Pstypes"
9
9
 
10
10
  desc "start [PROCESS]", "Start the application, or a specific process"
11
11
 
@@ -14,7 +14,7 @@ class Foreman::CLI < Thor
14
14
  :banner => '"alpha=5,bar=3"'
15
15
 
16
16
  def start(process=nil)
17
- check_procfile!
17
+ check_pstypes!
18
18
 
19
19
  if process
20
20
  engine.execute(process, options)
@@ -33,7 +33,7 @@ class Foreman::CLI < Thor
33
33
  :banner => '"alpha=5,bar=3"'
34
34
 
35
35
  def export(format, location=nil)
36
- check_procfile!
36
+ check_pstypes!
37
37
 
38
38
  formatter = case format
39
39
  when "upstart" then Foreman::Export::Upstart
@@ -49,16 +49,16 @@ class Foreman::CLI < Thor
49
49
 
50
50
  private ######################################################################
51
51
 
52
- def check_procfile!
53
- error("Procfile does not exist.") unless File.exist?(procfile)
52
+ def check_pstypes!
53
+ error("#{pstypes} does not exist.") unless File.exist?(pstypes)
54
54
  end
55
55
 
56
56
  def engine
57
- @engine ||= Foreman::Engine.new(procfile)
57
+ @engine ||= Foreman::Engine.new(pstypes)
58
58
  end
59
59
 
60
- def procfile
61
- options[:procfile] || "./Procfile"
60
+ def pstypes
61
+ options[:pstypes] || "Pstypes"
62
62
  end
63
63
 
64
64
  private ######################################################################
@@ -68,8 +68,8 @@ private ######################################################################
68
68
  exit 1
69
69
  end
70
70
 
71
- def procfile_exists?(procfile)
72
- File.exist?(procfile)
71
+ def pstypes_exists?(pstypes)
72
+ File.exist?(pstypes)
73
73
  end
74
74
 
75
75
  end
@@ -8,21 +8,21 @@ require "fileutils"
8
8
 
9
9
  class Foreman::Engine
10
10
 
11
- attr_reader :procfile
11
+ attr_reader :pstypes
12
12
  attr_reader :directory
13
13
 
14
14
  extend Term::ANSIColor
15
15
 
16
16
  COLORS = [ cyan, yellow, green, magenta, red ]
17
17
 
18
- def initialize(procfile)
19
- @procfile = read_procfile(procfile)
20
- @directory = File.expand_path(File.dirname(procfile))
18
+ def initialize(pstypes)
19
+ @pstypes = read_pstypes(pstypes)
20
+ @directory = File.expand_path(File.dirname(pstypes))
21
21
  end
22
22
 
23
23
  def processes
24
24
  @processes ||= begin
25
- procfile.split("\n").inject({}) do |hash, line|
25
+ pstypes.split("\n").inject({}) do |hash, line|
26
26
  next if line.strip == ""
27
27
  name, command = line.split(" ", 2)
28
28
  process = Foreman::Process.new(name, command)
@@ -66,36 +66,40 @@ private ######################################################################
66
66
  concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
67
67
 
68
68
  1.upto(concurrency[process.name]) do |num|
69
- fork_individual(process, port_for(process, num, options[:port]))
69
+ fork_individual(process, num, port_for(process, num, options[:port]))
70
70
  end
71
71
  end
72
72
 
73
- def fork_individual(process, port)
73
+ def fork_individual(process, num, port)
74
74
  ENV["PORT"] = port.to_s
75
+ ENV["PS"] = "#{process.name}.#{num}"
75
76
 
76
77
  pid = Process.fork do
77
78
  run(process)
78
79
  end
79
80
 
80
- info "started with pid #{pid}", process
81
+ info "started with pid #{pid}, PORT=#{port}", process
81
82
  running_processes[pid] = process
82
83
  end
83
84
 
84
85
  def run(process, log_to_file=true)
85
86
  proctitle "ruby: foreman #{process.name}"
86
87
 
87
- Dir.chdir directory do
88
- FileUtils.mkdir_p "log"
89
- command = process.command
88
+ begin
89
+ Dir.chdir directory do
90
+ FileUtils.mkdir_p "log"
91
+ command = process.command
90
92
 
91
- begin
92
93
  PTY.spawn("#{process.command} 2>&1") do |stdin, stdout, pid|
93
94
  until stdin.eof?
94
95
  info stdin.gets, process
95
96
  end
96
97
  end
97
- rescue PTY::ChildExited, Interrupt
98
+ end
99
+ rescue PTY::ChildExited, Interrupt
100
+ begin
98
101
  info "process exiting", process
102
+ rescue Interrupt
99
103
  end
100
104
  end
101
105
  end
@@ -125,8 +129,8 @@ private ######################################################################
125
129
  end
126
130
 
127
131
  def pad_process_name(process)
128
- name = process ? "#{process.name}:#{ENV["PORT"]}" : "system"
129
- name.ljust(longest_process_name + 6) # add 6 for port padding
132
+ name = process ? "#{ENV["PS"]}" : "system"
133
+ name.ljust(longest_process_name + 3) # add 3 for process number padding
130
134
  end
131
135
 
132
136
  def print_info
@@ -140,8 +144,8 @@ private ######################################################################
140
144
  $0 = title
141
145
  end
142
146
 
143
- def read_procfile(procfile)
144
- File.read(procfile)
147
+ def read_pstypes(pstypes)
148
+ File.read(pstypes)
145
149
  end
146
150
 
147
151
  def watch_for_termination
@@ -24,7 +24,7 @@ private ######################################################################
24
24
  end
25
25
 
26
26
  def export_template(name)
27
- File.read(File.expand_path("../../../../export/#{name}", __FILE__))
27
+ File.read(File.expand_path("../../../../data/export/#{name}", __FILE__))
28
28
  end
29
29
 
30
30
  def write_file(filename, contents)
@@ -27,8 +27,8 @@ class Foreman::Export::Inittab < Foreman::Export::Base
27
27
  inittab = inittab.join("\n") + "\n"
28
28
 
29
29
  if fname
30
- FileUtils.mkdir_p(log_root)
31
- FileUtils.chown(user, nil, log_root)
30
+ FileUtils.mkdir_p(log_root) rescue error "could not create #{log_root}"
31
+ FileUtils.chown(user, nil, log_root) rescue error "could not chown #{log_root} to #{user}"
32
32
  write_file(fname, inittab)
33
33
  else
34
34
  puts inittab
@@ -1,10 +1,10 @@
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" "June 2010" "Foreman 0.6.0" "Foreman Manual"
4
+ .TH "FOREMAN" "1" "October 2010" "Foreman 0.8.0" "Foreman Manual"
5
5
  .
6
6
  .SH "NAME"
7
- \fBforeman\fR \- manage Procfile\-based applications
7
+ \fBforeman\fR \- manage Pstypes\-based applications
8
8
  .
9
9
  .SH "SYNOPSIS"
10
10
  \fBforeman start [process]\fR
@@ -13,13 +13,13 @@
13
13
  \fBforeman export <format> [location]\fR
14
14
  .
15
15
  .SH "DESCRIPTION"
16
- \fBForeman\fR is a manager for Procfile\-based applications\. Its aim is to abstract away the details of the Procfile format, and allow you to either run your application directly or export it to some other process management format\.
16
+ \fBForeman\fR is a manager for Pstypes\-based applications\. Its aim is to abstract away the details of the Pstypes format, and allow you to either run your application directly or export it to some other process management format\.
17
17
  .
18
18
  .SH "RUNNING"
19
19
  \fBforeman start\fR is used to run your application directly from the command line\.
20
20
  .
21
21
  .P
22
- If no additional parameters are passed, foreman will run one instance of each type of process defined in your Procfile\.
22
+ If no additional parameters are passed, foreman will run one instance of each type of process defined in your Pstypes\.
23
23
  .
24
24
  .P
25
25
  If a parameter is passed, foreman will run one instance of the specified application type\.
@@ -28,8 +28,12 @@ If a parameter is passed, foreman will run one instance of the specified applica
28
28
  The following options control how the application is run:
29
29
  .
30
30
  .TP
31
- \fB\-s\fR, \fB\-\-screen\fR
32
- Run the application as a series of screen windows rather than interleaved in stdout\.
31
+ \fB\-c\fR, \fB\-\-concurrency\fR
32
+ Specify the number of each process type to run\. The value passed in should be in the format \fBprocess=num,process=num\fR
33
+ .
34
+ .TP
35
+ \fB\-p\fR, \fB\-\-port\fR
36
+ Specify which port to use as the base for this application\. Should be a multiple of 1000\.
33
37
  .
34
38
  .SH "EXPORTING"
35
39
  \fBforeman export\fR is used to export your application to another process management format\.
@@ -64,8 +68,8 @@ Specify the user the application should be run as\. Defaults to the app name
64
68
  These options control all modes of foreman\'s operation\.
65
69
  .
66
70
  .TP
67
- \fB\-f\fR, \fB\-\-procfile\fR
68
- Specify an alternate location for the application\'s Procfile\. This file\'s containing directory will be assumed to be the root directory of the application\.
71
+ \fB\-f\fR, \fB\-\-pstypes\fR
72
+ Specify an alternate location for the application\'s Pstypes\. This file\'s containing directory will be assumed to be the root directory of the application\.
69
73
  .
70
74
  .SH "EXPORT FORMATS"
71
75
  foreman currently supports the following output formats:
@@ -106,8 +110,8 @@ Will create a series of upstart scripts in the location you specify\. Scripts wi
106
110
  .P
107
111
  \fBrestart appname\-processname\-3\fR
108
112
  .
109
- .SH "PROCFILE"
110
- A Procfile should contain both a name for the process and the command used to run it\.
113
+ .SH "PSTYPES"
114
+ A Pstyes file should contain both a name for the process and the command used to run it\.
111
115
  .
112
116
  .IP "" 4
113
117
  .
@@ -147,13 +151,13 @@ $ foreman export upstart /etc/init
147
151
  .IP "" 0
148
152
  .
149
153
  .P
150
- Run one process type from the application defined in a specific Procfile:
154
+ Run one process type from the application defined in a specific Pstypes:
151
155
  .
152
156
  .IP "" 4
153
157
  .
154
158
  .nf
155
159
 
156
- $ foreman start alpha \-p ~/app/Procfile
160
+ $ foreman start alpha \-p ~/app/Pstypes
157
161
  .
158
162
  .fi
159
163
  .
@@ -5,17 +5,17 @@ describe "Foreman::CLI" do
5
5
  subject { Foreman::CLI.new }
6
6
 
7
7
  describe "start" do
8
- describe "with a non-existent Procfile" do
8
+ describe "with a non-existent Pstypes" do
9
9
  it "prints an error" do
10
- mock_error(subject, "Procfile does not exist.") do
10
+ mock_error(subject, "Pstypes does not exist.") do
11
11
  dont_allow.instance_of(Foreman::Engine).start
12
12
  subject.start
13
13
  end
14
14
  end
15
15
  end
16
16
 
17
- describe "with a Procfile" do
18
- before(:each) { write_procfile }
17
+ describe "with a Pstypes" do
18
+ before(:each) { write_pstypes }
19
19
 
20
20
  it "runs successfully" do
21
21
  dont_allow(subject).error
@@ -26,17 +26,17 @@ describe "Foreman::CLI" do
26
26
  end
27
27
 
28
28
  describe "export" do
29
- describe "with a non-existent Procfile" do
29
+ describe "with a non-existent Pstypes" do
30
30
  it "prints an error" do
31
- mock_error(subject, "Procfile does not exist.") do
31
+ mock_error(subject, "Pstypes does not exist.") do
32
32
  dont_allow.instance_of(Foreman::Engine).export
33
33
  subject.export("testapp")
34
34
  end
35
35
  end
36
36
  end
37
37
 
38
- describe "with a Procfile" do
39
- before(:each) { write_procfile }
38
+ describe "with a Pstypes" do
39
+ before(:each) { write_pstypes }
40
40
 
41
41
  describe "with an invalid formatter" do
42
42
  it "prints an error" do
@@ -2,18 +2,18 @@ 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("Pstypes") }
6
6
 
7
7
  describe "initialize" do
8
- describe "without an existing Procfile" do
8
+ describe "without an existing Pstypes" do
9
9
  it "raises an error" do
10
10
  lambda { subject }.should raise_error
11
11
  end
12
12
  end
13
13
 
14
- describe "with a Procfile" do
14
+ describe "with a Pstypes" do
15
15
  it "reads the processes" do
16
- write_procfile
16
+ write_pstypes
17
17
  subject.processes["alpha"].command.should == "./alpha"
18
18
  subject.processes["bravo"].command.should == "./bravo"
19
19
  end
@@ -22,7 +22,7 @@ describe "Foreman::Engine" do
22
22
 
23
23
  describe "start" do
24
24
  it "forks the processes" do
25
- write_procfile
25
+ write_pstypes
26
26
  mock(subject).fork(subject.processes["alpha"], {})
27
27
  mock(subject).fork(subject.processes["bravo"], {})
28
28
  mock(subject).watch_for_termination
@@ -30,7 +30,7 @@ describe "Foreman::Engine" do
30
30
  end
31
31
 
32
32
  it "handles concurrency" do
33
- write_procfile
33
+ write_pstypes
34
34
  mock(subject).fork_individual(subject.processes["alpha"], 5000)
35
35
  mock(subject).fork_individual(subject.processes["alpha"], 5001)
36
36
  mock(subject).fork_individual(subject.processes["bravo"], 5100)
@@ -41,7 +41,7 @@ describe "Foreman::Engine" do
41
41
 
42
42
  describe "execute" do
43
43
  it "runs the processes" do
44
- write_procfile
44
+ write_pstypes
45
45
  mock(subject).fork(subject.processes["alpha"], {})
46
46
  mock(subject).watch_for_termination
47
47
  subject.execute("alpha")
@@ -24,8 +24,8 @@ def write_foreman_config(app)
24
24
  end
25
25
  end
26
26
 
27
- def write_procfile(procfile="Procfile")
28
- File.open(procfile, "w") do |file|
27
+ def write_pstypes(pstypes="Pstypes")
28
+ File.open(pstypes, "w") do |file|
29
29
  file.puts "alpha ./alpha"
30
30
  file.puts "bravo ./bravo"
31
31
  end
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman
3
3
  version: !ruby/object:Gem::Version
4
- hash: 63
5
- prerelease: false
4
+ hash: 62196273
5
+ prerelease: true
6
6
  segments:
7
7
  - 0
8
- - 8
8
+ - 9
9
9
  - 0
10
- version: 0.8.0
10
+ - beta
11
+ - 1
12
+ version: 0.9.0.beta.1
11
13
  platform: ruby
12
14
  authors:
13
15
  - |
@@ -17,7 +19,7 @@ autorequire:
17
19
  bindir: bin
18
20
  cert_chain: []
19
21
 
20
- date: 2010-09-20 00:00:00 -04:00
22
+ date: 2010-10-15 00:00:00 -07:00
21
23
  default_executable:
22
24
  dependencies:
23
25
  - !ruby/object:Gem::Dependency
@@ -50,6 +52,20 @@ dependencies:
50
52
  version_requirements: *id002
51
53
  - !ruby/object:Gem::Dependency
52
54
  requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ name: ronn
65
+ prerelease: false
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ requirement: &id004 !ruby/object:Gem::Requirement
53
69
  none: false
54
70
  requirements:
55
71
  - - ~>
@@ -63,9 +79,9 @@ dependencies:
63
79
  type: :development
64
80
  name: fakefs
65
81
  prerelease: false
66
- version_requirements: *id003
82
+ version_requirements: *id004
67
83
  - !ruby/object:Gem::Dependency
68
- requirement: &id004 !ruby/object:Gem::Requirement
84
+ requirement: &id005 !ruby/object:Gem::Requirement
69
85
  none: false
70
86
  requirements:
71
87
  - - ~>
@@ -79,9 +95,9 @@ dependencies:
79
95
  type: :development
80
96
  name: rcov
81
97
  prerelease: false
82
- version_requirements: *id004
98
+ version_requirements: *id005
83
99
  - !ruby/object:Gem::Dependency
84
- requirement: &id005 !ruby/object:Gem::Requirement
100
+ requirement: &id006 !ruby/object:Gem::Requirement
85
101
  none: false
86
102
  requirements:
87
103
  - - ~>
@@ -95,9 +111,9 @@ dependencies:
95
111
  type: :development
96
112
  name: rr
97
113
  prerelease: false
98
- version_requirements: *id005
114
+ version_requirements: *id006
99
115
  - !ruby/object:Gem::Dependency
100
- requirement: &id006 !ruby/object:Gem::Requirement
116
+ requirement: &id007 !ruby/object:Gem::Requirement
101
117
  none: false
102
118
  requirements:
103
119
  - - ~>
@@ -113,9 +129,9 @@ dependencies:
113
129
  type: :development
114
130
  name: rspec
115
131
  prerelease: false
116
- version_requirements: *id006
132
+ version_requirements: *id007
117
133
  - !ruby/object:Gem::Dependency
118
- requirement: &id007 !ruby/object:Gem::Requirement
134
+ requirement: &id008 !ruby/object:Gem::Requirement
119
135
  none: false
120
136
  requirements:
121
137
  - - ~>
@@ -129,9 +145,9 @@ dependencies:
129
145
  type: :runtime
130
146
  name: term-ansicolor
131
147
  prerelease: false
132
- version_requirements: *id007
148
+ version_requirements: *id008
133
149
  - !ruby/object:Gem::Dependency
134
- requirement: &id008 !ruby/object:Gem::Requirement
150
+ requirement: &id009 !ruby/object:Gem::Requirement
135
151
  none: false
136
152
  requirements:
137
153
  - - ~>
@@ -145,7 +161,7 @@ dependencies:
145
161
  type: :runtime
146
162
  name: thor
147
163
  prerelease: false
148
- version_requirements: *id008
164
+ version_requirements: *id009
149
165
  description: Process manager for applications with multiple components
150
166
  email: |
151
167
  <ddollar@gmail.com>
@@ -159,10 +175,14 @@ extra_rdoc_files: []
159
175
  files:
160
176
  - bin/foreman
161
177
  - man/foreman.1
162
- - export/upstart/master.conf.erb
163
- - export/upstart/process.conf.erb
164
- - export/upstart/process_master.conf.erb
165
178
  - README.markdown
179
+ - data/example/Pstypes
180
+ - data/example/error
181
+ - data/example/log/neverdie.log
182
+ - data/example/ticker
183
+ - data/export/upstart/master.conf.erb
184
+ - data/export/upstart/process.conf.erb
185
+ - data/export/upstart/process_master.conf.erb
166
186
  - lib/foreman.rb
167
187
  - lib/foreman/cli.rb
168
188
  - lib/foreman/engine.rb
@@ -200,12 +220,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
200
220
  required_rubygems_version: !ruby/object:Gem::Requirement
201
221
  none: false
202
222
  requirements:
203
- - - ">="
223
+ - - ">"
204
224
  - !ruby/object:Gem::Version
205
- hash: 3
225
+ hash: 25
206
226
  segments:
207
- - 0
208
- version: "0"
227
+ - 1
228
+ - 3
229
+ - 1
230
+ version: 1.3.1
209
231
  requirements: []
210
232
 
211
233
  rubyforge_project: nowarning