aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/src/lib
diff options
context:
space:
mode:
authorastokes_rhn <astokes_rhn@ef72aa8b-4018-0410-8976-d6e080ef94d8>2007-07-25 15:10:20 +0000
committerastokes_rhn <astokes_rhn@ef72aa8b-4018-0410-8976-d6e080ef94d8>2007-07-25 15:10:20 +0000
commit7e9c9b84a6449f70c768a2334c1a68ce73499cd0 (patch)
tree7072d53ee8d1ac0aa4d848dfc47640a6bbcde2ce /trunk/src/lib
parent28f13dc4aec9d474447a5021eb45409bcba81182 (diff)
downloadsos-7e9c9b84a6449f70c768a2334c1a68ce73499cd0.tar.gz
branching off for stokes work
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/sos/trunk@223 ef72aa8b-4018-0410-8976-d6e080ef94d8
Diffstat (limited to 'trunk/src/lib')
-rw-r--r--trunk/src/lib/sos/__init__.py0
-rwxr-xr-xtrunk/src/lib/sos/helpers.py120
-rw-r--r--trunk/src/lib/sos/plugins/__init__.py0
-rw-r--r--trunk/src/lib/sos/plugins/amd.py31
-rw-r--r--trunk/src/lib/sos/plugins/apache.py26
-rw-r--r--trunk/src/lib/sos/plugins/bootloader.py31
-rw-r--r--trunk/src/lib/sos/plugins/cluster.py78
-rw-r--r--trunk/src/lib/sos/plugins/devicemapper.py38
-rw-r--r--trunk/src/lib/sos/plugins/filesys.py47
-rw-r--r--trunk/src/lib/sos/plugins/ftp.py24
-rw-r--r--trunk/src/lib/sos/plugins/general.py43
-rw-r--r--trunk/src/lib/sos/plugins/hardware.py55
-rw-r--r--trunk/src/lib/sos/plugins/initrd.py28
-rw-r--r--trunk/src/lib/sos/plugins/kernel.py131
-rw-r--r--trunk/src/lib/sos/plugins/ldap.py27
-rw-r--r--trunk/src/lib/sos/plugins/libraries.py24
-rw-r--r--trunk/src/lib/sos/plugins/mail.py25
-rw-r--r--trunk/src/lib/sos/plugins/memory.py30
-rw-r--r--trunk/src/lib/sos/plugins/named.py36
-rw-r--r--trunk/src/lib/sos/plugins/networking.py75
-rw-r--r--trunk/src/lib/sos/plugins/nfsserver.py27
-rw-r--r--trunk/src/lib/sos/plugins/pam.py25
-rw-r--r--trunk/src/lib/sos/plugins/printing.py24
-rw-r--r--trunk/src/lib/sos/plugins/process.py24
-rw-r--r--trunk/src/lib/sos/plugins/radius.py29
-rw-r--r--trunk/src/lib/sos/plugins/rhn.py91
-rw-r--r--trunk/src/lib/sos/plugins/rpm.py33
-rw-r--r--trunk/src/lib/sos/plugins/samba.py26
-rw-r--r--trunk/src/lib/sos/plugins/satellite.py53
-rw-r--r--trunk/src/lib/sos/plugins/selinux.py36
-rw-r--r--trunk/src/lib/sos/plugins/sendmail.py27
-rw-r--r--trunk/src/lib/sos/plugins/squid.py23
-rw-r--r--trunk/src/lib/sos/plugins/ssh.py27
-rw-r--r--trunk/src/lib/sos/plugins/startup.py25
-rw-r--r--trunk/src/lib/sos/plugins/system.py31
-rw-r--r--trunk/src/lib/sos/plugins/systemtap.py29
-rw-r--r--trunk/src/lib/sos/plugins/x11.py26
-rw-r--r--trunk/src/lib/sos/plugins/xen.py82
-rw-r--r--trunk/src/lib/sos/plugins/xinetd.py27
-rw-r--r--trunk/src/lib/sos/plugins/yum.py37
-rw-r--r--trunk/src/lib/sos/plugintools.py568
-rwxr-xr-xtrunk/src/lib/sos/policyredhat.py151
42 files changed, 2290 insertions, 0 deletions
diff --git a/trunk/src/lib/sos/__init__.py b/trunk/src/lib/sos/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/trunk/src/lib/sos/__init__.py
diff --git a/trunk/src/lib/sos/helpers.py b/trunk/src/lib/sos/helpers.py
new file mode 100755
index 00000000..54a86dba
--- /dev/null
+++ b/trunk/src/lib/sos/helpers.py
@@ -0,0 +1,120 @@
+## helpers.py
+## Implement policies required for the sos system support tool
+
+## Copyright (C) 2006 Steve Conklin <sconklin@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+## Some code adapted from "Python Cookbook, 2nd ed", by Alex
+## Martelli, Anna Martelli Ravenscroft, and David Ascher
+## (O'Reilly Media, 2005) 0-596-00797-3
+##
+
+"""
+helper functions used by sosreport and plugins
+"""
+import os, popen2, fcntl, select, itertools, sys, commands
+from time import time
+from tempfile import mkdtemp
+
+def importPlugin(pluginname, name):
+ """ Import a plugin to extend capabilities of sosreport
+ """
+ try:
+ plugin = __import__(pluginname, globals(), locals(), [name])
+ except ImportError:
+ return None
+ return getattr(plugin, name)
+
+
+def sosFindTmpDir():
+ """Find a temp directory to form the root for our gathered information
+ and reports.
+ """
+ workingBase = mkdtemp("","sos_")
+ return workingBase
+
+
+def makeNonBlocking(afd):
+ """ Make the file descriptor non-blocking. This prevents deadlocks.
+ """
+ fl = fcntl.fcntl(afd, fcntl.F_GETFL)
+ try:
+ fcntl.fcntl(afd, fcntl.F_SETFL, fl | os.O_NDELAY)
+ except AttributeError:
+ fcntl.fcntl(afd, fcntl.F_SETFL, fl | os.FNDELAY)
+
+
+def sosGetCommandOutput(command):
+ """ Execute a command and gather stdin, stdout, and return status.
+ Adapted from Python Cookbook - O'Reilly
+ """
+ stime = time()
+ errdata = ''
+ status,outdata=commands.getstatusoutput(command)
+ return (status, outdata, time()-stime)
+
+
+# FIXME: this needs to be made clean and moved to the plugin tools, so
+# that it prints nice color output like sysreport if the progress bar
+# is not enabled.
+def sosStatus(stat):
+ """ Complete a status line that has been output to the console,
+ providing pass/fail indication.
+ """
+ if not stat:
+ print " [ OK ]"
+ else:
+ print " [ FAILED ]"
+ sys.stdout.flush()
+ return
+
+
+def allEqual(elements):
+ ''' return True if all the elements are equal, otherwise False. '''
+ first_element = elements[0]
+ for other_element in elements[1:]:
+ if other_element != first_element:
+ return False
+ return True
+
+
+def commonPrefix(*sequences):
+ ''' return a list of common elements at the start of all sequences,
+ then a list of lists that are the unique tails of each sequence. '''
+ # if there are no sequences at all, we're done
+ if not sequences:
+ return [], []
+ # loop in parallel on the sequences
+ common = []
+ for elements in itertools.izip(*sequences):
+ # unless all elements are equal, bail out of the loop
+ if not allEqual(elements):
+ break
+ # got one more common element, append it and keep looping
+ common.append(elements[0])
+ # return the common prefix and unique tails
+ return common, [ sequence[len(common):] for sequence in sequences ]
+
+def sosRelPath(path1, path2, sep=os.path.sep, pardir=os.path.pardir):
+ ''' return a relative path from path1 equivalent to path path2.
+ In particular: the empty string, if path1 == path2;
+ path2, if path1 and path2 have no common prefix.
+ '''
+ common, (u1, u2) = commonPrefix(path1.split(sep), path2.split(sep))
+ if not common:
+ return path2 # leave path absolute if nothing at all in common
+ return sep.join( [pardir]*len(u1) + u2 )
+
diff --git a/trunk/src/lib/sos/plugins/__init__.py b/trunk/src/lib/sos/plugins/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/__init__.py
diff --git a/trunk/src/lib/sos/plugins/amd.py b/trunk/src/lib/sos/plugins/amd.py
new file mode 100644
index 00000000..1b1375cc
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/amd.py
@@ -0,0 +1,31 @@
+## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class amd(sos.plugintools.PluginBase):
+ """Amd automounter information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/amd.*")
+ self.addCopySpec("/etc/rc.d/init.d/amd")
+ self.addCopySpec("/etc/sysconfig/amd")
+ self.collectExtOutput("/bin/rpm -qV am-utils")
+ self.collectExtOutput("/bin/egrep -e 'automount|pid.*nfs' /proc/mounts")
+ self.collectExtOutput("/bin/mount | egrep -e 'automount|pid.*nfs'")
+ self.collectExtOutput("/sbin/chkconfig --list amd")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/apache.py b/trunk/src/lib/sos/plugins/apache.py
new file mode 100644
index 00000000..c5250fd9
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/apache.py
@@ -0,0 +1,26 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+from threading import Thread
+
+class apache(sos.plugintools.PluginBase):
+ """Apache related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/httpd/conf/httpd.conf")
+ self.addCopySpec("/etc/httpd/conf.d/*.conf")
+ self.addCopySpec("/var/log/httpd/*")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/bootloader.py b/trunk/src/lib/sos/plugins/bootloader.py
new file mode 100644
index 00000000..a820069e
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/bootloader.py
@@ -0,0 +1,31 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class bootloader(sos.plugintools.PluginBase):
+ """Bootloader information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/lilo.conf")
+ self.addCopySpec("/etc/milo.conf")
+ self.addCopySpec("/etc/silo.conf")
+ self.addCopySpec("/boot/grub/grub.conf")
+ self.addCopySpec("/boot/grub/device.map")
+ self.addCopySpec("/boot/efi/elilo.conf")
+ self.addCopySpec("/boot/yaboot.conf")
+
+ self.collectExtOutput("/sbin/lilo -q")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/cluster.py b/trunk/src/lib/sos/plugins/cluster.py
new file mode 100644
index 00000000..595d940a
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/cluster.py
@@ -0,0 +1,78 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import commands, os
+
+class cluster(sos.plugintools.PluginBase):
+ """cluster suite and GFS related information
+ """
+ def checkenabled(self):
+ # enable if any related package is installed
+ for pkg in [ "ccs", "cman", "cman-kernel", "magma", "magma-plugins",
+ "rgmanager", "fence", "dlm", "dlm-kernel", "gulm",
+ "GFS", "GFS-kernel", "lvm2-cluster" ]:
+ if self.cInfo["policy"].pkgByName(pkg) != None:
+ return True
+
+ # enable if any related file is present
+ for fname in [ "/etc/cluster/cluster.conf" ]:
+ try: os.stat(fname)
+ except:pass
+ else: return True
+
+ # no data related to RHCS/GFS exists
+ return False
+
+ def diagnose(self):
+ rhelver = self.cInfo["policy"].pkgDictByName("fedora-release")[0]
+ if rhelver == "6":
+ # check if the minimum set of packages is installed
+ # for RHEL4 RHCS(ccs, cman, cman-kernel, magma, magma-plugins, (dlm, dlm-kernel) || gulm, perl-Net-Telnet, rgmanager, fence)
+ # RHEL4 GFS (GFS, GFS-kernel, ccs, lvm2-cluster, fence)
+ for pkg in [ "ccs", "cman", "cman-kernel", "magma", "magma-plugins", "perl-Net-Telnet", "rgmanager", "fence" ]:
+ if self.cInfo["policy"].pkgByName(pkg) == None:
+ self.addDiagnose("required package is missing: %s" % pkg)
+
+ # check if all the needed daemons are active at sosreport time
+ # check if they are started at boot time in RHEL4 RHCS (cman, ccsd, rgmanager, fenced)
+ # and GFS (gfs, ccsd, clvmd, fenced)
+ for service in [ "cman", "ccsd", "rgmanager", "fence" ]:
+ if commands.getstatus("/sbin/service %s status" % service):
+ self.addDiagnose("service %s is not running" % service)
+
+ if not self.cInfo["policy"].runlevelDefault() in self.cInfo["policy"].runlevelByService(service):
+ self.addDiagnose("service %s is not started in default runlevel" % service)
+
+ # FIXME: what locking are we using ? check if packages exist
+# if self.cInfo["policy"].pkgByName(pkg) and self.cInfo["policy"].pkgByName(pkg) and not self.cInfo["policy"].pkgByName(pkg)
+
+ def setup(self):
+ self.collectExtOutput("/sbin/fdisk -l")
+ self.addCopySpec("/etc/cluster.conf")
+ self.addCopySpec("/etc/cluster.xml")
+ self.addCopySpec("/etc/cluster")
+ self.collectExtOutput("/usr/sbin/rg_test test /etc/cluster/cluster.conf")
+ self.addCopySpec("/proc/cluster")
+ self.collectExtOutput("/usr/bin/cman_tool status")
+ self.collectExtOutput("/usr/bin/cman_tool services")
+ self.collectExtOutput("/usr/bin/cman_tool -af nodes")
+ self.collectExtOutput("/usr/bin/ccs_tool lsnode")
+ self.collectExtOutput("/usr/bin/openais-cfgtool -s")
+ self.collectExtOutput("/usr/bin/clustat")
+ return
+
+ def postproc(self):
+ self.doRegexSub("/etc/cluster/cluster.conf", r"(\s*\<fencedevice\s*.*\s*passwd\s*=\s*)\S+(\")", r"\1***")
+ return
diff --git a/trunk/src/lib/sos/plugins/devicemapper.py b/trunk/src/lib/sos/plugins/devicemapper.py
new file mode 100644
index 00000000..e517aa3d
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/devicemapper.py
@@ -0,0 +1,38 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class devicemapper(sos.plugintools.PluginBase):
+ """device-mapper related information (dm, lvm, multipath)
+ """
+ def setup(self):
+ self.collectExtOutput("/sbin/dmsetup info -c")
+ self.collectExtOutput("/sbin/dmsetup table")
+ self.collectExtOutput("/sbin/dmsetup status")
+
+ self.collectExtOutput("/usr/sbin/vgscan -vvv")
+ self.collectExtOutput("/usr/sbin/vgdisplay -vv", root_symlink = "vgdisplay")
+ self.collectExtOutput("/usr/sbin/pvscan -v")
+ self.collectExtOutput("/usr/sbin/lvs -a -o +devices")
+ self.collectExtOutput("/usr/sbin/pvs -a -v")
+ self.collectExtOutput("/usr/sbin/vgs -v")
+
+ self.addCopySpec("/etc/lvm/lvm.conf")
+
+ self.addCopySpec("/etc/multipath.conf")
+ self.addCopySpec("/var/lib/multipath/bindings")
+ self.collectExtOutput("/sbin/multipath -v4 -ll")
+
+ return
diff --git a/trunk/src/lib/sos/plugins/filesys.py b/trunk/src/lib/sos/plugins/filesys.py
new file mode 100644
index 00000000..02bde2eb
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/filesys.py
@@ -0,0 +1,47 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import commands
+
+class filesys(sos.plugintools.PluginBase):
+ """information on filesystems
+ """
+ def setup(self):
+ self.addCopySpec("/proc/filesystems")
+ self.addCopySpec("/etc/fstab")
+ self.addCopySpec("/proc/self/mounts")
+ self.addCopySpec("/proc/mounts")
+ self.addCopySpec("/proc/mdstat")
+ self.addCopySpec("/etc/raidtab")
+ self.addCopySpec("/etc/mdadm.conf")
+ self.addCopySpec("/etc/auto.master")
+ self.addCopySpec("/etc/auto.misc")
+ self.addCopySpec("/etc/auto.net")
+
+ self.collectExtOutput("/bin/df -al", root_symlink = "df")
+ self.collectExtOutput("/usr/sbin/lsof -b +M -n -l", root_symlink = "lsof")
+ self.collectExtOutput("/bin/mount -l", root_symlink = "mount")
+ self.collectExtOutput("/sbin/blkid")
+
+ raiddevs = commands.getoutput("/bin/cat /proc/partitions | /bin/egrep -v \"^major|^$\" | /bin/awk '{print $4}' | /bin/grep \/ | /bin/egrep -v \"p[0123456789]$\"")
+ disks = commands.getoutput("/bin/cat /proc/partitions | /bin/egrep -v \"^major|^$\" | /bin/awk '{print $4}' | /bin/grep -v / | /bin/egrep -v \"[0123456789]$\"")
+ for disk in raiddevs.split('\n'):
+ if '' != disk.strip():
+ self.collectExtOutput("/sbin/fdisk -l /dev/%s" % (disk,))
+ for disk in disks.split('\n'):
+ if '' != disk.strip():
+ self.collectExtOutput("/sbin/fdisk -l /dev/%s" % (disk,))
+ return
+
diff --git a/trunk/src/lib/sos/plugins/ftp.py b/trunk/src/lib/sos/plugins/ftp.py
new file mode 100644
index 00000000..026954c0
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/ftp.py
@@ -0,0 +1,24 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class ftp(sos.plugintools.PluginBase):
+ """FTP server related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/ftp*")
+ self.addCopySpec("/etc/vsftpd")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/general.py b/trunk/src/lib/sos/plugins/general.py
new file mode 100644
index 00000000..06f55228
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/general.py
@@ -0,0 +1,43 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import glob
+
+class general(sos.plugintools.PluginBase):
+ """very basic system information
+ """
+
+ optionList = [("syslogsize", "maximum size (in MiB) of logs to collect per syslog file", "", 15)]
+
+ def setup(self):
+ self.addCopySpec("/etc/redhat-release")
+ self.addCopySpec("/etc/sysconfig")
+ self.addCopySpec("/proc/stat")
+ self.addCopySpec("/var/log/dmesg")
+ self.addCopySpec("/var/log/messages")
+ self.addCopySpecLimit("/var/log/messages.*", sizelimit = self.isOptionEnabled("syslogsize"))
+ self.addCopySpec("/var/log/secure")
+ self.addCopySpecLimit("/var/log/secure.*", sizelimit = self.isOptionEnabled("syslogsize"))
+ self.addCopySpec("/var/log/sa")
+ self.addCopySpec("/var/log/up2date")
+ self.addCopySpec("/etc/exports")
+ self.collectExtOutput("/bin/hostname", root_symlink = "hostname")
+ self.collectExtOutput("/bin/date", root_symlink = "date")
+ self.collectExtOutput("/usr/bin/uptime", root_symlink = "uptime")
+ return
+
+ def postproc(self):
+ self.doRegexSub("/etc/sysconfig/rhn/up2date", r"(\s*proxyPassword\s*=\s*)\S+", r"\1***")
+ return
diff --git a/trunk/src/lib/sos/plugins/hardware.py b/trunk/src/lib/sos/plugins/hardware.py
new file mode 100644
index 00000000..f8eeda88
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/hardware.py
@@ -0,0 +1,55 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import commands
+
+class hardware(sos.plugintools.PluginBase):
+ """hardware related information
+ """
+ def setup(self):
+ self.addCopySpec("/proc/partitions")
+ self.addCopySpec("/proc/cpuinfo")
+ self.addCopySpec("/proc/meminfo")
+ self.addCopySpec("/proc/ioports")
+ self.addCopySpec("/proc/interrupts")
+ self.addCopySpec("/proc/scsi")
+ self.addCopySpec("/proc/dma")
+ self.addCopySpec("/proc/devices")
+ self.addCopySpec("/proc/rtc")
+ self.addCopySpec("/proc/ide")
+ self.addCopySpec("/proc/bus")
+ self.addCopySpec("/etc/stinit.def")
+ self.addCopySpec("/etc/sysconfig/hwconf")
+ self.addCopySpec("/proc/chandev")
+ self.addCopySpec("/proc/dasd")
+ self.addCopySpec("/proc/s390dbf/tape")
+ self.collectExtOutput("/usr/share/rhn/up2dateclient/hardware.py")
+ self.collectExtOutput("""/bin/echo "lspci" ; /bin/echo ; /sbin/lspci ; /bin/echo ; /bin/echo ; /bin/echo "lspci -nvv" ; /bin/echo ; /sbin/lspci -nvv""", suggest_filename = "lspci", root_symlink = "lspci")
+
+ # FIXME: what is this for?
+ self.collectExtOutput("/bin/dmesg | /bin/grep -e 'e820.' -e 'agp.'")
+
+ # FIXME: what is this for?
+ tmpreg = ""
+ for hwmodule in commands.getoutput('cat /lib/modules/$(uname -r)/modules.pcimap | cut -d " " -f 1 | grep "[:alpha:]" | sort -u').split("\n"):
+ hwmodule = hwmodule.strip()
+ if len(hwmodule):
+ tmpreg = tmpreg + "|" + hwmodule
+ self.collectExtOutput("/bin/dmesg | /bin/egrep '(%s)'" % tmpreg[1:])
+
+ self.collectExtOutput("/sbin/lsusb")
+ self.collectExtOutput("/usr/bin/lshal")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/initrd.py b/trunk/src/lib/sos/plugins/initrd.py
new file mode 100644
index 00000000..83356548
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/initrd.py
@@ -0,0 +1,28 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import glob
+
+class initrd(sos.plugintools.PluginBase):
+ """initrd related information
+ """
+ def setup(self):
+ for initrd in glob.glob('/boot/initrd-*.img'):
+ self.collectExtOutput("/bin/zcat "+initrd+" | /bin/cpio "+
+ "--extract --to-stdout init" )
+ return
+
+ def defaultenabled(self):
+ return False
diff --git a/trunk/src/lib/sos/plugins/kernel.py b/trunk/src/lib/sos/plugins/kernel.py
new file mode 100644
index 00000000..09381b38
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/kernel.py
@@ -0,0 +1,131 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import commands, os, re
+
+class kernel(sos.plugintools.PluginBase):
+ """kernel related information
+ """
+ optionList = [("modinfo", 'Gathers module information on all modules', 'fast', 1),
+ ('sysrq', 'Trigger SysRq dumps', 'fast', 0)]
+ moduleFile = ""
+ taintList = [
+ {'regex':'mvfs*', 'description':'Clearcase module'},
+ {'regex':'vnode*', 'description':'Clearcase module'},
+ {'regex':'vxfs*', 'description':'Veritas file system module'},
+ {'regex':'vxportal*', 'description':'Veritas module'},
+ {'regex':'vxdmp*', 'description':'Veritas dynamic multipathing module'},
+ {'regex':'vxio*', 'description':'Veritas module'},
+ {'regex':'vxspec*"', 'description':'Veritas module'},
+ {'regex':'dcd*', 'description':'Dell OpenManage Server Administrator module'},
+ {'regex':'ocfs', 'description':'Oracle cluster filesystem module'},
+ {'regex':'oracle*', 'description':'Oracle module'},
+ {'regex':'vmnet*', 'description':'VMware module'},
+ {'regex':'vmmon*', 'description':'VMware module'},
+ {'regex':'egenera*', 'description':'Egenera module'},
+ {'regex':'emcp*', 'description':'EMC module'},
+ {'regex':'ocfs*', 'description':'OCFS module'},
+ {'regex':'nvidia', 'description':'NVidia module'},
+ {'regex':'ati-', 'description':'ATI module'}
+ ]
+
+ # HP
+ #
+ #
+
+
+ def setup(self):
+ self.collectExtOutput("/bin/uname -a", root_symlink = "uname")
+ self.moduleFile = self.collectOutputNow("/sbin/lsmod", root_symlink = "lsmod")
+ if self.isOptionEnabled('modinfo'):
+ runcmd = ""
+ for kmod in commands.getoutput('/sbin/lsmod | /bin/cut -f1 -d" " 2>/dev/null | /bin/grep -v Module 2>/dev/null').split('\n'):
+ if '' != kmod.strip():
+ runcmd = runcmd + " " + kmod
+ if len(runcmd):
+ self.collectExtOutput("/sbin/modinfo " + runcmd)
+ self.collectExtOutput("/sbin/ksyms")
+ self.addCopySpec("/proc/filesystems")
+ self.addCopySpec("/proc/ksyms")
+ self.addCopySpec("/proc/slabinfo")
+ kver = commands.getoutput('/bin/uname -r')
+ depfile = "/lib/modules/%s/modules.dep" % (kver,)
+ self.addCopySpec(depfile)
+ self.addCopySpec("/etc/conf.modules")
+ self.addCopySpec("/etc/modules.conf")
+ self.addCopySpec("/etc/modprobe.conf")
+ self.collectExtOutput("/usr/sbin/dmidecode", root_symlink = "dmidecode")
+ self.collectExtOutput("/usr/sbin/dkms status")
+ self.addCopySpec("/proc/cmdline")
+ self.addCopySpec("/proc/driver")
+ self.addCopySpec("/proc/sys/kernel/tainted")
+ # trigger some sysrq's. I'm not sure I like doing it this way, but
+ # since we end up with the sysrq dumps in syslog whether we run the
+ # syslog report before or after this, I suppose I can live with it.
+ if self.isOptionEnabled('sysrq') and os.access("/proc/sysrq-trigger", os.W_OK) and os.access("/proc/sys/kernel/sysrq", os.R_OK):
+ sysrq_state = commands.getoutput("/bin/cat /proc/sys/kernel/sysrq")
+ commands.getoutput("/bin/echo 1 > /proc/sys/kernel/sysrq")
+ for key in ['m', 'p', 't']:
+ commands.getoutput("/bin/echo %s > /proc/sysrq-trigger" % (key,))
+ commands.getoutput("/bin/echo %s > /proc/sys/kernel/sysrq" % (sysrq_state,))
+ # No need to grab syslog here if we can't trigger sysrq, so keep this
+ # inside the if
+ self.addCopySpec("/var/log/messages")
+
+ return
+
+ def analyze(self):
+ infd = open("/proc/modules", "r")
+ modules = infd.readlines()
+ infd.close()
+
+ for modname in modules:
+ modname=modname.split(" ")[0]
+ modinfo_srcver = commands.getoutput("/sbin/modinfo -F srcversion %s" % modname)
+ if not os.access("/sys/module/%s/srcversion" % modname, os.R_OK):
+ continue
+ infd = open("/sys/module/%s/srcversion" % modname, "r")
+ sys_srcver = infd.read().strip("\n")
+ infd.close()
+ if modinfo_srcver != sys_srcver:
+ self.addAlert("Loaded module %s differs from the one present on the file-system")
+
+ # this would be a good moment to check the module's signature
+ # but at the moment there's no easy way to do that outside of
+ # the kernel. i will probably need to write a C lib (derived from
+ # the kernel sources to do this verification.
+
+ savedtaint = os.path.join(self.cInfo['dstroot'], "/proc/sys/kernel/tainted")
+ infd = open(savedtaint, "r")
+ line = infd.read()
+ infd.close()
+ line = line.strip()
+ if (line != "0"):
+ self.addAlert("Kernel taint flag is <%s>\n" % line)
+
+
+ infd = open(self.moduleFile, "r")
+ modules = infd.readlines()
+ infd.close()
+
+ #print(modules)
+ for tainter in self.taintList:
+ p = re.compile(tainter['regex'])
+ for line in modules:
+ if p.match(line) != None:
+ # found a taint match, create an alert
+ moduleName = line.split()[0]
+ self.addAlert("Check for tainted kernel by module %s, which is %s" % (moduleName, tainter['description']))
+ return
diff --git a/trunk/src/lib/sos/plugins/ldap.py b/trunk/src/lib/sos/plugins/ldap.py
new file mode 100644
index 00000000..318a3ba9
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/ldap.py
@@ -0,0 +1,27 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class ldap(sos.plugintools.PluginBase):
+ """LDAP related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/ldap.conf")
+ self.addCopySpec("/etc/openldap")
+ return
+
+ def postproc(self):
+ self.doRegexSub("/etc/ldap.conf", r"(\s*bindpw\s*)\S+", r"\1***")
+ return
diff --git a/trunk/src/lib/sos/plugins/libraries.py b/trunk/src/lib/sos/plugins/libraries.py
new file mode 100644
index 00000000..70b63dba
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/libraries.py
@@ -0,0 +1,24 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class libraries(sos.plugintools.PluginBase):
+ """information on shared libraries
+ """
+ def setup(self):
+ self.addCopySpec("/etc/ld.so.conf")
+ self.addCopySpec("/etc/ld.so.conf.d")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/mail.py b/trunk/src/lib/sos/plugins/mail.py
new file mode 100644
index 00000000..0d4dda29
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/mail.py
@@ -0,0 +1,25 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class mail(sos.plugintools.PluginBase):
+ """mail server related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/mail")
+ self.addCopySpec("/etc/postfix/main.cf")
+ self.addCopySpec("/etc/postfix/master.cf")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/memory.py b/trunk/src/lib/sos/plugins/memory.py
new file mode 100644
index 00000000..7fbe39c3
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/memory.py
@@ -0,0 +1,30 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class memory(sos.plugintools.PluginBase):
+ """memory usage information
+ """
+ def setup(self):
+ self.addCopySpec("/proc/pci")
+ self.addCopySpec("/proc/meminfo")
+ self.addCopySpec("/proc/vmstat")
+ self.addCopySpec("/proc/slabinfo")
+
+ self.collectExtOutput("/bin/dmesg | grep -e 'e820.' -e 'aperature.'")
+ self.collectExtOutput("/usr/bin/free", root_symlink = "free")
+ self.collectExtOutput("/usr/bin/free -m")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/named.py b/trunk/src/lib/sos/plugins/named.py
new file mode 100644
index 00000000..68d56ca0
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/named.py
@@ -0,0 +1,36 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import commands
+import os
+
+class named(sos.plugintools.PluginBase):
+ """named related information
+ """
+ def setup(self):
+ dnsdir = ""
+ self.addCopySpec("/etc/named.boot")
+ self.addCopySpec("/etc/named.conf")
+ self.addCopySpec("/etc/sysconfig/named")
+ if os.access("/etc/named.conf", os.R_OK):
+ dnsdir = commands.getoutput("/bin/grep -i directory /etc/named.conf | /bin/gawk '{print $2}' | /bin/sed 's/\\\"//g' | /bin/sed 's/\;//g'")
+ if os.access("/etc/named.boot", os.R_OK):
+ dnsdir = commands.getoutput("/bin/grep -i directory /etc/named.boot | /bin/gawk '{print $2}' | /bin/sed 's/\\\"//g' | /bin/sed 's/\;//g'")
+ if '' != dnsdir.strip():
+ self.addCopySpec(dnsdir)
+ self.addForbiddenPath('/var/named/chroot/proc')
+ self.addForbiddenPath('/var/named/chroot/dev')
+ return
+
diff --git a/trunk/src/lib/sos/plugins/networking.py b/trunk/src/lib/sos/plugins/networking.py
new file mode 100644
index 00000000..54723663
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/networking.py
@@ -0,0 +1,75 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import os,re,commands
+
+class networking(sos.plugintools.PluginBase):
+ """network related information
+ """
+ optionList = [("traceroute", "collects a traceroute to rhn.redhat.com", "slow", 0)]
+
+ def get_interface_name(self,ifconfigFile):
+ """Return a dictionary for which key are interface name according to the
+ output of ifconifg-a stored in ifconfigFile.
+ """
+ out={}
+ if(os.path.isfile(ifconfigFile)):
+ f=open(ifconfigFile,'r')
+ content=f.read()
+ f.close()
+ reg=re.compile(r"^(eth\d+)\D",re.MULTILINE)
+ for name in reg.findall(content):
+ out[name]=1
+ return out
+
+ def collectIPTable(self,tablename):
+ """ When running the iptables command, it unfortunately auto-loads
+ the modules before trying to get output. Some people explicitly
+ don't want this, so check if the modules are loaded before running
+ the command. If they aren't loaded, there can't possibly be any
+ relevant rules in that table """
+
+ cmd = "/sbin/iptables -t "+tablename+" -nvL"
+
+ (status, output) = commands.getstatusoutput("/sbin/lsmod | grep -q "+tablename)
+ if status == 0:
+ self.collectExtOutput(cmd)
+ else:
+ self.writeTextToCommand(cmd,"IPTables module "+tablename+" not loaded\n")
+
+ def setup(self):
+ self.addCopySpec("/etc/nsswitch.conf")
+ self.addCopySpec("/etc/yp.conf")
+ self.addCopySpec("/etc/inetd.conf")
+ self.addCopySpec("/etc/xinetd.conf")
+ self.addCopySpec("/etc/xinetd.d")
+ self.addCopySpec("/etc/host*")
+ self.addCopySpec("/etc/resolv.conf")
+ ifconfigFile=self.collectExtOutput("/sbin/ifconfig -a", root_symlink = "ifconfig")
+ self.collectExtOutput("/sbin/route -n", root_symlink = "route")
+ self.collectExtOutput("/sbin/ipchains -nvL")
+ self.collectIPTable("filter")
+ self.collectIPTable("nat")
+ self.collectIPTable("mangle")
+ self.collectExtOutput("/bin/netstat -nap")
+ if ifconfigFile:
+ for eth in self.get_interface_name(ifconfigFile):
+ self.collectExtOutput("/sbin/ethtool "+eth)
+ if self.isOptionEnabled("traceroute"):
+ # The semicolon prevents the browser from thinking this is a link when viewing the report
+ self.collectExtOutput("/bin/traceroute rhn.redhat.com;")
+
+ return
+
diff --git a/trunk/src/lib/sos/plugins/nfsserver.py b/trunk/src/lib/sos/plugins/nfsserver.py
new file mode 100644
index 00000000..6c894177
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/nfsserver.py
@@ -0,0 +1,27 @@
+## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class nfsserver(sos.plugintools.PluginBase):
+ """NFS server-related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/exports")
+ self.collectExtOutput("/usr/sbin/rpcinfo -p localhost")
+ self.collectExtOutput("/usr/sbin/nfsstat")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/pam.py b/trunk/src/lib/sos/plugins/pam.py
new file mode 100644
index 00000000..8164bba3
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/pam.py
@@ -0,0 +1,25 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class pam(sos.plugintools.PluginBase):
+ """PAM related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/pam.d")
+ self.addCopySpec("/etc/security")
+ self.collectExtOutput("/bin/ls -laF /lib/security/pam_*so")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/printing.py b/trunk/src/lib/sos/plugins/printing.py
new file mode 100644
index 00000000..76a476eb
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/printing.py
@@ -0,0 +1,24 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class printing(sos.plugintools.PluginBase):
+ """printing related information (cups)
+ """
+ def setup(self):
+ self.addCopySpec("/etc/cups/*.conf")
+ self.addCopySpec("/var/log/cups")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/process.py b/trunk/src/lib/sos/plugins/process.py
new file mode 100644
index 00000000..7ed13a5e
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/process.py
@@ -0,0 +1,24 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class process(sos.plugintools.PluginBase):
+ """process information
+ """
+ def setup(self):
+ self.collectExtOutput("/bin/ps auxww", root_symlink = "ps")
+ self.collectExtOutput("/usr/bin/pstree", root_symlink = "pstree")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/radius.py b/trunk/src/lib/sos/plugins/radius.py
new file mode 100644
index 00000000..7ab53810
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/radius.py
@@ -0,0 +1,29 @@
+## Copyright (C) 2007 Navid Sheikhol-Eslami <navid@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class radius(sos.plugintools.PluginBase):
+ """radius related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/raddb")
+ self.addCopySpec("/etc/pam.d/radiusd")
+ return
+
+ def postproc(self):
+ self.doRegexSub("/etc/raddb/sql.conf", r"(\s*password\s*=\s*)\S+", r"\1***")
+ return
diff --git a/trunk/src/lib/sos/plugins/rhn.py b/trunk/src/lib/sos/plugins/rhn.py
new file mode 100644
index 00000000..049e51bc
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/rhn.py
@@ -0,0 +1,91 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+from sos.plugintools import PluginBase
+
+class rhn(PluginBase):
+ """RHN server related information
+ """
+ def checkenabled(self):
+ # XXX check for the presence of requisite packages
+ satellite = self.cInfo["policy"].pkgByName("rhns-satellite-tools")
+ proxy = self.cInfo["policy"].pkgByName("rhns-proxy-tools")
+ if not satellite and not proxy:
+ return False
+ return True
+
+ def setup(self):
+ #
+ # First, grab things needed from both Satellite and Proxy systems
+ #
+ # TODO: add chain load so we can use existing modules for httpd, &c.
+ #
+
+ # basic RHN logs and configs
+ self.addCopySpec("/var/log/rhn*")
+ self.addCopySpec("/etc/rhn")
+ self.collectExtOutput("/usr/share/rhn/up2date_client/hardware.py")
+
+ # httpd
+ self.addCopySpec("/etc/httpd/conf")
+ self.addCopySpec("/var/log/httpd")
+
+ # RPM manifests
+ self.collectExtOutput("/bin/rpm -qa --last | sort")
+
+ # monitoring scout logs
+ self.addCopySpec("/home/nocpulse/var/*.log*")
+ self.addCopySpec("/home/nocpulse/var/commands/*.log*")
+
+ satellite = self.cInfo["policy"].pkgByName("rhns-satellite-tools")
+ proxy = self.cInfo["policy"].pkgByName("rhns-proxy-tools")
+
+ #
+ # Now, go for product-specific data
+ #
+ if satellite:
+ self.setupSatellite(satellite)
+
+ if proxy:
+ self.setupProxy(proxy)
+
+ def setupSatellite(self, satellite):
+ self.collectExtOutput("/usr/bin/rhn-schema-version")
+ self.collectExtOutput("/usr/bin/rhn-charsets")
+
+ # oracle
+ self.addCopySpec("/etc/tnsnames.ora")
+
+ # tomcat (4.x and newer satellites only)
+ if not self.cInfo["policy"].pkgNVRA(satellite)[1].startswith("3."):
+ self.addCopySpec("/etc/tomcat5")
+ self.addCopySpec("/var/log/tomcat5")
+
+ # jabberd
+ # - logs to /var/log/messages
+ self.addCopySpec("/etc/jabberd")
+
+ # SSL build
+ self.addCopySpec("/root/ssl-build")
+
+ # monitoring logs
+ self.addCopySpec("/opt/notification/var/*.log*")
+ self.addCopySpec("/var/tmp/ack_handler.log*")
+ self.addCopySpec("/var/tmp/enqueue.log*")
+
+ def setupProxy(self, proxy):
+ # squid
+ self.addCopySpec("/etc/squid")
+ self.addCopySpec("/var/log/squid")
+
diff --git a/trunk/src/lib/sos/plugins/rpm.py b/trunk/src/lib/sos/plugins/rpm.py
new file mode 100644
index 00000000..b6fdb699
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/rpm.py
@@ -0,0 +1,33 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class rpm(sos.plugintools.PluginBase):
+ """RPM information
+ """
+ optionList = [("rpmq", "Queries for package information via rpm -q", "fast", 1),
+ ("rpmva", "Runs a verify on all packages", "slow", 1)]
+
+ def setup(self):
+ self.addCopySpec("/var/log/rpmpkgs")
+
+ if self.isOptionEnabled("rpmq"):
+ self.collectExtOutput("/bin/rpm -qa --qf \"%{NAME}-%{VERSION}-%{RELEASE}-%{ARCH}\n\"", root_symlink = "installed-rpms")
+
+ if self.isOptionEnabled("rpmva"):
+ self.eta_weight += 800 # this plugins takes 200x longer (for ETA)
+ self.collectExtOutput("/bin/rpm -Va", root_symlink = "rpm-Va")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/samba.py b/trunk/src/lib/sos/plugins/samba.py
new file mode 100644
index 00000000..ec65370e
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/samba.py
@@ -0,0 +1,26 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class samba(sos.plugintools.PluginBase):
+ """Samba related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/samba")
+ self.addCopySpec("/var/log/samba/*")
+ self.collectExtOutput("/usr/bin/wbinfo -g")
+ self.collectExtOutput("/usr/bin/wbinfo -u")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/satellite.py b/trunk/src/lib/sos/plugins/satellite.py
new file mode 100644
index 00000000..930d11b0
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/satellite.py
@@ -0,0 +1,53 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class satellite(sos.plugintools.PluginBase):
+ """RHN Satellite related information
+ """
+
+ def defaultenabled(self):
+ return False
+
+ def setup(self):
+ self.addCopySpec("/etc/httpd/conf")
+ self.addCopySpec("/etc/rhn")
+ self.addCopySpec("/etc/sysconfig/rhn")
+ self.addCopySpec("/etc/tnsnames.ora")
+ self.addCopySpec("/var/log/httpd") # httpd-logs
+ self.addCopySpec("/var/log/rhn*") # rhn-logs
+ self.addCopySpec("/var/log/rhn/rhn-database-installation.log")
+ self.addCopySpec("/etc/jabberd")
+
+ # tomcat for satellite 400+
+ self.addCopySpec("/etc/tomcat5")
+ self.addCopySpec("/var/log/tomcat5")
+
+ # all these used to go in $DIR/mon-logs
+ self.addCopySpec("/opt/notification/var/*.log*")
+ self.addCopySpec("/var/tmp/ack_handler.log*")
+ self.addCopySpec("/var/tmp/enqueue.log*")
+
+ self.addCopySpec("/home/nocpulse/var/*.log*")
+ self.addCopySpec("/home/nocpulse/var/commands/*.log*")
+ self.addCopySpec("/var/tmp/ack_handler.log*")
+ self.addCopySpec("/var/tmp/enqueue.log*")
+
+ self.addCopySpec("/root/ssl-build")
+ self.addCopySpec("rpm -qa --last") # $DIR/rpm-manifest
+ self.addCopySpec("/usr/bin/rhn-schema-version") # $DIR/database-schema-version
+ self.addCopySpec("/usr/bin/rhn-charsets") # $DIR/database-character-sets
+
+ return
diff --git a/trunk/src/lib/sos/plugins/selinux.py b/trunk/src/lib/sos/plugins/selinux.py
new file mode 100644
index 00000000..897c3991
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/selinux.py
@@ -0,0 +1,36 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import commands
+
+class selinux(sos.plugintools.PluginBase):
+ """selinux related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/selinux/*")
+ self.collectExtOutput("/usr/bin/selinuxconfig")
+ self.collectExtOutput("/usr/sbin/sestatus", root_symlink = "sestatus")
+ self.collectExtOutput("/bin/rpm -q -V selinux-policy-targeted")
+ self.collectExtOutput("/bin/rpm -q -V selinux-policy-strict")
+ return
+
+ def checkenabled(self):
+ # is selinux enabled ?
+ try:
+ if commands.getoutput("/usr/sbin/sestatus").split(":")[1].strip() == "disabled":
+ return False
+ except:
+ pass
+ return True
diff --git a/trunk/src/lib/sos/plugins/sendmail.py b/trunk/src/lib/sos/plugins/sendmail.py
new file mode 100644
index 00000000..d95b5d7b
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/sendmail.py
@@ -0,0 +1,27 @@
+## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class sendmail(sos.plugintools.PluginBase):
+ """sendmail information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/mail/*")
+ self.addCopySpec("/var/log/maillog")
+ self.collectExtOutput("/sbin/chkconfig --list sendmail")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/squid.py b/trunk/src/lib/sos/plugins/squid.py
new file mode 100644
index 00000000..4544ef9a
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/squid.py
@@ -0,0 +1,23 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class squid(sos.plugintools.PluginBase):
+ """squid related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/squid/squid.conf")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/ssh.py b/trunk/src/lib/sos/plugins/ssh.py
new file mode 100644
index 00000000..92a4c9e5
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/ssh.py
@@ -0,0 +1,27 @@
+## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class ssh(sos.plugintools.PluginBase):
+ """ssh-related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/ssh/ssh_config")
+ self.addCopySpec("/etc/ssh/sshd_config")
+ self.collectExtOutput("/sbin/chkconfig --list sshd")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/startup.py b/trunk/src/lib/sos/plugins/startup.py
new file mode 100644
index 00000000..02361393
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/startup.py
@@ -0,0 +1,25 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class startup(sos.plugintools.PluginBase):
+ """startup information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/rc.d")
+
+ self.collectExtOutput("/sbin/chkconfig --list", root_symlink = "chkconfig")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/system.py b/trunk/src/lib/sos/plugins/system.py
new file mode 100644
index 00000000..19d7859e
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/system.py
@@ -0,0 +1,31 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class system(sos.plugintools.PluginBase):
+ """core system related information
+ """
+ def setup(self):
+ self.addCopySpec("/proc/sys")
+ self.addCopySpec("/etc/sysctl.conf")
+ self.addCopySpec("/etc/cron*")
+ self.addCopySpec("/etc/syslog.conf")
+ self.addCopySpec("/etc/ntp.conf")
+ self.addCopySpec("/etc/ntp/step-tickers")
+ self.addCopySpec("/etc/ntp/ntpservers")
+ self.addCopySpec("/etc/auto.*")
+
+ return
+
diff --git a/trunk/src/lib/sos/plugins/systemtap.py b/trunk/src/lib/sos/plugins/systemtap.py
new file mode 100644
index 00000000..b99ce0cf
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/systemtap.py
@@ -0,0 +1,29 @@
+## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class systemtap(sos.plugintools.PluginBase):
+ """SystemTap pre-requisites information
+ """
+ def setup(self):
+ # requires systemtap, systemtap-runtime, kernel-devel,
+ # kernel-debuginfo, kernel-debuginfo-common
+ self.collectExtOutput("/bin/rpm -qa | /bin/egrep -e kernel.*`uname -r` -e systemtap -e elfutils | sort")
+ self.collectExtOutput("/usr/bin/stap -V 2")
+ self.collectExtOutput("/bin/uname -r")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/x11.py b/trunk/src/lib/sos/plugins/x11.py
new file mode 100644
index 00000000..9b7b7ac9
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/x11.py
@@ -0,0 +1,26 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class x11(sos.plugintools.PluginBase):
+ """X related information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/X11")
+ self.addCopySpec("/var/log/Xorg.*.log")
+ self.addCopySpec("/var/log/XFree86.*.log")
+ self.collectExtOutput("/bin/dmesg | grep -e 'agpgart.'")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/xen.py b/trunk/src/lib/sos/plugins/xen.py
new file mode 100644
index 00000000..d6daec63
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/xen.py
@@ -0,0 +1,82 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+import os, commands
+from stat import *
+
+class xen(sos.plugintools.PluginBase):
+ """Xen related information
+ """
+ def determineXenHost(self):
+ if os.access("/proc/acpi/dsdt", os.R_OK):
+ (status, output) = commands.getstatusoutput("/usr/bin/strings /proc/acpi/dsdt | grep -q int-xen")
+ if status == 0:
+ return "hvm"
+
+ if os.access("/proc/xen/capabilities", os.R_OK):
+ (status, output) = commands.getstatusoutput("grep -q control_d /proc/xen/capabilities")
+ if status == 0:
+ return "dom0"
+ else:
+ return "domU"
+ return "baremetal"
+
+ def checkenabled(self):
+ if self.determineXenHost() == "baremetal":
+ return False
+ return True
+
+ def domCollectProc(self):
+ self.addCopySpec("/proc/xen/balloon")
+ self.addCopySpec("/proc/xen/capabilities")
+ self.addCopySpec("/proc/xen/xsd_kva")
+ self.addCopySpec("/proc/xen/xsd_port")
+ # determine if CPU has PAE support
+ self.collectExtOutput("/bin/grep pae /proc/cpuinfo")
+ # determine if CPU has Intel-VT or AMD-V support
+ self.collectExtOutput("/bin/egrep -e 'vmx|svm' /proc/cpuinfo")
+
+ def setup(self):
+ host_type = self.determineXenHost()
+ if host_type == "domU":
+ # we should collect /proc/xen and /sys/hypervisor
+ self.domCollectProc()
+ # determine if hardware virtualization support is enabled
+ # in BIOS: /sys/hypervisor/properties/capabilities
+ self.addCopySpec("/sys/hypervisor")
+ elif host_type == "hvm":
+ # what do we collect here???
+ pass
+ elif host_type == "dom0":
+ # default of dom0, collect lots of system information
+ self.addCopySpec("/var/log/xen")
+ self.addCopySpec("/etc/xen")
+ self.collectExtOutput("/usr/bin/xenstore-ls")
+ self.collectExtOutput("/usr/sbin/xm dmesg")
+ self.collectExtOutput("/usr/sbin/xm info")
+ self.collectExtOutput("/usr/sbin/brctl show")
+ self.domCollectProc()
+ self.addCopySpec("/sys/hypervisor")
+ # FIXME: we *might* want to collect things in /sys/bus/xen*,
+ # /sys/class/xen*, /sys/devices/xen*, /sys/modules/blk*,
+ # /sys/modules/net*, but I've never heard of them actually being
+ # useful, so I'll leave it out for now
+ else:
+ # for bare-metal, we don't have to do anything special
+ return
+
+ self.addCustomText("Xen hostType: "+host_type)
+ return
+
diff --git a/trunk/src/lib/sos/plugins/xinetd.py b/trunk/src/lib/sos/plugins/xinetd.py
new file mode 100644
index 00000000..715c831f
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/xinetd.py
@@ -0,0 +1,27 @@
+## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class xinetd(sos.plugintools.PluginBase):
+ """xinetd information
+ """
+ def setup(self):
+ self.addCopySpec("/etc/xinetd.conf")
+ self.addCopySpec("/etc/xinetd.d/*")
+ self.collectExtOutput("/sbin/chkconfig --list xinetd")
+ return
+
diff --git a/trunk/src/lib/sos/plugins/yum.py b/trunk/src/lib/sos/plugins/yum.py
new file mode 100644
index 00000000..89102c38
--- /dev/null
+++ b/trunk/src/lib/sos/plugins/yum.py
@@ -0,0 +1,37 @@
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sos.plugintools
+
+class yum(sos.plugintools.PluginBase):
+ """yum information
+ """
+
+ def defaultenabled(self):
+ # enable with -e or -o
+ return False
+
+ def setup(self):
+ # Pull all yum related information
+ self.addCopySpec("/etc/yum")
+ self.addCopySpec("/etc/yum.repos.d")
+ self.addCopySpec("/etc/yum.conf")
+ self.addCopySpec("/var/log/yum.log")
+
+ # Get a list of channels the machine is subscribed to.
+ self.collectExtOutput("/bin/echo \"repo list\" | /usr/bin/yum shell")
+ # List various information about available packages
+ self.collectExtOutput("/usr/bin/yum list")
+
+ return
diff --git a/trunk/src/lib/sos/plugintools.py b/trunk/src/lib/sos/plugintools.py
new file mode 100644
index 00000000..238036ce
--- /dev/null
+++ b/trunk/src/lib/sos/plugintools.py
@@ -0,0 +1,568 @@
+## plugintools.py
+## This exports methods available for use by plugins for sos
+
+## Copyright (C) 2006 Steve Conklin <sconklin@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# pylint: disable-msg = R0902
+# pylint: disable-msg = R0904
+# pylint: disable-msg = W0702
+# pylint: disable-msg = W0703
+# pylint: disable-msg = R0201
+# pylint: disable-msg = W0611
+# pylint: disable-msg = W0613
+
+"""
+This is the base class for sosreport plugins
+"""
+from sos.helpers import *
+from threading import Thread, activeCount
+import os, os.path, sys, string, itertools, glob, re, traceback
+import logging
+from stat import *
+from time import time
+
+class PluginBase:
+ """
+ Base class for plugins
+ """
+ def __init__(self, pluginname, commons):
+ # pylint: disable-msg = E0203
+ try:
+ len(self.optionList)
+ except:
+ self.optionList = []
+ # pylint: enable-msg = E0203
+ self.copiedFiles = []
+ self.copiedDirs = []
+ self.executedCommands = []
+ self.diagnose_msgs = []
+ self.alerts = []
+ self.customText = ""
+ self.optNames = []
+ self.optParms = []
+ self.piName = pluginname
+ self.cInfo = commons
+ self.forbiddenPaths = []
+ self.copyPaths = []
+ self.collectProgs = []
+ self.thread = None
+ self.pid = None
+ self.eta_weight = 1
+ self.time_start = None
+ self.time_stop = None
+
+ self.soslog = logging.getLogger('sos')
+
+ # get the option list into a dictionary
+ for opt in self.optionList:
+ self.optNames.append(opt[0])
+ self.optParms.append({'desc':opt[1], 'speed':opt[2], 'enabled':opt[3]})
+
+ # Method for applying regexp substitutions
+ def doRegexSub(self, srcpath, regexp, subst):
+ '''Apply a regexp substitution to a file archived by sosreport.
+ '''
+ if len(self.copiedFiles):
+ for afile in self.copiedFiles:
+ if afile['srcpath'] == srcpath:
+ abspath = os.path.join(self.cInfo['dstroot'], srcpath.lstrip(os.path.sep))
+ try:
+ fp = open(abspath, 'r')
+ tmpout, occurs = re.subn( regexp, subst, fp.read() )
+ fp.close()
+ if occurs > 0:
+ fp = open(abspath,'w')
+ fp.write(tmpout)
+ fp.close()
+ return occurs
+ except SystemExit:
+ raise SystemExit
+ except KeyboardInterrupt:
+ raise KeyboardInterrupt
+ except Exception, e:
+ self.soslog.log(logging.VERBOSE, "Problem at path %s (%s)" % (abspath,e))
+ break
+ return False
+
+ # Methods for copying files and shelling out
+ def doCopyFileOrDir(self, srcpath):
+ # pylint: disable-msg = R0912
+ # pylint: disable-msg = R0915
+ ''' Copy file or directory to the destination tree. If a directory, then everything
+ below it is recursively copied. A list of copied files are saved for use later
+ in preparing a report
+ '''
+ copyProhibited = 0
+ for path in self.forbiddenPaths:
+ if ( srcpath.count(path) > 0 ):
+ copyProhibited = 1
+
+ if copyProhibited:
+ return ''
+
+ if os.path.islink(srcpath):
+ # This is a symlink - We need to also copy the file that it points to
+ # file and dir symlinks ar ehandled the same
+ link = os.readlink(srcpath)
+ if os.path.isabs(link):
+ # the link was an absolute path, and will not point to the new
+ # tree. We must adjust it.
+
+ # What's the name of the symlink on the dest tree?
+ dstslname = os.path.join(self.cInfo['dstroot'], srcpath.lstrip(os.path.sep))
+
+ # make sure the dst dir exists
+ if not (os.path.exists(os.path.dirname(dstslname)) and os.path.isdir(os.path.dirname(dstslname))):
+ # create the directory
+ os.makedirs(os.path.dirname(dstslname))
+
+ dstsldir = os.path.join(self.cInfo['dstroot'], link.lstrip(os.path.sep))
+ # Create the symlink on the dst tree
+ rpth = sosRelPath(os.path.dirname(dstslname), dstsldir)
+ os.symlink(rpth, dstslname)
+ else:
+ # no adjustment, symlink is the relative path
+ dstslname = link
+
+ if os.path.isdir(srcpath):
+ for afile in os.listdir(srcpath):
+ if afile == '.' or afile == '..':
+ pass
+ else:
+ try:
+ abspath = self.doCopyFileOrDir(srcpath+'/'+afile)
+ except SystemExit:
+ raise SystemExit
+ except KeyboardInterrupt:
+ raise KeyboardInterrupt
+ except Exception, e:
+ self.soslog.warning(traceback.format_exc())
+
+ # if on forbidden list, abspath is null
+ if not abspath == '':
+ dstslname = sosRelPath(self.cInfo['rptdir'], abspath)
+ self.copiedDirs.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link})
+ else:
+ try:
+ dstslname, abspath = self.__copyFile(srcpath)
+ self.copiedFiles.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link})
+ self.cInfo['xmlreport'].add_file(srcpath,os.stat(srcpath))
+ except SystemExit:
+ raise SystemExit
+ except KeyboardInterrupt:
+ raise KeyboardInterrupt
+ except Exception, e:
+ self.soslog.log(logging.VERBOSE, "Problem at path %s (%s)" % (srcpath, e))
+
+ return abspath
+
+ else:
+ if not os.path.exists(srcpath):
+ self.soslog.debug("File or directory %s does not exist\n" % srcpath)
+ elif os.path.isdir(srcpath):
+ for afile in os.listdir(srcpath):
+ if afile == '.' or afile == '..':
+ pass
+ else:
+ self.doCopyFileOrDir(srcpath+'/'+afile)
+ else:
+ # This is not a directory or a symlink
+ tdstpath, abspath = self.__copyFile(srcpath)
+ self.copiedFiles.append({'srcpath':srcpath, 'dstpath':tdstpath, 'symlink':"no"}) # save in our list
+ return abspath
+
+ def __copyFile(self, src):
+ """ call cp to copy a file, collect return status and output. Returns the
+ destination file name.
+ """
+ try:
+ # pylint: disable-msg = W0612
+ status, shout, runtime = sosGetCommandOutput("/bin/cp --parents -P --preserve=mode,ownership,timestamps,links " + src +" " + self.cInfo['dstroot'])
+ if status:
+ self.soslog.debug(shout)
+ abspath = os.path.join(self.cInfo['dstroot'], src.lstrip(os.path.sep))
+ relpath = sosRelPath(self.cInfo['rptdir'], abspath)
+ return relpath, abspath
+ except SystemExit:
+ raise SystemExit
+ except KeyboardInterrupt:
+ raise KeyboardInterrupt
+ except Exception,e:
+ self.soslog.warning("Problem copying file %s (%s)" % (src, e))
+
+ def addForbiddenPath(self, forbiddenPath):
+ """Specify a path to not copy, even if it's part of a copyPaths[] entry.
+ Note: do NOT use globs here.
+ """
+ self.forbiddenPaths.append(forbiddenPath)
+
+ def getAllOptions(self):
+ """
+ return a list of all options selected
+ """
+ return (self.optNames, self.optParms)
+
+ def setOption(self, optionname, enable):
+ ''' enable or disable the named option.
+ '''
+ for name, parms in zip(self.optNames, self.optParms):
+ if name == optionname:
+ parms['enabled'] = enable
+
+ def isOptionEnabled(self, optionname):
+ ''' see whether the named option is enabled.
+ '''
+ for name, parms in zip(self.optNames, self.optParms):
+ if name == optionname:
+ return parms['enabled']
+ # nonexistent options aren't enabled.
+ return 0
+
+ def addCopySpecLimit(self,fname,sizelimit = None):
+ """Add a file specification (with limits)
+ """
+ files = glob.glob(fname)
+ files.sort()
+ cursize = 0
+ for flog in files:
+ cursize += os.stat(flog)[ST_SIZE]
+ if sizelimit and (cursize / 1024 / 1024) > sizelimit:
+ break
+ self.addCopySpec(flog)
+
+ def addCopySpec(self, copyspec):
+ """ Add a file specification (can be file, dir,or shell glob) to be
+ copied into the sosreport by this module
+ """
+ # Glob case handling is such that a valid non-glob is a reduced glob
+ for filespec in glob.glob(copyspec):
+ self.copyPaths.append(filespec)
+
+ def copyFileGlob(self, srcglob):
+ """ Deprecated - please modify modules to use addCopySpec()
+ """
+ sys.stderr.write("Warning: thecopyFileGlob() function has been deprecated. Please")
+ sys.stderr.write("use addCopySpec() instead. Calling addCopySpec() now.")
+ self.addCopySpec(srcglob)
+
+ def copyFileOrDir(self, srcpath):
+ """ Deprecated - please modify modules to use addCopySpec()
+ """
+ sys.stderr.write("Warning: the copyFileOrDir() function has been deprecated. Please\n")
+ sys.stderr.write("use addCopySpec() instead. Calling addCopySpec() now.\n")
+ raise ValueError
+ #self.addCopySpec(srcpath)
+
+ def runExeInd(self, exe):
+ """ Deprecated - use callExtProg()
+ """
+ sys.stderr.write("Warning: the runExeInd() function has been deprecated. Please use\n")
+ sys.stderr.write("the callExtProg() function. This should only be called\n")
+ sys.stderr.write("if collect() is overridden.")
+ pass
+
+ def callExtProg(self, prog):
+ """ Execute a command independantly of the output gathering part of
+ sosreport
+ """
+ # Log if binary is not runnable or does not exist
+ if not os.access(prog.split()[0], os.X_OK):
+ self.soslog.log(logging.VERBOSE, "binary '%s' does not exist or is not runnable" % prog.split()[0])
+
+ # pylint: disable-msg = W0612
+ status, shout, runtime = sosGetCommandOutput(prog)
+ return status
+
+ def runExe(self, exe):
+ """ Deprecated - use collectExtOutput()
+ """
+ sys.stderr.write("Warning: the runExe() function has been deprecated. Please use\n")
+ sys.stderr.write("the collectExtOutput() function.\n")
+ pass
+
+ def collectExtOutput(self, exe, suggest_filename = None, root_symlink = None):
+ """
+ Run a program and collect the output
+ """
+ self.collectProgs.append( (exe,suggest_filename,root_symlink) )
+
+ def makeCommandFilename(self, exe):
+ """ The internal function to build up a filename based on a command """
+
+ mangledname = re.sub(r"[^\w\-\.\/]+", "_", exe)
+ mangledname = re.sub(r"/", ".", mangledname).strip(" ._-")[0:64]
+
+ outfn = self.cInfo['cmddir'] + "/" + self.piName + "/" + mangledname
+
+ # check for collisions
+ inc = 0
+ if os.path.exists(outfn):
+ inc = 2
+ while True:
+ newfn = outfn + "_" + inc
+ if not os.path.exists(newfn):
+ break
+ inc +=1
+
+ return outfn
+
+ def collectOutputNow(self, exe, suggest_filename = None, root_symlink = False):
+ """ Execute a command and save the output to a file for inclusion in
+ the report
+ """
+ # First check to make sure the binary exists and is runnable.
+ if not os.access(exe.split()[0], os.X_OK):
+ self.soslog.log(logging.VERBOSE, "binary '%s' does not exist or is not runnable, trying anyways" % exe.split()[0])
+
+ # pylint: disable-msg = W0612
+ status, shout, runtime = sosGetCommandOutput(exe)
+
+ if suggest_filename:
+ outfn = self.makeCommandFilename(suggest_filename)
+ else:
+ outfn = self.makeCommandFilename(exe)
+
+ if not os.path.isdir(os.path.dirname(outfn)):
+ os.mkdir(os.path.dirname(outfn))
+
+ outfd = open(outfn, "w")
+ if status == 127: outfd.write("# the command returned exit status 127, this normally means that the command was not found.\n\n")
+ if len(shout): outfd.write(shout+"\n")
+ outfd.close()
+
+ if root_symlink:
+ curdir = os.getcwd()
+ os.chdir(self.cInfo['dstroot'])
+ os.symlink(outfn[len(self.cInfo['dstroot'])+1:], root_symlink.strip("/."))
+ os.chdir(curdir)
+
+ outfn = outfn[len(self.cInfo['cmddir'])+1:]
+
+ # sosStatus(status)
+ # save info for later
+ self.executedCommands.append({'exe': exe, 'file':outfn}) # save in our list
+ self.cInfo['xmlreport'].add_command(cmdline=exe,exitcode=status,f_stdout=outfn,runtime=runtime)
+ return outfn
+
+ def writeTextToCommand(self, exe, text):
+ """ A function that allows you to write a random text string to the
+ command output location referenced by exe; this is useful if you want
+ to conditionally collect information, but still want the output file
+ to exist so as not to confuse readers """
+
+ outfn = self.makeCommandFilename(exe)
+
+ if not os.path.isdir(os.path.dirname(outfn)):
+ os.mkdir(os.path.dirname(outfn))
+
+ outfd = open(outfn, "w")
+ outfd.write(text)
+ outfd.close()
+
+ self.executedCommands.append({'exe': exe, 'file': outfn}) # save in our list
+ return outfn
+
+ # For adding warning messages regarding configuration sanity
+ def addDiagnose(self, alertstring):
+ """ Add a configuration sanity warning for this plugin. These
+ will be displayed on-screen before collection and in the report as well.
+ """
+ self.diagnose_msgs.append(alertstring)
+ return
+
+ # For adding output
+ def addAlert(self, alertstring):
+ """ Add an alert to the collection of alerts for this plugin. These
+ will be displayed in the report
+ """
+ self.alerts.append(alertstring)
+ return
+
+
+ def addCustomText(self, text):
+ """ Append text to the custom text that is included in the report. This
+ is freeform and can include html.
+ """
+ self.customText = self.customText + text
+ return
+
+ def doCollect(self):
+ """ This function has been replaced with copyStuff(threaded = True). Please change your
+ module calls. Calling setup() now.
+ """
+ return self.copyStuff(threaded = True)
+
+ def isRunning(self):
+ """
+ if threaded, is thread running ?
+ """
+ if self.thread: return self.thread.isAlive()
+ return None
+
+ def wait(self,timeout=None):
+ """
+ wait for a thread to complete - only called for threaded execution
+ """
+ self.thread.join(timeout)
+ return self.thread.isAlive()
+
+ def copyStuff(self, threaded = False, semaphore = None):
+ """
+ Collect the data for a plugin
+ """
+ if threaded and self.thread == None:
+ self.thread = Thread(target=self.copyStuff, name=self.piName+'-thread', args = [True, semaphore] )
+ self.thread.start()
+ return self.thread
+
+ if semaphore: semaphore.acquire()
+
+ self.soslog.log(logging.VERBOSE, "starting threaded plugin %s" % self.piName)
+
+ self.time_start = time()
+ self.time_stop = None
+
+ for path in self.copyPaths:
+ self.soslog.debug("copying pathspec %s" % path)
+ try:
+ self.doCopyFileOrDir(path)
+ except SystemExit:
+ raise SystemExit
+ except KeyboardInterrupt:
+ raise KeyboardInterrupt
+ except Exception, e:
+ self.soslog.log(logging.VERBOSE, "error copying from pathspec %s (%s), traceback follows:" % (path,e))
+ self.soslog.log(logging.VERBOSE, traceback.format_exc())
+ for (prog,suggest_filename,root_symlink) in self.collectProgs:
+ self.soslog.debug("collecting output of '%s'" % prog)
+ try:
+ self.collectOutputNow(prog, suggest_filename, root_symlink)
+ except SystemExit:
+ raise SystemExit
+ except KeyboardInterrupt:
+ raise KeyboardInterrupt
+ except:
+ self.soslog.log(logging.VERBOSE, "error collection output of '%s', traceback follows:" % prog)
+ self.soslog.log(logging.VERBOSE, traceback.format_exc())
+
+ self.time_stop = time()
+
+ if semaphore: semaphore.release()
+ self.soslog.log(logging.VERBOSE, "plugin %s returning" % self.piName)
+
+ def get_description(self):
+ """ This function will return the description for the plugin"""
+ try:
+ return self.__doc__.strip()
+ except:
+ return "<no description available>"
+
+ def checkenabled(self):
+ """ This function can be overidden to let the plugin decide whether
+ it should run or not.
+ """
+ return True
+
+ def defaultenabled(self):
+ """This devices whether a plugin should be automatically loaded or
+ only if manually specified in the command line."""
+ return True
+
+ def collect(self):
+ """ This function has been replaced with setup(). Please change your
+ module calls. Calling setup() now.
+ """
+ self.setup()
+
+ def diagnose(self):
+ """This class must be overridden to check the sanity of the system's
+ configuration before the collection begins.
+ """
+ pass
+
+ def setup(self):
+ """This class must be overridden to add the copyPaths, forbiddenPaths,
+ and external programs to be collected at a minimum.
+ """
+ pass
+
+ def analyze(self):
+ """
+ perform any analysis. To be replaced by a plugin if desired
+ """
+ pass
+
+ def postproc(self):
+ """
+ perform any postprocessing. To be replaced by a plugin if desired
+ """
+ pass
+
+ def report(self):
+ """ Present all information that was gathered in an html file that allows browsing
+ the results.
+ """
+ # make this prettier
+ html = '<hr/><a name="%s"></a>\n' % self.piName
+
+ # Intro
+ html = html + "<h2> Plugin <em>" + self.piName + "</em></h2>\n"
+
+ # Files
+ if len(self.copiedFiles):
+ html = html + "<p>Files copied:<br><ul>\n"
+ for afile in self.copiedFiles:
+ html = html + '<li><a href="%s">%s</a>' % (afile['dstpath'], afile['srcpath'])
+ if (afile['symlink'] == "yes"):
+ html = html + " (symlink to %s)" % afile['pointsto']
+ html = html + '</li>\n'
+ html = html + "</ul></p>\n"
+
+ # Dirs
+ if len(self.copiedDirs):
+ html = html + "<p>Directories Copied:<br><ul>\n"
+ for adir in self.copiedDirs:
+ html = html + '<li><a href="%s">%s</a>\n' % (adir['dstpath'], adir['srcpath'])
+ if (adir['symlink'] == "yes"):
+ html = html + " (symlink to %s)" % adir['pointsto']
+ html = html + '</li>\n'
+ html = html + "</ul></p>\n"
+
+ # Command Output
+ if len(self.executedCommands):
+ html = html + "<p>Commands Executed:<br><ul>\n"
+ # convert file name to relative path from our root
+ for cmd in self.executedCommands:
+ cmdOutRelPath = sosRelPath(self.cInfo['rptdir'], cmd['file'])
+ html = html + '<li><a href="%s">%s</a></li>\n' % (cmdOutRelPath, cmd['exe'])
+ html = html + "</ul></p>\n"
+
+ # Alerts
+ if len(self.alerts):
+ html = html + "<p>Alerts:<br><ul>\n"
+ for alert in self.alerts:
+ html = html + '<li>%s</li>\n' % alert
+ html = html + "</ul></p>\n"
+
+ # Custom Text
+ if (self.customText != ""):
+ html = html + "<p>Additional Information:<br>\n"
+ html = html + self.customText + "</p>\n"
+
+ return html
+
+
diff --git a/trunk/src/lib/sos/policyredhat.py b/trunk/src/lib/sos/policyredhat.py
new file mode 100755
index 00000000..d4a4074d
--- /dev/null
+++ b/trunk/src/lib/sos/policyredhat.py
@@ -0,0 +1,151 @@
+## policy-redhat.py
+## Implement policies required for the sos system support tool
+
+## Copyright (C) Steve Conklin <sconklin@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import os
+import commands
+import sys
+import string
+from tempfile import gettempdir
+from sos.helpers import *
+import random
+
+SOME_PATH = "/tmp/SomePath"
+
+#class SosError(Exception):
+# def __init__(self, code, message):
+# self.code = code
+# self.message = message
+#
+# def __str__(self):
+# return 'Sos Error %s: %s' % (self.code, self.message)
+
+
+class SosPolicy:
+ "This class implements various policies for sos"
+ def __init__(self):
+ #print "Policy init"
+ return
+
+ def setCommons(self, commons):
+ self.cInfo = commons
+ return
+
+ def validatePlugin(self, pluginpath):
+ "Validates the plugin as being acceptable to run"
+ # return value
+ # TODO implement this
+ #print "validating %s" % pluginpath
+ return True
+
+ def allPkgsByName(self, name):
+ # FIXME: we're relying on rpm to sort the output list
+ cmd = "/bin/rpm --qf '%%{N}-%%{V}-%%{R}-%%{ARCH}\n' -q %s" % (name,)
+ pkgs = os.popen(cmd).readlines()
+ return [pkg[:-1] for pkg in pkgs if pkg.startswith(name)]
+
+ def pkgByName(self, name):
+ # TODO: do a full NEVRA compare and return newest version, best arch
+ try:
+ # lame attempt at locating newest
+ pkg = self.allPkgsByName(name)[-1]
+ except IndexError:
+ pkg = None
+
+ return pkg
+
+ def pkgDictByName(self, name):
+ pkgName = self.pkgByName(name)
+ if pkgName and len(pkgName) > len(name):
+ return pkgName[len(name)+1:].split("-")
+ else:
+ return None
+
+ def runlevelByService(self, name):
+ ret = []
+ try:
+ for tabs in commands.getoutput("/sbin/chkconfig --list %s" % name).split():
+ (runlevel, onoff) = tabs.split(":")
+ if onoff == "on":
+ ret.append(int(runlevel))
+ except:
+ pass
+ return ret
+
+ def runlevelDefault(self):
+ # FIXME: get this from /etc/inittab
+ return 3
+
+ def pkgNVRA(self, pkg):
+ fields = pkg.split("-")
+ version, release, arch = fields[-3:]
+ name = "-".join(fields[:-3])
+ return (name, version, release, arch)
+
+ def packageResults(self):
+ localname = commands.getoutput("/bin/uname -n").split(".")[0]
+
+ try:
+ name = raw_input("Please enter your first initial and last name [%s]: " % localname)
+ if len(name) == 0: name = localname
+
+ ticketNumber = raw_input("Please enter the case number that you are generating this report for: ")
+ except KeyboardInterrupt:
+ print _("<interrupted>")
+ print _("Temporary files have been stored in ") % self.cInfo['dstroot']
+ return
+
+ if len(ticketNumber):
+ namestr = name + "." + ticketNumber
+ else:
+ namestr = name
+
+ ourtempdir = gettempdir()
+ tarballName = os.path.join(ourtempdir, "sosreport-" + namestr + ".tar.bz2")
+
+ namestr = namestr + "-" + str(random.randint(1, 999999))
+
+ aliasdir = os.path.join(ourtempdir, namestr)
+
+ tarcmd = "/bin/tar -jcf %s %s" % (tarballName, namestr)
+
+ print
+ print "Creating compressed tar archive..."
+ if not os.access(string.split(tarcmd)[0], os.X_OK):
+ print "Unable to create tarball"
+ return
+
+ # FIXME: gotta be a better way...
+ os.system("/bin/mv %s %s" % (self.cInfo['dstroot'], aliasdir))
+ curwd = os.getcwd()
+ os.chdir(ourtempdir)
+ oldmask = os.umask(077)
+ # pylint: disable-msg = W0612
+ status, shout, runtime = sosGetCommandOutput(tarcmd)
+ os.umask(oldmask)
+ os.chdir(curwd)
+ # FIXME: use python internal command
+ os.system("/bin/mv %s %s" % (aliasdir, self.cInfo['dstroot']))
+
+ sys.stdout.write("\n")
+ print "Your sosreport has been generated and saved in %s" % tarballName
+ print "Please send this file to your support representative."
+ sys.stdout.write("\n")
+
+ return
+