mirror of
https://github.com/elastic/logstash.git
synced 2025-04-25 07:07:54 -04:00
87 lines
2.5 KiB
Ruby
87 lines
2.5 KiB
Ruby
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
# license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright
|
|
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
# the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
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_unbundled_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
|