Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64f0749d16 | ||
|
|
6b77ca1e46 | ||
|
|
6a44dd3fd3 | ||
|
|
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 | ||
|
|
7d6de5b2a7 | ||
|
|
cc4306492e | ||
|
|
8b204db2f0 | ||
|
|
ebe160d425 | ||
|
|
0a61b1a62f |
@@ -16,9 +16,7 @@ notifications:
|
||||
- http://dx-helper.herokuapp.com/travis
|
||||
|
||||
rvm:
|
||||
- 1.8.7
|
||||
- 1.9.2
|
||||
- 1.9.3
|
||||
- jruby
|
||||
- rbx
|
||||
- ree
|
||||
|
||||
12
Changelog.md
12
Changelog.md
@@ -1,3 +1,15 @@
|
||||
## 0.57.0 (2012-08-21)
|
||||
|
||||
* fix startup checks for upstart exporter [Aditya Sanghi]
|
||||
|
||||
## 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]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
foreman (0.55.0)
|
||||
foreman (0.59.0)
|
||||
thor (>= 0.13.6)
|
||||
|
||||
GEM
|
||||
@@ -39,7 +39,7 @@ GEM
|
||||
multi_json (~> 1.0.3)
|
||||
simplecov-html (~> 0.5.3)
|
||||
simplecov-html (0.5.3)
|
||||
thor (0.15.4)
|
||||
thor (0.16.0)
|
||||
timecop (0.3.5)
|
||||
win32console (1.3.0-x86-mingw32)
|
||||
xml-simple (1.0.15)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/sh
|
||||
#
|
||||
#/ Usage: foreman-runner [-d <dir>] [-p] <command> [<args>...]
|
||||
#/
|
||||
@@ -16,12 +16,12 @@ usage() {
|
||||
exit
|
||||
}
|
||||
|
||||
read_profiled=""
|
||||
read_profile=""
|
||||
|
||||
while getopts ":hd:p" OPT; do
|
||||
case $OPT in
|
||||
d) cd "$OPTARG" ;;
|
||||
p) read_profiled="1" ;;
|
||||
p) read_profile="1" ;;
|
||||
h) usage ;;
|
||||
\?) error "invalid option: -$OPTARG" ;;
|
||||
:) error "option -$OPTARG requires an argument" ;;
|
||||
@@ -32,13 +32,10 @@ shift $((OPTIND-1))
|
||||
|
||||
[ -z "$1" ] && usage
|
||||
|
||||
if [ "$read_profiled" == "1" ]; then
|
||||
shopt -s nullglob
|
||||
for script in .profile.d/*; do
|
||||
echo "sourcing $script"
|
||||
source $script
|
||||
done
|
||||
shopt -u nullglob
|
||||
if [ "$read_profile" = "1" ]; then
|
||||
if [ -f .profile ]; then
|
||||
. .profile
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
||||
@@ -4,14 +4,25 @@
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<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>
|
||||
<array>
|
||||
<string><%= process.command %></string>
|
||||
<%- command_args.each do |command| -%>
|
||||
<string><%= command %></string>
|
||||
<%- end -%>
|
||||
</array>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string><%= log %>/<%= app %>-<%= name %>-<%=num%>.log</string>
|
||||
<key>UserName</key>
|
||||
|
||||
@@ -7,5 +7,10 @@ EOF
|
||||
|
||||
end script
|
||||
|
||||
start on started network
|
||||
stop on stopping network
|
||||
start on (started network-interface
|
||||
or started network-manager
|
||||
or started networking)
|
||||
|
||||
stop on (stopping network-interface
|
||||
or stopping network-manager
|
||||
or stopping networking)
|
||||
|
||||
54
lib/foreman/capistrano.rb
Normal file
54
lib/foreman/capistrano.rb
Normal file
@@ -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
|
||||
@@ -86,6 +86,7 @@ class Foreman::CLI < Thor
|
||||
end
|
||||
end
|
||||
Process.wait(pid)
|
||||
exit $?.exitstatus
|
||||
end
|
||||
|
||||
desc "version", "Display Foreman gem version"
|
||||
@@ -129,7 +130,7 @@ private ######################################################################
|
||||
def procfile
|
||||
case
|
||||
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"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -257,7 +257,6 @@ private
|
||||
reader, writer = create_pipe
|
||||
begin
|
||||
pid = process.run(:output => writer, :env => {
|
||||
"HOME" => process.cwd,
|
||||
"PORT" => port_for(process, n).to_s
|
||||
})
|
||||
writer.puts "started with pid #{pid}"
|
||||
|
||||
@@ -9,8 +9,10 @@ class Foreman::Env
|
||||
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
|
||||
key = $1
|
||||
case val = $2
|
||||
# Remove single quotes
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
@@ -119,7 +119,7 @@ private ######################################################################
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
@@ -13,7 +13,16 @@ class Foreman::Export::Inittab < Foreman::Export::Base
|
||||
1.upto(engine.formation[name]) do |num|
|
||||
id = app.slice(0, 2).upcase + sprintf("%02d", index)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,8 @@ class Foreman::Export::Launchd < Foreman::Export::Base
|
||||
super
|
||||
engine.each_process do |name, process|
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Foreman
|
||||
|
||||
VERSION = "0.55.0"
|
||||
VERSION = "0.59.0"
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "FOREMAN" "1" "July 2012" "Foreman 0.51.0" "Foreman Manual"
|
||||
.TH "FOREMAN" "1" "July 2012" "Foreman 0.57.0" "Foreman Manual"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBforeman\fR \- manage Procfile\-based applications
|
||||
|
||||
@@ -72,6 +72,11 @@ describe "Foreman::CLI", :fakefs do
|
||||
it "includes the environment" do
|
||||
forked_foreman("run #{resource_path("bin/env FOO")} -e #{resource_path(".env")}").should == "bar\n"
|
||||
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
|
||||
|
||||
describe "version" do
|
||||
|
||||
@@ -90,6 +90,14 @@ describe "Foreman::Engine", :fakefs do
|
||||
subject.env["OTHER"].should == 'escaped"quote'
|
||||
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
|
||||
lambda { subject.load_env "/tmp/env" }.should raise_error(Errno::ENOENT)
|
||||
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")
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# ----- foreman app processes -----
|
||||
AP01:4:respawn:/bin/su - app -c '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'
|
||||
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 'cd /tmp/app;export PORT=5001;./alpha >> /var/log/app/alpha-2.log 2>&1'
|
||||
# ----- end foreman app processes -----
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# ----- foreman app processes -----
|
||||
AP01:4:respawn:/bin/su - app -c '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'
|
||||
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 'cd /tmp/app;export PORT=5100;./bravo >> /var/log/app/bravo-1.log 2>&1'
|
||||
# ----- end foreman app processes -----
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
<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>
|
||||
@@ -12,6 +17,8 @@
|
||||
<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>
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>app-bravo-1</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PORT</key>
|
||||
<string>5100</string>
|
||||
</dict>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>./bravo</string>
|
||||
@@ -12,6 +17,8 @@
|
||||
<true/>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/var/log/app/app-bravo-1.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/var/log/app/app-bravo-1.log</string>
|
||||
<key>UserName</key>
|
||||
|
||||
30
spec/resources/export/launchd/launchd-c.default
Normal file
30
spec/resources/export/launchd/launchd-c.default
Normal file
@@ -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>
|
||||
@@ -7,5 +7,10 @@ EOF
|
||||
|
||||
end script
|
||||
|
||||
start on started network
|
||||
stop on stopping network
|
||||
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
|
||||
|
||||
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)
|
||||
block.should raise_error(SystemExit)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user