module OpenShift::Utils::ShellExec

Public Class Methods

kill_process_tree(pid) click to toggle source

::kill_process_tree 2199 -> fixnum

Given a pid find it and KILL it and all it's children

# File lib/openshift-origin-node/utils/shell_exec.rb, line 246
def self.kill_process_tree(pid)
  ps_results = %xps -e -opid,ppid --no-headers`.split("\n")

  ps_tree = Hash.new { |h, k| h[k] = [k] }
  ps_results.each { |pair|
    p, pp = pair.split(' ')
    ps_tree[pp.to_i] << p.to_i
  }
  Process.kill("KILL", *(ps_tree[pid].flatten))
end
run_as(uid, gid, cmd, pwd = ".", ignore_err = true, expected_rc = 0, timeout = 3600) click to toggle source
# File lib/openshift-origin-node/utils/shell_exec.rb, line 257
def self.run_as(uid, gid, cmd, pwd = ".", ignore_err = true, expected_rc = 0, timeout = 3600)
  mcs_level, err, rc = OpenShift::Utils::ShellExec.shellCmd("/usr/bin/oo-get-mcs-level #{uid}", pwd, true, 0, timeout)
  raise OpenShift::Utils::ShellExecutionException.new(
            "Shell command '#{cmd}' returned an error. rc=#{rc}. output=#{err}", rc, mcs_level, err) if 0 != rc

  command = "/usr/bin/runcon -r system_r -t openshift_t -l #{mcs_level.chomp} #{cmd}"
  pid     = fork {
    Process::GID.change_privilege(gid.to_i)
    Process::UID.change_privilege(uid.to_i)
    out, err, rc = OpenShift::Utils::ShellExec.shellCmd(command, pwd, true, 0, timeout)
    exit $?.exitstatus
  }

  if pid
    Process.wait(pid)
    rc = $?.exitstatus
    if !ignore_err and rc != expected_rc
      raise OpenShift::Utils::ShellExecutionException.new(
                "Shell command '#{command}' returned an error. rc=#{rc}", rc)
    end
    return rc
  else
    raise OpenShift::Utils::ShellExecutionException.new(
              "Shell command '#{command}' fork failed in run_as().")
  end
end
shellCmd(cmd, pwd = ".", ignore_err = true, expected_rc = 0, timeout = 3600) click to toggle source

Public: Execute shell command.

iv - A String value for the IV file. cmd - A String value of the command to run. pwd - A String value of target working directory. ignore_err - A Boolean value to determine if errors should be ignored. expected_rc - A Integer value for the expected return code of cmd.

Examples

OpenShift::Utils::ShellExec.shellCmd('ls /etc/passwd')
# => ["/etc/passwd\n","", 0]

Returns An Array with [stdout, stderr, return_code]

# File lib/openshift-origin-node/utils/shell_exec.rb, line 198
def self.shellCmd(cmd, pwd = ".", ignore_err = true, expected_rc = 0, timeout = 3600)
  out = err = rc = nil
  begin
    # Using Open4 spawn with cwd isn't thread safe
    m_cmd                      = "cd #{pwd} && ( #{cmd} )"
    pid, stdin, stdout, stderr = Open4.popen4ext(true, m_cmd)
    begin
      stdin.close
      out   = err = ""
      fds   = [stdout, stderr]
      buffs = {stdout.fileno => out, stderr.fileno => err}
      Timeout::timeout(timeout) do
        while not fds.empty?
          rs, ws, es = IO.select(fds, nil, nil)
          rs.each do |f|
            begin
              buffs[f.fileno] << f.read_nonblock(4096)
            rescue IO::WaitReadable, IO::WaitWritable # Wait in next select
            rescue EOFError
              fds.delete_if { |item| item.fileno == f.fileno }
            end
          end
        end
      end
    rescue Timeout::Error
      kill_process_tree(pid)
      raise ShellExecutionException.new(
                "Shell command '#{cmd}'' timed out (timeout is #{timeout})", -1, out, err)
    ensure
      stdout.close
      stderr.close
      rc = Process::waitpid2(pid)[1].exitstatus
    end
  rescue Exception => e
    raise OpenShift::Utils::ShellExecutionException.new(e.message, rc, out, err
          ) 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, out, err)
  end
  return [out, err, rc]
end

Public Instance Methods

shellCmd(cmd, pwd = ".", ignore_err = true, expected_rc = 0, timeout = 3600) click to toggle source
# File lib/openshift-origin-node/utils/shell_exec.rb, line 181
def shellCmd(cmd, pwd = ".", ignore_err = true, expected_rc = 0, timeout = 3600)
  OpenShift::Utils::ShellExec.shellCmd(cmd, pwd, ignore_err, expected_rc, timeout)
end