diff options
Diffstat (limited to 'src')
39 files changed, 954 insertions, 1555 deletions
diff --git a/src/Makefile b/src/Makefile index 37c384bc..942e4776 100644 --- a/src/Makefile +++ b/src/Makefile @@ -59,7 +59,7 @@ release: clean @echo " " @echo "The final archive is ./$(NAME)-$(VERSION).tar.bz2." -install:mo gpgkey +install:mo python setup.py install @rm -rf build/lib @@ -67,40 +67,18 @@ version: @echo "The version is $(NAME)-$(VERSION)" clean: - @rm -fv *~ .*~ changenew ChangeLog.old $(NAME)-$(VERSION).tar.bz2 sosreport.1.gz gpgkeys/rhsupport.* + @rm -fv *~ .*~ changenew ChangeLog.old $(NAME)-$(VERSION).tar.bz2 sosreport.1.gz @rm -rfv build/* -internal-rpm: gpgkey - @test -f sos-internal.spec - @mkdir -p $(TOPDIR)/SOURCES $(TOPDIR)/SRPMS $(TOPDIR)/RPMS $(TOPDIR)/BUILD $(SRCDIR)/dist - cp gpgkeys/rhsupport.pub gpgkeys/rhsupport.key $(TOPDIR)/SOURCES - -# this builds an RPM from the current working copy - @cd $(TOPDIR)/BUILD ; \ - rm -rf $(NAME)-$(VERSION) ; \ - ln -s $(SRCDIR) $(NAME)-$(VERSION) ; \ - tar --gzip --exclude=.svn --exclude=svn-commit.tmp --exclude=$(NAME)-$(VERSION)/build --exclude=$(NAME)-$(VERSION)/dist \ - --exclude gpgkeys/rhsupport.pub --exclude gpgkeys/rhsupport.key \ - -chSpf $(TOPDIR)/SOURCES/$(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION) ; \ - rm -f $(NAME)-$(VERSION) - - rpmbuild -ba --define="_topdir $(TOPDIR)" sos-internal.spec - @mv $(TOPDIR)/RPMS/noarch/$(NAME)-internal-*.rpm $(TOPDIR)/SRPMS/$(NAME)-internal-*.rpm dist/ - cp gpgkeys/rhsupport.key dist/ - -rpm: mo gpgkey - @mkdir -p $(TOPDIR)/SOURCES $(TOPDIR)/SRPMS $(TOPDIR)/RPMS $(TOPDIR)/BUILD $(SRCDIR)/dist - - cp gpgkeys/rhsupport.pub $(TOPDIR)/SOURCES - +rpm: mo @test -f sos.spec + @mkdir -p $(TOPDIR)/SOURCES $(TOPDIR)/SRPMS $(TOPDIR)/RPMS $(TOPDIR)/BUILD $(SRCDIR)/dist # this builds an RPM from the current working copy @cd $(TOPDIR)/BUILD ; \ rm -rf $(NAME)-$(VERSION) ; \ ln -s $(SRCDIR) $(NAME)-$(VERSION) ; \ tar --gzip --exclude=.svn --exclude=svn-commit.tmp --exclude=$(NAME)-$(VERSION)/build --exclude=$(NAME)-$(VERSION)/dist \ - --exclude gpgkeys/rhsupport.pub --exclude gpgkeys/rhsupport.key \ -chSpf $(TOPDIR)/SOURCES/$(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION) ; \ rm -f $(NAME)-$(VERSION) @@ -117,7 +95,3 @@ pot: mo: find locale/*/LC_MESSAGES -name sos.po -exec python tools/msgfmt.py {} \; - -gpgkey: - @test -f gpgkeys/rhsupport.pub && echo "GPG key already exists." || \ - gpg --batch --gen-key gpgkeys/gpg.template @@ -4,8 +4,8 @@ package maintainers, and anyone else to provide plugins that will collect, analyze, and report information that is useful for supporting software packages. -This project is hosted at http://hosted.fedoraproject.org/projects/sos -For the latest version, to contribute, and for more information, please visit there. +This project is hosted at http://sos.108.redhat.com. For the latest version, +to contribute, and for more information, please visit there. To access to the public source code repository for this project run: @@ -20,20 +20,9 @@ Maintainer: Navid Sheikhol-Eslami <navid@redhat.com> -Developers and Contributors: +Contributors: - Adam Stokes <astokes@redhat.com> - Cris Lalancette <clalance@redhat.com> - Eugene Teo <eteo@redhat.com> - John Berninger <jwb@redhat.com> - Justin Payne <jpayne@redhat.com> - Pierre Amadio <pamadio@redhat.com> - Qian Shen <qshen@redhat.com> Steve Conklin <sconklin@redhat.com> - -Thanks to: - - Eva Schaller <eschaller@redhat.com> for providing an Italian translation - Marco Ceci <mceci@redhat.com> for helping me out with the cluster plugin - Leonardo Macchia <lmacchia@redhat.com> for being my personal regexp generator - Imed Chihi <ichihi@redhat.com> for providing Arabic and French translations + Pierre Amadio <pamadio@redhat.com> + John Berninger <jwb@redhat.com> + Navid Sheikhol-Eslami <navid@redhat.com> diff --git a/src/extras/sysreport/functions b/src/extras/sysreport/functions index fff52ccd..74061d18 100755 --- a/src/extras/sysreport/functions +++ b/src/extras/sysreport/functions @@ -48,14 +48,14 @@ getpciinfo() { catiffile() { if [ -d $1 ]; then - /bin/cp -p -x --parents -R $1 $ROOT 2>>$ROOT/$log + /bin/cp -x --parents -R $1 $ROOT 2>>$ROOT/$log find $ROOT/$1 -type b -o -type c | xargs rm -f 2>/dev/null || : echo -n $STATUS echo_success return 1 fi if [ -f $1 ]; then - /bin/cp -p --parents $1 $ROOT 2>>$ROOT/$log + /bin/cp --parents $1 $ROOT 2>>$ROOT/$log echo -n $STATUS echo_success return 1 diff --git a/src/extras/sysreport/sysreport.legacy b/src/extras/sysreport/sysreport.legacy index 043ba026..3ffc1069 100755 --- a/src/extras/sysreport/sysreport.legacy +++ b/src/extras/sysreport/sysreport.legacy @@ -13,8 +13,8 @@ umask 0077 UTILDIR=/usr/share/sysreport VER=`/bin/uname -r` PATH="" -PROGNAME="sysreport" DATE=`/bin/date -u +%G%m%d%k%M%S | /usr/bin/tr -d ' '` +TEMP='/tmp' function usage { echo "Sysreport is a utility that gathers information about a system's" @@ -27,24 +27,17 @@ function usage { echo " -help : show help" echo " -norpm : omit collecting information about currently installed packages" echo " -dmidecode: enable dmidecode, getting information about the hardware" - echo " -firewall : collecting the system firewall rules" - echo " -home : place sysreport outputs within home directory" - echo " -usesysrq : collecting information about sysrq-trigger" echo exit 0 } -[ $# -lt 6 ] || usage +[ $# -lt 3 ] || usage for i do case "$i" in -help) usage;; -norpm) NORPM=yes;; -dmidecode) DMIDECODE=yes;; - -firewall) FIREWALL=yes;; - -home) HOMEDIR=yes;; - -sysrq) SYSRQ_TRIGGER=yes;; - -usesysrq) SYSRQ_TRIGGER=yes;; *) usage;; esac done @@ -60,15 +53,8 @@ if [ $UID != 0 ]; then exit 1 fi -if [ "$HOMEDIR" = yes ] ; then - TEMPDIR=$HOME - ROOT=$HOME/sysreport-$DATE - /bin/mkdir $ROOT >& /dev/null -else - TEMPDIR=/tmp - ROOT=`/bin/mktemp -dq /tmp/sysreport.XXXXXXXX` -fi -if [ $? != 0 ] ; then +ROOT=$TEMP/sysreport-$DATE +if ( ! mkdir $ROOT >& /dev/null ) ; then echo "Cannot make temp dir" exit 1 fi @@ -212,7 +198,7 @@ STATUS="Collecting information about X:" catiffile "/etc/X11" STATUS="Gathering sysctl information (/proc/sys):" -catifexec "/sbin/sysctl" "-a" +catiffile "/proc/sys" STATUS="Gathering sysctl information (/etc/sysctl.conf):" catiffile "/etc/sysctl.conf" @@ -395,9 +381,6 @@ catiffile "/etc/auto.net" STATUS="Collecting LVM information:" catifexec "/usr/sbin/vgdisplay" "-vv" -STATUS="Gathering LVM setup" -catiffile "/etc/lvm" - STATUS="Collecting SCSI Tape information (/etc/stinit.def)" catiffile "/etc/stinit.def" @@ -442,25 +425,23 @@ done STATUS="Collecting information about ypbind configuration:" catiffile "/etc/yp.conf" -if [ "$FIREWALL" == "yes" ]; then - KERNELMIN=`/bin/uname -r | /bin/sed -e 's,[^\.]*\.,,' -e 's,\..*,,'` - ipchainsmod=`/sbin/lsmod 2>/dev/null| /bin/grep ipchains` - - if [ "$KERNELMIN" -lt 3 ] || [ -n "${ipchainsmod}" ] ; then - STATUS="Getting ipchains information:" - catifexec "/sbin/ipchains" "-nvL" - elif [ "$KERNELMIN" -gt 3 ]; then - STATUS="Getting iptables information:" - if [ -f /etc/sysconfig/iptables-config ] ; then - catiffile "/etc/sysconfig/iptables-config" - fi - STATUS="Getting iptables information (filter):" - catifexec "/sbin/iptables" "-t filter -nvL" - STATUS="Getting iptables information (mangle):" - catifexec "/sbin/iptables" "-t mangle -nvL" - STATUS="Getting iptables information (nat):" - catifexec "/sbin/iptables" "-t nat -nvL" +KERNELMIN=`/bin/uname -r | /bin/sed -e 's,[^\.]*\.,,' -e 's,\..*,,'` +ipchainsmod=`/sbin/lsmod 2>/dev/null| /bin/grep ipchains` + +if [ "$KERNELMIN" -lt 3 ] || [ -n "${ipchainsmod}" ] ; then + STATUS="Getting ipchains information:" + catifexec "/sbin/ipchains" "-nvL" +elif [ "$KERNELMIN" -gt 3 ]; then + STATUS="Getting iptables information:" + if [ -f /etc/sysconfig/iptables-config ] ; then + catiffile "/etc/sysconfig/iptables-config" fi + STATUS="Getting iptables information (filter):" + catifexec "/sbin/iptables" "-t filter -nvL" + STATUS="Getting iptables information (mangle):" + catifexec "/sbin/iptables" "-t mangle -nvL" + STATUS="Getting iptables information (nat):" + catifexec "/sbin/iptables" "-t nat -nvL" fi # ldap client and server config @@ -603,22 +584,23 @@ for x in `/bin/ls -d /etc/cups/*.conf 2>/dev/null` ; do catiffile "$x" done +STATUS="Getting information about printcap" +catiffile "/etc/printcap" + echo echo "Gathering information from system logs" echo STATUS="Collecting information from dmesg:" catiffile "/var/log/dmesg" -if [ "$SYSRQ_TRIGGER" == "yes" ]; then - STATUS="Collecting information from /proc/sysrq-trigger" - if [ -f /proc/sysrq-trigger -a -f /proc/sys/kernel/sysrq ] ; then - sysr_state="$(/bin/cat /proc/sys/kernel/sysrq)" - echo 1 > /proc/sys/kernel/sysrq - for key in m p t ; do - echo $key > /proc/sysrq-trigger - done - echo $sysr_state > /proc/sys/kernel/sysrq - fi +STATUS="Collecting information from /proc/sysrq-trigger" +if [ -f /proc/sysrq-trigger -a -f /proc/sys/kernel/sysrq ] ; then + sysr_state="$(/bin/cat /proc/sys/kernel/sysrq)" + echo 1 > /proc/sys/kernel/sysrq + for key in m p t ; do + echo $key > /proc/sysrq-trigger + done + echo $sysr_state > /proc/sys/kernel/sysrq fi for x in `/bin/ls /var/log/messages*` ; do @@ -702,7 +684,6 @@ if [ -f $RHNDIR/systemid ] ; then catiffile "$RHNDIR/systemid" fi fi - # Get hardware profile information (for verification with system state and RHN) if [ -x /usr/share/rhn/up2date_client/hardware.py ] ; then STATUS="Gathering RHN hardware profile information" @@ -717,7 +698,6 @@ if [ -x /usr/bin/rhn-charsets ] ; then catifexec "/usr/bin/rhn-charsets" fi -# Get SELinux information echo echo "Gathering information on SELinux setup" echo @@ -726,8 +706,9 @@ catifexec "/usr/sbin/sestatus" catifexec "rpm" "-q -V selinux-policy-targeted" catifexec "rpm" "-q -V selinux-policy-strict" -cd $TEMPDIR +cd $TEMP /bin/echo +HOSTNM=`hostname -s` /bin/echo -n "Please enter your case number (if you have one): " while read CASENUM @@ -742,9 +723,9 @@ do esac done if [ ! $CASENUM ]; then - NAME=$PROGNAME-$HOSTNAME.$DATE + NAME=$HOSTNM.$DATE else - NAME="$PROGNAME-$HOSTNAME-$CASENUM.$DATE" + NAME="$HOSTNM-$CASENUM.$DATE" fi /bin/rm -Rf $NAME /bin/mv $ROOT $NAME @@ -759,7 +740,7 @@ fi /bin/rm -Rf $NAME /bin/echo -/bin/echo "Please send $TEMPDIR/${NAME}.${SUFFIX} to your support" +/bin/echo "Please send $TEMP/${NAME}.${SUFFIX} to your support" /bin/echo "representative." /bin/echo diff --git a/src/lib/sos/helpers.py b/src/lib/sos/helpers.py index 77f85b01..bcdee6fb 100755 --- a/src/lib/sos/helpers.py +++ b/src/lib/sos/helpers.py @@ -25,29 +25,9 @@ """ helper functions used by sosreport and plugins """ -import os, popen2, fcntl, select, sys, commands, signal -from time import time, sleep - -if sys.version_info[0] <= 2 and sys.version_info[1] <= 2: - # it's a RHEL3, activate work-arounds - # - import sos.rhel3_logging - logging = sos.rhel3_logging - - def mkdtemp(suffix = "", prefix = "temp_"): - import random - while True: - tempdir = "/tmp/%s_%d%s" % (prefix, random.randint(1,9999999), suffix) - if not os.path.exists(tempdir): break - os.mkdir(tempdir) - return tempdir - - os.path.sep = "/" - os.path.pardir = ".." -else: - # RHEL4+, business as usual - import logging - from tempfile import mkdtemp +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 @@ -77,72 +57,17 @@ def makeNonBlocking(afd): fcntl.fcntl(afd, fcntl.F_SETFL, fl | os.FNDELAY) -def sosGetCommandOutput(command, timeout = 300): +def sosGetCommandOutput(command): """ Execute a command and gather stdin, stdout, and return status. """ - soslog = logging.getLogger('sos') - - # Log if binary is not runnable or does not exist - for path in os.environ["PATH"].split(":"): - cmdfile = command.strip("(").split()[0] - # handle both absolute or relative paths - if ( ( not os.path.isabs(cmdfile) and os.access(os.path.join(path,cmdfile), os.X_OK) ) or \ - ( os.path.isabs(cmdfile) and os.access(cmdfile, os.X_OK) ) ): - break - else: - soslog.log(logging.VERBOSE, "binary '%s' does not exist or is not runnable" % cmdfile) - return (127, "", 0) - - # these are file descriptors, not file objects - r, w = os.pipe() - - pid = os.fork() - - if pid: - # we are the parent - os.close(w) # use os.close() to close a file descriptor - r_fd = os.fdopen(r) # turn r into a file object - stime=time() - txt = "" - sts = -1 - soslog.log(logging.VERBOSE2, 'forked command "%s" with pid %d, timeout is %d' % (command, pid, timeout) ) - while True: - # read output from pipe - ready = select.select([r], [], [], 1) - if r in ready[0]: - txt = txt + r_fd.read() - # is child still running ? - try: os.waitpid(pid, os.WNOHANG) - except: - # not running, make sure the child process gets cleaned up - try: sts = os.waitpid(pid, 0)[1] - except: pass - break - # has timeout passed ? - if time() - stime > timeout: - soslog.log(logging.VERBOSE, 'killing hung child with pid %s after %d seconds (command was "%s")' % (pid,timeout,command) ) - try: os.kill(pid, signal.SIGKILL) - except: pass - break - if txt[-1:] == '\n': txt = txt[:-1] - return (sts, txt, time()-stime) - else: - # we are the child - os.dup2(r, 0) - os.dup2(w, 1) - os.dup2(w, 2) - - import resource - maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] - if not hasattr(resource, "RLIM_INFINITY"): - resource.RLIM_INFINITY = -1L - if (maxfd == resource.RLIM_INFINITY): - maxfd = MAXFD - for fd in range(3, maxfd): - try: os.close(fd) - except OSError: pass - os.execl("/bin/sh", "/bin/sh", "-c", command) - os._exit(127) + stime = time() + inpipe, pipe = os.popen4(command, 'r') + inpipe.close() + text = pipe.read() + sts = pipe.close() + if sts is None: sts = 0 + if text[-1:] == '\n': text = text[:-1] + return (sts, text, 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 @@ -167,11 +92,23 @@ def allEqual(elements): return False return True -def commonPrefix(l1, l2, common = []): + +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 len(l1) < 1 or len(l2) < 1 or l1[0] != l2[0]: return common, [l1, l2] - return commonPrefix(l1[1:], l2[1:], common+[l1[0]]) + # 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. @@ -187,9 +124,3 @@ def sosRelPath(path1, path2, sep=os.path.sep, pardir=os.path.pardir): return path2 # leave path absolute if nothing at all in common return sep.join( [pardir]*len(u1) + u2 ) -def sosReadFile(fname): - ''' reads a file and returns its contents''' - fp = open(fname,"r") - content = fp.read() - fp.close() - return content diff --git a/src/lib/sos/plugins/apache.py b/src/lib/sos/plugins/apache.py index 10061918..c5250fd9 100644 --- a/src/lib/sos/plugins/apache.py +++ b/src/lib/sos/plugins/apache.py @@ -13,6 +13,7 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import sos.plugintools +from threading import Thread class apache(sos.plugintools.PluginBase): """Apache related information diff --git a/src/lib/sos/plugins/autofs.py b/src/lib/sos/plugins/autofs.py index 16a8d3fb..48dd57b4 100644 --- a/src/lib/sos/plugins/autofs.py +++ b/src/lib/sos/plugins/autofs.py @@ -15,7 +15,7 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import sos.plugintools -import os +import os, re class autofs(sos.plugintools.PluginBase): """autofs server-related information @@ -24,8 +24,38 @@ class autofs(sos.plugintools.PluginBase): if self.cInfo["policy"].runlevelDefault() in self.cInfo["policy"].runlevelByService("autofs"): return True return False - + + def checkdebug(self): + """ testing if autofs debug has been enabled anywhere + """ + # Global debugging + optlist=[] + opt = self.fileGrep(r"^(DEFAULT_LOGGING|DAEMONOPTIONS)=(.*)", "/etc/sysconfig/autofs") + for opt1 in opt: + for opt2 in opt1.split(" "): + optlist.append(opt2) + for dtest in optlist: + if dtest == "--debug" or dtest == "debug": + return True + + def getdaemondebug(self): + """ capture daemon debug output + """ + debugout = self.fileGrep(r"^(daemon.*)\s+(\/var\/log\/.*)", "/etc/sysconfig/autofs") + for i in debugout: + return i[1] + def setup(self): self.addCopySpec("/etc/auto*") self.addCopySpec("/etc/sysconfig/autofs") - self.addCopySpec("/etc/rc.d/init.d/autofs") + self.addCopySpec("/etc/init.d/autofs") + self.collectExtOutput("/bin/rpm -qV autofs") + self.collectExtOutput("/etc/init.d/autofs status") + self.collectExtOutput("ps auxwww | grep automount") + self.collectExtOutput("/bin/egrep -e 'automount|pid.*nfs' /proc/mounts") + self.collectExtOutput("/bin/mount | egrep -e 'automount|pid.*nfs'") + self.collectExtOutput("/sbin/chkconfig --list autofs") + if self.checkdebug(): + self.addCopySpec(self.getdaemondebug()) + return + diff --git a/src/lib/sos/plugins/cluster.py b/src/lib/sos/plugins/cluster.py index 6d4de2a0..f6169ddb 100644 --- a/src/lib/sos/plugins/cluster.py +++ b/src/lib/sos/plugins/cluster.py @@ -25,178 +25,139 @@ class cluster(sos.plugintools.PluginBase): ('taskdump', 'trigger 3 sysrq+t dumps every 5 seconds (dangerous)', 'slow', False)] def checkenabled(self): - rhelver = self.cInfo["policy"].rhelVersion() - if rhelver == 4: - self.packages = [ "ccs", "cman", "cman-kernel", "magma", "magma-plugins", - "rgmanager", "fence", "dlm", "dlm-kernel", "gulm", - "GFS", "GFS-kernel", "lvm2-cluster" ] - elif rhelver == 5: - self.packages = [ "rgmanager", "luci", "ricci", "system-config-cluster", - "gfs-utils", "gnbd", "kmod-gfs", "kmod-gnbd", "lvm2-cluster" ] - - self.files = [ "/etc/cluster/cluster.conf", "/proc/cluster" ] - return sos.plugintools.PluginBase.checkenabled(self) + # enable if any related package is installed + for pkg in [ "rgmanager", "luci", "ricci", "system-config-cluster", + "gfs-utils", "gnbd", "kmod-gfs", "kmod-gnbd", "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", "/proc/cluster" ]: + try: os.stat(fname) + except:pass + else: return True + + # no data related to RHCS/GFS exists + return False def has_gfs(self): - try: - if len(self.doRegexFindAll(r'^\S+\s+\S+\s+gfs\s+.*$', "/etc/mtab")): - return True - except: - return False + fp = open("/proc/mounts","r") + for line in fp.readlines(): + mntline = line.split(" ") + if mntline[2] == "gfs": + return True + fp.close() + return False def diagnose(self): - rhelver = self.cInfo["policy"].rhelVersion() - - # 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) - - pkgs_check = [] - mods_check = [] - serv_check = [] - - if rhelver == 4: - pkgs_check.extend( [ "ccs", "cman", "magma", "magma-plugins", "perl-Net-Telnet", "rgmanager", "fence" ] ) - mods_check.extend( [ "cman", "dlm" ] ) - if self.has_gfs(): - mods_check.append("gfs") - serv_check.extend( [ "cman", "ccsd", "rgmanager", "fenced" ] ) - if self.has_gfs(): - serv_check.extend( ["gfs", "clvmd"] ) - elif rhelver == 5: - pkgs_check.extend ( [ "cman", "perl-Net-Telnet", "rgmanager" ] ) - mods_check.extend( [ "dlm" ] ) - if self.has_gfs(): - mods_check.extend( ["gfs", "gfs2"] ) - serv_check.extend( [ "cman", "rgmanager" ] ) - if self.has_gfs(): - serv_check.extend( ["gfs", "clvmd"] ) - - # check that kernel module packages are installed for - # running kernel version - - for modname in mods_check: - found = 0 - - if self.cInfo["policy"].allPkgsByNameRegex( "^" + modname ): - found = 1 - - status, output = commands.getstatusoutput('/sbin/modinfo -F vermagic ' + modname) - - if status == 0: - found = 2 - - if len(self.fileGrep("^%s\s+" % modname, "/proc/modules")) > 0: - found = 3 - - if found == 0: - self.addDiagnose("required kernel module is missing: %s" % modname) - elif found == 1: - self.addDiagnose("required module is not available for current kernel: %s" % modname) - elif found == 2: - self.addDiagnose("required module is available but not loaded: %s" % modname) - - for pkg in pkgs_check: - if self.cInfo["policy"].pkgByName(pkg) == None: - self.addDiagnose("required package is missing: %s" % pkg) - - if rhelver == "4": - # (dlm, dlm-kernel) || gulm - if not ((self.cInfo["policy"].pkgByName("dlm") and self.cInfo["policy"].pkgByName("dlm-kernel")) or self.cInfo["policy"].pkgByName("gulm")): - self.addDiagnose("required packages are missing: (dlm, dlm-kernel) || gulm") - - # 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 serv_check: - status, output = commands.getstatusoutput("/sbin/service %s status &> /dev/null" % service) - if status != 0: - 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: missing important cman services - # FIXME: any cman service whose state != run ? - # Fence Domain: "default" 2 2 run - - - # is cluster quorate - if not self.is_cluster_quorate(): - self.addDiagnose("cluster node is not quorate") - - # if there is no cluster.conf, diagnose() finishes here. - try: - os.stat("/etc/cluster/cluster.conf") - except: - self.addDiagnose("/etc/cluster/cluster.conf is missing") - return - - # setup XML xpath context - xml = libxml2.parseFile("/etc/cluster/cluster.conf") - xpathContext = xml.xpathNewContext() - - # make sure that the node names are valid according to RFC 2181 - for hostname in xpathContext.xpathEval('/cluster/clusternodes/clusternode/@name'): - if not re.match('^[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$', hostname.content): - self.addDiagnose("node name (%s) contains invalid characters" % hostname.content) - - # do not rely on DNS to resolve node names, must have them in /etc/hosts - for hostname in xpathContext.xpathEval('/cluster/clusternodes/clusternode/@name'): - if len(self.fileGrep(r'^.*\W+%s' % hostname.content , "/etc/hosts")) == 0: - self.addDiagnose("node %s is not defined in /etc/hosts" % hostname.content) - - # check fencing (warn on no fencing) - if len(xpathContext.xpathEval("/cluster/clusternodes/clusternode[not(fence/method/device)]")): - if self.has_gfs(): - self.addDiagnose("one or more nodes have no fencing agent configured: fencing is required for GFS to work") - else: - self.addDiagnose("one or more nodes have no fencing agent configured: the cluster infrastructure might not work as intended") - - # check fencing (warn on manual) - if len(xpathContext.xpathEval("/cluster/clusternodes/clusternode[/cluster/fencedevices/fencedevice[@agent='fence_manual']/@name=fence/method/device/@name]")): - self.addDiagnose("one or more nodes have manual fencing agent configured (data integrity is not guaranteed)") - - # if fence_ilo or fence_drac, make sure acpid is not running - hostname = commands.getoutput("/bin/uname -n").split(".")[0] - if len(xpathContext.xpathEval('/cluster/clusternodes/clusternode[@name = "%s" and /cluster/fencedevices/fencedevice[@agent="fence_rsa" or @agent="fence_drac"]/@name=fence/method/device/@name]' % hostname )): - status, output = commands.getstatusoutput("/sbin/service acpid status") - if status == 0 or self.cInfo["policy"].runlevelDefault() in self.cInfo["policy"].runlevelByService("acpid"): - self.addDiagnose("acpid is enabled, this may cause problems with your fencing method.") - - # check for fs exported via nfs without nfsid attribute - if len(xpathContext.xpathEval("/cluster/rm/service//fs[not(@fsid)]/nfsexport")): - self.addDiagnose("one or more nfs export do not have a fsid attribute set.") - - # cluster.conf file version and the in-memory cluster configuration version matches - status, cluster_version = commands.getstatusoutput("cman_tool status | grep 'Config version'") - if not status: cluster_version = cluster_version[16:] - else: cluster_version = None - conf_version = xpathContext.xpathEval("/cluster/@config_version")[0].content - - if status == 0 and conf_version != cluster_version: - self.addDiagnose("cluster.conf and in-memory configuration version differ (%s != %s)" % (conf_version, cluster_version) ) - - status, output = commands.getstatusoutput("/usr/sbin/rg_test test /etc/cluster/cluster.conf") - if output.find("Error: ") > 0: - self.addDiagnose("configuration errors are present according to rg_test") - - # make sure the first part of the lock table matches the cluster name - # and that the locking protocol is sane - cluster_name = xpathContext.xpathEval("/cluster/@name")[0].content - - for fs in self.fileGrep(r'^[^#][/\w]*\W*[/\w]*\W*gfs', "/etc/fstab"): - # for each gfs entry - fs = fs.split() - lockproto = self.get_gfs_sb_field(fs[0], "sb_lockproto") - if lockproto and lockproto != self.get_locking_proto(): - self.addDiagnose("gfs mountpoint (%s) is using the wrong locking protocol (%s)" % (fs[0], lockproto) ) - - locktable = self.get_gfs_sb_field(fs[0], "sb_locktable") - try: locktable = locktable.split(":")[0] - except: continue - if locktable != cluster_name: - self.addDiagnose("gfs mountpoint (%s) is using the wrong locking table" % fs[0]) + try: rhelver = self.cInfo["policy"].pkgByName("redhat-release")[1] + except: rhelver = None + + # FIXME: we should only run tests specific for the version, now just do them all regardless + if rhelver.startswith("5"): + # check that kernel module packages are installed for + # running kernel version + pkgs_check = [ ] + if self.has_gfs(): pkgs_check.append("kmod-gfs") + + for pkgname in pkgs_check: + if not self.cInfo["policy"].pkgByName(pkgname): + self.addDiagnose("required package is missing: %s" % pkgname) + + # 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 [ "cman", "perl-Net-Telnet", "rgmanager" ]: + if self.cInfo["policy"].pkgByName(pkg) == None: + self.addDiagnose("required package is missing: %s" % pkg) + + # let's make modules sure are loaded + mods_check = [ "dlm" ] + if self.has_gfs(): mods_check.append("gfs") + for module in mods_check: + if len(self.fileGrep("^%s " % module, "/proc/modules")) == 0: + self.addDiagnose("required module is not loaded: %s" % module) + + # check if all the needed daemons are active at sosreport time + # check if they are started at boot time in RHEL5 RHCS (rgmanager, cman) + # and GFS (gfs, ccsd, clvmd, fenced) + checkserv = [ "cman", "rgmanager" ] + if self.has_gfs(): checkserv.extend( ["gfs", "clvmd"] ) + for service in checkserv: + status, output = commands.getstatusoutput("/sbin/service %s status" % service) + if status: + 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: any cman service whose state != run ? + # Fence Domain: "default" 2 2 run - + + # is cluster quorate + if not self.is_cluster_quorate(): + self.addDiagnose("cluster node is not quorate") + + # if there is no cluster.conf, diagnose() finishes here. + try: + os.stat("/etc/cluster/cluster.conf") + except: + self.addDiagnose("/etc/cluster/cluster.conf is missing") + return + + # setup XML xpath context + xml = libxml2.parseFile("/etc/cluster/cluster.conf") + xpathContext = xml.xpathNewContext() + + # check fencing (warn on no fencing) + if len(xpathContext.xpathEval("/cluster/clusternodes/clusternode[not(fence/method/device)]")): + if self.has_gfs(): + self.addDiagnose("one or more nodes have no fencing agent configured: fencing is required for GFS to work") + else: + self.addDiagnose("one or more nodes have no fencing agent configured: the cluster infrastructure might not work as intended") + + # check fencing (warn on manual) + if len(xpathContext.xpathEval("/cluster/clusternodes/clusternode[/cluster/fencedevices/fencedevice[@agent='fence_manual']/@name=fence/method/device/@name]")): + self.addDiagnose("one or more nodes have manual fencing agent configured (data integrity is not guaranteed)") + + # if fence_ilo or fence_drac, make sure acpid is not running + hostname = commands.getoutput("/bin/uname -n").split(".")[0] + if len(xpathContext.xpathEval('/cluster/clusternodes/clusternode[@name = "%s" and /cluster/fencedevices/fencedevice[@agent="fence_rsa" or @agent="fence_drac"]/@name=fence/method/device/@name]' % hostname )): + status, output = commands.getstatusoutput("/sbin/service acpid status") + if status == 0 or self.cInfo["policy"].runlevelDefault() in self.cInfo["policy"].runlevelByService("acpid"): + self.addDiagnose("acpid is enabled, this may cause problems with your fencing method.") + + # check for fs exported via nfs without nfsid attribute + if len(xpathContext.xpathEval("/cluster/rm/service//fs[not(@fsid)]/nfsexport")): + self.addDiagnose("one or more nfs export do not have a fsid attribute set.") + + # cluster.conf file version and the in-memory cluster configuration version matches + status, cluster_version = commands.getstatusoutput("cman_tool status | grep 'Config version'") + if not status: cluster_version = cluster_version[16:] + else: cluster_version = None + conf_version = xpathContext.xpathEval("/cluster/@config_version")[0].content + + if status == 0 and conf_version != cluster_version: + self.addDiagnose("cluster.conf and in-memory configuration version differ (%s != %s)" % (conf_version, cluster_version) ) + + # make sure the first part of the lock table matches the cluster name + # and that the locking protocol is sane + cluster_name = xpathContext.xpathEval("/cluster/@name")[0].content + + for fs in self.fileGrep(r'^[^#][/\w]*\W*[/\w]*\W*gfs', "/etc/fstab"): + # for each gfs entry + fs = fs.split() + + lockproto = self.get_gfs_sb_field(fs[0], "sb_lockproto") + if lockproto and lockproto != self.get_locking_proto(): + self.addDiagnose("gfs mountpoint (%s) is using the wrong locking protocol (%s)" % (fs[0], lockproto) ) + + locktable = self.get_gfs_sb_field(fs[0], "sb_locktable") + try: locktable = locktable.split(":")[0] + except: continue + if locktable != cluster_name: + self.addDiagnose("gfs mountpoint (%s) is using the wrong locking table" % fs[0]) def setup(self): self.collectExtOutput("/sbin/fdisk -l") @@ -214,9 +175,9 @@ class cluster(sos.plugintools.PluginBase): self.collectExtOutput("/sbin/ipvsadm -L") - if self.getOption('gfslockdump'): self.do_gfslockdump() - if self.getOption('lockdump'): self.do_lockdump() - if self.getOption('taskdump'): self.do_taskdump() + if self.isOptionEnabled('gfslockdump'): self.do_gfslockdump() + if self.isOptionEnabled('lockdump'): self.do_lockdump() + if self.isOptionEnabled('taskdump'): self.do_taskdump() return @@ -233,24 +194,20 @@ class cluster(sos.plugintools.PluginBase): self.addCopySpec("/var/log/messages") def do_lockdump(self): - status, output = commands.getstatusoutput("cman_tool services") - if status: - # command somehow failed - return False - - import re - - rhelver = self.get_redhat_release() - - if rhelver == "4": - regex = r'^DLM Lock Space:\s*"([^"]*)".*$' - elif rhelver == "5Server" or rhelver == "5Client": - regex = r'^dlm\s+[^\s]+\s+([^\s]+)\s.*$' - - reg=re.compile(regex,re.MULTILINE) - for lockspace in reg.findall(output): - commands.getstatusoutput("echo %s > /proc/cluster/dlm_locks" % lockspace) - self.collectOutputNow("cat /proc/cluster/dlm_locks", root_symlink = "dlm_locks_%s" % lockspace) + try: + fp = open("/proc/cluster/services","r") + except: + return + for line in fp.readlines(): + if line[0:14] == "DLM Lock Space": + try: + lockspace = line.split('"')[1] + except: + pass + else: + commands.getstatusoutput("echo %s > /proc/cluster/dlm_locks" % lockspace) + self.collectOutputNow("cat /proc/cluster/dlm_locks", root_symlink = "dlm_locks_%s" % lockspace) + fp.close() def get_locking_proto(self): # FIXME: what's the best way to find out ? @@ -258,11 +215,15 @@ class cluster(sos.plugintools.PluginBase): return "lock_gulm" def do_gfslockdump(self): - for mntpoint in self.doRegexFindAll(r'^\S+\s+([^\s]+)\s+gfs\s+.*$', "/proc/mounts"): - self.collectExtOutput("/sbin/gfs_tool lockdump %s" % mntpoint, root_symlink = "gfs_lockdump_" + self.mangleCommand(mntpoint) ) - - def do_rgmanager_bt(self): - # FIXME: threads backtrace via SIGALRM + fp = open("/proc/mounts","r") + for line in fp.readlines(): + mntline = line.split(" ") + if mntline[2] == "gfs": + self.collectExtOutput("/sbin/gfs_tool lockdump %s" % mntline[1], root_symlink = "gfs_lockdump_" + self.mangleCommand(mntline[1]) ) + fp.close() + + def do_rgmgr_bt(self): + # FIXME: threads backtrace return def postproc(self): @@ -272,7 +233,7 @@ class cluster(sos.plugintools.PluginBase): def is_cluster_quorate(self): output = commands.getoutput("cman_tool status | grep '^Membership state: '") try: - if output[18:] == "Cluster-Member": + if output.split(":")[1].strip() == "Cluster-Member": return True else: return False diff --git a/src/lib/sos/plugins/devicemapper.py b/src/lib/sos/plugins/devicemapper.py index 5a1b63c2..38009689 100644 --- a/src/lib/sos/plugins/devicemapper.py +++ b/src/lib/sos/plugins/devicemapper.py @@ -22,6 +22,11 @@ class devicemapper(sos.plugintools.PluginBase): optionList = [("lvmdump", 'collect raw metadata from PVs', 'slow', False)] + def do_lvmdump(self): + """Collects raw metadata directly from the PVs using dd + """ + sosGetCommandOutput("lvmdump -d %s" % os.path.join(self.cInfo['dstroot'],"lvmdump")) + def setup(self): self.collectExtOutput("/sbin/dmsetup info -c") self.collectExtOutput("/sbin/dmsetup table") @@ -40,18 +45,17 @@ class devicemapper(sos.plugintools.PluginBase): self.addCopySpec("/var/lib/multipath/bindings") self.collectExtOutput("/sbin/multipath -v4 -ll") - self.collectExtOutput("/usr/bin/systool -v -C -b scsi") + self.collectExtOutput("/usr/bin/systool -v -c -b scsi") self.collectExtOutput("/bin/ls -laR /dev") self.collectExtOutput("/bin/ls -laR /sys/block") if self.getOption('lvmdump'): - sosGetCommandOutput("lvmdump -d %s" % os.path.join(self.cInfo['dstroot'],"lvmdump")) + self.do_lvmdump() - if os.path.isdir("/sys/block"): - for disk in os.listdir("/sys/block"): - if disk in [ ".", ".." ] or disk.startswith("ram"): - continue - self.collectExtOutput("/usr/bin/udevinfo -ap /sys/block/%s" % (disk)) + for disk in os.listdir("/sys/block"): + if disk in [ ".", ".." ] or disk.startswith("ram"): + continue + self.collectExtOutput("/usr/bin/udevinfo -ap /sys/block/%s" % (disk)) return diff --git a/src/lib/sos/plugins/emc.py b/src/lib/sos/plugins/emc.py index 24b3e04c..16f039a8 100644 --- a/src/lib/sos/plugins/emc.py +++ b/src/lib/sos/plugins/emc.py @@ -37,7 +37,7 @@ class emc(sos.plugintools.PluginBase): def get_pp_files(self): """ EMC PowerPath specific information - files """ - self.collectExtOutput("/sbin/powermt version") + self.collectExtOutput("/sbin/powermt version") self.addCopySpec("/etc/init.d/PowerPath") self.addCopySpec("/etc/powermt.custom") self.addCopySpec("/etc/emcp_registration") @@ -50,7 +50,7 @@ class emc(sos.plugintools.PluginBase): return def get_pp_config(self): - """ EMC PowerPath specific information - commands + """ EMC PowerPath specific information - commands """ self.collectExtOutput("/sbin/powermt display") self.collectExtOutput("/sbin/powermt display dev=all") @@ -59,12 +59,12 @@ class emc(sos.plugintools.PluginBase): self.collectExtOutput("/sbin/powermt display ports") self.collectExtOutput("/sbin/powermt display paths") self.collectExtOutput("/sbin/powermt dump") - return + return def get_symcli_files(self): """ EMC Solutions Enabler SYMCLI specific information - files """ - self.addCopySpec("/var/symapi/db/symapi_db.bin") + self.addCopySpec("/var/symapi/db/symapi_db.bin") self.addCopySpec("/var/symapi/config/[a-z]*") self.addCopySpec("/var/symapi/log/[a-z]*") return @@ -116,7 +116,7 @@ class emc(sos.plugintools.PluginBase): self.collectExtOutput("/usr/symcli/bin/symmask list hba") self.collectExtOutput("/usr/symcli/bin/symmask list logins") self.collectExtOutput("/usr/symcli/bin/symmaskdb list database") - self.collectExtOutput("/usr/symcli/bin/symmaskdb -v list database") + self.collectExtOutput("/usr/symcli/bin/symmaskdb -v list database") return def get_navicli_config(self): @@ -139,14 +139,14 @@ class emc(sos.plugintools.PluginBase): self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s getdisk" % SP_address) self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s getcache" % SP_address) self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s getlun" % SP_address) - self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s getlun -rg -type -default -owner -crus -capacity" % SP_address) + self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s getlun -rg -type -default -owner -crus -capacity" % SP_address) self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s lunmapinfo" % SP_address) self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s getcrus" % SP_address) self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s port -list -all" % SP_address) self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s storagegroup -list" % SP_address) self.collectExtOutput("/opt/Navisphere/bin/navicli -h %s spportspeed -get" % SP_address) return - + def setup(self): ## About EMC Corporation default no if no EMC products are installed add_about_emc="no" @@ -184,9 +184,9 @@ class emc(sos.plugintools.PluginBase): self.get_navicli_config() print " Gathering Navisphere NAVICLI Host Agent information..." print " Please enter a CLARiiON SP IP address. In order to collect" - print " information for both SPA and SPB as well as multiple" + print " information for both SPA and SPB as well as multiple" print " CLARiiON arrays (if desired) you will be prompted multiple times." - print " To exit simply press [Enter]" + print " To exit simply press [Enter]" print "" add_about_emc = "yes" CLARiiON_IP_address_list = [] @@ -194,23 +194,23 @@ class emc(sos.plugintools.PluginBase): while CLARiiON_IP_loop == "stay_in": ans = raw_input("CLARiiON SP IP Address or [Enter] to exit: ") ## Check to make sure the CLARiiON SP IP address provided is valid - status, output = commands.getstatusoutput("/opt/Navisphere/bin/navicli -h %s getsptime" % ans) - if status == 0: + status, output = commands.getstatusoutput("/opt/Navisphere/bin/navicli -h %s getsptime" % ans) + if status == 0: CLARiiON_IP_address_list.append(ans) else: if ans != "": - print "The IP address you entered, %s, is not to an active CLARiiON SP." % ans + print "The IP address you entered, %s, is not to an active CLARiiON SP." % ans if ans == "": CLARiiON_IP_loop = "get_out" ## Sort and dedup the list of CLARiiON IP Addresses CLARiiON_IP_address_list.sort() for SP_address in CLARiiON_IP_address_list: if CLARiiON_IP_address_list.count(SP_address) > 1: - CLARiiON_IP_address_list.remove(SP_address) + CLARiiON_IP_address_list.remove(SP_address) for SP_address in CLARiiON_IP_address_list: if SP_address != "": print " Gathering NAVICLI information for %s..." % SP_address - self.get_navicli_SP_info(SP_address) + self.get_navicli_SP_info(SP_address) ## Only provide About EMC if EMC products are installed if add_about_emc != "no": diff --git a/src/lib/sos/plugins/filesys.py b/src/lib/sos/plugins/filesys.py index 3e3a7fba..bec046f2 100644 --- a/src/lib/sos/plugins/filesys.py +++ b/src/lib/sos/plugins/filesys.py @@ -13,7 +13,7 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import sos.plugintools -import os +import commands class filesys(sos.plugintools.PluginBase): """information on filesystems @@ -29,11 +29,12 @@ class filesys(sos.plugintools.PluginBase): self.addCopySpec("/etc/mdadm.conf") self.collectExtOutput("/bin/df -al", root_symlink = "df") + self.collectExtOutput("/usr/sbin/lsof -b +M -n -l", root_symlink = "lsof") self.collectExtOutput("/sbin/blkid") - + self.collectExtOutput("/sbin/fdisk -l", root_symlink = "fdisk-l") for extfs in self.doRegexFindAll(r"^(/dev/.+) on .+ type ext.\s+", mounts): self.collectExtOutput("/sbin/dumpe2fs %s" % (extfs)) - return + diff --git a/src/lib/sos/plugins/general.py b/src/lib/sos/plugins/general.py index 434bfdaa..062e0674 100644 --- a/src/lib/sos/plugins/general.py +++ b/src/lib/sos/plugins/general.py @@ -20,35 +20,25 @@ class general(sos.plugintools.PluginBase): """basic system information """ - optionList = [("syslogsize", "max size (MiB) to collect per syslog file", "", 15), - ("all_logs", "collect all log files defined in syslog.conf", "", False)] + optionList = [("syslogsize", "max size (MiB) to collect per syslog file", "", 15)] def setup(self): self.addCopySpec("/etc/redhat-release") self.addCopySpec("/etc/fedora-release") - self.addCopySpec("/etc/inittab") - self.addCopySpec("/etc/sos.conf") 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.getOption("syslogsize")) + self.addCopySpecLimit("/var/log/messages.*", sizelimit = self.isOptionEnabled("syslogsize")) self.addCopySpec("/var/log/secure") - self.addCopySpecLimit("/var/log/secure.*", sizelimit = self.getOption("syslogsize")) + 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") - self.collectExtOutput("/bin/env") - - if self.getOption('all_logs'): - logs=self.doRegexFindAll(r"^\S+\s+(\S+)", "/etc/syslog.conf") - for i in logs: - i = i.lstrip("-") - if not os.path.isfile(i): continue - self.addCopySpec(i) - + self.addCopySpec("/root/anaconda-ks.cfg") return def postproc(self): diff --git a/src/lib/sos/plugins/hardware.py b/src/lib/sos/plugins/hardware.py index ad4a5537..ba10a356 100644 --- a/src/lib/sos/plugins/hardware.py +++ b/src/lib/sos/plugins/hardware.py @@ -36,12 +36,23 @@ class hardware(sos.plugintools.PluginBase): self.addCopySpec("/proc/dasd") self.addCopySpec("/proc/s390dbf/tape") self.collectExtOutput("/usr/share/rhn/up2dateclient/hardware.py") - self.collectExtOutput("""/bin/echo -e "lspci:\n" ; /sbin/lspci ; /bin/echo -e "\nlspci -nvv:\n" ; /sbin/lspci -nvv ; /bin/echo -e "\nlspci -tv:\n" ; /sbin/lspci -tv""", suggest_filename = "lspci", root_symlink = "lspci") + self.collectExtOutput("""/bin/echo "lspci:" ; /bin/echo ; /sbin/lspci ; /bin/echo ; /bin/echo "lspci -nvv:" ; /bin/echo ; /sbin/lspci -nvv""", suggest_filename = "lspci", root_symlink = "lspci") self.collectExtOutput("/usr/sbin/dmidecode", root_symlink = "dmidecode") - if self.cInfo["policy"].getArch().endswith("386"): - self.collectExtOutput("/usr/sbin/x86info -a") + # FIXME: if arch == i386: +# self.collectExtOutput("/usr/sbin/x86info -a") + + # 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") diff --git a/src/lib/sos/plugins/initrd.py b/src/lib/sos/plugins/initrd.py index 7bd7e1f3..83356548 100644 --- a/src/lib/sos/plugins/initrd.py +++ b/src/lib/sos/plugins/initrd.py @@ -20,9 +20,9 @@ class initrd(sos.plugintools.PluginBase): """ def setup(self): for initrd in glob.glob('/boot/initrd-*.img'): - self.collectExtOutput("/bin/zcat "+initrd+" | /bin/cpio "+ + self.collectExtOutput("/bin/zcat "+initrd+" | /bin/cpio "+ "--extract --to-stdout init" ) return def defaultenabled(self): - return False + return False diff --git a/src/lib/sos/plugins/kernel.py b/src/lib/sos/plugins/kernel.py index 4fb0a864..8ca53b66 100644 --- a/src/lib/sos/plugins/kernel.py +++ b/src/lib/sos/plugins/kernel.py @@ -18,7 +18,7 @@ import commands, os, re class kernel(sos.plugintools.PluginBase): """kernel related information """ - optionList = [("modinfo", 'gathers information on all kernel modules', 'fast', True), + optionList = [("modinfo", 'gathers module information on all modules', 'fast', True), ('sysrq', 'trigger sysrq+[m,p,t] dumps', 'fast', False)] moduleFile = "" taintList = [ @@ -28,7 +28,7 @@ class kernel(sos.plugintools.PluginBase): {'regex':'vxportal*', 'description':'Veritas module'}, {'regex':'vxdmp*', 'description':'Veritas dynamic multipathing module'}, {'regex':'vxio*', 'description':'Veritas module'}, - {'regex':'vxspec*', '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'}, @@ -49,22 +49,22 @@ class kernel(sos.plugintools.PluginBase): def setup(self): self.collectExtOutput("/bin/uname -a", root_symlink = "uname") self.moduleFile = self.collectOutputNow("/sbin/lsmod", root_symlink = "lsmod") - - if self.getOption('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) - + 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/sysctl -a") self.collectExtOutput("/sbin/ksyms") self.addCopySpec("/sys/module/*/parameters") self.addCopySpec("/proc/filesystems") self.addCopySpec("/proc/ksyms") self.addCopySpec("/proc/slabinfo") - self.addCopySpec("/lib/modules/%s/modules.dep" % self.cInfo["policy"].kernelVersion()) + 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") @@ -72,18 +72,25 @@ class kernel(sos.plugintools.PluginBase): self.addCopySpec("/proc/cmdline") self.addCopySpec("/proc/driver") self.addCopySpec("/proc/sys/kernel/tainted") - - if self.getOption('sysrq') and os.access("/proc/sysrq-trigger", os.W_OK): - for key in ['m', 'p', 't']: - commands.getoutput("/bin/echo %s > /proc/sysrq-trigger" % (key,)) - self.addCopySpec("/var/log/messages") - + # FIXME: both RHEL4 and RHEL5 don't need sysrq to be enabled to trigger via sysrq-trigger + 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 diagnose(self): - + def analyze(self): infd = open("/proc/modules", "r") - for modname in infd.readlines(): + 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): @@ -92,17 +99,13 @@ class kernel(sos.plugintools.PluginBase): sys_srcver = infd.read().strip("\n") infd.close() if modinfo_srcver != sys_srcver: - self.addDiagnose("loaded module %s differs from the one present on the file-system" % modname) + 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. - infd.close() - - def analyze(self): - savedtaint = os.path.join(self.cInfo['dstroot'], "/proc/sys/kernel/tainted") infd = open(savedtaint, "r") line = infd.read() @@ -111,10 +114,12 @@ class kernel(sos.plugintools.PluginBase): 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: diff --git a/src/lib/sos/plugins/ldap.py b/src/lib/sos/plugins/ldap.py index b1a48420..318a3ba9 100644 --- a/src/lib/sos/plugins/ldap.py +++ b/src/lib/sos/plugins/ldap.py @@ -13,37 +13,14 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import sos.plugintools -import os class ldap(sos.plugintools.PluginBase): """LDAP related information """ - def checkenabled(self): - self.packages = [ "openldap" ] - self.files = [ "/etc/openldap/ldap.conf" ] - return sos.plugintools.PluginBase.checkenabled(self) - - def get_ldap_opts(self): - # capture /etc/openldap/ldap.conf options in dict - # FIXME: possibly not hardcode these options in? - ldapopts=["URI","BASE","TLS_CACERTDIR"] - results={} - tmplist=[] - for i in ldapopts: - t=self.doRegexFindAll(r"^(%s)\s+(.*)" % i,"/etc/openldap/ldap.conf") - for x in t: - results[x[0]]=x[1].rstrip("\n") - return results - - def diagnose(self): - # Validate ldap client options - ldapopts=self.get_ldap_opts() - if ldapopts.has_key("TLS_CACERTDIR") and not os.path.exists(ldapopts["TLS_CACERTDIR"]): - self.addDiagnose("%s does not exist and can cause connection issues involving TLS" % ldapopts["TLS_CACERTDIR"]) - 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***") diff --git a/src/lib/sos/plugins/named.py b/src/lib/sos/plugins/named.py index bb0d079e..421143cb 100644 --- a/src/lib/sos/plugins/named.py +++ b/src/lib/sos/plugins/named.py @@ -20,14 +20,21 @@ class named(sos.plugintools.PluginBase): """named related information """ def checkenabled(self): - self.files = [ "/etc/named.conf", "/etc/sysconfig/named" ] - self.packages = [ "bind", "bind-chroot" ] - return sos.plugintools.PluginBase.checkenabled(self) + if self.cInfo["policy"].pkgByName("bind") or os.path.exists("/etc/named.conf") or os.path.exists("/etc/sysconfig/named"): + return True + return False def setup(self): - self.addCopySpec("/etc/named.boot") - self.addCopySpec("/etc/named.conf") - self.addCopySpec("/etc/sysconfig/named") - self.addCopySpec("/var/named") - self.addForbiddenPath('/var/named/chroot/proc') - self.addForbiddenPath('/var/named/chroot/dev') + 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/src/lib/sos/plugins/networking.py b/src/lib/sos/plugins/networking.py index 164ed43a..080ae694 100644 --- a/src/lib/sos/plugins/networking.py +++ b/src/lib/sos/plugins/networking.py @@ -24,7 +24,14 @@ class networking(sos.plugintools.PluginBase): """Return a dictionary for which key are interface name according to the output of ifconifg-a stored in ifconfigFile. """ - out=self.doRegexFindAll(r"^(eth\d+)\D", 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): @@ -53,19 +60,20 @@ class networking(sos.plugintools.PluginBase): self.addCopySpec("/etc/resolv.conf") ifconfigFile=self.collectOutputNow("/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 -s") self.collectExtOutput("/bin/netstat -neopa", root_symlink = "netstat") - self.collectExtOutput("/sbin/ip route show table all") + # FIXME: we should collect "ip route table <tablename>" for all tables (from "ip rule") self.collectExtOutput("/sbin/ip link") self.collectExtOutput("/sbin/ip address") self.collectExtOutput("/sbin/ifenslave -a") if ifconfigFile: for eth in self.get_interface_name(ifconfigFile): self.collectExtOutput("/sbin/ethtool "+eth) - if self.getOption("traceroute"): + if self.isOptionEnabled("traceroute"): self.collectExtOutput("/bin/traceroute -n rhn.redhat.com") return diff --git a/src/lib/sos/plugins/nfsserver.py b/src/lib/sos/plugins/nfsserver.py index 1e352032..9564aa22 100644 --- a/src/lib/sos/plugins/nfsserver.py +++ b/src/lib/sos/plugins/nfsserver.py @@ -35,10 +35,7 @@ class nfsserver(sos.plugintools.PluginBase): def setup(self): self.addCopySpec("/etc/exports") - self.addCopySpec("/var/lib/nfs/etab") - self.addCopySpec("/var/lib/nfs/xtab") - self.addCopySpec("/var/lib/nfs/rmtab") self.collectExtOutput("/usr/sbin/rpcinfo -p localhost") - self.collectExtOutput("/usr/sbin/nfsstat -a") + self.collectExtOutput("/usr/sbin/nfsstat") return diff --git a/src/lib/sos/plugins/pam.py b/src/lib/sos/plugins/pam.py index 1a50811b..8164bba3 100644 --- a/src/lib/sos/plugins/pam.py +++ b/src/lib/sos/plugins/pam.py @@ -20,6 +20,6 @@ class pam(sos.plugintools.PluginBase): def setup(self): self.addCopySpec("/etc/pam.d") self.addCopySpec("/etc/security") - self.collectExtOutput("/bin/ls -laF /lib/security") + self.collectExtOutput("/bin/ls -laF /lib/security/pam_*so") return diff --git a/src/lib/sos/plugins/process.py b/src/lib/sos/plugins/process.py index 0d89e06b..47e37edf 100644 --- a/src/lib/sos/plugins/process.py +++ b/src/lib/sos/plugins/process.py @@ -25,7 +25,6 @@ class process(sos.plugintools.PluginBase): self.collectExtOutput("/bin/ps auxwwwm") self.collectExtOutput("/bin/ps alxwww") self.collectExtOutput("/usr/bin/pstree", root_symlink = "pstree") - self.collectExtOutput("/usr/sbin/lsof -b +M -n -l", root_symlink = "lsof") return def find_mountpoint(s): @@ -41,7 +40,7 @@ class process(sos.plugintools.PluginBase): line = line.split() if line[0] == "D": # keep an eye on the process to see if the stat changes - for inc in range(1,10): + for inc in range(1,5): try: if len(self.fileGrep("^State: D", " /proc/%d/status" % int(line[1]))) == 0: # status is not D, good. let's get out of the loop. diff --git a/src/lib/sos/plugins/rpm.py b/src/lib/sos/plugins/rpm.py index f1c09e33..d9f1e79b 100644 --- a/src/lib/sos/plugins/rpm.py +++ b/src/lib/sos/plugins/rpm.py @@ -22,12 +22,12 @@ class rpm(sos.plugintools.PluginBase): def setup(self): self.addCopySpec("/var/log/rpmpkgs") - - if self.getOption("rpmq"): - self.collectExtOutput("/bin/rpm -qa --qf \"%{NAME}-%{VERSION}-%{RELEASE}-%{ARCH}\n\"", root_symlink = "installed-rpms") - - if self.getOption("rpmva"): - self.eta_weight += 1500 # this plugins takes 200x longer (for ETA) - self.collectExtOutput("/bin/rpm -Va", root_symlink = "rpm-Va", timeout = 3600) + + if self.isOptionEnabled("rpmq"): + self.collectExtOutput("/bin/rpm -qa --qf=\"%{NAME}-%{VERSION}-%{RELEASE}-%{ARCH}~~%{INSTALLTIME:date}\n\"|/bin/awk -F ~~ '{printf \"%-60s%s\\n\",$1,$2}'", 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/src/lib/sos/plugins/selinux.py b/src/lib/sos/plugins/selinux.py index 5f0c1f40..897c3991 100644 --- a/src/lib/sos/plugins/selinux.py +++ b/src/lib/sos/plugins/selinux.py @@ -19,32 +19,18 @@ class selinux(sos.plugintools.PluginBase): """selinux related information """ def setup(self): - # sestatus is always collected in checkenabled() - self.addCopySpec("/etc/selinux") + self.addCopySpec("/etc/selinux/*") self.collectExtOutput("/usr/bin/selinuxconfig") - self.eta_weight += 120 # this plugins takes 120x longer (for ETA) - self.collectExtOutput("/sbin/fixfiles check") - - self.addForbiddenPath("/etc/selinux/targeted") - + 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 self.collectOutputNow("/usr/sbin/sestatus", root_symlink = "sestatus").split(":")[1].strip() == "disabled": + if commands.getoutput("/usr/sbin/sestatus").split(":")[1].strip() == "disabled": return False except: pass return True - - def analyze(self): - # Check for SELinux denials and capture raw output from sealert - if self.cInfo["policy"].runlevelDefault() in self.cInfo["policy"].runlevelByService("setroubleshoot"): - # TODO: fixup regex for more precise matching - sealert=doRegexFindAll(r"^.*setroubleshoot:.*(sealert\s-l\s.*)","/var/log/messages") - if sealert: - for i in sealert: - self.collectExtOutput("%s" % i) - self.addAlert("There are numerous selinux errors present and "+ - "possible fixes stated in the sealert output.") diff --git a/src/lib/sos/plugins/squid.py b/src/lib/sos/plugins/squid.py index 7de66100..fdd3b8cf 100644 --- a/src/lib/sos/plugins/squid.py +++ b/src/lib/sos/plugins/squid.py @@ -19,12 +19,11 @@ class squid(sos.plugintools.PluginBase): """squid related information """ def checkenabled(self): - self.files = [ "/etc/squid/squid.conf" ] - self.packages = [ "squid" ] - return sos.plugintools.PluginBase.checkenabled(self) + if self.cInfo["policy"].pkgByName("squid") != None or os.path.exists("/etc/squid/squid.conf"): + return True + return False def setup(self): self.addCopySpec("/etc/squid/squid.conf") - self.addCopySpec("/var/log/squid") return diff --git a/src/lib/sos/plugins/startup.py b/src/lib/sos/plugins/startup.py index a0d3e400..59014aaa 100644 --- a/src/lib/sos/plugins/startup.py +++ b/src/lib/sos/plugins/startup.py @@ -19,6 +19,7 @@ class startup(sos.plugintools.PluginBase): """ def setup(self): self.addCopySpec("/etc/rc.d") + self.collectExtOutput("/sbin/chkconfig --list", root_symlink = "chkconfig") self.collectExtOutput("/sbin/runlevel") return diff --git a/src/lib/sos/plugins/systemtap.py b/src/lib/sos/plugins/systemtap.py index 0f5dda19..b99ce0cf 100644 --- a/src/lib/sos/plugins/systemtap.py +++ b/src/lib/sos/plugins/systemtap.py @@ -17,15 +17,13 @@ import sos.plugintools class systemtap(sos.plugintools.PluginBase): - """SystemTap information + """SystemTap pre-requisites information """ - def checkenabled(self): - self.files = [ "/usr/bin/stap" ] - self.packages = [ "systemtap", "systemtap-runtime" ] - return sos.plugintools.PluginBase.checkenabled(self) - 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/src/lib/sos/plugins/x11.py b/src/lib/sos/plugins/x11.py index 755352ef..4abd8782 100644 --- a/src/lib/sos/plugins/x11.py +++ b/src/lib/sos/plugins/x11.py @@ -19,19 +19,16 @@ class x11(sos.plugintools.PluginBase): """X related information """ def checkenabled(self): - try:os.stat("/etc/X11") - except:pass - else:return True - return False + try: os.stat("/etc/X11") + except: pass + else: return True + + return False 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.'") - - self.addForbiddenPath("/etc/X11/X") - self.addForbiddenPath("/etc/X11/fontpath.d") - return diff --git a/src/lib/sos/plugins/xen.py b/src/lib/sos/plugins/xen.py index 89ed359f..28c0ed43 100644 --- a/src/lib/sos/plugins/xen.py +++ b/src/lib/sos/plugins/xen.py @@ -38,6 +38,11 @@ class xen(sos.plugintools.PluginBase): return False return True + def is_running_xenstored(self): + xs_pid = os.popen("pidof xenstored").read() + xs_pidnum = re.split('\n$',xs_pid)[0] + return xs_pidnum.isdigit() + def domCollectProc(self): self.addCopySpec("/proc/xen/balloon") self.addCopySpec("/proc/xen/capabilities") @@ -68,10 +73,17 @@ class xen(sos.plugintools.PluginBase): self.collectExtOutput("/usr/sbin/xm info") self.collectExtOutput("/usr/sbin/brctl show") self.domCollectProc() - # work-around for BZ#371251 which eventually needs to be fixed in xen - status, output = commands.getstatusoutput("/sbin/service xend status &> /dev/null") - if status == 0: - self.addCopySpec("/sys/hypervisor") + self.addCopySpec("/sys/hypervisor/version") + self.addCopySpec("/sys/hypervisor/compilation") + self.addCopySpec("/sys/hypervisor/properties") + self.addCopySpec("/sys/hypervisor/type") + if is_xenstored_running(): + self.addCopySpec("/sys/hypervisor/uuid") + self.collectExtOutput("/usr/bin/xenstore-ls") + else: + # we need tdb instead of xenstore-ls if cannot get it. + self.addCopySpec("/var/lib/xenstored/tdb") + # 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 diff --git a/src/lib/sos/plugins/yum.py b/src/lib/sos/plugins/yum.py index 672451ee..1f389d30 100644 --- a/src/lib/sos/plugins/yum.py +++ b/src/lib/sos/plugins/yum.py @@ -22,17 +22,22 @@ class yum(sos.plugintools.PluginBase): optionList = [("yumlist", "list repositories and packages", "slow", False)] def checkenabled(self): - self.files = [ "/etc/yum.conf" ] - self.packages = [ "yum" ] - return sos.plugintools.PluginBase.checkenabled(self) + if self.cInfo["policy"].pkgByName("yum") or os.path.exists("/etc/yum.conf"): + return True + return False - def analyze(self): + def diagnose(self): + # FIXME: diagnose should only report actual problems, disabling this for now. + return True # repo sanity checking # TODO: elaborate/validate actual repo files, however this directory should # be empty on RHEL 5+ systems. - if self.cInfo["policy"].rhelVersion() == 5: - if len(os.listdir("/etc/yum.repos.d/")): - self.addAlert("/etc/yum.repos.d/ contains additional repository "+ + try: rhelver = self.cInfo["policy"].pkgDictByName("redhat-release")[0] + except: rhelver = None + + if rhelver == "5" or True: + if len(os.listdir('/etc/yum.repos.d/')): + self.addDiagnose("/etc/yum.repos.d/ contains additional repository "+ "information and can cause rpm conflicts.") def setup(self): @@ -42,7 +47,7 @@ class yum(sos.plugintools.PluginBase): self.addCopySpec("/etc/yum.conf") self.addCopySpec("/var/log/yum.log") - if self.getOption("yumlist"): + if self.isOptionEnabled("yumlist"): # 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 diff --git a/src/lib/sos/plugintools.py b/src/lib/sos/plugintools.py index f9e10ae1..fc4d4b97 100644 --- a/src/lib/sos/plugintools.py +++ b/src/lib/sos/plugintools.py @@ -30,31 +30,11 @@ This is the base class for sosreport plugins """ from sos.helpers import * from threading import Thread, activeCount -import os, os.path, sys, string, glob, re, traceback -import shutil +import os, os.path, sys, string, itertools, glob, re, traceback +import logging from stat import * from time import time -# RHEL3 doesn't have a logging module, activate work-around -try: - import logging -except ImportError: - import sos.rhel3_logging - logging = sos.rhel3_logging - -# python < 2.4 (RHEL3 and RHEL4) doesn't have format_exc, activate work-around -if sys.version_info[0] <= 2 and sys.version_info[1] < 4: - def format_exc(): - import StringIO - - output = StringIO.StringIO() - traceback.print_exc(file = output) - toret = output.getvalue() - output.close() - return toret - - traceback.format_exc = format_exc - class PluginBase: """ Base class for plugins @@ -85,11 +65,6 @@ class PluginBase: self.time_start = None self.time_stop = None - self.packages = [] - self.files = [] - - self.must_exit = False - self.soslog = logging.getLogger('sos') # get the option list into a dictionary @@ -119,10 +94,10 @@ class PluginBase: except KeyboardInterrupt: raise KeyboardInterrupt except Exception, e: - self.soslog.log(logging.VERBOSE, "problem at path %s (%s)" % (abspath,e)) + self.soslog.log(logging.VERBOSE, "Problem at path %s (%s)" % (abspath,e)) break return False - + def doRegexFindAll(self,regex,fname): ''' Return a list of all non overlapping matches in the string(s) ''' @@ -134,7 +109,7 @@ class PluginBase: for i in reg.findall(content): out.append(i) return out - + # Methods for copying files and shelling out def doCopyFileOrDir(self, srcpath): # pylint: disable-msg = R0912 @@ -151,103 +126,113 @@ class PluginBase: if copyProhibited: return '' - if not os.path.exists(srcpath): - self.soslog.debug("file or directory %s does not exist" % srcpath) - return - if os.path.islink(srcpath): # This is a symlink - We need to also copy the file that it points to - - # FIXME: ignore directories for now - if os.path.isdir(srcpath): - return - + # file and dir symlinks ar ehandled the same link = os.readlink(srcpath) - # What's the name of the symlink on the dest tree? - dstslname = os.path.join(self.cInfo['dstroot'], srcpath.lstrip(os.path.sep)) - if os.path.isabs(link): # the link was an absolute path, and will not point to the new # tree. We must adjust it. - rpth = sosRelPath(os.path.dirname(dstslname), os.path.join(self.cInfo['dstroot'], link.lstrip(os.path.sep))) + + # 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 - rpth = link + dstslname = link - # make sure the link doesn't already exists - if os.path.exists(dstslname): - self.soslog.log(logging.DEBUG, "skipping symlink creation: already exists (%s)" % dstslname) + if os.path.isdir(srcpath): # symlink to a directory + # FIXME: don't recurse symlinks until vicious loops are detected return - # make sure the dst dir exists - if not (os.path.exists(os.path.dirname(dstslname)) and os.path.isdir(os.path.dirname(dstslname))): - os.makedirs(os.path.dirname(dstslname)) + abslink = os.path.abspath(os.path.dirname(srcpath) + "/" + link) + self.soslog.log(logging.VERBOSE2, "DIRLINK %s to %s [%s]" % (srcpath,link,abslink)) + for tmplink in self.copiedDirs: + if tmplink["srcpath"] == abslink or tmplink["pointsto"] == abslink: + self.soslog.log(logging.VERBOSE2, "already copied [%s]" % srcpath) + return - self.soslog.log(logging.VERBOSE3, "creating symlink %s -> %s" % (dstslname, rpth)) - os.symlink(rpth, dstslname) - self.copiedFiles.append({'srcpath':srcpath, 'dstpath':rpth, 'symlink':"yes", 'pointsto':link}) - self.doCopyFileOrDir(link) - return + for afile in os.listdir(srcpath): + if afile == '.' or afile == '..': + pass + else: + self.soslog.log(logging.VERBOSE2, "copying (file or dir) %s" % srcpath+'/'+afile) + try: + abspath = self.doCopyFileOrDir(srcpath+'/'+afile) + except SystemExit: + raise SystemExit + except KeyboardInterrupt: + raise KeyboardInterrupt + except Exception, e: + self.soslog.verbose(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':os.path.abspath(srcpath+'/'+afile) }) + else: + self.soslog.log(logging.VERBOSE2, "copying symlink %s" % srcpath) + try: + dstslname, abspath = self.__copyFile(srcpath) + self.copiedFiles.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link}) + 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: # not a symlink - if os.path.isdir(srcpath): + 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) - return - - # if we get here, it's definitely a regular file (not a symlink or dir) - - self.soslog.log(logging.VERBOSE3, "copying file %s" % srcpath) - try: - tdstpath, abspath = self.__copyFile(srcpath) - except "AlreadyExists": - self.soslog.log(logging.DEBUG, "error copying file %s (already exists)" % (srcpath)) - return - except IOError: - self.soslog.log(logging.VERBOSE2, "error copying file %s (IOError)" % (srcpath)) - return - except: - self.soslog.log(logging.VERBOSE2, "error copying file %s (SOMETHING HAPPENED)" % (srcpath)) - - self.copiedFiles.append({'srcpath':srcpath, 'dstpath':tdstpath, 'symlink':"no"}) # save in our list - - 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 __copyFile(self, src): """ call cp to copy a file, collect return status and output. Returns the destination file name. """ - rel_dir = os.path.dirname(src).lstrip(os.path.sep) -# if rel_dir[0] == "/": rel_dir = rel_dir[1:] - new_dir = os.path.join(self.cInfo['dstroot'], rel_dir) - new_fname = os.path.join(new_dir, os.path.basename(src)) - - if not os.path.exists(new_fname): - if not os.path.isdir(new_dir): - os.makedirs(new_dir) - - if os.path.islink(src): - linkto = os.readlink(src) - os.symlink(linkto, new_fname) - else: - shutil.copy2(src, new_dir) - else: - raise "AlreadyExists" - - abspath = os.path.join(self.cInfo['dstroot'], src.lstrip(os.path.sep)) - relpath = sosRelPath(self.cInfo['rptdir'], abspath) - return (relpath, abspath) + 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. """ - # Glob case handling is such that a valid non-glob is a reduced glob - for filespec in glob.glob(forbiddenPath): - self.forbiddenPaths.append(filespec) + self.forbiddenPaths.append(forbiddenPath) def getAllOptions(self): """ @@ -255,22 +240,14 @@ class PluginBase: """ return (self.optNames, self.optParms) - def setOption(self, optionname, value): - ''' set the named option to value. + 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'] = value - return True - else: - return False + parms['enabled'] = enable def isOptionEnabled(self, optionname): - ''' Deprecated, use getOption() instead - ''' - return self.getOption(optionname) - - def getOption(self, optionname): ''' see whether the named option is enabled. ''' for name, parms in zip(self.optNames, self.optParms): @@ -282,9 +259,6 @@ class PluginBase: def addCopySpecLimit(self,fname,sizelimit = None): """Add a file specification (with limits) """ - if not ( fname and len(fname) ): - self.soslog.warning("invalid file path") - return False files = glob.glob(fname) files.sort() cursize = 0 @@ -298,26 +272,57 @@ class PluginBase: """ Add a file specification (can be file, dir,or shell glob) to be copied into the sosreport by this module """ - if not ( copyspec and len(copyspec) ): - self.soslog.warning("invalid file path") - return False # 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) + 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, timeout = 300): + 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, timeout) ) + self.collectProgs.append( (exe,suggest_filename,root_symlink) ) def fileGrep(self, regexp, fname): results = [] @@ -353,13 +358,18 @@ class PluginBase: return outfn - def collectOutputNow(self, exe, suggest_filename = None, root_symlink = False, timeout = 300): + 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]) + + # FIXME: we should have a timeout or we may end waiting forever # pylint: disable-msg = W0612 - status, shout, runtime = sosGetCommandOutput(exe, timeout = timeout) + status, shout, runtime = sosGetCommandOutput(exe) if suggest_filename: outfn = self.makeCommandFilename(suggest_filename) @@ -369,7 +379,7 @@ class PluginBase: if not os.path.isdir(os.path.dirname(outfn)): os.mkdir(os.path.dirname(outfn)) - if not (status == 127 or status == 32512): # if not command_not_found + if not (status == 127 or status == 32512): outfd = open(outfn, "w") if len(shout): outfd.write(shout+"\n") outfd.close() @@ -377,8 +387,7 @@ class PluginBase: if root_symlink: curdir = os.getcwd() os.chdir(self.cInfo['dstroot']) - try: os.symlink(outfn[len(self.cInfo['dstroot'])+1:], root_symlink.strip("/.")) - except: pass + os.symlink(outfn[len(self.cInfo['dstroot'])+1:], root_symlink.strip("/.")) os.chdir(curdir) outfn_strip = outfn[len(self.cInfo['cmddir'])+1:] @@ -467,10 +476,6 @@ class PluginBase: if semaphore: semaphore.acquire() - if self.must_exit: - semaphore.release() - return - self.soslog.log(logging.VERBOSE, "starting threaded plugin %s" % self.piName) self.time_start = time() @@ -481,29 +486,33 @@ class PluginBase: try: self.doCopyFileOrDir(path) except SystemExit: - if semaphore: semaphore.release() - if threaded: return KeyboardInterrupt - else: raise KeyboardInterrupt + if threaded: + return SystemExit + else: + raise SystemExit except KeyboardInterrupt: - if semaphore: semaphore.release() - if threaded: return KeyboardInterrupt - else: raise KeyboardInterrupt + if threaded: + return KeyboardInterrupt + else: + raise KeyboardInterrupt except Exception, e: self.soslog.log(logging.VERBOSE2, "error copying from pathspec %s (%s), traceback follows:" % (path,e)) self.soslog.log(logging.VERBOSE2, traceback.format_exc()) - for (prog, suggest_filename, root_symlink, timeout) in self.collectProgs: + 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, timeout) + self.collectOutputNow(prog, suggest_filename, root_symlink) except SystemExit: - if semaphore: semaphore.release() - if threaded: return SystemExit - else: raise SystemExit + if threaded: + return SystemExit + else: + raise SystemExit except KeyboardInterrupt: - if semaphore: semaphore.release() - if threaded: return KeyboardInterrupt - else: raise KeyboardInterrupt - except Exception, e: + if threaded: + return KeyboardInterrupt + else: + raise KeyboardInterrupt + except: self.soslog.log(logging.VERBOSE2, "error collection output of '%s', traceback follows:" % prog) self.soslog.log(logging.VERBOSE2, traceback.format_exc()) @@ -512,10 +521,6 @@ class PluginBase: if semaphore: semaphore.release() self.soslog.log(logging.VERBOSE, "plugin %s returning" % self.piName) - def exit_please(self): - """ This function tells the plugin that it should exit ASAP""" - self.must_exit = True - def get_description(self): """ This function will return the description for the plugin""" try: @@ -527,17 +532,7 @@ class PluginBase: """ This function can be overidden to let the plugin decide whether it should run or not. """ - # some files or packages have been specified for this package - if len(self.files) or len(self.packages): - for fname in self.files: - if os.path.exists(fname): - return True - for pkgname in self.packages: - if self.cInfo["policy"].pkgByName(pkgname): - return True - return False - - return True + return True def defaultenabled(self): """This devices whether a plugin should be automatically loaded or @@ -609,11 +604,11 @@ class PluginBase: html = html + "<p>Commands Executed:<br><ul>\n" # convert file name to relative path from our root for cmd in self.executedCommands: - if cmd["file"] and len(cmd["file"]): - cmdOutRelPath = sosRelPath(self.cInfo['rptdir'], self.cInfo['cmddir'] + "/" + cmd['file']) - html = html + '<li><a href="%s">%s</a></li>\n' % (cmdOutRelPath, cmd['exe']) - else: - html = html + '<li>%s</li>\n' % (cmd['exe']) + if cmd["file"] and len(cmd["file"]): + cmdOutRelPath = sosRelPath(self.cInfo['rptdir'], self.cInfo['cmddir'] + "/" + cmd['file']) + html = html + '<li><a href="%s">%s</a></li>\n' % (cmdOutRelPath, cmd['exe']) + else: + html = html + '<li>%s</li>\n' % (cmd['exe']) html = html + "</ul></p>\n" # Alerts @@ -629,3 +624,5 @@ class PluginBase: html = html + self.customText + "</p>\n" return html + + diff --git a/src/lib/sos/policyredhat.py b/src/lib/sos/policyredhat.py index a10e7dfb..c25a9d55 100755 --- a/src/lib/sos/policyredhat.py +++ b/src/lib/sos/policyredhat.py @@ -26,45 +26,22 @@ from sos.helpers import * import random import re import md5 -import rpm -import time - -sys.path.insert(0, "/usr/share/rhn/") -try: - from up2date_client import up2dateAuth - from up2date_client import config - from rhn import rpclib -except: - # might fail if non-RHEL - pass + +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) -def memoized(function): - ''' function decorator to allow caching of return values - ''' - function.cache={} - def f(*args): - try: - return function.cache[args] - except KeyError: - result = function.cache[args] = function(*args) - return result - return f class SosPolicy: "This class implements various policies for sos" def __init__(self): - self.report_file = "" - self.report_md5 = "" - self.reportName = "" - self.ticketNumber = "" + #print "Policy init" return def setCommons(self, commons): @@ -78,45 +55,35 @@ class SosPolicy: #print "validating %s" % pluginpath return True - def pkgProvides(self, name): - pkg = self.pkgByName(name) - return pkg['providename'] - def pkgRequires(self, name): - pkg = self.pkgByName(name) - return pkg['requirename'] + # FIXME: we're relying on rpm to sort the output list + cmd = "/bin/rpm -q --requires %s" % (name) + return [requires[:-1].split() for requires in os.popen(cmd).readlines()] def allPkgsByName(self, name): - return self.allPkgs("name", name) - - def allPkgsByNameRegex(self, regex_name): - reg = re.compile(regex_name) - return [pkg for pkg in self.allPkgs() if reg.match(pkg['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].split() 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 - return self.allPkgsByName(name)[-1] - except: - pass - return None - - def allPkgs(self, ds = None, value = None): - # if possible return the cached values - try: return self._cache_rpm[ "%s-%s" % (ds,value) ] - except AttributeError: self._cache_rpm = {} - except KeyError: pass - - ts = rpm.TransactionSet() - if ds and value: - mi = ts.dbMatch(ds, value) + pkg = self.allPkgsByName(name)[-1] + except IndexError: + pkg = None + + return pkg + + def pkgDictByName(self, name): + # FIXME: what does this do again ?? + pkgName = self.pkgByName(name) + print pkgName + if pkgName and len(pkgName) > len(name): + return pkgName[len(name)+1:].split("-") else: - mi = ts.dbMatch() - - self._cache_rpm[ "%s-%s" % (ds,value) ] = [pkg for pkg in mi] - del mi, ts - return self._cache_rpm[ "%s-%s" % (ds,value) ] + return None def runlevelByService(self, name): ret = [] @@ -124,7 +91,7 @@ class SosPolicy: for tabs in commands.getoutput("/sbin/chkconfig --list %s" % name).split(): try: (runlevel, onoff) = tabs.split(":", 1) - except: + except ValueError: pass else: if onoff == "on": @@ -135,7 +102,7 @@ class SosPolicy: def runlevelDefault(self): try: - reg=self.doRegexFindAll(r"^id:(\d{1}):initdefault:", "/etc/inittab") + reg=self.fileGrep(r"^id:(\d{1}):initdefault:", "/etc/inittab") for initlevel in reg: return initlevel except: @@ -144,36 +111,9 @@ class SosPolicy: def kernelVersion(self): return commands.getoutput("/bin/uname -r").strip("\n") - def hostName(self): - return commands.getoutput("/bin/hostname").split(".")[0] - - def rhelVersion(self): - try: - pkgname = self.pkgByName("redhat-release")["version"] - if pkgname[0] == "4": - return 4 - elif pkgname in [ "5Server", "5Client" ]: - return 5 - except: pass - return False - - def rhnUsername(self): - try: - cfg = config.initUp2dateConfig() - - return rpclib.xmlrpclib.loads(up2dateAuth.getSystemId())[0][0]['username'] - except: - # ignore any exception and return an empty username - return "" - def isKernelSMP(self): - if commands.getoutput("/bin/uname -v").split()[1] == "SMP": - return True - else: - return False - - def getArch(self): - return commands.getoutput("/bin/uname -m").strip() + if self.kernelVersion()[-3:]=="smp": return True + else: return False def pkgNVRA(self, pkg): fields = pkg.split("-") @@ -181,188 +121,85 @@ class SosPolicy: name = "-".join(fields[:-3]) return (name, version, release, arch) - def getDstroot(self): - """Find a temp directory to form the root for our gathered information - and reports. - """ - dstroot = "/tmp/%s-%s" % (self.hostName(), time.strftime("%Y%m%d%H%M%S")) - try: - os.mkdir(dstroot, 0700) - except: - return False - return dstroot - - def preWork(self): + def preWork(self, name="", ticket=""): # this method will be called before the gathering begins - localname = self.rhnUsername() - if len(localname) == 0: localname = self.hostName() + localname = commands.getoutput("/bin/uname -n").split(".")[0] - if not self.cInfo['cmdlineopts'].batch: - try: + try: + if len(name) == 0: self.reportName = raw_input(_("Please enter your first initial and last name [%s]: ") % localname) - self.reportName = re.sub(r"[^a-zA-Z.0-9]", "", self.reportName) + else: + self.reportName = str(name) + self.reportName = re.sub(r"[^a-zA-Z.0-9]", "", self.reportName) - self.ticketNumber = raw_input(_("Please enter the case number that you are generating this report for: ")) - self.ticketNumber = re.sub(r"[^0-9]", "", self.ticketNumber) - print - except: - print - sys.exit(0) + if len(self.reportName) == 0: + self.reportName = localname - if len(self.reportName) == 0: - self.reportName = localname - - return + if len(ticket) == 0: + self.ticketNumber = raw_input(_("Please enter the case number that you are generating this report for: ")) + else: + self.ticketNumber = str(ticket) + self.ticketNumber = re.sub(r"[^0-9]", "", self.ticketNumber) - def renameResults(self, newName): - newName = os.path.join(gettempdir(), newName) - if len(self.report_file) and os.path.isfile(self.report_file): - try: os.rename(self.report_file, newName) - except: return False - self.report_file = newName + print + except KeyboardInterrupt: + print + sys.exit(0) def packageResults(self): - self.renameResults("sosreport-%s-%s.tar.bz2" % (self.reportName, time.strftime("%Y%m%d%H%M%S"))) + if len(self.ticketNumber): + namestr = self.reportName + "." + self.ticketNumber + else: + namestr = self.reportName + + ourtempdir = gettempdir() + tarballName = os.path.join(ourtempdir, "sosreport-" + namestr + ".tar.bz2") - tarcmd = "/bin/tar -jcf %s %s" % (self.report_file, os.path.basename(self.cInfo['dstroot'])) + namestr = namestr + "-" + str(random.randint(1, 999999)) + + aliasdir = os.path.join(ourtempdir, namestr) + + tarcmd = "/bin/tar -jcf %s %s" % (tarballName, namestr) print _("Creating compressed 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(os.path.dirname(self.cInfo['dstroot'])) + os.chdir(ourtempdir) oldmask = os.umask(077) - status, shout = commands.getstatusoutput(tarcmd) + # 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'])) - return - - def cleanDstroot(self): - if not os.path.isdir(os.path.join(self.cInfo['dstroot'],"sos_commands")): - # doesn't look like a dstroot, refusing to clean - return False - os.system("/bin/rm -rf %s" % self.cInfo['dstroot']) - - def encryptResults(self): - # make sure a report exists - if not self.report_file: - return False - - print _("Encrypting archive...") - gpgname = self.report_file + ".gpg" - - try: - keyring = self.cInfo['config'].get("general", "gpg_keyring") - except: - keyring = "/usr/share/sos/rhsupport.pub" - - try: - recipient = self.cInfo['config'].get("general", "gpg_recipient") - except: - recipient = "support@redhat.com" - - status, output = commands.getstatusoutput("""/usr/bin/gpg --trust-model always --batch --keyring "%s" --no-default-keyring --compress-level 0 --encrypt --recipient "%s" --output "%s" "%s" """ % (keyring, recipient, gpgname, self.report_file)) - if status == 0: - os.unlink(self.report_file) - self.report_file = gpgname - else: - print _("There was a problem encrypting your report.") - sys.exit(1) - - def displayResults(self): - # make sure a report exists - if not self.report_file: - return False - - # calculate md5 - fp = open(self.report_file, "r") - self.report_md5 = md5.new(fp.read()).hexdigest() + # add last 6 chars from md5sum to file name + fp = open(tarballName, "r") + md5out = md5.new(fp.read()).hexdigest() fp.close() - - self.renameResults("sosreport-%s-%s-%s.tar.bz2" % (self.reportName, time.strftime("%Y%m%d%H%M%S"), self.report_md5[-4:])) - - # store md5 into file - fp = open(self.report_file + ".md5", "w") - fp.write(self.report_md5 + "\n") + oldtarballName = tarballName + tarballName = os.path.join(ourtempdir, "sosreport-%s-%s.tar.bz2" % (namestr, md5out[-6:]) ) + os.system("/bin/mv %s %s" % (oldtarballName, tarballName) ) + # store md5 to a file + fp = open(tarballName + ".md5", "w") + fp.write(md5out + "\n") fp.close() + sys.stdout.write("\n") + print _("Your sosreport has been generated and saved in:\n %s") % tarballName print - print _("Your sosreport has been generated and saved in:\n %s") % self.report_file - print - if len(self.report_md5): - print _("The md5sum is: ") + self.report_md5 + if md5out: + print _("The md5sum is: ") + md5out print print _("Please send this file to your support representative.") - print - - def uploadResults(self): - # make sure a report exists - if not self.report_file: - return False - - print + sys.stdout.write("\n") - # make sure it's readable - try: - fp = open(self.report_file, "r") - except: - return False - - # read ftp URL from configuration - try: - upload_url = self.cInfo['config'].get("general", "upload_url") - except: - upload_url = "ftp://dropbox.redhat.com/incoming" - - from urlparse import urlparse - url = urlparse(upload_url) - - if url[0] != "ftp": - print _("Cannot upload to specified URL.") - return - - # extract username and password from URL, if present - if url[1].find("@") > 0: - username, host = url[1].split("@", 1) - if username.find(":") > 0: - username, passwd = username.split(":", 1) - else: - passwd = None - else: - username, passwd, host = None, None, url[1] - - # extract port, if present - if host.find(":") > 0: - host, port = host.split(":", 1) - port = int(port) - else: - port = 21 - - path = url[2] - - try: - from ftplib import FTP - upload_name = os.path.basename(self.report_file) - - ftp = FTP() - ftp.connect(host, port) - if username and passwd: - ftp.login(username, passwd) - else: - ftp.login() - ftp.cwd(path) - ftp.set_pasv(True) - ftp.storbinary('STOR %s' % upload_name, fp) - ftp.quit() - except: - print _("There was a problem uploading your report to Red Hat support.") - else: - print _("Your report was successfully uploaded to Red Hat's ftp server with name:") - print " " + upload_name - print - print _("Please communicate this name to your support representative.") - print + return - fp.close() diff --git a/src/locale/fr/LC_MESSAGES/sos.po b/src/locale/fr/LC_MESSAGES/sos.po index 752355ab..cbc0634e 100644 --- a/src/locale/fr/LC_MESSAGES/sos.po +++ b/src/locale/fr/LC_MESSAGES/sos.po @@ -1,192 +1,160 @@ -# translation of fr.po to French -# French translations for PACKAGE package. -# Copyright (C) 2007 ORGANIZATION +# sosreport Fench translation file +# Copyright (C) Red Hat UK, Ltd. +# Imed Chihi <ichihi@redhat.com>, 2007. # -# Automatically generated, 2007. -# Decroux Fabien <fdecroux@redhat.com>, 2007. msgid "" msgstr "" -"Project-Id-Version: fr\n" -"POT-Creation-Date: 2007-10-24 08:45\n" -"PO-Revision-Date: 2007-11-08 10:11+1000\n" -"Last-Translator: Decroux Fabien <fdecroux@redhat.com>\n" -"Language-Team: French <fr@li.org>\n" +"Project-Id-Version: sos 1.7\n" +"POT-Creation-Date: 2007-08-02 10:20\n" +"PO-Revision-Date: 2007-08-02 13:00+01\n" +"Last-Translator: Imed Chihi <ichihi@redhat.com>\n" +"Language-Team: FR <navid@redhat.com>\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: utf-8\n" "Generated-By: pygettext.py 1.5\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: KBabel 1.11.4\n" -#: lib/sos/policyredhat.py:203 +#: lib/sos/policyredhat.py:127 msgid "Please enter your first initial and last name [%s]: " -msgstr "Veuillez saisir votre premier prénom (si vous en avez plusieurs) et votre nom [%s] :" +msgstr "Prière d'entrer votre première initiale et votre nom [%s]: " -#: lib/sos/policyredhat.py:206 +#: lib/sos/policyredhat.py:132 msgid "Please enter the case number that you are generating this report for: " -msgstr "Veuillez saisir le numéro de cas pour lequel vous générez ce rapport :" +msgstr "Prière de donner le numéro de ticket pour lequel vous avez généré ce rapport: " -#: lib/sos/policyredhat.py:231 +#: lib/sos/policyredhat.py:155 msgid "Creating compressed archive..." -msgstr "Création d'une archive compressée..." +msgstr "Création de l'archive compressée en cours..." -#: lib/sos/policyredhat.py:253 -msgid "Encrypting archive..." -msgstr "Cryptage de l'archive..." - -#: lib/sos/policyredhat.py:271 -msgid "There was a problem encrypting your report." -msgstr "Une erreur s'est produire lors du cryptage de votre rapport." - -#: lib/sos/policyredhat.py:292 +#: lib/sos/policyredhat.py:185 msgid "" "Your sosreport has been generated and saved in:\n" " %s" -msgstr "" -"Votre rapport sos a été généré et enregistré dans :\n" +"Votre sosreport a été généré et copié dans:\n" " %s" -#: lib/sos/policyredhat.py:295 +#: lib/sos/policyredhat.py:188 msgid "The md5sum is: " -msgstr "Le md5sum est :" +msgstr "La somme md5sum est: " -#: lib/sos/policyredhat.py:297 +#: lib/sos/policyredhat.py:190 msgid "Please send this file to your support representative." -msgstr "Veuillez envoyer ce fichier à votre représentant de support." - -#: lib/sos/policyredhat.py:323 -msgid "Cannot upload to specified URL." -msgstr "Impossible de le télécharger vers l'URL spécifié." - -#: lib/sos/policyredhat.py:360 -msgid "There was a problem uploading your report to Red Hat support." -msgstr "Une erreur s'est produite lors du téléchargement de votre rapport vers le support Red Hat." - -#: lib/sos/policyredhat.py:362 -msgid "Your report was successfully uploaded to Red Hat's ftp server with name:" -msgstr "Votre rapport a été téléchargé avec succès vers le serveur ftp de Red Hat avec le nom :" - -#: lib/sos/policyredhat.py:365 -msgid "Please communicate this name to your support representative." -msgstr "Veuillez communiquer ce nom à votre représentant de support." - -#: sosreport:395 -msgid "Could not create temporary directory." -msgstr "Impossible de créer un répertoire temporaire." +msgstr "Prière d'envoyer ce rapport à votre représentant de Support." -#: sosreport:451 +#: sosreport:370 msgid "sosreport (version %s)" -msgstr "sosreport (version %s)" +msgstr "" -#: sosreport:468 +#: sosreport:388 msgid "plugin %s does not validate, skipping" -msgstr "le plugin %s n'a pas été validé, ignoré" +msgstr "plugin %s ne s'applique pas, desactivé" -#: sosreport:474 +#: sosreport:392 msgid "plugin %s skipped (--skip-plugins)" -msgstr "le plugin %s a été ignoré (--skip-plugins)" +msgstr "plugin %s desactivé (--skip-plugins)" -#: sosreport:478 +#: sosreport:396 msgid "plugin %s is inactive (use -e or -o to enable)." -msgstr "le plugin %s est inactif (utilisez -e ou -o pour l'activer)." +msgstr "plugin %s a été desactivé (utiliser -e ou -o pour réactiver)." -#: sosreport:486 +#: sosreport:404 msgid "plugin %s not specified in --only-plugins list" -msgstr "le plugin %s n'a pas été spécifié dans la liste --only-plugins" +msgstr "plugin %s non specifié dans la liste --only-plugins" -#: sosreport:491 +#: sosreport:409 msgid "plugin %s does not install, skipping" -msgstr "le plugin %s ne s'installe pas, ignoré" +msgstr "Plugin %s ne s'installe pas, déscativé" + +#: sosreport:412 +msgid "could not load plugin %s" +msgstr "Echec du chargement du plugin %s" -#: sosreport:554 +#: sosreport:455 msgid "processing options from plugin: %s" -msgstr "traitement des options du plugin : %s" +msgstr "Traitement des options du plugin: %s" -#: sosreport:565 +#: sosreport:466 msgid "no valid plugins found" -msgstr "aucun plugin valide n'a été trouvé" +msgstr "Aucun plugin valide trouvé" -#: sosreport:570 +#: sosreport:471 msgid "The following plugins are currently enabled:" -msgstr "Les plugins suivants sont activés :" +msgstr "Les plugins suivants sont actuellement activés:" -#: sosreport:575 +#: sosreport:476 msgid "No plugin enabled." -msgstr "Aucun plugin n'est activé." +msgstr "Aucun plugin activé." -#: sosreport:579 +#: sosreport:480 msgid "The following plugins are currently disabled:" -msgstr "Les plugins suivants sont désactivés :" +msgstr "Les plugins suivants sont actuellment déscativés:" -#: sosreport:586 +#: sosreport:487 msgid "The following plugin options are available:" -msgstr "Les options du plugin suivant sont disponibles :" +msgstr "Les options de plugin suivantes sont disponibles:" -#: sosreport:606 +#: sosreport:507 msgid "No plugin options available." -msgstr "Aucune option n'est disponible pour ce plugin." +msgstr "Pas d'options de plugin configurables." -#: sosreport:614 +#: sosreport:515 msgid "sosreport requires root permissions to run." -msgstr "sosreport requiert des permissions root pour démarrer." +msgstr "sosreport doit être lancé avec les privilèges root." -#: sosreport:621 +#: sosreport:522 msgid "no valid plugins were enabled" -msgstr "aucun plugin valide n'a été activé" +msgstr "Aucun plugin valide n'a été activé" -#: sosreport:624 +#: sosreport:526 msgid "" "This utility will collect some detailed information about the\n" "hardware and setup of your Red Hat Enterprise Linux system.\n" "The information is collected and an archive is packaged under\n" -"/tmp, which you can send to a support representative.\n" +"/tmp, which you can send to a support rappresentative.\n" "Red Hat will use this information for diagnostic purposes ONLY\n" "and it will be considered confidential information.\n" "\n" "This process may take a while to complete.\n" "No changes will be made to your system.\n" "\n" +"Press ENTER to continue, or CTRL-C to quit.\n" msgstr "" -"Cet utilitaire collectera des informations détaillées à propos du\n" -"matériel et de l'installation de votre système Red Hat Enterprise Linux.\n" -"Les informations sont collectées et une archive est créée sous /tmp.\n" -"Vous pouvez l'envoyer à un représentant de support.\n" -"Red Hat utilisera ces informations à des fins de diagnostique SEULEMENT\n" -"et elles seront considérées commes des informations confidentielles.\n" +"Cet outil va collecter des informations détaillées sur le matériel\n" +"et la configuration de votre système Red Hat Enterprise Linux.\n" +"Les informations seront assemblées dans une archive sous /tmp,\n" +"que vous pouvez renvoyer à un représentant du Support Red Hat.\n" +"Red Hat utilisera ces informations à fin d'anaylser les problèmes UNIQUEMENT\n" +"et elles seront considérées comme confidentielles.\n" "\n" -"Ce processus peut prendre un certain temps avant d'être terminé.\n" -"Aucun changement ne sera effectué sur votre système.\n" +"Ce processus pourrait prendre du temps pour finir.\n" +"Aucun changement ne sera apporté à votre système.\n" "\n" +"Tapez ENTREE pour continuer, ou CTRL-C pour quitter.\n.\n" -#: sosreport:638 -msgid "Press ENTER to continue, or CTRL-C to quit.\n" -msgstr "Appuyez sur Entrée pour continuer ou CTRL-C pour quitter.\n" - -#: sosreport:654 +#: sosreport:555 msgid "One or more plugins have detected a problem in your configuration." -msgstr "Un ou plusieurs plugins ont détecté un problème dans votre configuration." +msgstr "Un ou plusieurs plugins ont détecté un problème avec votre configuration." -#: sosreport:655 +#: sosreport:556 msgid "Please review the following messages:" -msgstr "Veuillez revoir les messages suivants :" +msgstr "Prière de vérifier les messages suivants:" -#: sosreport:671 +#: sosreport:571 msgid "Are you sure you would like to continue (y/n) ? " -msgstr "Êtes-vous sûr de vouloir continuer (y/n) ?" +msgstr "Voulez vous continuer (y/n)?" -#: sosreport:672 +#: sosreport:572 msgid "Y" -msgstr "Y" +msgstr "O" -#: sosreport:672 +#: sosreport:572 msgid "y" -msgstr "y" +msgstr "o" -#: sosreport:675 +#: sosreport:575 msgid "N" msgstr "N" -#: sosreport:675 +#: sosreport:575 msgid "n" msgstr "n" - diff --git a/src/locale/it/LC_MESSAGES/sos.po b/src/locale/it/LC_MESSAGES/sos.po index 7e6ee4c2..cafd4c42 100644 --- a/src/locale/it/LC_MESSAGES/sos.po +++ b/src/locale/it/LC_MESSAGES/sos.po @@ -1,41 +1,33 @@ -# translation of it.po to +# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # msgid "" msgstr "" -"Project-Id-Version: it\n" -"POT-Creation-Date: 2007-10-24 08:45\n" -"PO-Revision-Date: 2007-11-06 15:02+1000\n" -"Last-Translator: \n" -"Language-Team: <it@li.org>\n" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2007-08-03 09:39\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: utf-8\n" "Generated-By: pygettext.py 1.5\n" -"X-Generator: KBabel 1.11.4\n" -#: lib/sos/policyredhat.py:203 + +#: lib/sos/policyredhat.py:127 msgid "Please enter your first initial and last name [%s]: " msgstr "Inserire l'iniziale del nome e il cognome [%s]: " -#: lib/sos/policyredhat.py:206 +#: lib/sos/policyredhat.py:132 msgid "Please enter the case number that you are generating this report for: " msgstr "Inserire il numero del caso a cui si riferisce questo report: " -#: lib/sos/policyredhat.py:231 +#: lib/sos/policyredhat.py:155 msgid "Creating compressed archive..." msgstr "Creazione di un archivio compresso in corso..." -#: lib/sos/policyredhat.py:253 -msgid "Encrypting archive..." -msgstr "Cifratura archivio in corso..." - -#: lib/sos/policyredhat.py:271 -msgid "There was a problem encrypting your report." -msgstr "Si è verificato un problema durante la cifratura di questo report." - -#: lib/sos/policyredhat.py:292 +#: lib/sos/policyredhat.py:185 msgid "" "Your sosreport has been generated and saved in:\n" " %s" @@ -43,147 +35,129 @@ msgstr "" "Il sosreport é stato creato e salvato in:\n" " %s" -#: lib/sos/policyredhat.py:295 +#: lib/sos/policyredhat.py:188 msgid "The md5sum is: " msgstr "L'md5sum é: " -#: lib/sos/policyredhat.py:297 +#: lib/sos/policyredhat.py:190 msgid "Please send this file to your support representative." -msgstr "Si prega di inviare questo file al rappresentante del supporto tecnico." - -#: lib/sos/policyredhat.py:323 -msgid "Cannot upload to specified URL." -msgstr "Impossibile caricare sull'URL specificato." - -#: lib/sos/policyredhat.py:360 -msgid "There was a problem uploading your report to Red Hat support." -msgstr "Si è verificato un problema durante il caricamento del vostro report su Red Hat support." +msgstr "E' pregato di inviare questo file al rappresentante del supporto tecnico." -#: lib/sos/policyredhat.py:362 -msgid "Your report was successfully uploaded to Red Hat's ftp server with name:" -msgstr "Il vostro report è stato caricato con successo sul server ftp di Red Hat con il nome:" - -#: lib/sos/policyredhat.py:365 -msgid "Please communicate this name to your support representative." -msgstr "Si prega di inviare questo nome al rappresentante del supporto tecnico." - -#: sosreport:395 -msgid "Could not create temporary directory." -msgstr "Impossibile creare le directory temporanea." - -#: sosreport:451 +#: sosreport:372 msgid "sosreport (version %s)" msgstr "sosreport (versione %s)" -#: sosreport:468 +#: sosreport:390 msgid "plugin %s does not validate, skipping" msgstr "la plugin %s non é valida e verrà ignorata" -#: sosreport:474 +#: sosreport:394 msgid "plugin %s skipped (--skip-plugins)" msgstr "plugin %s disattivata (--skip-plugins)" -#: sosreport:478 +#: sosreport:398 msgid "plugin %s is inactive (use -e or -o to enable)." msgstr "plugin %s non é attiva (utilizzare -e o -o per riattivarla)." -#: sosreport:486 +#: sosreport:406 msgid "plugin %s not specified in --only-plugins list" msgstr "plugin %s non specificata nella lista --only-plugins" -#: sosreport:491 +#: sosreport:411 msgid "plugin %s does not install, skipping" msgstr "non é stato possibile installare la plugin %s" -#: sosreport:554 +#: sosreport:414 +msgid "could not load plugin %s" +msgstr "impossibile caricare la plugin %s" + +#: sosreport:457 msgid "processing options from plugin: %s" msgstr "sto processando le opzioni della plugin: %s" -#: sosreport:565 +#: sosreport:468 msgid "no valid plugins found" msgstr "nessuna plugin valida é stata trovata" -#: sosreport:570 +#: sosreport:473 msgid "The following plugins are currently enabled:" msgstr "Le seguenti plugin sono attive:" -#: sosreport:575 +#: sosreport:478 msgid "No plugin enabled." msgstr "Nessuna plugin abilitata." -#: sosreport:579 +#: sosreport:482 msgid "The following plugins are currently disabled:" msgstr "Le seguenti plugin sono disattivate:" -#: sosreport:586 +#: sosreport:489 msgid "The following plugin options are available:" msgstr "Sono disponibili le seguenti opzioni per la plugin:" -#: sosreport:606 +#: sosreport:509 msgid "No plugin options available." msgstr "Nessuna opzione disponibile per le plugins attive." -#: sosreport:614 +#: sosreport:517 msgid "sosreport requires root permissions to run." msgstr "sosreport necessita dei permessi di root" -#: sosreport:621 +#: sosreport:524 msgid "no valid plugins were enabled" msgstr "non é stata attivata nessuna plugin valida" -#: sosreport:624 +#: sosreport:528 msgid "" "This utility will collect some detailed information about the\n" "hardware and setup of your Red Hat Enterprise Linux system.\n" "The information is collected and an archive is packaged under\n" -"/tmp, which you can send to a support representative.\n" +"/tmp, which you can send to a support rappresentative.\n" "Red Hat will use this information for diagnostic purposes ONLY\n" "and it will be considered confidential information.\n" "\n" "This process may take a while to complete.\n" "No changes will be made to your system.\n" "\n" +"Press ENTER to continue, or CTRL-C to quit.\n" msgstr "" -"Questa utilità raccoglierà alcune informazioni dettagliate\n" -"sull'hardware e sulla impostazione del vostro sistema Red Hat\n" -"Enterprise Linux. Queste informazioni verranno archiviate in\n" -"/tmp, e possono essere inviate ad un rappresentante del supporto tecnico.\n" -"Red Hat utilizzerà questi dati ESCLUSIVAMENTE per scopi diagnostici e\n" -"verranno considerate informazioni riservate\n" +"Questo programma collezionerà delle informazioni dettagliate\n" +"su hardware e configurazione del vostro sistema Red Hat\n" +"Enterprise Linux. Queste informazioni verranno usate per\n" +"diagnosticare i problemi del vostro sistema e sono considerate\n" +"strettamente confidenziali. Red Hat utilizzerà questi dati\n" +"ESCLUSIVAMENTE per scopi diagnostici.\n" "\n" "Questo processo potrebbe durare alcuni minuti.\n" -"Non verrà apportata alcuna modifica al vostro sistema.\n" +"Non verrà apportata nessuna modifica al vostro sistema.\n" "\n" +"Premere ENTER per continuare, o CTRL-C per uscire.\n" -#: sosreport:638 -msgid "Press ENTER to continue, or CTRL-C to quit.\n" -msgstr "Premere INVIO per continuare, o CTRL-C per usicre.\n" - -#: sosreport:654 +#: sosreport:555 msgid "One or more plugins have detected a problem in your configuration." -msgstr "Una o più plugin hanno causato problemi nella configurazione del sistema:" +msgstr "Una o più plugin hanno determinato problemi nella configurazione del sistema:" -#: sosreport:655 +#: sosreport:556 msgid "Please review the following messages:" -msgstr "Si prega di verificare i seguenti messaggi:" +msgstr "Verifichi i seguenti messaggi:" -#: sosreport:671 +#: sosreport:571 msgid "Are you sure you would like to continue (y/n) ? " msgstr "E' sicuro di voler continuare (s/n) ? " -#: sosreport:672 +#: sosreport:572 msgid "Y" msgstr "S" -#: sosreport:672 +#: sosreport:572 msgid "y" msgstr "s" -#: sosreport:675 +#: sosreport:575 msgid "N" -msgstr "N" +msgstr "" -#: sosreport:675 +#: sosreport:575 msgid "n" -msgstr "n" +msgstr "" diff --git a/src/setup.py b/src/setup.py index d34ae6c8..b64c3593 100644 --- a/src/setup.py +++ b/src/setup.py @@ -9,82 +9,6 @@ setup( packages = ['sos', 'sos.plugins'], scripts = [], package_dir = {'': 'lib',}, - data_files = [ ('/etc', [ 'sos.conf']), ('/usr/sbin', ['sosreport', 'extras/sysreport/sysreport.legacy']), ('/usr/bin', ['extras/rh-upload-core']), ('/usr/share/sysreport', ['extras/sysreport/text.xsl', 'extras/sysreport/functions', 'extras/sysreport/sysreport-fdisk']), ('/usr/share/man/man1', ['sosreport.1']), - ('/usr/share/locale/af/LC_MESSAGES', ['locale/af/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/am/LC_MESSAGES', ['locale/am/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ar/LC_MESSAGES', ['locale/ar/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/as/LC_MESSAGES', ['locale/as/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/be/LC_MESSAGES', ['locale/be/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/bg/LC_MESSAGES', ['locale/bg/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/bn/LC_MESSAGES', ['locale/bn/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/bn_IN/LC_MESSAGES', ['locale/bn_IN/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/bs/LC_MESSAGES', ['locale/bs/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ca/LC_MESSAGES', ['locale/ca/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/cs/LC_MESSAGES', ['locale/cs/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/cy/LC_MESSAGES', ['locale/cy/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/da/LC_MESSAGES', ['locale/da/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/de/LC_MESSAGES', ['locale/de/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/el/LC_MESSAGES', ['locale/el/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/en/LC_MESSAGES', ['locale/en/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/en_GB/LC_MESSAGES', ['locale/en_GB/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/es/LC_MESSAGES', ['locale/es/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/et/LC_MESSAGES', ['locale/et/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/eu_ES/LC_MESSAGES', ['locale/eu_ES/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/fa/LC_MESSAGES', ['locale/fa/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/fi/LC_MESSAGES', ['locale/fi/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/fr/LC_MESSAGES', ['locale/fr/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/gl/LC_MESSAGES', ['locale/gl/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/gu/LC_MESSAGES', ['locale/gu/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/he/LC_MESSAGES', ['locale/he/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/hi/LC_MESSAGES', ['locale/hi/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/hr/LC_MESSAGES', ['locale/hr/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/hu/LC_MESSAGES', ['locale/hu/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/hy/LC_MESSAGES', ['locale/hy/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/id/LC_MESSAGES', ['locale/id/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ilo/LC_MESSAGES', ['locale/ilo/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/is/LC_MESSAGES', ['locale/is/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/it/LC_MESSAGES', ['locale/it/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ja/LC_MESSAGES', ['locale/ja/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ka/LC_MESSAGES', ['locale/ka/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/kn/LC_MESSAGES', ['locale/kn/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ko/LC_MESSAGES', ['locale/ko/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ku/LC_MESSAGES', ['locale/ku/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/lo/LC_MESSAGES', ['locale/lo/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/lt/LC_MESSAGES', ['locale/lt/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/lv/LC_MESSAGES', ['locale/lv/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/mk/LC_MESSAGES', ['locale/mk/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ml/LC_MESSAGES', ['locale/ml/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/mr/LC_MESSAGES', ['locale/mr/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ms/LC_MESSAGES', ['locale/ms/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/my/LC_MESSAGES', ['locale/my/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/nb/LC_MESSAGES', ['locale/nb/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/nl/LC_MESSAGES', ['locale/nl/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/nn/LC_MESSAGES', ['locale/nn/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/no/LC_MESSAGES', ['locale/no/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/nso/LC_MESSAGES', ['locale/nso/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/or/LC_MESSAGES', ['locale/or/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/pa/LC_MESSAGES', ['locale/pa/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/pl/LC_MESSAGES', ['locale/pl/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/pt/LC_MESSAGES', ['locale/pt/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/pt_BR/LC_MESSAGES', ['locale/pt_BR/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ro/LC_MESSAGES', ['locale/ro/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ru/LC_MESSAGES', ['locale/ru/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/si/LC_MESSAGES', ['locale/si/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/sk/LC_MESSAGES', ['locale/sk/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/sl/LC_MESSAGES', ['locale/sl/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/sq/LC_MESSAGES', ['locale/sq/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/sr/LC_MESSAGES', ['locale/sr/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/sr@latin/LC_MESSAGES', ['locale/sr@latin/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/sv/LC_MESSAGES', ['locale/sv/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ta/LC_MESSAGES', ['locale/ta/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/te/LC_MESSAGES', ['locale/te/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/th/LC_MESSAGES', ['locale/th/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/tr/LC_MESSAGES', ['locale/tr/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/uk/LC_MESSAGES', ['locale/uk/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/ur/LC_MESSAGES', ['locale/ur/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/vi/LC_MESSAGES', ['locale/vi/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/zh_CN/LC_MESSAGES', ['locale/zh_CN/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/zh_TW/LC_MESSAGES', ['locale/zh_TW/LC_MESSAGES/sos.mo']), - ('/usr/share/locale/zu/LC_MESSAGES', ['locale/zu/LC_MESSAGES/sos.mo']), + data_files = [ ('/usr/sbin', ['sosreport', 'extras/sysreport/sysreport.legacy']), ('/usr/bin', ['extras/rh-upload-core']), ('/usr/share/sysreport', ['extras/sysreport/text.xsl', 'extras/sysreport/functions', 'extras/sysreport/sysreport-fdisk']), ('/usr/share/man/man1', ['sosreport.1']), ('/usr/share/locale/en', []), ('/usr/share/locale/it', []), ('/usr/share/locale/en/LC_MESSAGES', ['locale/en/LC_MESSAGES/sos.mo']), ('/usr/share/locale/it/LC_MESSAGES', ['locale/it/LC_MESSAGES/sos.mo']), ('/usr/share/locale/fr/LC_MESSAGES', ['locale/fr/LC_MESSAGES/sos.mo']), ('/usr/share/locale/ar/LC_MESSAGES', ['locale/ar/LC_MESSAGES/sos.mo']) ] ) diff --git a/src/sos.spec b/src/sos.spec index 3b3f8534..0a0d8add 100644 --- a/src/sos.spec +++ b/src/sos.spec @@ -1,8 +1,8 @@ %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} %define name sos -%define version 1.8 -%define release 0pre2 +%define version 1.7 +%define release 9 %define _localedir %_datadir/locale @@ -10,23 +10,19 @@ Summary: A set of tools to gather troubleshooting information from a system Name: %{name} Version: %{version} Release: %{release}%{?dist} -Group: Application/Tools # The source for this package was pulled from upstream's svn. Use the # following commands to generate the tarball: # svn --username guest export https://sos.108.redhat.com/svn/sos/tags/r1-7 sos-1.7 # tar -czvf sos-1.7.tar.gz sos-1.7 Source0: %{name}-%{version}.tar.gz -Source1: rhsupport.pub License: GPL +Group: Development/Libraries BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot BuildArch: noarch -Url: https://hosted.fedoraproject.org/projects/sos +Url: http://sos.108.redhat.com/ BuildRequires: python-devel Requires: libxml2-python -%if 0%{?rhel} -Provides: sysreport = 1.4.3-13 Obsoletes: sysreport -%endif %description Sos is a set of tools that gathers information about system @@ -42,18 +38,8 @@ python setup.py build %install rm -rf ${RPM_BUILD_ROOT} -install -D -m644 %{SOURCE1} ${RPM_BUILD_ROOT}/usr/share/sos/rhsupport.pub python setup.py install --optimize 1 --root=$RPM_BUILD_ROOT - -%if 0%{?rhel} ln -s /usr/sbin/sosreport $RPM_BUILD_ROOT/usr/sbin/sysreport -%endif -%if ! 0%{?rhel} -rm -f $RPM_BUILD_ROOT/usr/sbin/sysreport.legacy -rm -f $RPM_BUILD_ROOT/usr/share/sysreport/functions -rm -f $RPM_BUILD_ROOT/usr/share/sysreport/sysreport-fdisk -rm -f $RPM_BUILD_ROOT/usr/share/sysreport/text.xsl -%endif %clean rm -rf ${RPM_BUILD_ROOT} @@ -61,76 +47,20 @@ rm -rf ${RPM_BUILD_ROOT} %files %defattr(-,root,root,-) %{_sbindir}/sosreport -/usr/share/sos/rhsupport.pub /usr/bin/rh-upload-core -%if 0%{?rhel} /usr/sbin/sysreport /usr/sbin/sysreport.legacy /usr/share/sysreport -%endif %{python_sitelib}/sos/ %{_mandir}/man1/sosreport.1* %{_localedir}/*/LC_MESSAGES/sos.mo %doc README README.rh-upload-core TODO LICENSE ChangeLog -%config /etc/sos.conf %changelog -* Wed Nov 21 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.8-0 -- Resolves: bz368261 sosGetCommandOutput() does not block on hung processes -- Resolves: bz361861 work-around missing traceback.format_exc() in RHEL4 -- Resolves: bz394781 device-mapper: use /sbin/lvm_dump to collect dm related info -- Resolves: bz386691 unattended --batch option -- Resolves: bz371251 sos could hang when accessing /sys/hypervisor/uuid -- selinux: always collect sestatus -- added many languages -- added --debug option which causes exceptions not to be trapped -- updated to sysreport-1.4.3-13.el5 -- ftp upload to dropbox with --upload -- cluster: major rewrite to support different versions of RHEL -- cluster: check rg_test for errors -- minor changes in various plug-ins (yum, networking, process, kernel) -- fixed some exceptions in threads which were not properly trapped -- veritas: don't run rpm -qa every time -- using rpm's python bindings instead of external binary -- corrected autofs and ldap plugin that were failing when debug option was not found in config file. -- implemented built-in checkdebug() that uses self.files and self.packages to make the decision -- missing binaries are properly detected now. -- better doExitCode handling -- fixed problem with rpm module intercepting SIGINT -- error when user specifies an invalid plugin or plugin option -- named: fixed indentation -- replaced isOptionEnabled() with getOption() -- tune2fs and fdisk were not always run against the correct devices/mountpoint -- added gpg key to package -- updated README with new svn repo and contributors -- updated manpage -- better signal handling -- caching of rpm -q outputs -- report filename includes rhnUsername if available -- report encryption via gpg and support pubkey -- autofs: removed redundant files -- filesys: better handling of removable devices -- added sosReadFile() returns a file's contents -- return after looping inside a directory -- collect udevinfo for each block device -- simply collect output of fdisk -l in one go -- handle sysreport invocation properly (warn if shell is interactive, otherwise spawn sysreport.legacy) -- progress bar don't show 100% until finished() is called -- Resolves: bz238778 added lspci -t -- now runs on RHEL3 as well (python 2.2) -- replaced commonPrefix() with faster code -- filesys: one fdisk -l for all -- selinux: collect fixfilex check output -- devicemapper: collect udevinfo for all block devices -- cluster: validate node names according to RFC 2181 -- systemtap: cleaned up and added checkenabled() method -- added kdump plugin -- added collection of /etc/inittab -- Resolves: bz332151 apply regex to case number in sysreport for RHEL4 -- Resolves: bz332211 apply regex to case number in sysreport for RHEL5 -- Resolves: bz400111 sos incorrectly reports cluster data in SMP machine - -* Wed Aug 13 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.7-8 +* Thu Aug 16 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.7-9 +- corrected a problem causing sometimes exceptions not to be catched when triggered within a thread + +* Mon Aug 13 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.7-8 - added README.rh-upload-core * Mon Aug 13 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.7-7 diff --git a/src/sosreport b/src/sosreport index 37a88a47..888e0b54 100755 --- a/src/sosreport +++ b/src/sosreport @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python """ Gather information about a system and report it using plugins supplied for application-specific information @@ -28,26 +28,19 @@ supplied for application-specific information import sys import os from optparse import OptionParser, Option -import ConfigParser import sos.policyredhat from sos.helpers import * from snack import * from threading import Thread, activeCount import signal +import logging from stat import * from time import strftime, localtime, time from pwd import getpwuid import gettext from threading import Semaphore -# RHEL3 doesn't have a logging module -try: - import logging -except ImportError: - import sos.rhel3_logging - logging = sos.rhel3_logging - -__version__ = 1.8 +__version__ = 1.7 __breakHits__ = 0 # Use this to track how many times we enter the exit routine @@ -57,15 +50,10 @@ def exittermhandler(signum, frame): def doExitCode(): from threading import enumerate - global __breakHits__, loadedplugins, dstroot - + global __breakHits__ __breakHits__ += 1 if ( ( activeCount() > 1 ) and ( __breakHits__ == 1 ) ): print "SIGTERM received, multiple threads detected, waiting for all threads to exit" - - for plugname, plug in loadedplugins: - plug.exit_please() - for thread in enumerate(): if thread.getName() == "MainThread": continue @@ -74,41 +62,20 @@ def doExitCode(): try: thread.join() except KeyboardInterrupt: - doExitCode() + pass else: print "All threads ended, cleaning up." - doExit(1) - - if ( ( activeCount() > 1 ) and ( __breakHits__ > 1 ) ): - print "Multiple SIGTERMs, multiple threads, attempting to signal threads to die immediately." + if ( ( activeCount() > 1 ) and ( __breakHits__ > 1 ) ): + print "Multiple SIGTERMs, multiple threads, attempting to signal threads to die immediately" ## FIXME: Add thread-kill code (see FIXME below) - return - elif ( ( activeCount() > 1 ) and ( __breakHits__ > 2 ) ): - print "Multiple SIGTERMs, multiple threads, process suicides." - os.kill(os.getpid(), signal.SIGKILL) - elif ( ( activeCount() == 1 ) and ( __breakHits__ > 2 ) ): +# os.kill(os.getpid(), signal.SIGKILL) + print "Threads dead, cleaning up." + if ( ( activeCount() == 1 ) and ( __breakHits__ > 2 ) ): print "Multiple SIGTERMs, single thread, exiting without cleaning up." - doExit(3) - - doExit("Abnormal exit") - -def doExit(error=0): - global policy - policy.cleanDstroot() - sys.exit(error) - -def doException(type, value, tb): - if hasattr(sys, 'ps1') or not sys.stderr.isatty(): - # we are in interactive mode or we don't have a tty-like - # device, so we call the default hook - sys.__excepthook__(type, value, tb) - else: - import traceback, pdb - # we are NOT in interactive mode, print the exception... - traceback.print_exception(type, value, tb) - print - # ...then start the debugger in post-mortem mode. - pdb.pm() + sys.exit(3) + + # FIXME: Add code here to clean up /tmp + sys.exit("Abnormal exit") # Handle any sort of exit signal cleanly # Currently, we intercept only sig 15 (TERM) @@ -117,6 +84,9 @@ signal.signal(signal.SIGTERM, exittermhandler) ## FIXME: Need to figure out how to IPC with child threads in case of ## multiple SIGTERMs. +# for debugging +__raisePlugins__ = 0 + class OptionParser_extended(OptionParser): def print_help(self): OptionParser.print_help(self) @@ -125,10 +95,10 @@ class OptionParser_extended(OptionParser): print print " enable cluster plugin only and collect dlm lockdumps:" print " # sosreport -o cluster -k cluster.lockdump" - print + print print " disable memory and samba plugins, turn off rpm -Va collection:" print " # sosreport -n memory,samba -k rpm.rpmva=off" - print + print class SosOption (Option): """Allow to specify comma delimited list of plugins""" @@ -163,51 +133,39 @@ __cmdParser__.add_option("-k", action="extend", \ __cmdParser__.add_option("-a", "--alloptions", action="store_true", \ dest="usealloptions", default=False, \ help="enable all options for loaded plugins") -__cmdParser__.add_option("-u", "--upload", action="store_true", \ - dest="upload", default=False, \ - help="upload the report to Red Hat support") -#__cmdParser__.add_option("--encrypt", action="store_true", \ -# dest="encrypt", default=False, \ -# help="encrypt with GPG using Red Hat support's public key") -__cmdParser__.add_option("--batch", action="store_true", \ - dest="batch", default=False, \ - help="do not ask any question (batch mode)") -__cmdParser__.add_option("--no-colors", action="store_true", \ - dest="nocolors", default=False, \ - help="do not use terminal colors for text") __cmdParser__.add_option("-v", "--verbose", action="count", \ dest="verbosity", \ help="increase verbosity") -__cmdParser__.add_option("--debug", action="count", \ - dest="debug", \ - help="enabling debugging") __cmdParser__.add_option("--no-progressbar", action="store_false", \ dest="progressbar", default=True, \ help="do not display a progress bar.") __cmdParser__.add_option("--no-multithread", action="store_true", \ dest="nomultithread", \ help="disable multi-threaded gathering mode (slower)", default=False) +__cmdParser__.add_option("--name", action="store", \ + dest="name",type="string", \ + help="first initial and last name.", default="") +__cmdParser__.add_option("--ticket-number", action="store", \ + dest="ticketnumber", type="string", \ + help="ticket number.", default="") if sys.argv[0].endswith("sysreport"): - print - print "WARNING: sysreport is deprecated, please use sosreport instead." - if not sys.stdin.isatty(): - print + try: + ppid = os.getppid() + fp = open("/proc/%d/cmdline" % ppid, "r") + cmd = fp.read() + fp.close() + except: + cmd = "" + if not sys.stdin.isatty() or cmd.find("bash") < 0: os.execl("/bin/sh", "/bin/sh", "-c", "/usr/sbin/sysreport.legacy") - sys.exit(-1) - -if "-norpm" in sys.argv: + os.exit(-1) print - print """WARNING: sysreport's "-norpm" option is deprecated, please use "-k rpm.rpmva=off" instead.""" - print - sys.exit(1) + print "WARNING: sysreport is deprecated, please use sosreport instead." (__cmdLineOpts__, __cmdLineArgs__)=__cmdParser__.parse_args() def textcolor(text, fg, raw=0): - global __cmdLineOpts__ - if __cmdLineOpts__.nocolors: - return text colors = { "black":"30", "red":"31", "green":"32", "brown":"33", "blue":"34", "purple":"35", "cyan":"36", "lgray":"37", "gray":"1;30", "lred":"1;31", "lgreen":"1;32", "yellow":"1;33", "lblue":"1;34", "pink":"1;35", @@ -230,11 +188,11 @@ class progressBar: self.last_amount_update = time() self.update() - def updateAmount(self, newAmount = 0, finished = False): + def updateAmount(self, newAmount = 0): if newAmount < self.min: newAmount = self.min if newAmount > self.max: - newAmount = self.max - 1 + newAmount = self.max if self.amount != newAmount: self.last_amount_update = time() self.amount = newAmount @@ -249,8 +207,6 @@ class progressBar: percentDone = round(timeElapsed * 100 / self.eta) except: percentDone = 0 - if percentDone >= 100 and not finished: - percentDone = 99 if percentDone > 100: percentDone = 100 ETA = timeElapsed @@ -285,7 +241,7 @@ class progressBar: self.updateAmount(self.amount+toInc) def finished(self): - self.updateAmount(self.max, finished = True) + self.updateAmount(self.max) sys.stdout.write(self.progBar + '\n') sys.stdout.flush() @@ -359,14 +315,6 @@ class XmlReport: outfn.write(self.doc.serialize(None,1)) outfn.close() -# if debugging is enabled, allow plugins to raise exceptions - -if __cmdLineOpts__.debug: - sys.excepthook = doException - __raisePlugins__ = 1 -else: - __raisePlugins__ = 0 - def sosreport(): # pylint: disable-msg = R0912 # pylint: disable-msg = R0914 @@ -374,13 +322,6 @@ def sosreport(): """ This is the top-level function that gathers and processes all sosreport information """ - - global loadedplugins, dstroot, policy - - config = ConfigParser.ConfigParser() - try: config.readfp(open('/etc/sos.conf')) - except IOError: pass - loadedplugins = [] skippedplugins = [] alloptions = [] @@ -395,12 +336,8 @@ def sosreport(): pluginpath = path + "/sos/plugins" # Set up common info and create destinations - - dstroot = policy.getDstroot() - if not dstroot: - print _("Could not create temporary directory.") - doExit() + dstroot = sosFindTmpDir() cmddir = os.path.join(dstroot, "sos_commands") logdir = os.path.join(dstroot, "sos_logs") rptdir = os.path.join(dstroot, "sos_reports") @@ -409,7 +346,7 @@ def sosreport(): os.mkdir(rptdir, 0755) # initialize i18n language localization - gettext.install('sos', '/usr/share/locale', unicode=False) + gettext.install('sos', '/usr/share/locale', unicode=False) # initialize logging soslog = logging.getLogger('sos') @@ -417,15 +354,12 @@ def sosreport(): logging.VERBOSE = logging.INFO - 1 logging.VERBOSE2 = logging.INFO - 2 - logging.VERBOSE3 = logging.INFO - 3 + logging.VERBOSE3 = logging.INFO - 3 logging.addLevelName(logging.VERBOSE, "verbose") logging.addLevelName(logging.VERBOSE2,"verbose2") logging.addLevelName(logging.VERBOSE3,"verbose3") - # if stdin is not a tty, disable colors and don't ask questions - if not sys.stdin.isatty(): - __cmdLineOpts__.nocolors = True - __cmdLineOpts__.batch = True + # FIXME: strip colours if terminal doesn't allow it # log to a file flog = logging.FileHandler(logdir + "/sos.log") @@ -448,7 +382,7 @@ def sosreport(): # set up dict so everyone can share the following commons = {'dstroot': dstroot, 'cmddir': cmddir, 'logdir': logdir, 'rptdir': rptdir, 'soslog': soslog, 'policy': policy, 'verbosity' : __cmdLineOpts__.verbosity, - 'xmlreport' : xmlrep, 'cmdlineopts':__cmdLineOpts__, 'config':config } + 'xmlreport' : xmlrep } # Make policy aware of the commons policy.setCommons(commons) @@ -456,11 +390,12 @@ def sosreport(): print soslog.info ( _("sosreport (version %s)") % __version__) print - + # generate list of available plugins plugins = os.listdir(pluginpath) plugins.sort() - plugin_names = [] + + # FIXME: should at least print a warning if the user references a plugin which does not exist # validate and load plugins for plug in plugins: @@ -468,33 +403,36 @@ def sosreport(): if not plug[-3:] == '.py' or plugbase == "__init__": continue try: - if policy.validatePlugin(pluginpath + plug): - pluginClass = importPlugin("sos.plugins." + plugbase, plugbase) - else: - soslog.warning(_("plugin %s does not validate, skipping") % plug) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - # plug-in is valid, let's decide whether run it or not - plugin_names.append(plugbase) - if plugbase in __cmdLineOpts__.noplugins: - soslog.log(logging.VERBOSE, _("plugin %s skipped (--skip-plugins)") % plugbase) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - if not pluginClass(plugbase, commons).checkenabled() and not plugbase in __cmdLineOpts__.enableplugins and not plugbase in __cmdLineOpts__.onlyplugins: - soslog.log(logging.VERBOSE, _("plugin %s is inactive (use -e or -o to enable).") % plug) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - if not pluginClass(plugbase, commons).defaultenabled() and not plugbase in __cmdLineOpts__.enableplugins and not plugbase in __cmdLineOpts__.onlyplugins: - soslog.log(logging.VERBOSE, "plugin %s not loaded by default (use -e or -o to enable)." % plug) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - if __cmdLineOpts__.onlyplugins and not plugbase in __cmdLineOpts__.onlyplugins: - soslog.log(logging.VERBOSE, _("plugin %s not specified in --only-plugins list") % plug) - skippedplugins.append((plugbase, pluginClass(plugbase, commons))) - continue - loadedplugins.append((plugbase, pluginClass(plugbase, commons))) + #print "importing plugin: %s" % plugbase + try: + if policy.validatePlugin(pluginpath + plug): + pluginClass = importPlugin("sos.plugins." + plugbase, plugbase) + else: + soslog.warning(_("plugin %s does not validate, skipping") % plug) + skippedplugins.append((plugbase, pluginClass(plugbase, commons))) + continue + if plugbase in __cmdLineOpts__.noplugins: + soslog.log(logging.VERBOSE, _("plugin %s skipped (--skip-plugins)") % plugbase) + skippedplugins.append((plugbase, pluginClass(plugbase, commons))) + continue + if not pluginClass(plugbase, commons).checkenabled() and not plugbase in __cmdLineOpts__.enableplugins and not plugbase in __cmdLineOpts__.onlyplugins: + soslog.log(logging.VERBOSE, _("plugin %s is inactive (use -e or -o to enable).") % plug) + skippedplugins.append((plugbase, pluginClass(plugbase, commons))) + continue + if not pluginClass(plugbase, commons).defaultenabled() and not plugbase in __cmdLineOpts__.enableplugins and not plugbase in __cmdLineOpts__.onlyplugins: + soslog.log(logging.VERBOSE, "plugin %s not loaded by default (use -e or -o to enable)." % plug) + skippedplugins.append((plugbase, pluginClass(plugbase, commons))) + continue + if __cmdLineOpts__.onlyplugins and not plugbase in __cmdLineOpts__.onlyplugins: + soslog.log(logging.VERBOSE, _("plugin %s not specified in --only-plugins list") % plug) + skippedplugins.append((plugbase, pluginClass(plugbase, commons))) + continue + loadedplugins.append((plugbase, pluginClass(plugbase, commons))) + except: + soslog.warning(_("plugin %s does not install, skipping") % plug) + raise except: - soslog.warning(_("plugin %s does not install, skipping") % plug) + soslog.warning(_("could not load plugin %s") % plug) if __raisePlugins__: raise @@ -506,14 +444,6 @@ def sosreport(): if type(parms["enabled"])==bool: parms["enabled"] = True - # read plugin tunables from configuration file - if config.has_section("tunables"): - if not __cmdLineOpts__.plugopts: - __cmdLineOpts__.plugopts = [] - - for opt, val in config.items("tunables"): - __cmdLineOpts__.plugopts.append(opt + "=" + val) - if __cmdLineOpts__.plugopts: opts = {} for opt in __cmdLineOpts__.plugopts: @@ -523,7 +453,7 @@ def sosreport(): except: val=True else: - if val.lower() in ["off", "disable", "disabled", "false"]: + if val == "off" or val == "disable" or val == "disabled": val = False else: # try to convert string "val" to int() @@ -531,11 +461,7 @@ def sosreport(): except: pass # split up "general.syslogsize" - try: - plug, opt = opt.split(".") - except: - plug = opt - opt = True + plug, opt = opt.split(".") try: opts[plug] except KeyError: opts[plug] = [] @@ -544,26 +470,10 @@ def sosreport(): for plugname, plug in loadedplugins: if opts.has_key(plugname): for opt,val in opts[plugname]: - soslog.log(logging.VERBOSE, 'setting option "%s" for plugin (%s) to "%s"' % (plugname,opt,val)) - if not plug.setOption(opt,val): - soslog.error('no such option "%s" for plugin (%s)' % (opt,plugname)) - doExit(1) - del opts[plugname] - for plugname in opts.keys(): - soslog.error('unable to set option for disabled or non-existing plugin (%s)' % (plugname)) - doExit(1) + soslog.log(logging.VERBOSE, "setting option %s for plugin %s to %s" % (plugname,opt,val)) + plug.setOption(opt,val) del opt,opts,val - # error if the user references a plugin which does not exist - unk_plugs = [plugname.split(".")[0] for plugname in __cmdLineOpts__.onlyplugins if not plugname.split(".")[0] in plugin_names] - unk_plugs += [plugname.split(".")[0] for plugname in __cmdLineOpts__.noplugins if not plugname.split(".")[0] in plugin_names] - unk_plugs += [plugname.split(".")[0] for plugname in __cmdLineOpts__.enableplugins if not plugname.split(".")[0] in plugin_names] - if len(unk_plugs): - for plugname in unk_plugs: - soslog.error('a non-existing plugin (%s) was specified in the command line' % (plugname)) - doExit(1) - del unk_plugs - for plugname, plug in loadedplugins: soslog.log(logging.VERBOSE3, _("processing options from plugin: %s") % plugname) names, parms = plug.getAllOptions() @@ -577,7 +487,7 @@ def sosreport(): if __cmdLineOpts__.listPlugins: if not len(loadedplugins) and not len(skippedplugins): soslog.error(_("no valid plugins found")) - doExit(1) + sys.exit(1) # FIXME: make -l output more concise if len(loadedplugins): @@ -620,22 +530,26 @@ def sosreport(): print _("No plugin options available.") print - doExit() + sys.exit() # to go anywhere further than listing the plugins we will need root permissions. # if os.getuid() != 0: print _('sosreport requires root permissions to run.') - doExit(1) + sys.exit(1) # we don't need to keep in memory plugins we are not going to use del skippedplugins if not len(loadedplugins): soslog.error(_("no valid plugins were enabled")) - doExit(1) + sys.exit(1) - msg = _("""This utility will collect some detailed information about the + isUnattended = False + if len(__cmdLineOpts__.name) > 0 and len(__cmdLineOpts__.ticketnumber) > 0: isUnattended = True + if not isUnattended: + try: + raw_input(_("""This utility will collect some detailed information about the hardware and setup of your Red Hat Enterprise Linux system. The information is collected and an archive is packaged under /tmp, which you can send to a support representative. @@ -645,14 +559,11 @@ and it will be considered confidential information. This process may take a while to complete. No changes will be made to your system. -""") - if __cmdLineOpts__.batch: - print msg - else: - msg += _("""Press ENTER to continue, or CTRL-C to quit.\n""") - try: raw_input(msg) - except: print ; doExit() - del msg +Press ENTER to continue, or CTRL-C to quit. +""")) + except KeyboardInterrupt: + print + sys.exit(0) # Call the diagnose() method for each plugin tmpcount = 0 @@ -679,32 +590,37 @@ No changes will be made to your system. fp.close() print - if not __cmdLineOpts__.batch: - try: - while True: + try: + while True: + if not isUnattended: yorno = raw_input( _("Are you sure you would like to continue (y/n) ? ") ) - if yorno == _("y") or yorno == _("Y"): - print - break - elif yorno == _("n") or yorno == _("N"): - doExit(0) - del yorno - except KeyboardInterrupt: - print - doExit(0) - - policy.preWork() + else: + yorno = _("Y") + + if yorno == _("y") or yorno == _("Y"): + print + break + elif yorno == _("n") or yorno == _("N"): + sys.exit(0) + del yorno + except KeyboardInterrupt: + print + sys.exit(0) + + if isUnattended: + policy.preWork(__cmdLineOpts__.name, __cmdLineOpts__.ticketnumber) + else: + policy.preWork() + # Call the setup() method for each plugin for plugname, plug in loadedplugins: soslog.log(logging.VERBOSE2, "Preloading files and commands to be gathered by plugin %s" % plugname) try: - plug.setup() - except KeyboardInterrupt: - raise + plug.setup() except: - if __raisePlugins__: - raise + if __raisePlugins__: + raise # Setup the progress bar if __cmdLineOpts__.progressbar: @@ -723,17 +639,15 @@ No changes will be made to your system. # Call the collect method for each plugin plugrunning = Semaphore(2) for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE, "requesting plugin %s" % plugname) + soslog.log(logging.VERBOSE, "executing plugin %s" % plugname) try: if not __cmdLineOpts__.nomultithread: plug.copyStuff(threaded = True, semaphore = plugrunning) else: - plug.copyStuff() + plug.copyStuff() if __cmdLineOpts__.progressbar: pbar.incAmount(plug.eta_weight) pbar.update() - except KeyboardInterrupt: - raise except: if __raisePlugins__: raise @@ -841,6 +755,8 @@ No changes will be made to your system. rfd.close() + # Collect any needed user information (name, etc) + # Call the postproc method for each plugin for plugname, plug in loadedplugins: try: @@ -851,23 +767,14 @@ No changes will be made to your system. # package up the results for the support organization policy.packageResults() - # delete gathered files - policy.cleanDstroot() - - # let's encrypt the tar-ball - #if __cmdLineOpts__.encrypt: - # policy.encryptResults() - + os.system("/bin/rm -rf %s" % dstroot) # automated submission will go here - if not __cmdLineOpts__.upload: - policy.displayResults() - else: - policy.uploadResults() # Close all log files and perform any cleanup logging.shutdown() - + + if __name__ == '__main__': try: sosreport() diff --git a/src/sosreport.1 b/src/sosreport.1 index 3ae187a8..cd7d34df 100644 --- a/src/sosreport.1 +++ b/src/sosreport.1 @@ -44,21 +44,19 @@ Do not display a progress bar (ETA will not be available). .TP .B \--no-multithread Disable multithreaded collection and analysis of the sosreport data. -.SH MAINTAINER +.SH MAINTAINERS .nf Navid Sheikhol-Eslami <navid@redhat.com> .fi +.SH TRANSLATIONS +.nf +Eva Schaller <eschalle@redhat.com> [Italian] +Imed Chihi <ichihi@redhat.com> [Arabic] [French] +.fi .SH AUTHORS .nf Steve Conklin <sconklin@redhat.com> John Berninger <jwb@redhat.com> +Navid Sheikhol-Eslami <navid@redhat.com> Pierre Amadio <pamadio@redhat.com> -Adam Stokes <astokes@redhat.com> -.fi -.SH THANKS TO -.nf -Eva Schaller <eschaller@redhat.com> for providing an Italian translation -Marco Ceci <mceci@redhat.com> for helping me out with the cluster plugin -Leonardo Macchia <lmacchia@redhat.com> for being my personal regexp generator -Imed Chihi <ichihi@redhat.com> for providing Arabic and French translations .fi diff --git a/src/tools/msgfmt.py b/src/tools/msgfmt.py index 8a2d4e66..277901c0 100644 --- a/src/tools/msgfmt.py +++ b/src/tools/msgfmt.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/python # -*- coding: iso-8859-1 -*- # Written by Martin v. Löwis <loewis@informatik.hu-berlin.de> diff --git a/src/tools/pygettext.py b/src/tools/pygettext.py index 040b5c7f..e44b61b4 100644 --- a/src/tools/pygettext.py +++ b/src/tools/pygettext.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/python # -*- coding: iso-8859-1 -*- # Originally written by Barry Warsaw <barry@zope.com> # |