aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/sos/__init__.py0
-rwxr-xr-xsrc/lib/sos/helpers.py140
-rw-r--r--src/lib/sos/plugins/__init__.py0
-rw-r--r--src/lib/sos/plugins/apache.py24
-rw-r--r--src/lib/sos/plugins/bootloader.py31
-rw-r--r--src/lib/sos/plugins/cluster.py25
-rw-r--r--src/lib/sos/plugins/filesys.py46
-rw-r--r--src/lib/sos/plugins/ftp.py24
-rw-r--r--src/lib/sos/plugins/general.py35
-rw-r--r--src/lib/sos/plugins/hardware.py50
-rw-r--r--src/lib/sos/plugins/kernel.py61
-rw-r--r--src/lib/sos/plugins/ldap.py24
-rw-r--r--src/lib/sos/plugins/libraries.py24
-rw-r--r--src/lib/sos/plugins/mail.py25
-rw-r--r--src/lib/sos/plugins/memory.py27
-rw-r--r--src/lib/sos/plugins/named.py34
-rw-r--r--src/lib/sos/plugins/networking.py58
-rw-r--r--src/lib/sos/plugins/pam.py23
-rw-r--r--src/lib/sos/plugins/process.py24
-rw-r--r--src/lib/sos/plugins/rhn.py86
-rw-r--r--src/lib/sos/plugins/rpm.py32
-rw-r--r--src/lib/sos/plugins/samba.py25
-rw-r--r--src/lib/sos/plugins/selinux.py26
-rw-r--r--src/lib/sos/plugins/squid.py23
-rw-r--r--src/lib/sos/plugins/startup.py26
-rw-r--r--src/lib/sos/plugins/system.py31
-rw-r--r--src/lib/sos/plugins/tarball.py41
-rw-r--r--src/lib/sos/plugins/x11.py26
-rw-r--r--src/lib/sos/plugintools.py299
-rwxr-xr-xsrc/lib/sos/policyredhat.py70
30 files changed, 1360 insertions, 0 deletions
diff --git a/src/lib/sos/__init__.py b/src/lib/sos/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/lib/sos/__init__.py
diff --git a/src/lib/sos/helpers.py b/src/lib/sos/helpers.py
new file mode 100755
index 00000000..447c164f
--- /dev/null
+++ b/src/lib/sos/helpers.py
@@ -0,0 +1,140 @@
+## 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
+##
+
+import os, popen2, fcntl, select, itertools, sys
+from tempfile import mkdtemp
+
+workingBase = None
+
+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(fd):
+ """ Make the file desccriptor non-blocking. This prevents deadlocks.
+ """
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ try:
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)
+ except AttributeError:
+ fcntl.fcntl(fd, 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
+ """
+ child = popen2.Popen3(command, 1) # Capture stdout and stderr from command
+ child.tochild.close() # don't need to write to child's stdin
+ outfile = child.fromchild
+ outfd = outfile.fileno()
+ errfile = child.childerr
+ errfd = errfile.fileno()
+ makeNonBlocking(outfd) # Don't deadlock! Make fd's nonblocking.
+ makeNonBlocking(errfd)
+ outdata, errdata = [], []
+ outeof = erreof = False
+ while True:
+ to_check = [outfd]*(not outeof) + [errfd]*(not erreof)
+ ready = select.select(to_check, [], []) # Wait for input
+ if outfd in ready[0]:
+ outchunk = outfile.read()
+ if outchunk == '':
+ outeof = True
+ else:
+ outdata.append(outchunk)
+ if errfd in ready[0]:
+ errchunk = errfile.read()
+ if errchunk == '':
+ erreof = True
+ else:
+ errdata.append(errchunk)
+ if outeof and erreof:
+ break
+ select.select([],[],[],.1) # Allow a little time for buffers to fill
+ err = child.wait()
+ return (err, ''.join(outdata), ''.join(errdata))
+
+
+# TODO - this needs to be made clean and moved to the plugin tools, so
+# that it prints nice color output like sysreport
+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(p1, p2, sep=os.path.sep, pardir=os.path.pardir):
+ ''' return a relative path from p1 equivalent to path p2.
+ In particular: the empty string, if p1 == p2;
+ p2, if p1 and p2 have no common prefix.
+ '''
+ common, (u1, u2) = commonPrefix(p1.split(sep), p2.split(sep))
+ if not common:
+ return p2 # leave path absolute if nothing at all in common
+ return sep.join( [pardir]*len(u1) + u2 )
+
diff --git a/src/lib/sos/plugins/__init__.py b/src/lib/sos/plugins/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/lib/sos/plugins/__init__.py
diff --git a/src/lib/sos/plugins/apache.py b/src/lib/sos/plugins/apache.py
new file mode 100644
index 00000000..6a3e35ea
--- /dev/null
+++ b/src/lib/sos/plugins/apache.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 apache(sos.plugintools.PluginBase):
+ """This plugin gathers Apache related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/httpd/conf/httpd.conf")
+ self.copyFileGlob("/etc/httpd/conf.d/*.conf")
+ return
+
diff --git a/src/lib/sos/plugins/bootloader.py b/src/lib/sos/plugins/bootloader.py
new file mode 100644
index 00000000..06d653a8
--- /dev/null
+++ b/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):
+ """This plugin gathers bootloader information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/lilo.conf")
+ self.copyFileOrDir("/etc/milo.conf")
+ self.copyFileOrDir("/etc/silo.conf")
+ self.copyFileOrDir("/boot/grub/grub.conf")
+ self.copyFileOrDir("/boot/grub/device.map")
+ self.copyFileOrDir("/boot/efi/elilo.conf")
+ self.copyFileOrDir("/boot/yaboot.conf")
+
+ self.runExe("/sbin/lilo -q")
+ return
+
diff --git a/src/lib/sos/plugins/cluster.py b/src/lib/sos/plugins/cluster.py
new file mode 100644
index 00000000..35f7e9a9
--- /dev/null
+++ b/src/lib/sos/plugins/cluster.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 cluster(sos.plugintools.PluginBase):
+ """This plugin gathers cluster related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/cluster.conf")
+ self.copyFileOrDir("/etc/cluster.xml")
+ self.copyFileOrDir("/etc/cluster")
+ return
+
diff --git a/src/lib/sos/plugins/filesys.py b/src/lib/sos/plugins/filesys.py
new file mode 100644
index 00000000..71859047
--- /dev/null
+++ b/src/lib/sos/plugins/filesys.py
@@ -0,0 +1,46 @@
+### 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):
+ """This plugin gathers infomraiton on filesystems
+ """
+ def collect(self):
+ self.copyFileOrDir("/proc/filesystems")
+ self.copyFileOrDir("/etc/fstab")
+ self.copyFileOrDir("/proc/mounts")
+ self.copyFileOrDir("/proc/mdstat")
+ self.copyFileOrDir("/etc/raidtab")
+ self.copyFileOrDir("/etc/mdadm.conf")
+ self.copyFileOrDir("/etc/auto.master")
+ self.copyFileOrDir("/etc/auto.misc")
+ self.copyFileOrDir("/etc/auto.net")
+
+ self.runExe("/bin/df -al")
+ self.runExe("/usr/sbin/lsof -b +M -n -l")
+ self.runExe("/bin/mount -l")
+ self.runExe("/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.runExe("/sbin/fdisk -l /dev/%s 2>&1" % (disk,))
+ for disk in disks.split('\n'):
+ if '' != disk.strip():
+ self.runExe("/sbin/fdisk -l /dev/%s 2>&1" % (disk,))
+ return
+
diff --git a/src/lib/sos/plugins/ftp.py b/src/lib/sos/plugins/ftp.py
new file mode 100644
index 00000000..f1c80304
--- /dev/null
+++ b/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):
+ """This plugin gathers FTP server related information
+ """
+ def collect(self):
+ self.copyFileGlob("/etc/ftp*")
+ self.copyFileOrDir("/etc/vsftpd")
+ return
+
diff --git a/src/lib/sos/plugins/general.py b/src/lib/sos/plugins/general.py
new file mode 100644
index 00000000..9a9544a7
--- /dev/null
+++ b/src/lib/sos/plugins/general.py
@@ -0,0 +1,35 @@
+### 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 general(sos.plugintools.PluginBase):
+ """This plugin gathers very basic system information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/redhat-release")
+ self.copyFileOrDir("/etc/sysconfig")
+ self.copyFileOrDir("/proc/stat")
+ self.copyFileOrDir("/var/log/dmesg")
+ self.copyFileOrDir("/var/log/messages")
+ self.copyFileOrDir("/var/log/sa")
+ self.copyFileOrDir("/var/log/secure")
+ self.copyFileOrDir("/var/log/up2date")
+ self.copyFileOrDir("/etc/exports")
+ self.copyFileGlob("/etc/cups/*.conf")
+ self.runExe("/bin/hostname")
+ self.runExe("/bin/date")
+ self.runExe("/usr/bin/uptime")
+ return
+
diff --git a/src/lib/sos/plugins/hardware.py b/src/lib/sos/plugins/hardware.py
new file mode 100644
index 00000000..7f2b075b
--- /dev/null
+++ b/src/lib/sos/plugins/hardware.py
@@ -0,0 +1,50 @@
+### 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):
+ """This plugin gathers hardware related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/proc/partitions")
+ self.copyFileOrDir("/proc/cpuinfo")
+ self.copyFileOrDir("/proc/meminfo")
+ self.copyFileOrDir("/proc/ioports")
+ self.copyFileOrDir("/proc/interrupts")
+ self.copyFileOrDir("/proc/scsi")
+ self.copyFileOrDir("/proc/dma")
+ self.copyFileOrDir("/proc/devices")
+ self.copyFileOrDir("/proc/rtc")
+ self.copyFileOrDir("/proc/ide")
+ self.copyFileOrDir("/proc/bus")
+ self.copyFileOrDir("/etc/stinit.def")
+ self.copyFileOrDir("/etc/sysconfig/hwconf")
+ self.copyFileOrDir("/proc/chandev")
+ self.copyFileOrDir("/proc/dasd")
+ self.copyFileOrDir("/proc/s390dbf/tape")
+ self.runExe("/usr/share/rhn/up2dateclient/hardware.py")
+ self.runExe("/sbin/lspci -vvn")
+ self.runExe("dmesg | grep -e 'e820.' -e 'agp.'")
+
+ for hwmodule in commands.getoutput('cat pcitable | grep -v "Card:" | awk \'{ gsub("\"","",$0); { print $NF; };} \' | uniq -u'):
+ cmdToRun = "dmesg | grep %s" % (hwmodule,)
+ self.runExe(cmdToRun)
+
+ self.runExe("/usr/sbin/vgdisplay -vv")
+ self.runExe("/sbin/lsusb")
+ self.runExe("/usr/bin/lshal")
+ return
+
diff --git a/src/lib/sos/plugins/kernel.py b/src/lib/sos/plugins/kernel.py
new file mode 100644
index 00000000..064a8314
--- /dev/null
+++ b/src/lib/sos/plugins/kernel.py
@@ -0,0 +1,61 @@
+### 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 kernel(sos.plugintools.PluginBase):
+ """This plugin gathers kernel related information
+ """
+ optionList = [("modinfo", 'Gathers module information on all modules', 'fast', 1),
+ ('sysrq', 'Trigger SysRq dumps', 'fast', 1)]
+
+ def collect(self):
+ self.runExe("/bin/uname -a")
+ self.runExe("/sbin/lsmod")
+ if self.isOptionEnabled('modinfo'):
+ 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 = "/sbin/modinfo %s" % (kmod,)
+ self.runExe(runcmd)
+ self.runExe("/sbin/ksyms")
+ self.copyFileOrDir("/proc/filesystems")
+ self.copyFileOrDir("/proc/ksyms")
+ self.copyFileOrDir("/proc/slabinfo")
+ kver = commands.getoutput('/bin/uname -r')
+ depfile = "/lib/modules/%s/modules.dep" % (kver,)
+ self.copyFileOrDir(depfile)
+ self.copyFileOrDir("/etc/conf.modules")
+ self.copyFileOrDir("/etc/modules.conf")
+ self.copyFileOrDir("/etc/modprobe.conf")
+ self.runExe("/usr/sbin/dmidecode")
+ self.runExe("/usr/sbin/dkms status")
+ self.copyFileOrDir("/proc/cmdline")
+ self.copyFileOrDir("/proc/driver")
+ # 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.copyFileGlob("/var/log/messages*")
+
+
+ return
+
diff --git a/src/lib/sos/plugins/ldap.py b/src/lib/sos/plugins/ldap.py
new file mode 100644
index 00000000..4a353a26
--- /dev/null
+++ b/src/lib/sos/plugins/ldap.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 ldap(sos.plugintools.PluginBase):
+ """This plugin gathers LDAP related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/ldap.conf")
+ self.copyFileOrDir("/etc/openldap")
+ return
+
diff --git a/src/lib/sos/plugins/libraries.py b/src/lib/sos/plugins/libraries.py
new file mode 100644
index 00000000..f6adf89b
--- /dev/null
+++ b/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):
+ """This plugin gathers information on shared libraries
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/ld.so.conf")
+ self.copyFileOrDir("/etc/ld.so.conf.d")
+ return
+
diff --git a/src/lib/sos/plugins/mail.py b/src/lib/sos/plugins/mail.py
new file mode 100644
index 00000000..8945550d
--- /dev/null
+++ b/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):
+ """This plugin gathers mail server related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/mail")
+ self.copyFileOrDir("/etc/postfix/main.cf")
+ self.copyFileOrDir("/etc/postfix/master.cf")
+ return
+
diff --git a/src/lib/sos/plugins/memory.py b/src/lib/sos/plugins/memory.py
new file mode 100644
index 00000000..0e6d6a60
--- /dev/null
+++ b/src/lib/sos/plugins/memory.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 memory(sos.plugintools.PluginBase):
+ """This plugin gathers memory usage information
+ """
+ def collect(self):
+ self.copyFileOrDir("/proc/pci")
+ self.copyFileOrDir("/proc/meminfo")
+
+ self.runExe("/bin/dmesg | grep -e 'e820.' -e 'aperature.'")
+ self.runExe("/usr/bin/free")
+ return
+
diff --git a/src/lib/sos/plugins/named.py b/src/lib/sos/plugins/named.py
new file mode 100644
index 00000000..7d77c40d
--- /dev/null
+++ b/src/lib/sos/plugins/named.py
@@ -0,0 +1,34 @@
+### 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):
+ """This plugin gathers named related information
+ """
+ def collect(self):
+ dnsdir = ""
+ self.copyFileOrDir("/etc/named.boot")
+ self.copyFileOrDir("/etc/named.conf")
+ 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():
+ print "FIX named.py - hangs when named chrooted because of /var/named/chroot/proc"
+ #self.copyFileOrDir(dnsdir)
+ return
+
diff --git a/src/lib/sos/plugins/networking.py b/src/lib/sos/plugins/networking.py
new file mode 100644
index 00000000..f6a8fdb0
--- /dev/null
+++ b/src/lib/sos/plugins/networking.py
@@ -0,0 +1,58 @@
+### 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
+
+class networking(sos.plugintools.PluginBase):
+ """This plugin gathers network related information
+ """
+
+ def get_interface_name(self,ifconfigFile):
+ """Return a dictionnary for wich key are intefrace name according to the
+ output of ifcongif-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 collect(self):
+ self.copyFileOrDir("/etc/nsswitch.conf")
+ self.copyFileOrDir("/etc/yp.conf")
+ self.copyFileOrDir("/etc/inetd.conf")
+ self.copyFileOrDir("/etc/xinetd.conf")
+ self.copyFileOrDir("/etc/xinetd.d")
+ self.copyFileGlob("/etc/host*")
+ self.copyFileOrDir("/etc/resolv.conf")
+ # self.copyFileOrDir("/etc/sysconfig/iptables-config")
+ # The above is redundant
+ ifconfigFile=self.runExe("/sbin/ifconfig -a")
+ self.runExe("/sbin/route -n")
+ self.runExe("/sbin/ipchains -nvL")
+ self.runExe("/sbin/iptables -t filter -nvL")
+ self.runExe("/sbin/iptables -t nat -nvL")
+ self.runExe("/sbin/iptables -t mangle -nvL")
+ if ifconfigFile:
+ for eth in self.get_interface_name(ifconfigFile):
+ self.runExe("/sbin/ethtool "+eth)
+
+ return
+
diff --git a/src/lib/sos/plugins/pam.py b/src/lib/sos/plugins/pam.py
new file mode 100644
index 00000000..adce0046
--- /dev/null
+++ b/src/lib/sos/plugins/pam.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 pam(sos.plugintools.PluginBase):
+ """This plugin gathers PAM related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/pam.d")
+ return
+
diff --git a/src/lib/sos/plugins/process.py b/src/lib/sos/plugins/process.py
new file mode 100644
index 00000000..d360af10
--- /dev/null
+++ b/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):
+ """This plugin gathers process information
+ """
+ def collect(self):
+ self.runExe("/bin/ps auxww")
+ self.runExe("/usr/bin/pstree")
+ return
+
diff --git a/src/lib/sos/plugins/rhn.py b/src/lib/sos/plugins/rhn.py
new file mode 100644
index 00000000..512e0d7d
--- /dev/null
+++ b/src/lib/sos/plugins/rhn.py
@@ -0,0 +1,86 @@
+### 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):
+ """This plugin gathers RHN server related information
+ """
+ def collect(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
+
+ #
+ # 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.copyFileGlob("/var/log/rhn*")
+ self.copyFileOrDir("/etc/rhn")
+ self.runExe("/usr/share/rhn/up2date_client/hardware.py")
+
+ # httpd
+ self.copyFileOrDir("/etc/httpd/conf")
+ self.copyFileOrDir("/var/log/httpd")
+
+ # RPM manifests
+ self.runExe("/bin/rpm -qa --last | sort")
+
+ # monitoring scout logs
+ self.copyFileGlob("/home/nocpulse/var/*.log*")
+ self.copyFileGlob("/home/nocpulse/var/commands/*.log*")
+
+ #
+ # Now, go for product-specific data
+ #
+ if satellite:
+ self.collectSatellite(satellite)
+
+ if proxy:
+ self.collectProxy(proxy)
+
+ def collectSatellite(self, satellite):
+ self.runExe("/usr/bin/rhn-schema-version")
+ self.runExe("/usr/bin/rhn-charsets")
+
+ # oracle
+ self.copyFileOrDir("/etc/tnsnames.ora")
+
+ # tomcat (4.x and newer satellites only)
+ if not self.cInfo["policy"].pkgNVRA(satellite)[1].startswith("3."):
+ self.copyFileOrDir("/etc/tomcat5")
+ self.copyFileOrDir("/var/log/tomcat5")
+
+ # jabberd
+ # - logs to /var/log/messages
+ self.copyFileOrDir("/etc/jabberd")
+
+ # SSL build
+ self.copyFileOrDir("/root/ssl-build")
+
+ # monitoring logs
+ self.copyFileGlob("/opt/notification/var/*.log*")
+ self.copyFileGlob("/var/tmp/ack_handler.log*")
+ self.copyFileGlob("/var/tmp/enqueue.log*")
+
+ def collectProxy(self, proxy):
+ # squid
+ self.copyFileOrDir("/etc/squid")
+ self.copyFileOrDir("/var/log/squid")
+
diff --git a/src/lib/sos/plugins/rpm.py b/src/lib/sos/plugins/rpm.py
new file mode 100644
index 00000000..44b9d5c8
--- /dev/null
+++ b/src/lib/sos/plugins/rpm.py
@@ -0,0 +1,32 @@
+### 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):
+ """This plugin gathers RPM information
+ """
+ optionList = [("rpmq", "Queries for package information via rpm -q", "fast", 1),
+ ("rpmva", "Runs a verify on all packages", "slow", 0)]
+
+ def collect(self):
+ self.copyFileOrDir("/var/log/rpmpkgs")
+
+ if self.isOptionEnabled("rpmq"):
+ self.runExe("/bin/rpm -qa --qf \"%{NAME}-%{VERSION}-%{RELEASE}-%{ARCH}\n\"")
+
+ if self.isOptionEnabled("rpmva"):
+ self.runExe("/bin/rpm -Va")
+ return
+
diff --git a/src/lib/sos/plugins/samba.py b/src/lib/sos/plugins/samba.py
new file mode 100644
index 00000000..848da265
--- /dev/null
+++ b/src/lib/sos/plugins/samba.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 samba(sos.plugintools.PluginBase):
+ """This plugin gathers Samba related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/samba")
+ self.runExe("/usr/bin/wbinfo -g")
+ self.runExe("/usr/bin/wbinfo -u")
+ return
+
diff --git a/src/lib/sos/plugins/selinux.py b/src/lib/sos/plugins/selinux.py
new file mode 100644
index 00000000..51fe90d9
--- /dev/null
+++ b/src/lib/sos/plugins/selinux.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 selinux(sos.plugintools.PluginBase):
+ """This plugin gathers selinux related information
+ """
+ def collect(self):
+ self.runExe("/usr/bin/selinuxconfig")
+ self.runExe("/usr/sbin/sestatus")
+ self.runExe("/bin/rpm -q -V selinux-policy-targeted")
+ self.runExe("/bin/rpm -q -V selinux-policy-strict")
+ return
+
diff --git a/src/lib/sos/plugins/squid.py b/src/lib/sos/plugins/squid.py
new file mode 100644
index 00000000..e552a99e
--- /dev/null
+++ b/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):
+ """This plugin gathers Squid related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/squid/squid.conf")
+ return
+
diff --git a/src/lib/sos/plugins/startup.py b/src/lib/sos/plugins/startup.py
new file mode 100644
index 00000000..820ee0e7
--- /dev/null
+++ b/src/lib/sos/plugins/startup.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 startup(sos.plugintools.PluginBase):
+ """This plugin gathers startup information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/rc.d")
+
+ self.runExe("/sbin/chkconfig --list")
+ # self.runExe("/bin/ls /etc/rc.d/rc*.d/") # This is redundant.
+ return
+
diff --git a/src/lib/sos/plugins/system.py b/src/lib/sos/plugins/system.py
new file mode 100644
index 00000000..b98b40df
--- /dev/null
+++ b/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):
+ """This plugin gathers core system related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/proc/sys")
+ self.copyFileOrDir("/etc/sysctl.conf")
+ self.copyFileGlob("/etc/cron*")
+ self.copyFileOrDir("/etc/syslog.conf")
+ self.copyFileOrDir("/etc/ntp.conf")
+ self.copyFileOrDir("/etc/ntp/step-tickers")
+ self.copyFileOrDir("/etc/ntp/ntpservers")
+ self.copyFileOrDir("/etc/auto.*")
+
+ return
+
diff --git a/src/lib/sos/plugins/tarball.py b/src/lib/sos/plugins/tarball.py
new file mode 100644
index 00000000..787ffed2
--- /dev/null
+++ b/src/lib/sos/plugins/tarball.py
@@ -0,0 +1,41 @@
+### 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 sys
+import sos.plugintools
+from sos.helpers import *
+
+class tarball(sos.plugintools.PluginBase):
+ """This plugin tars up the information gathered by sosreport
+ """
+ def postproc(self, dstroot):
+ print "Please enter your first initial and last name (jsmith): ",
+ name = sys.stdin.readline()[:-1]
+
+ print "Please enter the case number that you are generating this",
+ print "report for: ",
+ ticketNumber = sys.stdin.readline()[:-1]
+
+ dirName = name + "." + ticketNumber
+ self.runExeInd("/bin/mkdir /tmp/%s" % dirName)
+ self.runExeInd("/bin/mv %s/* /tmp/%s"
+ % (dstroot, dirName))
+ self.runExeInd("/bin/rm -rf %s" % dstroot)
+ self.runExeInd("/bin/tar --directory /tmp -jcf "
+ "/tmp/%s.tar.bz2 %s"
+ % (dirName, dirName))
+ self.runExeInd("/bin/rm -rf /tmp/%s" % dirName)
+ print "Your tarball is located at /tmp/%s.tar.bz2" % dirName
+ return "/tmp/" + dirName
+
diff --git a/src/lib/sos/plugins/x11.py b/src/lib/sos/plugins/x11.py
new file mode 100644
index 00000000..9d9b27c9
--- /dev/null
+++ b/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):
+ """This plugin gathers X related information
+ """
+ def collect(self):
+ self.copyFileOrDir("/etc/X11")
+ self.copyFileGlob("/var/log/Xorg.*.log")
+ self.copyFileGlob("/var/log/XFree86.*.log")
+ self.runExe("/bin/dmesg | grep -e 'agpgart.'")
+ return
+
diff --git a/src/lib/sos/plugintools.py b/src/lib/sos/plugintools.py
new file mode 100644
index 00000000..1a0fd9d4
--- /dev/null
+++ b/src/lib/sos/plugintools.py
@@ -0,0 +1,299 @@
+## 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.
+
+from sos.helpers import *
+import os, os.path, sys, string, itertools, glob
+
+class PluginBase:
+ """
+ Base class for plugins
+ """
+# optionList = []
+# copiedFiles = []
+# copiedDirs = []
+# executedCommands = []
+# alerts = []
+# customText = ""
+# cInfo = None
+# piName = None
+# optNames = []
+# optParms = []
+
+ def __init__(self, pluginname, commons):
+ try:
+ foo = len(self.optionList)
+ except:
+ self.optionList = []
+ self.copiedFiles = []
+ self.copiedDirs = []
+ self.executedCommands = []
+ self.alerts = []
+ self.customText = ""
+ self.optNames = []
+ self.optParms = []
+ self.piName = pluginname
+ self.cInfo = commons
+
+ # 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]})
+ return
+
+
+ def __copyFile(self, src):
+ """ call cp to copy a file, collect return status and output. Returns the
+ destination file name.
+ """
+ print "Copying %s" % src,
+ sys.stdout.flush()
+
+ status, shout, sherr = sosGetCommandOutput("/bin/cp --parents " + src + " " + self.cInfo['dstroot'])
+ self.cInfo['logfd'].write(shout)
+ self.cInfo['logfd'].write(sherr)
+ sosStatus(status)
+ abspath = os.path.join(self.cInfo['dstroot'], src.lstrip(os.path.sep))
+ relpath = sosRelPath(self.cInfo['rptdir'], abspath)
+ return relpath, abspath
+
+
+ def __copyDir(self, src):
+ """ call cp to copy a directory tree, collect return status and output. Returns the path where it
+ got put.
+ """
+ print "Copying %s" % src,
+ sys.stdout.flush()
+
+ status, shout, sherr = sosGetCommandOutput("/bin/cp --parents -R " + src + " " + self.cInfo['dstroot'])
+ self.cInfo['logfd'].write(shout)
+ self.cInfo['logfd'].write(sherr)
+ sosStatus(status)
+ abspath = self.cInfo['dstroot'] + src
+ relpath = sosRelPath(self.cInfo['rptdir'], abspath)
+ return relpath, abspath
+
+ # Methods for dealing with options
+
+ def getAllOptions(self):
+ 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 copyFileGlob(self, srcglob):
+ ''' Copy all files and/or directories specified by the glob to the
+ destination tree.
+ '''
+ for source in glob.glob(srcglob):
+ self.copyFileOrDir(source)
+
+ # Methods for copying files and shelling out
+ def copyFileOrDir(self, srcpath):
+ ''' 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
+ '''
+ 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)
+
+ if os.path.isdir(srcpath):
+ dstslname, abspath = self.__copyDir(srcpath)
+ self.copiedDirs.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link})
+ else:
+ dstslname, abspath = self.__copyFile(srcpath)
+ self.copiedFiles.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link})
+
+ # Recurse to copy whatever it points to
+ newpath = os.path.normpath(os.path.join(os.path.dirname(srcpath), link))
+ self.copyFileOrDir(newpath)
+ return abspath
+
+ else:
+ if not os.path.exists(srcpath):
+ self.cInfo['logfd'].write("File or directory %s does not exist\n" % srcpath)
+ elif os.path.isdir(srcpath):
+ tdstpath, abspath = self.__copyDir(srcpath)
+ self.copiedDirs.append({'srcpath':srcpath, 'dstpath':tdstpath, 'symlink':"no", 'pointsto':""})
+ return abspath
+ 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 runExeInd(self, exe):
+ """ Execute a command independantly of the output gathering part of
+ sosreport
+ """
+
+ # First check to make sure the binary exists and is runnable.
+ if not os.access(exe.split()[0], os.X_OK):
+ return
+
+ status, shout, sherr = sosGetCommandOutput(exe)
+
+ return status
+
+ def runExe(self, exe):
+ """ 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):
+ return
+
+ print "Collecting output from command <%s>" % (exe),
+ sys.stdout.flush()
+
+ status, shout, sherr = sosGetCommandOutput(exe)
+
+ # build file name for output
+ rawcmd = os.path.basename(exe).strip()[:28]
+
+ # Mangle command to make it suitable for a file name
+ tabl = string.maketrans(" /\t;#$|%\"'`}{\n", "_._-----------")
+ mangledname = rawcmd.translate(tabl)
+
+ outfn = self.cInfo['cmddir'] + "/" + self.piName + "." + mangledname
+
+ # check for collisions
+ while os.path.exists(outfn):
+ outfn = outfn + "z"
+
+ outfd = open(outfn, "w")
+ outfd.write(shout)
+ outfd.close()
+ self.cInfo['logfd'].write(sherr)
+ sosStatus(status)
+ # save info for later
+ self.executedCommands.append({'exe': exe, 'file':outfn}) # save in our list
+ return outfn
+
+ # 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
+
+
+ # What follows are the methods which may be overridden by the plugin
+
+
+ def collect(self):
+ pass
+
+ def analyze(self):
+ pass
+
+ def postproc(self, dstroot):
+ pass
+
+ def report(self):
+ """ Present all information that was gathered in an html file that allows browsing
+ the results.
+ """
+ # TODO make this prettier, this is a first pass
+ 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 file in self.copiedFiles:
+ html = html + '<li><a href="%s">%s</a>' % (file['dstpath'], file['srcpath'])
+ if (file['symlink'] == "yes"):
+ html = html + " (symlink to %s)" % file['pointsto']
+ html = html + '</li>\n'
+ html = html + "</ul></p>\n"
+
+ # Dirs
+ if len(self.copiedDirs):
+ html = html + "<p>Directories Copied:<br><ul>\n"
+ for dir in self.copiedDirs:
+ html = html + '<li><a href="%s">%s</a>\n' % (dir['dstpath'], dir['srcpath'])
+ if (dir['symlink'] == "yes"):
+ html = html + " (symlink to %s)" % dir['pointsto']
+ html = html + '</li>\n'
+ html = html + "</ul></p>\n"
+
+ # Command Output
+ if len(self.executedCommands):
+ html = html + "<p>Commands Executed:<br><ul>\n"
+ for cmd in self.executedCommands:
+ html = html + '<li><a href="%s">%s</a></li>\n' % (cmd['file'], 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/src/lib/sos/policyredhat.py b/src/lib/sos/policyredhat.py
new file mode 100755
index 00000000..14e5fa8a
--- /dev/null
+++ b/src/lib/sos/policyredhat.py
@@ -0,0 +1,70 @@
+## 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.path
+#import copy
+#import md5
+import os
+
+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 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 pkgNVRA(self, pkg):
+ fields = pkg.split("-")
+ version, release, arch = fields[-3:]
+ name = "-".join(fields[:-3])
+ return (name, version, release, arch)
+