::oo_spawn(command, [, options]) -> [stdout, stderr, exit status]
spawn executes specified command and return its stdout, stderr and exit status. Or, raise exceptions if certain conditions are not met.
command: command line string which is passed to the standard shell
options: hash
:env: hash name => val : set the environment variable name => nil : unset the environment variable :unsetenv_others => true : clear environment variables except specified by :env :chdir => path : set current directory when running command :expected_exitstatus : An Integer value for the expected return code of command : If not set spawn() returns exitstatus from command otherwise : raise an error if exitstatus is not expected_exitstatus :timeout : Maximum number of seconds to wait for command to finish. default: 3600 :uid : spawn command as given user in a SELinux context using runuser/runcon, : stdin for the command is %rdev/ull
# File lib/openshift-origin-node/utils/shell_exec.rb, line 72 def self.oo_spawn(command, options = {}) options[:env] ||= {} options[:timeout] ||= 3600 options[:buffer_size] ||= 32768 opts = {} opts[:unsetenv_others] = (options[:unsetenv_others] ||= false) opts[:close_others] = true opts[:chdir] = options[:chdir] unless options[:chdir].nil? IO.pipe do |read_stderr, write_stderr| IO.pipe do |read_stdout, write_stdout| opts[:out] = write_stdout opts[:err] = write_stderr if options[:uid] # lazy init otherwise we end up with a cyclic require... require 'openshift-origin-node/model/unix_user' opts[:in] = '/dev/null' context = %Q{unconfined_u:system_r:openshift_t:#{UnixUser.get_mcs_label(options[:uid])}} name = Etc.getpwuid(options[:uid]).name command = %Q{/sbin/runuser -m -s /bin/sh #{name} -c "exec /usr/bin/runcon '#{context}' /bin/sh -c \\"#{command}\\""} end NodeLogger.trace_logger.debug { "oo_spawn running #{command}" } pid = Kernel.spawn(options[:env], command, opts) unless pid raise OpenShift::Utils::ShellExecutionException.new( "Kernel.spawn failed for command '#{command}'") end begin write_stdout.close write_stderr.close out, err, status = read_results(pid, read_stdout, read_stderr, options) NodeLogger.logger.debug { "Shell command '#{command}' ran. rc=#{status.exitstatus}" } if (!options[:expected_exitstatus].nil?) && (status.exitstatus != options[:expected_exitstatus]) raise OpenShift::Utils::ShellExecutionException.new( "Shell command '#{command}' returned an error. rc=#{status.exitstatus}", status.exitstatus, out, err) end return [out, err, status.exitstatus] rescue TimeoutExceeded => e ShellExec.kill_process_tree(pid) raise OpenShift::Utils::ShellExecutionException.new( "Shell command '#{command}'' exceeded timeout of #{e.seconds}", -1, out, err) end end end end