diff options
72 files changed, 732 insertions, 1466 deletions
@@ -1,5 +1,6 @@ Adam Stokes <adam.stokes@ubuntu.com> Ben Turner <bturner@redhat.com> +Chris J Arges <chris.j.arges@ubuntu.com> Eric Williams <eric.williams@canonical.com> Eugene Teo <eteo@redhat.com> Gary Kotton <gkotton@redhat.com> @@ -36,5 +36,5 @@ Debian/Ubuntu users can install via PPA: ``` sudo add-apt-repository ppa:debugmonkeys/sosreport sudo apt-get update -sudo apt-get install sos +sudo apt-get install sosreport ``` diff --git a/debian/changelog b/debian/changelog index a70f2c54..2f5840cf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,6 @@ -sos (2.3) unstable; urgency=low +sosreport (2.3+git20130411-1) unstable; urgency=low - * Initial release. + * Package updated from git rev 1baf743 + Closes: #698329 - -- Adam Stokes <adam.stokes@canonical.com> Mon, 20 Feb 2012 16:41:39 +0000 + -- Adam Stokes <adam.stokes@ubuntu.com> Thu, 11 Apr 2013 20:55:56 -0400 diff --git a/debian/compat b/debian/compat index 45a4fb75..ec635144 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/debian/control b/debian/control index 6436a604..d82f284a 100644 --- a/debian/control +++ b/debian/control @@ -1,14 +1,15 @@ -Source: sos -Maintainer: Adam Stokes <adam.stokes@canonical.com> +Source: sosreport +Maintainer: Adam Stokes <adam.stokes@ubuntu.com> Section: python Priority: optional -Standards-Version: 3.9.2 -Build-Depends: debhelper (>= 8), python-support, python (>=2.7), gettext +Standards-Version: 3.9.4 +Build-Depends: debhelper (>= 9), python (>=2.7), gettext, python-nose +Homepage: https://github.com/sosreport/sosreport -Package: sos +Package: sosreport Architecture: any -Depends: ${python:Depends}, ${misc:Depends}, python-selinux -Description: A set of tools to gather troubleshooting information from a system +Depends: ${python:Depends}, ${misc:Depends} +Description: Set of tools to gather troubleshooting data from a system Sos is a set of tools that gathers information about system hardware and configuration. The information can then be used for diagnostic purposes and debugging. Sos is commonly used to help diff --git a/debian/copyright b/debian/copyright index e69de29b..a7cb4f00 100644 --- a/debian/copyright +++ b/debian/copyright @@ -0,0 +1,31 @@ +This package was originally debianized by Adam Stokes +<adam.stokes@ubuntu.com> on Thu Apr 11 18:48:47 EST 2013 + +It was downloaded from https://github.com/sosreport/sosreport + +Author: Bryn Reeves: <bmr@redhat.com> + https://github.com/sosreport + +Copyright: 2007-2013 Red Hat, Inc. + +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., 51 Franklin St, Fifth Floor, Boston, +MA 02110-1301, USA. + +On Debian systems, the complete text of the GNU General Public +License, version 2, can be found in /usr/share/common-licenses/GPL-2. + +The Debian packaging is (C) 2012-2013, Adam Stokes <adam.stokes@ubuntu.com> +and is licensed under the GPL, see above. + diff --git a/debian/rules b/debian/rules index d1b7c05f..9ba428e9 100755 --- a/debian/rules +++ b/debian/rules @@ -3,11 +3,8 @@ DH_ALWAYS_EXCLUDE=.git %: - dh $@ - -override_dh_pysupport: - dh_python2 -p sos -override_dh_fixperms: - dh_fixperms -Xsos -override_dh_auto_test: - + dh $@ --with python2 + +override_dh_auto_install: + dh_auto_install + rm -f $(CURDIR)/debian/sosreport/usr/share/sos/LICENSE diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 00000000..d3827e75 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +1.0 @@ -1,8 +1,8 @@ [general] -ftp_upload_url = ftp://dropbox.redhat.com/incoming -gpg_keyring = /usr/share/sos/rhsupport.pub -gpg_recipient = support@redhat.com +#ftp_upload_url = ftp://example.com/incoming +#gpg_keyring = /usr/share/sos/rhsupport.pub +#gpg_recipient = support@redhat.com smtp_server = None [plugins] diff --git a/sos/archive.py b/sos/archive.py index f837c600..f1b0b057 100644 --- a/sos/archive.py +++ b/sos/archive.py @@ -28,6 +28,11 @@ import re from subprocess import Popen, PIPE, STDOUT try: + import selinux +except ImportError: + pass + +try: from cStringIO import StringIO except ImportError: from StringIO import StringIO diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py index b0e3ab3f..435d69fe 100644 --- a/sos/plugins/__init__.py +++ b/sos/plugins/__init__.py @@ -26,15 +26,10 @@ from __future__ import with_statement from sos.utilities import sos_get_command_output, import_module, grep, fileobj, tail -from sos import _sos as _ -import inspect import os -import sys -import string import glob import re import traceback -import shutil from stat import * from time import time from itertools import * @@ -138,8 +133,6 @@ class Plugin(object): self.copy_strings = [] self.collect_cmds = [] - self.must_exit = False - self.soslog = self.commons['soslog'] if self.commons.has_key('soslog') else logging.getLogger('sos') self.proflog = self.commons['proflog'] if self.commons.has_key('proflog') else logging.getLogger('sosprofile') @@ -246,41 +239,41 @@ class Plugin(object): return False def copy_symlink(self, srcpath, sub=None): - # the target stored in the original symlink + # the target stored in the original symlink linkdest = os.readlink(srcpath) - # absolute path to the link target - absdest = os.path.normpath(os.path.join( - os.path.dirname(srcpath), linkdest)) - # adjust the target used inside the report to always be relative - if os.path.isabs(linkdest): - reldest = os.path.relpath(linkdest, - os.path.dirname(srcpath)) - self.soslog.debug("made link target %s relative as %s" - % (linkdest, reldest)) - else: - reldest = linkdest - - self.soslog.debug( - "copying link %s pointing to %s with sub=%s, isdir=%s" - % (srcpath, linkdest, sub, os.path.isdir(absdest))) + # absolute path to the link target + absdest = os.path.normpath(os.path.join( + os.path.dirname(srcpath), linkdest)) + # adjust the target used inside the report to always be relative + if os.path.isabs(linkdest): + reldest = os.path.relpath(linkdest, + os.path.dirname(srcpath)) + self.soslog.debug("made link target %s relative as %s" + % (linkdest, reldest)) + else: + reldest = linkdest + + self.soslog.debug( + "copying link %s pointing to %s with sub=%s, isdir=%s" + % (srcpath, linkdest, sub, os.path.isdir(absdest))) if os.path.isdir(absdest): self.soslog.debug("link %s is a directory, skipping..." - % linkdest) + % linkdest) return if sub: old, new = sub reldest = srcpath.replace(old, new) - # use the relative target path in the tarball + # use the relative target path in the tarball self.archive.add_link(reldest,srcpath) - # copy the symlink target translating relative targets - # to absolute paths to pass to do_copy_file_or_dir. - self.soslog.debug("normalized link target %s as %s" - %(linkdest, absdest)) - self.do_copy_file_or_dir(absdest) + # copy the symlink target translating relative targets + # to absolute paths to pass to do_copy_file_or_dir. + self.soslog.debug("normalized link target %s as %s" + %(linkdest, absdest)) + self.do_copy_file_or_dir(absdest) self.copied_files.append({ 'srcpath':srcpath, @@ -598,10 +591,6 @@ class Plugin(object): self.soslog.debug("error collecting output of '%s' (%s)" % (prog, e)) - def exit_please(self): - """ This function tells the plugin that it should exit ASAP""" - self.must_exit = True - def get_description(self): """ This function will return the description for the plugin""" try: @@ -714,142 +703,6 @@ class IndependentPlugin(object): """Tagging class that indicates this plugin can run on any platform""" pass -class AS7Mixin(object): - """A mixin class that adds some helpful methods for AS7 related plugins""" - - class Request(object): - - def __init__(self, resource, operation="read-resource", parameters=None): - self.resource = resource - self.operation = operation - if parameters: - self.parameters = parameters - else: - self.parameters = {} - - def url_parts(self): - """Generator function to split a url into (key, value) tuples. The - url should contain an even number of pairs. In the case of / the - generator will immediately stop iteration. - """ - parts = self.resource.strip("/").split("/") - - if parts == ['']: - raise StopIteration - - while parts: - yield (parts.pop(0), parts.pop(0)) - - def get_jboss_home(self): - return self._get_opt('home', 'as7_home') or os.getenv("JBOSS_HOME", None) - - def query(self, request_obj): - try: - return self.query_java(request_obj) - except Exception, e: - self.add_alert("JBOSS API call failed, falling back to HTTP: %s" % e) - return self.query_http(request_obj) - - def _get_opt(self, first, second, default=None): - val = self.get_option(first) - if val: - return val - val = self.get_option(second) - if val: - return val - return default - - def query_java(self, request_obj): - from org.jboss.dmr import ModelNode - controller_client = self.get_option('controller_client_proxy') - if not controller_client: - raise AttributeError("Controller Client is not available") - - request = ModelNode() - request.get("operation").set(request_obj.operation) - - for key, val in request_obj.url_parts(): - request.get('address').add(key,val) - - if request_obj.parameters: - for key, value in request_obj.parameters.iteritems(): - request.get(key).set(value) - - return controller_client.execute(request).toJSONString(True) - - def query_http(self, request_obj, postdata=None): - host = self._get_opt('host', 'as7_host') - port = self._get_opt('port', 'as7_port') - - username = self._get_opt('user', 'as7_user') - password = self._get_opt('pass', 'as7_pass') - - uri = "http://%s:%s/management" % (host,port) - - json_data = {'operation': request_obj.operation, - 'address': []} - - for key, val in request_obj.url_parts(): - json_data['address'].append({key:val}) - - for key, val in request_obj.parameters.iteritems(): - json_data[key] = val - - postdata = json.dumps(json_data) - headers = {'Content-Type': 'application/json', - 'Accept': 'application/json'} - - opener = urllib2.build_opener() - - if username and password: - passwd_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() - passwd_manager.add_password(realm="ManagementRealm", - uri=uri, - user=username, - passwd=password) - digest_auth_handler = urllib2.HTTPDigestAuthHandler(passwd_manager) - basic_auth_handler = urllib2.HTTPBasicAuthHandler(passwd_manager) - - opener.add_handler(digest_auth_handler) - opener.add_handler(basic_auth_handler) - - req = urllib2.Request(uri, data=postdata, headers=headers) - - try: - resp = opener.open(req) - return resp.read() - except Exception, e: - err_msg = "Could not query url: %s; error: %s" % (uri, e) - self.add_alert(err_msg) - return err_msg - - def set_domain_info(self, parameters=None): - """This function will add host controller and server instance name data - if it is present to the desired resource. This is to support - domain-mode operation in AS7. - """ - host_controller_name = self.get_option("as7_host_controller_name") - server_name = self.get_option("as7_server_name") - - if host_controller_name and server_name: - if not parameters: - parameters = {} - - parameters['host'] = host_controller_name - parameters['server'] = server_name - - return parameters - - - def resource_to_file(self, resource=None, parameters=None, operation='read-resource', outfile=None): - parameters = self.set_domain_info(parameters) - - r = self.Request(resource=resource, - parameters=parameters, - operation=operation) - self.add_string_as_file(self.query(r), filename=outfile) - - def import_plugin(name, superclasses=None): """Import name as a module and return a list of all classes defined in that module. superclasses should be a tuple of valid superclasses to import, diff --git a/sos/plugins/as7.py b/sos/plugins/as7.py deleted file mode 100644 index 52f71203..00000000 --- a/sos/plugins/as7.py +++ /dev/null @@ -1,253 +0,0 @@ -import os -import sys -import re -import zipfile -import urllib2 -import tempfile -from xml.etree import ElementTree -from itertools import chain - -from sos.plugins import Plugin, IndependentPlugin, AS7Mixin -from sos.utilities import DirTree, find, checksum - -class AS7(Plugin, IndependentPlugin, AS7Mixin): - """JBoss related information - """ - - requires_root = False - - version = "1.0" - - option_list = [ - ("home", "JBoss's installation dir (i.e. JBOSS_HOME)", '', False), - ("logsize", 'max size (MiB) to collect per log file', '', 15), - ("stdjar", 'Collect jar statistics for standard jars.', '', True), - ("host", 'hostname of the management api for jboss', '', 'localhost'), - ("port", 'port of the management api for jboss', '', '9990'), - ("user", 'username for management console', '', None), - ("pass", 'password for management console', '', None), - ] - - __MD5_CHUNK_SIZE=128 - __jbossHome=None - __haveJava=False - __twiddleCmd=None - __jbossServerConfigDirs = ["standalone", "domain"] - __jbossHTMLBody=None - - def __alert(self, msg): - self.soslog.error(msg) - self.add_alert(msg) - - def __getJbossHome(self): - - self.__jbossHome = self.get_jboss_home() - if not self.__jbossHome: - self.add_alert("ERROR: The JBoss installation directory was not supplied.\ - The JBoss SOS plug-in cannot continue.") - return False - - self.add_alert("INFO: The JBoss installation directory supplied to SOS is " + - self.__jbossHome) - return True - - - def __getMd5(self, file): - """Returns the MD5 sum of the specified file.""" - - retVal = "?" * 32 - - try: - retVal = checksum(file, self.__MD5_CHUNK_SIZE) - except IOError, ioe: - self.__alert("ERROR: Unable to open %s for reading. Error: %s" % (file,ioe)) - - return retVal - - def __getManifest(self, jarFile): - """ - Given a jar file, this function will extract the Manifest and return it's contents - as a string. - """ - manifest = None - try: - zf = zipfile.ZipFile(jarFile) - try: - manifest = zf.read("META-INF/MANIFEST.MF") - except Exception, e: - self.__alert("ERROR: reading manifest from %s. Error: %s" % (jarFile, e)) - zf.close() - except Exception, e: - self.__alert("ERROR: reading contents of %s. Error: %s" % (jarFile, e)) - return manifest - - def __getStdJarInfo(self): - jar_info_list = [] - - for jarFile in find("*.jar", self.__jbossHome): - checksum = self.__getMd5(jarFile) - manifest = self.__getManifest(jarFile) - path = jarFile.replace(self.__jbossHome, 'JBOSSHOME') - if manifest: - manifest = manifest.strip() - jar_info_list.append((path, checksum, manifest)) - - if jar_info_list: - jar_info_list.sort() - self.add_string_as_file("\n".join([ - "%s\n%s\n%s\n===\n" % (name, checksum, manifest) - for (name, checksum, manifest) in jar_info_list]), - 'jarinfo.txt') - else: - self.add_alert("WARN: No jars found in JBoss system path (" + self.__jbossHome + ").") - - def get_online_data(self): - """ - This function co-locates calls to the management api that gather - information from a running system. - """ - self.resource_to_file(resource="/", - parameters={"recursive": "true"}, - outfile="configuration.json") - self.resource_to_file(resource="/core-service/service-container", - operation="dump-services", - outfile="dump-services.json") - self.resource_to_file(resource="/subsystem/modcluster", - operation="read-proxies-configuration", - outfile="cluster-proxies-configuration.json") - self.resource_to_file(resource="/core-service/platform-mbean/type/threading", - operation="dump-all-threads", - parameters={"locked-synchronizers": "true", - "locked-monitors": "true"}, - outfile="threaddump.json") - - def __getFiles(self, configDirAry): - """ - This function will collect files from JBOSS_HOME for analysis. The scope of files to - be collected are determined by options to this SOS plug-in. - """ - for dir_ in configDirAry: - path = os.path.join(self.__jbossHome, dir_) - ## First add forbidden files - self.add_forbidden_path(os.path.join(path, "tmp")) - self.add_forbidden_path(os.path.join(path, "work")) - self.add_forbidden_path(os.path.join(path, "data")) - - if os.path.exists(path): - ## First get everything in the conf dir - confDir = os.path.join(path, "configuration") - self.add_forbidden_path(os.path.join(confDir, 'mgmt-users.properties')) - self.add_forbidden_path(os.path.join(confDir, 'application-users.properties')) - - for logFile in find("*.log", path): - self.add_copy_spec_limit(logFile, - self.get_option("logsize"), - sub=(self.__jbossHome, 'JBOSSHOME')) - - for xml in find("*.xml", path): - self.add_copy_spec(xml, sub=(self.__jbossHome, 'JBOSSHOME')) - - for prop in find("*.properties", path): - self.add_copy_spec(prop, sub=(self.__jbossHome, 'JBOSSHOME')) - - deployment_info = self.__get_deployment_info(confDir) - deployments = self.__get_deployments(path) - for deployment in deployments: - self.__get_listing_from_deployment(deployment, deployment_info) - - for xml in find("*.xml", os.path.join(self.__jbossHome, 'modules')): - self.add_copy_spec(xml, sub=(self.__jbossHome, 'JBOSSHOME')) - - def __get_deployment_info(self, dir_): - """Gets the deployment name to sha1 mapping for all deployments defined - in configs under dir_""" - deployment_info = {} - for config in find("*.xml", dir_): - root = ElementTree.parse(config).getroot() - # the namespace is harder to fetch than it should be - ns = root.tag.rpartition("}")[0] - ns += "}" - for deployment in root.findall("./%sdeployments/%sdeployment" % (ns, ns)): - name = deployment.attrib.get("name") - sha1 = deployment.getchildren()[0].attrib.get("sha1") - deployment_info[sha1] = name - return deployment_info - - def __get_deployments(self, path): - return list(chain( - find("*", os.path.join(path, "deployments")), - find("content", path))) - - def __get_listing_from_deployment(self, path, mapping): - try: - zf = zipfile.ZipFile(path) - contents = [] - for zipinfo in zf.infolist(): - if zipinfo.filename.endswith("/"): - continue - contents.append((zipinfo.filename, zipinfo.file_size)) - zf.close() - contents.sort() - output = "\n".join(["%s:%d" % (fn, fs) for fn, fs in contents]) - - path_to = path.replace(self.__jbossHome, '') - if 'content' in path: - path_to = path_to.strip(os.path.sep).rstrip("content") - path_to = os.path.join(*path_to.split(os.path.sep)[:-2]) - sha1 = "".join(path.split(os.path.sep)[-3:-1]) - name = mapping.get(sha1, sha1) - else: - path_to, name = os.path.split(path_to) - - self.add_string_as_file(output, os.path.join(path_to, "%s.txt" % name)) - except: - # this is probably not a zipfile so we don't care - pass - - def check_enabled(self): - return self.__getJbossHome() - - def setup(self): - - if not self.__getJbossHome(): - self.exit_please() - - try: - self.get_online_data() - except urllib2.URLError: - pass - - if self.get_option("stdjar"): - self.__getStdJarInfo() - - tree = DirTree(self.__jbossHome).as_string() - self.add_string_as_file(tree, "jboss_home_tree.txt") - - self.__getFiles(self.__jbossServerConfigDirs) - - def postproc(self): - """ - Obfuscate passwords. - """ - - password_xml_regex = re.compile(r'<password>.*</password>', re.IGNORECASE) - - for dir_ in self.__jbossServerConfigDirs: - path = os.path.join(self.__jbossHome, dir_) - - self.do_file_sub(os.path.join(path,"configuration","*.xml"), - password_xml_regex, - r'<password>********</password>') - - tmp = os.path.join(path,"configuration") - for propFile in find("*-users.properties", tmp): - self.do_file_sub(propFile, - r"=(.*)", - r'=********') - -# Remove PW from -ds.xml files - tmp = os.path.join(path, "deployments") - for dsFile in find("*-ds.xml", tmp): - self.do_file_sub(dsFile, - password_xml_regex, - r"<password>********</password>") diff --git a/sos/plugins/auditd.py b/sos/plugins/auditd.py index 27dda2ba..f0eb8a5c 100644 --- a/sos/plugins/auditd.py +++ b/sos/plugins/auditd.py @@ -12,14 +12,17 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class Auditd(Plugin, RedHatPlugin): +class auditd(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): """Auditd related information """ - option_list = [("syslogsize", "max size (MiB) to collect per syslog file", "", 15)] + option_list = [("logsize", "maximum size (MiB) of logs to collect", + "", 15)] def setup(self): - self.add_copy_specs(["/etc/audit/auditd.conf", "/etc/audit/audit.rules"]) - self.add_copy_spec_limit("/var/log/audit*", sizelimit = self.get_option("syslogsize")) + self.add_copy_specs(["/etc/audit/auditd.conf", + "/etc/audit/audit.rules"]) + self.add_copy_spec_limit("/var/log/audit*", + sizelimit = self.get_option("logsize")) diff --git a/sos/plugins/autofs.py b/sos/plugins/autofs.py index f88d4f8b..b1d264ba 100644 --- a/sos/plugins/autofs.py +++ b/sos/plugins/autofs.py @@ -15,7 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin, UbuntuPlugin, DebianPlugin -import os, re class Autofs(Plugin): """autofs server-related information diff --git a/sos/plugins/cgroups.py b/sos/plugins/cgroups.py index 1027c04e..102b71c4 100644 --- a/sos/plugins/cgroups.py +++ b/sos/plugins/cgroups.py @@ -39,5 +39,4 @@ class RedHatCgroups(Cgroups, RedHatPlugin): "/etc/cgsnapshot_blacklist.conf", "/etc/cgconfig.conf", "/etc/cgrules.conf"]) - cgroups.setup(self) diff --git a/sos/plugins/cluster.py b/sos/plugins/cluster.py index 07eeb458..e31a295b 100644 --- a/sos/plugins/cluster.py +++ b/sos/plugins/cluster.py @@ -13,7 +13,7 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -import os, re +import re from glob import glob class Cluster(Plugin, RedHatPlugin): diff --git a/sos/plugins/corosync.py b/sos/plugins/corosync.py index 2c2bf35b..79333c2f 100644 --- a/sos/plugins/corosync.py +++ b/sos/plugins/corosync.py @@ -12,13 +12,13 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class corosync(Plugin, RedHatPlugin): +class Corosync(Plugin): """ corosync information """ - files = ('corosync',) + plugin_name = "corosync" packages = ('corosync',) def setup(self): @@ -34,3 +34,20 @@ class corosync(Plugin, RedHatPlugin): self.add_cmd_output("corosync-objctl -w runtime.blackbox.dump_state=$(date +\%s)") self.add_cmd_output("corosync-objctl -w runtime.blackbox.dump_flight_data=$(date +\%s)") self.call_ext_prog("killall -USR2 corosync") + +class RedHatCorosync(Corosync, RedHatPlugin): + """ corosync information for RedHat based distribution + """ + + def setup(self): + super(RedHatCorosync, self).setup() + + +class DebianCorosync(Corosync, DebianPlugin, UbuntuPlugin): + """ corosync information for Debian and Ubuntu distributions + """ + + def setup(self): + super(DebianCorosync, self).setup() + + files = ('/usr/sbin/corosync',) diff --git a/sos/plugins/devicemapper.py b/sos/plugins/devicemapper.py index 1aded5b0..5a3e027c 100644 --- a/sos/plugins/devicemapper.py +++ b/sos/plugins/devicemapper.py @@ -19,8 +19,8 @@ class devicemapper(Plugin, RedHatPlugin): """device-mapper related information (dm, lvm, multipath) """ - option_list = [("lvmdump", 'collect raw metadata from PVs', 'slow', False)] - option_list = [("lvmdump-a", 'use the -a option of lvmdump (requires the "lvmdump" option)', 'slow', False)] + option_list = [("lvmdump", 'collect raw metadata from PVs', 'slow', False), + ("lvmdump-a", 'use the -a option of lvmdump (requires the "lvmdump" option)', 'slow', False)] dmraid_options = ['V','b','r','s','tay','rD'] def do_lvmdump(self): diff --git a/sos/plugins/dhcp.py b/sos/plugins/dhcp.py index ccddd75d..71946c2b 100644 --- a/sos/plugins/dhcp.py +++ b/sos/plugins/dhcp.py @@ -14,32 +14,32 @@ from sos.plugins import Plugin, RedHatPlugin, UbuntuPlugin -class dhcp(Plugin): +class Dhcp(Plugin): """DHCP related information """ plugin_name = "dhcp" -class RedHatDhcp(dhcp, RedHatPlugin): +class RedHatDhcp(Dhcp, RedHatPlugin): """DHCP related information for Red Hat based distributions""" files = ('/etc/rc.d/init.d/dhcpd',) packages = ('dhcp',) def setup(self): - super(DhcpRedHat, self).setup() + super(RedHatDhcp, self).setup() self.add_copy_specs([ "/etc/dhcpd.conf", "/etc/dhcp"]) -class UbuntuDhcp(dhcp, UbuntuPlugin): +class UbuntuDhcp(Dhcp, UbuntuPlugin): """DHCP related information for Debian based distributions""" files = ('/etc/init.d/udhcpd',) packages = ('udhcpd',) def setup(self): - super(DhcpDebian, self).setup() + super(DebianDhcp, self).setup() self.add_copy_specs([ "/etc/default/udhcpd", "/etc/udhcpd.conf" diff --git a/sos/plugins/dovecot.py b/sos/plugins/dovecot.py index b3c5f929..2d92a6b9 100644 --- a/sos/plugins/dovecot.py +++ b/sos/plugins/dovecot.py @@ -12,13 +12,32 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import os -class dovecot(Plugin, RedHatPlugin): +class Dovecot(Plugin): """dovecot server related information """ + + plugin_name = "dovecot" + + def setup(self): + self.add_copy_spec("/etc/dovecot*") + self.add_cmd_output("dovecot -n") + +class RedHatDovecot(Dovecot, RedHatPlugin): + """dovecot server related information for RedHat based distribution + """ def setup(self): - if os.path.exists("/etc/dovecot.conf"): - self.add_copy_spec("/etc/dovecot*") - self.add_cmd_output("dovecot -n") + super(RedHatDovecot, self).setup() + + packages = ('dovecot', ) + files = ('/etc/dovecot.conf',) + +class DebianDovecot(Dovecot, DebianPlugin, UbuntuPlugin): + """dovecot server related information for Debian based distribution + """ + def setup(self): + super(DebianDovecot, self).setup() + + files = ('/etc/dovecot/README',) diff --git a/sos/plugins/emc.py b/sos/plugins/emc.py index 88b3ba21..7646ea2c 100644 --- a/sos/plugins/emc.py +++ b/sos/plugins/emc.py @@ -70,51 +70,51 @@ class emc(Plugin, RedHatPlugin): def get_symcli_config(self): """ EMC Solutions Enabler SYMCLI specific information - Symmetrix/DMX - commands """ - self.add_cmd_output("/usr/symclisymcli -def") - self.add_cmd_output("/usr/symclisymdg list") - self.add_cmd_output("/usr/symclisymdg -v list") - self.add_cmd_output("/usr/symclisymcg list") - self.add_cmd_output("/usr/symclisymcg -v list") - self.add_cmd_output("/usr/symclisymcfg list") - self.add_cmd_output("/usr/symclisymcfg -v list") - self.add_cmd_output("/usr/symclisymcfg -db") - self.add_cmd_output("/usr/symclisymcfg -semaphores list") - self.add_cmd_output("/usr/symclisymcfg -dir all -v list") - self.add_cmd_output("/usr/symclisymcfg -connections list") - self.add_cmd_output("/usr/symclisymcfg -app -v list") - self.add_cmd_output("/usr/symclisymcfg -fa all -port list") - self.add_cmd_output("/usr/symclisymcfg -ra all -port list") - self.add_cmd_output("/usr/symclisymcfg -sa all -port list") - self.add_cmd_output("/usr/symclisymcfg list -lock") - self.add_cmd_output("/usr/symclisymcfg list -lockn all") - self.add_cmd_output("/usr/symclisyminq") - self.add_cmd_output("/usr/symclisyminq -v") - self.add_cmd_output("/usr/symclisyminq -symmids") - self.add_cmd_output("/usr/symclisyminq hba -fibre") - self.add_cmd_output("/usr/symclisyminq hba -scsi") - self.add_cmd_output("/usr/symclisymhost show -config") - self.add_cmd_output("/usr/symclistordaemon list") - self.add_cmd_output("/usr/symclistordaemon -v list") - self.add_cmd_output("/usr/symclisympd list") - self.add_cmd_output("/usr/symclisympd list -vcm") - self.add_cmd_output("/usr/symclisymdev list") - self.add_cmd_output("/usr/symclisymdev -v list") - self.add_cmd_output("/usr/symclisymdev -rdfa list") - self.add_cmd_output("/usr/symclisymdev -rdfa -v list") - self.add_cmd_output("/usr/symclisymbcv list") - self.add_cmd_output("/usr/symclisymbcv -v list") - self.add_cmd_output("/usr/symclisymrdf list") - self.add_cmd_output("/usr/symclisymrdf -v list") - self.add_cmd_output("/usr/symclisymrdf -rdfa list") - self.add_cmd_output("/usr/symclisymrdf -rdfa -v list") - self.add_cmd_output("/usr/symclisymsnap list") - self.add_cmd_output("/usr/symclisymsnap list -savedevs") - self.add_cmd_output("/usr/symclisymclone list") - self.add_cmd_output("/usr/symclisymevent list") - self.add_cmd_output("/usr/symclisymmask list hba") - self.add_cmd_output("/usr/symclisymmask list logins") - self.add_cmd_output("/usr/symclisymmaskdb list database") - self.add_cmd_output("/usr/symclisymmaskdb -v list database") + self.add_cmd_output("symclisymcli -def") + self.add_cmd_output("symclisymdg list") + self.add_cmd_output("symclisymdg -v list") + self.add_cmd_output("symclisymcg list") + self.add_cmd_output("symclisymcg -v list") + self.add_cmd_output("symclisymcfg list") + self.add_cmd_output("symclisymcfg -v list") + self.add_cmd_output("symclisymcfg -db") + self.add_cmd_output("symclisymcfg -semaphores list") + self.add_cmd_output("symclisymcfg -dir all -v list") + self.add_cmd_output("symclisymcfg -connections list") + self.add_cmd_output("symclisymcfg -app -v list") + self.add_cmd_output("symclisymcfg -fa all -port list") + self.add_cmd_output("symclisymcfg -ra all -port list") + self.add_cmd_output("symclisymcfg -sa all -port list") + self.add_cmd_output("symclisymcfg list -lock") + self.add_cmd_output("symclisymcfg list -lockn all") + self.add_cmd_output("symclisyminq") + self.add_cmd_output("symclisyminq -v") + self.add_cmd_output("symclisyminq -symmids") + self.add_cmd_output("symclisyminq hba -fibre") + self.add_cmd_output("symclisyminq hba -scsi") + self.add_cmd_output("symclisymhost show -config") + self.add_cmd_output("symclistordaemon list") + self.add_cmd_output("symclistordaemon -v list") + self.add_cmd_output("symclisympd list") + self.add_cmd_output("symclisympd list -vcm") + self.add_cmd_output("symclisymdev list") + self.add_cmd_output("symclisymdev -v list") + self.add_cmd_output("symclisymdev -rdfa list") + self.add_cmd_output("symclisymdev -rdfa -v list") + self.add_cmd_output("symclisymbcv list") + self.add_cmd_output("symclisymbcv -v list") + self.add_cmd_output("symclisymrdf list") + self.add_cmd_output("symclisymrdf -v list") + self.add_cmd_output("symclisymrdf -rdfa list") + self.add_cmd_output("symclisymrdf -rdfa -v list") + self.add_cmd_output("symclisymsnap list") + self.add_cmd_output("symclisymsnap list -savedevs") + self.add_cmd_output("symclisymclone list") + self.add_cmd_output("symclisymevent list") + self.add_cmd_output("symclisymmask list hba") + self.add_cmd_output("symclisymmask list logins") + self.add_cmd_output("symclisymmaskdb list database") + self.add_cmd_output("symclisymmaskdb -v list database") def get_navicli_config(self): """ EMC Navisphere Host Agent NAVICLI specific information - files @@ -129,19 +129,19 @@ class emc(Plugin, RedHatPlugin): def get_navicli_SP_info(self,SP_address): """ EMC Navisphere Host Agent NAVICLI specific information - CLARiiON - commands """ - self.add_cmd_output("/opt/Navispherenavicli -h %s getall" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s getsptime -spa" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s getsptime -spb" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s getlog" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s getdisk" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s getcache" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s getlun" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s getlun -rg -type -default -owner -crus -capacity" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s lunmapinfo" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s getcrus" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s port -list -all" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s storagegroup -list" % SP_address) - self.add_cmd_output("/opt/Navispherenavicli -h %s spportspeed -get" % SP_address) + self.add_cmd_output("navicli -h %s getall" % SP_address) + self.add_cmd_output("navicli -h %s getsptime -spa" % SP_address) + self.add_cmd_output("navicli -h %s getsptime -spb" % SP_address) + self.add_cmd_output("navicli -h %s getlog" % SP_address) + self.add_cmd_output("navicli -h %s getdisk" % SP_address) + self.add_cmd_output("navicli -h %s getcache" % SP_address) + self.add_cmd_output("navicli -h %s getlun" % SP_address) + self.add_cmd_output("navicli -h %s getlun -rg -type -default -owner -crus -capacity" % SP_address) + self.add_cmd_output("navicli -h %s lunmapinfo" % SP_address) + self.add_cmd_output("navicli -h %s getcrus" % SP_address) + self.add_cmd_output("navicli -h %s port -list -all" % SP_address) + self.add_cmd_output("navicli -h %s storagegroup -list" % SP_address) + self.add_cmd_output("navicli -h %s spportspeed -get" % SP_address) def check_enabled(self): self.packages = [ "EMCpower" ] @@ -194,7 +194,7 @@ class emc(Plugin, RedHatPlugin): while CLARiiON_IP_loop == "stay_in": ans = raw_input("CLARiiON SP IP Address or [Enter] to exit: ") ## Check to make sure the CLARiiON SP IP address provided is valid - p = Popen("/opt/Navispherenavicli -h %s getsptime" % (ans,), shell=True, stdout=PIPE, stderr=PIPE) + p = Popen("navicli -h %s getsptime" % (ans,), shell=True, stdout=PIPE, stderr=PIPE) out, err = p.communicate() if p.returncode == 0: CLARiiON_IP_address_list.append(ans) diff --git a/sos/plugins/ftp.py b/sos/plugins/ftp.py index 7dc4676d..693b8cbd 100644 --- a/sos/plugins/ftp.py +++ b/sos/plugins/ftp.py @@ -13,7 +13,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -from os.path import exists class ftp(Plugin, RedHatPlugin): """FTP server related information diff --git a/sos/plugins/general.py b/sos/plugins/general.py index 2bbf3203..557e7db9 100644 --- a/sos/plugins/general.py +++ b/sos/plugins/general.py @@ -52,7 +52,7 @@ class General(Plugin): self.add_cmd_output("dmesg") self.add_cmd_output("alternatives --display java", root_symlink="java") - self.add_cmd_output("readlink -f /usrjava") + self.add_cmd_output("readlink -f /usr/bin/java") self.add_cmd_output("tree /var/lib") self.add_cmd_output("ls -lR /var/lib") @@ -98,7 +98,6 @@ class DebianGeneral(General, DebianPlugin): self.add_copy_specs([ "/etc/debian_version", "/etc/default", - "/var/log/up2date", "/etc/lsb-release" ]) class UbuntuGeneral(General, UbuntuPlugin): @@ -107,19 +106,20 @@ class UbuntuGeneral(General, UbuntuPlugin): def setup(self): super(UbuntuGeneral, self).setup() self.add_copy_specs([ + "/etc/default", + "/etc/lsb-release", "/etc/os-release", - "/var/log/ufw.log", - "/var/log/apport.log", - "/var/log/syslog", - "/var/log/udev", - "/var/log/boot*", - "/var/log/dmesg*", - "/var/log/kern*", - "/var/log/mail*", - "/var/log/dist-upgrade", - "/var/log/landscape", - "/var/log/installer", - "/var/log/unattended-upgrades", - "/var/log/upstart" + "/var/log/apport.log", + "/var/log/syslog", + "/var/log/udev", + "/var/log/boot*", + "/var/log/dmesg*", + "/var/log/kern*", + "/var/log/mail*", + "/var/log/dist-upgrade", + "/var/log/landscape", + "/var/log/installer", + "/var/log/unattended-upgrades", + "/var/log/upstart" ]) - self.add_cmd_output("ufw app list",root_symlink="ufw") + diff --git a/sos/plugins/hardware.py b/sos/plugins/hardware.py index 10601f67..92c84829 100644 --- a/sos/plugins/hardware.py +++ b/sos/plugins/hardware.py @@ -49,23 +49,16 @@ class hardware(Plugin): self.add_cmd_output("dmidecode", root_symlink = "dmidecode") - if os.path.exists("cpufreq-info"): - self.add_cmd_output("cpufreq-info") - if os.path.exists("cpupower"): - self.add_cmd_output("cpupower info") - self.add_cmd_output("cpupower frequency-info") + self.add_cmd_output("cpufreq-info") + self.add_cmd_output("cpupower info") + self.add_cmd_output("cpupower frequency-info") if self.policy().get_arch().endswith("386"): self.add_cmd_output("x86info -a") - if os.path.exists("lsusb"): - lsusb_path = "lsusb" - else: - lsusb_path = "lsusb" - - self.add_cmd_output("%s"% lsusb_path) - self.add_cmd_output("%s -v"% lsusb_path) - self.add_cmd_output("%s -t"% lsusb_path) + self.add_cmd_output("lsusb") + self.add_cmd_output("lsusb -v") + self.add_cmd_output("lsusb -t") self.add_cmd_output("lshal") self.add_cmd_output("systool -c fc_host -v") @@ -78,7 +71,7 @@ class RedHatHardware(hardware, RedHatPlugin): def setup(self): super(RedHatHardware, self).setup() hwpaths = glob("/usr/share/rhn/up2date*client/hardware.py") - if (len(hwpaths) == 0): + if (len(hwpaths) == 0): return self.add_cmd_output(hwpaths[0]) diff --git a/sos/plugins/ipa.py b/sos/plugins/ipa.py index 1adbe162..3bbf71cd 100644 --- a/sos/plugins/ipa.py +++ b/sos/plugins/ipa.py @@ -15,7 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -from os.path import exists class Ipa(Plugin, RedHatPlugin): """IPA diagnostic information diff --git a/sos/plugins/iscsi.py b/sos/plugins/iscsi.py index 22e37bd7..2a49ee4c 100644 --- a/sos/plugins/iscsi.py +++ b/sos/plugins/iscsi.py @@ -13,7 +13,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin +from sos.plugins import Plugin, RedHatPlugin class Iscsi(Plugin): """iscsi-initiator related information diff --git a/sos/plugins/iscsitarget.py b/sos/plugins/iscsitarget.py index 284fe36b..1657e6cb 100644 --- a/sos/plugins/iscsitarget.py +++ b/sos/plugins/iscsitarget.py @@ -17,30 +17,31 @@ from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class iscsitarget(Plugin): +class Iscsitarget(Plugin): """iscsi-target related information """ plugin_name = "iscsitarget" -class RedHatIscsiTarget(Plugin, RedHatPlugin): +class RedHatIscsiTarget(Iscsitarget, RedHatPlugin): """iscsi-target related information for Red Hat distributions """ packages = ('scsi-target-utils',) def setup(self): + super(RedHatIscsiTarget, self).setup() self.add_copy_spec("/etc/tgt/targets.conf") self.add_cmd_output("tgtadm --lld iscsi --op show --mode target") -class DebianIscsiTarget(iscsitarget, DebianPlugin, UbuntuPlugin): +class DebianIscsiTarget(Iscsitarget, DebianPlugin, UbuntuPlugin): """iscsi-target related information for Debian based distributions """ packages = ('iscsitarget',) def setup(self): - super(DebianIscsi, self).setup() + super(DebianIscsiTarget, self).setup() self.add_copy_specs([ "/etc/iet", "/etc/sysctl.d/30-iscsitarget.conf", diff --git a/sos/plugins/jboss.py b/sos/plugins/jboss.py deleted file mode 100644 index f36ba1d0..00000000 --- a/sos/plugins/jboss.py +++ /dev/null @@ -1,713 +0,0 @@ -import os -import zipfile -import platform -import fnmatch -import shlex -import subprocess -import string -import grp, pwd - -from sos.plugins import Plugin, RedHatPlugin -from sos.utilities import DirTree, find - -class jboss(Plugin, RedHatPlugin): - """JBoss related information - """ - - option_list = [("home", 'JBoss\'s installation dir (i.e. JBOSS_HOME)', '', False), - ("javahome", 'Java\'s installation dir (i.e. JAVA_HOME)', '', False), - ("profile", 'Quoted and space separated list of server profiles to limit collection. \ -Default=\'all default minimal production standard web\'.', '', False), - ("user", 'JBoss JMX invoker user to be used with twiddle.', '', False), - ("pass", 'JBoss JMX invoker user\'s password to be used with twiddle.', '', False), - ("logsize", 'max size (MiB) to collect per log file', '', 15), - ("stdjar", 'Collect jar statistics for standard jars.', '', True), - ("servjar", 'Collect jar statistics from any server configuration dirs.', '', True), - ("twiddle", 'Collect twiddle data.', '', True), - ("appxml", 'Quoted and space separated list of application\'s whose XML descriptors you want. The keyword \"all\" will collect all descriptors in the designated profile(s).', '', False)] - - __MD5_CHUNK_SIZE=128 - __jbossHome=None - __haveJava=False - __twiddleCmd=None - __jbossSystemJarDirs = [ "client", "lib" , "common/lib" ] - __jbossServerConfigDirs = ["all", "default", "minimal", "production", "standard", "web"] - __jbossHTMLBody=None - - def __getJbossHome(self): - """ - Will attempt to locate the JBoss installation dir in either jboss.home or - scrape it from the environment variable JBOSS_HOME. - Returns: - True JBOSS_HOME is set and the path exists. False otherwise. - """ - if self.get_option("home"): - ## Prefer this value first over the ENV - self.__jbossHome=self.get_option("home") - self.add_alert("INFO: The JBoss installation directory supplied to SOS is " + - self.__jbossHome) - elif os.environ.get("JBOSS_HOME"): - self.__jbossHome=os.environ.get("JBOSS_HOME") - self.add_alert("INFO: The JBoss installation directory (i.e. JBOSS_HOME) from the environment is " + - self.__jbossHome) - else: - self.add_alert("ERROR: The JBoss installation directory was not supplied.\ - The JBoss SOS plug-in cannot continue.") - return False - - if os.path.exists(self.__jbossHome): - ## We need to set JBOSS_CLASSPATH otherwise some twiddle commands will not work. - jbossClasspath=None - tmp=os.path.join(self.__jbossHome, "lib") - if os.path.exists(tmp): - jbossClasspath=tmp + os.sep + "*" + os.pathsep - else: - self.add_alert("WARN: The JBoss lib directory does not exist. Dir(%s) " % tmp) - - tmp=os.path.join(self.__jbossHome, "common" , "lib") - if os.path.exists(tmp): - jbossClasspath+=tmp + os.sep + "*" - else: - self.add_alert("WARN: The JBoss lib directory does not exist. Dir(%s) " % tmp) - - os.environ['JBOSS_CLASSPATH']=jbossClasspath - - return True - else: - msg = "ERROR: The path to the JBoss installation directory does not exist. Path is: " + self.__jbossHome - print msg - self.add_alert(msg) - return False - - def __getJavaHome(self): - """ - This SOS plug-in makes extensive use of JBoss' twiddle program and twiddle uses Java. As such, we - need to ensure that java and JAVA_HOME is known to the plug-in so that it can use Java. - This function will put JAVA_HOME and JAVA_HOME/bin into the environment if they're not already - there. - """ - javaHome=None - java="bin/java" - - if self.get_option("javahome"): - ## Prefer this value first over the ENV - javaHome=self.get_option("javahome") - self.add_alert("INFO: The Java installation directory supplied to SOS is " + - javaHome) - elif os.environ.get("JAVA_HOME"): - javaHome=os.environ.get("JAVA_HOME") - self.add_alert("INFO: The Java installation directory (i.e. JAVA_HOME) from the environment is " + - javaHome) - else: - ## Test to see if Java is already in the PATH - (status, output, rtime) = self.call_ext_prog("java -version") - if (status == 0): - self.add_alert("INFO: The Java installation directory is in the system path.") - return True - else: - self.add_alert("ERROR: The Java installation directory was not supplied.\ - The JBoss SOS plug-in will not collect twiddle data.") - return False - - - java=os.path.join(javaHome, java) - if os.path.exists(java) and os.access(java, os.X_OK): - os.environ['JAVA_HOME']=javaHome - ## Place the supplied Java at the *head* of the path. - os.environ['PATH'] = os.path.join(javaHome, "bin") + os.pathsep + os.environ['PATH'] - return True - else: - msg = "ERROR: The path to the Java installation directory does not exist. Path is: %s" % (javaHome) - print msg - self.add_alert(msg) - return False - - - def __getJMXCredentials(self): - """ - Read the JMX credentials from the option list. - Returns: - A formatted credential string for twiddle consumption if both user and pass - are supplied. None otherwise. - """ - credential = None - ## Let's make a best effort not to pass expansions or escapes to the shell - ## by strong quoting the user's input - if self.get_option("user"): - credential=" -u '" + self.get_option("user") + "' " - if self.get_option("pass"): - credential+=" -p '" + self.get_option("pass") + "' " - else: - credential=None - return credential - - def __updateServerConfigDirs(self): - """ - By default this plug-in will attempt to collect logs from every - JBoss server configuration directory (i.e. profile). The - user may have supplied a limited list, as such, we must respect - that wish. - Returns: - Nothing. Will update __jbossServerConfigDirs if the user - supplied a limited list. - """ - if self.get_option("profile"): - profiles=self.get_option("profile") - ## I'd rather use comma as the delimiter but get_option doesn't seem to be passing it through. - ## Since we are using spaces as the delimiter, we need to filter out empty list elements - ## if the user did something like ' all default web '. - profiles=profiles.split(' ') - ## Flter(None doesn't work. Allows 0. - self.__jbossServerConfigDirs=filter(lambda x: len(x), profiles) - return - - def __buildTwiddleCmd(self): - """ - Utility function to build the twiddle command with/without credentials - so that it can be used by later fcns. If twiddle is found - """ - ## In the off-chance that SOS is ever ported to cygwin or this plugin - ## is ported to win... - if platform.system() == "Windows": - self.__twiddleCmd=os.path.join(self.__jbossHome, "bin", "twiddle.bat") - else: - self.__twiddleCmd=os.path.join(self.__jbossHome, "bin", "twiddle.sh") - - if os.path.exists(self.__twiddleCmd) and os.access(self.__twiddleCmd, os.X_OK): - credential = self.__getJMXCredentials() - if credential: - self.__twiddleCmd += credential - else: - ## Reset twiddlecmd to None - self.add_alert("ERROR: The twiddle program could not be found. Program=%s" % (self.__twiddleCmd)) - self.__twiddleCmd = None - - return - - def __createHTMLBodyStart(self): - """ - The free-form HTML that can be inserted into the SOS report with add_custom_text is within - a <p> block. We need to add a few pieces of HTML so that all of our subsequent data will - be rendered properly. - """ - self.__jbossHTMLBody = """ - <br/> - <br/> - <script type="text/javascript"> - <!-- - function show(h) { - var tbl = document.getElementById(h); - tbl.style.display = 'block'; - } - function hide(h) { - var tbl = document.getElementById(h); - tbl.style.display = 'none'; - } - // --> - </script> - <b>JBoss SOS Report Table of Contents</b> - <ul style="list-style-type: square"> - <li><a href="#system-jar-info">JBoss System Jar Information</a> - </li> - <li><a href="#profile-jar-info">JBoss Server Configurations Jar Information</a> - </li> - <li><a href="#jboss-home-directory-tree">JBOSS_HOME Directory Tree</a> - </li> - <li><a href="#jboss-system-mbean-data">JBoss JMX MBean Data from <tt>jboss.system:*</tt></a> - </li> - <li><a href="#jboss-mbean-data">JBoss JMX MBean Data from <tt>jboss:*</tt></a> - </li> - <li><a href="#jboss-mbean-summary">JBoss MBean Summary</a> - </li> - <li><a href="#jboss-messaging">JBoss JMX Messaging MBean Data from <tt>jboss.messaging:*</tt></a> - </li> - <li><a href="#jboss-j2ee">JBoss JMX J2EE MBean Data from <tt>jboss.j2ee:*</tt></a> - </li> - <li><a href="#jboss-vfs">JBoss JMX VFS MBean Data from <tt>jboss.vfs:*</tt></a> - </li> - <li><a href="#jboss-jsr77-data">JBoss JSR77 Data</a> - </li> - </ul> - <br/> - <br/> - """ - - def __getMd5(self, file): - """ - Will perform an MD5 sum on a given file and return the file's message digest. This function - will not read the entire file into memory, instead, it will consume the file in 128 byte - chunks. This might be slightly slower but, the intent of a SOS report is to collect data from - a system that could be under stress and we shouldn't stress it more by loading entire Jars into - real memory. - - Note: This fcn expects hashlib; however, this isn't always available. If it isn't then - we will use md5sum - """ - - retVal="????????????????????????????????" - - try: - import hashlib - try: - fd = open(file,"rb") - except IOError, ioe: - msg = "ERROR: Unable to open %s for reading. Error: " % (file,ioe) - print msg - self.add_alert(msg) - - md5 = hashlib.md5() - data = fd.read(self.__MD5_CHUNK_SIZE) - while data: - md5.update(data) - data = fd.read(self.__MD5_CHUNK_SIZE) - retVal = md5.hexdigest() - except ImportError, e: - process = subprocess.Popen(['md5sum', file], - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - result = process.communicate() - if (process.returncode == 0): - retVal = result[0].partition(' ')[0] - else: - msg = "ERROR: Unable to compute md5sum of %s. Msg (%s)" % (file, result[1]) - print msg - self.add_alert(msg) - - return retVal - - - def __getManifest(self, jarFile): - """ - Given a jar file, this function will extract the Manifest and return it's contents - as a string. - """ - manifest=None - try: - zf = zipfile.ZipFile(jarFile) - try: - manifest=zf.read("META-INF/MANIFEST.MF") - except Exception, e: - msg="ERROR: reading manifest from %s. Error: %s" % (jarFile, e) - print msg - self.add_alert(msg) - zf.close() - except Exception, e: - msg="ERROR: reading contents of %s. Error: %s" % (jarFile, e) - print msg - self.add_alert(msg) - return manifest - - def __getStdJarInfo(self): - - self.__jbossHTMLBody += """ - <div id="system-jar-info" style="font-weight: bold;">– JBoss System Jar Information</div> - """ - - for dir in self.__jbossSystemJarDirs: - path=os.path.join(self.__jbossHome, dir) - if os.path.exists(path): - nicePath=path.replace(os.sep, "-") - self.__jbossHTMLBody += """ - <div> - — Summary of Jar Files in JBoss System Directory - <tt>%s</tt> - ( <a href="javascript:show('%s')">Show</a> / <a - href="javascript:hide('%s')">Hide</a> ): - </div> - <div id="%s" style="overflow: hidden; display: none"> - <ul style="list-style-type: square"> - """ % (path,nicePath,nicePath,nicePath) - - found= False - for jarFile in find("*.jar", path): - found= True - nicePath=jarFile.replace(os.sep, "-") - self.__jbossHTMLBody += """ - <li>Jar File: <tt>%s</tt><br/> - MD5: <tt>%s</tt> - <br /> Manifest File ( - <a href="javascript:show('%s')">Show</a> / - <a href="javascript:hide('%s')">Hide</a> ):<br /> - <div id="%s" style="overflow: hidden; display: none"> - <pre> - %s - </pre> - </div> - </li> - """ % (jarFile, - self.__getMd5(jarFile), - nicePath, - nicePath, - nicePath, - self.__getManifest(jarFile)) - - if not found: - self.add_alert("WARN: No jars found in JBoss system path (" + path + ").") - self.__jbossHTMLBody += """ - </ul> - </div> - """ - else: - self.add_alert("ERROR: JBoss system path (" + path + ") does not exist.") - return - - def __getServerConfigJarInfo(self, configDirAry): - - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="profile-jar-info" style="font-weight: bold;">– JBoss Server Configurations Jar Information</div> - """ - for dir in configDirAry: - serverDir = os.path.join("server", dir) - path=os.path.join(self.__jbossHome, serverDir) - if os.path.exists(path): - nicePath=path.replace(os.sep, "-") - self.__jbossHTMLBody += """ - <div> - — Summary of Jar Files in the <tt>%s</tt> JBoss Server Configuration - ( <a href="javascript:show('%s')">Show</a> / <a - href="javascript:hide('%s')">Hide</a> ): - </div> - <div id="%s" style="overflow: hidden; display: none"> - <ul style="list-style-type: square"> - """ % (dir, nicePath,nicePath,nicePath) - - found = False - for jarFile in find("*.jar", path): - found = True - nicePath=jarFile.replace(os.sep, "-") - self.__jbossHTMLBody += """ - <li id="system-jar-info">Jar File: <tt>%s</tt><br/> - MD5: <tt>%s</tt> - <br /> Manifest File ( - <a href="javascript:show('%s')">Show</a> / - <a href="javascript:hide('%s')">Hide</a> ):<br /> - <div id="%s" style="overflow: hidden; display: none"> - <pre> - %s - </pre> - </div> - </li> - """ % (jarFile, - self.__getMd5(jarFile), - nicePath, - nicePath, - nicePath, - self.__getManifest(jarFile)) - - if not found: - self.add_alert("WARN: No jars found in the JBoss server configuration (%s)." % (path)) - - self.__jbossHTMLBody += """ - </ul> -</div> - """ - else: - self.add_alert("ERROR: JBoss server configuration path (" + path + ") does not exist.") - - return - - def __getJBossHomeTree(self): - """ - This function will execute the "tree" command on JBOSS_HOME. - """ - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="jboss-home-directory-tree" style="font-weight: bold;">– JBOSS_HOME Directory Tree</div> - - <div> - — JBOSS_HOME Tree - ( <a href="javascript:show('jboss-home-tree')">Show</a> / <a - href="javascript:hide('jboss-home-tree')">Hide</a> ): - </div> - <div id="jboss-home-tree" style="overflow: hidden; display: none"> - <pre> - """ - try: - output = DirTree(self.__jbossHome).as_string() - self.__jbossHTMLBody += """ -%s - </pre> - </div> - """ % (output) - except Exception, e: - self.__jbossHTMLBody += """ - ERROR: Unable to generate <tt>tree</tt> on JBOSS_HOME. - Exception: %s - </pre> - </div> - """ % e - return - - def __getMbeanData(self, dataTitle, divId, twiddleOpts): - credentials = "" - if self.__haveJava and self.__twiddleCmd: - self.__jbossHTMLBody += """ - <div> - — %s - ( <a href="javascript:show('%s')">Show</a> / <a - href="javascript:hide('%s')">Hide</a> ): - </div> - <div id="%s" style="overflow: hidden; display: none"> - <table style="margin-left: 30px;font-size:14px"> - <tr> - <td align="left"> - Twiddle Options: - </td> - <td align="left"><tt>%s</tt></td> - </tr> - </table> - <pre> - - """ % (dataTitle, divId, divId, divId,twiddleOpts) - cmd = "%s %s" % (self.__twiddleCmd, twiddleOpts) - - proc = subprocess.Popen(shlex.split(cmd), stderr=subprocess.STDOUT, stdout=subprocess.PIPE) - output = proc.communicate()[0] - status = proc.returncode - if status == 0 and output: - self.__jbossHTMLBody += output.strip() - else: - self.__jbossHTMLBody += """ - ERROR: Unable to collect %s data. - Output: %s - Status: %d - """ % (twiddleOpts, output, status) - else: - self.__jbossHTMLBody += "ERROR: Unable to collect data twiddle or Java is missing." - - self.__jbossHTMLBody += """ - </pre> - </div> - """ - return - - def __getTwiddleData(self): - """ - This function co-locates all of the calls to twiddle so that they can be easily disabled. - """ - - ## Get jboss.system.* Data - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="jboss-system-mbean-data" style="font-weight: bold;">– JBoss JMX MBean Data from <tt>jboss.system:*</tt></div> - """ - self.__getMbeanData("JBoss Server Info", - "jboss-server-info", - " get 'jboss.system:type=ServerInfo' ") - self.__getMbeanData("JBoss Server Config Info", - "jboss-server-config-info", - " get 'jboss.system:type=ServerConfig' ") - self.__getMbeanData("JBoss CXF Server Config Info", - "jboss-cxfserver-config-info", - " get 'jboss.ws:service=ServerConfig' ") - self.__getMbeanData("JBoss Memory Pool Info", - "jboss-memory-pool-info", - " invoke 'jboss.system:type=ServerInfo' listMemoryPools true ") - self.__getMbeanData("JBoss Thread CPU Utilization", - "jboss-thread-cpu-info", - " invoke 'jboss.system:type=ServerInfo' listThreadCpuUtilization ") - self.__getMbeanData("JBoss Thread Dump", - "jboss-thread-dump", - " invoke 'jboss.system:type=ServerInfo' listThreadDump ") - self.__getMbeanData("JBoss Logging Config Info", - "jboss-logging-config-info", - " get 'jboss.system:service=Logging,type=Log4jService' ") - - ## Get jboss.* Data - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="jboss-mbean-data" style="font-weight: bold;">– JBoss JMX MBean Data from <tt>jboss:*</tt></div> - """ - self.__getMbeanData("JBoss System Properties", - "jboss-system-properties-info", - " invoke 'jboss:name=SystemProperties,type=Service' showAll ") - - self.__getMbeanData("JBoss JNDI List View", - "jboss-jndi-list-info", - " invoke 'jboss:service=JNDIView' list true ") - - ## MBean Summary - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="jboss-mbean-summary" style="font-weight: bold;">– JBoss MBean Summary</div> - """ - self.__getMbeanData("JBoss MBean Vendor/Version Info", - "jboss-vendor-version", - " get 'JMImplementation:type=MBeanServerDelegate' ") - self.__getMbeanData("JBoss MBean Count", - "jboss-mbean-count", - " serverinfo -c ") - self.__getMbeanData("JBoss MBean List", - "jboss-mbean-list", - " serverinfo -l ") - - ##JBoss Messaging Data - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="jboss-messaging" style="font-weight: bold;">– JBoss JMX Messaging MBean Data from <tt>jboss.messaging:*</tt></div> - """ - self.__getMbeanData("JBoss Message Counters", - "jboss-message-counters", - " invoke 'jboss.messaging:service=ServerPeer' listMessageCountersAsHTML ") - - self.__getMbeanData("JBoss Prepared Transactions Table", - "jboss-prepared-transactions", - " invoke 'jboss.messaging:service=ServerPeer' listAllPreparedTransactions ") - - self.__getMbeanData("JBoss Active Clients Table", - "jboss-active-clients", - " invoke 'jboss.messaging:service=ServerPeer' showActiveClientsAsHTML ") - - ## Get j2ee Data query 'jboss.j2ee:*' - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="jboss-j2ee" style="font-weight: bold;">– JBoss JMX J2EE MBean Data from <tt>jboss.j2ee:*</tt></div> - """ - self.__getMbeanData("JBoss J2EE MBeans", - "jboss-j2ee-mbeans", - " query 'jboss.j2ee:*' ") - - ## VFS - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="jboss-vfs" style="font-weight: bold;">– JBoss JMX VFS MBean Data from <tt>jboss.vfs:*</tt></div> - """ - self.__getMbeanData("JBoss VFS Cached Contexts", - "jboss-vfs-contexts", - " invoke 'jboss.vfs:service=VFSCacheStatistics' listCachedContexts ") - - ## Get jsr77 Data - self.__jbossHTMLBody += """ - <br/> - <br/> - <div id="jboss-jsr77-data" style="font-weight: bold;">– JBoss JSR77 Data</div> - """ - self.__getMbeanData("JBoss JSR77 Data", - "jboss-jsr77", - " jsr77 ") - return - - - def __getFiles(self, configDirAry): - """ - This function will collect files from JBOSS_HOME for analysis. The scope of files to - be collected are determined by options to this SOS plug-in. - """ - - for dir in configDirAry: - path=os.path.join(self.__jbossHome, "server", dir) - ## First add forbidden files - self.add_forbidden_path(os.path.join(path, "tmp")) - self.add_forbidden_path(os.path.join(path, "work")) - self.add_forbidden_path(os.path.join(path, "data")) - - if os.path.exists(path): - ## First get everything in the conf dir - confDir=os.path.join(path, "conf") - self.do_copy_file_or_dir(confDir) - ## Log dir next - logDir=os.path.join(path, "log") - - for logFile in find("*", logDir): - self.add_copy_spec_limit(logFile, self.get_option("logsize")) - ## Deploy dir - deployDir=os.path.join(path, "deploy") - - for deployFile in find("*", deployDir, max_depth=1): - self.add_copy_spec(deployFile) - - ## Get application deployment descriptors if designated. - if self.option_enabled("appxml"): - appxml=self.get_option("appxml") - ## I'd rather use comma as the delimiter but get_option doesn't seem to be passing it through. - ## Since we are using spaces as the delimiter, we need to filter out empty list elements - ## if the user did something like ' all default web '. - appxml=appxml.split(' ') - ## Flter(None doesn't work. Allows 0. - appxml=filter(lambda x: len(x), appxml) - for app in appxml: - pat = os.path.join("*%s*" % (app,), "WEB-INF") - for file in find("*.xml", deployDir, path_pattern=pat): - self.add_copy_spec(file) - return - - def check_enabled(self): - if not self.__getJbossHome(): - return False - return True - - def setup(self): - - ## We need to know where JBoss is installed and if we can't find it we - ## must exit immediately. - if not self.__getJbossHome(): - self.exit_please() - return - - ## Check to see if the user passed in a limited list of server config jars. - self.__updateServerConfigDirs() - - ## Generate HTML Body for report - self.__createHTMLBodyStart() - - ## Generate hashes of the stock Jar files for the report. - if self.get_option("stdjar"): - self.__getStdJarInfo() - - ## Generate hashes for the Jars in the various profiles - if self.get_option("servjar"): - self.__getServerConfigJarInfo(self.__jbossServerConfigDirs) - - ## Generate a Tree for JBOSS_HOME - self.__getJBossHomeTree() - - if self.get_option("twiddle"): - ## We need to know where Java is installed or at least ensure that it - ## is available to the plug-in so that we can run twiddle. - self.__haveJava = self.__getJavaHome() - self.__buildTwiddleCmd() - self.__getTwiddleData() - - - self.add_custom_text(self.__jbossHTMLBody) - - self.__getFiles(self.__jbossServerConfigDirs) - - return - - def postproc(self): - """ - Obfuscate passwords. - """ - - for dir in self.__jbossServerConfigDirs: - path=os.path.join(self.__jbossHome, "server", dir) - ## Really annoying that there appears to be no vehicle to - ## say I want ignore case...argh! - self.do_file_sub(os.path.join(path,"conf","login-config.xml"), - r"\"[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]\".*>.*</[Mm][Oo][Dd][Uu][Ll][Ee]-[Oo][Pp][Tt][Ii][Oo][Nn].*>", - r'"password">********</module-option>') - - tmp = os.path.join(path,"conf", "props") - for propFile in find("*-users.properties", tmp): - self.do_file_sub(propFile, - r"=(.*)", - r'=********') - - ## Remove PW from -ds.xml files - tmp=os.path.join(path, "deploy") - for dsFile in find("*-ds.xml", tmp): - self.do_file_sub(dsFile, - r"<[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd].*>.*</[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd].*>", - r"<password>********</password>") - return diff --git a/sos/plugins/kdump.py b/sos/plugins/kdump.py index 6cd7e89d..ebe17ede 100644 --- a/sos/plugins/kdump.py +++ b/sos/plugins/kdump.py @@ -13,7 +13,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -from os.path import exists class kdump(Plugin): """Kdump related information diff --git a/sos/plugins/kernel.py b/sos/plugins/kernel.py index eeaf7514..4ebf3575 100644 --- a/sos/plugins/kernel.py +++ b/sos/plugins/kernel.py @@ -13,7 +13,7 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -import os, re +import os class kernel(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): """kernel related information @@ -35,8 +35,6 @@ class kernel(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): self.add_cmd_output("modinfo " + runcmd) self.add_cmd_output("sysctl -a") - if os.path.isfile("ksyms"): - self.add_cmd_output("ksyms") self.add_copy_specs([ "/proc/sys/kernel/random/boot_id", "/sys/module/*/parameters", diff --git a/sos/plugins/landscape.py b/sos/plugins/landscape.py index f544ebb7..c31dea70 100644 --- a/sos/plugins/landscape.py +++ b/sos/plugins/landscape.py @@ -13,7 +13,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, UbuntuPlugin -import os class Landscape(Plugin, UbuntuPlugin): """ @@ -69,4 +68,4 @@ class Landscape(Plugin, UbuntuPlugin): r"registration_password[***]" ) -
\ No newline at end of file + diff --git a/sos/plugins/ldap.py b/sos/plugins/ldap.py index dff5d625..3fce4278 100644 --- a/sos/plugins/ldap.py +++ b/sos/plugins/ldap.py @@ -12,15 +12,15 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import os -class ldap(Plugin, RedHatPlugin): +class Ldap(Plugin): """LDAP related information """ - files = ('/etc/openldap/ldap.conf',) - packages = ('openldap', 'nss-pam-ldapd') + plugin_name = "ldap" + ldap_conf = "/etc/openldap/ldap.conf" def get_ldap_opts(self): # capture /etc/openldap/ldap.conf options in dict @@ -29,14 +29,38 @@ class ldap(Plugin, RedHatPlugin): results={} tmplist=[] for i in ldapopts: - t=self.do_regex_find_all(r"^(%s)\s+(.*)" % i,"/etc/openldap/ldap.conf") + t=self.do_regex_find_all(r"^(%s)\s+(.*)" % i,self.ldap_conf) for x in t: results[x[0]]=x[1].rstrip("\n") return results def setup(self): + super(Ldap, self).setup() + +class RedHatLdap(Ldap, RedHatPlugin): + """LDAP related information for RedHat based distribution + """ + + packages = ('openldap', 'nss-pam-ldapd') + + def setup(self): + super(RedHatLdap, self).setup() self.add_copy_specs(["/etc/ldap.conf", "/etc/openldap", "/etc/nslcd.conf"]) def postproc(self): self.do_file_sub("/etc/ldap.conf", r"(\s*bindpw\s*)\S+", r"\1***") self.do_file_sub("/etc/nslcd.conf", r"(\s*bindpw\s*)\S+", r"\1***") + +class DebianLdap(Ldap, DebianPlugin, UbuntuPlugin): + """LDAP related information for Debian based distribution + """ + + ldap_conf = "/etc/ldap/ldap.conf" + packages = ('slapd', 'ldap-utils') + + def setup(self): + super(DebianLdap, self).setup() + + def setup(self): + self.add_copy_specs(["/etc/ldap/ldap.conf", "/etc/ldap/slapd.d"]) + diff --git a/sos/plugins/logrotate.py b/sos/plugins/logrotate.py index 3a56a549..960e4b7e 100644 --- a/sos/plugins/logrotate.py +++ b/sos/plugins/logrotate.py @@ -12,9 +12,9 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class logrotate(Plugin, RedHatPlugin): +class logrotate(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): """logrotate configuration files and debug info """ diff --git a/sos/plugins/lsbrelease.py b/sos/plugins/lsbrelease.py index eee68e16..e3e996e9 100644 --- a/sos/plugins/lsbrelease.py +++ b/sos/plugins/lsbrelease.py @@ -13,10 +13,10 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import os -class lsbrelease(Plugin, RedHatPlugin): +class lsbrelease(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): """Linux Standard Base information """ diff --git a/sos/plugins/mysql.py b/sos/plugins/mysql.py index 1437c162..e3c971fe 100644 --- a/sos/plugins/mysql.py +++ b/sos/plugins/mysql.py @@ -12,19 +12,41 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin from os.path import exists -class mysql(Plugin, RedHatPlugin): +class Mysql(Plugin): """MySQL related information """ - files = ('/etc/my.cnf',) + plugin_name = "mysql" + mysql_cnf = "/etc/my.cnf" + + def setup(self): + super(Mysql, self).setup() + self.add_copy_specs([self.mysql_cnf, + "/var/log/mysql*"]) + + +class RedHatMysql(Mysql, RedHatPlugin): + """MySQL related information for RedHat based distributions + """ + packages = ('mysql-server', 'mysql') def setup(self): - self.add_copy_specs([ - "/etc/my.cnf", - "/etc/sysconfig/network", - "/etc/ld.so.conf.d/mysql*", - "/var/log/mysql*"]) + self.mysql_cnf = "/etc/my.cnf" + super(RedHatMysql, self).setup() + self.add_copy_spec("/etc/ld.so.conf.d/mysql*") + + +class DebianMysql(Mysql, DebianPlugin, UbuntuPlugin): + """MySQL related information for Debian based distributions + """ + + packages = ('mysql-server', 'mysql-common') + + def setup(self): + self.mysql_cnf = "/etc/mysql/my.cnf" + super(DebianMysql, self).setup() + self.add_copy_spec("/etc/mysql/conf.d/mysql*") diff --git a/sos/plugins/named.py b/sos/plugins/named.py index 812e20da..8a347f8e 100644 --- a/sos/plugins/named.py +++ b/sos/plugins/named.py @@ -12,40 +12,74 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import commands -from os.path import normpath, join, exists -class named(Plugin, RedHatPlugin): +class Named(Plugin): """named related information """ - files = ('/etc/named.conf', '/etc/sysconfig/named') - packages = ('bind',) + plugin_name = "named" + named_conf = "/etc/named.conf" + config_files = named_conf + + def setup(self): + for cfg in config_files: + if exists(cfg): + self.add_copy_spec(cfg) + self.add_copy_spec(self.get_dns_dir(cfg)) + self.add_forbidden_path(join(self.get_dns_dir(cfg), + "chroot/dev")) + self.add_forbidden_path(join(self.get_dns_dir(cfg), + "chroot/proc")) def get_dns_dir(self, config_file): """ grab directory path from named{conf,boot} """ directory_list = self.do_regex_find_all("directory\s+\"(.*)\"", config_file) - return normpath(directory_list[0]) + if directory_list: + return normpath(directory_list[0]) + else: + return "" - def setup(self): - config_files = ("/etc/named.conf", + def postproc(self): + match = r"(\s*arg \"password )[^\"]*" + subst = r"\1******" + self.do_file_sub(named_conf, match, subst) + + +class RedHatNamed(Named, RedHatPlugin): + """named related information for RedHat based distribution + """ + + named_conf = "/etc/named.conf" + config_files = ("/etc/named.conf", "/etc/named.boot") - for cfg in config_files: - if exists(cfg): - self.add_copy_spec(cfg) - self.add_copy_spec(self.get_dns_dir(cfg)) - self.add_forbidden_path(join(self.get_dns_dir(cfg),"chroot/dev")) - self.add_forbidden_path(join(self.get_dns_dir(cfg),"chroot/proc")) + files = (named_conf, '/etc/sysconfig/named') + packages = ('bind',) + def setup(self): + super(RedHatNamed, self).setup() self.add_copy_spec("/etc/named/") self.add_copy_spec("/etc/sysconfig/named") self.add_cmd_output("klist -ket /etc/named.keytab") self.add_forbidden_path("/etc/named.keytab") return - def postproc(self): - match = r"(\s*arg \"password )[^\"]*" - subst = r"\1******" - self.do_file_sub("/etc/named.conf", match, subst) + +class DebianNamed(Named, DebianPlugin, UbuntuPlugin): + """named related information for Debian based distribution + """ + + files = ('/etc/bind/named.conf') + packages = ('bind9',) + named_conf = "/etc/bind/named.conf" + config_files = (named_conf, + "/etc/bind/named.conf.options", + "/etc/bind/named.conf.local") + + def setup(self): + super(DebianNamed, self).setup() + self.add_copy_spec("/etc/bind/") + return + diff --git a/sos/plugins/netdump.py b/sos/plugins/netdump.py index 235dd5f7..964e14e8 100644 --- a/sos/plugins/netdump.py +++ b/sos/plugins/netdump.py @@ -13,7 +13,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -from os.path import exists class netdump(Plugin, RedHatPlugin): """Netdump Configuration Information diff --git a/sos/plugins/networking.py b/sos/plugins/networking.py index 3ff8fe7a..a7e07a80 100644 --- a/sos/plugins/networking.py +++ b/sos/plugins/networking.py @@ -12,14 +12,20 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import os import re -class networking(Plugin, RedHatPlugin): +class Networking(Plugin): """network related information """ - option_list = [("traceroute", "collects a traceroute to rhn.redhat.com", "slow", False)] + plugin_name = "networking" + trace_host = "www.example.com" + option_list = [("traceroute", "collects a traceroute to %s" % trace_host, + "slow", False)] + + def setup(self): + super(Networking, self).setup() def get_bridge_name(self,brctl_out): """Return a list for which items are bridge name according to the @@ -28,8 +34,8 @@ class networking(Plugin, RedHatPlugin): out=[] for line in brctl_out[1].splitlines(): if line.startswith("bridge name") \ - or line.isspace() \ - or line[:1].isspace(): + or line.isspace() \ + or line[:1].isspace(): continue br_name, br_rest = line.split(None, 1) out.append(br_name) @@ -69,7 +75,12 @@ class networking(Plugin, RedHatPlugin): "/etc/xinetd.conf", "/etc/xinetd.d", "/etc/host*", - "/etc/resolv.conf"]) + "/etc/resolv.conf" + "/etc/network*", + "/etc/NetworkManager/NetworkManager.conf", + "/etc/NetworkManager/system-connections", + "/etc/dnsmasq*"]) + ip_addr_file=self.get_cmd_output_now("ip -o addr", root_symlink = "ip_addr") ip_addr_out=self.call_ext_prog("ip -o addr") self.add_cmd_output("route -n", root_symlink = "route") @@ -96,8 +107,6 @@ class networking(Plugin, RedHatPlugin): self.add_cmd_output("ethtool -a "+eth) self.add_cmd_output("ethtool -c "+eth) self.add_cmd_output("ethtool -g "+eth) - if self.get_option("traceroute"): - self.add_cmd_output("traceroute -n rhn.redhat.com") if os.path.exists("brctl"): brctl_file=self.add_cmd_output("brctl show") @@ -105,5 +114,39 @@ class networking(Plugin, RedHatPlugin): if brctl_out: for br_name in self.get_bridge_name(brctl_out): self.add_cmd_output("brctl showstp "+br_name) + + if self.get_option("traceroute"): + self.add_cmd_output("/bin/traceroute -n %s" % trace_host) + return + def postproc(self): + for root, dirs, files in os.walk("/etc/NetworkManager/system-connections"): + for net_conf in files: + self.do_file_sub("/etc/NetworkManager/system-connections/"+net_conf, r"psk=(.*)",r"psk=***") + +class RedHatNetworking(Networking, RedHatPlugin): + """network related information for RedHat based distribution + """ + trace_host = "rhn.redhat.com" + def setup(self): + super(RedHatNetworking, self).setup() + +class UbuntuNetworking(Networking, UbuntuPlugin): + """network related information for Ubuntu based distribution + """ + trace_host = "archive.ubuntu.com" + + def setup(self): + super(UbuntuNetworking, self).setup() + + self.add_copy_specs([ + "/etc/resolvconf", + "/etc/ufw", + "/var/log/ufw.Log", + "/etc/resolv.conf"]) + self.add_cmd_output("/usr/sbin/ufw status") + self.add_cmd_output("/usr/sbin/ufw app list") + if self.get_option("traceroute"): + self.add_cmd_output("/usr/sbin/traceroute -n %s" % trace_host) + diff --git a/sos/plugins/nis.py b/sos/plugins/nis.py index 4f4d6258..8f98d325 100644 --- a/sos/plugins/nis.py +++ b/sos/plugins/nis.py @@ -15,10 +15,10 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import os -class nis(Plugin, RedHatPlugin): +class nis(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): """NIS related information """ diff --git a/sos/plugins/ntp.py b/sos/plugins/ntp.py index 45f428d9..dff9f985 100644 --- a/sos/plugins/ntp.py +++ b/sos/plugins/ntp.py @@ -12,14 +12,36 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class ntp(Plugin, RedHatPlugin): +class Ntp(Plugin): """NTP related information """ + plugin_name = "ntp" + packages = ('ntp',) def setup(self): - self.add_cmd_output("ntpstat") + self.add_copy_spec("/etc/ntp.conf") self.add_cmd_output("ntptime") + + +class RedHatNtp(Ntp, RedHatPlugin): + """NTP related information for RedHat based distributions + """ + + def setup(self): + super(RedHatNtp, self).setup() + self.add_copy_spec("/etc/sysconfig/ntpd") + self.add_cmd_output("ntpstat") + + +class DebianNtp(Ntp, DebianPlugin, UbuntuPlugin): + """NTP related information for Debian based distributions + """ + + def setup(self): + super(DebianNtp, self).setup() + self.add_copy_spec('/etc/default/ntp') + diff --git a/sos/plugins/openswan.py b/sos/plugins/openswan.py index d57a8db6..2c4a1c01 100644 --- a/sos/plugins/openswan.py +++ b/sos/plugins/openswan.py @@ -15,7 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -from os.path import exists class openswan(Plugin, RedHatPlugin): """ipsec related information diff --git a/sos/plugins/pam.py b/sos/plugins/pam.py index 701f0c8b..307a405b 100644 --- a/sos/plugins/pam.py +++ b/sos/plugins/pam.py @@ -12,12 +12,34 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class pam(Plugin, RedHatPlugin): +class Pam(Plugin): """PAM related information """ + + plugin_name = "pam" + security_libs = "" + def setup(self): self.add_copy_spec("/etc/pam.d") self.add_copy_spec("/etc/security") - self.add_cmd_output("ls -lanF /lib*/security") + self.add_cmd_output("ls -lanF %s" % self.security_libs) + +class RedHatPam(Pam, RedHatPlugin): + """PAM related information for RedHat based distribution + """ + security_libs = "/lib*/security" + + def setup(self): + super(RedHatPam, self).setup() + + +class DebianPam(Pam, DebianPlugin, UbuntuPlugin): + """PAM related information for Debian based distribution + """ + security_libs = "/lib/x86_64-linux-gnu/security" + + def setup(self): + super(DebianPam, self).setup() + diff --git a/sos/plugins/postfix.py b/sos/plugins/postfix.py index d2c3c8fc..6f0f9b4d 100644 --- a/sos/plugins/postfix.py +++ b/sos/plugins/postfix.py @@ -12,19 +12,39 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin from os.path import exists -class postfix(Plugin, RedHatPlugin): +class Postfix(Plugin): """mail server related information """ + plugin_name = "postfix" - files = ('/etc/rc.d/init.d/postfix',) packages = ('postfix',) def setup(self): self.add_copy_specs([ - "/etc/mail", "/etc/postfix/main.cf", "/etc/postfix/master.cf"]) self.add_cmd_output("postconf") + +class RedHatPostfix(Postfix, RedHatPlugin): + """mail server related information for RedHat based distributions + """ + + files = ('/etc/rc.d/init.d/postfix',) + packages = ('postfix',) + + def setup(self): + super(RedHatPostfix, self).setup() + self.add_copy_spec("/etc/mail") + +class DebianPostfix(Postfix, DebianPlugin, UbuntuPlugin): + """mail server related information for Debian based Distribution + """ + + packages = ('postfix',) + + def setup(self): + super(DebianPostfix, self).setup() + self.add_copy_spec("/etc/postfix/dynamicmaps.cf") diff --git a/sos/plugins/postgresql.py b/sos/plugins/postgresql.py index 1ae269fb..0a8e5ac3 100644 --- a/sos/plugins/postgresql.py +++ b/sos/plugins/postgresql.py @@ -1,15 +1,14 @@ import os -import fnmatch -import shlex -import subprocess import tempfile -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, UbuntuPlugin, DebianPlugin from sos.utilities import find -class postgresql(Plugin, RedHatPlugin): +class PostgreSQL(Plugin): """PostgreSQL related information""" + plugin_name = "postgresql" + packages = ('postgresql',) tmp_dir = None @@ -44,6 +43,17 @@ class postgresql(Plugin, RedHatPlugin): else: self.add_alert("WARN: password must be supplied to dump a database.") + def postproc(self): + import shutil + if self.tmp_dir: + shutil.rmtree(self.tmp_dir) + +class RedHatPostgreSQL(PostgreSQL, RedHatPlugin): + """PostgreSQL related information for Red Hat distributions""" + + def setup(self): + super(RedHatPostgreSQL, self).setup() + # Copy PostgreSQL log files. for file in find("*.log", self.get_option("pghome")): self.add_copy_spec(file) @@ -54,8 +64,22 @@ class postgresql(Plugin, RedHatPlugin): self.add_copy_spec(os.path.join(self.get_option("pghome"), "data" , "PG_VERSION")) self.add_copy_spec(os.path.join(self.get_option("pghome"), "data" , "postmaster.opts")) +class DebianPostgreSQL(PostgreSQL, DebianPlugin, UbuntuPlugin): + """PostgreSQL related information for Debian/Ubuntu distributions""" + + def setup(self): + super(DebianPostgreSQL, self).setup() + + # Copy PostgreSQL log files. + self.add_copy_spec("/var/log/postgresql/*.log") + # Copy PostgreSQL config files. + self.add_copy_spec("/etc/postgresql/*/main/*.conf") + + self.add_copy_spec("/var/lib/postgresql/*/main/PG_VERSION") + self.add_copy_spec("/var/lib/postgresql/*/main/postmaster.opts") + + + + + - def postproc(self): - import shutil - if self.tmp_dir: - shutil.rmtree(self.tmp_dir) diff --git a/sos/plugins/ppp.py b/sos/plugins/ppp.py index 207071c5..76e44046 100644 --- a/sos/plugins/ppp.py +++ b/sos/plugins/ppp.py @@ -15,7 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -from os.path import exists class ppp(Plugin, RedHatPlugin): """ppp, wvdial and rp-pppoe related information diff --git a/sos/plugins/process.py b/sos/plugins/process.py index 83e8f588..3b06c7c4 100644 --- a/sos/plugins/process.py +++ b/sos/plugins/process.py @@ -13,10 +13,9 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -import time import os -class process(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): +class Process(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): """process information """ def setup(self): @@ -25,7 +24,3 @@ class process(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): self.add_cmd_output("ps alxwww") self.add_cmd_output("pstree", root_symlink = "pstree") self.add_cmd_output("lsof -b +M -n -l", root_symlink = "lsof") - - def find_mountpoint(s): - if (os.path.ismount(s) or len(s)==0): return s - else: return mountpoint(os.path.split(s)[0]) diff --git a/sos/plugins/psacct.py b/sos/plugins/psacct.py index 528f141c..74bd9f06 100644 --- a/sos/plugins/psacct.py +++ b/sos/plugins/psacct.py @@ -12,9 +12,9 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class psacct(Plugin, RedHatPlugin): +class Psacct(Plugin): """Process accounting related information """ @@ -23,7 +23,29 @@ class psacct(Plugin, RedHatPlugin): packages = [ "psacct" ] + +class RedHatPsacct(Psacct, RedHatPlugin): + """Process accounting related information for RedHat based distributions + """ + plugin_name = "psacct" + + packages = [ "psacct" ] + def setup(self): + super(RedHatPsacct, self).setup() self.add_copy_spec("/var/account/pacct") if self.get_option("all"): self.add_copy_spec("/var/account/pacct*.gz") + +class DebianPsacct(Psacct, DebianPlugin, UbuntuPlugin): + """Process accounting related information for Debian based distributions + """ + + plugin_name = "acct" + packages = [ "acct" ] + + def setup(self): + super(DebianPsacct, self).setup() + self.add_copy_specs(["/var/log/account/pacct", "/etc/default/acct"]) + if self.get_option("all"): + self.add_copy_spec("/var/log/account/pacct*.gz") diff --git a/sos/plugins/pxe.py b/sos/plugins/pxe.py index 082db155..fcb1a4b7 100644 --- a/sos/plugins/pxe.py +++ b/sos/plugins/pxe.py @@ -12,19 +12,42 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin from os.path import exists -class pxe(Plugin, RedHatPlugin): +class Pxe(Plugin): """PXE related information """ - option_list = [("tftpboot", 'gathers content in /tftpboot', 'slow', False)] - files = ('pxeos',) + option_list = [("tftpboot", 'gathers content from the tftpboot path', + 'slow', False)] + plugin_name = "pxe" + + +class RedHatPxe(Pxe, RedHatPlugin): + """PXE related information for RedHat based distributions + """ + + files = ('/usr/sbin/pxeos',) packages = ('system-config-netboot-cmd',) def setup(self): - self.add_cmd_output("pxeos -l") + super(RedHatPxe, self).setup() + self.add_cmd_output("/usr/sbin/pxeos -l") self.add_copy_spec("/etc/dhcpd.conf") if self.get_option("tftpboot"): self.add_copy_spec("/tftpboot") + + +class DebianPxe(Pxe, DebianPlugin, UbuntuPlugin): + """PXE related information for Ubuntu based distributions + """ + + packages = ('tftpd-hpa',) + + def setup(self): + super(DebianPxe, self).setup() + self.add_copy_spec("/etc/dhcp/dhcpd.conf") + self.add_copy_spec("/etc/default/tftpd-hpa") + if self.get_option("tftpboot"): + self.add_copy_spec("/var/lib/tftpboot") diff --git a/sos/plugins/quagga.py b/sos/plugins/quagga.py index 28ba983f..703b4a54 100644 --- a/sos/plugins/quagga.py +++ b/sos/plugins/quagga.py @@ -15,7 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -from os.path import exists class quagga(Plugin, RedHatPlugin): """quagga related information diff --git a/sos/plugins/radius.py b/sos/plugins/radius.py index 972b179c..e814526e 100644 --- a/sos/plugins/radius.py +++ b/sos/plugins/radius.py @@ -15,7 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -from os.path import exists class radius(Plugin): """radius related information diff --git a/sos/plugins/s390.py b/sos/plugins/s390.py index 26698ebc..82164a4d 100644 --- a/sos/plugins/s390.py +++ b/sos/plugins/s390.py @@ -14,7 +14,6 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -import os from sos.plugins import Plugin, RedHatPlugin class s390(Plugin, RedHatPlugin): diff --git a/sos/plugins/samba.py b/sos/plugins/samba.py index 23f3d7b4..d4e2fe82 100644 --- a/sos/plugins/samba.py +++ b/sos/plugins/samba.py @@ -12,17 +12,34 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class samba(Plugin, RedHatPlugin): +class Samba(Plugin): """Samba related information """ + plugin_name = "samba" + def setup(self): self.add_copy_specs([ "/etc/samba", - "/var/log/samba/*", - "/etc/krb5.conf", - "/etc/krb5.keytab"]) + "/var/log/samba/*",]) self.add_cmd_output("wbinfo -g") self.add_cmd_output("wbinfo -u") self.add_cmd_output("testparm -s -v") + + +class RedHatSamba(Samba, RedHatPlugin): + """Samba related information for RedHat based distributions + """ + def setup(self): + super(RedHatSamba, self).setup() + # FIXME: krb5 specific + self.add_copy_specs([ + "/etc/krb5.conf", + "/etc/krb5.keytab"]) + +class DebianSamba(Samba, DebianPlugin, UbuntuPlugin): + """Samba related information for Debian based distributions + """ + def setup(self): + super(DebianSamba, self).setup() diff --git a/sos/plugins/sar.py b/sos/plugins/sar.py index 8bb9c37f..4e6cf51c 100644 --- a/sos/plugins/sar.py +++ b/sos/plugins/sar.py @@ -15,43 +15,45 @@ from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import os -class sar(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): - """Generate the sar file from /var/log/sa/saXX files +class Sar(Plugin,): + """ Collect system activity reporter data """ - sapath='/var/log/sa' - sarcmd='sar' - files = (sapath, sarcmd) + packages = ('sysstat',) + sa_path = '/var/log/sa' - def setup(self): + def check_enabled(self): # check to see if we are force-enabled with no sar installation - if not os.path.exists(self.sapath) or not os.path.isdir(self.sapath): - self.soslog.error( - "sar directory %s does not exist or is not a directory" - % self.sapath) - return - - if not os.path.exists(self.sarcmd) \ - or not os.access(self.sarcmd, os.X_OK): - self.soslog.error( - "sar command %s does not exist or is not runnable" - % self.sarcmd) - return - - # catch exceptions here to avoid races - try: - dir_list=os.listdir(self.sapath) - except Exception, e: - self.soslog.error("sar path %s cannot be read: %s" - % (self.sapath, e)) - return + if not os.path.exists(self.sa_path) or not os.path.isdir(self.sa_path): + self.soslog.info("sar directory %s does not exist" % self.sa_path + + " or is not a directory") + return False + return True + def setup(self): + dirList = os.listdir(self.sa_path) # find all the sa file that don't have an existing sar file - for fname in dir_list: + for fname in dirList: if fname[0:2] == 'sa' and fname[2] != 'r': sar_filename = 'sar' + fname[2:4] - if sar_filename not in dir_list: - sar_command = "sh -c \"LANG=C sar " \ - + "-A -f /var/log/sa/" + fname + "\"" - self.add_cmd_output(sar_command, sar_filename) - self.add_copy_spec("/var/log/sa/sar*") + sa_data_path = os.path.join(self.sa_path, fname) + if sar_filename not in dirList: + sar_cmd = 'sh -c "LANG=C sar -A -f %s"' % sa_data_path + self.add_cmd_output(sar_cmd, sar_filename) + sadf_cmd = "sadf -x %s" % sa_data_path + self.add_cmd_output(sadf_cmd, "%s.xml" % fname) + self.add_copy_spec(os.path.join(self.sa_path, "sar*")) + + +class RedHatSar(Sar, RedHatPlugin): + """ Collect system activity reporter data + """ + + sa_path = '/var/log/sa' + + +class DebianSar(Sar, DebianPlugin, UbuntuPlugin): + """ Collect system activity reporter data + """ + + sa_path = '/var/log/sysstat' diff --git a/sos/plugins/selinux.py b/sos/plugins/selinux.py index bbcf7b71..d35010a7 100644 --- a/sos/plugins/selinux.py +++ b/sos/plugins/selinux.py @@ -17,30 +17,17 @@ from sos.plugins import Plugin, RedHatPlugin class selinux(Plugin, RedHatPlugin): """selinux related information """ + option_list = [("fixfiles", 'Print incorrect file context labels', 'slow', False)] + packages = ('libselinux',) + def setup(self): # sestatus is always collected in check_enabled() self.add_copy_spec("/etc/selinux") if self.get_option('fixfiles'): - self.add_cmd_output("fixfiles check") - self.add_forbidden_path("/etc/selinux/targeted") - - if not self.policy().pkg_by_name('setroubleshoot'): - return + self.add_cmd_output("fixfiles -v check") + self.add_cmd_output("sestatus -b") + self.add_cmd_output("selinuxdefcon root") + self.add_cmd_output("selinuxconlist root") + self.add_cmd_output("selinuxexeccon /bin/passwd") - # Check for SELinux denials and capture raw output from sealert - if self.policy().default_runlevel() in self.policy().runlevel_by_service("setroubleshoot"): - # TODO: fixup regex for more precise matching - sealert=do_regex_find_all(r"^.*setroubleshoot:.*(sealert\s-l\s.*)","/var/log/messages") - if sealert: - for i in sealert: - self.add_cmd_output("%s" % i) - self.add_alert("There are numerous selinux errors present and "+ - "possible fixes stated in the sealert output.") - def check_enabled(self): - try: - if self.get_cmd_output_now("sestatus", root_symlink = "sestatus").split(":")[1].strip() == "disabled": - return False - except: - pass - return True diff --git a/sos/plugins/sendmail.py b/sos/plugins/sendmail.py index 1b52a6af..4efbf95d 100644 --- a/sos/plugins/sendmail.py +++ b/sos/plugins/sendmail.py @@ -14,15 +14,36 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin from os.path import exists -class sendmail(Plugin, RedHatPlugin): +class Sendmail(Plugin): """sendmail information """ + plugin_name = "sendmail" + + packages = ('sendmail',) + + +class RedHatSendmail(Sendmail, RedHatPlugin): + """sendmail information for RedHat based distributions + """ + files = ('/etc/rc.d/init.d/sendmail',) packages = ('sendmail',) def setup(self): + super(RedHatSendmail, self).setup() self.add_copy_specs(["/etc/mail/*", "/var/log/maillog"]) + +class DebianSendmail(Sendmail, DebianPlugin, UbuntuPlugin): + """sendmail information for Debian based distributions + """ + + files = ('/etc/init.d/sendmail',) + packages = ('sendmail',) + + def setup(self): + super(DebianSendmail, self).setup() + self.add_copy_specs(["/etc/mail/*", "/var/log/mail.*"]) diff --git a/sos/plugins/smartcard.py b/sos/plugins/smartcard.py index 6975b0aa..969aa611 100644 --- a/sos/plugins/smartcard.py +++ b/sos/plugins/smartcard.py @@ -15,8 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -import os -from time import time class smartcard(Plugin, RedHatPlugin): """Smart Card related information diff --git a/sos/plugins/snmp.py b/sos/plugins/snmp.py index 63aac8e6..177c0e26 100644 --- a/sos/plugins/snmp.py +++ b/sos/plugins/snmp.py @@ -14,15 +14,33 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin from os.path import exists -class snmp(Plugin, RedHatPlugin): +class Snmp(Plugin): """snmp related information """ + plugin_name = "snmp" files = ('/etc/snmp/snmpd.conf',) - packages = ('net-snmp',) def setup(self): self.add_copy_spec("/etc/snmp") + +class RedHatSnmp(Snmp, RedHatPlugin): + """snmp related information for RedHat based distributions + """ + + packages = ('net-snmp',) + + def setup(self): + super(RedHatSnmp, self).setup() + +class DebianSnmp(Snmp, DebianPlugin, UbuntuPlugin): + """snmp related information for Debian based distributions + """ + + packages = ('snmp',) + + def setup(self): + super(DebianSnmp, self).setup() diff --git a/sos/plugins/soundcard.py b/sos/plugins/soundcard.py index 0a01499c..b92b4c51 100644 --- a/sos/plugins/soundcard.py +++ b/sos/plugins/soundcard.py @@ -12,23 +12,43 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import os -class soundcard(Plugin, RedHatPlugin): +class Soundcard(Plugin): """ Sound card information """ + plugin_name = "soundcard" + def default_enabled(self): return False def setup(self): - self.add_copy_specs([ - "/proc/asound/*", - "/etc/alsa/*", - "/etc/asound.*"]) + self.add_copy_spec("/proc/asound/*") self.add_cmd_output("lspci | grep -i audio") self.add_cmd_output("aplay -l") self.add_cmd_output("aplay -L") self.add_cmd_output("amixer") - self.add_cmd_output("lsmod | grep snd | awk '{print $1}'", suggest_filename = "sndmodules_loaded") + self.add_cmd_output("lsmod | grep snd | awk '{print $1}'",\ + suggest_filename = "sndmodules_loaded") + +class RedHatSoundcard(Soundcard, RedHatPlugin): + """ Sound card information for RedHat distros + """ + + def setup(self): + super(RedHatSoundcard, self).setup() + + self.add_copy_specs([ + "/etc/alsa/*", + "/etc/asound.*"]) + +class DebianSoundcard(Soundcard, DebianPlugin, UbuntuPlugin): + """ Sound card information for Debian/Ubuntu distros + """ + + def setup(self): + super(DebianSoundcard, self).setup() + + self.add_copy_spec("/etc/pulse/*") diff --git a/sos/plugins/squid.py b/sos/plugins/squid.py index a83c45a1..dae5759f 100644 --- a/sos/plugins/squid.py +++ b/sos/plugins/squid.py @@ -13,7 +13,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -import os class squid(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): """squid related information diff --git a/sos/plugins/startup.py b/sos/plugins/startup.py index 18326f35..76d85efe 100644 --- a/sos/plugins/startup.py +++ b/sos/plugins/startup.py @@ -12,17 +12,37 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -class startup(Plugin, RedHatPlugin): +class Startup(Plugin): """startup information """ + plugin_name = "startup" + option_list = [("servicestatus", "get a status of all running services", "slow", False)] def setup(self): + if self.get_option('servicestatus'): + self.add_cmd_output("/sbin/service --status-all") + self.add_cmd_output("/sbin/runlevel") + +class RedHatStartup(Startup, RedHatPlugin): + """startup information for RedHat based distributions + """ + + def setup(self): + super(RedHatStartup, self).setup() self.add_copy_spec("/etc/rc.d") + self.add_cmd_output("/sbin/chkconfig --list", root_symlink = "chkconfig") + +class DebianStartup(Startup, DebianPlugin, UbuntuPlugin): + """startup information + """ + + def setup(self): + super(DebianStartup, self).setup() + self.add_copy_spec("/etc/rc*.d") - self.add_cmd_output("chkconfig --list", root_symlink = "chkconfig") + self.add_cmd_output("/sbin/initctl show-config", root_symlink = "initctl") if self.get_option('servicestatus'): - self.add_cmd_output("service --status-all") - self.add_cmd_output("runlevel") + self.add_cmd_output("/sbin/initctl list") diff --git a/sos/plugins/sunrpc.py b/sos/plugins/sunrpc.py index 12277513..dff6ed80 100644 --- a/sos/plugins/sunrpc.py +++ b/sos/plugins/sunrpc.py @@ -14,7 +14,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin +from sos.plugins import Plugin, RedHatPlugin class sunrpc(Plugin): """Sun RPC related information diff --git a/sos/plugins/systemd.py b/sos/plugins/systemd.py index 84a3e759..046fb227 100644 --- a/sos/plugins/systemd.py +++ b/sos/plugins/systemd.py @@ -14,8 +14,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -import os +from sos.plugins import Plugin, RedHatPlugin class systemd(Plugin, RedHatPlugin): """ Information on systemd and related subsystems diff --git a/sos/plugins/tftpserver.py b/sos/plugins/tftpserver.py index 29324e42..4a4018f4 100644 --- a/sos/plugins/tftpserver.py +++ b/sos/plugins/tftpserver.py @@ -15,7 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -from os.path import exists class tftpserver(Plugin, RedHatPlugin): """tftpserver related information diff --git a/sos/plugins/vmware.py b/sos/plugins/vmware.py index 7e102c73..d7d39f82 100644 --- a/sos/plugins/vmware.py +++ b/sos/plugins/vmware.py @@ -13,7 +13,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -from os.path import exists class vmware(Plugin, RedHatPlugin): """VMWare related information diff --git a/sos/plugins/xinetd.py b/sos/plugins/xinetd.py index 0a8833e8..8c3945e0 100644 --- a/sos/plugins/xinetd.py +++ b/sos/plugins/xinetd.py @@ -15,7 +15,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin -import os class Xinetd(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): """xinetd information diff --git a/sos/plugins/yum.py b/sos/plugins/yum.py index d691c43c..18519df3 100644 --- a/sos/plugins/yum.py +++ b/sos/plugins/yum.py @@ -13,7 +13,6 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from sos.plugins import Plugin, RedHatPlugin -import os class Yum(Plugin, RedHatPlugin): """yum information diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py index 8148c894..522aaff5 100644 --- a/sos/policies/__init__.py +++ b/sos/policies/__init__.py @@ -5,6 +5,7 @@ import re import platform import time import fnmatch +import sys from os import environ from sos.utilities import ImporterHelper, \ diff --git a/sos/policies/debian.py b/sos/policies/debian.py index 409ba85a..b6009aa8 100644 --- a/sos/policies/debian.py +++ b/sos/policies/debian.py @@ -16,6 +16,10 @@ class DebianPolicy(LinuxPolicy): def __init__(self): super(DebianPolicy, self).__init__() + self.report_name = "" + self.ticket_number = "" + self.package_manager = PackageManager("dpkg-query -W -f='${Package}|${Version}\\n' \*") + self.valid_subclasses = [DebianPlugin] @classmethod def check(self): diff --git a/sos/policies/ubuntu.py b/sos/policies/ubuntu.py index 97f2d14a..c9a8177b 100644 --- a/sos/policies/ubuntu.py +++ b/sos/policies/ubuntu.py @@ -2,17 +2,17 @@ from __future__ import with_statement import os -from sos.plugins import UbuntuPlugin, IndependentPlugin +from sos.plugins import UbuntuPlugin, DebianPlugin, IndependentPlugin from sos.policies.debian import DebianPolicy class UbuntuPolicy(DebianPolicy): distro = "Ubuntu" vendor = "Ubuntu" vendor_url = "http://www.ubuntu.com/" - valid_subclasses = [UbuntuPlugin] def __init__(self): super(UbuntuPolicy, self).__init__() + self.valid_subclasses = [DebianPlugin, UbuntuPlugin] @classmethod def check(self): diff --git a/sos/sosreport.py b/sos/sosreport.py index 37b7f67f..9a72b142 100644 --- a/sos/sosreport.py +++ b/sos/sosreport.py @@ -285,15 +285,9 @@ class SoSReport(object): raise SystemExit() # sys.exit(error) - def _exit_nice(self): - for plugname, plugin in self.loaded_plugins: - plugin.exit_please() - self.ui_log.info("All processes ended, cleaning up.") - self._exit(1) - def get_exit_handler(self): def exit_handler(signum, frame): - self._exit_nice() + self._exit() return exit_handler def _read_config(self): diff --git a/sos/utilities.py b/sos/utilities.py index 64d0ce62..fcc78c54 100644 --- a/sos/utilities.py +++ b/sos/utilities.py @@ -35,10 +35,6 @@ import tarfile import hashlib import logging import fnmatch -try: - import selinux -except ImportError: - pass from contextlib import closing try: diff --git a/tests/test_exe.py b/tests/test_exe.py index f35d93f0..09b2813e 100755 --- a/tests/test_exe.py +++ b/tests/test_exe.py @@ -1,2 +1,2 @@ -#!/usr/bin/env python +#!/usr/bin/python print "executed" |