lib/percheron/actions/exec.rb
module Percheron
module Actions
class Exec
include Base
def initialize(unit, needed_units, scripts, description)
@unit = unit
@needed_units = needed_units
@scripts = scripts
@description = description
end
def execute!
$logger.debug "Executing #{description} #{scripts.inspect} on '#{unit.display_name}' unit"
results = exec!
results.compact.empty? ? nil : unit
end
private
attr_reader :unit, :needed_units, :scripts, :description
def exec!
results = []
started_needed_units = start_units!(needed_units)
results << execute_scripts_on_running_unit!
results << stop_units!(started_needed_units)
results
end
def execute_scripts_on_running_unit!
unit_running = unit.running?
Start.new(unit, exec_scripts: false).execute! unless unit_running
execute_scripts!
commit_and_tag_new_image!
Stop.new(unit).execute! unless unit_running
end
def commit_and_tag_new_image!
new_image = unit.container.commit
new_image.tag(repo: unit.image_repo, tag: unit.version.to_s, force: true)
end
def execute_scripts!
scripts.each do |script|
in_working_directory(base_dir) do
file = Pathname.new(File.expand_path(script, base_dir))
execute_command!('/bin/sh -x /tmp/%s 2>&1' % file.basename)
end
end
end
def execute_command!(command)
$logger.info "Executing #{description} '#{command}' for '#{unit.display_name}' unit"
unit.container.exec(command.split(' ')) do |stream, out|
$logger.debug '%s: %s' % [ stream, out.strip ]
end
end
def stop_units!(units)
exec_on_units!(units) do |unit|
Stop.new(unit).execute! if unit.running?
end
end
def start_units!(units, scripts: true)
exec_on_units!(units) do |unit|
next if unit.running?
units = unit.startable_needed_units.values
Start.new(unit, needed_units: units, exec_scripts: scripts).execute!
end
end
def exec_on_units!(units)
units.each_with_object([]) do |unit, all|
all << unit if yield(unit)
end.compact
end
end
end
end