diff options
Diffstat (limited to 'lib/oxidized/hook/exec.rb')
-rw-r--r-- | lib/oxidized/hook/exec.rb | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/lib/oxidized/hook/exec.rb b/lib/oxidized/hook/exec.rb new file mode 100644 index 0000000..eb71466 --- /dev/null +++ b/lib/oxidized/hook/exec.rb @@ -0,0 +1,84 @@ +class Exec < Oxidized::Hook + include Process + + def initialize + super + @timeout = 60 + @async = false + end + + def validate_cfg! + # Syntax check + if cfg.has_key? "timeout" + @timeout = cfg.timeout + raise "invalid timeout value" unless @timeout.is_a?(Integer) && + @timeout > 0 + end + + if cfg.has_key? "async" + @async = !!cfg.async + end + + if cfg.has_key? "cmd" + @cmd = cfg.cmd + raise "invalid cmd value" unless @cmd.is_a?(String) || @cmd.is_a?(Array) + end + + rescue RuntimeError => e + raise ArgumentError, + "#{self.class.name}: configuration invalid: #{e.message}" + end + + def run_hook ctx + env = make_env ctx + log "Execute: #{@cmd.inspect}", :debug + th = Thread.new do + begin + run_cmd! env + rescue => e + raise e unless @async + end + end + th.join unless @async + end + + def run_cmd! env + pid, status = nil, nil + Timeout.timeout(@timeout) do + pid = spawn env, @cmd , :unsetenv_others => true + pid, status = wait2 pid + unless status.exitstatus.zero? + msg = "#{@cmd.inspect} failed with exit value #{status.exitstatus}" + log msg, :error + raise msg + end + end + rescue TimeoutError + kill "TERM", pid + msg = "#{@cmd} timed out" + log msg, :error + raise TimeoutError, msg + end + + def make_env ctx + env = { + "OX_EVENT" => ctx.event.to_s + } + if ctx.node + env.merge!( + "OX_NODE_NAME" => ctx.node.name.to_s, + "OX_NODE_FROM" => ctx.node.from.to_s, + "OX_NODE_MSG" => ctx.node.msg.to_s, + "OX_NODE_GROUP" => ctx.node.group.to_s, + "OX_EVENT" => ctx.event.to_s, + ) + end + if ctx.job + env.merge!( + "OX_JOB_STATUS" => ctx.job.status.to_s, + "OX_JOB_TIME" => ctx.job.time.to_s, + ) + end + env + end +end |