1
data/export/systemd/master.target.erb
Normal file
1
data/export/systemd/master.target.erb
Normal file
@@ -0,0 +1 @@
|
||||
[Unit]
|
||||
18
data/export/systemd/process.service.erb
Normal file
18
data/export/systemd/process.service.erb
Normal file
@@ -0,0 +1,18 @@
|
||||
[Unit]
|
||||
StopWhenUnneeded=true
|
||||
|
||||
[Service]
|
||||
User=<%= user %>
|
||||
WorkingDirectory=<%= engine.root %>
|
||||
Environment=PORT=<%= port %><% engine.env.each_pair do |var,env| %>
|
||||
Environment=<%= var.upcase %>=<%= env %><% end %>
|
||||
ExecStart=/bin/bash -lc '<%= process.command %>'
|
||||
Restart=always
|
||||
StandardInput=null
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=%n
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=<%= app %>-<%= name %>.target
|
||||
5
data/export/systemd/process_master.target.erb
Normal file
5
data/export/systemd/process_master.target.erb
Normal file
@@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
StopWhenUnneeded=true
|
||||
|
||||
[Install]
|
||||
WantedBy=<%= app %>.target
|
||||
@@ -32,3 +32,4 @@ require "foreman/export/bluepill"
|
||||
require "foreman/export/runit"
|
||||
require "foreman/export/supervisord"
|
||||
require "foreman/export/launchd"
|
||||
require "foreman/export/systemd"
|
||||
|
||||
25
lib/foreman/export/systemd.rb
Normal file
25
lib/foreman/export/systemd.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
require "erb"
|
||||
require "foreman/export"
|
||||
|
||||
class Foreman::Export::Systemd < Foreman::Export::Base
|
||||
|
||||
def export
|
||||
super
|
||||
|
||||
Dir["#{location}/#{app}*.target"].concat(Dir["#{location}/#{app}*.service"]).each do |file|
|
||||
clean file
|
||||
end
|
||||
|
||||
write_template "systemd/master.target.erb", "#{app}.target", binding
|
||||
|
||||
engine.each_process do |name, process|
|
||||
next if engine.formation[name] < 1
|
||||
write_template "systemd/process_master.target.erb", "#{app}-#{name}.target", binding
|
||||
|
||||
1.upto(engine.formation[name]) do |num|
|
||||
port = engine.port_for(process, num)
|
||||
write_template "systemd/process.service.erb", "#{app}-#{name}-#{num}.service", binding
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -103,6 +103,8 @@ foreman currently supports the following output formats:
|
||||
|
||||
* runit
|
||||
|
||||
* systemd
|
||||
|
||||
* upstart
|
||||
|
||||
## INITTAB EXPORT
|
||||
@@ -114,6 +116,17 @@ Will export a chunk of inittab-compatible configuration:
|
||||
EX02:4:respawn:/bin/su - example -c 'PORT=5100 bundle exec rake jobs:work >> /var/log/job-1.log 2>&1'
|
||||
# ----- end foreman example processes -----
|
||||
|
||||
## SYSTEMD EXPORT
|
||||
|
||||
Will create a series of systemd scripts in the location you specify. Scripts
|
||||
will be structured to make the following commands valid:
|
||||
|
||||
`systemctl start appname.target`
|
||||
|
||||
`systemctl stop appname-processname.target`
|
||||
|
||||
`systemctl restart appname-processname-3.service`
|
||||
|
||||
## UPSTART EXPORT
|
||||
|
||||
Will create a series of upstart scripts in the location you specify. Scripts
|
||||
|
||||
91
spec/foreman/export/systemd_spec.rb
Normal file
91
spec/foreman/export/systemd_spec.rb
Normal file
@@ -0,0 +1,91 @@
|
||||
require "spec_helper"
|
||||
require "foreman/engine"
|
||||
require "foreman/export/systemd"
|
||||
require "tmpdir"
|
||||
|
||||
describe Foreman::Export::Systemd, :fakefs do
|
||||
let(:procfile) { write_procfile("/tmp/app/Procfile") }
|
||||
let(:formation) { nil }
|
||||
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
||||
let(:options) { Hash.new }
|
||||
let(:systemd) { Foreman::Export::Systemd.new("/tmp/init", engine, options) }
|
||||
|
||||
before(:each) { load_export_templates_into_fakefs("systemd") }
|
||||
before(:each) { stub(systemd).say }
|
||||
|
||||
it "exports to the filesystem" do
|
||||
systemd.export
|
||||
|
||||
File.read("/tmp/init/app.target").should == example_export_file("systemd/app.target")
|
||||
File.read("/tmp/init/app-alpha.target").should == example_export_file("systemd/app-alpha.target")
|
||||
File.read("/tmp/init/app-alpha-1.service").should == example_export_file("systemd/app-alpha-1.service")
|
||||
File.read("/tmp/init/app-bravo.target").should == example_export_file("systemd/app-bravo.target")
|
||||
File.read("/tmp/init/app-bravo-1.service").should == example_export_file("systemd/app-bravo-1.service")
|
||||
end
|
||||
|
||||
it "cleans up if exporting into an existing dir" do
|
||||
mock(FileUtils).rm("/tmp/init/app.target")
|
||||
mock(FileUtils).rm("/tmp/init/app-alpha.target")
|
||||
mock(FileUtils).rm("/tmp/init/app-alpha-1.service")
|
||||
mock(FileUtils).rm("/tmp/init/app-bravo.target")
|
||||
mock(FileUtils).rm("/tmp/init/app-bravo-1.service")
|
||||
mock(FileUtils).rm("/tmp/init/app-foo-bar.target")
|
||||
mock(FileUtils).rm("/tmp/init/app-foo-bar-1.service")
|
||||
mock(FileUtils).rm("/tmp/init/app-foo_bar.target")
|
||||
mock(FileUtils).rm("/tmp/init/app-foo_bar-1.service")
|
||||
|
||||
systemd.export
|
||||
systemd.export
|
||||
end
|
||||
|
||||
it "includes environment variables" do
|
||||
engine.env['KEY'] = 'some "value"'
|
||||
systemd.export
|
||||
File.read("/tmp/init/app-alpha-1.service").should =~ /KEY=some "value"$/
|
||||
end
|
||||
|
||||
context "with a formation" do
|
||||
let(:formation) { "alpha=2" }
|
||||
|
||||
it "exports to the filesystem with concurrency" do
|
||||
systemd.export
|
||||
|
||||
File.read("/tmp/init/app.target").should == example_export_file("systemd/app.target")
|
||||
File.read("/tmp/init/app-alpha.target").should == example_export_file("systemd/app-alpha.target")
|
||||
File.read("/tmp/init/app-alpha-1.service").should == example_export_file("systemd/app-alpha-1.service")
|
||||
File.read("/tmp/init/app-alpha-2.service").should == example_export_file("systemd/app-alpha-2.service")
|
||||
File.exists?("/tmp/init/app-bravo-1.service").should == false
|
||||
end
|
||||
end
|
||||
|
||||
context "with alternate templates" do
|
||||
let(:template) { "/tmp/alternate" }
|
||||
let(:options) { { :app => "app", :template => template } }
|
||||
|
||||
before do
|
||||
FileUtils.mkdir_p template
|
||||
File.open("#{template}/master.target.erb", "w") { |f| f.puts "alternate_template" }
|
||||
end
|
||||
|
||||
it "can export with alternate template files" do
|
||||
systemd.export
|
||||
File.read("/tmp/init/app.target").should == "alternate_template\n"
|
||||
end
|
||||
end
|
||||
|
||||
context "with alternate templates from home dir" do
|
||||
|
||||
before do
|
||||
FileUtils.mkdir_p File.expand_path("~/.foreman/templates/systemd")
|
||||
File.open(File.expand_path("~/.foreman/templates/systemd/master.target.erb"), "w") do |file|
|
||||
file.puts "default_alternate_template"
|
||||
end
|
||||
end
|
||||
|
||||
it "can export with alternate template files" do
|
||||
systemd.export
|
||||
File.read("/tmp/init/app.target").should == "default_alternate_template\n"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
17
spec/resources/export/systemd/app-alpha-1.service
Normal file
17
spec/resources/export/systemd/app-alpha-1.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
StopWhenUnneeded=true
|
||||
|
||||
[Service]
|
||||
User=app
|
||||
WorkingDirectory=/tmp/app
|
||||
Environment=PORT=5000
|
||||
ExecStart=/bin/bash -lc './alpha'
|
||||
Restart=always
|
||||
StandardInput=null
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=%n
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=app-alpha.target
|
||||
17
spec/resources/export/systemd/app-alpha-2.service
Normal file
17
spec/resources/export/systemd/app-alpha-2.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
StopWhenUnneeded=true
|
||||
|
||||
[Service]
|
||||
User=app
|
||||
WorkingDirectory=/tmp/app
|
||||
Environment=PORT=5001
|
||||
ExecStart=/bin/bash -lc './alpha'
|
||||
Restart=always
|
||||
StandardInput=null
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=%n
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=app-alpha.target
|
||||
5
spec/resources/export/systemd/app-alpha.target
Normal file
5
spec/resources/export/systemd/app-alpha.target
Normal file
@@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
StopWhenUnneeded=true
|
||||
|
||||
[Install]
|
||||
WantedBy=app.target
|
||||
17
spec/resources/export/systemd/app-bravo-1.service
Normal file
17
spec/resources/export/systemd/app-bravo-1.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
StopWhenUnneeded=true
|
||||
|
||||
[Service]
|
||||
User=app
|
||||
WorkingDirectory=/tmp/app
|
||||
Environment=PORT=5100
|
||||
ExecStart=/bin/bash -lc './bravo'
|
||||
Restart=always
|
||||
StandardInput=null
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=%n
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=app-bravo.target
|
||||
5
spec/resources/export/systemd/app-bravo.target
Normal file
5
spec/resources/export/systemd/app-bravo.target
Normal file
@@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
StopWhenUnneeded=true
|
||||
|
||||
[Install]
|
||||
WantedBy=app.target
|
||||
1
spec/resources/export/systemd/app.target
Normal file
1
spec/resources/export/systemd/app.target
Normal file
@@ -0,0 +1 @@
|
||||
[Unit]
|
||||
Reference in New Issue
Block a user