diff --git a/data/export/supervisord/app.conf.erb b/data/export/supervisord/app.conf.erb new file mode 100644 index 0000000..9e2b156 --- /dev/null +++ b/data/export/supervisord/app.conf.erb @@ -0,0 +1,21 @@ +<% +engine.procfile.entries.each do |process| + next if (conc = self.concurrency[process.name]) < 1 + 1.upto(self.concurrency[process.name]) do |num| + port = engine.port_for(process, num, self.port) + 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}") +%> +[program:<%= app %>-<%= name %>] +command=<%= process.command %> +autostart=true +autorestart=true +stopsignal=QUIT +stdout_logfile=<%= log_root %>/<%=process.name%>-<%=num%>-out.log +stderr_logfile=<%= log_root %>/<%=process.name%>-<%=num%>-err.log +user=<%= user %> +directory=<%= engine.directory %> +environment=<%= environment.join(',') %><% + end +end +%> \ No newline at end of file diff --git a/lib/foreman/export.rb b/lib/foreman/export.rb index df31d66..7cd80f3 100644 --- a/lib/foreman/export.rb +++ b/lib/foreman/export.rb @@ -30,3 +30,5 @@ require "foreman/export/inittab" require "foreman/export/upstart" require "foreman/export/bluepill" require "foreman/export/runit" +require "foreman/export/supervisord" + diff --git a/lib/foreman/export/supervisord.rb b/lib/foreman/export/supervisord.rb new file mode 100644 index 0000000..11eedd6 --- /dev/null +++ b/lib/foreman/export/supervisord.rb @@ -0,0 +1,26 @@ +require "erb" +require "foreman/export" + +class Foreman::Export::Supervisord < Foreman::Export::Base + + def export + error("Must specify a location") unless location + + FileUtils.mkdir_p location + + app = self.app || File.basename(engine.directory) + user = self.user || app + log_root = self.log || "/var/log/#{app}" + template_root = self.template + + Dir["#{location}/#{app}*.conf"].each do |file| + say "cleaning up: #{file}" + FileUtils.rm(file) + end + + app_template = export_template("supervisord", "app.conf.erb", template_root) + app_config = ERB.new(app_template, 0, '<').result(binding) + write_file "#{location}/#{app}.conf", app_config + end + +end diff --git a/spec/foreman/export/supervisord_spec.rb b/spec/foreman/export/supervisord_spec.rb new file mode 100644 index 0000000..c87d056 --- /dev/null +++ b/spec/foreman/export/supervisord_spec.rb @@ -0,0 +1,75 @@ +require "spec_helper" +require "foreman/engine" +require "foreman/export/supervisord" +require "tmpdir" + +describe Foreman::Export::Supervisord, :fakefs do + let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") } + let(:engine) { Foreman::Engine.new(procfile) } + let(:options) { Hash.new } + let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, options) } + + before(:each) { load_export_templates_into_fakefs("supervisord") } + before(:each) { stub(supervisord).say } + + it "exports to the filesystem" do + supervisord.export + + File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app.conf") + end + + it "cleans up if exporting into an existing dir" do + mock(FileUtils).rm("/tmp/init/app.conf") + + supervisord.export + supervisord.export + end + + context "with concurrency" do + let(:options) { Hash[:concurrency => "alpha=2"] } + + it "exports to the filesystem with concurrency" do + supervisord.export + + File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-2.conf") + end + end + + context "with alternate templates" do + let(:template_root) { "/tmp/alternate" } + let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, :template => template_root) } + + before do + FileUtils.mkdir_p template_root + File.open("#{template_root}/app.conf.erb", "w") { |f| f.puts "alternate_template" } + end + + it "can export with alternate template files" do + supervisord.export + + File.read("/tmp/init/app.conf").should == "alternate_template\n" + end + end + + context "with alternate templates from home dir" do + let(:default_template_root) {File.expand_path("#{ENV['HOME']}/.foreman/templates")} + + before do + ENV['_FOREMAN_SPEC_HOME'] = ENV['HOME'] + ENV['HOME'] = "/home/appuser" + FileUtils.mkdir_p default_template_root + File.open("#{default_template_root}/app.conf.erb", "w") { |f| f.puts "default_alternate_template" } + end + + after do + ENV['HOME'] = ENV.delete('_FOREMAN_SPEC_HOME') + end + + it "can export with alternate template files" do + supervisord.export + + File.read("/tmp/init/app.conf").should == "default_alternate_template\n" + end + end + +end diff --git a/spec/resources/export/supervisord/app-alpha-2.conf b/spec/resources/export/supervisord/app-alpha-2.conf new file mode 100644 index 0000000..c16b72f --- /dev/null +++ b/spec/resources/export/supervisord/app-alpha-2.conf @@ -0,0 +1,21 @@ + +[program:app-alpha-1] +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=PORT=5000 +[program:app-alpha-2] +command=./alpha +autostart=true +autorestart=true +stopsignal=QUIT +stdout_logfile=/var/log/app/alpha-2-out.log +stderr_logfile=/var/log/app/alpha-2-err.log +user=app +directory=/tmp/app +environment=PORT=5001 diff --git a/spec/resources/export/supervisord/app.conf b/spec/resources/export/supervisord/app.conf new file mode 100644 index 0000000..efcb28e --- /dev/null +++ b/spec/resources/export/supervisord/app.conf @@ -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=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=PORT=5100