Compare commits

..

14 Commits

Author SHA1 Message Date
199e7de97c update gems. 2014-03-17 20:12:11 +00:00
dlage
defc40b911 Merge pull request #5 from phemmer/systemd-dependencies
export: fix systemd dependencies
2014-03-17 19:39:14 +00:00
dlage
37dcba0e33 Merge pull request #3 from phemmer/shellfix
Shellfix
2014-03-17 19:37:20 +00:00
dlage
d205e3ba2e Merge pull request #4 from phemmer/run-nofork
don't fork on 'run'
2014-03-17 19:37:05 +00:00
dlage
9905334f01 Merge pull request #2 from ged/better-357-fix
A better fix for #357.
2014-03-17 19:29:45 +00:00
dlage
dd292ed7da Merge pull request #1 from petergoldstein/feature/add_2_1_0
Feature/add 2 1 0
2014-03-17 19:25:46 +00:00
Patrick Hemmer
67ffbe2aa2 export: fix systemd dependencies
With the previous way systemd services were exported, you had to enable every single process one by one to get the service operational.

Consider the following Procfile:

    web: bundle exec thin start
    worker: bundle exec worker start

Exported with:

    foreman export systemd /usr/lib/systemd/system -a myapp -c worker=3

You will have to perform the following to start the service:

    systemctl enable myapp-web-1.service
    systemctl enable myapp-worker-1.service
    systemctl enable myapp-worker-2.service
    systemctl enable myapp-worker-3.service
    systemctl enable myapp-web.target
    systemctl enable myapp-worker.target
    systemctl start myapp.target

Thats 7 commands, and you have to know the names of each service. Nasty.

With the changes here, you will have to perform the following:

    systemctl enable myapp.target
    systemctl start myapp.target

You can also `systemctl start myapp.target` without enabling as well. Previously if you tried to start `myapp.target` without enabling each individual process it would not work.

---

Additionally, this change also adds the dependency to 'multi-user.target' (the default behavior for all services). This will properly shut down (or start) the app when the system changes runlevels. The previous method did not do this.
2014-02-17 00:40:39 -05:00
Peter M. Goldstein
da8bba5941 Use a 1.9.2 compatible version of rdiscount 2014-01-13 17:38:11 -08:00
Peter M. Goldstein
2aa1cbf94f Bump up gem versions in Gemfile.lock. Minor changes to eliminate deprecation warnings. 2014-01-13 17:30:58 -08:00
Peter M. Goldstein
34a1163fe9 Add Ruby 2.1.0, clean up references in allow_failures to now un-tested rvms. 2014-01-13 15:28:47 -08:00
Patrick Hemmer
2e5f610b76 don't fork on 'run'
This removes the fork when doing `foreman run`. The fork results in an unnecessary process laying around. The parent process doesn't do anything other than fork and wait for the child to exit.
2013-11-26 00:09:19 -05:00
Michael Granger
20392d98a1 A better fix for #357.
This is a better fix for several reasons:

- It's more portable; the arguments/options to 'ps' vary widely across
  platforms.
- Killing children by forking yet more children (i.e., via backtick) is
  problematic when you're trying to kill processes because of resource
  starvation.
- Processes should not signal processes other than their own children,
  especially in a generic task-runner like Foreman. If the signal
  should propagate, then the sub-process should propagate signals to its
  children itself. There's no way to know what cleanup or preparation
  is necessary for a clean shutdown (e.g., SIGINT/SIGTERM), and
  in what order grandchild processes should be shut down to properly
  release locks, close files, etc.
- foreman-runner doesn't (shouldn't?) create grandchild processes; the
  last thing it does is `exec` the program it's launching, which
  will replace the program of the *current* process with the one
  being started up.
2013-11-05 11:56:13 -08:00
Patrick Hemmer
e8538d9f45 exec on upstart to prevent useless procs floating around 2013-10-02 20:41:51 -04:00
Patrick Hemmer
4a51a2aa8a specify a shell when using upstart 2013-10-02 20:08:47 -04:00
12 changed files with 73 additions and 77 deletions

View File

@@ -3,8 +3,6 @@ script: bundle exec rake spec
matrix:
allow_failures:
- rvm: jruby
- rvm: rbx
- rvm: ree
notifications:
email: false
@@ -19,4 +17,5 @@ rvm:
- 1.9.2
- 1.9.3
- 2.0.0
- 2.1.0
- jruby

View File

@@ -18,6 +18,8 @@ group :development do
gem 'rr', '~> 1.0.2'
gem 'rspec', '~> 2.0'
gem "simplecov", :require => false
gem 'timecop'
gem 'timecop', '0.6.1'
gem 'yard'
gem 'mime-types', '~> 1.25.1'
gem 'rdiscount', '~> 1.6.8'
end

View File

@@ -8,44 +8,46 @@ PATH
GEM
remote: http://rubygems.org/
specs:
aws-s3 (0.6.2)
aws-s3 (0.6.3)
builder
mime-types
xml-simple
builder (3.0.0)
diff-lcs (1.1.3)
dotenv (0.7.0)
builder (3.2.2)
diff-lcs (1.2.5)
docile (1.1.3)
dotenv (0.10.0)
fakefs (0.3.2)
hpricot (0.8.6)
hpricot (0.8.6-java)
mime-types (1.16)
multi_json (1.0.4)
mustache (0.11.2)
posix-spawn (0.3.6)
rake (0.9.2.2)
rdiscount (1.6.5)
mime-types (1.25.1)
multi_json (1.9.0)
mustache (0.99.5)
posix-spawn (0.3.8)
rake (10.1.1)
rdiscount (1.6.8)
ronn (0.7.3)
hpricot (>= 0.8.2)
mustache (>= 0.7.0)
rdiscount (>= 1.5.8)
rr (1.0.2)
rspec (2.8.0)
rspec-core (~> 2.8.0)
rspec-expectations (~> 2.8.0)
rspec-mocks (~> 2.8.0)
rspec-core (2.8.0)
rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.8.0)
simplecov (0.5.4)
multi_json (~> 1.0.3)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
thor (0.16.0)
timecop (0.3.5)
win32console (1.3.0-x86-mingw32)
xml-simple (1.0.15)
yard (0.8.2)
rr (1.0.5)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.8)
rspec-expectations (2.14.5)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.6)
simplecov (0.8.2)
docile (~> 1.1.0)
multi_json
simplecov-html (~> 0.8.0)
simplecov-html (0.8.0)
thor (0.18.1)
timecop (0.6.1)
win32console (1.3.2-x86-mingw32)
xml-simple (1.1.3)
yard (0.8.7.3)
PLATFORMS
java
@@ -56,12 +58,14 @@ DEPENDENCIES
aws-s3
fakefs (~> 0.3.2)
foreman!
mime-types (~> 1.25.1)
posix-spawn (~> 0.3.6)
rake
rdiscount (~> 1.6.8)
ronn
rr (~> 1.0.2)
rspec (~> 2.0)
simplecov
timecop
timecop (= 0.6.1)
win32console (~> 1.3.0)
yard

View File

@@ -1 +1,6 @@
[Unit]
StopWhenUnneeded=true
Wants=<%= process_master_names.join(' ') %>
[Install]
WantedBy=multi-user.target

View File

@@ -13,6 +13,3 @@ StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process
[Install]
WantedBy=<%= app %>-<%= name %>.target

View File

@@ -1,5 +1,3 @@
[Unit]
StopWhenUnneeded=true
[Install]
WantedBy=<%= app %>.target
Wants=<%= process_names.join(' ') %>

View File

@@ -2,4 +2,4 @@ start on starting <%= app %>-<%= name %>
stop on stopping <%= app %>-<%= name %>
respawn
exec su - <%= user %> -c 'cd <%= engine.root %>; export PORT=<%= port %>;<% engine.env.each_pair do |var,env| %> export <%= var.upcase %>=<%= shell_quote(env) %>; <% end %> <%= process.command %> >> <%= log %>/<%=name%>-<%=num%>.log 2>&1'
exec su - <%= user %> -s /bin/sh -c 'cd <%= engine.root %>; export PORT=<%= port %>;<% engine.env.each_pair do |var,env| %> export <%= var.upcase %>=<%= shell_quote(env) %>; <% end %> exec <%= process.command %> >> <%= log %>/<%=name%>-<%=num%>.log 2>&1'

View File

@@ -83,22 +83,18 @@ class Foreman::CLI < Thor
engine.load_procfile(procfile)
end
pid = fork do
begin
engine.env.each { |k,v| ENV[k] = v }
if args.size == 1 && process = engine.process(args.first)
process.exec(:env => engine.env)
else
exec args.shelljoin
end
rescue Errno::EACCES
error "not executable: #{args.first}"
rescue Errno::ENOENT
error "command not found: #{args.first}"
begin
engine.env.each { |k,v| ENV[k] = v }
if args.size == 1 && process = engine.process(args.first)
process.exec(:env => engine.env)
else
exec args.shelljoin
end
rescue Errno::EACCES
error "not executable: #{args.first}"
rescue Errno::ENOENT
error "command not found: #{args.first}"
end
Process.wait(pid)
exit $?.exitstatus
end
desc "version", "Display Foreman gem version"

View File

@@ -176,19 +176,14 @@ class Foreman::Engine
#
# @param [String] signal The signal to send to each process
#
def kill_children(signal="SIGTERM")
if Foreman.windows?
@running.each do |pid, (process, index)|
system "sending #{signal} to #{name_for(pid)} at pid #{pid}"
begin
Process.kill(signal, pid)
rescue Errno::ESRCH, Errno::EPERM
end
end
else
def kill_children( signal="SIGTERM" )
@running.each do |pid, (process, index)|
system "sending #{signal} to #{name_for(pid)} at pid #{pid}"
begin
Process.kill signal, *@running.keys unless @running.empty?
rescue Errno::ESRCH, Errno::EPERM
Process.kill( signal, pid )
rescue Errno::ESRCH, Errno::EPERM => err
system " %p when sending signal %p to pid %d: %s" %
[ err.class, signal, pid, err.message ]
end
end
end
@@ -198,14 +193,7 @@ class Foreman::Engine
# @param [String] signal The signal to send
#
def killall(signal="SIGTERM")
if Foreman.windows?
kill_children(signal)
else
begin
Process.kill "-#{signal}", Process.pid
rescue Errno::ESRCH, Errno::EPERM
end
end
kill_children(signal)
end
# Get the process formation

View File

@@ -10,16 +10,23 @@ class Foreman::Export::Systemd < Foreman::Export::Base
clean file
end
write_template "systemd/master.target.erb", "#{app}.target", binding
process_master_names = []
engine.each_process do |name, process|
next if engine.formation[name] < 1
write_template "systemd/process_master.target.erb", "#{app}-#{name}.target", binding
process_names = []
1.upto(engine.formation[name]) do |num|
port = engine.port_for(process, num)
write_template "systemd/process.service.erb", "#{app}-#{name}-#{num}.service", binding
process_names << "#{app}-#{name}-#{num}.service"
end
write_template "systemd/process_master.target.erb", "#{app}-#{name}.target", binding
process_master_names << "#{app}-#{name}.target"
end
write_template "systemd/master.target.erb", "#{app}.target", binding
end
end

View File

@@ -31,6 +31,6 @@ describe Foreman::Export::Runit, :fakefs do
end
it "creates a full path to the export directory" do
expect { runit.export }.to_not raise_error(Errno::ENOENT)
expect { runit.export }.to_not raise_error
end
end

View File

@@ -177,5 +177,5 @@ RSpec.configure do |config|
config.order = 'rand'
config.include FakeFS::SpecHelpers, :fakefs
config.mock_with :rr
config.backtrace_clean_patterns = []
config.backtrace_exclusion_patterns = []
end