diff options
Diffstat (limited to 'trunk/src/sosreport')
-rwxr-xr-x | trunk/src/sosreport | 725 |
1 files changed, 0 insertions, 725 deletions
diff --git a/trunk/src/sosreport b/trunk/src/sosreport deleted file mode 100755 index 86d66b4d..00000000 --- a/trunk/src/sosreport +++ /dev/null @@ -1,725 +0,0 @@ -#!/usr/bin/env python -""" -Gather information about a system and report it using plugins -supplied for application-specific information -""" -## sosreport.py -## gather information about a system and report it - -## Copyright (C) 2006 Steve Conklin <sconklin@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -# pylint: disable-msg = W0611 -# pylint: disable-msg = W0702 - -import sys -import os -#import curses -from optparse import OptionParser, Option -import sos.policyredhat -from sos.helpers import * -from snack import * -from threading import Thread, activeCount, enumerate -import signal -import logging -from stat import * -from time import strftime, localtime, time -from pwd import getpwuid -import gettext -from threading import Semaphore - -__version__ = 1.7 - -__breakHits__ = 0 # Use this to track how many times we enter the exit routine - -## Set up routines to be linked to signals for termination handling -def exittermhandler(signum, frame): - doExitCode() - -def doExitCode(): - global __breakHits__ - __breakHits__ += 1 - if ( ( activeCount() > 1 ) and ( __breakHits__ == 1 ) ): - print "SIGTERM received, multiple threads detected, waiting for all threads to exit" - for thread in enumerate(): - if thread.getName() != "MainThread": - thread.join() - print "All threads ended, cleaning up." - if ( ( activeCount() > 1 ) and ( __breakHits__ > 1 ) ): - print "Multiple SIGTERMs, multiple threads, attempting to signal threads to die immediately" - ## FIXME: Add thread-kill code (see FIXME below) - print "Threads dead, cleaning up." - if ( ( activeCount() == 1 ) and ( __breakHits__ > 2 ) ): - print "Multiple SIGTERMs, single thread, exiting without cleaning up." - sys.exit(3) - - # FIXME: Add code here to clean up /tmp - sys.exit("Abnormal exit") - -# Handle any sort of exit signal cleanly -# Currently, we intercept only sig 15 (TERM) -signal.signal(signal.SIGTERM, exittermhandler) - -## FIXME: Need to figure out how to IPC with child threads in case of -## multiple SIGTERMs. -## FIXME: Need to figure out how to handle SIGKILL - we can't intercept it. - -# for debugging -__raisePlugins__ = 1 - -class SosOption (Option): - """Allow to specify comma delimited list of plugins""" - ACTIONS = Option.ACTIONS + ("extend",) - STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",) - TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",) - - def take_action(self, action, dest, opt, value, values, parser): - if action == "extend": - try: lvalue = value.split(",") - except: pass - else: values.ensure_value(dest, []).extend(lvalue) - else: - Option.take_action(self, action, dest, opt, value, values, parser) - -__cmdParser__ = OptionParser(option_class=SosOption) -__cmdParser__.add_option("-a", "--alloptions", action="store_true", \ - dest="usealloptions", default=False, \ - help="Use all options for loaded plugins") -__cmdParser__.add_option("-f", "--fastoptions", action="store_true", \ - dest="fastoptions", default=False, \ - help="Use only fast options for loaded plugins") -__cmdParser__.add_option("-g", "--gatheronly", action="store_true", \ - dest="gatheronly", default=False, \ - help="Gather information locally but don't package or submit") -__cmdParser__.add_option("-l", "--list-plugins", action="store_true", \ - dest="listPlugins", default=False, \ - help="list existing plugins") -__cmdParser__.add_option("-n", "--noplugin", action="extend", \ - dest="noplugins", type="string", \ - help="skip these plugins", default = []) -__cmdParser__.add_option("-o", "--onlyplugin", action="extend", \ - dest="onlyplugins", type="string", \ - help="enable these plugins only", default = []) -__cmdParser__.add_option("-e", "--enableplugin", action="extend", \ - dest="enableplugins", type="string", \ - help="list of inactive plugins to be enabled", default = []) -__cmdParser__.add_option("-k", "--pluginopts", action="extend", \ - dest="plugopts", type="string", \ - help="plugin options in plugin_name.option=value format") -__cmdParser__.add_option("-v", "--verbose", action="count", \ - dest="verbosity", \ - help="How obnoxious we're being about telling the user what we're doing.") -__cmdParser__.add_option("-c", "--curses", action="store_true", \ - dest="use_curses", default=False, \ - help="Display a text GUI menu to modify plugin options.") -__cmdParser__.add_option("--no-progressbar", action="store_false", \ - dest="progressbar", default=True, \ - help="Do not display a progress bar.") -__cmdParser__.add_option("--no-multithread", action="store_true", \ - dest="nomultithread", \ - help="Disable multi-threaded gathering mode (slower)", default=False) -(__cmdLineOpts__, __cmdLineArgs__)=__cmdParser__.parse_args() - -def textcolor(text, fg, bg=None, raw=0): - colors = { "black":"30", "red":"31", "green":"32", "brown":"33", "blue":"34", - "purple":"35", "cyan":"36", "lgray":"37", "gray":"1;30", "lred":"1;31", - "lgreen":"1;32", "yellow":"1;33", "lblue":"1;34", "pink":"1;35", - "lcyan":"1;36", "white":"1;37" } - opencol = "\033[" - closecol = "m" - clear = opencol + "0" + closecol - f = opencol + colors[fg] + closecol - return "%s%s%s" % (f, text, clear) - -def get_curse_options(alloptions): - """ - use curses to enable the user to select some options - """ - # alloptions is an array of (plug, plugname, optname, parms(dictionary)) tuples - plugName = [] - out = [] - - # get a sorted list of all plugin names - for rrr in alloptions: - if rrr[1] not in plugName: - plugName.append(rrr[1]) - - plugName.sort() - plugCbox = CheckboxTree(height=5, scroll=1) - - countOpt = -1 - - optDic = {} - optDicCounter = 0 - - # iterate over all plugins with options - for curPlugName in plugName: - plugCbox.addItem(curPlugName, (snackArgs['append'],)) - countOpt = countOpt+1 - - for opt in alloptions: - if opt[1] != curPlugName: - continue - - snt = opt[2] + " ("+opt[3]['desc']+") is " + opt[3]['speed'] - plugCbox.addItem(snt, (countOpt, snackArgs['append']), item = optDicCounter, selected = opt[3]['enabled']) - optDic[optDicCounter] = opt - optDicCounter += 1 - - - screen = SnackScreen() - bb = ButtonBar(screen, (("Ok", "ok"), ("Cancel", "cancel"))) - g = GridForm(screen, "Select Sosreport Options", 1, 10) - g.add(plugCbox, 0, 0) - g.add(bb, 0, 1, growx = 1) - result = g.runOnce() - - screen.finish() - - if bb.buttonPressed(result) == "cancel": - raise "Cancelled" - - for rrr in range(0, optDicCounter): - optDic[rrr][3]['enabled'] = plugCbox.getEntryValue(rrr)[1] - out.append((optDic[rrr])) - - return out - -class progressBar: - def __init__(self, minValue = 0, maxValue = 10, totalWidth=40): - self.progBar = "[]" # This holds the progress bar string - self.min = minValue - self.max = maxValue - self.width = totalWidth - self.amount = 0 # When amount == max, we are 100% done - self.time_start = time() - self.eta = 0 - self.last_amount_update = time() - self.update() - - def updateAmount(self, newAmount = 0): - if newAmount < self.min: newAmount = self.min - if newAmount > self.max: newAmount = self.max - if self.amount != newAmount: - self.last_amount_update = time() - self.amount = newAmount - last_update_relative = round(self.last_amount_update - self.time_start) - self.eta = round(last_update_relative * self.max / self.amount) - - # generate ETA - timeElapsed = round(time() - self.time_start) - last_update_relative = round(self.last_amount_update - self.time_start) - if timeElapsed >= 10 and self.amount > 0: - percentDone = round(timeElapsed * 100 / self.eta) - if percentDone > 100: - percentDone = 100 - ETA = timeElapsed - elif self.eta < timeElapsed: - ETA = timeElapsed - else: - ETA = self.eta - ETA = "[%02d:%02d/%02d:%02d]" % (round(timeElapsed/60), timeElapsed % 60, round(ETA/60), ETA % 60) - else: - ETA = "[%02d:%02d/--:--]" % (round(timeElapsed/60), timeElapsed % 60) - if self.amount < self.max: - percentDone = 0 - else: - percentDone = 100 - - # Figure out how many hash bars the percentage should be - allFull = self.width - 2 - numHashes = (percentDone / 100.0) * allFull - numHashes = int(round(numHashes)) - - # build a progress bar with hashes and spaces - self.progBar = " [" + '#'*numHashes + ' '*(allFull-numHashes) + "]" - - # figure out where to put the percentage, roughly centered - percentPlace = (len(self.progBar) / 2) - len(str(percentDone)) - percentString = str(percentDone) + "%" - - # slice the percentage into the bar - self.progBar = " Progress" + self.progBar[0:percentPlace] + percentString + self.progBar[percentPlace+len(percentString):] + ETA - - def incAmount(self, toInc = 1): - self.updateAmount(self.amount+toInc) - - def finished(self): - self.updateAmount(self.max) - sys.stdout.write(self.progBar + '\n') - sys.stdout.flush() - - def update(self): - self.updateAmount(self.amount) - 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 - # pylint: disable-msg = R0915 - """ - This is the top-level function that gathers and processes all sosreport information - """ - loadedplugins = [] - skippedplugins = [] - alloptions = [] - - # perhaps we should automatically locate the policy module?? - policy = sos.policyredhat.SosPolicy() - - # find the plugins path - paths = sys.path - for path in paths: - if path.strip()[-len("site-packages"):] == "site-packages": - pluginpath = path + "/sos/plugins" - reporterpath = path + "/sos/reporters" - - # Set up common info and create destinations - - dstroot = sosFindTmpDir() - cmddir = os.path.join(dstroot, "sos_commands") - logdir = os.path.join(dstroot, "sos_logs") - rptdir = os.path.join(dstroot, "sos_reports") - os.mkdir(cmddir, 0755) - os.mkdir(logdir, 0755) - os.mkdir(rptdir, 0755) - - # initialize i18n language localization - gettext.install('sos', '/usr/share/locale', unicode=False) - - # initialize logging - soslog = logging.getLogger('sos') - soslog.setLevel(logging.DEBUG) - - # log to a file - flog = logging.FileHandler(logdir + "/sos.log") - flog.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s')) - flog.setLevel(logging.DEBUG) - soslog.addHandler(flog) - - # define a Handler which writes INFO messages or higher to the sys.stderr - console = logging.StreamHandler(sys.stderr) - if __cmdLineOpts__.verbosity > 0: - console.setLevel(20 - __cmdLineOpts__.verbosity) - __cmdLineOpts__.progressbar = False - else: - console.setLevel(logging.INFO) - console.setFormatter(logging.Formatter('%(message)s')) - soslog.addHandler(console) - - logging.VERBOSE = logging.INFO - 1 - logging.VERBOSE2 = logging.INFO - 2 - logging.VERBOSE3 = logging.INFO - 3 - logging.addLevelName(logging.VERBOSE, "verbose") - logging.addLevelName(logging.VERBOSE2,"verbose2") - logging.addLevelName(logging.VERBOSE3,"verbose3") - - 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, - 'xmlreport' : xmlrep } - - # Make policy aware of the commons - policy.setCommons(commons) - - print - soslog.info ( _("sosreport (version %s)") % __version__) - print - - # generate list of available plugins - plugins = os.listdir(pluginpath) - plugins.sort() - - # validate and load plugins - for plug in plugins: - plugbase = plug[:-3] - if not plug[-3:] == '.py' or plugbase == "__init__": - continue - try: - #print "importing plugin: %s" % plugbase - try: - if policy.validatePlugin(pluginpath + plug): - pluginClass = importPlugin("sos.plugins." + plugbase, plugbase) - else: - soslog.warning(_("plugin %s does not validate, skipping") % plug) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - if plugbase in __cmdLineOpts__.noplugins: - soslog.log(logging.VERBOSE, _("plug %s skipped (noplugins)") % plugbase) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - if not pluginClass(plugbase, commons).checkenabled() and not plugbase in __cmdLineOpts__.enableplugins and not plugbase in __cmdLineOpts__.onlyplugins: - soslog.log(logging.VERBOSE, _("plugin %s is inactive (use -e or -o to enable).") % plug) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - if not pluginClass(plugbase, commons).defaultenabled() and not plugbase in __cmdLineOpts__.enableplugins and not plugbase in __cmdLineOpts__.onlyplugins: - soslog.log(logging.VERBOSE, "plugin %s not loaded by default (use -e or -o to enable)." % plug) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - if __cmdLineOpts__.onlyplugins and not plugbase in __cmdLineOpts__.onlyplugins: - soslog.log(logging.VERBOSE, _("plugin %s not specified in --onlyplugin list") % plug) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - loadedplugins.append((plugbase, pluginClass(plugbase, commons))) - except: - soslog.warning(_("plugin %s does not install, skipping") % plug) - raise - except: - soslog.warning(_("could not load plugin %s") % plug) - if __raisePlugins__: - raise - - # First, gather and process options - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE3, _("processing options from plugin: %s") % plugname) - names, parms = plug.getAllOptions() - for optname, optparm in zip(names, parms): - alloptions.append((plug, plugname, optname, optparm)) - - if __cmdLineOpts__.listPlugins: - if not len(loadedplugins) and not len(skippedplugins): - soslog.error(_("no valid plugins found")) - sys.exit(1) - - if len(loadedplugins): - print _("The following plugins are currently enabled:") - print - for (plugname,plug) in loadedplugins: - print " %-25s %s" % (textcolor(plugname,"lblue"),plug.get_description()) - else: - print _("No plugin enabled.") - print - - if len(alloptions): - print _("The following plugin options are available:") - print - for (plug, plugname, optname, optparm) in alloptions: - print " %-25s %s [%d]" % (plugname + "." + optname, optparm["desc"], optparm["enabled"]) - else: - print _("No plugin options available.") - - if len(skippedplugins): - print - print _("The following plugins are currently disabled:") - print - for (plugname,plugclass) in skippedplugins: - print " %-25s %s" % (textcolor(plugname,"blue"),plugclass.get_description()) - - print - sys.exit() - - # to go anywhere further than listing the plugins we will need root permissions. - # - if os.getuid() != 0: - print _('sosreport requires root permissions to run.') - sys.exit(1) - - # we don't need to keep in memory plugins we are not going to use - del skippedplugins - - if not len(loadedplugins): - soslog.error(_("no valid plugins were enabled")) - sys.exit(1) - - try: - raw_input(_("""This utility will collect some detailed information about the -hardware and setup of your Red Hat Enterprise Linux system. -This information will be used to diagnose problems with your -system and will be considered confidential information. -Red Hat will use this information for diagnostic purposes ONLY. - -This process may take a while to complete. -No changes will be made to your system. - -Press ENTER to continue, or CTRL-C to quit. -""")) - except KeyboardInterrupt: - print - sys.exit(0) - - # setup plugin options - if __cmdLineOpts__.plugopts: - opts = {} - for opt in __cmdLineOpts__.plugopts: - try: opt, val = opt.split("=") - except: val=1 - plug, opt = opt.split(".") - try: val = int(val) # try to convert string "val" to int() - except: pass - try: opts[plug] - except KeyError: opts[plug] = [] - opts[plug].append( (opt,val) ) - for plugname, plug in loadedplugins: - if opts.has_key(plugname): - for opt,val in opts[plugname]: - soslog.log(logging.VERBOSE, "setting option %s for plugin %s to %s" % (plugname,opt,val)) - plug.setOption(opt,val) - del opt,opts,val - elif not __cmdLineOpts__.fastoptions and not __cmdLineOpts__.usealloptions: - if len(alloptions) and __cmdLineOpts__.use_curses: - try: - get_curse_options(alloptions) - except "Cancelled": - sys.exit(_("Exiting.")) - elif __cmdLineOpts__.fastoptions: - for i in range(len(alloptions)): - for plug, plugname, optname, optparm in alloptions: - if optparm['speed'] == 'fast': - plug.setOption(optname, 1) - else: - plug.setOption(optname, 0) - elif __cmdLineOpts__.usealloptions: - for i in range(len(alloptions)): - for plug, plugname, optname, optparm in alloptions: - plug.setOption(optname, 1) - - # Call the diagnose() method for each plugin - tmpcount = 0 - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE2, "Performing sanity check for plugin %s" % plugname) - plug.diagnose() - tmpcount += len(plug.diagnose_msgs) - if tmpcount > 0: - print _("One or more plugin has detected a problem in your configuration.") - print _("Please review the following messages:") - print - for plugname, plug in loadedplugins: - for msg in plug.diagnose_msgs: - soslog.warning(" * %s: %s", plugname, msg) - print - try: - raw_input( _("Press ENTER to continue, or CTRL-C to quit.\n") ) - except KeyboardInterrupt: - print - sys.exit(0) - - # Call the setup() method for each plugin - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE2, "Preloading files and commands to be gathered by plugin %s" % plugname) - plug.setup() - - # Setup the progress bar - if __cmdLineOpts__.progressbar: - # gather information useful for generating ETA - eta_weight = len(loadedplugins) - for plugname, plug in loadedplugins: - eta_weight += plug.eta_weight - pbar = progressBar(minValue = 0, maxValue = eta_weight) - # pbar.max = number_of_plugins + weight (default 1 per plugin) - - if __cmdLineOpts__.nomultithread: - soslog.log(logging.VERBOSE, "using single-threading") - else: - soslog.log(logging.VERBOSE, "using multi-threading") - - # Call the collect method for each plugin - plugrunning = Semaphore(2) - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE, "executing plugin %s" % plugname) - if not __cmdLineOpts__.nomultithread: - plug.copyStuff(threaded = True, semaphore = plugrunning) - else: - plug.copyStuff() - if __cmdLineOpts__.progressbar: - pbar.incAmount(plug.eta_weight) - pbar.update() - del plugrunning - - # Wait for all the collection threads to exit - if not __cmdLineOpts__.nomultithread: - finishedplugins = [] - while len(loadedplugins) > 0: - plugname, plug = loadedplugins.pop(0) - if not plug.wait(0.5): - finishedplugins.append((plugname,plug)) - soslog.log(logging.VERBOSE2, "plugin %s has returned" % plugname) - if __cmdLineOpts__.progressbar: - pbar.incAmount(plug.eta_weight) - else: - soslog.log(logging.VERBOSE3, "plugin %s still hasn't returned" % plugname) - loadedplugins.append((plugname,plug)) - if __cmdLineOpts__.progressbar: - pbar.update() - loadedplugins = finishedplugins - del finishedplugins - - xmlrep.serialize_to_file(rptdir + "/" + "sosreport.xml") - - # Call the analyze method for each plugin - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE2, "Analyzing results of plugin %s" % plugname,) - try: - plug.analyze() - except: - # catch exceptions in analyse() and keep working - pass - if __cmdLineOpts__.progressbar: - pbar.incAmount() - pbar.update() - - if __cmdLineOpts__.progressbar: - pbar.finished() - sys.stdout.write("\n") - - # Generate the header for the html output file - rfd = open(rptdir + "/" + "sosreport.html", "w") - rfd.write(""" - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> - <head> - <link rel="stylesheet" type="text/css" media="screen" href="donot.css" /> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title>Sos System Report</title> - </head> - - <body> - """) - - - # Make a pass to gather Alerts and a list of module names - allAlerts = [] - plugNames = [] - for plugname, plug in loadedplugins: - for alert in plug.alerts: - allAlerts.append('<a href="#%s">%s</a>: %s' % (plugname, plugname, alert)) - plugNames.append(plugname) - - - - # Create a table of links to the module info - rfd.write("<hr/><h3>Loaded Plugins:</h3>") - rfd.write("<table><tr>\n") - rr = 0 - for i in range(len(plugNames)): - rfd.write('<td><a href="#%s">%s</a></td>\n' % (plugNames[i], plugNames[i])) - rr = divmod(i, 4)[1] - if (rr == 3): - rfd.write('</tr>') - if not (rr == 3): - rfd.write('</tr>') - rfd.write('</table>\n') - - rfd.write('<hr/><h3>Alerts:</h3>') - rfd.write('<ul>') - for alert in allAlerts: - rfd.write('<li>%s</li>' % alert) - rfd.write('</ul>') - - - # Call the report method for each plugin - for plugname, plug in loadedplugins: - html = plug.report() - rfd.write(html) - - rfd.write("</body></html>") - - rfd.close() - - # Collect any needed user information (name, etc) - - # Call the postproc method for each plugin - for plugname, plug in loadedplugins: - plug.postproc() - - if __cmdLineOpts__.gatheronly: - soslog.info(_("Collected information is in ") + dstroot) - soslog.info(_("Your html report is in ") + rptdir + "/" + "sosreport.html") - else: - # package up the results for the support organization - policy.packageResults() - # delete gathered files - os.system("/bin/rm -rf %s" % dstroot) - # automated submission will go here - - # Close all log files and perform any cleanup - logging.shutdown() - - -if __name__ == '__main__': - try: - sosreport() - except KeyboardInterrupt: - doExitCode() |