diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/lib/sos/helpers.py | 4 | ||||
-rw-r--r-- | src/lib/sos/plugintools.py | 20 | ||||
-rwxr-xr-x | src/lib/sos/policyredhat.py | 2 | ||||
-rwxr-xr-x | src/sosreport | 80 |
4 files changed, 98 insertions, 8 deletions
diff --git a/src/lib/sos/helpers.py b/src/lib/sos/helpers.py index 5524c0e4..8ba503c1 100755 --- a/src/lib/sos/helpers.py +++ b/src/lib/sos/helpers.py @@ -26,6 +26,7 @@ helper functions used by sosreport and plugins """ import os, popen2, fcntl, select, itertools, sys +from time import time from tempfile import mkdtemp def importPlugin(pluginname, name): @@ -60,6 +61,7 @@ def sosGetCommandOutput(command): """ Execute a command and gather stdin, stdout, and return status. Adapted from Python Cookbook - O'Reilly """ + stime = time() child = popen2.Popen3(command, 1) # Capture stdout and stderr from command child.tochild.close() # don't need to write to child's stdin outfile = child.fromchild @@ -89,7 +91,7 @@ def sosGetCommandOutput(command): break select.select([], [], [], .1) # Allow a little time for buffers to fill err = child.wait() - return (err, ''.join(outdata), ''.join(errdata)) + return (err, ''.join(outdata), ''.join(errdata), time()-stime) # this needs to be made clean and moved to the plugin tools, so diff --git a/src/lib/sos/plugintools.py b/src/lib/sos/plugintools.py index 5c301ed6..27203765 100644 --- a/src/lib/sos/plugintools.py +++ b/src/lib/sos/plugintools.py @@ -150,6 +150,7 @@ class PluginBase: try: dstslname, abspath = self.__copyFile(srcpath) self.copiedFiles.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link}) + self.cInfo['xmlreport'].add_file(srcpath,os.stat(srcpath)) except SystemExit: raise SystemExit except KeyboardInterrupt: @@ -194,7 +195,7 @@ class PluginBase: """ try: # pylint: disable-msg = W0612 - status, shout, sherr = sosGetCommandOutput("/bin/cp --parents -p " + src +" " + self.cInfo['dstroot']) + status, shout, sherr, runtime = sosGetCommandOutput("/bin/cp --parents -p " + src +" " + self.cInfo['dstroot']) if status: self.cInfo['soslog'].debug(shout) self.cInfo['soslog'].debug(sherr) @@ -277,7 +278,7 @@ class PluginBase: return # pylint: disable-msg = W0612 - status, shout, sherr = sosGetCommandOutput(prog) + status, shout, sherr, runtime = sosGetCommandOutput(prog) return status def runExe(self, exe): @@ -320,17 +321,28 @@ class PluginBase: return # pylint: disable-msg = W0612 - status, shout, sherr = sosGetCommandOutput(exe) + status, shout, sherr, runtime = sosGetCommandOutput(exe) outfn = self.makeCommandFilename(exe) outfd = open(outfn, "w") outfd.write(shout) outfd.close() - self.cInfo['soslog'].debug(sherr) + outfn = outfn[len(self.cInfo['cmddir'])+1:] + if len(sherr) > 0: + errfn = outfn + ".err" + outfd = open(errfn, "w") + outfd.write(sherr) + outfd.close() + errfn = errfn[len(self.cInfo['cmddir'] + "/" )+1:] + self.cInfo['soslog'].debug(sherr) + else: + errfn = None + # sosStatus(status) # save info for later self.executedCommands.append({'exe': exe, 'file':outfn}) # save in our list + self.cInfo['xmlreport'].add_command(cmdline=exe,exitcode=status,f_stdout=outfn,f_stderr=errfn,runtime=runtime) return outfn def writeTextToCommand(self, exe, text): diff --git a/src/lib/sos/policyredhat.py b/src/lib/sos/policyredhat.py index 08e0f9b3..80643576 100755 --- a/src/lib/sos/policyredhat.py +++ b/src/lib/sos/policyredhat.py @@ -111,7 +111,7 @@ class SosPolicy: os.chdir(ourtempdir) oldmask = os.umask(077) # pylint: disable-msg = W0612 - status, shout, sherr = sosGetCommandOutput(tarcmd) + status, shout, sherr, runtime = sosGetCommandOutput(tarcmd) os.umask(oldmask) os.chdir(curwd) os.system("/bin/mv %s %s" % (aliasdir, self.cInfo['dstroot'])) diff --git a/src/sosreport b/src/sosreport index 119f319e..1bf8b981 100755 --- a/src/sosreport +++ b/src/sosreport @@ -35,6 +35,9 @@ from snack import * from threading import Thread, activeCount, enumerate import signal import logging +from stat import * +from time import strftime, localtime +from pwd import getpwuid __breakHits__ = 0 # Use this to track how many times we enter the exit routine @@ -224,7 +227,74 @@ class progressBar: def update(self): sys.stdout.write(self.progBar + '\r') sys.stdout.flush() - + +class XmlReport: + def __init__(self): + try: + import libxml2 + except: + self.enabled = False + return + else: + self.enabled = True + self.doc = libxml2.newDoc("1.0") + self.root = self.doc.newChild(None, "sos", None) + self.commands = self.root.newChild(None, "commands", None) + self.files = self.root.newChild(None, "files", None) + + def add_command(self,cmdline,exitcode,stdout = None,stderr = None,f_stdout=None,f_stderr=None, runtime=None): + if not self.enabled: return + + cmd = self.commands.newChild(None, "cmd", None) + + cmd.setNsProp(None, "cmdline", cmdline) + + cmdchild = cmd.newChild(None, "exitcode", str(exitcode)) + + if runtime: + cmd.newChild(None, "runtime", str(runtime)) + + if stdout or f_stdout: + cmdchild = cmd.newChild(None, "stdout", stdout) + if f_stdout: + cmdchild.setNsProp(None, "file", f_stdout) + + if stderr or f_stderr: + cmdchild = cmd.newChild(None, "stderr", stderr) + if f_stderr: + cmdchild.setNsProp(None, "file", f_stderr) + + def add_file(self,fname,stats): + if not self.enabled: return + + cfile = self.files.newChild(None,"file",None) + + cfile.setNsProp(None, "fname", fname) + + cchild = cfile.newChild(None, "uid", str(stats[ST_UID])) + cchild.setNsProp(None,"name", getpwuid(stats[ST_UID])[0]) + cchild = cfile.newChild(None, "gid", str(stats[ST_GID])) + cchild.setNsProp(None,"name", getpwuid(stats[ST_GID])[0]) + cfile.newChild(None, "mode", str(oct(S_IMODE(stats[ST_MODE])))) + cchild = cfile.newChild(None, "ctime", strftime('%a %b %d %H:%M:%S %Y', localtime(stats[ST_CTIME]))) + cchild.setNsProp(None,"tstamp", str(stats[ST_CTIME])) + cchild = cfile.newChild(None, "atime", strftime('%a %b %d %H:%M:%S %Y', localtime(stats[ST_ATIME]))) + cchild.setNsProp(None,"tstamp", str(stats[ST_ATIME])) + cchild = cfile.newChild(None, "mtime", strftime('%a %b %d %H:%M:%S %Y', localtime(stats[ST_MTIME]))) + cchild.setNsProp(None,"tstamp", str(stats[ST_MTIME])) + + def serialize(self): + if not self.enabled: return + + print self.doc.serialize(None, 1) + + def serialize_to_file(self,fname): + if not self.enabled: return + + outfn = open(fname,"w") + outfn.write(self.doc.serialize(None,1)) + outfn.close() + def sosreport(): # pylint: disable-msg = R0912 # pylint: disable-msg = R0914 @@ -277,9 +347,12 @@ def sosreport(): logging.addLevelName(logging.VERBOSE3,"verbose3") soslog = logging.getLogger('') + xmlrep = XmlReport() + # set up dict so everyone can share the following commons = {'dstroot': dstroot, 'cmddir': cmddir, 'logdir': logdir, 'rptdir': rptdir, - 'soslog': soslog, 'policy': policy, 'verbosity' : __cmdLineOpts__.verbosity} + 'soslog': soslog, 'policy': policy, 'verbosity' : __cmdLineOpts__.verbosity, + 'xmlreport' : xmlrep } # Make policy aware of the commons @@ -392,6 +465,9 @@ def sosreport(): pbar.incAmount(30) pbar.update() + xmlrep.serialize() + xmlrep.serialize_to_file(rptdir + "/" + "sosreport.xml") + # Wait for all the collection threads to exit if __cmdLineOpts__.multithread: for plugname, plug in loadedplugins: |