def execute(*cmd, **kwargs): process_input = kwargs.pop('process_input', None) check_exit_code = kwargs.pop('check_exit_code', [0]) cwd = kwargs.pop('cwd', None) env_overrides = kwargs.pop('env_overrides', None) close_stdin = kwargs.pop('close_stdin', False) ignore_exit_code = False if isinstance(check_exit_code, bool): ignore_exit_code = not check_exit_code check_exit_code = [0] elif isinstance(check_exit_code, int): check_exit_code = [check_exit_code] run_as_root = kwargs.pop('run_as_root', False) shell = kwargs.pop('shell', False) execute_cmd = list() for c in cmd: execute_cmd.append(str(c)) str_cmd = " ".join(execute_cmd) if shell: execute_cmd = str_cmd.strip() if not shell: LOG.debug('Running cmd: %s' % (execute_cmd)) else: LOG.debug('Running shell cmd: %s' % (execute_cmd)) if process_input is not None: LOG.debug('With stdin: %s' % (process_input)) if cwd: LOG.debug("In working directory: %s" % (cwd)) stdin_fh = subprocess.PIPE stdout_fh = subprocess.PIPE stderr_fh = subprocess.PIPE close_file_descriptors = True if 'stdout_fh' in kwargs.keys(): stdout_fh = kwargs.get('stdout_fh') LOG.debug("Redirecting stdout to file handle: %s" % (stdout_fh)) if 'stdin_fh' in kwargs.keys(): stdin_fh = kwargs.get('stdin_fh') LOG.debug("Redirecting stdin to file handle: %s" % (stdin_fh)) process_input = None if 'stderr_fh' in kwargs.keys(): stderr_fh = kwargs.get('stderr_fh') LOG.debug("Redirecting stderr to file handle: %s" % (stderr_fh)) process_env = None if env_overrides and len(env_overrides): process_env = env.get() LOG.debug("With additional environment overrides: %s" % (env_overrides)) for (k, v) in env_overrides.items(): process_env[k] = str(v) rc = None result = None with Rooted(run_as_root): obj = subprocess.Popen(execute_cmd, stdin=stdin_fh, stdout=stdout_fh, stderr=stderr_fh, close_fds=close_file_descriptors, cwd=cwd, shell=shell, env=process_env) if process_input is not None: result = obj.communicate(str(process_input)) else: result = obj.communicate() if (stdin_fh != subprocess.PIPE and obj.stdin and close_stdin): obj.stdin.close() rc = obj.returncode LOG.debug('Cmd result had exit code: %s' % rc) if (not ignore_exit_code) and (rc not in check_exit_code): (stdout, stderr) = result raise excp.ProcessExecutionError( exit_code=rc, stdout=stdout, stderr=stderr, cmd=str_cmd) else: #log it anyway if rc not in check_exit_code: (stdout, stderr) = result LOG.debug("A failure may of just happened when running command \"%s\" [%s] (%s, %s)", str_cmd, rc, stdout.strip(), stderr.strip()) return result
def execute(*cmd, **kwargs): process_input = kwargs.pop('process_input', None) check_exit_code = kwargs.pop('check_exit_code', [0]) cwd = kwargs.pop('cwd', None) env_overrides = kwargs.pop('env_overrides', None) close_stdin = kwargs.pop('close_stdin', False) ignore_exit_code = kwargs.pop('ignore_exit_code', False) if isinstance(check_exit_code, bool): ignore_exit_code = not check_exit_code check_exit_code = [0] elif isinstance(check_exit_code, int): check_exit_code = [check_exit_code] run_as_root = kwargs.pop('run_as_root', False) shell = kwargs.pop('shell', False) execute_cmd = list() for c in cmd: execute_cmd.append(str(c)) str_cmd = " ".join(execute_cmd) if shell: execute_cmd = str_cmd.strip() if not shell: LOG.audit('Running cmd: %s' % (execute_cmd)) else: LOG.audit('Running shell cmd: %s' % (execute_cmd)) if process_input is not None: LOG.audit('With stdin: %s' % (process_input)) if cwd: LOG.audit("In working directory: %s" % (cwd)) stdin_fh = subprocess.PIPE stdout_fh = subprocess.PIPE stderr_fh = subprocess.PIPE close_file_descriptors = True if 'stdout_fh' in kwargs.keys(): stdout_fh = kwargs.get('stdout_fh') LOG.debug("Redirecting stdout to file handle: %s" % (stdout_fh)) if 'stdin_fh' in kwargs.keys(): stdin_fh = kwargs.get('stdin_fh') LOG.debug("Redirecting stdin to file handle: %s" % (stdin_fh)) process_input = None if 'stderr_fh' in kwargs.keys(): stderr_fh = kwargs.get('stderr_fh') LOG.debug("Redirecting stderr to file handle: %s" % (stderr_fh)) process_env = None if env_overrides and len(env_overrides): process_env = env.get() LOG.audit("With additional environment overrides: %s" % (env_overrides)) for (k, v) in env_overrides.items(): process_env[k] = str(v) rc = None result = None with Rooted(run_as_root): if DRYRUN_MODE: rc = DRY_RC result = DRY_STDOUT_ERR else: try: obj = subprocess.Popen(execute_cmd, stdin=stdin_fh, stdout=stdout_fh, stderr=stderr_fh, close_fds=close_file_descriptors, cwd=cwd, shell=shell, env=process_env) if process_input is not None: result = obj.communicate(str(process_input)) else: result = obj.communicate() except OSError as e: error_description = "%s: [%s, %s]" % (e.message, e.errno, e.strerror) raise excp.ProcessExecutionError(description=error_description, cmd=str_cmd) if (stdin_fh != subprocess.PIPE and obj.stdin and close_stdin): obj.stdin.close() rc = obj.returncode LOG.audit('Cmd result had exit code: %s' % rc) if not result: result = ("", "") (stdout, stderr) = result if stdout is None: stdout = '' if stderr is None: stderr = '' if (not ignore_exit_code) and (rc not in check_exit_code): raise excp.ProcessExecutionError(exit_code=rc, stdout=stdout, \ stderr=stderr, cmd=str_cmd) else: # Log it anyway if rc not in check_exit_code: LOG.debug("A failure may of just happened when running command \"%s\" [%s] (%s, %s)", \ str_cmd, rc, stdout.strip(), stderr.strip()) # Log for debugging figuring stuff out LOG.debug("Received stdout: %s" % (stdout.strip())) LOG.debug("Received stderr: %s" % (stderr.strip())) return (stdout, stderr)