diff options
author | Anton Aksola <anton.aksola@nebula.fi> | 2015-08-28 11:05:18 +0300 |
---|---|---|
committer | Anton Aksola <anton.aksola@nebula.fi> | 2015-08-28 11:05:18 +0300 |
commit | 0906e02a8538b698ed8bd7c72e6a09d3e809b67a (patch) | |
tree | d494ee43f71d41034efa98f5b5ab59ab5500207a /lib/oxidized/hook | |
parent | 18cf96b36e54cb52c678e4e6395e595b6f9b4159 (diff) |
Initial implementation of the hook feature
The current implementation is modular and allows users to define hooks
in several ways:
* Use one of the built-in hook types (currently only 'exec')
* Define their own Hook classes inside ~/.config/oxidized/hook
Exec hook type runs a user defined command with or without shell. It
populates a bunch of environment variables with metadata. The command
can either be run as synchronous or asynchronous. The default is
synchronous.
Diffstat (limited to 'lib/oxidized/hook')
-rw-r--r-- | lib/oxidized/hook/exec.rb | 84 | ||||
-rw-r--r-- | lib/oxidized/hook/noophook.rb | 9 |
2 files changed, 93 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 diff --git a/lib/oxidized/hook/noophook.rb b/lib/oxidized/hook/noophook.rb new file mode 100644 index 0000000..d4673ba --- /dev/null +++ b/lib/oxidized/hook/noophook.rb @@ -0,0 +1,9 @@ +class NoopHook < Oxidized::Hook + def validate_cfg! + log "Validate config" + end + + def run_hook ctx + log "Run hook with context: #{ctx}" + end +end |