Compare commits
69
Commits
v0.35.0
...
v0.37.0.pre4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a04032454a | ||
|
|
29c94c785d | ||
|
|
a0a2dd9454 | ||
|
|
1b701cddf3 | ||
|
|
4080b3f1f2 | ||
|
|
84c49ae2b8 | ||
|
|
d54b46806c | ||
|
|
bc1c5e4c74 | ||
|
|
ed4a32518f | ||
|
|
c7167e1c83 | ||
|
|
db93432118 | ||
|
|
5eada6b7cc | ||
|
|
5e46b1f43a | ||
|
|
ef723f5831 | ||
|
|
52e24ef64b | ||
|
|
0b1daf1927 | ||
|
|
e0d84a56d7 | ||
|
|
7ee2edcc60 | ||
|
|
d428ac5356 | ||
|
|
5351b49fee | ||
|
|
6ebe76d8c1 | ||
|
|
7c43c672c9 | ||
|
|
41d9050ae3 | ||
|
|
09e9cefa3a | ||
|
|
85efe5c1ba | ||
|
|
c21634c04e | ||
|
|
6d4f3476f1 | ||
|
|
724812d6e3 | ||
|
|
ce6ec4848d | ||
|
|
a37a097f73 | ||
|
|
f28725bdac | ||
|
|
51eee011ce | ||
|
|
6c8c848f54 | ||
|
|
f60c4cb767 | ||
|
|
4ad49cb058 | ||
|
|
e993af2b20 | ||
|
|
d7000bccfa | ||
|
|
2995a605b4 | ||
|
|
ef280e802d | ||
|
|
8a9001842c | ||
|
|
8a8d31eb43 | ||
|
|
3e98170878 | ||
|
|
3d84de3062 | ||
|
|
9cc0afca49 | ||
|
|
7a25d3ac5a | ||
|
|
db1a5df354 | ||
|
|
e137596ce0 | ||
|
|
c9042c5aae | ||
|
|
550adc8070 | ||
|
|
fbdde3e62a | ||
|
|
e161ecb630 | ||
|
|
853a88dfbf | ||
|
|
b4cab08327 | ||
|
|
ade0005a92 | ||
|
|
241b91a0d5 | ||
|
|
047f106d48 | ||
|
|
df043e60d8 | ||
|
|
158c184f8c | ||
|
|
2ed1fe8d44 | ||
|
|
a008886bd0 | ||
|
|
c62f892ff6 | ||
|
|
d885e019b3 | ||
|
|
cfd337b44d | ||
|
|
e76f3533dc | ||
|
|
1485eeb859 | ||
|
|
e0b5928e88 | ||
|
|
a73dce5405 | ||
|
|
2abddb42b3 | ||
|
|
d961a32cfe |
+1
-1
@@ -5,4 +5,4 @@
|
|||||||
/man/*.markdown
|
/man/*.markdown
|
||||||
/pkg
|
/pkg
|
||||||
/tags
|
/tags
|
||||||
|
/vendor
|
||||||
+1
-1
@@ -11,4 +11,4 @@ notifications:
|
|||||||
on_success: always
|
on_success: always
|
||||||
on_failure: always
|
on_failure: always
|
||||||
urls:
|
urls:
|
||||||
- https://dx-helper.herokuapp.com/travis
|
- http://dx-helper.herokuapp.com/travis
|
||||||
|
|||||||
@@ -2,6 +2,14 @@ source "http://rubygems.org"
|
|||||||
|
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
|
platform :mingw do
|
||||||
|
gem "win32console", "~> 1.3.0"
|
||||||
|
end
|
||||||
|
|
||||||
|
platform :jruby do
|
||||||
|
gem "posix-spawn", "~> 0.3.6"
|
||||||
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'parka'
|
gem 'parka'
|
||||||
gem 'rake'
|
gem 'rake'
|
||||||
@@ -10,6 +18,7 @@ group :development do
|
|||||||
gem 'rcov', '~> 0.9.8'
|
gem 'rcov', '~> 0.9.8'
|
||||||
gem 'rr', '~> 1.0.2'
|
gem 'rr', '~> 1.0.2'
|
||||||
gem 'rspec', '~> 2.0'
|
gem 'rspec', '~> 2.0'
|
||||||
|
gem 'ZenTest'
|
||||||
gem 'aws-s3'
|
gem 'aws-s3'
|
||||||
gem "rubyzip"
|
gem "rubyzip"
|
||||||
end
|
end
|
||||||
|
|||||||
+12
-2
@@ -1,13 +1,14 @@
|
|||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
foreman (0.35.0)
|
foreman (0.37.0.pre4)
|
||||||
term-ansicolor (~> 1.0.5)
|
term-ansicolor (~> 1.0.7)
|
||||||
thor (>= 0.13.6)
|
thor (>= 0.13.6)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
ZenTest (4.6.2)
|
||||||
aws-s3 (0.6.2)
|
aws-s3 (0.6.2)
|
||||||
builder
|
builder
|
||||||
mime-types
|
mime-types
|
||||||
@@ -17,14 +18,17 @@ GEM
|
|||||||
diff-lcs (1.1.3)
|
diff-lcs (1.1.3)
|
||||||
fakefs (0.3.2)
|
fakefs (0.3.2)
|
||||||
hpricot (0.8.2)
|
hpricot (0.8.2)
|
||||||
|
hpricot (0.8.2-java)
|
||||||
mime-types (1.16)
|
mime-types (1.16)
|
||||||
mustache (0.11.2)
|
mustache (0.11.2)
|
||||||
parka (0.6.2)
|
parka (0.6.2)
|
||||||
crack
|
crack
|
||||||
rest-client
|
rest-client
|
||||||
thor
|
thor
|
||||||
|
posix-spawn (0.3.6)
|
||||||
rake (0.9.2.2)
|
rake (0.9.2.2)
|
||||||
rcov (0.9.8)
|
rcov (0.9.8)
|
||||||
|
rcov (0.9.8-java)
|
||||||
rdiscount (1.6.5)
|
rdiscount (1.6.5)
|
||||||
rest-client (1.6.1)
|
rest-client (1.6.1)
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
@@ -44,19 +48,25 @@ GEM
|
|||||||
rubyzip (0.9.4)
|
rubyzip (0.9.4)
|
||||||
term-ansicolor (1.0.7)
|
term-ansicolor (1.0.7)
|
||||||
thor (0.14.6)
|
thor (0.14.6)
|
||||||
|
win32console (1.3.0-x86-mingw32)
|
||||||
xml-simple (1.0.15)
|
xml-simple (1.0.15)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
|
java
|
||||||
ruby
|
ruby
|
||||||
|
x86-mingw32
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
ZenTest
|
||||||
aws-s3
|
aws-s3
|
||||||
fakefs (~> 0.3.2)
|
fakefs (~> 0.3.2)
|
||||||
foreman!
|
foreman!
|
||||||
parka
|
parka
|
||||||
|
posix-spawn (~> 0.3.6)
|
||||||
rake
|
rake
|
||||||
rcov (~> 0.9.8)
|
rcov (~> 0.9.8)
|
||||||
ronn
|
ronn
|
||||||
rr (~> 1.0.2)
|
rr (~> 1.0.2)
|
||||||
rspec (~> 2.0)
|
rspec (~> 2.0)
|
||||||
rubyzip
|
rubyzip
|
||||||
|
win32console (~> 1.3.0)
|
||||||
|
|||||||
+23
-34
@@ -1,49 +1,38 @@
|
|||||||
# Foreman
|
# Foreman
|
||||||
|
|
||||||
## Installation
|
Manage Procfile-based applications
|
||||||
|
|
||||||
* Rubygems
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>If you have...</th>
|
||||||
|
<th>Install with...</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Ruby (MRI, JRuby, Windows)</td>
|
||||||
|
<td><pre>$ gem install foreman</pre></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Mac OS X</td>
|
||||||
|
<td><a href="http://assets.foreman.io/foreman/foreman.pkg">foreman.pkg</a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
gem install foreman
|
## Getting Started
|
||||||
|
|
||||||
* OSX
|
* http://blog.daviddollar.org/2011/05/06/introducing-foreman.html
|
||||||
|
|
||||||
http://assets.foreman.io/foreman/foreman.pkg
|
## Documentation
|
||||||
|
|
||||||
* Standalone Tarball
|
|
||||||
|
|
||||||
http://assets.foreman.io/foreman/foreman.tgz
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
http://blog.daviddollar.org/2011/05/06/introducing-foreman.html
|
|
||||||
|
|
||||||
## Manual
|
|
||||||
|
|
||||||
* [man page](http://ddollar.github.com/foreman)
|
* [man page](http://ddollar.github.com/foreman)
|
||||||
* [wiki](http://github.com/ddollar/foreman/wiki)
|
* [wiki](http://github.com/ddollar/foreman/wiki)
|
||||||
|
|
||||||
## Authorship
|
## Authors
|
||||||
|
|
||||||
Created by David Dollar
|
#### Created and maintained by
|
||||||
|
David Dollar
|
||||||
|
|
||||||
Patches contributed by:
|
#### Patches contributed by
|
||||||
|
Adam Wiggins, Chris Continanza, Chris Lowder, Craig R Webster, Dan Farina, Dan Peterson, David Dollar, Fletcher Nichol, Gabriel Burt, Gamaliel Toro, Greg Reinacker, Hugues Le Gendre, Hunter Nield, Iain Hecker, Jay Zeschin, Keith Rarick, Khaja Minhajuddin, Lincoln Stoll, Marcos Muino Garcia, Mark McGranaghan, Matt Griffin, Matt Haynes, Matthijs Langenberg, Michael Dwan, Michael van Rooijen, Mike Javorski, Nathan Broadbent, Nathan L Smith, Nick Zadrozny, Phil Hagelberg, Ricardo Chimal, Jr, Thom May, Tom Ward, brainopia, clifff, jc00ke
|
||||||
* Adam Wiggins
|
|
||||||
* Dan Peterson
|
|
||||||
* Hunter Nield
|
|
||||||
* Jay Zeschin
|
|
||||||
* Keith Rarick
|
|
||||||
* Khaja Minhajuddin
|
|
||||||
* Matt Haynes
|
|
||||||
* Michael van Rooijen
|
|
||||||
* Mike Javorski
|
|
||||||
* Nathan L Smith
|
|
||||||
* Nick Zadrozny
|
|
||||||
* Ricardo Chimal, Jr
|
|
||||||
* Thom May
|
|
||||||
* clifff
|
|
||||||
* Greg Reinacker
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
require "rubygems"
|
|
||||||
require "bundler"
|
|
||||||
Bundler.setup
|
|
||||||
|
|
||||||
require "rake"
|
require "rake"
|
||||||
require "rspec"
|
require "rspec"
|
||||||
require "rspec/core/rake_task"
|
require "rspec/core/rake_task"
|
||||||
@@ -55,6 +51,11 @@ task :pages => "man:commit" do
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
task :authors do
|
||||||
|
authors = %x{ git log --pretty=format:"%an" | sort -u }.split("\n")
|
||||||
|
puts authors.join(", ")
|
||||||
|
end
|
||||||
|
|
||||||
## dist
|
## dist
|
||||||
|
|
||||||
require "erb"
|
require "erb"
|
||||||
@@ -102,9 +103,13 @@ def clean(file)
|
|||||||
rm file if File.exists?(file)
|
rm file if File.exists?(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
def distribution_files
|
def distribution_files(type=nil)
|
||||||
require "foreman/distribution"
|
require "foreman/distribution"
|
||||||
Foreman::Distribution.files
|
base_files = Foreman::Distribution.files
|
||||||
|
type_files = type ?
|
||||||
|
Dir[File.expand_path("../dist/resources/#{type}/**/*", __FILE__)] :
|
||||||
|
[]
|
||||||
|
base_files.concat(type_files)
|
||||||
end
|
end
|
||||||
|
|
||||||
def mkchdir(dir)
|
def mkchdir(dir)
|
||||||
|
|||||||
+35
-1
@@ -1,2 +1,36 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec $1 2>&1
|
#
|
||||||
|
#/ Usage: runner [-d <dir>] <command>
|
||||||
|
#/
|
||||||
|
#/ Run a command with exec, optionally changing directory first
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo $@ >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat $0 | grep '^#/' | cut -c4-
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts ":hd:" OPT; do
|
||||||
|
case $OPT in
|
||||||
|
d) cd $OPTARG ;;
|
||||||
|
h) usage ;;
|
||||||
|
\?) error "invalid option: -$OPTARG" ;;
|
||||||
|
:) error "option -$OPTARG requires an argument" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
command=$1
|
||||||
|
|
||||||
|
if [ "$1" == "" ]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec $1
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Bluepill.application("<%= app %>", :foreground => false, :log_file => "/var/log/
|
|||||||
|
|
||||||
<% engine.procfile.entries.each do |process| %>
|
<% engine.procfile.entries.each do |process| %>
|
||||||
<% 1.upto(concurrency[process.name]) do |num| %>
|
<% 1.upto(concurrency[process.name]) do |num| %>
|
||||||
<% port = engine.port_for(process, num, options[:port]) %>
|
<% port = engine.port_for(process, num, self.port) %>
|
||||||
app.process("<%= process.name %>-<%=num%>") do |process|
|
app.process("<%= process.name %>-<%=num%>") do |process|
|
||||||
process.start_command = "<%= process.command.gsub("$PORT", port.to_s) %>"
|
process.start_command = "<%= process.command.gsub("$PORT", port.to_s) %>"
|
||||||
|
|
||||||
|
|||||||
Vendored
+48
@@ -0,0 +1,48 @@
|
|||||||
|
file pkg("/apt-#{version}/foreman-#{version}.deb") => distribution_files("deb") do |t|
|
||||||
|
mkchdir(File.dirname(t.name)) do
|
||||||
|
mkchdir("usr/local/foreman") do
|
||||||
|
assemble_distribution
|
||||||
|
assemble_gems
|
||||||
|
assemble resource("deb/foreman"), "bin/foreman", 0755
|
||||||
|
File.chmod 0755, "bin/runner"
|
||||||
|
end
|
||||||
|
|
||||||
|
assemble resource("deb/control"), "control"
|
||||||
|
assemble resource("deb/postinst"), "postinst"
|
||||||
|
|
||||||
|
sh "tar czvf data.tar.gz usr/local/foreman --owner=root --group=root"
|
||||||
|
sh "tar czvf control.tar.gz control postinst"
|
||||||
|
|
||||||
|
File.open("debian-binary", "w") do |f|
|
||||||
|
f.puts "2.0"
|
||||||
|
end
|
||||||
|
|
||||||
|
deb = File.basename(t.name)
|
||||||
|
|
||||||
|
sh "ar -r #{t.name} debian-binary control.tar.gz data.tar.gz"
|
||||||
|
|
||||||
|
touch "Sources"
|
||||||
|
sh "apt-ftparchive packages . > Packages"
|
||||||
|
sh "gzip -c Packages > Packages.gz"
|
||||||
|
sh "apt-ftparchive release . > Release"
|
||||||
|
sh "gpg -abs -u 0F1B0520 -o Release.gpg Release"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Build a .deb package"
|
||||||
|
task "deb:build" => pkg("/apt-#{version}/foreman-#{version}.deb")
|
||||||
|
|
||||||
|
desc "Remove build artifacts for .deb"
|
||||||
|
task "deb:clean" do
|
||||||
|
clean pkg("foreman-#{version}.deb")
|
||||||
|
FileUtils.rm_rf("pkg/apt-#{version}") if Dir.exists?("pkg/apt-#{version}")
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Publish .deb to S3."
|
||||||
|
task "deb:release" => "deb:build" do |t|
|
||||||
|
Dir["pkg/apt-#{version}/*"].each do |file|
|
||||||
|
unless File.directory?(file)
|
||||||
|
store file, "apt/#{File.basename(file)}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
file pkg("foreman-#{version}-jruby.gem") => distribution_files do |t|
|
||||||
|
sh "env PLATFORM=java gem build foreman.gemspec"
|
||||||
|
sh "mv foreman-#{version}-java.gem #{t.name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
task "jruby:build" => pkg("foreman-#{version}-jruby.gem")
|
||||||
|
|
||||||
|
task "jruby:clean" do
|
||||||
|
clean pkg("foreman-#{version}-jruby.gem")
|
||||||
|
end
|
||||||
|
|
||||||
|
task "jruby:release" => "jruby:build" do |t|
|
||||||
|
sh "parka push -f #{pkg("foreman-#{version}-jruby.gem")}"
|
||||||
|
end
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
file pkg("foreman-#{version}-mingw32.gem") => distribution_files do |t|
|
||||||
|
sh "env PLATFORM=mingw32 gem build foreman.gemspec"
|
||||||
|
sh "mv foreman-#{version}-mingw32.gem #{t.name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
task "mingw32:build" => pkg("foreman-#{version}-mingw32.gem")
|
||||||
|
|
||||||
|
task "mingw32:clean" do
|
||||||
|
clean pkg("foreman-#{version}-mingw32.gem")
|
||||||
|
end
|
||||||
|
|
||||||
|
task "mingw32:release" => "mingw32:build" do |t|
|
||||||
|
sh "parka push -f #{pkg("foreman-#{version}-mingw32.gem")}"
|
||||||
|
end
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
Package: foreman
|
||||||
|
Version: <%= version %>
|
||||||
|
Section: main
|
||||||
|
Priority: standard
|
||||||
|
Architecture: all
|
||||||
|
Depends: ruby1.9.1
|
||||||
|
Maintainer: Heroku
|
||||||
|
Description: Manage Procfile-based applications.
|
||||||
|
Foreman is a manager for Procfile-based applications. Its aim is to
|
||||||
|
abstract away the details of the Procfile format, and allow you to
|
||||||
|
either run your application directly or export it to some other
|
||||||
|
process management format.
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env ruby1.9.1
|
||||||
|
|
||||||
|
# resolve bin path, ignoring symlinks
|
||||||
|
require "pathname"
|
||||||
|
bin_file = Pathname.new(__FILE__).realpath
|
||||||
|
|
||||||
|
# add locally vendored gems to libpath
|
||||||
|
gem_dir = File.expand_path("../../vendor/gems", bin_file)
|
||||||
|
Dir["#{gem_dir}/**/lib"].each do |libdir|
|
||||||
|
$:.unshift libdir
|
||||||
|
end
|
||||||
|
|
||||||
|
# add self to libpath
|
||||||
|
$:.unshift File.expand_path("../../lib", bin_file)
|
||||||
|
|
||||||
|
require "foreman/cli"
|
||||||
|
|
||||||
|
Foreman::CLI.start
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v1.4.11 (Darwin)
|
||||||
|
|
||||||
|
mQENBE5SfAEBCADLp056ZgfdtAMXLWpEuL9zY+dIHIY5qLQcDmUivjHLVE4l3Bi3
|
||||||
|
Mn570K0W9rfk7fHBPEO2XJEDdjk8Bg6mWTAeGjdfZgZaL+qO9NjqQ5QmVR+vgp7s
|
||||||
|
yxJYlfY+JYTZvl/JiDWGhuPHSPggXILCMf3SpqWMHGPqe/3RAK+CHCNv/94uaoS4
|
||||||
|
vi4HQT+k4sRceiM8WqkSRYSoc7rzdDejZn+InCYFfR56VeSFF4G4I6neZs/q5T9d
|
||||||
|
Ty2i5d0gZLaX/Iqc+3Dy0vDKClc0HUQJ6ajDPuUqKLHFUpqyuwfJij60+C3GMi8K
|
||||||
|
ckRPti31EPFVzq3GPHU+GqA+e9j84WHr4uJ5ABEBAAG0L0hlcm9rdSBSZWxlYXNl
|
||||||
|
IEVuZ2luZWVyaW5nIDxyZWxlYXNlQGhlcm9rdS5jb20+iQE4BBMBAgAiBQJOUnwB
|
||||||
|
AhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRDJJ+vgDxsFIChECAC9h4Ay
|
||||||
|
Nx4AQFu85cjR9rijyBflPeVqi7Xhzd7IvLg2+kZSexlb2oidj7iVSMy+vy5tG9g9
|
||||||
|
8Az/JqMCVjcZ7ltn60OGU8gIYpJqt6VmH3vfJBxXu/Sm9tym3UCYGVvMAN5Oq6yB
|
||||||
|
HlQkQ8F3p0cW69PmF+fibkgo9RE0EYlBIt2rUHNilTGFS6vXGr5reFFp3/rRHq3k
|
||||||
|
bixnUwFSqNujJgnBKDPwtSYKc4pMpnhuv88xEpLH7vU8NLXQZMitKQguV8XEmcsu
|
||||||
|
43LXlsx5uVr239/XNW+h412gIHFDSzB/YuLWlVUXMfquC96z/wxMqWWZyskDNgr0
|
||||||
|
WDdMgzK6CUfXSqQhuQENBE5SfAEBCADbnGKcXpdVauQpINQLtRnrT0BJIrIo1Yxv
|
||||||
|
LQRb3G7RU+Eq6aHXwk9fSKa6nEv9RsmqiW874yODnr0d/DTUWMHT+jRvPHm1wlbE
|
||||||
|
pGR1aPSo7GgkSUdaT6CVBN3JWZ2kVJGqohNoJMYbfVaWd/kpa/LiMFWzS8LfWT2K
|
||||||
|
xiO2vIh4qBfeRCGR7s8rADCHuHJ0eibADrgqcRfdPrChB1JiYLeTdV4yRmSzJ7TM
|
||||||
|
zWX7OVpGfIFLbCw9NeN65pI9ePs2mSPM7DYkhhKSXWMwJNXFzn1blOGiwAwKb48P
|
||||||
|
a/QpE6TG3PQzbYyTTP0Td1XgKAHcprvbc89a/nAk3a+PJQ/MqvDzABEBAAGJAR8E
|
||||||
|
GAECAAkFAk5SfAECGwwACgkQySfr4A8bBSD4mAgAnCT5WRiDl0259Px9Z9J9Wk8Z
|
||||||
|
SxugDct2Yhzca4aw1Ou4cfaIFCDXzFlBzSJfqk0HoVhp9r2gzEPUCKnSjRDyxaMo
|
||||||
|
wZCUtqigBua+z4NB4AWgeOl/2S06I2ki1K7pfl4piYcHtEThHamnhVPJ2Hi6HsHq
|
||||||
|
mUU+8SxleHE4GCXmKkuvxelUq9jrhHikIkm1RoqFOPb9zV3WRy4YzVHQSYfHmfk0
|
||||||
|
9kXlM/CS0sfNv2UKCX+5e6eFIZv0rdtpp6VEh0tsFmsIClY6Z9MX7bgp8MnUJpyk
|
||||||
|
OeIzOzQgkb4aeT0Whl+EPcTeDZfqIhVBoNXupUanmWNppFcMngxfqG2NGi1vvQ==
|
||||||
|
=aUAq
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
ln -sf /usr/local/foreman/bin/foreman /usr/bin/foreman
|
||||||
+11
-1
@@ -16,6 +16,16 @@ Gem::Specification.new do |gem|
|
|||||||
gem.files = Dir["**/*"].select { |d| d =~ %r{^(README|bin/|data/|ext/|lib/|spec/|test/)} }
|
gem.files = Dir["**/*"].select { |d| d =~ %r{^(README|bin/|data/|ext/|lib/|spec/|test/)} }
|
||||||
gem.files << "man/foreman.1"
|
gem.files << "man/foreman.1"
|
||||||
|
|
||||||
gem.add_dependency 'term-ansicolor', '~> 1.0.5'
|
gem.add_dependency 'term-ansicolor', '~> 1.0.7'
|
||||||
gem.add_dependency 'thor', '>= 0.13.6'
|
gem.add_dependency 'thor', '>= 0.13.6'
|
||||||
|
|
||||||
|
if ENV["PLATFORM"] == "java"
|
||||||
|
gem.add_dependency "posix-spawn", "~> 0.3.6"
|
||||||
|
gem.platform = Gem::Platform.new("java")
|
||||||
|
end
|
||||||
|
|
||||||
|
if ENV["PLATFORM"] == "mingw32"
|
||||||
|
gem.add_dependency "win32console", "~> 1.3.0"
|
||||||
|
gem.platform = Gem::Platform.new("mingw32")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+8
-1
@@ -14,5 +14,12 @@ module Foreman
|
|||||||
File.expand_path("../../bin/runner", __FILE__)
|
File.expand_path("../../bin/runner", __FILE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
def self.jruby?
|
||||||
|
defined?(RUBY_PLATFORM) and RUBY_PLATFORM == "java"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.windows?
|
||||||
|
defined?(RUBY_PLATFORM) and RUBY_PLATFORM =~ /(win|w)32$/
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|||||||
+13
-8
@@ -1,10 +1,14 @@
|
|||||||
require "foreman"
|
require "foreman"
|
||||||
|
require "foreman/helpers"
|
||||||
require "foreman/engine"
|
require "foreman/engine"
|
||||||
require "foreman/export"
|
require "foreman/export"
|
||||||
require "thor"
|
require "thor"
|
||||||
require "yaml"
|
require "yaml"
|
||||||
|
|
||||||
class Foreman::CLI < Thor
|
class Foreman::CLI < Thor
|
||||||
|
include Foreman::Helpers
|
||||||
|
|
||||||
|
class_option :procfile, :type => :string, :aliases => "-f", :desc => "Default: Procfile"
|
||||||
|
|
||||||
desc "start", "Start the application"
|
desc "start", "Start the application"
|
||||||
|
|
||||||
@@ -42,16 +46,17 @@ class Foreman::CLI < Thor
|
|||||||
def export(format, location=nil)
|
def export(format, location=nil)
|
||||||
check_procfile!
|
check_procfile!
|
||||||
|
|
||||||
formatter = case format
|
begin
|
||||||
when "inittab" then Foreman::Export::Inittab
|
require "foreman/export/#{ format.tr('-', '_') }"
|
||||||
when "upstart" then Foreman::Export::Upstart
|
classy_format = classify(format)
|
||||||
when "bluepill" then Foreman::Export::Bluepill
|
formatter = constantize("Foreman::Export::#{ classy_format }")
|
||||||
when "runit" then Foreman::Export::Runit
|
rescue NameError => ex
|
||||||
else error "Unknown export format: #{format}."
|
error "Unknown export format: #{format} (no class Foreman::Export::#{ classy_format })."
|
||||||
|
rescue LoadError => ex
|
||||||
|
error "Unknown export format: #{format} (unable to load file 'foreman/export/#{ format.tr('-', '_') }')."
|
||||||
end
|
end
|
||||||
|
|
||||||
formatter.new(engine).export(location, options)
|
formatter.new(location, engine, options).export
|
||||||
|
|
||||||
rescue Foreman::Export::Exception => ex
|
rescue Foreman::Export::Exception => ex
|
||||||
error ex.message
|
error ex.message
|
||||||
end
|
end
|
||||||
|
|||||||
+11
-9
@@ -2,7 +2,6 @@ require "foreman"
|
|||||||
require "foreman/process"
|
require "foreman/process"
|
||||||
require "foreman/procfile"
|
require "foreman/procfile"
|
||||||
require "foreman/utils"
|
require "foreman/utils"
|
||||||
require "pty"
|
|
||||||
require "tempfile"
|
require "tempfile"
|
||||||
require "timeout"
|
require "timeout"
|
||||||
require "term/ansicolor"
|
require "term/ansicolor"
|
||||||
@@ -74,7 +73,7 @@ private ######################################################################
|
|||||||
def kill_all(signal="SIGTERM")
|
def kill_all(signal="SIGTERM")
|
||||||
running_processes.each do |pid, process|
|
running_processes.each do |pid, process|
|
||||||
info "sending #{signal} to pid #{pid}"
|
info "sending #{signal} to pid #{pid}"
|
||||||
Process.kill(signal, pid) rescue Errno::ESRCH
|
process.kill signal
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -89,11 +88,14 @@ private ######################################################################
|
|||||||
|
|
||||||
def watch_for_output
|
def watch_for_output
|
||||||
Thread.new do
|
Thread.new do
|
||||||
|
require "win32console" if Foreman.windows?
|
||||||
begin
|
begin
|
||||||
loop do
|
loop do
|
||||||
rs, ws = IO.select(readers.values, [], [], 1)
|
rs, ws = IO.select(readers.values, [], [], 1)
|
||||||
(rs || []).each do |r|
|
(rs || []).each do |r|
|
||||||
ps, message = r.gets.split(",", 2)
|
data = r.gets
|
||||||
|
next unless data
|
||||||
|
ps, message = data.split(",", 2)
|
||||||
color = colors[ps.split(".").first]
|
color = colors[ps.split(".").first]
|
||||||
info message, ps, color
|
info message, ps, color
|
||||||
end
|
end
|
||||||
@@ -134,11 +136,6 @@ private ######################################################################
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def error(message)
|
|
||||||
puts "ERROR: #{message}"
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
|
|
||||||
def longest_process_name
|
def longest_process_name
|
||||||
@longest_process_name ||= begin
|
@longest_process_name ||= begin
|
||||||
longest = procfile.process_names.map { |name| name.length }.sort.last
|
longest = procfile.process_names.map { |name| name.length }.sort.last
|
||||||
@@ -156,7 +153,7 @@ private ######################################################################
|
|||||||
end
|
end
|
||||||
|
|
||||||
def termtitle(title)
|
def termtitle(title)
|
||||||
printf("\033]0;#{title}\007")
|
printf("\033]0;#{title}\007") unless Foreman.windows?
|
||||||
end
|
end
|
||||||
|
|
||||||
def running_processes
|
def running_processes
|
||||||
@@ -217,6 +214,11 @@ private ######################################################################
|
|||||||
def apply_environment!
|
def apply_environment!
|
||||||
@environment.each { |k,v| ENV[k] = v }
|
@environment.each { |k,v| ENV[k] = v }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def error(message)
|
||||||
|
puts "ERROR: #{message}"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
include Env
|
include Env
|
||||||
|
|||||||
@@ -3,10 +3,17 @@ require "foreman/utils"
|
|||||||
|
|
||||||
class Foreman::Export::Base
|
class Foreman::Export::Base
|
||||||
|
|
||||||
attr_reader :engine
|
attr_reader :location, :engine, :app, :log, :port, :user, :template, :concurrency
|
||||||
|
|
||||||
def initialize(engine)
|
def initialize(location, engine, options={})
|
||||||
@engine = engine
|
@location = location
|
||||||
|
@engine = engine
|
||||||
|
@app = options[:app]
|
||||||
|
@log = options[:log]
|
||||||
|
@port = options[:port]
|
||||||
|
@user = options[:user]
|
||||||
|
@template = options[:template]
|
||||||
|
@concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
|
||||||
end
|
end
|
||||||
|
|
||||||
def export
|
def export
|
||||||
|
|||||||
@@ -3,23 +3,21 @@ require "foreman/export"
|
|||||||
|
|
||||||
class Foreman::Export::Bluepill < Foreman::Export::Base
|
class Foreman::Export::Bluepill < Foreman::Export::Base
|
||||||
|
|
||||||
def export(location, options={})
|
def export
|
||||||
error("Must specify a location") unless location
|
error("Must specify a location") unless location
|
||||||
|
|
||||||
FileUtils.mkdir_p location
|
FileUtils.mkdir_p location
|
||||||
|
|
||||||
app = options[:app] || File.basename(engine.directory)
|
app = self.app || File.basename(engine.directory)
|
||||||
user = options[:user] || app
|
user = self.user || app
|
||||||
log_root = options[:log] || "/var/log/#{app}"
|
log_root = self.log || "/var/log/#{app}"
|
||||||
template_root = options[:template]
|
template_root = self.template
|
||||||
|
|
||||||
Dir["#{location}/#{app}.pill"].each do |file|
|
Dir["#{location}/#{app}.pill"].each do |file|
|
||||||
say "cleaning up: #{file}"
|
say "cleaning up: #{file}"
|
||||||
FileUtils.rm(file)
|
FileUtils.rm(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
|
|
||||||
|
|
||||||
master_template = export_template("bluepill", "master.pill.erb", template_root)
|
master_template = export_template("bluepill", "master.pill.erb", template_root)
|
||||||
master_config = ERB.new(master_template).result(binding)
|
master_config = ERB.new(master_template).result(binding)
|
||||||
write_file "#{location}/#{app}.pill", master_config
|
write_file "#{location}/#{app}.pill", master_config
|
||||||
|
|||||||
@@ -2,20 +2,18 @@ require "foreman/export"
|
|||||||
|
|
||||||
class Foreman::Export::Inittab < Foreman::Export::Base
|
class Foreman::Export::Inittab < Foreman::Export::Base
|
||||||
|
|
||||||
def export(fname=nil, options={})
|
def export
|
||||||
app = options[:app] || File.basename(engine.directory)
|
app = self.app || File.basename(engine.directory)
|
||||||
user = options[:user] || app
|
user = self.user || app
|
||||||
log_root = options[:log] || "/var/log/#{app}"
|
log_root = self.log || "/var/log/#{app}"
|
||||||
|
|
||||||
concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
|
|
||||||
|
|
||||||
inittab = []
|
inittab = []
|
||||||
inittab << "# ----- foreman #{app} processes -----"
|
inittab << "# ----- foreman #{app} processes -----"
|
||||||
|
|
||||||
engine.procfile.entries.inject(1) do |index, process|
|
engine.procfile.entries.inject(1) do |index, process|
|
||||||
1.upto(concurrency[process.name]) do |num|
|
1.upto(self.concurrency[process.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, options[:port])
|
port = engine.port_for(process, num, self.port)
|
||||||
inittab << "#{id}:4:respawn:/bin/su - #{user} -c 'PORT=#{port} #{process.command} >> #{log_root}/#{process.name}-#{num}.log 2>&1'"
|
inittab << "#{id}:4:respawn:/bin/su - #{user} -c 'PORT=#{port} #{process.command} >> #{log_root}/#{process.name}-#{num}.log 2>&1'"
|
||||||
index += 1
|
index += 1
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,21 +4,19 @@ require "foreman/export"
|
|||||||
class Foreman::Export::Runit < Foreman::Export::Base
|
class Foreman::Export::Runit < Foreman::Export::Base
|
||||||
ENV_VARIABLE_REGEX = /([a-zA-Z_]+[a-zA-Z0-9_]*)=(\S+)/
|
ENV_VARIABLE_REGEX = /([a-zA-Z_]+[a-zA-Z0-9_]*)=(\S+)/
|
||||||
|
|
||||||
def export(location, options={})
|
def export
|
||||||
error("Must specify a location") unless location
|
error("Must specify a location") unless location
|
||||||
|
|
||||||
app = options[:app] || File.basename(engine.directory)
|
app = self.app || File.basename(engine.directory)
|
||||||
user = options[:user] || app
|
user = self.user || app
|
||||||
log_root = options[:log] || "/var/log/#{app}"
|
log_root = self.log || "/var/log/#{app}"
|
||||||
template_root = options[:template]
|
template_root = self.template
|
||||||
|
|
||||||
concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
|
|
||||||
|
|
||||||
run_template = export_template('runit', 'run.erb', template_root)
|
run_template = export_template('runit', 'run.erb', template_root)
|
||||||
log_run_template = export_template('runit', 'log_run.erb', template_root)
|
log_run_template = export_template('runit', 'log_run.erb', template_root)
|
||||||
|
|
||||||
engine.procfile.entries.each do |process|
|
engine.procfile.entries.each do |process|
|
||||||
1.upto(concurrency[process.name]) do |num|
|
1.upto(self.concurrency[process.name]) do |num|
|
||||||
process_directory = "#{location}/#{app}-#{process.name}-#{num}"
|
process_directory = "#{location}/#{app}-#{process.name}-#{num}"
|
||||||
process_env_directory = "#{process_directory}/env"
|
process_env_directory = "#{process_directory}/env"
|
||||||
process_log_directory = "#{process_directory}/log"
|
process_log_directory = "#{process_directory}/log"
|
||||||
@@ -31,7 +29,7 @@ class Foreman::Export::Runit < Foreman::Export::Base
|
|||||||
write_file "#{process_directory}/run", run
|
write_file "#{process_directory}/run", run
|
||||||
FileUtils.chmod 0755, "#{process_directory}/run"
|
FileUtils.chmod 0755, "#{process_directory}/run"
|
||||||
|
|
||||||
port = engine.port_for(process, num, options[:port])
|
port = engine.port_for(process, num, self.port)
|
||||||
environment_variables = {'PORT' => port}.
|
environment_variables = {'PORT' => port}.
|
||||||
merge(engine.environment).
|
merge(engine.environment).
|
||||||
merge(inline_variables(process.command))
|
merge(inline_variables(process.command))
|
||||||
@@ -51,7 +49,7 @@ class Foreman::Export::Runit < Foreman::Export::Base
|
|||||||
private
|
private
|
||||||
def create_directory(location)
|
def create_directory(location)
|
||||||
say "creating: #{location}"
|
say "creating: #{location}"
|
||||||
FileUtils.mkdir(location)
|
FileUtils.mkdir_p(location)
|
||||||
end
|
end
|
||||||
|
|
||||||
def inline_variables(command)
|
def inline_variables(command)
|
||||||
|
|||||||
@@ -3,23 +3,21 @@ require "foreman/export"
|
|||||||
|
|
||||||
class Foreman::Export::Upstart < Foreman::Export::Base
|
class Foreman::Export::Upstart < Foreman::Export::Base
|
||||||
|
|
||||||
def export(location, options={})
|
def export
|
||||||
error("Must specify a location") unless location
|
error("Must specify a location") unless location
|
||||||
|
|
||||||
FileUtils.mkdir_p location
|
FileUtils.mkdir_p location
|
||||||
|
|
||||||
app = options[:app] || File.basename(engine.directory)
|
app = self.app || File.basename(engine.directory)
|
||||||
user = options[:user] || app
|
user = self.user || app
|
||||||
log_root = options[:log] || "/var/log/#{app}"
|
log_root = self.log || "/var/log/#{app}"
|
||||||
template_root = options[:template]
|
template_root = self.template
|
||||||
|
|
||||||
Dir["#{location}/#{app}*.conf"].each do |file|
|
Dir["#{location}/#{app}*.conf"].each do |file|
|
||||||
say "cleaning up: #{file}"
|
say "cleaning up: #{file}"
|
||||||
FileUtils.rm(file)
|
FileUtils.rm(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
concurrency = Foreman::Utils.parse_concurrency(options[:concurrency])
|
|
||||||
|
|
||||||
master_template = export_template("upstart", "master.conf.erb", template_root)
|
master_template = export_template("upstart", "master.conf.erb", template_root)
|
||||||
master_config = ERB.new(master_template).result(binding)
|
master_config = ERB.new(master_template).result(binding)
|
||||||
write_file "#{location}/#{app}.conf", master_config
|
write_file "#{location}/#{app}.conf", master_config
|
||||||
@@ -27,13 +25,13 @@ class Foreman::Export::Upstart < Foreman::Export::Base
|
|||||||
process_template = export_template("upstart", "process.conf.erb", template_root)
|
process_template = export_template("upstart", "process.conf.erb", template_root)
|
||||||
|
|
||||||
engine.procfile.entries.each do |process|
|
engine.procfile.entries.each do |process|
|
||||||
next if (conc = concurrency[process.name]) < 1
|
next if (conc = self.concurrency[process.name]) < 1
|
||||||
process_master_template = export_template("upstart", "process_master.conf.erb", template_root)
|
process_master_template = export_template("upstart", "process_master.conf.erb", template_root)
|
||||||
process_master_config = ERB.new(process_master_template).result(binding)
|
process_master_config = ERB.new(process_master_template).result(binding)
|
||||||
write_file "#{location}/#{app}-#{process.name}.conf", process_master_config
|
write_file "#{location}/#{app}-#{process.name}.conf", process_master_config
|
||||||
|
|
||||||
1.upto(concurrency[process.name]) do |num|
|
1.upto(self.concurrency[process.name]) do |num|
|
||||||
port = engine.port_for(process, num, options[:port])
|
port = engine.port_for(process, num, self.port)
|
||||||
process_config = ERB.new(process_template).result(binding)
|
process_config = ERB.new(process_template).result(binding)
|
||||||
write_file "#{location}/#{app}-#{process.name}-#{num}.conf", process_config
|
write_file "#{location}/#{app}-#{process.name}-#{num}.conf", process_config
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
module Foreman::Helpers
|
||||||
|
# Copied whole sale from, https://github.com/defunkt/resque/
|
||||||
|
|
||||||
|
# Given a word with dashes, returns a camel cased version of it.
|
||||||
|
#
|
||||||
|
# classify('job-name') # => 'JobName'
|
||||||
|
def classify(dashed_word)
|
||||||
|
dashed_word.split('-').each { |part| part[0] = part[0].chr.upcase }.join
|
||||||
|
end
|
||||||
|
|
||||||
|
# Tries to find a constant with the name specified in the argument string:
|
||||||
|
#
|
||||||
|
# constantize("Module") # => Module
|
||||||
|
# constantize("Test::Unit") # => Test::Unit
|
||||||
|
#
|
||||||
|
# The name is assumed to be the one of a top-level constant, no matter
|
||||||
|
# whether it starts with "::" or not. No lexical context is taken into
|
||||||
|
# account:
|
||||||
|
#
|
||||||
|
# C = 'outside'
|
||||||
|
# module M
|
||||||
|
# C = 'inside'
|
||||||
|
# C # => 'inside'
|
||||||
|
# constantize("C") # => 'outside', same as ::C
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# NameError is raised when the constant is unknown.
|
||||||
|
def constantize(camel_cased_word)
|
||||||
|
camel_cased_word = camel_cased_word.to_s
|
||||||
|
|
||||||
|
if camel_cased_word.include?('-')
|
||||||
|
camel_cased_word = classify(camel_cased_word)
|
||||||
|
end
|
||||||
|
|
||||||
|
names = camel_cased_word.split('::')
|
||||||
|
names.shift if names.empty? || names.first.empty?
|
||||||
|
|
||||||
|
constant = Object
|
||||||
|
names.each do |name|
|
||||||
|
args = Module.method(:const_get).arity != 1 ? [false] : []
|
||||||
|
|
||||||
|
if constant.const_defined?(name, *args)
|
||||||
|
constant = constant.const_get(name)
|
||||||
|
else
|
||||||
|
constant = constant.const_missing(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
constant
|
||||||
|
end
|
||||||
|
end
|
||||||
+47
-19
@@ -1,4 +1,5 @@
|
|||||||
require "foreman"
|
require "foreman"
|
||||||
|
require "rubygems"
|
||||||
|
|
||||||
class Foreman::Process
|
class Foreman::Process
|
||||||
|
|
||||||
@@ -14,10 +15,8 @@ class Foreman::Process
|
|||||||
end
|
end
|
||||||
|
|
||||||
def run(pipe, basedir, environment)
|
def run(pipe, basedir, environment)
|
||||||
Dir.chdir(basedir) do
|
with_environment(environment.merge("PORT" => port.to_s)) do
|
||||||
with_environment(environment.merge("PORT" => port.to_s)) do
|
run_process basedir, entry.command, pipe
|
||||||
run_process entry.command, pipe
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -25,21 +24,52 @@ class Foreman::Process
|
|||||||
"%s.%s" % [ entry.name, num ]
|
"%s.%s" % [ entry.name, num ]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def kill(signal)
|
||||||
|
pid && Process.kill(signal, pid)
|
||||||
|
rescue Errno::ESRCH
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def detach
|
||||||
|
pid && Process.detach(pid)
|
||||||
|
end
|
||||||
|
|
||||||
|
def alive?
|
||||||
|
kill(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dead?
|
||||||
|
!alive?
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fork_with_io(command)
|
def fork_with_io(command, basedir)
|
||||||
reader, writer = IO.pipe
|
reader, writer = IO.pipe
|
||||||
pid = fork do
|
command = replace_command_env(command)
|
||||||
trap("INT", "IGNORE")
|
pid = if Foreman.windows?
|
||||||
$stdout.reopen writer
|
Dir.chdir(basedir) do
|
||||||
reader.close
|
Process.spawn command, :out => writer, :err => writer
|
||||||
exec Foreman.runner, replace_command_env(command)
|
end
|
||||||
|
elsif Foreman.jruby?
|
||||||
|
require "posix/spawn"
|
||||||
|
POSIX::Spawn.spawn(Foreman.runner, "-d", basedir, command, {
|
||||||
|
:out => writer, :err => writer
|
||||||
|
})
|
||||||
|
else
|
||||||
|
fork do
|
||||||
|
writer.sync = true
|
||||||
|
$stdout.reopen writer
|
||||||
|
$stderr.reopen writer
|
||||||
|
reader.close
|
||||||
|
exec Foreman.runner, "-d", basedir, command
|
||||||
|
end
|
||||||
end
|
end
|
||||||
[ reader, pid ]
|
[ reader, pid ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_process(command, pipe)
|
def run_process(basedir, command, pipe)
|
||||||
io, @pid = fork_with_io(command)
|
io, @pid = fork_with_io(command, basedir)
|
||||||
output pipe, "started with pid %d" % @pid
|
output pipe, "started with pid %d" % @pid
|
||||||
Thread.new do
|
Thread.new do
|
||||||
until io.eof?
|
until io.eof?
|
||||||
@@ -57,12 +87,10 @@ private
|
|||||||
end
|
end
|
||||||
|
|
||||||
def with_environment(environment)
|
def with_environment(environment)
|
||||||
old_env = ENV.each_pair.inject({}) { |h,(k,v)| h.update(k => v) }
|
original = ENV.to_hash
|
||||||
environment.each { |k,v| ENV[k] = v }
|
ENV.update environment
|
||||||
ret = yield
|
yield
|
||||||
ENV.clear
|
ensure
|
||||||
old_env.each { |k,v| ENV[k] = v}
|
ENV.replace original
|
||||||
ret
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
module Foreman
|
module Foreman
|
||||||
|
|
||||||
VERSION = "0.35.0"
|
VERSION = "0.37.0.pre4"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
+17
-13
@@ -1,7 +1,7 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
require "foreman/cli"
|
require "foreman/cli"
|
||||||
|
|
||||||
describe "Foreman::CLI" do
|
describe "Foreman::CLI", :fakefs do
|
||||||
subject { Foreman::CLI.new }
|
subject { Foreman::CLI.new }
|
||||||
|
|
||||||
describe "start" do
|
describe "start" do
|
||||||
@@ -30,7 +30,9 @@ describe "Foreman::CLI" do
|
|||||||
it "respects --env" do
|
it "respects --env" do
|
||||||
write_procfile
|
write_procfile
|
||||||
write_env("envfile")
|
write_env("envfile")
|
||||||
mock.instance_of(Foreman::Export::Upstart).export("/upstart", { "env" => "envfile" })
|
mock_export = mock(Foreman::Export::Upstart)
|
||||||
|
mock(Foreman::Export::Upstart).new("/upstart", is_a(Foreman::Engine), { "env" => "envfile" }) { mock_export }
|
||||||
|
mock_export.export
|
||||||
foreman %{ export upstart /upstart --env envfile }
|
foreman %{ export upstart /upstart --env envfile }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -49,7 +51,7 @@ describe "Foreman::CLI" do
|
|||||||
|
|
||||||
describe "with an invalid formatter" do
|
describe "with an invalid formatter" do
|
||||||
it "prints an error" do
|
it "prints an error" do
|
||||||
mock_error(subject, "Unknown export format: invalidformatter.") do
|
mock_error(subject, "Unknown export format: invalidformatter (unable to load file 'foreman/export/invalidformatter').") do
|
||||||
subject.export("invalidformatter")
|
subject.export("invalidformatter")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -60,7 +62,9 @@ describe "Foreman::CLI" do
|
|||||||
|
|
||||||
it "runs successfully" do
|
it "runs successfully" do
|
||||||
dont_allow(subject).error
|
dont_allow(subject).error
|
||||||
mock.instance_of(Foreman::Export::Upstart).export("/tmp/foo", {})
|
mock_export = mock(Foreman::Export::Upstart)
|
||||||
|
mock(Foreman::Export::Upstart).new("/tmp/foo", is_a(Foreman::Engine), {}) { mock_export }
|
||||||
|
mock_export.export
|
||||||
subject.export("upstart", "/tmp/foo")
|
subject.export("upstart", "/tmp/foo")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -89,47 +93,47 @@ describe "Foreman::CLI" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "run" do
|
describe "run" do
|
||||||
describe "with a valid Procfile" do
|
describe "with a valid Procfile" do
|
||||||
before { write_procfile }
|
before { write_procfile }
|
||||||
|
|
||||||
describe "and a command" do
|
describe "and a command" do
|
||||||
let(:command) { ["ls", "-l"] }
|
let(:command) { ["ls", "-l"] }
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
stub(subject).exec
|
stub(subject).exec
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should load the environment file" do
|
it "should load the environment file" do
|
||||||
write_env
|
write_env
|
||||||
preserving_env do
|
preserving_env do
|
||||||
subject.run *command
|
subject.run *command
|
||||||
ENV["FOO"].should == "bar"
|
ENV["FOO"].should == "bar"
|
||||||
end
|
end
|
||||||
|
|
||||||
ENV["FOO"].should be_nil
|
ENV["FOO"].should be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should runute the command as a string" do
|
it "should runute the command as a string" do
|
||||||
mock(subject).exec(command.join(" "))
|
mock(subject).exec(command.join(" "))
|
||||||
subject.run *command
|
subject.run *command
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "and a non-existent command" do
|
describe "and a non-existent command" do
|
||||||
let(:command) { "iuhtngrglhulhdfg" }
|
let(:command) { "iuhtngrglhulhdfg" }
|
||||||
|
|
||||||
it "should print an error" do
|
it "should print an error" do
|
||||||
mock_error(subject, "command not found: #{command}") do
|
mock_error(subject, "command not found: #{command}") do
|
||||||
subject.run command
|
subject.run command
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "and a non-executable command" do
|
describe "and a non-executable command" do
|
||||||
let(:command) { __FILE__ }
|
let(:command) { __FILE__ }
|
||||||
|
|
||||||
it "should print an error" do
|
it "should print an error" do
|
||||||
mock_error(subject, "not executable: #{command}") do
|
mock_error(subject, "not executable: #{command}") do
|
||||||
subject.run command
|
subject.run command
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
require "foreman/engine"
|
require "foreman/engine"
|
||||||
|
|
||||||
describe "Foreman::Engine" do
|
describe "Foreman::Engine", :fakefs do
|
||||||
subject { Foreman::Engine.new("Procfile", {}) }
|
subject { Foreman::Engine.new("Procfile", {}) }
|
||||||
|
|
||||||
describe "initialize" do
|
describe "initialize" do
|
||||||
@@ -24,8 +24,8 @@ describe "Foreman::Engine" do
|
|||||||
describe "start" do
|
describe "start" do
|
||||||
it "forks the processes" do
|
it "forks the processes" do
|
||||||
write_procfile
|
write_procfile
|
||||||
mock.instance_of(Foreman::Process).run_process("./alpha", is_a(IO))
|
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./alpha", is_a(IO))
|
||||||
mock.instance_of(Foreman::Process).run_process("./bravo", is_a(IO))
|
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./bravo", is_a(IO))
|
||||||
mock(subject).watch_for_output
|
mock(subject).watch_for_output
|
||||||
mock(subject).watch_for_termination
|
mock(subject).watch_for_termination
|
||||||
subject.start
|
subject.start
|
||||||
@@ -34,8 +34,8 @@ describe "Foreman::Engine" do
|
|||||||
it "handles concurrency" do
|
it "handles concurrency" do
|
||||||
write_procfile
|
write_procfile
|
||||||
engine = Foreman::Engine.new("Procfile",:concurrency => "alpha=2")
|
engine = Foreman::Engine.new("Procfile",:concurrency => "alpha=2")
|
||||||
mock.instance_of(Foreman::Process).run_process("./alpha", is_a(IO)).twice
|
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./alpha", is_a(IO)).twice
|
||||||
mock.instance_of(Foreman::Process).run_process("./bravo", is_a(IO)).never
|
mock.instance_of(Foreman::Process).run_process(Dir.pwd, "./bravo", is_a(IO)).never
|
||||||
mock(engine).watch_for_output
|
mock(engine).watch_for_output
|
||||||
mock(engine).watch_for_termination
|
mock(engine).watch_for_termination
|
||||||
engine.start
|
engine.start
|
||||||
|
|||||||
@@ -3,22 +3,27 @@ require "foreman/engine"
|
|||||||
require "foreman/export/bluepill"
|
require "foreman/export/bluepill"
|
||||||
require "tmpdir"
|
require "tmpdir"
|
||||||
|
|
||||||
describe Foreman::Export::Bluepill do
|
describe Foreman::Export::Bluepill, :fakefs do
|
||||||
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
||||||
let(:engine) { Foreman::Engine.new(procfile) }
|
let(:engine) { Foreman::Engine.new(procfile) }
|
||||||
let(:bluepill) { Foreman::Export::Bluepill.new(engine) }
|
let(:options) { Hash.new }
|
||||||
|
let(:bluepill) { Foreman::Export::Bluepill.new("/tmp/init", engine, options) }
|
||||||
|
|
||||||
before(:each) { load_export_templates_into_fakefs("bluepill") }
|
before(:each) { load_export_templates_into_fakefs("bluepill") }
|
||||||
before(:each) { stub(bluepill).say }
|
before(:each) { stub(bluepill).say }
|
||||||
|
|
||||||
it "exports to the filesystem" do
|
it "exports to the filesystem" do
|
||||||
bluepill.export("/tmp/init")
|
bluepill.export
|
||||||
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app.pill"))
|
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app.pill"))
|
||||||
end
|
end
|
||||||
|
|
||||||
it "exports to the filesystem with concurrency" do
|
context "with concurrency" do
|
||||||
bluepill.export("/tmp/init", :concurrency => "alpha=2")
|
let(:options) { Hash[:concurrency => "alpha=2"] }
|
||||||
|
|
||||||
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app-concurrency.pill"))
|
it "exports to the filesystem with concurrency" do
|
||||||
|
bluepill.export
|
||||||
|
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app-concurrency.pill"))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
end
|
||||||
|
|||||||
@@ -3,34 +3,39 @@ require "foreman/engine"
|
|||||||
require "foreman/export/runit"
|
require "foreman/export/runit"
|
||||||
require "tmpdir"
|
require "tmpdir"
|
||||||
|
|
||||||
describe Foreman::Export::Runit do
|
describe Foreman::Export::Runit, :fakefs do
|
||||||
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", 'bar=baz') }
|
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", 'bar=baz') }
|
||||||
let(:engine) { Foreman::Engine.new(procfile) }
|
let(:engine) { Foreman::Engine.new(procfile) }
|
||||||
let(:runit) { Foreman::Export::Runit.new(engine) }
|
let(:runit) { Foreman::Export::Runit.new('/tmp/init', engine, :concurrency => 'alpha=2,bravo=1') }
|
||||||
|
|
||||||
before(:each) { load_export_templates_into_fakefs("runit") }
|
before(:each) { load_export_templates_into_fakefs("runit") }
|
||||||
before(:each) { stub(runit).say }
|
before(:each) { stub(runit).say }
|
||||||
before(:each) { stub(FakeFS::FileUtils).chmod }
|
before(:each) { stub(FakeFS::FileUtils).chmod }
|
||||||
|
|
||||||
it "exports to the filesystem" do
|
it "exports to the filesystem" do
|
||||||
FileUtils.mkdir_p('/tmp/init')
|
FileUtils.mkdir_p('/tmp/init')
|
||||||
runit.export('/tmp/init', :concurrency => "alpha=2,bravo=1")
|
|
||||||
|
runit.export
|
||||||
|
|
||||||
File.read("/tmp/init/app-alpha-1/run").should == example_export_file('runit/app-alpha-1-run')
|
File.read("/tmp/init/app-alpha-1/run").should == example_export_file('runit/app-alpha-1-run')
|
||||||
File.read("/tmp/init/app-alpha-1/log/run").should ==
|
File.read("/tmp/init/app-alpha-1/log/run").should ==
|
||||||
example_export_file('runit/app-alpha-1-log-run')
|
example_export_file('runit/app-alpha-1-log-run')
|
||||||
File.read("/tmp/init/app-alpha-1/env/PORT").should == "5000\n"
|
File.read("/tmp/init/app-alpha-1/env/PORT").should == "5000\n"
|
||||||
File.read("/tmp/init/app-alpha-1/env/BAR").should == "baz\n"
|
File.read("/tmp/init/app-alpha-1/env/BAR").should == "baz\n"
|
||||||
|
|
||||||
File.read("/tmp/init/app-alpha-2/run").should == example_export_file('runit/app-alpha-2-run')
|
File.read("/tmp/init/app-alpha-2/run").should == example_export_file('runit/app-alpha-2-run')
|
||||||
File.read("/tmp/init/app-alpha-2/log/run").should ==
|
File.read("/tmp/init/app-alpha-2/log/run").should ==
|
||||||
example_export_file('runit/app-alpha-2-log-run')
|
example_export_file('runit/app-alpha-2-log-run')
|
||||||
File.read("/tmp/init/app-alpha-2/env/PORT").should == "5001\n"
|
File.read("/tmp/init/app-alpha-2/env/PORT").should == "5001\n"
|
||||||
File.read("/tmp/init/app-alpha-2/env/BAR").should == "baz\n"
|
File.read("/tmp/init/app-alpha-2/env/BAR").should == "baz\n"
|
||||||
|
|
||||||
File.read("/tmp/init/app-bravo-1/run").should == example_export_file('runit/app-bravo-1-run')
|
File.read("/tmp/init/app-bravo-1/run").should == example_export_file('runit/app-bravo-1-run')
|
||||||
File.read("/tmp/init/app-bravo-1/log/run").should ==
|
File.read("/tmp/init/app-bravo-1/log/run").should ==
|
||||||
example_export_file('runit/app-bravo-1-log-run')
|
example_export_file('runit/app-bravo-1-log-run')
|
||||||
File.read("/tmp/init/app-bravo-1/env/PORT").should == "5100\n"
|
File.read("/tmp/init/app-bravo-1/env/PORT").should == "5100\n"
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
it "creates a full path to the export directory" do
|
||||||
|
expect { runit.export }.to_not raise_error(Errno::ENOENT)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -3,16 +3,17 @@ require "foreman/engine"
|
|||||||
require "foreman/export/upstart"
|
require "foreman/export/upstart"
|
||||||
require "tmpdir"
|
require "tmpdir"
|
||||||
|
|
||||||
describe Foreman::Export::Upstart do
|
describe Foreman::Export::Upstart, :fakefs do
|
||||||
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
||||||
let(:engine) { Foreman::Engine.new(procfile) }
|
let(:engine) { Foreman::Engine.new(procfile) }
|
||||||
let(:upstart) { Foreman::Export::Upstart.new(engine) }
|
let(:options) { Hash.new }
|
||||||
|
let(:upstart) { Foreman::Export::Upstart.new("/tmp/init", engine, options) }
|
||||||
|
|
||||||
before(:each) { load_export_templates_into_fakefs("upstart") }
|
before(:each) { load_export_templates_into_fakefs("upstart") }
|
||||||
before(:each) { stub(upstart).say }
|
before(:each) { stub(upstart).say }
|
||||||
|
|
||||||
it "exports to the filesystem" do
|
it "exports to the filesystem" do
|
||||||
upstart.export("/tmp/init")
|
upstart.export
|
||||||
|
|
||||||
File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
|
File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
|
||||||
File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
|
File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
|
||||||
@@ -21,18 +22,23 @@ describe Foreman::Export::Upstart do
|
|||||||
File.read("/tmp/init/app-bravo-1.conf").should == example_export_file("upstart/app-bravo-1.conf")
|
File.read("/tmp/init/app-bravo-1.conf").should == example_export_file("upstart/app-bravo-1.conf")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "exports to the filesystem with concurrency" do
|
context "with concurrency" do
|
||||||
upstart.export("/tmp/init", :concurrency => "alpha=2")
|
let(:options) { Hash[:concurrency => "alpha=2"] }
|
||||||
|
|
||||||
File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
|
it "exports to the filesystem with concurrency" do
|
||||||
File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
|
upstart.export
|
||||||
File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
|
|
||||||
File.read("/tmp/init/app-alpha-2.conf").should == example_export_file("upstart/app-alpha-2.conf")
|
File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
|
||||||
File.exists?("/tmp/init/app-bravo-1.conf").should == false
|
File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
|
||||||
|
File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
|
||||||
|
File.read("/tmp/init/app-alpha-2.conf").should == example_export_file("upstart/app-alpha-2.conf")
|
||||||
|
File.exists?("/tmp/init/app-bravo-1.conf").should == false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with alternate templates" do
|
context "with alternate templates" do
|
||||||
let(:template_root) { "/tmp/alternate" }
|
let(:template_root) { "/tmp/alternate" }
|
||||||
|
let(:upstart) { Foreman::Export::Upstart.new("/tmp/init", engine, :template => template_root) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
FileUtils.mkdir_p template_root
|
FileUtils.mkdir_p template_root
|
||||||
@@ -40,7 +46,7 @@ describe Foreman::Export::Upstart do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "can export with alternate template files" do
|
it "can export with alternate template files" do
|
||||||
upstart.export("/tmp/init", :template => template_root)
|
upstart.export
|
||||||
|
|
||||||
File.read("/tmp/init/app.conf").should == "alternate_template\n"
|
File.read("/tmp/init/app.conf").should == "alternate_template\n"
|
||||||
end
|
end
|
||||||
@@ -61,7 +67,7 @@ describe Foreman::Export::Upstart do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "can export with alternate template files" do
|
it "can export with alternate template files" do
|
||||||
upstart.export("/tmp/init")
|
upstart.export
|
||||||
|
|
||||||
File.read("/tmp/init/app.conf").should == "default_alternate_template\n"
|
File.read("/tmp/init/app.conf").should == "default_alternate_template\n"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,2 +1,131 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
require "foreman/process"
|
require 'foreman/process'
|
||||||
|
require 'ostruct'
|
||||||
|
require 'timeout'
|
||||||
|
require 'tmpdir'
|
||||||
|
|
||||||
|
describe Foreman::Process do
|
||||||
|
subject { described_class.new entry, number, port }
|
||||||
|
|
||||||
|
let(:number) { 1 }
|
||||||
|
let(:port) { 777 }
|
||||||
|
let(:command) { "script" }
|
||||||
|
let(:name) { "foobar" }
|
||||||
|
let(:entry) { OpenStruct.new :name => name, :command => command }
|
||||||
|
|
||||||
|
its(:entry) { entry }
|
||||||
|
its(:num) { number }
|
||||||
|
its(:port) { port }
|
||||||
|
its(:name) { "#{name}.#{port}" }
|
||||||
|
its(:pid) { nil }
|
||||||
|
|
||||||
|
describe '#run' do
|
||||||
|
let(:pipe) { :pipe }
|
||||||
|
let(:basedir) { Dir.mktmpdir }
|
||||||
|
let(:env) {{ 'foo' => 'bar' }}
|
||||||
|
let(:init_delta) { 0.1 }
|
||||||
|
|
||||||
|
after { FileUtils.remove_entry_secure basedir }
|
||||||
|
|
||||||
|
def run(cmd=command)
|
||||||
|
entry.command = cmd
|
||||||
|
subject.run pipe, basedir, env
|
||||||
|
subject.detach && sleep(init_delta)
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_file(executable, code)
|
||||||
|
file = File.open("#{basedir}/script", 'w') {|it| it << code }
|
||||||
|
run "#{executable} #{file.path}"
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'options' do
|
||||||
|
it 'should set PORT for environment' do
|
||||||
|
mock(subject).run_process(basedir, command, pipe) do
|
||||||
|
ENV['PORT'].should == port.to_s
|
||||||
|
end
|
||||||
|
run
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should set custom variables for environment' do
|
||||||
|
mock(subject).run_process(basedir, command, pipe) do
|
||||||
|
ENV['foo'].should == 'bar'
|
||||||
|
end
|
||||||
|
run
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should restore environment afterwards' do
|
||||||
|
mock(subject).run_process(basedir, command, pipe)
|
||||||
|
run
|
||||||
|
ENV.should_not include('PORT', 'foo')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'process' do
|
||||||
|
around do |spec|
|
||||||
|
IO.pipe do |reader, writer|
|
||||||
|
@reader, @writer = reader, writer
|
||||||
|
spec.run
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:pipe) { @writer }
|
||||||
|
let(:output) { @reader.read_nonblock 1024 }
|
||||||
|
|
||||||
|
it 'should not block' do
|
||||||
|
expect {
|
||||||
|
Timeout.timeout(2*init_delta) { run 'sleep 2' }
|
||||||
|
}.should_not raise_exception
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should be alive' do
|
||||||
|
run 'sleep 1'
|
||||||
|
subject.should be_alive
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should be dead' do
|
||||||
|
run 'exit'
|
||||||
|
subject.should be_dead
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should be killable' do
|
||||||
|
run 'sleep 1'
|
||||||
|
subject.kill 'TERM'
|
||||||
|
subject.should be_dead
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should send different signals' do
|
||||||
|
run_file 'ruby', <<-CODE
|
||||||
|
trap "TERM", "IGNORE"
|
||||||
|
loop { sleep 1 }
|
||||||
|
CODE
|
||||||
|
sleep 1 # wait for ruby to start
|
||||||
|
subject.should be_alive
|
||||||
|
subject.kill 'TERM'
|
||||||
|
subject.should be_alive
|
||||||
|
subject.kill 'KILL'
|
||||||
|
subject.should be_dead
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should redirect stdout' do
|
||||||
|
run 'echo hey'
|
||||||
|
output.should include('hey')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should redirect stderr' do
|
||||||
|
run 'echo hey >2'
|
||||||
|
output.should include('hey')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should handle variables' do
|
||||||
|
run 'echo $PORT'
|
||||||
|
output.should include('777')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should handle arguments' do
|
||||||
|
pending
|
||||||
|
run %{ sh -c "trap '' TERM; sleep 10" }
|
||||||
|
subject.should be_alive
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -8,13 +8,8 @@ describe Foreman do
|
|||||||
it { should be_a String }
|
it { should be_a String }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "::load_env!(env_file)" do
|
describe "::load_env!(env_file)", :fakefs do
|
||||||
before do
|
|
||||||
FakeFS.activate!
|
|
||||||
end
|
|
||||||
|
|
||||||
after do
|
after do
|
||||||
FakeFS.deactivate!
|
|
||||||
ENV['FOO'] = nil
|
ENV['FOO'] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -22,7 +17,7 @@ describe Foreman do
|
|||||||
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
|
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
|
||||||
Foreman.load_env!("/tmp/env1")
|
Foreman.load_env!("/tmp/env1")
|
||||||
ENV['FOO'].should == 'bar'
|
ENV['FOO'].should == 'bar'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should assume env_file in ./.env" do
|
it "should assume env_file in ./.env" do
|
||||||
File.open("./.env", "w") { |f| f.puts("FOO=bar") }
|
File.open("./.env", "w") { |f| f.puts("FOO=bar") }
|
||||||
|
|||||||
+3
-3
@@ -3,16 +3,16 @@ require "spec_helper"
|
|||||||
describe "spec helpers" do
|
describe "spec helpers" do
|
||||||
describe "#preserving_env" do
|
describe "#preserving_env" do
|
||||||
after { ENV.delete "FOO" }
|
after { ENV.delete "FOO" }
|
||||||
|
|
||||||
it "should remove added environment vars" do
|
it "should remove added environment vars" do
|
||||||
preserving_env { ENV["FOO"] = "baz" }
|
preserving_env { ENV["FOO"] = "baz" }
|
||||||
ENV["FOO"].should == nil
|
ENV["FOO"].should == nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should reset modified environment vars" do
|
it "should reset modified environment vars" do
|
||||||
ENV["FOO"] = "bar"
|
ENV["FOO"] = "bar"
|
||||||
preserving_env { ENV["FOO"] = "baz"}
|
preserving_env { ENV["FOO"] = "baz"}
|
||||||
ENV["FOO"].should == "bar"
|
ENV["FOO"].should == "bar"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+3
-2
@@ -76,10 +76,11 @@ end
|
|||||||
def normalize_space(s)
|
def normalize_space(s)
|
||||||
s.gsub(/\n[\n\s]*/, "\n")
|
s.gsub(/\n[\n\s]*/, "\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
||||||
config.color_enabled = true
|
config.color_enabled = true
|
||||||
config.order = 'rand'
|
config.order = 'rand'
|
||||||
config.include FakeFS::SpecHelpers
|
config.include FakeFS::SpecHelpers, :fakefs
|
||||||
config.mock_with :rr
|
config.mock_with :rr
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user