foreman-capistrano 0.51.0
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 +7 -0
- data/data/export/upstart/process_master.conf.erb +2 -0
- data/lib/foreman/capistrano.rb +55 -0
- data/lib/foreman/cli.rb +140 -0
- data/lib/foreman/distribution.rb +9 -0
- data/lib/foreman/engine/cli.rb +104 -0
- data/lib/foreman/engine.rb +313 -0
- data/lib/foreman/env.rb +27 -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/export.rb +34 -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/lib/foreman.rb +23 -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 +145 -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,7 @@
|
|
1
|
+
start on starting <%= app %>-<%= name %>
|
2
|
+
stop on stopping <%= app %>-<%= name %>
|
3
|
+
respawn
|
4
|
+
|
5
|
+
exec su - <%= user %> --shell=/bin/bash -c 'cd <%= engine.root %>; trap '\''kill -QUIT $(jobs -p)'\'' EXIT; 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'
|
6
|
+
|
7
|
+
|
@@ -0,0 +1,55 @@
|
|
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
|
55
|
+
|
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
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require "foreman/engine"
|
2
|
+
|
3
|
+
class Foreman::Engine::CLI < Foreman::Engine
|
4
|
+
|
5
|
+
module Color
|
6
|
+
|
7
|
+
ANSI = {
|
8
|
+
:reset => 0,
|
9
|
+
:black => 30,
|
10
|
+
:red => 31,
|
11
|
+
:green => 32,
|
12
|
+
:yellow => 33,
|
13
|
+
:blue => 34,
|
14
|
+
:magenta => 35,
|
15
|
+
:cyan => 36,
|
16
|
+
:white => 37,
|
17
|
+
:bright_black => 30,
|
18
|
+
:bright_red => 31,
|
19
|
+
:bright_green => 32,
|
20
|
+
:bright_yellow => 33,
|
21
|
+
:bright_blue => 34,
|
22
|
+
:bright_magenta => 35,
|
23
|
+
:bright_cyan => 36,
|
24
|
+
:bright_white => 37,
|
25
|
+
}
|
26
|
+
|
27
|
+
def self.enable(io, force=false)
|
28
|
+
io.extend(self)
|
29
|
+
@@color_force = force
|
30
|
+
end
|
31
|
+
|
32
|
+
def color?
|
33
|
+
return true if @@color_force
|
34
|
+
return false if Foreman.windows?
|
35
|
+
return false unless self.respond_to?(:isatty)
|
36
|
+
self.isatty && ENV["TERM"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def color(name)
|
40
|
+
return "" unless color?
|
41
|
+
return "" unless ansi = ANSI[name.to_sym]
|
42
|
+
"\e[#{ansi}m"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
FOREMAN_COLORS = %w( cyan yellow green magenta red blue intense_cyan intense_yellow
|
48
|
+
intense_green intense_magenta intense_red, intense_blue )
|
49
|
+
|
50
|
+
def startup
|
51
|
+
@colors = map_colors
|
52
|
+
proctitle "foreman: master" unless Foreman.windows?
|
53
|
+
Color.enable($stdout, options[:color])
|
54
|
+
end
|
55
|
+
|
56
|
+
def output(name, data)
|
57
|
+
data.to_s.chomp.split("\n").each do |message|
|
58
|
+
output = ""
|
59
|
+
output += $stdout.color(@colors[name.split(".").first].to_sym)
|
60
|
+
output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
|
61
|
+
output += $stdout.color(:reset)
|
62
|
+
output += message
|
63
|
+
$stdout.puts output
|
64
|
+
$stdout.flush
|
65
|
+
end
|
66
|
+
rescue Errno::EPIPE
|
67
|
+
terminate_gracefully
|
68
|
+
end
|
69
|
+
|
70
|
+
def shutdown
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def name_padding
|
76
|
+
@name_padding ||= begin
|
77
|
+
index_padding = @names.values.map { |n| formation[n] }.max.to_s.length + 1
|
78
|
+
name_padding = @names.values.map { |n| n.length + index_padding }.sort.last
|
79
|
+
[ 6, name_padding ].max
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def pad_process_name(name)
|
84
|
+
name.ljust(name_padding, " ")
|
85
|
+
end
|
86
|
+
|
87
|
+
def map_colors
|
88
|
+
colors = Hash.new("white")
|
89
|
+
@names.values.each_with_index do |name, index|
|
90
|
+
colors[name] = FOREMAN_COLORS[index % FOREMAN_COLORS.length]
|
91
|
+
end
|
92
|
+
colors["system"] = "intense_white"
|
93
|
+
colors
|
94
|
+
end
|
95
|
+
|
96
|
+
def proctitle(title)
|
97
|
+
$0 = title
|
98
|
+
end
|
99
|
+
|
100
|
+
def termtitle(title)
|
101
|
+
printf("\033]0;#{title}\007") unless Foreman.windows?
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|