Forked from
DM / dm-docs
261 commits behind, 825 commits ahead of the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
dmSubprocess.py 4.83 KiB
#!/usr/bin/env python
#
# Subprocess class
#
import os
import subprocess
import platform
from dm.common.utility.loggingManager import LoggingManager
from dm.common.exceptions.commandFailed import CommandFailed
#######################################################################
class DmSubprocess(subprocess.Popen):
# Get subprocess instance.
@classmethod
def getSubprocess(cls, command, cwd=None):
close_fds = True
if platform.system() != 'Windows':
close_fds = False
p = DmSubprocess(command, close_fds=close_fds, cwd=cwd)
return p
# Execute command
@classmethod
def executeCommand(cls, command, cwd=None):
""" Create subprocess and run it, return subprocess object. """
p = cls.getSubprocess(command, cwd)
p.run()
return p
# Execute command, ignore errors.
@classmethod
def executeCommandAndIgnoreFailure(cls, command, cwd=None):
""" Create subprocess, run it, igore any failures, and return subprocess object. """
p = cls.getSubprocess(command, cwd)
try:
p.run()
except CommandFailed, ex:
p.getLogger().debug('Command failed, stdout: %s, stderr: %s' % (p.getStdOut(), p.getStdErr()))
return p
@classmethod
def executeCommandAndLogToStdOut(cls, command, cwd=None):
""" Execute command, display output to stdout, maintain log file and return subprocess object. """
p = cls.getSubprocess(command, cwd)
p.__commandLog()
while True:
outp = p.stdout.readline()
if not outp:
break
print outp,
retval = p.wait()
p.logger.debug('Exit status: %s' % retval)
if retval != 0:
error = ''
while True:
err = p.stderr.readline()
if not err:
break
error += err
raise CommandFailed(error)
return p
def __init__(self, args, bufsize=0, executable=None, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=None, close_fds=False, shell=True, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, useExceptions=True, quietMode=False):
""" Overrides Popen constructor with more appropriate defaults. """
subprocess.Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags)
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
self._stdout = None
self._stderr = None
self._args = args
self._cwd = cwd
self.useExceptions = useExceptions
self.quietMode = quietMode
def __commandLog(self):
# Not very useful to show the name of this file.
# Walk up the stack to find the caller.
import traceback
stack = traceback.extract_stack()
for i in range(2, len(stack)):
if stack[-i][0] != stack[-1][0]:
fileName, lineNumber, functionName, text = stack[-i]
break
else:
fileName = lineNumber = functionName = text = '?'
self.logger.debug('From [%s:%s] Invoking: [%s]' % (os.path.basename(fileName), lineNumber, self._args))
def run(self, input=None):
""" Run subprocess. """
if not self.quietMode:
self.__commandLog()
(self._stdout, self._stderr) = subprocess.Popen.communicate(self, input)
if not self.quietMode:
self.logger.debug('Exit status: %s' % self.returncode)
if self.returncode != 0 and self.useExceptions:
if not self.quietMode:
self.logger.debug('StdOut: %s' % self._stdout)
self.logger.debug('StdErr: %s' % self._stderr)
error = self._stderr.strip()
if error == '':
error = self._stdout.strip()
raise CommandFailed('%s' % (error))
return (self._stdout, self._stderr)
def getLogger(self):
return self.logger
def getArgs(self):
return self._args
def getStdOut(self):
return self._stdout
def getStdErr(self):
return self._stderr
def getExitStatus(self):
return self.returncode
def toDict(self):
result = {
'command' : self._args,
'exitStatus' : self.returncode,
'stdErr' : self._stderr,
'stdOut' : self._stdout,
'workingDir' : self._cwd
}
return result
#######################################################################
# Testing.
if __name__ == '__main__':
p = DmSubprocess('ls -l', useExceptions=False)
print p.toDict()
p.run()
#print p.getStdOut()
#print p.getStdErr()
#print p.getExitStatus()
print p.toDict()