foreman 0.50.0-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +46 -0
- data/bin/foreman +7 -0
- data/bin/foreman-runner +32 -0
- data/bin/taskman +8 -0
- data/data/example/Procfile +4 -0
- data/data/example/Procfile.without_colon +2 -0
- data/data/example/error +7 -0
- data/data/example/log/neverdie.log +4 -0
- data/data/example/spawnee +14 -0
- data/data/example/spawner +7 -0
- data/data/example/ticker +14 -0
- data/data/example/utf8 +11 -0
- data/data/export/bluepill/master.pill.erb +28 -0
- data/data/export/launchd/launchd.plist.erb +22 -0
- data/data/export/runit/log/run.erb +7 -0
- data/data/export/runit/run.erb +3 -0
- data/data/export/supervisord/app.conf.erb +27 -0
- data/data/export/upstart/master.conf.erb +8 -0
- data/data/export/upstart/process.conf.erb +5 -0
- data/data/export/upstart/process_master.conf.erb +2 -0
- data/lib/foreman.rb +23 -0
- data/lib/foreman/cli.rb +140 -0
- data/lib/foreman/distribution.rb +9 -0
- data/lib/foreman/engine.rb +313 -0
- data/lib/foreman/engine/cli.rb +105 -0
- data/lib/foreman/env.rb +27 -0
- data/lib/foreman/export.rb +34 -0
- data/lib/foreman/export/base.rb +146 -0
- data/lib/foreman/export/bluepill.rb +12 -0
- data/lib/foreman/export/inittab.rb +33 -0
- data/lib/foreman/export/launchd.rb +15 -0
- data/lib/foreman/export/runit.rb +34 -0
- data/lib/foreman/export/supervisord.rb +16 -0
- data/lib/foreman/export/upstart.rb +25 -0
- data/lib/foreman/helpers.rb +45 -0
- data/lib/foreman/process.rb +102 -0
- data/lib/foreman/procfile.rb +92 -0
- data/lib/foreman/version.rb +5 -0
- data/man/foreman.1 +244 -0
- data/spec/foreman/cli_spec.rb +87 -0
- data/spec/foreman/engine_spec.rb +104 -0
- data/spec/foreman/export/base_spec.rb +19 -0
- data/spec/foreman/export/bluepill_spec.rb +37 -0
- data/spec/foreman/export/inittab_spec.rb +40 -0
- data/spec/foreman/export/launchd_spec.rb +21 -0
- data/spec/foreman/export/runit_spec.rb +36 -0
- data/spec/foreman/export/supervisord_spec.rb +36 -0
- data/spec/foreman/export/upstart_spec.rb +88 -0
- data/spec/foreman/export_spec.rb +24 -0
- data/spec/foreman/helpers_spec.rb +26 -0
- data/spec/foreman/process_spec.rb +48 -0
- data/spec/foreman/procfile_spec.rb +41 -0
- data/spec/foreman_spec.rb +16 -0
- data/spec/helper_spec.rb +18 -0
- data/spec/resources/Procfile +4 -0
- data/spec/resources/bin/echo +2 -0
- data/spec/resources/bin/env +2 -0
- data/spec/resources/bin/test +2 -0
- data/spec/resources/bin/utf8 +2 -0
- data/spec/resources/export/bluepill/app-concurrency.pill +49 -0
- data/spec/resources/export/bluepill/app.pill +46 -0
- data/spec/resources/export/inittab/inittab.concurrency +4 -0
- data/spec/resources/export/inittab/inittab.default +4 -0
- data/spec/resources/export/launchd/launchd-a.default +22 -0
- data/spec/resources/export/launchd/launchd-b.default +22 -0
- data/spec/resources/export/runit/app-alpha-1/log/run +7 -0
- data/spec/resources/export/runit/app-alpha-1/run +3 -0
- data/spec/resources/export/runit/app-alpha-2/log/run +7 -0
- data/spec/resources/export/runit/app-alpha-2/run +3 -0
- data/spec/resources/export/runit/app-bravo-1/log/run +7 -0
- data/spec/resources/export/runit/app-bravo-1/run +3 -0
- data/spec/resources/export/supervisord/app-alpha-1.conf +24 -0
- data/spec/resources/export/supervisord/app-alpha-2.conf +24 -0
- data/spec/resources/export/upstart/app-alpha-1.conf +5 -0
- data/spec/resources/export/upstart/app-alpha-2.conf +5 -0
- data/spec/resources/export/upstart/app-alpha.conf +2 -0
- data/spec/resources/export/upstart/app-bravo-1.conf +5 -0
- data/spec/resources/export/upstart/app-bravo.conf +2 -0
- data/spec/resources/export/upstart/app.conf +8 -0
- data/spec/spec_helper.rb +153 -0
- metadata +148 -0
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Foreman
|
2
|
+
|
3
|
+
Manage Procfile-based applications
|
4
|
+
|
5
|
+
<table>
|
6
|
+
<tr>
|
7
|
+
<th>If you have...</th>
|
8
|
+
<th>Install with...</th>
|
9
|
+
</tr>
|
10
|
+
<tr>
|
11
|
+
<td>Ruby (MRI, JRuby, Windows)</td>
|
12
|
+
<td><pre>$ gem install foreman</pre></td>
|
13
|
+
</tr>
|
14
|
+
<tr>
|
15
|
+
<td>Mac OS X</td>
|
16
|
+
<td><a href="http://assets.foreman.io/foreman/foreman.pkg">foreman.pkg</a></td>
|
17
|
+
</tr>
|
18
|
+
</table>
|
19
|
+
|
20
|
+
## Getting Started
|
21
|
+
|
22
|
+
* http://blog.daviddollar.org/2011/05/06/introducing-foreman.html
|
23
|
+
|
24
|
+
## Documentation
|
25
|
+
|
26
|
+
* [man page](http://ddollar.github.com/foreman)
|
27
|
+
* [wiki](http://github.com/ddollar/foreman/wiki)
|
28
|
+
* [changelog](https://github.com/ddollar/foreman/blob/master/Changelog.md)
|
29
|
+
|
30
|
+
## Ports
|
31
|
+
|
32
|
+
* [shoreman](https://github.com/hecticjeff/shoreman) - shell
|
33
|
+
* [honcho](https://github.com/nickstenning/honcho) - python
|
34
|
+
* [norman](https://github.com/josh/norman) - node.js
|
35
|
+
|
36
|
+
## Authors
|
37
|
+
|
38
|
+
#### Created and maintained by
|
39
|
+
David Dollar
|
40
|
+
|
41
|
+
#### Patches contributed by
|
42
|
+
[Contributor List](https://github.com/ddollar/foreman/contributors)
|
43
|
+
|
44
|
+
## License
|
45
|
+
|
46
|
+
MIT
|
data/bin/foreman
ADDED
data/bin/foreman-runner
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
#
|
3
|
+
#/ Usage: foreman-runner [-d <dir>] <command> [<args>...]
|
4
|
+
#/
|
5
|
+
#/ Run a command with exec, optionally changing directory first
|
6
|
+
|
7
|
+
set -e
|
8
|
+
|
9
|
+
error() {
|
10
|
+
echo $@ >&2
|
11
|
+
exit 1
|
12
|
+
}
|
13
|
+
|
14
|
+
usage() {
|
15
|
+
cat $0 | grep '^#/' | cut -c4-
|
16
|
+
exit
|
17
|
+
}
|
18
|
+
|
19
|
+
while getopts ":hd:" OPT; do
|
20
|
+
case $OPT in
|
21
|
+
d) cd "$OPTARG" ;;
|
22
|
+
h) usage ;;
|
23
|
+
\?) error "invalid option: -$OPTARG" ;;
|
24
|
+
:) error "option -$OPTARG requires an argument" ;;
|
25
|
+
esac
|
26
|
+
done
|
27
|
+
|
28
|
+
shift $((OPTIND-1))
|
29
|
+
|
30
|
+
[ -z "$1" ] && usage
|
31
|
+
|
32
|
+
exec "$@"
|
data/bin/taskman
ADDED
data/data/example/error
ADDED
data/data/example/ticker
ADDED
data/data/example/utf8
ADDED
@@ -0,0 +1,28 @@
|
|
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.each_process do |name, process| %>
|
7
|
+
<% 1.upto(engine.formation[name]) do |num| %>
|
8
|
+
<% port = engine.port_for(process, num) %>
|
9
|
+
app.process("<%= name %>-<%= num %>") do |process|
|
10
|
+
process.start_command = "<%= process.command %>"
|
11
|
+
|
12
|
+
process.working_dir = "<%= engine.root %>"
|
13
|
+
process.daemonize = true
|
14
|
+
process.environment = <%= engine.env.merge("PORT" => port.to_s).inspect %>
|
15
|
+
process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]
|
16
|
+
process.stop_grace_time = 45.seconds
|
17
|
+
|
18
|
+
process.stdout = process.stderr = "<%= log %>/<%= app %>-<%= name %>-<%= num %>.log"
|
19
|
+
|
20
|
+
process.monitor_children do |children|
|
21
|
+
children.stop_command "kill {{PID}}"
|
22
|
+
end
|
23
|
+
|
24
|
+
process.group = "<%= app %>-<%= name %>"
|
25
|
+
end
|
26
|
+
<% end %>
|
27
|
+
<% end %>
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
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}-#{name}-#{num}" %></string>
|
7
|
+
<key>ProgramArguments</key>
|
8
|
+
<array>
|
9
|
+
<string><%= process.command %></string>
|
10
|
+
</array>
|
11
|
+
<key>KeepAlive</key>
|
12
|
+
<true/>
|
13
|
+
<key>RunAtLoad</key>
|
14
|
+
<true/>
|
15
|
+
<key>StandardErrorPath</key>
|
16
|
+
<string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
|
17
|
+
<key>UserName</key>
|
18
|
+
<string><%= user %></string>
|
19
|
+
<key>WorkingDirectory</key>
|
20
|
+
<string><%= engine.root %></string>
|
21
|
+
</dict>
|
22
|
+
</plist>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<%
|
2
|
+
app_names = []
|
3
|
+
engine.each_process do |name, process|
|
4
|
+
1.upto(engine.formation[name]) do |num|
|
5
|
+
port = engine.port_for(process, num)
|
6
|
+
full_name = "#{app}-#{name}-#{num}"
|
7
|
+
environment = engine.env.merge("PORT" => port.to_s).map do |key, value|
|
8
|
+
"#{key}=#{shell_quote(value)}"
|
9
|
+
end
|
10
|
+
app_names << full_name
|
11
|
+
%>
|
12
|
+
[program:<%= full_name %>]
|
13
|
+
command=<%= process.command %>
|
14
|
+
autostart=true
|
15
|
+
autorestart=true
|
16
|
+
stopsignal=QUIT
|
17
|
+
stdout_logfile=<%= log %>/<%= name %>-<%= num %>.log
|
18
|
+
stderr_logfile=<%= log %>/<%= name %>-<%= num %>.error.log
|
19
|
+
user=<%= user %>
|
20
|
+
directory=<%= engine.root %>
|
21
|
+
environment=<%= environment.join(',') %><%
|
22
|
+
end
|
23
|
+
end
|
24
|
+
%>
|
25
|
+
|
26
|
+
[group:<%= app %>]
|
27
|
+
programs=<%= app_names.join(',') %>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
start on starting <%= app %>-<%= name %>
|
2
|
+
stop on stopping <%= app %>-<%= name %>
|
3
|
+
respawn
|
4
|
+
|
5
|
+
exec su - <%= user %> -c 'cd <%= engine.root %>; export PORT=<%= port %>;<% engine.env.each_pair do |var,env| %> export <%= var.upcase %>=<%= shell_quote(env) %>; <% end %> <%= process.command %> >> <%= log %>/<%=name%>-<%=num%>.log 2>&1'
|
data/lib/foreman.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "foreman/version"
|
2
|
+
|
3
|
+
module Foreman
|
4
|
+
|
5
|
+
class AppDoesNotExist < Exception; end
|
6
|
+
|
7
|
+
def self.runner
|
8
|
+
File.expand_path("../../bin/foreman-runner", __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.jruby?
|
12
|
+
defined?(RUBY_PLATFORM) and RUBY_PLATFORM == "java"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.ruby_18?
|
16
|
+
defined?(RUBY_VERSION) and RUBY_VERSION =~ /^1\.8\.\d+/
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.windows?
|
20
|
+
defined?(RUBY_PLATFORM) and RUBY_PLATFORM =~ /(win|w)32$/
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/lib/foreman/cli.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
require "foreman"
|
2
|
+
require "foreman/helpers"
|
3
|
+
require "foreman/engine"
|
4
|
+
require "foreman/engine/cli"
|
5
|
+
require "foreman/export"
|
6
|
+
require "foreman/version"
|
7
|
+
require "shellwords"
|
8
|
+
require "yaml"
|
9
|
+
require "thor"
|
10
|
+
|
11
|
+
class Foreman::CLI < Thor
|
12
|
+
|
13
|
+
include Foreman::Helpers
|
14
|
+
|
15
|
+
map ["-v", "--version"] => :version
|
16
|
+
|
17
|
+
class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
|
18
|
+
class_option :root, :type => :string, :aliases => "-d", :desc => "Default: Procfile directory"
|
19
|
+
|
20
|
+
desc "start [PROCESS]", "Start the application (or a specific PROCESS)"
|
21
|
+
|
22
|
+
method_option :color, :type => :boolean, :aliases => "-c", :desc => "Force color to be enabled"
|
23
|
+
method_option :env, :type => :string, :aliases => "-e", :desc => "Specify an environment file to load, defaults to .env"
|
24
|
+
method_option :formation, :type => :string, :aliases => "-m", :banner => '"alpha=5,bar=3"'
|
25
|
+
method_option :port, :type => :numeric, :aliases => "-p"
|
26
|
+
|
27
|
+
class << self
|
28
|
+
# Hackery. Take the run method away from Thor so that we can redefine it.
|
29
|
+
def is_thor_reserved_word?(word, type)
|
30
|
+
return false if word == "run"
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def start(process=nil)
|
36
|
+
check_procfile!
|
37
|
+
load_environment!
|
38
|
+
engine.load_procfile(procfile)
|
39
|
+
engine.options[:formation] = "#{process}=1" if process
|
40
|
+
engine.start
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "export FORMAT LOCATION", "Export the application to another process management format"
|
44
|
+
|
45
|
+
method_option :app, :type => :string, :aliases => "-a"
|
46
|
+
method_option :log, :type => :string, :aliases => "-l"
|
47
|
+
method_option :env, :type => :string, :aliases => "-e", :desc => "Specify an environment file to load, defaults to .env"
|
48
|
+
method_option :port, :type => :numeric, :aliases => "-p"
|
49
|
+
method_option :user, :type => :string, :aliases => "-u"
|
50
|
+
method_option :template, :type => :string, :aliases => "-t"
|
51
|
+
method_option :concurrency, :type => :string, :aliases => "-c", :banner => '"alpha=5,bar=3"'
|
52
|
+
|
53
|
+
def export(format, location=nil)
|
54
|
+
check_procfile!
|
55
|
+
load_environment!
|
56
|
+
engine.load_procfile(procfile)
|
57
|
+
formatter = Foreman::Export.formatter(format)
|
58
|
+
formatter.new(location, engine, options).export
|
59
|
+
rescue Foreman::Export::Exception => ex
|
60
|
+
error ex.message
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "check", "Validate your application's Procfile"
|
64
|
+
|
65
|
+
def check
|
66
|
+
check_procfile!
|
67
|
+
engine.load_procfile(procfile)
|
68
|
+
error "no processes defined" unless engine.processes.length > 0
|
69
|
+
puts "valid procfile detected (#{engine.process_names.join(', ')})"
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "run COMMAND [ARGS...]", "Run a command using your application's environment"
|
73
|
+
|
74
|
+
method_option :env, :type => :string, :aliases => "-e", :desc => "Specify an environment file to load, defaults to .env"
|
75
|
+
|
76
|
+
def run(*args)
|
77
|
+
load_environment!
|
78
|
+
begin
|
79
|
+
exec engine.env, args.shelljoin
|
80
|
+
rescue Errno::EACCES
|
81
|
+
error "not executable: #{args.first}"
|
82
|
+
rescue Errno::ENOENT
|
83
|
+
error "command not found: #{args.first}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
desc "version", "Display Foreman gem version"
|
88
|
+
|
89
|
+
def version
|
90
|
+
puts Foreman::VERSION
|
91
|
+
end
|
92
|
+
|
93
|
+
no_tasks do
|
94
|
+
def engine
|
95
|
+
@engine ||= begin
|
96
|
+
engine_class = Foreman::Engine::CLI
|
97
|
+
engine = engine_class.new(options)
|
98
|
+
engine
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
private ######################################################################
|
104
|
+
|
105
|
+
def error(message)
|
106
|
+
puts "ERROR: #{message}"
|
107
|
+
exit 1
|
108
|
+
end
|
109
|
+
|
110
|
+
def check_procfile!
|
111
|
+
error("#{procfile} does not exist.") unless File.exist?(procfile)
|
112
|
+
end
|
113
|
+
|
114
|
+
def load_environment!
|
115
|
+
if options[:env]
|
116
|
+
options[:env].split(",").each do |file|
|
117
|
+
engine.load_env file
|
118
|
+
end
|
119
|
+
else
|
120
|
+
default_env = File.join(engine.root, ".env")
|
121
|
+
engine.load_env default_env if File.exists?(default_env)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def procfile
|
126
|
+
case
|
127
|
+
when options[:procfile] then options[:procfile]
|
128
|
+
when options[:root] then File.expand_path(File.join(options[:app_root], "Procfile"))
|
129
|
+
else "Procfile"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def options
|
134
|
+
original_options = super
|
135
|
+
return original_options unless File.exists?(".foreman")
|
136
|
+
defaults = ::YAML::load_file(".foreman") || {}
|
137
|
+
Thor::CoreExt::HashWithIndifferentAccess.new(defaults.merge(original_options))
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|