mirror of
https://github.com/elastic/logstash.git
synced 2025-04-21 21:27:20 -04:00
71 lines
1.7 KiB
Ruby
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
|