nginx-amplify-agent/amplify/agent/common/util/subp.py

56 lines
1.8 KiB
Python

# -*- coding: utf-8 -*-
import subprocess
from amplify.agent.common.errors import AmplifySubprocessError
__author__ = "Mike Belov"
__copyright__ = "Copyright (C) Nginx, Inc. All rights reserved."
__license__ = ""
__maintainer__ = "Mike Belov"
__email__ = "dedm@nginx.com"
def call(command, check=True):
"""
Calls subprocess.Popen with the command
:param command: full shell command
:param check: check the return code or not
:return: subprocess stdout [], stderr [] - both as lists
"""
subprocess_params = dict(
shell=True,
universal_newlines=True,
encoding='utf-8',
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
process = subprocess.Popen(command, **subprocess_params)
try:
raw_out, raw_err = process.communicate()
if process.returncode != 0 and check:
raise AmplifySubprocessError(message=command, payload=dict(returncode=process.returncode, error=raw_err))
else:
if type(raw_out) == bytes:
raw_out = raw_out.decode('utf-8')
if type(raw_err) == bytes:
raw_err = raw_err.decode('utf-8')
out = raw_out.split('\n')
err = raw_err.split('\n')
return out, err
except:
raise
finally:
# warning: if GreenletExit was the original exception thrown, no other raised exception in this
# finally block should be left unhandled
# in the case of multiple greenlets trying to run and read from and close stdout/stderr,
# this can lead to RuntimeError: reentrant calls. Watch for exception and ignore
for pipe in (process.stdin, process.stdout, process.stderr):
try:
pipe.close()
except:
pass