foreman 0.57.0 → 0.58.0
Sign up to get free protection for your applications and to get access to all the features.
- data/data/export/launchd/launchd.plist.erb +12 -1
- data/lib/foreman/capistrano.rb +54 -0
- data/lib/foreman/cli.rb +2 -1
- data/lib/foreman/engine.rb +0 -1
- data/lib/foreman/env.rb +3 -1
- data/lib/foreman/export/base.rb +1 -1
- data/lib/foreman/export/inittab.rb +10 -1
- data/lib/foreman/export/launchd.rb +2 -0
- data/lib/foreman/version.rb +1 -1
- data/man/foreman.1 +1 -1
- data/spec/foreman/cli_spec.rb +5 -0
- data/spec/foreman/engine_spec.rb +8 -0
- data/spec/foreman/export/launchd_spec.rb +10 -0
- data/spec/resources/export/inittab/inittab.concurrency +2 -2
- data/spec/resources/export/inittab/inittab.default +2 -2
- data/spec/resources/export/launchd/launchd-a.default +7 -0
- data/spec/resources/export/launchd/launchd-b.default +7 -0
- data/spec/resources/export/launchd/launchd-c.default +30 -0
- data/spec/spec_helper.rb +6 -0
- metadata +6 -11
@@ -4,14 +4,25 @@
|
|
4
4
|
<dict>
|
5
5
|
<key>Label</key>
|
6
6
|
<string><%= "#{app}-#{name}-#{num}" %></string>
|
7
|
+
<key>EnvironmentVariables</key>
|
8
|
+
<dict>
|
9
|
+
<%- engine.env.merge("PORT" => port).each_pair do |var,env| -%>
|
10
|
+
<key><%= var.upcase %></key>
|
11
|
+
<string><%= env %></string>
|
12
|
+
<%- end -%>
|
13
|
+
</dict>
|
7
14
|
<key>ProgramArguments</key>
|
8
15
|
<array>
|
9
|
-
|
16
|
+
<%- command_args.each do |command| -%>
|
17
|
+
<string><%= command %></string>
|
18
|
+
<%- end -%>
|
10
19
|
</array>
|
11
20
|
<key>KeepAlive</key>
|
12
21
|
<true/>
|
13
22
|
<key>RunAtLoad</key>
|
14
23
|
<true/>
|
24
|
+
<key>StandardOutPath</key>
|
25
|
+
<string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
|
15
26
|
<key>StandardErrorPath</key>
|
16
27
|
<string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
|
17
28
|
<key>UserName</key>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
if defined?(Capistrano)
|
2
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
3
|
+
|
4
|
+
namespace :foreman do
|
5
|
+
desc <<-DESC
|
6
|
+
Export the Procfile to upstart. Will use sudo if available.
|
7
|
+
|
8
|
+
You can override any of these defaults by setting the variables shown below.
|
9
|
+
|
10
|
+
set :foreman_format, "upstart"
|
11
|
+
set :foreman_location, "/etc/init"
|
12
|
+
set :foreman_procfile, "Procfile"
|
13
|
+
set :foreman_app, application
|
14
|
+
set :foreman_user, user
|
15
|
+
set :foreman_log, "#{shared_path}/log"
|
16
|
+
set :foreman_concurrency, false
|
17
|
+
DESC
|
18
|
+
task :export, :roles => :app do
|
19
|
+
bundle_cmd = fetch(:bundle_cmd, "bundle")
|
20
|
+
foreman_format = fetch(:foreman_format, "upstart")
|
21
|
+
foreman_location = fetch(:foreman_location, "/etc/init")
|
22
|
+
foreman_procfile = fetch(:foreman_procfile, "Procfile")
|
23
|
+
foreman_app = fetch(:foreman_app, application)
|
24
|
+
foreman_user = fetch(:foreman_user, user)
|
25
|
+
foreman_log = fetch(:foreman_log, "#{shared_path}/log")
|
26
|
+
foreman_concurrency = fetch(:foreman_concurrency, false)
|
27
|
+
|
28
|
+
args = ["#{foreman_format} #{foreman_location}"]
|
29
|
+
args << "-f #{foreman_procfile}"
|
30
|
+
args << "-a #{foreman_app}"
|
31
|
+
args << "-u #{foreman_user}"
|
32
|
+
args << "-l #{foreman_log}"
|
33
|
+
args << "-c #{foreman_concurrency}" if foreman_concurrency
|
34
|
+
run "cd #{release_path} && #{sudo} #{bundle_cmd} exec foreman export #{args.join(' ')}"
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Start the application services"
|
38
|
+
task :start, :roles => :app do
|
39
|
+
run "#{sudo} start #{application}"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Stop the application services"
|
43
|
+
task :stop, :roles => :app do
|
44
|
+
run "#{sudo} stop #{application}"
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Restart the application services"
|
48
|
+
task :restart, :roles => :app do
|
49
|
+
run "#{sudo} start #{application} || #{sudo} restart #{application}"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/foreman/cli.rb
CHANGED
@@ -86,6 +86,7 @@ class Foreman::CLI < Thor
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
Process.wait(pid)
|
89
|
+
exit $?.exitstatus
|
89
90
|
end
|
90
91
|
|
91
92
|
desc "version", "Display Foreman gem version"
|
@@ -129,7 +130,7 @@ private ######################################################################
|
|
129
130
|
def procfile
|
130
131
|
case
|
131
132
|
when options[:procfile] then options[:procfile]
|
132
|
-
when options[:root] then File.expand_path(File.join(options[:
|
133
|
+
when options[:root] then File.expand_path(File.join(options[:root], "Procfile"))
|
133
134
|
else "Procfile"
|
134
135
|
end
|
135
136
|
end
|
data/lib/foreman/engine.rb
CHANGED
data/lib/foreman/env.rb
CHANGED
@@ -9,8 +9,10 @@ class Foreman::Env
|
|
9
9
|
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
|
10
10
|
key = $1
|
11
11
|
case val = $2
|
12
|
+
# Remove single quotes
|
12
13
|
when /\A'(.*)'\z/ then ax[key] = $1
|
13
|
-
|
14
|
+
# Remove double quotes and unescape string preserving newline characters
|
15
|
+
when /\A"(.*)"\z/ then ax[key] = $1.gsub('\n', "\n").gsub(/\\(.)/, '\1')
|
14
16
|
else ax[key] = val
|
15
17
|
end
|
16
18
|
end
|
data/lib/foreman/export/base.rb
CHANGED
@@ -119,7 +119,7 @@ private ######################################################################
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def write_template(name, target, binding)
|
122
|
-
compiled = ERB.new(export_template(name)).result(binding)
|
122
|
+
compiled = ERB.new(export_template(name), nil, '-').result(binding)
|
123
123
|
write_file target, compiled
|
124
124
|
end
|
125
125
|
|
@@ -13,7 +13,16 @@ class Foreman::Export::Inittab < Foreman::Export::Base
|
|
13
13
|
1.upto(engine.formation[name]) do |num|
|
14
14
|
id = app.slice(0, 2).upcase + sprintf("%02d", index)
|
15
15
|
port = engine.port_for(process, num)
|
16
|
-
|
16
|
+
|
17
|
+
commands = []
|
18
|
+
commands << "cd #{engine.root}"
|
19
|
+
commands << "export PORT=#{port}"
|
20
|
+
engine.env.each_pair do |var, env|
|
21
|
+
commands << "export #{var.upcase}=#{shell_quote(env)}"
|
22
|
+
end
|
23
|
+
commands << "#{process.command} >> #{log}/#{name}-#{num}.log 2>&1"
|
24
|
+
|
25
|
+
inittab << "#{id}:4:respawn:/bin/su - #{user} -c '#{commands.join(";")}'"
|
17
26
|
index += 1
|
18
27
|
end
|
19
28
|
end
|
@@ -7,6 +7,8 @@ class Foreman::Export::Launchd < Foreman::Export::Base
|
|
7
7
|
super
|
8
8
|
engine.each_process do |name, process|
|
9
9
|
1.upto(engine.formation[name]) do |num|
|
10
|
+
port = engine.port_for(process, num)
|
11
|
+
command_args = process.command.split(" ")
|
10
12
|
write_template "launchd/launchd.plist.erb", "#{app}-#{name}-#{num}.plist", binding
|
11
13
|
end
|
12
14
|
end
|
data/lib/foreman/version.rb
CHANGED
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" "July 2012" "Foreman 0.
|
4
|
+
.TH "FOREMAN" "1" "July 2012" "Foreman 0.57.0" "Foreman Manual"
|
5
5
|
.
|
6
6
|
.SH "NAME"
|
7
7
|
\fBforeman\fR \- manage Procfile\-based applications
|
data/spec/foreman/cli_spec.rb
CHANGED
@@ -72,6 +72,11 @@ describe "Foreman::CLI", :fakefs do
|
|
72
72
|
it "includes the environment" do
|
73
73
|
forked_foreman("run #{resource_path("bin/env FOO")} -e #{resource_path(".env")}").should == "bar\n"
|
74
74
|
end
|
75
|
+
|
76
|
+
it "exits with the same exit code as the command" do
|
77
|
+
fork_and_get_exitstatus("run echo 1").should == 0
|
78
|
+
fork_and_get_exitstatus("run date 'invalid_date'").should == 1
|
79
|
+
end
|
75
80
|
end
|
76
81
|
|
77
82
|
describe "version" do
|
data/spec/foreman/engine_spec.rb
CHANGED
@@ -90,6 +90,14 @@ describe "Foreman::Engine", :fakefs do
|
|
90
90
|
subject.env["OTHER"].should == 'escaped"quote'
|
91
91
|
end
|
92
92
|
|
93
|
+
it "should handle multiline strings" do
|
94
|
+
File.open("/tmp/env", "w") do |f|
|
95
|
+
f.puts 'FOO="bar\nbaz"'
|
96
|
+
end
|
97
|
+
subject.load_env "/tmp/env"
|
98
|
+
subject.env["FOO"].should == "bar\nbaz"
|
99
|
+
end
|
100
|
+
|
93
101
|
it "should fail if specified and doesnt exist" do
|
94
102
|
lambda { subject.load_env "/tmp/env" }.should raise_error(Errno::ENOENT)
|
95
103
|
end
|
@@ -18,4 +18,14 @@ describe Foreman::Export::Launchd, :fakefs do
|
|
18
18
|
File.read("/tmp/init/app-bravo-1.plist").should == example_export_file("launchd/launchd-b.default")
|
19
19
|
end
|
20
20
|
|
21
|
+
context "with multiple command arguments" do
|
22
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", "charlie") }
|
23
|
+
|
24
|
+
it "splits each command argument" do
|
25
|
+
launchd.export
|
26
|
+
File.read("/tmp/init/app-alpha-1.plist").should == example_export_file("launchd/launchd-c.default")
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
21
31
|
end
|
@@ -1,4 +1,4 @@
|
|
1
1
|
# ----- foreman app processes -----
|
2
|
-
AP01:4:respawn:/bin/su - app -c 'PORT=5000
|
3
|
-
AP02:4:respawn:/bin/su - app -c 'PORT=5001
|
2
|
+
AP01:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5000;./alpha >> /var/log/app/alpha-1.log 2>&1'
|
3
|
+
AP02:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5001;./alpha >> /var/log/app/alpha-2.log 2>&1'
|
4
4
|
# ----- end foreman app processes -----
|
@@ -1,4 +1,4 @@
|
|
1
1
|
# ----- foreman app processes -----
|
2
|
-
AP01:4:respawn:/bin/su - app -c 'PORT=5000
|
3
|
-
AP02:4:respawn:/bin/su - app -c 'PORT=5100
|
2
|
+
AP01:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5000;./alpha >> /var/log/app/alpha-1.log 2>&1'
|
3
|
+
AP02:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5100;./bravo >> /var/log/app/bravo-1.log 2>&1'
|
4
4
|
# ----- end foreman app processes -----
|
@@ -4,6 +4,11 @@
|
|
4
4
|
<dict>
|
5
5
|
<key>Label</key>
|
6
6
|
<string>app-alpha-1</string>
|
7
|
+
<key>EnvironmentVariables</key>
|
8
|
+
<dict>
|
9
|
+
<key>PORT</key>
|
10
|
+
<string>5000</string>
|
11
|
+
</dict>
|
7
12
|
<key>ProgramArguments</key>
|
8
13
|
<array>
|
9
14
|
<string>./alpha</string>
|
@@ -12,6 +17,8 @@
|
|
12
17
|
<true/>
|
13
18
|
<key>RunAtLoad</key>
|
14
19
|
<true/>
|
20
|
+
<key>StandardOutPath</key>
|
21
|
+
<string>/var/log/app/app-alpha-1.log</string>
|
15
22
|
<key>StandardErrorPath</key>
|
16
23
|
<string>/var/log/app/app-alpha-1.log</string>
|
17
24
|
<key>UserName</key>
|
@@ -4,6 +4,11 @@
|
|
4
4
|
<dict>
|
5
5
|
<key>Label</key>
|
6
6
|
<string>app-bravo-1</string>
|
7
|
+
<key>EnvironmentVariables</key>
|
8
|
+
<dict>
|
9
|
+
<key>PORT</key>
|
10
|
+
<string>5100</string>
|
11
|
+
</dict>
|
7
12
|
<key>ProgramArguments</key>
|
8
13
|
<array>
|
9
14
|
<string>./bravo</string>
|
@@ -12,6 +17,8 @@
|
|
12
17
|
<true/>
|
13
18
|
<key>RunAtLoad</key>
|
14
19
|
<true/>
|
20
|
+
<key>StandardOutPath</key>
|
21
|
+
<string>/var/log/app/app-bravo-1.log</string>
|
15
22
|
<key>StandardErrorPath</key>
|
16
23
|
<string>/var/log/app/app-bravo-1.log</string>
|
17
24
|
<key>UserName</key>
|
@@ -0,0 +1,30 @@
|
|
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>EnvironmentVariables</key>
|
8
|
+
<dict>
|
9
|
+
<key>PORT</key>
|
10
|
+
<string>5000</string>
|
11
|
+
</dict>
|
12
|
+
<key>ProgramArguments</key>
|
13
|
+
<array>
|
14
|
+
<string>./alpha</string>
|
15
|
+
<string>charlie</string>
|
16
|
+
</array>
|
17
|
+
<key>KeepAlive</key>
|
18
|
+
<true/>
|
19
|
+
<key>RunAtLoad</key>
|
20
|
+
<true/>
|
21
|
+
<key>StandardOutPath</key>
|
22
|
+
<string>/var/log/app/app-alpha-1.log</string>
|
23
|
+
<key>StandardErrorPath</key>
|
24
|
+
<string>/var/log/app/app-alpha-1.log</string>
|
25
|
+
<key>UserName</key>
|
26
|
+
<string>app</string>
|
27
|
+
<key>WorkingDirectory</key>
|
28
|
+
<string>/tmp/app</string>
|
29
|
+
</dict>
|
30
|
+
</plist>
|
data/spec/spec_helper.rb
CHANGED
@@ -58,6 +58,12 @@ def fork_and_capture(&blk)
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
def fork_and_get_exitstatus(args)
|
62
|
+
pid = Process.spawn("bundle exec bin/foreman #{args}", :out => "/dev/null", :err => "/dev/null")
|
63
|
+
Process.wait(pid)
|
64
|
+
$?.exitstatus
|
65
|
+
end
|
66
|
+
|
61
67
|
def mock_exit(&block)
|
62
68
|
block.should raise_error(SystemExit)
|
63
69
|
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.
|
4
|
+
version: 0.58.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
16
|
-
requirement: &
|
16
|
+
requirement: &70177359356080 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 0.13.6
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70177359356080
|
25
25
|
description: Process manager for applications with multiple components
|
26
26
|
email: ddollar@gmail.com
|
27
27
|
executables:
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- data/export/upstart/master.conf.erb
|
49
49
|
- data/export/upstart/process.conf.erb
|
50
50
|
- data/export/upstart/process_master.conf.erb
|
51
|
+
- lib/foreman/capistrano.rb
|
51
52
|
- lib/foreman/cli.rb
|
52
53
|
- lib/foreman/distribution.rb
|
53
54
|
- lib/foreman/engine/cli.rb
|
@@ -92,6 +93,7 @@ files:
|
|
92
93
|
- spec/resources/export/inittab/inittab.default
|
93
94
|
- spec/resources/export/launchd/launchd-a.default
|
94
95
|
- spec/resources/export/launchd/launchd-b.default
|
96
|
+
- spec/resources/export/launchd/launchd-c.default
|
95
97
|
- spec/resources/export/runit/app-alpha-1/log/run
|
96
98
|
- spec/resources/export/runit/app-alpha-1/run
|
97
99
|
- spec/resources/export/runit/app-alpha-2/log/run
|
@@ -121,18 +123,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
123
|
- - ! '>='
|
122
124
|
- !ruby/object:Gem::Version
|
123
125
|
version: '0'
|
124
|
-
segments:
|
125
|
-
- 0
|
126
|
-
hash: 1574791230196847546
|
127
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
127
|
none: false
|
129
128
|
requirements:
|
130
129
|
- - ! '>='
|
131
130
|
- !ruby/object:Gem::Version
|
132
131
|
version: '0'
|
133
|
-
segments:
|
134
|
-
- 0
|
135
|
-
hash: 1574791230196847546
|
136
132
|
requirements: []
|
137
133
|
rubyforge_project:
|
138
134
|
rubygems_version: 1.8.11
|
@@ -140,4 +136,3 @@ signing_key:
|
|
140
136
|
specification_version: 3
|
141
137
|
summary: Process manager for applications with multiple components
|
142
138
|
test_files: []
|
143
|
-
has_rdoc:
|