Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c04dab649 | ||
|
|
96e26e7412 | ||
|
|
a2c03cc402 | ||
|
|
803115c0c4 | ||
|
|
a4343187ad | ||
|
|
98af1f0943 | ||
|
|
af2d4762a8 | ||
|
|
1d06124457 | ||
|
|
698e6ae092 | ||
|
|
c617ddb3b2 | ||
|
|
f6d4badcd2 | ||
|
|
f29bf49a35 | ||
|
|
e06d36b27c | ||
|
|
85e62dfbeb | ||
|
|
574e852710 | ||
|
|
68f098c1d2 | ||
|
|
e8bdafdfc1 | ||
|
|
4abd3ebedb | ||
|
|
f765436dde | ||
|
|
b5c513b4b5 | ||
|
|
ee761ff098 | ||
|
|
27c22deb6c | ||
|
|
681a9f7e61 | ||
|
|
8335a2b1ba | ||
|
|
407425ca78 | ||
|
|
6ca505b4cd | ||
|
|
612eae5e21 | ||
|
|
497b5ea1eb | ||
|
|
cd384e0d59 | ||
|
|
8921cac35b | ||
|
|
7d6de5b2a7 | ||
|
|
cc4306492e | ||
|
|
6042783e82 | ||
|
|
b7b3a9f898 | ||
|
|
8b204db2f0 | ||
|
|
15643dcb3f | ||
|
|
5f0f2f5378 | ||
|
|
c1b57b59cf | ||
|
|
21d53818f2 | ||
|
|
359d6f1c34 | ||
|
|
584f251e4a | ||
|
|
7d9c2b2ac4 | ||
|
|
fba4d9beff | ||
|
|
0bde5fdab5 | ||
|
|
ebe160d425 | ||
|
|
1beab80c1f | ||
|
|
7b270f9f4a | ||
|
|
03e5342067 | ||
|
|
b1d57426fb | ||
|
|
06e5c52f35 | ||
|
|
64ca839c0b | ||
|
|
80aebda023 | ||
|
|
5dee2281a2 | ||
|
|
efb6d2f11d | ||
|
|
ac528d3b50 | ||
|
|
cefd4e351e | ||
|
|
9849f4558a | ||
|
|
4b53b42be1 | ||
|
|
219acaf690 | ||
|
|
f8118d7b40 | ||
|
|
0a61b1a62f |
@@ -16,9 +16,7 @@ notifications:
|
|||||||
- http://dx-helper.herokuapp.com/travis
|
- http://dx-helper.herokuapp.com/travis
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
- 1.8.7
|
|
||||||
- 1.9.2
|
- 1.9.2
|
||||||
- 1.9.3
|
- 1.9.3
|
||||||
- jruby
|
- jruby
|
||||||
- rbx
|
|
||||||
- ree
|
- ree
|
||||||
|
|||||||
+63
-4
@@ -1,8 +1,67 @@
|
|||||||
## 0.48.0.pre1 (2012-06-11)
|
## 0.57.0 (2012-08-21)
|
||||||
|
|
||||||
* Massive refactoring for programmatic control and stability [David Dollar]
|
* fix startup checks for upstart exporter [Aditya Sanghi]
|
||||||
* Procfile commands with shell interpolations now work again [David Dollar]
|
|
||||||
* Stop trying to test on Ruby 1.8 [David Dollar]
|
## 0.56.0 (2012-08-19)
|
||||||
|
|
||||||
|
* read .profile, not .profile.d [David Dollar]
|
||||||
|
|
||||||
|
## 0.55.0 (2012-08-14)
|
||||||
|
|
||||||
|
* use a forked process to exec a run with environment [David Dollar]
|
||||||
|
|
||||||
|
## 0.54.0 (2012-08-14)
|
||||||
|
|
||||||
|
* use Foreman::Process to extract command running [David Dollar]
|
||||||
|
* changed to check env for bash [brntbeer]
|
||||||
|
|
||||||
|
## 0.53.0 (2012-07-24)
|
||||||
|
|
||||||
|
* put app root in $HOME [David Dollar]
|
||||||
|
|
||||||
|
## 0.52.0 (2012-07-24)
|
||||||
|
|
||||||
|
* wrap command in a runner that sources .profile.d scripts [David Dollar]
|
||||||
|
* fix upstart export specs [David Dollar]
|
||||||
|
* Make upstart export start/stop with network [Daniel Farrell]
|
||||||
|
|
||||||
|
## 0.51.0 (2012-07-11)
|
||||||
|
|
||||||
|
* dont try to colorize windows [David Dollar]
|
||||||
|
|
||||||
|
## 0.50.0 (2012-07-11)
|
||||||
|
|
||||||
|
* handle windows [David Dollar]
|
||||||
|
|
||||||
|
## 0.49.0 (2012-07-11)
|
||||||
|
|
||||||
|
* 1.8 compatibility [David Dollar]
|
||||||
|
* use one pgroup for all of foreman and kill that since ruby 1.8 sucks at pgroups [David Dollar]
|
||||||
|
* better debugging [David Dollar]
|
||||||
|
|
||||||
|
## 0.48.0 (2012-07-10)
|
||||||
|
|
||||||
|
* allow old exporter format to work, but with deprecation warning [David Dollar]
|
||||||
|
* remove debugging code [David Dollar]
|
||||||
|
* Merge pull request #219 from MarkDBlackwell/patch-1 [David Dollar]
|
||||||
|
* Avoid crash by verifying the existence of SIGHUP before accessing it. [Mark D. Blackwell]
|
||||||
|
* allow color to be forced on [David Dollar]
|
||||||
|
* terminate gracefully if stdout goes away [David Dollar]
|
||||||
|
* always flush output [David Dollar]
|
||||||
|
* Merge pull request #212 from morgoth/added-version-command [David Dollar]
|
||||||
|
* added command for displaying foreman version [Wojciech Wnętrzak]
|
||||||
|
* Merge pull request #211 from morgoth/fixed-yaml-usage [David Dollar]
|
||||||
|
* fixed using YAML [Wojciech Wnętrzak]
|
||||||
|
* test on more things, but don't fail [David Dollar]
|
||||||
|
* changelog [David Dollar]
|
||||||
|
* 0.48.0.pre1 [David Dollar]
|
||||||
|
* foreman doesn't work on ruby 1.8, may try to fix later [David Dollar]
|
||||||
|
* use bash [David Dollar]
|
||||||
|
* massive refactoring for programmatic control and stability [David Dollar]
|
||||||
|
* Merge pull request #164 from hsume2/master [David Dollar]
|
||||||
|
* Only run tmux specs if tmux is installed [Henry Hsu]
|
||||||
|
* Do not assume BUNDLE_GEMFILE [Henry Hsu]
|
||||||
|
* Add support for starting procfile in tmux session [Henry Hsu]
|
||||||
|
|
||||||
## 0.47.0 (2012-06-07)
|
## 0.47.0 (2012-06-07)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
foreman (0.48.0)
|
foreman (0.58.0)
|
||||||
thor (>= 0.13.6)
|
thor (>= 0.13.6)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
@@ -39,7 +39,7 @@ GEM
|
|||||||
multi_json (~> 1.0.3)
|
multi_json (~> 1.0.3)
|
||||||
simplecov-html (~> 0.5.3)
|
simplecov-html (~> 0.5.3)
|
||||||
simplecov-html (0.5.3)
|
simplecov-html (0.5.3)
|
||||||
thor (0.15.3)
|
thor (0.16.0)
|
||||||
timecop (0.3.5)
|
timecop (0.3.5)
|
||||||
win32console (1.3.0-x86-mingw32)
|
win32console (1.3.0-x86-mingw32)
|
||||||
xml-simple (1.0.15)
|
xml-simple (1.0.15)
|
||||||
|
|||||||
+12
-3
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
#/ Usage: foreman-runner [-d <dir>] <command> [<args>...]
|
#/ Usage: foreman-runner [-d <dir>] [-p] <command> [<args>...]
|
||||||
#/
|
#/
|
||||||
#/ Run a command with exec, optionally changing directory first
|
#/ Run a command with exec, optionally changing directory first
|
||||||
|
|
||||||
@@ -16,9 +16,12 @@ usage() {
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
while getopts ":hd:" OPT; do
|
read_profile=""
|
||||||
|
|
||||||
|
while getopts ":hd:p" OPT; do
|
||||||
case $OPT in
|
case $OPT in
|
||||||
d) cd "$OPTARG" ;;
|
d) cd "$OPTARG" ;;
|
||||||
|
p) read_profile="1" ;;
|
||||||
h) usage ;;
|
h) usage ;;
|
||||||
\?) error "invalid option: -$OPTARG" ;;
|
\?) error "invalid option: -$OPTARG" ;;
|
||||||
:) error "option -$OPTARG requires an argument" ;;
|
:) error "option -$OPTARG requires an argument" ;;
|
||||||
@@ -29,4 +32,10 @@ shift $((OPTIND-1))
|
|||||||
|
|
||||||
[ -z "$1" ] && usage
|
[ -z "$1" ] && usage
|
||||||
|
|
||||||
|
if [ "$read_profile" == "1" ]; then
|
||||||
|
if [ -f .profile ]; then
|
||||||
|
source .profile
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
export FOO=bar
|
||||||
@@ -9,6 +9,6 @@ sigterm() {
|
|||||||
#trap sigterm SIGTERM
|
#trap sigterm SIGTERM
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
echo "$NAME: ping"
|
echo "$NAME: ping $$"
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -4,14 +4,25 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>Label</key>
|
<key>Label</key>
|
||||||
<string><%= "#{app}-#{name}-#{num}" %></string>
|
<string><%= "#{app}-#{name}-#{num}" %></string>
|
||||||
|
<key>EnvironmentVariables</key>
|
||||||
|
<dict>
|
||||||
|
<%- engine.env.merge("PORT" => port).each_pair do |var,env| -%>
|
||||||
|
<key><%= var.upcase %></key>
|
||||||
|
<string><%= env %></string>
|
||||||
|
<%- end -%>
|
||||||
|
</dict>
|
||||||
<key>ProgramArguments</key>
|
<key>ProgramArguments</key>
|
||||||
<array>
|
<array>
|
||||||
<string><%= process.command %></string>
|
<%- command_args.each do |command| -%>
|
||||||
|
<string><%= command %></string>
|
||||||
|
<%- end -%>
|
||||||
</array>
|
</array>
|
||||||
<key>KeepAlive</key>
|
<key>KeepAlive</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>RunAtLoad</key>
|
<key>RunAtLoad</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>StandardOutPath</key>
|
||||||
|
<string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
|
||||||
<key>StandardErrorPath</key>
|
<key>StandardErrorPath</key>
|
||||||
<string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
|
<string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
|
||||||
<key>UserName</key>
|
<key>UserName</key>
|
||||||
|
|||||||
@@ -6,3 +6,11 @@ bash << "EOF"
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
end script
|
end script
|
||||||
|
|
||||||
|
start on (started network-interface
|
||||||
|
or started network-manager
|
||||||
|
or started networking)
|
||||||
|
|
||||||
|
stop on (stopping network-interface
|
||||||
|
or stopping network-manager
|
||||||
|
or stopping networking)
|
||||||
|
|||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
file pkg("foreman-#{version}-x86-mswin32.gem") => distribution_files do |t|
|
||||||
|
Bundler.with_clean_env do
|
||||||
|
sh "env PLATFORM=mswin32 gem build foreman.gemspec"
|
||||||
|
end
|
||||||
|
sh "mv foreman-#{version}-x86-mswin32.gem #{t.name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
task "mswin32:build" => pkg("foreman-#{version}-x86-mswin32.gem")
|
||||||
|
|
||||||
|
task "mswin32:clean" do
|
||||||
|
clean pkg("foreman-#{version}-x86-mswin32.gem")
|
||||||
|
end
|
||||||
|
|
||||||
|
task "mswin32:release" => "mswin32:build" do |t|
|
||||||
|
sh "gem push #{pkg("foreman-#{version}-x86-mswin32.gem")} || echo 'error'"
|
||||||
|
end
|
||||||
@@ -12,6 +12,10 @@ module Foreman
|
|||||||
defined?(RUBY_PLATFORM) and RUBY_PLATFORM == "java"
|
defined?(RUBY_PLATFORM) and RUBY_PLATFORM == "java"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.ruby_18?
|
||||||
|
defined?(RUBY_VERSION) and RUBY_VERSION =~ /^1\.8\.\d+/
|
||||||
|
end
|
||||||
|
|
||||||
def self.windows?
|
def self.windows?
|
||||||
defined?(RUBY_PLATFORM) and RUBY_PLATFORM =~ /(win|w)32$/
|
defined?(RUBY_PLATFORM) and RUBY_PLATFORM =~ /(win|w)32$/
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
if defined?(Capistrano)
|
||||||
|
Capistrano::Configuration.instance(:must_exist).load do
|
||||||
|
|
||||||
|
namespace :foreman do
|
||||||
|
desc <<-DESC
|
||||||
|
Export the Procfile to upstart. Will use sudo if available.
|
||||||
|
|
||||||
|
You can override any of these defaults by setting the variables shown below.
|
||||||
|
|
||||||
|
set :foreman_format, "upstart"
|
||||||
|
set :foreman_location, "/etc/init"
|
||||||
|
set :foreman_procfile, "Procfile"
|
||||||
|
set :foreman_app, application
|
||||||
|
set :foreman_user, user
|
||||||
|
set :foreman_log, "#{shared_path}/log"
|
||||||
|
set :foreman_concurrency, false
|
||||||
|
DESC
|
||||||
|
task :export, :roles => :app do
|
||||||
|
bundle_cmd = fetch(:bundle_cmd, "bundle")
|
||||||
|
foreman_format = fetch(:foreman_format, "upstart")
|
||||||
|
foreman_location = fetch(:foreman_location, "/etc/init")
|
||||||
|
foreman_procfile = fetch(:foreman_procfile, "Procfile")
|
||||||
|
foreman_app = fetch(:foreman_app, application)
|
||||||
|
foreman_user = fetch(:foreman_user, user)
|
||||||
|
foreman_log = fetch(:foreman_log, "#{shared_path}/log")
|
||||||
|
foreman_concurrency = fetch(:foreman_concurrency, false)
|
||||||
|
|
||||||
|
args = ["#{foreman_format} #{foreman_location}"]
|
||||||
|
args << "-f #{foreman_procfile}"
|
||||||
|
args << "-a #{foreman_app}"
|
||||||
|
args << "-u #{foreman_user}"
|
||||||
|
args << "-l #{foreman_log}"
|
||||||
|
args << "-c #{foreman_concurrency}" if foreman_concurrency
|
||||||
|
run "cd #{release_path} && #{sudo} #{bundle_cmd} exec foreman export #{args.join(' ')}"
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Start the application services"
|
||||||
|
task :start, :roles => :app do
|
||||||
|
run "#{sudo} start #{application}"
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Stop the application services"
|
||||||
|
task :stop, :roles => :app do
|
||||||
|
run "#{sudo} stop #{application}"
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Restart the application services"
|
||||||
|
task :restart, :roles => :app do
|
||||||
|
run "#{sudo} start #{application} || #{sudo} restart #{application}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
+12
-7
@@ -75,13 +75,18 @@ class Foreman::CLI < Thor
|
|||||||
|
|
||||||
def run(*args)
|
def run(*args)
|
||||||
load_environment!
|
load_environment!
|
||||||
begin
|
pid = fork do
|
||||||
exec engine.env, args.shelljoin
|
begin
|
||||||
rescue Errno::EACCES
|
engine.env.each { |k,v| ENV[k] = v }
|
||||||
error "not executable: #{args.first}"
|
exec args.shelljoin
|
||||||
rescue Errno::ENOENT
|
rescue Errno::EACCES
|
||||||
error "command not found: #{args.first}"
|
error "not executable: #{args.first}"
|
||||||
|
rescue Errno::ENOENT
|
||||||
|
error "command not found: #{args.first}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Process.wait(pid)
|
||||||
|
exit $?.exitstatus
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "version", "Display Foreman gem version"
|
desc "version", "Display Foreman gem version"
|
||||||
@@ -125,7 +130,7 @@ private ######################################################################
|
|||||||
def procfile
|
def procfile
|
||||||
case
|
case
|
||||||
when options[:procfile] then options[:procfile]
|
when options[:procfile] then options[:procfile]
|
||||||
when options[:root] then File.expand_path(File.join(options[:app_root], "Procfile"))
|
when options[:root] then File.expand_path(File.join(options[:root], "Procfile"))
|
||||||
else "Procfile"
|
else "Procfile"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+21
-7
@@ -99,10 +99,17 @@ class Foreman::Engine
|
|||||||
# @param [String] signal The signal to send to each process
|
# @param [String] signal The signal to send to each process
|
||||||
#
|
#
|
||||||
def killall(signal="SIGTERM")
|
def killall(signal="SIGTERM")
|
||||||
@running.each do |pid, (process, index)|
|
if Foreman.windows?
|
||||||
system "sending #{signal} to #{name_for(pid)} at pid #{pid}"
|
@running.each do |pid, (process, index)|
|
||||||
|
system "sending #{signal} to #{name_for(pid)} at pid #{pid}"
|
||||||
|
begin
|
||||||
|
Process.kill(signal, pid)
|
||||||
|
rescue Errno::ESRCH, Errno::EPERM
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
begin
|
begin
|
||||||
Process.kill(signal, -1 * pid)
|
Process.kill "-#{signal}", Process.pid
|
||||||
rescue Errno::ESRCH, Errno::EPERM
|
rescue Errno::ESRCH, Errno::EPERM
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -249,7 +256,9 @@ private
|
|||||||
1.upto(formation[@names[process]]) do |n|
|
1.upto(formation[@names[process]]) do |n|
|
||||||
reader, writer = create_pipe
|
reader, writer = create_pipe
|
||||||
begin
|
begin
|
||||||
pid = process.run(:output => writer, :env => { "PORT" => port_for(process, n).to_s })
|
pid = process.run(:output => writer, :env => {
|
||||||
|
"PORT" => port_for(process, n).to_s
|
||||||
|
})
|
||||||
writer.puts "started with pid #{pid}"
|
writer.puts "started with pid #{pid}"
|
||||||
rescue Errno::ENOENT
|
rescue Errno::ENOENT
|
||||||
writer.puts "unknown command: #{process.command}"
|
writer.puts "unknown command: #{process.command}"
|
||||||
@@ -266,7 +275,7 @@ private
|
|||||||
loop do
|
loop do
|
||||||
(IO.select(@readers.values).first || []).each do |reader|
|
(IO.select(@readers.values).first || []).each do |reader|
|
||||||
data = reader.gets
|
data = reader.gets
|
||||||
output_with_mutex name_for(@readers.key(reader)), data
|
output_with_mutex name_for(@readers.invert[reader]), data
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue Exception => ex
|
rescue Exception => ex
|
||||||
@@ -288,8 +297,13 @@ private
|
|||||||
def terminate_gracefully
|
def terminate_gracefully
|
||||||
return if @terminating
|
return if @terminating
|
||||||
@terminating = true
|
@terminating = true
|
||||||
system "sending SIGTERM to all processes"
|
if Foreman.windows?
|
||||||
killall "SIGTERM"
|
system "sending SIGKILL to all processes"
|
||||||
|
killall "SIGKILL"
|
||||||
|
else
|
||||||
|
system "sending SIGTERM to all processes"
|
||||||
|
killall "SIGTERM"
|
||||||
|
end
|
||||||
Timeout.timeout(5) do
|
Timeout.timeout(5) do
|
||||||
watch_for_termination while @running.length > 0
|
watch_for_termination while @running.length > 0
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class Foreman::Engine::CLI < Foreman::Engine
|
|||||||
|
|
||||||
def color?
|
def color?
|
||||||
return true if @@color_force
|
return true if @@color_force
|
||||||
|
return false if Foreman.windows?
|
||||||
return false unless self.respond_to?(:isatty)
|
return false unless self.respond_to?(:isatty)
|
||||||
self.isatty && ENV["TERM"]
|
self.isatty && ENV["TERM"]
|
||||||
end
|
end
|
||||||
@@ -48,12 +49,12 @@ class Foreman::Engine::CLI < Foreman::Engine
|
|||||||
|
|
||||||
def startup
|
def startup
|
||||||
@colors = map_colors
|
@colors = map_colors
|
||||||
proctitle "foreman: master"
|
proctitle "foreman: master" unless Foreman.windows?
|
||||||
|
Color.enable($stdout, options[:color])
|
||||||
end
|
end
|
||||||
|
|
||||||
def output(name, data)
|
def output(name, data)
|
||||||
data.to_s.chomp.split("\n").each do |message|
|
data.to_s.chomp.split("\n").each do |message|
|
||||||
Color.enable($stdout, options[:color]) unless $stdout.respond_to?(:color?)
|
|
||||||
output = ""
|
output = ""
|
||||||
output += $stdout.color(@colors[name.split(".").first].to_sym)
|
output += $stdout.color(@colors[name.split(".").first].to_sym)
|
||||||
output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
|
output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
|
||||||
|
|||||||
+3
-1
@@ -9,8 +9,10 @@ class Foreman::Env
|
|||||||
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
|
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
|
||||||
key = $1
|
key = $1
|
||||||
case val = $2
|
case val = $2
|
||||||
|
# Remove single quotes
|
||||||
when /\A'(.*)'\z/ then ax[key] = $1
|
when /\A'(.*)'\z/ then ax[key] = $1
|
||||||
when /\A"(.*)"\z/ then ax[key] = $1.gsub(/\\(.)/, '\1')
|
# Remove double quotes and unescape string preserving newline characters
|
||||||
|
when /\A"(.*)"\z/ then ax[key] = $1.gsub('\n', "\n").gsub(/\\(.)/, '\1')
|
||||||
else ax[key] = val
|
else ax[key] = val
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ private ######################################################################
|
|||||||
end
|
end
|
||||||
|
|
||||||
def write_template(name, target, binding)
|
def write_template(name, target, binding)
|
||||||
compiled = ERB.new(export_template(name)).result(binding)
|
compiled = ERB.new(export_template(name), nil, '-').result(binding)
|
||||||
write_file target, compiled
|
write_file target, compiled
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,16 @@ class Foreman::Export::Inittab < Foreman::Export::Base
|
|||||||
1.upto(engine.formation[name]) do |num|
|
1.upto(engine.formation[name]) do |num|
|
||||||
id = app.slice(0, 2).upcase + sprintf("%02d", index)
|
id = app.slice(0, 2).upcase + sprintf("%02d", index)
|
||||||
port = engine.port_for(process, num)
|
port = engine.port_for(process, num)
|
||||||
inittab << "#{id}:4:respawn:/bin/su - #{user} -c 'PORT=#{port} #{process.command} >> #{log}/#{name}-#{num}.log 2>&1'"
|
|
||||||
|
commands = []
|
||||||
|
commands << "cd #{engine.root}"
|
||||||
|
commands << "export PORT=#{port}"
|
||||||
|
engine.env.each_pair do |var, env|
|
||||||
|
commands << "export #{var.upcase}=#{shell_quote(env)}"
|
||||||
|
end
|
||||||
|
commands << "#{process.command} >> #{log}/#{name}-#{num}.log 2>&1"
|
||||||
|
|
||||||
|
inittab << "#{id}:4:respawn:/bin/su - #{user} -c '#{commands.join(";")}'"
|
||||||
index += 1
|
index += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ class Foreman::Export::Launchd < Foreman::Export::Base
|
|||||||
super
|
super
|
||||||
engine.each_process do |name, process|
|
engine.each_process do |name, process|
|
||||||
1.upto(engine.formation[name]) do |num|
|
1.upto(engine.formation[name]) do |num|
|
||||||
|
port = engine.port_for(process, num)
|
||||||
|
command_args = process.command.split(" ")
|
||||||
write_template "launchd/launchd.plist.erb", "#{app}-#{name}-#{num}.plist", binding
|
write_template "launchd/launchd.plist.erb", "#{app}-#{name}-#{num}.plist", binding
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+27
-11
@@ -36,17 +36,27 @@ class Foreman::Process
|
|||||||
|
|
||||||
if Foreman.windows?
|
if Foreman.windows?
|
||||||
Dir.chdir(cwd) do
|
Dir.chdir(cwd) do
|
||||||
Process.spawn env, command, :out => output, :err => output, :new_pgroup => true
|
expanded_command = command.dup
|
||||||
|
env.each do |key, val|
|
||||||
|
expanded_command.gsub!("$#{key}", val)
|
||||||
|
end
|
||||||
|
Process.spawn env, expanded_command, :out => output, :err => output
|
||||||
end
|
end
|
||||||
elsif Foreman.jruby?
|
elsif Foreman.jruby?
|
||||||
Dir.chdir(cwd) do
|
require "posix/spawn"
|
||||||
require "posix/spawn"
|
wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
|
||||||
POSIX::Spawn.spawn env, command, :out => output, :err => output, :pgroup => 0
|
POSIX::Spawn.spawn env, wrapped_command, :out => output, :err => output
|
||||||
|
elsif Foreman.ruby_18?
|
||||||
|
fork do
|
||||||
|
$stdout.reopen output
|
||||||
|
$stderr.reopen output
|
||||||
|
env.each { |k,v| ENV[k] = v }
|
||||||
|
wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
|
||||||
|
exec wrapped_command
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Dir.chdir(cwd) do
|
wrapped_command = "#{Foreman.runner} -d '#{cwd}' -p -- #{command}"
|
||||||
Process.spawn env, command, :out => output, :err => output, :pgroup => 0
|
Process.spawn env, wrapped_command, :out => output, :err => output
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -55,7 +65,11 @@ class Foreman::Process
|
|||||||
# @param [String] signal The signal to send
|
# @param [String] signal The signal to send
|
||||||
#
|
#
|
||||||
def kill(signal)
|
def kill(signal)
|
||||||
pid && Process.kill(signal, -1 * pid)
|
if Foreman.windows?
|
||||||
|
pid && Process.kill(signal, pid)
|
||||||
|
else
|
||||||
|
pid && Process.kill("-#{signal}", pid)
|
||||||
|
end
|
||||||
rescue Errno::ESRCH
|
rescue Errno::ESRCH
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
@@ -76,10 +90,12 @@ class Foreman::Process
|
|||||||
!alive?
|
!alive?
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
# Returns the working directory for this +Process+
|
||||||
|
#
|
||||||
|
# @returns [String]
|
||||||
|
#
|
||||||
def cwd
|
def cwd
|
||||||
@options[:cwd] || "."
|
File.expand_path(@options[:cwd] || ".")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
module Foreman
|
module Foreman
|
||||||
|
|
||||||
VERSION = "0.48.0"
|
VERSION = "0.58.0"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
.\" generated with Ronn/v0.7.3
|
.\" generated with Ronn/v0.7.3
|
||||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||||
.
|
.
|
||||||
.TH "FOREMAN" "1" "April 2012" "Foreman 0.46.0" "Foreman Manual"
|
.TH "FOREMAN" "1" "July 2012" "Foreman 0.57.0" "Foreman Manual"
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBforeman\fR \- manage Procfile\-based applications
|
\fBforeman\fR \- manage Procfile\-based applications
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ describe "Foreman::CLI", :fakefs do
|
|||||||
it "includes the environment" do
|
it "includes the environment" do
|
||||||
forked_foreman("run #{resource_path("bin/env FOO")} -e #{resource_path(".env")}").should == "bar\n"
|
forked_foreman("run #{resource_path("bin/env FOO")} -e #{resource_path(".env")}").should == "bar\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "exits with the same exit code as the command" do
|
||||||
|
fork_and_get_exitstatus("run echo 1").should == 0
|
||||||
|
fork_and_get_exitstatus("run date 'invalid_date'").should == 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "version" do
|
describe "version" do
|
||||||
|
|||||||
@@ -90,6 +90,14 @@ describe "Foreman::Engine", :fakefs do
|
|||||||
subject.env["OTHER"].should == 'escaped"quote'
|
subject.env["OTHER"].should == 'escaped"quote'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should handle multiline strings" do
|
||||||
|
File.open("/tmp/env", "w") do |f|
|
||||||
|
f.puts 'FOO="bar\nbaz"'
|
||||||
|
end
|
||||||
|
subject.load_env "/tmp/env"
|
||||||
|
subject.env["FOO"].should == "bar\nbaz"
|
||||||
|
end
|
||||||
|
|
||||||
it "should fail if specified and doesnt exist" do
|
it "should fail if specified and doesnt exist" do
|
||||||
lambda { subject.load_env "/tmp/env" }.should raise_error(Errno::ENOENT)
|
lambda { subject.load_env "/tmp/env" }.should raise_error(Errno::ENOENT)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -18,4 +18,14 @@ describe Foreman::Export::Launchd, :fakefs do
|
|||||||
File.read("/tmp/init/app-bravo-1.plist").should == example_export_file("launchd/launchd-b.default")
|
File.read("/tmp/init/app-bravo-1.plist").should == example_export_file("launchd/launchd-b.default")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with multiple command arguments" do
|
||||||
|
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", "charlie") }
|
||||||
|
|
||||||
|
it "splits each command argument" do
|
||||||
|
launchd.export
|
||||||
|
File.read("/tmp/init/app-alpha-1.plist").should == example_export_file("launchd/launchd-c.default")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# ----- foreman app processes -----
|
# ----- foreman app processes -----
|
||||||
AP01:4:respawn:/bin/su - app -c 'PORT=5000 ./alpha >> /var/log/app/alpha-1.log 2>&1'
|
AP01:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5000;./alpha >> /var/log/app/alpha-1.log 2>&1'
|
||||||
AP02:4:respawn:/bin/su - app -c 'PORT=5001 ./alpha >> /var/log/app/alpha-2.log 2>&1'
|
AP02:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5001;./alpha >> /var/log/app/alpha-2.log 2>&1'
|
||||||
# ----- end foreman app processes -----
|
# ----- end foreman app processes -----
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# ----- foreman app processes -----
|
# ----- foreman app processes -----
|
||||||
AP01:4:respawn:/bin/su - app -c 'PORT=5000 ./alpha >> /var/log/app/alpha-1.log 2>&1'
|
AP01:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5000;./alpha >> /var/log/app/alpha-1.log 2>&1'
|
||||||
AP02:4:respawn:/bin/su - app -c 'PORT=5100 ./bravo >> /var/log/app/bravo-1.log 2>&1'
|
AP02:4:respawn:/bin/su - app -c 'cd /tmp/app;export PORT=5100;./bravo >> /var/log/app/bravo-1.log 2>&1'
|
||||||
# ----- end foreman app processes -----
|
# ----- end foreman app processes -----
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>Label</key>
|
<key>Label</key>
|
||||||
<string>app-alpha-1</string>
|
<string>app-alpha-1</string>
|
||||||
|
<key>EnvironmentVariables</key>
|
||||||
|
<dict>
|
||||||
|
<key>PORT</key>
|
||||||
|
<string>5000</string>
|
||||||
|
</dict>
|
||||||
<key>ProgramArguments</key>
|
<key>ProgramArguments</key>
|
||||||
<array>
|
<array>
|
||||||
<string>./alpha</string>
|
<string>./alpha</string>
|
||||||
@@ -12,6 +17,8 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>RunAtLoad</key>
|
<key>RunAtLoad</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>StandardOutPath</key>
|
||||||
|
<string>/var/log/app/app-alpha-1.log</string>
|
||||||
<key>StandardErrorPath</key>
|
<key>StandardErrorPath</key>
|
||||||
<string>/var/log/app/app-alpha-1.log</string>
|
<string>/var/log/app/app-alpha-1.log</string>
|
||||||
<key>UserName</key>
|
<key>UserName</key>
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>Label</key>
|
<key>Label</key>
|
||||||
<string>app-bravo-1</string>
|
<string>app-bravo-1</string>
|
||||||
|
<key>EnvironmentVariables</key>
|
||||||
|
<dict>
|
||||||
|
<key>PORT</key>
|
||||||
|
<string>5100</string>
|
||||||
|
</dict>
|
||||||
<key>ProgramArguments</key>
|
<key>ProgramArguments</key>
|
||||||
<array>
|
<array>
|
||||||
<string>./bravo</string>
|
<string>./bravo</string>
|
||||||
@@ -12,6 +17,8 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>RunAtLoad</key>
|
<key>RunAtLoad</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>StandardOutPath</key>
|
||||||
|
<string>/var/log/app/app-bravo-1.log</string>
|
||||||
<key>StandardErrorPath</key>
|
<key>StandardErrorPath</key>
|
||||||
<string>/var/log/app/app-bravo-1.log</string>
|
<string>/var/log/app/app-bravo-1.log</string>
|
||||||
<key>UserName</key>
|
<key>UserName</key>
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>Label</key>
|
||||||
|
<string>app-alpha-1</string>
|
||||||
|
<key>EnvironmentVariables</key>
|
||||||
|
<dict>
|
||||||
|
<key>PORT</key>
|
||||||
|
<string>5000</string>
|
||||||
|
</dict>
|
||||||
|
<key>ProgramArguments</key>
|
||||||
|
<array>
|
||||||
|
<string>./alpha</string>
|
||||||
|
<string>charlie</string>
|
||||||
|
</array>
|
||||||
|
<key>KeepAlive</key>
|
||||||
|
<true/>
|
||||||
|
<key>RunAtLoad</key>
|
||||||
|
<true/>
|
||||||
|
<key>StandardOutPath</key>
|
||||||
|
<string>/var/log/app/app-alpha-1.log</string>
|
||||||
|
<key>StandardErrorPath</key>
|
||||||
|
<string>/var/log/app/app-alpha-1.log</string>
|
||||||
|
<key>UserName</key>
|
||||||
|
<string>app</string>
|
||||||
|
<key>WorkingDirectory</key>
|
||||||
|
<string>/tmp/app</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -6,3 +6,11 @@ bash << "EOF"
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
end script
|
end script
|
||||||
|
|
||||||
|
start on (started network-interface
|
||||||
|
or started network-manager
|
||||||
|
or started networking)
|
||||||
|
|
||||||
|
stop on (stopping network-interface
|
||||||
|
or stopping network-manager
|
||||||
|
or stopping networking)
|
||||||
|
|||||||
@@ -58,6 +58,12 @@ def fork_and_capture(&blk)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fork_and_get_exitstatus(args)
|
||||||
|
pid = Process.spawn("bundle exec bin/foreman #{args}", :out => "/dev/null", :err => "/dev/null")
|
||||||
|
Process.wait(pid)
|
||||||
|
$?.exitstatus
|
||||||
|
end
|
||||||
|
|
||||||
def mock_exit(&block)
|
def mock_exit(&block)
|
||||||
block.should raise_error(SystemExit)
|
block.should raise_error(SystemExit)
|
||||||
end
|
end
|
||||||
|
|||||||
+1
-2
@@ -32,7 +32,7 @@ def latest_release
|
|||||||
end
|
end
|
||||||
|
|
||||||
def newer_release
|
def newer_release
|
||||||
tags = %x{ git tag --contains v#{latest_release} }.split("\n").sort_by do |tag|
|
tags = %x{ git tag --contains v#{latest_release} | grep -v pre }.split("\n").sort_by do |tag|
|
||||||
Gem::Version.new(tag[1..-1])
|
Gem::Version.new(tag[1..-1])
|
||||||
end
|
end
|
||||||
tags[1]
|
tags[1]
|
||||||
@@ -60,7 +60,6 @@ end
|
|||||||
|
|
||||||
desc "Cut a release"
|
desc "Cut a release"
|
||||||
task :release do
|
task :release do
|
||||||
Rake::Task["authors"].invoke
|
|
||||||
Rake::Task["changelog"].invoke
|
Rake::Task["changelog"].invoke
|
||||||
Rake::Task["pages"].invoke
|
Rake::Task["pages"].invoke
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user