Compare commits

...
37 Commits
Author SHA1 Message Date
David Dollar 5689d75a87 0.44.0 2012-04-23 15:55:56 -04:00
David Dollar 1325b6750e make var output order repeatable 2012-04-23 15:53:59 -04:00
David Dollar 638005403f clean up file/directory interaction, add some tests 2012-04-23 15:50:23 -04:00
David Dollar 55f274532f Merge pull request #183 from technomancy/app_root
Look for .env and app_root in the same dir as the Procfile.
2012-04-23 12:20:10 -07:00
Phil Hagelberg 66f76c2036 Look for .env and app_root in the same dir as the Procfile. 2012-04-20 20:59:37 -07:00
David Dollar 865cabb525 update docs 2012-04-20 19:33:14 -04:00
David Dollar 7c3c4bc58f add more options to the start docs 2012-04-20 19:33:11 -04:00
David Dollar 2dbe8c733b update docs 2012-04-20 17:42:47 -04:00
David Dollar 84352b82cc changelog 2012-04-20 17:42:33 -04:00
David Dollar 383c1f87af 0.43.0 2012-04-20 17:41:08 -04:00
David Dollar ce3003b026 factor out wrap_environment 2012-04-20 17:40:53 -04:00
David Dollar e06f4b2f9e Merge pull request #182 from leahpar/master
Supervisord Export fix for environments containing commas
2012-04-20 14:36:26 -07:00
Raphael Randschau b721fd894e per default wrap every environment value in quotes 2012-04-20 21:15:43 +02:00
Raphael Randschau b8ea6fd4b3 fix typo in spec description 2012-04-20 09:14:12 +02:00
Raphael Randschau dbda63263b fix supervisord export for environments containing commas 2012-04-20 09:11:25 +02:00
David Dollar 93cdc31be0 update docs 2012-04-18 13:04:45 -04:00
David Dollar 4dfbe46690 update changelog 2012-04-18 13:03:58 -04:00
David Dollar 0033f9caeb 0.42.0 2012-04-18 13:02:51 -04:00
David Dollar 74839800a9 Merge pull request #181 from technomancy/master
Public read_environment
2012-04-18 10:01:38 -07:00
Phil Hagelberg b75337e21e Move read_environment to a public class method. 2012-04-18 09:56:17 -07:00
David Dollar d94f941189 update gemfile.lock 2012-04-18 12:49:33 -04:00
David Dollar 0b34f067cb Revert "Merge pull request #176 from rtyler/feature/156-foreman-stop-command"
Rewriting using a better Process API

This reverts commit dbe51832b0, reversing
changes made to 69216b4c5e.
2012-04-18 12:48:51 -04:00
David Dollar dbe51832b0 Merge pull request #176 from rtyler/feature/156-foreman-stop-command
Adding #stop method to Foreman::Engine
2012-04-11 10:29:54 -07:00
R. Tyler Croy 3a2a53be95 Remove ALL_PROCESSES and default the name arguments to #start/#stop to nil 2012-04-11 10:25:58 -07:00
R. Tyler Croy b2bf95479e Refactor #stop to reference ALL_PROCESSES for a bit clearer readability 2012-04-10 20:35:59 -07:00
R. Tyler Croy 48f764e347 Refactor #spawn_processes into #start(name)
When passed nil (aka ALL_PROCESSES) #start will start all processes in the
Procfile as per existing behavior
2012-04-10 20:35:59 -07:00
R. Tyler Croy de62d0655e Re-name the main Foreman::Engine method to #run to avoid a name collision with #start(name) 2012-04-10 20:35:59 -07:00
R. Tyler Croy 38aecff886 When executing #stop(nil), all processes should be sent the signal 2012-04-10 20:35:58 -07:00
R. Tyler Croy e4a3215257 Re-implement #terminate_gracefully with #stop(name) 2012-04-10 20:19:23 -07:00
R. Tyler Croy c705b5fbef Add #stop method on Foreman::Engine for stopping certain named processes
This will make embedding foreman "nicer" since the embedder can then stop
a specific process (e.g. turning off a service for an integration fail-over test)
2012-04-10 20:10:51 -07:00
David Dollar 69216b4c5e Merge pull request #171 from technomancy/0.41.0-deparkaed
Drop parka dependency to make things easier on the build slaves.
2012-03-26 15:05:35 -07:00
Phil Hagelberg 5d2930745a Drop parka dependency to make things easier on the build slaves. 2012-03-26 15:01:04 -07:00
David Dollar 8fc3d1ef24 Merge pull request #161 from leahpar/master
Supervisord Support (Update & Bugfix)
2012-03-16 18:47:15 -07:00
David Dollar d33e4fb0ed update changelog 2012-03-16 16:36:16 -04:00
Raphael Randschau 1217ef1b56 fix typo 2012-03-05 15:51:10 +01:00
Raphael Randschau c9943d70ec add group support for supervisord 2012-03-05 15:48:40 +01:00
Raphael Randschau 08dca57eb4 fix enviroment export 2012-02-25 17:24:27 +01:00
16 changed files with 168 additions and 43 deletions
+16
View File
@@ -1,3 +1,19 @@
## 0.43.0 (2012-04-20)
* wrap supervisord env vars in quotes [Raphael Randschau]
## 0.42.0 (2012-04-18)
* Move read_environment to a public class method. [Phil Hagelberg]
* Drop parka dependency [Phil Hagelberg]
* add group support for supervisord [Raphael Randschau]
* fix enviroment export [Raphael Randschau]
## 0.41.0 (2012-03-16)
* replace term-ansicolor with built-in colorization [David Dollar]
* supervisord export template [Raphael Randschau]
## 0.40.0 (2012-02-24) ## 0.40.0 (2012-02-24)
* support various quoting styles in .env [David Dollar] * support various quoting styles in .env [David Dollar]
-1
View File
@@ -12,7 +12,6 @@ end
group :development do group :development do
gem 'aws-s3' gem 'aws-s3'
gem 'parka'
gem 'rake' gem 'rake'
gem 'ronn' gem 'ronn'
gem 'fakefs', '~> 0.3.2' gem 'fakefs', '~> 0.3.2'
+1 -9
View File
@@ -1,7 +1,7 @@
PATH PATH
remote: . remote: .
specs: specs:
foreman (0.41.0) foreman (0.44.0)
thor (>= 0.13.6) thor (>= 0.13.6)
GEM GEM
@@ -12,7 +12,6 @@ GEM
mime-types mime-types
xml-simple xml-simple
builder (3.0.0) builder (3.0.0)
crack (0.1.8)
diff-lcs (1.1.3) diff-lcs (1.1.3)
fakefs (0.3.2) fakefs (0.3.2)
hpricot (0.8.6) hpricot (0.8.6)
@@ -20,15 +19,9 @@ GEM
mime-types (1.16) mime-types (1.16)
multi_json (1.0.4) multi_json (1.0.4)
mustache (0.11.2) mustache (0.11.2)
parka (0.6.2)
crack
rest-client
thor
posix-spawn (0.3.6) posix-spawn (0.3.6)
rake (0.9.2.2) rake (0.9.2.2)
rdiscount (1.6.5) rdiscount (1.6.5)
rest-client (1.6.1)
mime-types (>= 1.16)
ronn (0.7.3) ronn (0.7.3)
hpricot (>= 0.8.2) hpricot (>= 0.8.2)
mustache (>= 0.7.0) mustache (>= 0.7.0)
@@ -59,7 +52,6 @@ DEPENDENCIES
aws-s3 aws-s3
fakefs (~> 0.3.2) fakefs (~> 0.3.2)
foreman! foreman!
parka
posix-spawn (~> 0.3.6) posix-spawn (~> 0.3.6)
rake rake
ronn ronn
+8 -2
View File
@@ -1,12 +1,15 @@
<% <%
app_names = []
engine.procfile.entries.each do |process| engine.procfile.entries.each do |process|
next if (conc = self.concurrency[process.name]) < 1 next if (conc = self.concurrency[process.name]) < 1
1.upto(self.concurrency[process.name]) do |num| 1.upto(self.concurrency[process.name]) do |num|
port = engine.port_for(process, num, self.port) port = engine.port_for(process, num, self.port)
name = if (conc > 1); "#{process.name}-#{num}" else process.name; end name = if (conc > 1); "#{process.name}-#{num}" else process.name; end
environment = (engine.environment.each_pair { |var,env| "#{var.upcase}=#{env}" }.to_a << "PORT=#{port}") environment = (engine.environment.keys.sort.map{ |var| %{#{var.upcase}="#{engine.environment[var]}"} } + [%{PORT="#{port}"}])
app_name = "#{app}-#{name}"
app_names << app_name
%> %>
[program:<%= app %>-<%= name %>] [program:<%= app_name %>]
command=<%= process.command %> command=<%= process.command %>
autostart=true autostart=true
autorestart=true autorestart=true
@@ -19,3 +22,6 @@ environment=<%= environment.join(',') %><%
end end
end end
%> %>
[group:<%= app %>]
programs=<%= app_names.join(',') %>
+5 -1
View File
@@ -83,7 +83,11 @@ private ######################################################################
end end
def procfile def procfile
options[:procfile] || "Procfile" case
when options[:procfile] then options[:procfile]
when options[:app_root] then File.expand_path(File.join(options[:app_root], "Procfile"))
else "Procfile"
end
end end
def error(message) def error(message)
+24 -17
View File
@@ -24,8 +24,10 @@ class Foreman::Engine
@procfile = Foreman::Procfile.new(procfile) @procfile = Foreman::Procfile.new(procfile)
@directory = options[:app_root] || File.expand_path(File.dirname(procfile)) @directory = options[:app_root] || File.expand_path(File.dirname(procfile))
@options = options.dup @options = options.dup
@environment = read_environment_files(options[:env])
@output_mutex = Mutex.new @output_mutex = Mutex.new
@options[:env] ||= default_env
@environment = read_environment_files(@options[:env])
end end
def start def start
@@ -51,6 +53,22 @@ class Foreman::Engine
environment.each { |k,v| ENV[k] = v } environment.each { |k,v| ENV[k] = v }
end end
def self.read_environment(filename)
return {} unless File.exists?(filename)
File.read(filename).split("\n").inject({}) do |hash, line|
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
key, val = [$1, $2]
case val
when /\A'(.*)'\z/ then hash[key] = $1
when /\A"(.*)"\z/ then hash[key] = $1.gsub(/\\(.)/, '\1')
else hash[key] = val
end
end
hash
end
end
private ###################################################################### private ######################################################################
def spawn_processes def spawn_processes
@@ -195,26 +213,15 @@ private ######################################################################
(filenames || "").split(",").map(&:strip).each do |filename| (filenames || "").split(",").map(&:strip).each do |filename|
error "No such file: #{filename}" unless File.exists?(filename) error "No such file: #{filename}" unless File.exists?(filename)
environment.merge!(read_environment(filename)) environment.merge!(Foreman::Engine.read_environment(filename))
end end
environment.merge!(read_environment(".env")) unless filenames
environment environment
end end
def read_environment(filename) def default_env
return {} unless File.exists?(filename) env = File.join(directory, ".env")
File.exists?(env) ? env : ""
File.read(filename).split("\n").inject({}) do |hash, line|
if line =~ /\A([A-Za-z_0-9]+)=(.*)\z/
key, val = [$1, $2]
case val
when /\A'(.*)'\z/ then hash[key] = $1
when /\A"(.*)"\z/ then hash[key] = $1.gsub(/\\(.)/, '\1')
else hash[key] = val
end
end
hash
end
end end
end end
+1 -1
View File
@@ -1,5 +1,5 @@
module Foreman module Foreman
VERSION = "0.41.0" VERSION = "0.44.0"
end end
+9 -1
View File
@@ -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" "February 2012" "Foreman 0.39.0" "Foreman Manual" .TH "FOREMAN" "1" "April 2012" "Foreman 0.43.0" "Foreman Manual"
. .
.SH "NAME" .SH "NAME"
\fBforeman\fR \- manage Procfile\-based applications \fBforeman\fR \- manage Procfile\-based applications
@@ -35,6 +35,14 @@ The following options control how the application is run:
Specify the number of each process type to run\. The value passed in should be in the format \fBprocess=num,process=num\fR Specify the number of each process type to run\. The value passed in should be in the format \fBprocess=num,process=num\fR
. .
.TP .TP
\fB\-e\fR, \fB\-\-env\fR
Specify one or more \.env files to load
.
.TP
\fB\-f\fR, \fB\-\-procfile\fR
Specify an alternate Procfile to load, implies \fB\-d\fR at the Procfile root\.
.
.TP
\fB\-p\fR, \fB\-\-port\fR \fB\-p\fR, \fB\-\-port\fR
Specify which port to use as the base for this application\. Should be a multiple of 1000\. Specify which port to use as the base for this application\. Should be a multiple of 1000\.
. .
+6
View File
@@ -30,6 +30,12 @@ The following options control how the application is run:
Specify the number of each process type to run. The value passed in Specify the number of each process type to run. The value passed in
should be in the format `process=num,process=num` should be in the format `process=num,process=num`
* `-e`, `--env`:
Specify one or more .env files to load
* `-f`, `--procfile`:
Specify an alternate Procfile to load, implies `-d` at the Procfile root.
* `-p`, `--port`: * `-p`, `--port`:
Specify which port to use as the base for this application. Should be Specify which port to use as the base for this application. Should be
a multiple of 1000. a multiple of 1000.
+9
View File
@@ -34,6 +34,15 @@ describe "Foreman::CLI", :fakefs do
subject.start("alpha") subject.start("alpha")
end end
end end
describe "with an alternate root" do
it "reads the Procfile from that root" do
write_procfile "/some/app/Procfile"
mock(Foreman::Procfile).new("/some/app/Procfile")
mock.instance_of(Foreman::Engine).start
foreman %{ start -d /some/app }
end
end
end end
describe "export" do describe "export" do
+17
View File
@@ -49,6 +49,14 @@ describe "Foreman::Engine", :fakefs do
end end
end end
describe "directories" do
it "has the directory default relative to the Procfile" do
write_procfile "/some/app/Procfile"
engine = Foreman::Engine.new("/some/app/Procfile")
engine.directory.should == "/some/app"
end
end
describe "environment" do describe "environment" do
before(:each) do before(:each) do
write_procfile write_procfile
@@ -97,6 +105,15 @@ describe "Foreman::Engine", :fakefs do
engine.environment.should == {"FOO"=>"qoo"} engine.environment.should == {"FOO"=>"qoo"}
engine.start engine.start
end end
it "should be loaded relative to the Procfile" do
FileUtils.mkdir_p "/some/app"
File.open("/some/app/.env", "w") { |f| f.puts("FOO=qoo") }
write_procfile "/some/app/Procfile"
engine = Foreman::Engine.new("/some/app/Procfile")
engine.environment.should == {"FOO"=>"qoo"}
engine.start
end
end end
describe "utf8" do describe "utf8" do
+16 -6
View File
@@ -15,12 +15,11 @@ describe Foreman::Export::Supervisord, :fakefs do
it "exports to the filesystem" do it "exports to the filesystem" do
supervisord.export supervisord.export
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app.conf") File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app.conf")
end end
it "cleans up if exporting into an existing dir" do it "cleans up if exporting into an existing dir" do
mock(FileUtils).rm("/tmp/init/app.conf") mock(FileUtils).rm("/tmp/init/app.conf")
supervisord.export supervisord.export
supervisord.export supervisord.export
end end
@@ -30,8 +29,7 @@ describe Foreman::Export::Supervisord, :fakefs do
it "exports to the filesystem with concurrency" do it "exports to the filesystem with concurrency" do
supervisord.export supervisord.export
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-2.conf")
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-2.conf")
end end
end end
@@ -46,7 +44,6 @@ describe Foreman::Export::Supervisord, :fakefs do
it "can export with alternate template files" do it "can export with alternate template files" do
supervisord.export supervisord.export
File.read("/tmp/init/app.conf").should == "alternate_template\n" File.read("/tmp/init/app.conf").should == "alternate_template\n"
end end
end end
@@ -67,9 +64,22 @@ describe Foreman::Export::Supervisord, :fakefs do
it "can export with alternate template files" do it "can export with alternate template files" do
supervisord.export supervisord.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
end end
context "environment export" do
it "correctly translates environment when exporting" do
File.open("/tmp/supervisord_env", "w") { |f| f.puts("QUEUE=fastqueue,slowqueue\nVERBOSE=1") }
engine = Foreman::Engine.new(procfile,:env => "/tmp/supervisord_env")
supervisor = Foreman::Export::Supervisord.new("/tmp/init", engine, options)
stub(supervisor).say
supervisor.export
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-env-with-comma.conf")
end
end
end end
@@ -8,7 +8,7 @@ stdout_logfile=/var/log/app/alpha-1-out.log
stderr_logfile=/var/log/app/alpha-1-err.log stderr_logfile=/var/log/app/alpha-1-err.log
user=app user=app
directory=/tmp/app directory=/tmp/app
environment=PORT=5000 environment=PORT="5000"
[program:app-alpha-2] [program:app-alpha-2]
command=./alpha command=./alpha
autostart=true autostart=true
@@ -18,4 +18,7 @@ stdout_logfile=/var/log/app/alpha-2-out.log
stderr_logfile=/var/log/app/alpha-2-err.log stderr_logfile=/var/log/app/alpha-2-err.log
user=app user=app
directory=/tmp/app directory=/tmp/app
environment=PORT=5001 environment=PORT="5001"
[group:app]
programs=app-alpha-1,app-alpha-2
@@ -0,0 +1,24 @@
[program:app-alpha]
command=./alpha
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/app/alpha-1-out.log
stderr_logfile=/var/log/app/alpha-1-err.log
user=app
directory=/tmp/app
environment=QUEUE="fastqueue,slowqueue",VERBOSE="1",PORT="5000"
[program:app-bravo]
command=./bravo
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/app/bravo-1-out.log
stderr_logfile=/var/log/app/bravo-1-err.log
user=app
directory=/tmp/app
environment=QUEUE="fastqueue,slowqueue",VERBOSE="1",PORT="5100"
[group:app]
programs=app-alpha,app-bravo
@@ -0,0 +1,21 @@
[program:app-alpha]
command=./alpha
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/app/alpha-1-out.log
stderr_logfile=/var/log/app/alpha-1-err.log
user=app
directory=/tmp/app
environment=FOO="bar",PORT="5000"
[program:app-bravo]
command=./bravo
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/app/bravo-1-out.log
stderr_logfile=/var/log/app/bravo-1-err.log
user=app
directory=/tmp/app
environment=FOO="bar",PORT="5100"
+5 -2
View File
@@ -8,7 +8,7 @@ stdout_logfile=/var/log/app/alpha-1-out.log
stderr_logfile=/var/log/app/alpha-1-err.log stderr_logfile=/var/log/app/alpha-1-err.log
user=app user=app
directory=/tmp/app directory=/tmp/app
environment=PORT=5000 environment=PORT="5000"
[program:app-bravo] [program:app-bravo]
command=./bravo command=./bravo
autostart=true autostart=true
@@ -18,4 +18,7 @@ stdout_logfile=/var/log/app/bravo-1-out.log
stderr_logfile=/var/log/app/bravo-1-err.log stderr_logfile=/var/log/app/bravo-1-err.log
user=app user=app
directory=/tmp/app directory=/tmp/app
environment=PORT=5100 environment=PORT="5100"
[group:app]
programs=app-alpha,app-bravo