From ae336e387650fbe872ede117dce7cb5078b2f234 Mon Sep 17 00:00:00 2001 From: sconklin Date: Wed, 16 Aug 2006 19:22:12 +0000 Subject: lint removal only wait for threads if we're running threaded git-svn-id: svn+ssh://svn.fedorahosted.org/svn/sos/trunk@42 ef72aa8b-4018-0410-8976-d6e080ef94d8 --- src/lib/sos/helpers.py | 38 ++++++++------- src/lib/sos/plugintools.py | 118 ++++++++++++++++++++++++++++++--------------- 2 files changed, 99 insertions(+), 57 deletions(-) (limited to 'src/lib') diff --git a/src/lib/sos/helpers.py b/src/lib/sos/helpers.py index 447c164f..5524c0e4 100755 --- a/src/lib/sos/helpers.py +++ b/src/lib/sos/helpers.py @@ -22,11 +22,12 @@ ## (O'Reilly Media, 2005) 0-596-00797-3 ## +""" +helper functions used by sosreport and plugins +""" import os, popen2, fcntl, select, itertools, sys from tempfile import mkdtemp -workingBase = None - def importPlugin(pluginname, name): """ Import a plugin to extend capabilities of sosreport """ @@ -45,14 +46,14 @@ def sosFindTmpDir(): return workingBase -def makeNonBlocking(fd): +def makeNonBlocking(afd): """ Make the file desccriptor non-blocking. This prevents deadlocks. """ - fl = fcntl.fcntl(fd, fcntl.F_GETFL) + fl = fcntl.fcntl(afd, fcntl.F_GETFL) try: - fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY) + fcntl.fcntl(afd, fcntl.F_SETFL, fl | os.O_NDELAY) except AttributeError: - fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.FNDELAY) + fcntl.fcntl(afd, fcntl.F_SETFL, fl | os.FNDELAY) def sosGetCommandOutput(command): @@ -86,12 +87,12 @@ def sosGetCommandOutput(command): errdata.append(errchunk) if outeof and erreof: break - select.select([],[],[],.1) # Allow a little time for buffers to fill + select.select([], [], [], .1) # Allow a little time for buffers to fill err = child.wait() return (err, ''.join(outdata), ''.join(errdata)) -# TODO - this needs to be made clean and moved to the plugin tools, so +# this needs to be made clean and moved to the plugin tools, so # that it prints nice color output like sysreport def sosStatus(stat): """ Complete a status line that has been output to the console, @@ -109,7 +110,8 @@ def allEqual(elements): ''' return True if all the elements are equal, otherwise False. ''' first_element = elements[0] for other_element in elements[1:]: - if other_element != first_element: return False + if other_element != first_element: + return False return True @@ -117,24 +119,26 @@ def commonPrefix(*sequences): ''' return a list of common elements at the start of all sequences, then a list of lists that are the unique tails of each sequence. ''' # if there are no sequences at all, we're done - if not sequences: return [], [] + if not sequences: + return [], [] # loop in parallel on the sequences common = [] for elements in itertools.izip(*sequences): # unless all elements are equal, bail out of the loop - if not allEqual(elements): break + if not allEqual(elements): + break # got one more common element, append it and keep looping common.append(elements[0]) # return the common prefix and unique tails return common, [ sequence[len(common):] for sequence in sequences ] -def sosRelPath(p1, p2, sep=os.path.sep, pardir=os.path.pardir): - ''' return a relative path from p1 equivalent to path p2. - In particular: the empty string, if p1 == p2; - p2, if p1 and p2 have no common prefix. +def sosRelPath(path1, path2, sep=os.path.sep, pardir=os.path.pardir): + ''' return a relative path from path1 equivalent to path path2. + In particular: the empty string, if path1 == path2; + path2, if path1 and path2 have no common prefix. ''' - common, (u1, u2) = commonPrefix(p1.split(sep), p2.split(sep)) + common, (u1, u2) = commonPrefix(path1.split(sep), path2.split(sep)) if not common: - return p2 # leave path absolute if nothing at all in common + return path2 # leave path absolute if nothing at all in common return sep.join( [pardir]*len(u1) + u2 ) diff --git a/src/lib/sos/plugintools.py b/src/lib/sos/plugintools.py index 3e788199..ac057dba 100644 --- a/src/lib/sos/plugintools.py +++ b/src/lib/sos/plugintools.py @@ -17,6 +17,17 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# pylint: disable-msg = R0902 +# pylint: disable-msg = R0904 +# pylint: disable-msg = W0702 +# pylint: disable-msg = W0703 +# pylint: disable-msg = R0201 +# pylint: disable-msg = W0611 +# pylint: disable-msg = W0613 + +""" +This is the base class for sosreport plugins +""" from sos.helpers import * from threading import Thread import os, os.path, sys, string, itertools, glob @@ -26,10 +37,12 @@ class PluginBase: Base class for plugins """ def __init__(self, pluginname, commons): + # pylint: disable-msg = E0203 try: - foo = len(self.optionList) + len(self.optionList) except: self.optionList = [] + # pylint: enable-msg = E0203 self.copiedFiles = [] self.copiedDirs = [] self.executedCommands = [] @@ -42,15 +55,17 @@ class PluginBase: self.forbiddenPaths = [] self.copyPaths = [] self.collectProgs = [] + self.thread = None # get the option list into a dictionary for opt in self.optionList: self.optNames.append(opt[0]) self.optParms.append({'desc':opt[1], 'speed':opt[2], 'enabled':opt[3]}) - return # Methods for copying files and shelling out def doCopyFileOrDir(self, srcpath): + # pylint: disable-msg = R0912 + # pylint: disable-msg = R0915 ''' Copy file or directory to the destination tree. If a directory, then everything below it is recursively copied. A list of copied files are saved for use later in preparing a report @@ -62,7 +77,7 @@ class PluginBase: if copyProhibited: sys.stderr.write("%s is on the copyProhibited list\n" % srcpath) - sys.stderr.flush + sys.stderr.flush() return '' if os.path.islink(srcpath): @@ -90,49 +105,49 @@ class PluginBase: dstslname = link if os.path.isdir(srcpath): - for file in os.listdir(srcpath): - if file == '.' or file == '..': + for afile in os.listdir(srcpath): + if afile == '.' or afile == '..': pass else: try: - abspath = self.doCopyFileOrDir(srcpath+'/'+file) + abspath = self.doCopyFileOrDir(srcpath+'/'+afile) except: - sys.stderr.write("1Problem at path %s\n" % srcpath+'/'+file,) - sys.stderr.flush() + sys.stderr.write("1Problem at path %s\n" % srcpath+'/'+afile,) + sys.stderr.flush() # if on forbidden list, abspath is null if not abspath == '': dstslname = sosRelPath(self.cInfo['rptdir'], abspath) self.copiedDirs.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link}) else: try: - dstslname, abspath = self.__copyFile(srcpath) + dstslname, abspath = self.__copyFile(srcpath) except: - sys.stderr.write("2Problem at path %s\n" % srcpath) - sys.stderr.flush() + sys.stderr.write("2Problem at path %s\n" % srcpath) + sys.stderr.flush() self.copiedFiles.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link}) # Recurse to copy whatever it points to newpath = os.path.normpath(os.path.join(os.path.dirname(srcpath), link)) try: - self.doCopyFileOrDir(newpath) + self.doCopyFileOrDir(newpath) except: - sys.stderr.write("3Problem at path %s" % newpath,) - sys.stderr.flush + sys.stderr.write("3Problem at path %s" % newpath,) + sys.stderr.flush() return abspath else: if not os.path.exists(srcpath): self.cInfo['logfd'].write("File or directory %s does not exist\n" % srcpath) elif os.path.isdir(srcpath): - for file in os.listdir(srcpath): - if file == '.' or file == '..': + for afile in os.listdir(srcpath): + if afile == '.' or afile == '..': pass else: - self.doCopyFileOrDir(srcpath+'/'+file) + self.doCopyFileOrDir(srcpath+'/'+afile) else: # This is not a directory or a symlink tdstpath, abspath = self.__copyFile(srcpath) - self.copiedFiles.append({'srcpath':srcpath, 'dstpath':tdstpath,'symlink':"no"}) # save in our list + self.copiedFiles.append({'srcpath':srcpath, 'dstpath':tdstpath, 'symlink':"no"}) # save in our list return abspath def __copyFile(self, src): @@ -140,16 +155,16 @@ class PluginBase: destination file name. """ try: - status, shout, sherr = sosGetCommandOutput("/bin/cp --parents " + src +" " + self.cInfo['dstroot']) - self.cInfo['logfd'].write(shout) - self.cInfo['logfd'].write(sherr) - #sosStatus(status) - abspath = os.path.join(self.cInfo['dstroot'], src.lstrip(os.path.sep)) - relpath = sosRelPath(self.cInfo['rptdir'], abspath) - return relpath, abspath + # pylint: disable-msg = W0612 + status, shout, sherr = sosGetCommandOutput("/bin/cp --parents " + src +" " + self.cInfo['dstroot']) + self.cInfo['logfd'].write(shout) + self.cInfo['logfd'].write(sherr) + abspath = os.path.join(self.cInfo['dstroot'], src.lstrip(os.path.sep)) + relpath = sosRelPath(self.cInfo['rptdir'], abspath) + return relpath, abspath except Exception,e: - sys.stderr.write("4Problem copying file %s\n" % src,) - print e + sys.stderr.write("4Problem copying file %s\n" % src,) + print e def addForbiddenPath(self, forbiddenPath): """Specify a path to not copy, even if it's part of a copyPaths[] entry. @@ -158,6 +173,9 @@ class PluginBase: self.forbiddenPaths.append(forbiddenPath) def getAllOptions(self): + """ + return a list of all options selected + """ return (self.optNames, self.optParms) def setOption(self, optionname, enable): @@ -182,7 +200,7 @@ class PluginBase: """ # Glob case handling is such that a valid non-glob is a reduced glob for filespec in glob.glob(copyspec): - self.copyPaths.append(filespec) + self.copyPaths.append(filespec) def copyFileGlob(self, srcglob): """ Deprecated - please modify modules to use addCopySpec() @@ -197,7 +215,7 @@ class PluginBase: sys.stderr.write("Warning: the copyFileOrDir() function has been deprecated. Please\n") sys.stderr.write("use addCopySpec() instead. Calling addCopySpec() now.\n") raise ValueError - self.addCopySpec(srcpath) + #self.addCopySpec(srcpath) def runExeInd(self, exe): """ Deprecated - use callExtProg() @@ -214,7 +232,8 @@ class PluginBase: # First check to make sure the binary exists and is runnable. if not os.access(prog.split()[0], os.X_OK): return - + + # pylint: disable-msg = W0612 status, shout, sherr = sosGetCommandOutput(prog) return status @@ -226,6 +245,9 @@ class PluginBase: pass def collectExtOutput(self, exe): + """ + Run a program and collect the output + """ self.collectProgs.append(exe) def collectOutputNow(self, exe): @@ -236,6 +258,7 @@ class PluginBase: if not os.access(exe.split()[0], os.X_OK): return + # pylint: disable-msg = W0612 status, shout, sherr = sosGetCommandOutput(exe) # build file name for output @@ -277,13 +300,22 @@ class PluginBase: return def doCollect(self, verbosity): - self.thread = Thread(target=self.copyStuff,name=self.piName+'-thread',args=(verbosity,)) + """ + create a thread which calls the copyStuff method for a plugin + """ + self.thread = Thread(target=self.copyStuff, name=self.piName+'-thread', args=(verbosity,)) self.thread.start() def wait(self): + """ + wait for a thread to complete - only called for threaded execution + """ self.thread.join() def copyStuff(self, verbosity): + """ + Collect the data for a plugin + """ for path in self.copyPaths: try: self.doCopyFileOrDir(path) @@ -311,16 +343,22 @@ class PluginBase: pass def analyze(self, verbosity): + """ + perform any analysis. To be replaced by a plugin if desired + """ pass def postproc(self, dstroot): + """ + perform any postprocessing. To be replaced by a plugin if desired + """ pass def report(self): """ Present all information that was gathered in an html file that allows browsing the results. """ - # TODO make this prettier, this is a first pass + # make this prettier html = '
\n' % self.piName # Intro @@ -329,20 +367,20 @@ class PluginBase: # Files if len(self.copiedFiles): html = html + "

Files copied:

\n" # Dirs if len(self.copiedDirs): html = html + "

Directories Copied:

\n" -- cgit