From 67ffbe2aa29cdb04335e5f7d30fe874c1ddf26e0 Mon Sep 17 00:00:00 2001 From: Patrick Hemmer Date: Mon, 17 Feb 2014 00:40:39 -0500 Subject: [PATCH] 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. --- data/export/systemd/master.target.erb | 5 +++++ data/export/systemd/process.service.erb | 3 --- data/export/systemd/process_master.target.erb | 4 +--- lib/foreman/export/systemd.rb | 11 +++++++++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/data/export/systemd/master.target.erb b/data/export/systemd/master.target.erb index 3a8466d..d054c29 100644 --- a/data/export/systemd/master.target.erb +++ b/data/export/systemd/master.target.erb @@ -1 +1,6 @@ [Unit] +StopWhenUnneeded=true +Wants=<%= process_master_names.join(' ') %> + +[Install] +WantedBy=multi-user.target diff --git a/data/export/systemd/process.service.erb b/data/export/systemd/process.service.erb index e51d8c0..aa2668d 100644 --- a/data/export/systemd/process.service.erb +++ b/data/export/systemd/process.service.erb @@ -13,6 +13,3 @@ StandardOutput=syslog StandardError=syslog SyslogIdentifier=%n KillMode=process - -[Install] -WantedBy=<%= app %>-<%= name %>.target diff --git a/data/export/systemd/process_master.target.erb b/data/export/systemd/process_master.target.erb index 0a2f981..7b3b9bb 100644 --- a/data/export/systemd/process_master.target.erb +++ b/data/export/systemd/process_master.target.erb @@ -1,5 +1,3 @@ [Unit] StopWhenUnneeded=true - -[Install] -WantedBy=<%= app %>.target \ No newline at end of file +Wants=<%= process_names.join(' ') %> diff --git a/lib/foreman/export/systemd.rb b/lib/foreman/export/systemd.rb index a6f0381..78a643c 100644 --- a/lib/foreman/export/systemd.rb +++ b/lib/foreman/export/systemd.rb @@ -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