diff --git a/lib/foreman/cli.rb b/lib/foreman/cli.rb index 8f8b72c..5ee9dd9 100644 --- a/lib/foreman/cli.rb +++ b/lib/foreman/cli.rb @@ -1,4 +1,5 @@ require "foreman" +require "foreman/configuration" require "foreman/engine" require "foreman/export" require "thor" @@ -12,9 +13,9 @@ class Foreman::CLI < Thor Foreman::Engine.new(procfile).start end - desc "export NAME [PROCFILE] [FORMAT]", "Export the app described in PROCFILE as NAME to another FORMAT" + desc "export APP [PROCFILE] [FORMAT]", "Export the app described in PROCFILE as APP to another FORMAT" - def export(name, procfile="Procfile", format="upstart") + def export(app, procfile="Procfile", format="upstart") error "#{procfile} does not exist." unless File.exist?(procfile) formatter = case format @@ -22,7 +23,26 @@ class Foreman::CLI < Thor else error "Unknown export format: #{format}" end - formatter.new(Foreman::Engine.new(procfile)).export(name) + formatter.new(Foreman::Engine.new(procfile)).export(app) + end + + desc "scale APP PROCESS AMOUNT", "Change the concurrency of a given process type" + + def scale(app, process, amount) + config = Foreman::Configuration.new(app) + + amount = amount.to_i + old_amount = config.processes[process] + + config.scale(process, amount) + + if (old_amount < amount) + ((old_amount+1)..amount).each { |num| system "start #{app}-#{process} NUM=#{num}" } + elsif (amount < old_amount) + ((amount+1)..old_amount).each { |num| system "stop #{app}-#{process} NUM=#{num}" } + end + + config.write end private ###################################################################### diff --git a/lib/foreman/configuration.rb b/lib/foreman/configuration.rb new file mode 100644 index 0000000..7c4f39a --- /dev/null +++ b/lib/foreman/configuration.rb @@ -0,0 +1,44 @@ +require "foreman" + +class Foreman::Configuration + + attr_reader :app + attr_reader :processes + + def initialize(app) + @app = app + @processes = {} + read_initial_config + end + + def scale(process, amount) + processes[process] = amount.to_i + end + + def write + write_file "/etc/foreman/#{app}.conf", <<-UPSTART_CONFIG +#{app}_processes="#{processes.keys.join(' ')}" +#{processes.keys.map { |k| "#{app}_#{k}=\"#{processes[k]}\"" }.join("\n")} + UPSTART_CONFIG + end + +private ###################################################################### + + def read_initial_config + config = File.read("/etc/foreman/#{app}.conf").split("\n").inject({}) do |accum, line| + key, value = line.match(/^(.+?)\s*=\s*"(.+?)"\s*$/).captures + #accum.update(parts(1) => parts(2)) + accum.update(key => value) + end + config["#{app}_processes"].split(" ").each do |process| + scale(process, config["#{app}_#{process}"]) + end + end + + def write_file(filename, contents) + File.open(filename, "w") do |file| + file.puts contents + end + end + +end diff --git a/lib/foreman/export/upstart.rb b/lib/foreman/export/upstart.rb index 24a79ca..724b9f8 100644 --- a/lib/foreman/export/upstart.rb +++ b/lib/foreman/export/upstart.rb @@ -1,3 +1,4 @@ +require "foreman/configuration" require "foreman/export" class Foreman::Export::Upstart @@ -8,31 +9,33 @@ class Foreman::Export::Upstart @engine = engine end - def export(name) + def export(app) FileUtils.mkdir_p "/etc/foreman" FileUtils.mkdir_p "/etc/init" - write_file "/etc/foreman/#{name}.conf", <<-UPSTART_CONFIG -#{name}_processes="#{engine.processes.keys.join(' ')}" -#{engine.processes.keys.map { |k| "#{name}_#{k}=\"1\"" }.join("\n")} - UPSTART_CONFIG + config = Foreman::Configuration.new(app) - write_file "/etc/init/#{name}.conf", <<-UPSTART_MASTER + engine.processes.each do |name, process| + config.scale(name, 1) + end + config.write + + write_file "/etc/init/#{app}.conf", <<-UPSTART_MASTER pre-start script bash << "EOF" - mkdir -p /var/log/#{name} + mkdir -p /var/log/#{app} - if [ -f /etc/foreman/#{name}.conf ]; then - source /etc/foreman/#{name}.conf + if [ -f /etc/foreman/#{app}.conf ]; then + source /etc/foreman/#{app}.conf fi - for process in $( echo "$#{name}_processes" ); do - process_count_config="#{name}_$process" + for process in $( echo "$#{app}_processes" ); do + process_count_config="#{app}_$process" process_count=${!process_count_config} for ((i=1; i<=${process_count:=1}; i+=1)); do - start #{name}-$process NUM=$i + start #{app}-$process NUM=$i done done EOF @@ -41,18 +44,18 @@ end script UPSTART_MASTER engine.processes.values.each do |process| - write_file "/etc/init/#{name}-#{process.name}.conf", <<-UPSTART_CHILD + write_file "/etc/init/#{app}-#{process.name}.conf", <<-UPSTART_CHILD instance $NUM -stop on stopping #{name} +stop on stopping #{app} respawn chdir #{engine.directory} -exec #{process.command} >>/var/log/#{name}/#{process.name}.log 2>&1 +exec #{process.command} >>/var/log/#{app}/#{process.name}.log 2>&1 UPSTART_CHILD end end -private +private ###################################################################### def write_file(filename, contents) File.open(filename, "w") do |file|