aboutsummaryrefslogtreecommitdiffstats
path: root/src/sosreport
diff options
context:
space:
mode:
authorshnavid <shnavid@ef72aa8b-4018-0410-8976-d6e080ef94d8>2007-07-31 15:11:27 +0000
committershnavid <shnavid@ef72aa8b-4018-0410-8976-d6e080ef94d8>2007-07-31 15:11:27 +0000
commite60b7c5a10a03ebca251da29f21e2eb446d3fa60 (patch)
tree66feb12d80d087d8d181656171a430f0de30fa5f /src/sosreport
parent349400ba1f8d54283dec1d1083f7b5ca3ce90a04 (diff)
downloadsos-e60b7c5a10a03ebca251da29f21e2eb446d3fa60.tar.gz
Merged navid-dev r276 into the trunk
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/sos/trunk@278 ef72aa8b-4018-0410-8976-d6e080ef94d8
Diffstat (limited to 'src/sosreport')
-rwxr-xr-xsrc/sosreport252
1 files changed, 96 insertions, 156 deletions
diff --git a/src/sosreport b/src/sosreport
index 6607c453..89242fa0 100755
--- a/src/sosreport
+++ b/src/sosreport
@@ -27,12 +27,11 @@ supplied for application-specific information
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
+from threading import Thread, activeCount
import signal
import logging
from stat import *
@@ -56,7 +55,7 @@ def doExitCode():
print "SIGTERM received, multiple threads detected, waiting for all threads to exit"
for thread in enumerate():
if thread.getName() != "MainThread":
- thread.join()
+ 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"
@@ -80,6 +79,19 @@ signal.signal(signal.SIGTERM, exittermhandler)
# for debugging
__raisePlugins__ = 1
+class OptionParser_extended(OptionParser):
+ def print_help(self):
+ OptionParser.print_help(self)
+ print
+ print "Some examples:"
+ print
+ print " enable cluster plugin only and collect dlm lockdumps:"
+ print " # sosreport -o cluster -k cluster.lockdump"
+ print
+ print " disable memory and samba plugins, turn off rpm -Va collection:"
+ print " # sosreport -n memory,samba -k rpm.rpmva=off"
+ print
+
class SosOption (Option):
"""Allow to specify comma delimited list of plugins"""
ACTIONS = Option.ACTIONS + ("extend",)
@@ -94,46 +106,37 @@ class SosOption (Option):
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__ = OptionParser_extended(option_class=SosOption)
__cmdParser__.add_option("-l", "--list-plugins", action="store_true", \
dest="listPlugins", default=False, \
- help="list existing plugins")
-__cmdParser__.add_option("-n", "--noplugin", action="extend", \
+ help="list plugins and available plugin options")
+__cmdParser__.add_option("-n", action="extend", \
dest="noplugins", type="string", \
help="skip these plugins", default = [])
-__cmdParser__.add_option("-o", "--onlyplugin", action="extend", \
+__cmdParser__.add_option("-e", action="extend", \
+ dest="enableplugins", type="string", \
+ help="enable these plugins", default = [])
+__cmdParser__.add_option("-o", 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", \
+__cmdParser__.add_option("-k", action="extend", \
dest="plugopts", type="string", \
- help="plugin options in plugin_name.option=value format")
+ help="plugin options in plugname.option=value format (see -l)")
+__cmdParser__.add_option("-a", "--alloptions", action="store_true", \
+ dest="usealloptions", default=False, \
+ help="enable all options for loaded plugins")
__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.")
+ help="increase verbosity")
__cmdParser__.add_option("--no-progressbar", action="store_false", \
dest="progressbar", default=True, \
- help="Do not display a progress bar.")
+ 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)
+ help="disable multi-threaded gathering mode (slower)", default=False)
(__cmdLineOpts__, __cmdLineArgs__)=__cmdParser__.parse_args()
-def textcolor(text, fg, bg=None, raw=0):
+def textcolor(text, fg, 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",
@@ -144,60 +147,6 @@ def textcolor(text, fg, bg=None, raw=0):
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
@@ -211,8 +160,10 @@ class progressBar:
self.update()
def updateAmount(self, newAmount = 0):
- if newAmount < self.min: newAmount = self.min
- if newAmount > self.max: newAmount = self.max
+ 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
@@ -225,34 +176,34 @@ class progressBar:
if timeElapsed >= 10 and self.amount > 0:
percentDone = round(timeElapsed * 100 / self.eta)
if percentDone > 100:
- percentDone = 100
- ETA = timeElapsed
+ percentDone = 100
+ ETA = timeElapsed
elif self.eta < timeElapsed:
- ETA = timeElapsed
+ ETA = timeElapsed
else:
- ETA = self.eta
+ ETA = self.eta
ETA = "[%02d:%02d/%02d:%02d]" % (int(timeElapsed/60), timeElapsed % 60, round(ETA/60), ETA % 60)
else:
ETA = "[%02d:%02d/--:--]" % (int(timeElapsed/60), timeElapsed % 60)
if self.amount < self.max:
- percentDone = 0
+ percentDone = 0
else:
- percentDone = 100
+ 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
+ self.progBar = ""
+ for inc in range(0,allFull):
+ if inc == int(allFull / 2):
+ self.progBar = self.progBar + textcolor("%d%%" % percentDone, "blue")
+ elif inc < numHashes:
+ self.progBar = self.progBar + textcolor('#', "green")
+ else:
+ self.progBar = self.progBar + ' '
+ self.progBar = " Progress [" + self.progBar + "]" + ETA
def incAmount(self, toInc = 1):
self.updateAmount(self.amount+toInc)
@@ -281,7 +232,7 @@ class XmlReport:
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):
+ 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)
@@ -351,9 +302,8 @@ def sosreport():
# find the plugins path
paths = sys.path
for path in paths:
- if path.strip()[-len("site-packages"):] == "site-packages":
+ if path.strip()[-len("site-packages"):] == "site-packages":
pluginpath = path + "/sos/plugins"
- reporterpath = path + "/sos/reporters"
# Set up common info and create destinations
@@ -372,6 +322,8 @@ def sosreport():
soslog = logging.getLogger('sos')
soslog.setLevel(logging.DEBUG)
+ # FIXME: strip colours if terminal doesn't allow it
+
# log to a file
flog = logging.FileHandler(logdir + "/sos.log")
flog.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))
@@ -448,34 +400,40 @@ def sosreport():
soslog.warning(_("plugin %s does not install, skipping") % plug)
raise
except:
- soslog.warning(_("could not load plugin %s") % plug)
- if __raisePlugins__:
+ soslog.warning(_("could not load plugin %s") % plug)
+ if __raisePlugins__:
raise
# First, gather and process options
# using the options specified in the command line (if any)
+ if __cmdLineOpts__.usealloptions:
+ for plugname, plug in loadedplugins:
+ for name, parms in zip(plug.optNames, plug.optParms):
+ if type(parms["enabled"])==bool:
+ parms["enabled"] = True
+
if __cmdLineOpts__.plugopts:
opts = {}
for opt in __cmdLineOpts__.plugopts:
- # split up "general.syslogsize=5"
- try:
- opt, val = opt.split("=")
- except:
- val=True
- else:
- if val == "off" or val == "disable" or val == "disabled":
- val = False
- else:
- # try to convert string "val" to int()
- try: val = int(val)
- except: pass
+ # split up "general.syslogsize=5"
+ try:
+ opt, val = opt.split("=")
+ except:
+ val=True
+ else:
+ if val == "off" or val == "disable" or val == "disabled":
+ val = False
+ else:
+ # try to convert string "val" to int()
+ try: val = int(val)
+ except: pass
- # split up "general.syslogsize"
- plug, opt = opt.split(".")
+ # split up "general.syslogsize"
+ plug, opt = opt.split(".")
- try: opts[plug]
- except KeyError: opts[plug] = []
- opts[plug].append( (opt,val) )
+ try: opts[plug]
+ except KeyError: opts[plug] = []
+ opts[plug].append( (opt,val) )
for plugname, plug in loadedplugins:
if opts.has_key(plugname):
@@ -483,24 +441,6 @@ def sosreport():
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:
- # FIXME: with int and bool options, fast/slow/all breaks
- 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)
for plugname, plug in loadedplugins:
soslog.log(logging.VERBOSE3, _("processing options from plugin: %s") % plugname)
@@ -518,19 +458,19 @@ def sosreport():
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())
+ 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 _("No plugin enabled.")
print
if len(skippedplugins):
print _("The following plugins are currently disabled:")
print
for (plugname,plugclass) in skippedplugins:
- print " %-25s %s" % (textcolor(plugname,"blue"),plugclass.get_description())
+ print " %-25s %s" % (textcolor(plugname,"lgray"),plugclass.get_description())
print
if len(alloptions):
@@ -599,7 +539,7 @@ Press ENTER to continue, or CTRL-C to quit.
raise
tmpcount += len(plug.diagnose_msgs)
if tmpcount > 0:
- print _("One or more plugin has detected a problem in your configuration.")
+ print _("One or more plugins have detected a problem in your configuration.")
print _("Please review the following messages:")
print
for plugname, plug in loadedplugins:
@@ -751,17 +691,17 @@ Press ENTER to continue, or CTRL-C to quit.
# Call the postproc method for each plugin
for plugname, plug in loadedplugins:
- plug.postproc()
+ try:
+ plug.postproc()
+ except:
+ if __raisePlugins__:
+ raise
- 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
+ # 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()