aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sos/sosreport.py404
1 files changed, 220 insertions, 184 deletions
diff --git a/sos/sosreport.py b/sos/sosreport.py
index 90890643..165c68ce 100644
--- a/sos/sosreport.py
+++ b/sos/sosreport.py
@@ -2,24 +2,24 @@
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
+# sosreport.py
+# gather information about a system and report it
-## Copyright (C) 2006 Steve Conklin <sconklin@redhat.com>
+# 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 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.
+# 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.
+# 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.
import sys
import traceback
@@ -32,14 +32,14 @@ from sos.utilities import ImporterHelper
from stat import ST_UID, ST_GID, ST_MODE, ST_CTIME, ST_ATIME, ST_MTIME, S_IMODE
from time import strftime, localtime
from collections import deque
-import textwrap
import tempfile
from sos import _sos as _
from sos import __version__
import sos.policies
from sos.archive import TarFileArchive, ZipFileArchive
-from sos.reporting import Report, Section, Command, CopiedFile, CreatedFile, Alert, Note, PlainTextReport
+from sos.reporting import (Report, Section, Command, CopiedFile, CreatedFile,
+ Alert, Note, PlainTextReport)
# PYCOMPAT
import six
@@ -61,21 +61,21 @@ class TempFileUtil(object):
self.files = []
def new(self):
- fd, fname = tempfile.mkstemp(dir=self.tmp_dir)
- fobj = open(fname, 'w')
- self.files.append((fname, fobj))
- return fobj
+ fd, fname = tempfile.mkstemp(dir=self.tmp_dir)
+ fobj = open(fname, 'w')
+ self.files.append((fname, fobj))
+ return fobj
def clean(self):
for fname, f in self.files:
try:
f.flush()
f.close()
- except Exception as e:
+ except Exception:
pass
try:
os.unlink(fname)
- except Exception as e:
+ except Exception:
pass
self.files = []
@@ -86,13 +86,14 @@ class OptionParserExtended(OptionParser):
""" Prints help content including examples """
OptionParser.print_help(self, out)
print_()
- print_( "Some examples:")
+ print_("Some examples:")
print_()
- print_( " enable cluster plugin only and collect dlm lockdumps:")
- print_( " # sosreport -o cluster -k cluster.lockdump")
+ 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_(" disable memory and samba plugins, turn off rpm -Va "
+ "collection:")
+ print_(" # sosreport -n memory,samba -k rpm.rpmva=off")
print_()
@@ -132,7 +133,7 @@ class XmlReport(object):
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,
+ def add_command(self, cmdline, exitcode, stdout=None, stderr=None,
f_stdout=None, f_stderr=None, runtime=None):
""" Appends command run into report """
if not self.enabled:
@@ -169,14 +170,17 @@ class XmlReport(object):
cchild = cfile.newChild(None, "uid", str(stats[ST_UID]))
cchild = cfile.newChild(None, "gid", str(stats[ST_GID]))
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 = 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 = 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 = 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):
@@ -229,13 +233,13 @@ class SoSOptions(object):
self._options = None
def _check_options_initialized(self):
- if self._options != None:
+ if self._options is not None:
raise ValueError("SoSOptions object already initialized "
+ "from command line")
@property
def list_plugins(self):
- if self._options != None:
+ if self._options is not None:
return self._options.list_plugins
return self._list_plugins
@@ -248,7 +252,7 @@ class SoSOptions(object):
@property
def noplugins(self):
- if self._options != None:
+ if self._options is not None:
return self._options.noplugins
return self._noplugins
@@ -259,18 +263,18 @@ class SoSOptions(object):
@property
def enableplugins(self):
- if self._options != None:
+ if self._options is not None:
return self._options.enableplugins
return self._enableplugins
@enableplugins.setter
- def enableplugins(self):
+ def enableplugins(self, value):
self._check_options_initialized()
self._enableplugins = value
@property
def onlyplugins(self):
- if self._options != None:
+ if self._options is not None:
return self._options.onlyplugins
return self._onlyplugins
@@ -281,33 +285,33 @@ class SoSOptions(object):
@property
def plugopts(self):
- if self._options != None:
+ if self._options is not None:
return self._options.plugopts
return self._plugopts
@plugopts.setter
def plugopts(self, value):
# If we check for anything it should be itterability.
- #if not isinstance(value, list):
+ # if not isinstance(value, list):
# raise TypeError("SoSOptions.plugopts expects a list")
self._plugopts = value
@property
def usealloptions(self):
- if self._options != None:
+ if self._options is not None:
return self._options.usealloptions
return self._usealloptions
@usealloptions.setter
def usealloptions(self, value):
self._check_options_initialized()
- if not isinsance(value, bool):
+ if not isinstance(value, bool):
raise TypeError("SoSOptions.usealloptions expects a boolean")
self._usealloptions = value
@property
def all_logs(self):
- if self._options != None:
+ if self._options is not None:
return self._options.all_logs
return self._all_logs
@@ -320,7 +324,7 @@ class SoSOptions(object):
@property
def log_size(self):
- if self._options != None:
+ if self._options is not None:
return self._options.log_size
return self._log_size
@@ -328,12 +332,13 @@ class SoSOptions(object):
def log_size(self, value):
self._check_options_initialized()
if value < 0:
- raise ValueError("SoSOptions.log_size expects a value greater than zero")
+ raise ValueError("SoSOptions.log_size expects a value greater "
+ "than zero")
self._log_size = value
@property
def batch(self):
- if self._options != None:
+ if self._options is not None:
return self._options.batch
return self._batch
@@ -346,12 +351,12 @@ class SoSOptions(object):
@property
def build(self):
- if self._options != None:
+ if self._options is not None:
return self._options.build
return self._build
@build.setter
- def build(self):
+ def build(self, value):
self._check_options_initialized()
if not isinstance(value, bool):
raise TypeError("SoSOptions.build expects a boolean")
@@ -359,7 +364,7 @@ class SoSOptions(object):
@property
def verbosity(self):
- if self._options != None:
+ if self._options is not None:
return self._options.verbosity
return self._verbosity
@@ -372,7 +377,7 @@ class SoSOptions(object):
@property
def verify(self):
- if self._options != None:
+ if self._options is not None:
return self._options.verify
return self._verify
@@ -385,7 +390,7 @@ class SoSOptions(object):
@property
def quiet(self):
- if self._options != None:
+ if self._options is not None:
return self._options.quiet
return self._quiet
@@ -398,7 +403,7 @@ class SoSOptions(object):
@property
def debug(self):
- if self._options != None:
+ if self._options is not None:
return self._options.debug
return self._debug
@@ -411,7 +416,7 @@ class SoSOptions(object):
@property
def ticket_number(self):
- if self._options != None:
+ if self._options is not None:
return self._options.ticket_number
return self._ticket_number
@@ -422,7 +427,7 @@ class SoSOptions(object):
@property
def customer_name(self):
- if self._options != None:
+ if self._options is not None:
return self._options.customer_name
return self._customer_name
@@ -433,7 +438,7 @@ class SoSOptions(object):
@property
def config_file(self):
- if self._options != None:
+ if self._options is not None:
return self._options.config_file
return self._config_file
@@ -444,7 +449,7 @@ class SoSOptions(object):
@property
def tmp_dir(self):
- if self._options != None:
+ if self._options is not None:
return self._options.tmp_dir
return self._tmp_dir
@@ -455,7 +460,7 @@ class SoSOptions(object):
@property
def report(self):
- if self._options != None:
+ if self._options is not None:
return self._options.report
return self._report
@@ -468,7 +473,7 @@ class SoSOptions(object):
@property
def compression_type(self):
- if self._options != None:
+ if self._options is not None:
return self._options.compression_type
return self._compression_type
@@ -482,66 +487,71 @@ class SoSOptions(object):
self.parser = parser = OptionParserExtended(option_class=SosOption)
parser.add_option("-l", "--list-plugins", action="store_true",
- dest="list_plugins", default=False,
- help="list plugins and available plugin options")
+ dest="list_plugins", default=False,
+ help="list plugins and available plugin options")
parser.add_option("-n", "--skip-plugins", action="extend",
- dest="noplugins", type="string",
- help="disable these plugins", default = deque())
+ dest="noplugins", type="string",
+ help="disable these plugins", default=deque())
parser.add_option("-e", "--enable-plugins", action="extend",
- dest="enableplugins", type="string",
- help="enable these plugins", default = deque())
+ dest="enableplugins", type="string",
+ help="enable these plugins", default=deque())
parser.add_option("-o", "--only-plugins", action="extend",
- dest="onlyplugins", type="string",
- help="enable these plugins only", default = deque())
+ dest="onlyplugins", type="string",
+ help="enable these plugins only", default=deque())
parser.add_option("-k", "--plugin-option", action="extend",
- dest="plugopts", type="string",
- help="plugin options in plugname.option=value format (see -l)",
- default = deque())
+ dest="plugopts", type="string",
+ help="plugin options in plugname.option=value "
+ "format (see -l)",
+ default=deque())
parser.add_option("--log-size", action="store",
- dest="log_size", default=10, type="int",
- help="set a limit on the size of collected logs")
+ dest="log_size", default=10, type="int",
+ help="set a limit on the size of collected logs")
parser.add_option("-a", "--alloptions", action="store_true",
- dest="usealloptions", default=False,
- help="enable all options for loaded plugins")
+ dest="usealloptions", default=False,
+ help="enable all options for loaded plugins")
parser.add_option("--all-logs", action="store_true",
- dest="all_logs", default=False,
- help="collect all available logs regardless of size")
+ dest="all_logs", default=False,
+ help="collect all available logs regardless of size")
parser.add_option("--batch", action="store_true",
- dest="batch", default=False,
- help="batch mode - do not prompt interactively")
- parser.add_option("--build", action="store_true", \
- dest="build", default=False, \
- help="preserve the temporary directory and do not package results")
+ dest="batch", default=False,
+ help="batch mode - do not prompt interactively")
+ parser.add_option("--build", action="store_true",
+ dest="build", default=False,
+ help="preserve the temporary directory and do not "
+ "package results")
parser.add_option("-v", "--verbose", action="count",
- dest="verbosity",
- help="increase verbosity")
+ dest="verbosity",
+ help="increase verbosity")
parser.add_option("", "--verify", action="store_true",
- dest="verify", default=False,
- help="perform data verification during collection")
+ dest="verify", default=False,
+ help="perform data verification during collection")
parser.add_option("", "--quiet", action="store_true",
- dest="quiet", default=False,
- help="only print fatal errors")
+ dest="quiet", default=False,
+ help="only print fatal errors")
parser.add_option("--debug", action="count",
- dest="debug",
- help="enable interactive debugging using the python debugger")
+ dest="debug",
+ help="enable interactive debugging using the python "
+ "debugger")
parser.add_option("--ticket-number", action="store",
- dest="ticket_number",
- help="specify ticket number")
+ dest="ticket_number",
+ help="specify ticket number")
parser.add_option("--name", action="store",
- dest="customer_name",
- help="specify report name")
+ dest="customer_name",
+ help="specify report name")
parser.add_option("--config-file", action="store",
- dest="config_file",
- help="specify alternate configuration file")
+ dest="config_file",
+ help="specify alternate configuration file")
parser.add_option("--tmp-dir", action="store",
- dest="tmp_dir",
- help="specify alternate temporary directory", default=None)
+ dest="tmp_dir",
+ help="specify alternate temporary directory",
+ default=None)
parser.add_option("--no-report", action="store_true",
- dest="report",
- help="Disable HTML/XML reporting", default=False)
+ dest="report",
+ help="Disable HTML/XML reporting", default=False)
parser.add_option("-z", "--compression-type", dest="compression_type",
- help="compression technology to use [auto, zip, gzip, bzip2, xz] (default=auto)",
- default="auto")
+ help="compression technology to use [auto, zip, "
+ "gzip, bzip2, xz] (default=auto)",
+ default="auto")
return parser.parse_args(args)[0]
@@ -562,7 +572,7 @@ class SoSReport(object):
import signal
signal.signal(signal.SIGTERM, self.get_exit_handler())
except Exception:
- pass # not available in java, but we don't care
+ pass # not available in java, but we don't care
self.opts = SoSOptions(args)
self._set_debug()
@@ -571,44 +581,46 @@ class SoSReport(object):
try:
self.policy = sos.policies.load()
except KeyboardInterrupt:
- self._exit(0)
+ self._exit(0)
self._is_root = self.policy.is_root()
self.tmpdir = os.path.abspath(
self.policy.get_tmp_dir(self.opts.tmp_dir))
if not os.path.isdir(self.tmpdir) \
- or not os.access(self.tmpdir, os.W_OK):
+ or not os.access(self.tmpdir, os.W_OK):
# write directly to stderr as logging is not initialised yet
- sys.stderr.write("temporary directory %s " % self.tmpdir \
- + "does not exist or is not writable\n")
+ sys.stderr.write("temporary directory %s " % self.tmpdir
+ + "does not exist or is not writable\n")
self._exit(1)
self.tempfile_util = TempFileUtil(self.tmpdir)
self._set_directories()
def print_header(self):
- self.ui_log.info("\n%s\n" % _("sosreport (version %s)" % (__version__,)))
+ self.ui_log.info("\n%s\n" % _("sosreport (version %s)" %
+ (__version__,)))
def get_commons(self):
return {
- 'cmddir': self.cmddir,
- 'logdir': self.logdir,
- 'rptdir': self.rptdir,
- 'tmpdir': self.tmpdir,
- 'soslog': self.soslog,
- 'policy': self.policy,
- 'verbosity': self.opts.verbosity,
- 'xmlreport': self.xml_report,
- 'cmdlineopts': self.opts,
- 'config': self.config,
- 'global_plugin_options': self.global_plugin_options,
- }
+ 'cmddir': self.cmddir,
+ 'logdir': self.logdir,
+ 'rptdir': self.rptdir,
+ 'tmpdir': self.tmpdir,
+ 'soslog': self.soslog,
+ 'policy': self.policy,
+ 'verbosity': self.opts.verbosity,
+ 'xmlreport': self.xml_report,
+ 'cmdlineopts': self.opts,
+ 'config': self.config,
+ 'global_plugin_options': self.global_plugin_options,
+ }
def get_temp_file(self):
return self.tempfile_util.new()
def _set_archive(self):
- archive_name = os.path.join(self.tmpdir,self.policy.get_archive_name())
+ archive_name = os.path.join(self.tmpdir,
+ self.policy.get_archive_name())
if self.opts.compression_type == 'auto':
auto_archive = self.policy.get_preferred_archive()
self.archive = auto_archive(archive_name, self.tmpdir)
@@ -643,9 +655,11 @@ class SoSReport(object):
# device, so we call the default hook
sys.__excepthook__(etype, eval_, etrace)
else:
- import traceback, pdb
+ import traceback
+ import pdb
# we are NOT in interactive mode, print the exception...
- traceback.print_exception(etype, eval_, etrace, limit=2, file=sys.stdout)
+ traceback.print_exception(etype, eval_, etrace, limit=2,
+ file=sys.stdout)
print_()
# ...then start the debugger in post-mortem mode.
pdb.pm()
@@ -677,7 +691,8 @@ class SoSReport(object):
self.sos_log_file = self.get_temp_file()
self.sos_log_file.close()
flog = logging.FileHandler(self.sos_log_file.name)
- flog.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))
+ flog.setFormatter(logging.Formatter(
+ '%(asctime)s %(levelname)s: %(message)s'))
flog.setLevel(logging.INFO)
self.soslog.addHandler(flog)
@@ -700,7 +715,8 @@ class SoSReport(object):
self.sos_ui_log_file = self.get_temp_file()
self.sos_ui_log_file.close()
ui_fhandler = logging.FileHandler(self.sos_ui_log_file.name)
- ui_fhandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))
+ ui_fhandler.setFormatter(logging.Formatter(
+ '%(asctime)s %(levelname)s: %(message)s'))
self.ui_log.addHandler(ui_fhandler)
@@ -720,9 +736,11 @@ class SoSReport(object):
logger.removeHandler(h)
if getattr(self, "sos_log_file", None):
- self.archive.add_file(self.sos_log_file.name, dest=os.path.join('sos_logs', 'sos.log'))
+ self.archive.add_file(self.sos_log_file.name,
+ dest=os.path.join('sos_logs', 'sos.log'))
if getattr(self, "sos_ui_log_file", None):
- self.archive.add_file(self.sos_ui_log_file.name, dest=os.path.join('sos_logs', 'ui.log'))
+ self.archive.add_file(self.sos_ui_log_file.name,
+ dest=os.path.join('sos_logs', 'ui.log'))
def _get_disabled_plugins(self):
disabled = []
@@ -737,17 +755,17 @@ class SoSReport(object):
def _is_inactive(self, plugin_name, pluginClass):
return (not pluginClass(self.get_commons()).check_enabled() and
- not plugin_name in self.opts.enableplugins and
- not plugin_name in self.opts.onlyplugins)
+ plugin_name not in self.opts.enableplugins and
+ plugin_name not in self.opts.onlyplugins)
def _is_not_default(self, plugin_name, pluginClass):
return (not pluginClass(self.get_commons()).default_enabled() and
- not plugin_name in self.opts.enableplugins and
- not plugin_name in self.opts.onlyplugins)
+ plugin_name not in self.opts.enableplugins and
+ plugin_name not in self.opts.onlyplugins)
def _is_not_specified(self, plugin_name):
return (self.opts.onlyplugins and
- not plugin_name in self.opts.onlyplugins)
+ plugin_name not in self.opts.onlyplugins)
def _skip(self, plugin_class, reason="unknown"):
self.skipped_plugins.append((
@@ -773,46 +791,49 @@ class SoSReport(object):
for plug in plugins:
plugbase, ext = os.path.splitext(plug)
try:
- plugin_classes = import_plugin(plugbase,
- tuple(self.policy.valid_subclasses))
+ plugin_classes = import_plugin(
+ plugbase, tuple(self.policy.valid_subclasses))
if not len(plugin_classes):
# no valid plugin classes for this policy
continue
plugin_class = self.policy.match_plugin(plugin_classes)
if not self.policy.validate_plugin(plugin_class):
- self.soslog.warning(_("plugin %s does not validate, skipping") % plug)
+ self.soslog.warning(
+ _("plugin %s does not validate, skipping") % plug)
if self.opts.verbosity > 0:
self._skip(plugin_class, _("does not validate"))
continue
if plugin_class.requires_root and not self._is_root:
- self.soslog.info(_("plugin %s requires root permissions to execute, skipping") % plug)
+ self.soslog.info(_("plugin %s requires root permissions"
+ "to execute, skipping") % plug)
self._skip(plugin_class, _("requires root"))
continue
# plug-in is valid, let's decide whether run it or not
self.plugin_names.append(plugbase)
- if self._is_skipped(plugbase):
+ if self._is_skipped(plugbase):
self._skip(plugin_class, _("skipped"))
continue
- if self._is_inactive(plugbase, plugin_class):
+ if self._is_inactive(plugbase, plugin_class):
self._skip(plugin_class, _("inactive"))
continue
- if self._is_not_default(plugbase, plugin_class):
+ if self._is_not_default(plugbase, plugin_class):
self._skip(plugin_class, _("not default"))
continue
- if self._is_not_specified(plugbase):
+ if self._is_not_specified(plugbase):
self._skip(plugin_class, _("not specified"))
continue
self._load(plugin_class)
except Exception as e:
- self.soslog.warning(_("plugin %s does not install, skipping: %s") % (plug, e))
+ self.soslog.warning(_("plugin %s does not install, "
+ "skipping: %s") % (plug, e))
if self.raise_plugins:
raise
@@ -820,7 +841,7 @@ class SoSReport(object):
if self.opts.usealloptions:
for plugname, plug in self.loaded_plugins:
for name, parms in zip(plug.opt_names, plug.opt_parms):
- if type(parms["enabled"])==bool:
+ if type(parms["enabled"]) == bool:
parms["enabled"] = True
def _set_tunables(self):
@@ -860,19 +881,19 @@ class SoSReport(object):
opts[plug]
except KeyError:
opts[plug] = deque()
- opts[plug].append( (opt, val) )
+ opts[plug].append((opt, val))
for plugname, plug in self.loaded_plugins:
if plugname in opts:
for opt, val in opts[plugname]:
if not plug.set_option(opt, val):
self.soslog.error('no such option "%s" for plugin '
- '(%s)' % (opt,plugname))
+ '(%s)' % (opt, plugname))
self._exit(1)
del opts[plugname]
for plugname in opts.keys():
- self.soslog.error('unable to set option for disabled or non-existing '
- 'plugin (%s)' % (plugname))
+ self.soslog.error('unable to set option for disabled or '
+ 'non-existing plugin (%s)' % (plugname))
def _check_for_unknown_plugins(self):
import itertools
@@ -880,16 +901,17 @@ class SoSReport(object):
self.opts.noplugins,
self.opts.enableplugins):
plugin_name = plugin.split(".")[0]
- if not plugin_name in self.plugin_names:
- self.soslog.fatal('a non-existing plugin (%s) was specified in the '
- 'command line' % (plugin_name))
+ if plugin_name not in self.plugin_names:
+ self.soslog.fatal('a non-existing plugin (%s) was specified'
+ 'in the command line' % (plugin_name))
self._exit(1)
def _set_plugin_options(self):
for plugin_name, plugin in self.loaded_plugins:
names, parms = plugin.get_all_options()
for optname, optparm in zip(names, parms):
- self.all_options.append((plugin, plugin_name, optname, optparm))
+ self.all_options.append((plugin, plugin_name, optname,
+ optparm))
def list_plugins(self):
if not self.loaded_plugins and not self.skipped_plugins:
@@ -900,27 +922,30 @@ class SoSReport(object):
self.ui_log.info(_("The following plugins are currently enabled:"))
self.ui_log.info("")
for (plugname, plug) in self.loaded_plugins:
- self.ui_log.info(" %-20s %s" % (plugname, plug.get_description()))
+ self.ui_log.info(" %-20s %s" % (plugname,
+ plug.get_description()))
else:
self.ui_log.info(_("No plugin enabled."))
self.ui_log.info("")
if self.skipped_plugins:
- self.ui_log.info(_("The following plugins are currently disabled:"))
+ self.ui_log.info(_("The following plugins are currently "
+ "disabled:"))
self.ui_log.info("")
for (plugname, plugclass, reason) in self.skipped_plugins:
- self.ui_log.info(" %-20s %-14s %s" % (plugname,
- reason,
- plugclass.get_description()))
+ self.ui_log.info(" %-20s %-14s %s" % (
+ plugname,
+ reason,
+ plugclass.get_description()))
self.ui_log.info("")
if self.all_options:
self.ui_log.info(_("The following plugin options are available:"))
self.ui_log.info("")
- for (plug, plugname, optname, optparm) in self.all_options:
+ for (plug, plugname, optname, optparm) in self.all_options:
# format option value based on its type (int or bool)
if type(optparm["enabled"]) == bool:
- if optparm["enabled"] == True:
+ if optparm["enabled"] is True:
tmpopt = "on"
else:
tmpopt = "off"
@@ -956,7 +981,7 @@ class SoSReport(object):
compression_methods = ('auto', 'zip', 'bzip2', 'gzip', 'xz')
method = self.opts.compression_type
if method not in compression_methods:
- compression_list = ', '.join (compression_methods)
+ compression_list = ', '.join(compression_methods)
self.ui_log.error("")
self.ui_log.error("Invalid compression specified: " + method)
self.ui_log.error("Valid types are: " + compression_list)
@@ -1009,7 +1034,8 @@ class SoSReport(object):
versions.append("sosreport: %s" % __version__)
for plugname, plug in self.loaded_plugins:
versions.append("%s: %s" % (plugname, plug.version))
- self.archive.add_string(content="\n".join(versions), dest='version.txt')
+ self.archive.add_string(content="\n".join(versions),
+ dest='version.txt')
def collect(self):
self.ui_log.info(_(" Running plugins. Please wait ..."))
@@ -1020,7 +1046,8 @@ class SoSReport(object):
plugruncount += 1
plugname, plug = i[0]
status_line = (" Running %d/%d: %s... "
- % (plugruncount, len(self.loaded_plugins), plugname))
+ % (plugruncount, len(self.loaded_plugins),
+ plugname))
if self.opts.verbosity == 0:
status_line = "\r%s" % status_line
else:
@@ -1050,11 +1077,13 @@ class SoSReport(object):
for plugname, plug in self.loaded_plugins:
for oneFile in plug.copied_files:
try:
- self.xml_report.add_file(oneFile["srcpath"], os.stat(oneFile["srcpath"]))
+ self.xml_report.add_file(oneFile["srcpath"],
+ os.stat(oneFile["srcpath"]))
except:
pass
try:
- self.xml_report.serialize_to_file(os.path.join(self.rptdir, "sosreport.xml"))
+ self.xml_report.serialize_to_file(os.path.join(self.rptdir,
+ "sosreport.xml"))
except (OSError, IOError) as e:
if e.errno in fatal_fs_errors:
self.ui_log.error("")
@@ -1077,7 +1106,7 @@ class SoSReport(object):
for f in plug.copied_files:
section.add(CopiedFile(name=f['srcpath'],
- href= ".." + f['dstpath']))
+ href=".." + f['dstpath']))
for cmd in plug.executed_commands:
section.add(Command(name=cmd['exe'], return_code=0,
@@ -1091,7 +1120,8 @@ class SoSReport(object):
fd = self.get_temp_file()
fd.write(str(PlainTextReport(report)))
fd.flush()
- self.archive.add_file(fd.name, dest=os.path.join('sos_reports', 'sos.txt'))
+ self.archive.add_file(fd.name, dest=os.path.join('sos_reports',
+ 'sos.txt'))
except (OSError, IOError) as e:
if e.errno in fatal_fs_errors:
self.ui_log.error("")
@@ -1115,15 +1145,17 @@ class SoSReport(object):
# Generate the header for the html output file
rfd = self.get_temp_file()
rfd.write("""
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+ <!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>
+ <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
@@ -1131,7 +1163,8 @@ class SoSReport(object):
plugNames = deque()
for plugname, plug in self.loaded_plugins:
for alert in plug.alerts:
- allAlerts.append('<a href="#%s">%s</a>: %s' % (plugname, plugname,
+ allAlerts.append('<a href="#%s">%s</a>: %s' % (plugname,
+ plugname,
alert))
plugNames.append(plugname)
@@ -1166,14 +1199,15 @@ class SoSReport(object):
rfd.write(html)
rfd.write("</body></html>")
rfd.flush()
- self.archive.add_file(rfd.name, dest=os.path.join('sos_reports', 'sos.html'))
+ self.archive.add_file(rfd.name, dest=os.path.join('sos_reports',
+ 'sos.html'))
def postproc(self):
for plugname, plug in self.loaded_plugins:
try:
plug.postproc()
except (OSError, IOError) as e:
- if e.errno in fatal_fs_errors:
+ if e.errno in fatal_fs_errors:
self.ui_log.error("")
self.ui_log.error(" %s while post-processing plugin data"
% e.strerror)
@@ -1189,17 +1223,18 @@ class SoSReport(object):
self._finish_logging()
# package up the results for the support organization
if not self.opts.build:
- print (_("Creating compressed archive..."))
+ print(_("Creating compressed archive..."))
# compression could fail for a number of reasons
try:
- final_filename = self.archive.finalize(self.opts.compression_type)
+ final_filename = self.archive.finalize(
+ self.opts.compression_type)
except (OSError, IOError) as e:
if e.errno in fatal_fs_errors:
- self.ui_log.error("")
- self.ui_log.error(" %s while finalizing archive"
- % e.strerror)
- self.ui_log.error("")
- self._exit(1)
+ self.ui_log.error("")
+ self.ui_log.error(" %s while finalizing archive"
+ % e.strerror)
+ self.ui_log.error("")
+ self._exit(1)
except:
if self.opts.debug:
raise
@@ -1207,7 +1242,7 @@ class SoSReport(object):
return False
else:
final_filename = self.archive.get_archive_path()
- self.policy.display_results(final_filename, build = self.opts.build)
+ self.policy.display_results(final_filename, build=self.opts.build)
self.tempfile_util.clean()
return True
@@ -1218,7 +1253,7 @@ class SoSReport(object):
return True
def set_global_plugin_option(self, key, value):
- self.global_plugin_options[key] = value;
+ self.global_plugin_options[key] = value
def execute(self):
try:
@@ -1258,6 +1293,7 @@ class SoSReport(object):
self.tempfile_util.clean()
return False
+
def main(args):
"""The main entry point"""
sos = SoSReport(args)