def self.shellCmd(cmd, pwd = ".", ignore_err = true, expected_rc = 0, timeout = 3600)
out = err = rc = nil
begin
m_cmd = "cd #{pwd} && ( #{cmd} )"
pid, stdin, stdout, stderr = Open4.popen4ext(true, m_cmd)
begin
stdin.close
Timeout::timeout(timeout) do
out = stdout.read
err = stderr.read
end
rescue Timeout::Error
pstree = Hash.new{|a,b| a[b]=[b]}
pppids = Hash[*`ps -e -opid,ppid --no-headers`.map{|p| p.to_i}]
pppids.each do |l_pid, l_ppid|
pstree[l_ppid] << pstree[l_pid]
end
Process.kill("KILL", *(pstree[pid].flatten))
raise OpenShift::Utils::ShellExecutionException.new("command timed out")
ensure
stdout.close
stderr.close
rc = Process::waitpid2(pid)[1].exitstatus
end
rescue Exception => e
raise OpenShift::Utils::ShellExecutionException.new(e.message
) unless ignore_err
end
if !ignore_err and rc != expected_rc
raise OpenShift::Utils::ShellExecutionException.new(
"Shell command '#{cmd}' returned an error. rc=#{rc}", rc)
end
return [out, err, rc]
end