From 676d3ff8d16d3f505aad3d9e4ba3b8988dabea47 Mon Sep 17 00:00:00 2001 From: Matthijs Langenberg Date: Tue, 8 Nov 2011 16:43:15 +0100 Subject: [PATCH] Add runit export format. Fix #28 --- Gemfile | 2 +- Gemfile.lock | 4 +- data/export/runit/log_run.erb | 7 +++ data/export/runit/run.erb | 3 + lib/foreman/cli.rb | 1 + lib/foreman/export.rb | 1 + lib/foreman/export/runit.rb | 60 +++++++++++++++++++ spec/foreman/export/runit_spec.rb | 35 +++++++++++ .../export/runit/app-alpha-1-log-run | 7 +++ spec/resources/export/runit/app-alpha-1-run | 3 + .../export/runit/app-alpha-2-log-run | 7 +++ spec/resources/export/runit/app-alpha-2-run | 3 + .../export/runit/app-bravo-1-log-run | 7 +++ spec/resources/export/runit/app-bravo-1-run | 3 + spec/spec_helper.rb | 4 +- 15 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 data/export/runit/log_run.erb create mode 100644 data/export/runit/run.erb create mode 100644 lib/foreman/export/runit.rb create mode 100644 spec/foreman/export/runit_spec.rb create mode 100644 spec/resources/export/runit/app-alpha-1-log-run create mode 100644 spec/resources/export/runit/app-alpha-1-run create mode 100644 spec/resources/export/runit/app-alpha-2-log-run create mode 100644 spec/resources/export/runit/app-alpha-2-run create mode 100644 spec/resources/export/runit/app-bravo-1-log-run create mode 100644 spec/resources/export/runit/app-bravo-1-run diff --git a/Gemfile b/Gemfile index 34c5b31..bbb9b0b 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ group :development do gem 'parka' gem 'rake' gem 'ronn' - gem 'fakefs', '~> 0.2.1' + gem 'fakefs', '~> 0.3.2' gem 'rcov', '~> 0.9.8' gem 'rr', '~> 1.0.2' gem 'rspec', '~> 2.6.0' diff --git a/Gemfile.lock b/Gemfile.lock index a9945bd..003fa60 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,7 +15,7 @@ GEM builder (3.0.0) crack (0.1.8) diff-lcs (1.1.2) - fakefs (0.2.1) + fakefs (0.3.2) hpricot (0.8.2) mime-types (1.16) mustache (0.11.2) @@ -51,7 +51,7 @@ PLATFORMS DEPENDENCIES aws-s3 - fakefs (~> 0.2.1) + fakefs (~> 0.3.2) foreman! parka rake diff --git a/data/export/runit/log_run.erb b/data/export/runit/log_run.erb new file mode 100644 index 0000000..ca143c9 --- /dev/null +++ b/data/export/runit/log_run.erb @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +LOG=<%= log_root %>/<%= process.name %>-<%= num %> + +test -d "$LOG" || mkdir -p m2750 "$LOG" && chown <%= user %> "$LOG" +exec chpst -u <%= user %> svlogd "$LOG" \ No newline at end of file diff --git a/data/export/runit/run.erb b/data/export/runit/run.erb new file mode 100644 index 0000000..a992edd --- /dev/null +++ b/data/export/runit/run.erb @@ -0,0 +1,3 @@ +#!/bin/sh +cd <%= engine.directory %> +exec chpst -u <%= user %> -e <%= process_env_directory %> <%= process.command %> \ No newline at end of file diff --git a/lib/foreman/cli.rb b/lib/foreman/cli.rb index d756516..a32e156 100644 --- a/lib/foreman/cli.rb +++ b/lib/foreman/cli.rb @@ -42,6 +42,7 @@ class Foreman::CLI < Thor when "inittab" then Foreman::Export::Inittab when "upstart" then Foreman::Export::Upstart when "bluepill" then Foreman::Export::Bluepill + when "runit" then Foreman::Export::Runit else error "Unknown export format: #{format}." end diff --git a/lib/foreman/export.rb b/lib/foreman/export.rb index 7976694..8a0e0b3 100644 --- a/lib/foreman/export.rb +++ b/lib/foreman/export.rb @@ -8,3 +8,4 @@ require "foreman/export/base" require "foreman/export/inittab" require "foreman/export/upstart" require "foreman/export/bluepill" +require "foreman/export/runit" diff --git a/lib/foreman/export/runit.rb b/lib/foreman/export/runit.rb new file mode 100644 index 0000000..43807ab --- /dev/null +++ b/lib/foreman/export/runit.rb @@ -0,0 +1,60 @@ +require "erb" +require "foreman/export" + +class Foreman::Export::Runit < Foreman::Export::Base + ENV_VARIABLE_REGEX = /([a-zA-Z_]+[a-zA-Z0-9_]*)=(\S+)/ + + def export(location, options={}) + error("Must specify a location") unless location + + app = options[:app] || File.basename(engine.directory) + user = options[:user] || app + log_root = options[:log] || "/var/log/#{app}" + template_root = options[:template] + + concurrency = Foreman::Utils.parse_concurrency(options[:concurrency]) + + run_template = export_template('runit', 'run.erb', template_root) + log_run_template = export_template('runit', 'log_run.erb', template_root) + + engine.processes.each do |process| + 1.upto(concurrency[process.name]) do |num| + process_directory = "#{location}/#{app}-#{process.name}-#{num}" + process_env_directory = "#{process_directory}/env" + process_log_directory = "#{process_directory}/log" + + create_directory process_directory + create_directory process_env_directory + create_directory process_log_directory + + run = ERB.new(run_template).result(binding) + write_file "#{process_directory}/run", run + + port = engine.port_for(process, num, options[:port]) + environment_variables = {'PORT' => port}. + merge(engine.environment). + merge(inline_variables(process.command)) + + environment_variables.each_pair do |var, env| + write_file "#{process_env_directory}/#{var.upcase}", env + end + + log_run = ERB.new(log_run_template).result(binding) + write_file "#{process_log_directory}/run", log_run + + end + end + + end + + private + def create_directory(location) + say "creating: #{location}" + FileUtils.mkdir(location) + end + + def inline_variables(command) + variable_name_regex = + Hash[*command.scan(ENV_VARIABLE_REGEX).flatten] + end +end \ No newline at end of file diff --git a/spec/foreman/export/runit_spec.rb b/spec/foreman/export/runit_spec.rb new file mode 100644 index 0000000..9218bfa --- /dev/null +++ b/spec/foreman/export/runit_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" +require "foreman/engine" +require "foreman/export/runit" +require "tmpdir" + +describe Foreman::Export::Runit do + let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", 'bar=baz') } + let(:engine) { Foreman::Engine.new(procfile) } + let(:runit) { Foreman::Export::Runit.new(engine) } + + before(:each) { load_export_templates_into_fakefs("runit") } + before(:each) { stub(runit).say } + + it "exports to the filesystem" do + FileUtils.mkdir_p('/tmp/init') + runit.export('/tmp/init', :concurrency => 'alpha=2') + + File.read("/tmp/init/app-alpha-1/run").should == example_export_file('runit/app-alpha-1-run') + File.read("/tmp/init/app-alpha-1/log/run").should == + example_export_file('runit/app-alpha-1-log-run') + File.read("/tmp/init/app-alpha-1/env/PORT").should == "5000\n" + File.read("/tmp/init/app-alpha-1/env/BAR").should == "baz\n" + + File.read("/tmp/init/app-alpha-2/run").should == example_export_file('runit/app-alpha-2-run') + File.read("/tmp/init/app-alpha-2/log/run").should == + example_export_file('runit/app-alpha-2-log-run') + File.read("/tmp/init/app-alpha-2/env/PORT").should == "5001\n" + File.read("/tmp/init/app-alpha-2/env/BAR").should == "baz\n" + + File.read("/tmp/init/app-bravo-1/run").should == example_export_file('runit/app-bravo-1-run') + File.read("/tmp/init/app-bravo-1/log/run").should == + example_export_file('runit/app-bravo-1-log-run') + File.read("/tmp/init/app-bravo-1/env/PORT").should == "5100\n" + end +end \ No newline at end of file diff --git a/spec/resources/export/runit/app-alpha-1-log-run b/spec/resources/export/runit/app-alpha-1-log-run new file mode 100644 index 0000000..2631d0a --- /dev/null +++ b/spec/resources/export/runit/app-alpha-1-log-run @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +LOG=/var/log/app/alpha-1 + +test -d "$LOG" || mkdir -p m2750 "$LOG" && chown app "$LOG" +exec chpst -u app svlogd "$LOG" diff --git a/spec/resources/export/runit/app-alpha-1-run b/spec/resources/export/runit/app-alpha-1-run new file mode 100644 index 0000000..cb8890a --- /dev/null +++ b/spec/resources/export/runit/app-alpha-1-run @@ -0,0 +1,3 @@ +#!/bin/sh +cd /tmp/app +exec chpst -u app -e /tmp/init/app-alpha-1/env ./alpha bar=baz diff --git a/spec/resources/export/runit/app-alpha-2-log-run b/spec/resources/export/runit/app-alpha-2-log-run new file mode 100644 index 0000000..d89fd1a --- /dev/null +++ b/spec/resources/export/runit/app-alpha-2-log-run @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +LOG=/var/log/app/alpha-2 + +test -d "$LOG" || mkdir -p m2750 "$LOG" && chown app "$LOG" +exec chpst -u app svlogd "$LOG" diff --git a/spec/resources/export/runit/app-alpha-2-run b/spec/resources/export/runit/app-alpha-2-run new file mode 100644 index 0000000..aac847a --- /dev/null +++ b/spec/resources/export/runit/app-alpha-2-run @@ -0,0 +1,3 @@ +#!/bin/sh +cd /tmp/app +exec chpst -u app -e /tmp/init/app-alpha-2/env ./alpha bar=baz diff --git a/spec/resources/export/runit/app-bravo-1-log-run b/spec/resources/export/runit/app-bravo-1-log-run new file mode 100644 index 0000000..9d55c77 --- /dev/null +++ b/spec/resources/export/runit/app-bravo-1-log-run @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +LOG=/var/log/app/bravo-1 + +test -d "$LOG" || mkdir -p m2750 "$LOG" && chown app "$LOG" +exec chpst -u app svlogd "$LOG" diff --git a/spec/resources/export/runit/app-bravo-1-run b/spec/resources/export/runit/app-bravo-1-run new file mode 100644 index 0000000..cd2b4ed --- /dev/null +++ b/spec/resources/export/runit/app-bravo-1-run @@ -0,0 +1,3 @@ +#!/bin/sh +cd /tmp/app +exec chpst -u app -e /tmp/init/app-bravo-1/env ./bravo diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c9061e9..5a901bc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -28,9 +28,9 @@ def write_foreman_config(app) end end -def write_procfile(procfile="Procfile") +def write_procfile(procfile="Procfile", alpha_env="") File.open(procfile, "w") do |file| - file.puts "alpha: ./alpha" + file.puts "alpha: ./alpha" + " #{alpha_env}".rstrip file.puts "\n" file.puts "bravo:\t./bravo" end