logstash/qa/vagrant/command.rb

71 lines
1.7 KiB
Ruby

# encoding: utf-8
require "open3"
require "bundler"
module LogStash
class CommandExecutor
class CommandError < StandardError; end
class CommandResponse
attr_reader :stdin, :stdout, :stderr, :exitstatus
def initialize(stdin, stdout, stderr, exitstatus)
@stdin = stdin
@stdout = stdout
@stderr = stderr
@exitstatus = exitstatus
end
def success?
exitstatus == 0
end
end
def self.run(cmd, debug=false)
# This block is require to be able to launch a ruby subprocess
# that use bundler.
Bundler.with_clean_env do
stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
stdout_acc, stderr_acc = "", ""
stdout_reporter = reporter(stdout, wait_thr) do |c|
stdout_acc << c
print c if debug
end
reporter(stderr, wait_thr) do |c|
stderr_acc << c;
print c if debug
end
stdout_reporter.join
CommandResponse.new(stdin, stdout_acc, stderr_acc, wait_thr.value.exitstatus)
end
end
# This method will raise an exception if the `CMD`
# was not run successfully and will display the content of STDERR
def self.run!(cmd, debug=false)
response = run(cmd, debug)
unless response.success?
raise CommandError, "CMD: #{cmd} STDERR: #{response.stderr}"
end
response
end
private
def self.reporter(io, wait_thr, &block)
Thread.new(io, wait_thr) do |_io, _wait_thr|
while (_wait_thr.status == "run")
begin
c = _io.read(1)
block.call(c) if c
rescue IO::WaitReadable
IO.select([_io])
retry
end
end
end
end
end
end