lib/rcs-common/updater/payload.rb
require 'timeout'
require 'fileutils'
require 'open3'
require_relative "tmp_dir"
require_relative "../trace.rb"
module RCS
module Updater
class Payload
include RCS::Tracer
include TmpDir
attr_reader :options, :payload, :timeout
attr_reader :filepath, :output, :return_code, :stored
DEFAULT_TIMEOUT = 600
def initialize(payload, options = {})
@options = options
@payload = payload
@timeout = options['timeout'].to_i
@timeout = DEFAULT_TIMEOUT if @timeout <= 0
end
def ruby?; options['ruby']; end
def storable?; options['store']; end
def spawn?; options['spawn']; end
def runnable?
options['exec'] or ruby? or spawn?
end
def [](name)
instance_variable_get("@#{name}")
end
def run
@return_code = nil
@output = ""
cmd = "#{'ruby ' if ruby?}#{storable? ? filepath : payload}"
if spawn?
trace(:debug, "[spawn] #{cmd}")
return spawn(cmd)
end
Timeout::timeout(@timeout) do
trace(:debug, "Timeout has been set to #{@timeout} sec") if @timeout != DEFAULT_TIMEOUT
trace(:debug, "[popen] #{cmd}")
Open3.popen2e(cmd) do |stdin, std_out_err, wait_thr|
while line = std_out_err.gets
trace(:debug, "[std_out_err] #{line.strip}")
@output << line
end
@return_code = wait_thr.value.exitstatus
end
end
return @return_code
ensure
FileUtils.rm_f(filepath) if stored
end
def store
@filepath = "#{tmpdir}/" + (@options['filename'] || Time.now.to_f.to_s.gsub(".", ""))
FileUtils.mkdir_p(tmpdir)
trace(:debug, "Storing payload into #{filepath}")
File.open(filepath, "wb") { |f| f.write(payload) }
@stored = true
end
end
end
end