class ForemanMaintain::Utils::CommandRunner
Wrapper around running a command
Attributes
command[R]
logger[R]
Public Class Methods
new(logger, command, options)
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 10 def initialize(logger, command, options) options.validate_options!(:stdin, :interactive, :valid_exit_statuses, :env) options[:valid_exit_statuses] ||= [0] options[:env] ||= {} @logger = logger @command = command @stdin = options[:stdin] @interactive = options[:interactive] @options = options @valid_exit_statuses = options[:valid_exit_statuses] @env = options[:env] raise ArgumentError, 'Can not pass stdin for interactive command' if @interactive && @stdin end
Public Instance Methods
execution_error()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 52 def execution_error raise Error::ExecutionError.new(@command, exit_status, @stdin, @interactive ? nil : @output) end
exit_status()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 43 def exit_status raise 'Command not yet executed' unless defined? @exit_status @exit_status end
interactive?()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 34 def interactive? @interactive end
output()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 38 def output raise 'Command not yet executed' unless defined? @output @output end
run()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 24 def run logger&.debug("Running command #{@command} with stdin #{@stdin.inspect}") if @interactive run_interactively else run_non_interactively end logger&.debug("output of the command:\n #{output}") end
success?()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 48 def success? @valid_exit_statuses.include? exit_status end
Private Instance Methods
full_command()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 95 def full_command "#{@command} 2>&1" end
run_interactively()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 61 def run_interactively # use tmp files to capture output and exit status of the command when # running interactively log_file = Tempfile.open('captured-output') exit_file = Tempfile.open('captured-exit-code') Kernel.system( "stdbuf -oL -eL bash -c '#{full_command}; echo $? > #{exit_file.path}'"\ "| tee -i #{log_file.path}" ) File.open(log_file.path) { |f| @output = f.read } File.open(exit_file.path) do |f| exit_status = f.read.strip @exit_status = if exit_status.empty? 256 else exit_status.to_i end end ensure log_file.close exit_file.close end
run_non_interactively()
click to toggle source
# File lib/foreman_maintain/utils/command_runner.rb, line 84 def run_non_interactively IO.popen(@env, full_command, 'r+') do |f| if @stdin f.puts(@stdin) f.close_write end @output = f.read.strip end @exit_status = $CHILD_STATUS.exitstatus end