Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Major updates to most of SoSReport

Code reorganization
Cross platform support for Windows, OS X and Linux
Dynamically loaded policies
Support for loading plugins from multiple locations
  via __path__ modification of sos.plugins
Support for running via Jython
Support for executing from a jarfile
Support for json based reporting infrastructure
  - Previous reporting methods still exist
Support for other checksum algorithms (determined by policy)
Support for other compression algorithms (determined by policy)
New plugin API for writing arbitrary information in a new file inside
    the report archive.
New plugin API for modifying files that have been added to the
    archive.
Added API for global plugin options
  - external interface is unavailable at this time
Many small bugfixes
  • Loading branch information...
commit 6ea48cbbc85d007dfefd1f254db66ff2e0a9cec5 1 parent 1e83a26
@jhjaggars jhjaggars authored
Showing with 4,204 additions and 2,144 deletions.
  1. +9 −0 .gitignore
  2. +2 −0  AUTHORS
  3. +0 −248 ChangeLog.deprecated
  4. +39 −5 Makefile
  5. +8 −28 README
  6. +17 −0 __run__.py
  7. +1 −1  sos.spec
  8. +18 −7 sos/{__init__.py.in → __init__.py}
  9. +0 −79 sos/helpers.py
  10. +615 −0 sos/plugins/__init__.py
  11. +3 −3 sos/plugins/abrt.py
  12. +2 −2 sos/plugins/acpid.py
  13. +2 −2 sos/plugins/amd.py
  14. +2 −2 sos/plugins/anaconda.py
  15. +3 −3 sos/plugins/apache.py
  16. +2 −2 sos/plugins/auditd.py
  17. +6 −6 sos/plugins/autofs.py
  18. +2 −2 sos/plugins/bootloader.py
  19. +6 −6 sos/plugins/cluster.py
  20. +3 −3 sos/plugins/cobbler.py
  21. +3 −5 sos/plugins/corosync.py
  22. +2 −2 sos/plugins/crontab.py
  23. +2 −2 sos/plugins/cs.py
  24. +2 −3 sos/plugins/devicemapper.py
  25. +4 −4 sos/plugins/dhcp.py
  26. +2 −2 sos/plugins/dovecot.py
  27. +2 −2 sos/plugins/ds.py
  28. +339 −0 sos/plugins/eap6.py
  29. +4 −4 sos/plugins/emc.py
  30. +5 −5 sos/plugins/filesys.py
  31. +2 −2 sos/plugins/ftp.py
  32. +2 −2 sos/plugins/gdm.py
  33. +2 −2 sos/plugins/general.py
  34. +2 −2 sos/plugins/gluster.py
  35. +2 −2 sos/plugins/hardware.py
  36. +2 −2 sos/plugins/hts.py
  37. +2 −2 sos/plugins/i18n.py
  38. +2 −2 sos/plugins/initrd.py
  39. +2 −2 sos/plugins/ipa.py
  40. +2 −2 sos/plugins/ipsec.py
  41. +2 −2 sos/plugins/iscsi.py
  42. +3 −3 sos/plugins/iscsitarget.py
  43. +708 −0 sos/plugins/jboss.py
  44. +2 −2 sos/plugins/kdump.py
  45. +3 −3 sos/plugins/kernel.py
  46. +2 −2 sos/plugins/kvm.py
  47. +3 −3 sos/plugins/ldap.py
  48. +3 −3 sos/plugins/libraries.py
  49. +2 −2 sos/plugins/libvirt.py
  50. +3 −3 sos/plugins/logrotate.py
  51. +2 −2 sos/plugins/lsbrelease.py
  52. +3 −3 sos/plugins/memory.py
  53. +2 −2 sos/plugins/mrggrid.py
  54. +2 −2 sos/plugins/mrgmessg.py
  55. +3 −3 sos/plugins/mysql.py
  56. +4 −4 sos/plugins/named.py
  57. +2 −2 sos/plugins/netdump.py
  58. +2 −2 sos/plugins/networking.py
  59. +2 −2 sos/plugins/nfsserver.py
  60. +2 −2 sos/plugins/nscd.py
  61. +2 −2 sos/plugins/ntp.py
  62. +2 −2 sos/plugins/oddjob.py
  63. +2 −2 sos/plugins/openssl.py
  64. +2 −2 sos/plugins/openswan.py
  65. +2 −2 sos/plugins/pam.py
  66. +3 −3 sos/plugins/postfix.py
  67. +56 −0 sos/plugins/postgresql.py
  68. +2 −2 sos/plugins/ppp.py
  69. +2 −2 sos/plugins/printing.py
  70. +2 −2 sos/plugins/process.py
  71. +2 −2 sos/plugins/psacct.py
  72. +3 −3 sos/plugins/pxe.py
  73. +2 −2 sos/plugins/qpidd.py
  74. +2 −2 sos/plugins/quagga.py
  75. +2 −2 sos/plugins/radius.py
  76. +23 −0 sos/plugins/rhevm.py
  77. +2 −2 sos/plugins/rhn.py
  78. +3 −3 sos/plugins/rpm.py
  79. +2 −2 sos/plugins/s390.py
  80. +2 −2 sos/plugins/samba.py
  81. +3 −3 sos/plugins/sar.py
  82. +2 −2 sos/plugins/selinux.py
  83. +2 −2 sos/plugins/sendmail.py
  84. +2 −2 sos/plugins/smartcard.py
  85. +2 −2 sos/plugins/snmp.py
  86. +2 −2 sos/plugins/soundcard.py
  87. +3 −3 sos/plugins/squid.py
  88. +2 −2 sos/plugins/ssh.py
  89. +2 −2 sos/plugins/sssd.py
  90. +3 −3 sos/plugins/startup.py
  91. +2 −2 sos/plugins/system.py
  92. +3 −3 sos/plugins/systemtap.py
  93. +2 −2 sos/plugins/tftpserver.py
  94. +3 −3 sos/plugins/tomcat.py
  95. +2 −2 sos/plugins/udev.py
  96. +3 −3 sos/plugins/veritas.py
  97. +3 −3 sos/plugins/vmware.py
  98. +3 −3 sos/plugins/x11.py
  99. +3 −3 sos/plugins/xen.py
  100. +2 −2 sos/plugins/xinetd.py
  101. +3 −3 sos/plugins/yum.py
  102. +0 −560 sos/plugintools.py
  103. +276 −0 sos/policies/__init__.py
  104. +13 −0 sos/policies/osx.py
  105. +229 −0 sos/policies/redhat.py
  106. +41 −0 sos/policies/windows.py
  107. +0 −411 sos/policyredhat.py
  108. +131 −0 sos/reporting.py
  109. +680 −582 sos/sosreport.py
  110. +445 −0 sos/utilities.py
  111. +3 −5 sosreport
  112. +130 −0 tests/archive_tests.py
  113. +118 −0 tests/report_tests.py
  114. +1 −0  tests/worker_link
  115. +87 −0 tools/osdetect.py
View
9 .gitignore
@@ -0,0 +1,9 @@
+*~
+*.class
+*swp*
+*.pyc
+*.sw*
+tags
+buildjar/
+gpgkeys/rhsupport.*
+rpm-build/*
View
2  AUTHORS
@@ -7,9 +7,11 @@ Keith Kearnan <kearnan_keith@emc.com>
Kent Lamb <klamb@redhat.com>
Marc Sauton <msauton@redhat.com>
Navid Sheikhol-Eslami <navid@redhat.com>
+Pierre Amadio <pamadio@redhat.com>
Pierre Carrier <pcarrier@redhat.com>
Ranjith Rajaram <rrajaram@redhat.com>
Sadique Puthen <sputhenp@redhat.com>
Shijoe George <spanjikk@redhat.com>
Steve Conklin <sconklin@redhat.com>
Tomas Smetana <tsmetana@redhat.com>
+John Berninger <jwb@redhat.com>
View
248 ChangeLog.deprecated
@@ -1,248 +0,0 @@
-2007-06-15 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * [BZ#241282] initial port to RHEL4 :) sos core now runs happily, plugins will probably need to be fixed as well.
- * Initial commit of XML reporting to gather details about commands executed and files gathered.
- * Exceptions in plugin.analyse() were not catched allowing a bad plugin to break sosreport.
-
-2007-06-15 Eugene Teo <eteo@redhat.com>
-
- * lib/sos/plugins/apache.py, lib/sos/plugins/nfsserver.py, lib/sos/plugins/selinux.py, lib/sos/plugins/xinetd.py, lib/sos/plugins/ssh.py, lib/sos/plugins/sendmail.py, lib/sos/plugins/samba.py, lib/sos/plugins/named.py, lib/sos/plugins/cluster.py:
- - Edited apache.py to gather /var/log/httpd/* log files
- - Added nfsserver.py to gather NFS server-related debugging information
- - Edited selinux.py to gather /etc/selinux/* configuration files
- - Added xinetd.py to gather xinetd-related information
- - Added ssh.py to gather ssh-related information
- - Added sendmail.py to gather sendmail information
- - Edited samba.py to gather /var/log/samba/* log files
- - Edited named.py to gather /etc/sysconfig/named
- - Edited cluster.py to gather the output of fdisk -l to show the
- shared storage devices that should be available to each system
-
-2007-05-28 Eugene Teo <eteo@redhat.com>
-
- * lib/sos/plugins/systemtap.py:
- - Added systemtap.py to gather SystemTap pre-requisites information
-
-2007-05-28 Eugene Teo <eteo@redhat.com>
-
- * lib/sos/plugins/amd.py:
- - Added amd.py to gather Amd automounter information
-
-2007-05-25 Eugene Teo <eteo@redhat.com>
-
- * lib/sos/plugins/xen.py, lib/sos/plugins/pam.py, lib/sos/plugins/memory.py:
- - Edited xen.py to determine if CPU has PAE/Intel VT/AMD-V support
- - Edited pam.py to gather configurations in /etc/security, and files
- listing of /lib/security/pam_*so
- - Edited memory.py to gather /proc/{vmstat,slabinfo}, and free -m
- output
-
-2007-04-23 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Running "multipath" without arguments might change the device-mapper maps, which we want to avoid if things are broken.
-
-2007-04-02 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Replaced xen plugin with (better) version from Chris Lalancette <clalance@redhat.com>
-
-2007-03-29 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Added a checkenabled() function which can be used to disable a plugin at run-time.
- * Disable the progress-bar if verbosity is enabled.
-
-2007-03-27 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Fixed hardware plugin to use modules.pcimap instead of deprecated pcitable.
- * Added a random suffix to sosreport tree to avoid overwriting an existing tree with same name.
- * Better logging using python's logging module.
- * Verbose logs included in sosreport (sos_logs/sos.log)
-
-2007-03-15 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Implemented a progress bar (RFE BZ#219672) which can be disabled from the command line.
- * Added check to see if the loaded module matches the copy on the file-system
-
-2007-03-14 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * fixed BZ#219877 (ncurses "Cancel" button makes sosreport exit)
-
-2007-03-07 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Allow passing multiple comma-separated plugin names to -n (--noplugin) and -o (--onlyplugin) options.
- * Added further commands' output to gather from lvm_dump
-
-
-2007-02-20 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Added a specialized plugin for device-mapper related configuration files and command outputs (device-mapper, LVM and multipath)
- * Added --onlyplugin option (-o) to selectively choose which plugins to load (complementary to existing --noplugin)
- * Exit if no valid plugin was selected (rather than building an empty sosreport).
-
-2007-02-16 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Strip out the shared secret (bindpw) from /etc/ldap.conf
- * Collect parsed configuration tree directly from ccsd (useful for troubleshooting parsing issues)
- * Scamble password information for fencing devices.
-
-2007-01-26 Navid Sheikhol-Eslami <navid@redhat.com>
-
- * Added doRegexSub() to be called in postproc() to apply a regexp substitution to files
- * Added radius plugin for freeradius data collection
- * Ask full name to prevent errors when moving the sos tree before packaging
- * Reformat tar file name is no ticket number is given
-
-2006-06-19 Steve Conklin <sconklin@tintin>
-
- * ChangeLog, LICENSE, setup.py, sos.spec:
- Added License file and bumped release
-
-2006-06-08 dlehman <dlehman@tintin>
-
- * example_plugins/example.py, example_plugins/fsusage.py, example_plugins/release.py, example_plugins/template.py, lib/sos/helpers.py, lib/sos/plugins/apache.py, lib/sos/plugins/bootloader.py, lib/sos/plugins/cluster.py, lib/sos/plugins/filesys.py, lib/sos/plugins/ftp.py, lib/sos/plugins/general.py, lib/sos/plugins/hardware.py, lib/sos/plugins/kernel.py, lib/sos/plugins/ldap.py, lib/sos/plugins/libraries.py, lib/sos/plugins/mail.py, lib/sos/plugins/memory.py, lib/sos/plugins/named.py, lib/sos/plugins/networking.py, lib/sos/plugins/pam.py, lib/sos/plugins/process.py, lib/sos/plugins/rhn.py, lib/sos/plugins/rpm.py, lib/sos/plugins/samba.py, lib/sos/plugins/selinux.py, lib/sos/plugins/squid.py, lib/sos/plugins/startup.py, lib/sos/plugins/system.py, lib/sos/plugins/tarball.py, lib/sos/plugins/x11.py, lib/sos/plugintools.py, lib/sos/policyredhat.py, setup.py, sosreport:
- - Flesh out rhn plugin to handle Proxy or Satellite
- - Add package queries to policyredhat.py (allPkgsByName, pkgByName, pkgNVRA)
- - Add policy instance to the commons dict for access from plugins
- - Use string objects' methods instead of the string module where possible
- - Remove imports of unused string module
- - Cleanup some typos, redundant initializations, &c
-
-2006-06-08 dlehman <dlehman@tintin>
-
- * example_plugins/example.py, example_plugins/fsusage.py, example_plugins/release.py, example_plugins/template.py, lib/sos/helpers.py, lib/sos/plugins/apache.py, lib/sos/plugins/bootloader.py, lib/sos/plugins/cluster.py, lib/sos/plugins/filesys.py, lib/sos/plugins/ftp.py, lib/sos/plugins/general.py, lib/sos/plugins/hardware.py, lib/sos/plugins/kernel.py, lib/sos/plugins/ldap.py, lib/sos/plugins/libraries.py, lib/sos/plugins/mail.py, lib/sos/plugins/memory.py, lib/sos/plugins/named.py, lib/sos/plugins/networking.py, lib/sos/plugins/pam.py, lib/sos/plugins/process.py, lib/sos/plugins/rhn.py, lib/sos/plugins/rpm.py, lib/sos/plugins/samba.py, lib/sos/plugins/selinux.py, lib/sos/plugins/squid.py, lib/sos/plugins/startup.py, lib/sos/plugins/system.py, lib/sos/plugins/tarball.py, lib/sos/plugins/x11.py, lib/sos/plugintools.py, lib/sos/policyredhat.py, setup.py, sosreport:
- - Flesh out rhn plugin to handle Proxy or Satellite
- - Add package queries to policyredhat.py (allPkgsByName, pkgByName, pkgNVRA)
- - Add policy instance to the commons dict for access from plugins
- - Use string objects' methods instead of the string module where possible
- - Remove imports of unused string module
- - Cleanup some typos, redundant initializations, &c
-
-2006-06-05 jwhiter <jwhiter@tintin>
-
- * lib/sos/plugins/system.py:
- adding the abilit to capture the autofs maps to system.py
-
-2006-05-31 Steve Conklin <sconklin@tintin>
-
- * ChangeLog, Makefile: New Makefile and ChangeLog (autogenerated)
-
- * Changelog, setup.py, sos.spec:
- Removed old Changelog file and sync'd version and Changelog in spec file
-
- * lib/sos/plugins/networking.py, TODO, setup.py, sos.spec:
- Final patches and version change before submission to Fedora
-
-2006-05-31 Steve Conklin <sconklin@tintin>
-
- * Changelog, setup.py, sos.spec:
- Removed old Changelog file and sync'd version and Changelog in spec file
-
- * lib/sos/plugins/networking.py, TODO, setup.py, sos.spec:
- Final patches and version change before submission to Fedora
-
-2006-05-26 Steve Conklin <sconklin@tintin>
-
- * Changelog, lib/sos/helpers.py, lib/sos/plugintools.py, setup.py, sosreport:
- Added pamadio's curses UI for selecting plugin options
- Added flushing stdout after informational messages
-
-2006-05-26 jwhiter <jwhiter@tintin>
-
- * lib/sos/plugins/filesys.py:
- - making the filesys.py plugin call 'blkid' when running at the request of L1, this will allow us to map labels with actual devices.
-
- * lib/sos/plugins/tarball.py, lib/sos/plugintools.py, sosreport:
- - Adding tarball.py to create a tarball of the report after it is run
- - Updated sosreport to call postproc() in all the plugins, which handles the post run
- - Added runExeInd() which will just run the exe and return the status to plugintools.py
- - Added postproc() to plugintools.py so that plugins can implement it
-
-2006-05-25 Steve Conklin <sconklin@tintin>
-
- * lib/sos/plugintools.py, sosreport:
- Fixed file naming for commands to eliminate special chars and prevent
- name collisions. Added sorting of plugins by name before reporting.
-
- * TODO, lib/sos/plugins/kernel.py, lib/sos/plugintools.py, setup.py:
- Fixed option handling
-
-2006-05-23 jwhiter <jwhiter@tintin>
-
- * Changelog, lib/sos/plugins/kernel.py, setup.py:
- Adding jwb's patch to have sosreport grab sysrq data.
-
-2006-05-22 Steve Conklin <sconklin@tintin>
-
- * lib/sos/plugins/apache.py: oops, forgot this file
-
- * lib/sos/plugins/bootloader.py, lib/sos/plugins/filesys.py, lib/sos/plugins/ftp.py, lib/sos/plugins/general.py, lib/sos/plugins/hardware.py, lib/sos/plugins/kernel.py, lib/sos/plugins/ldap.py, lib/sos/plugins/mail.py, lib/sos/plugins/memory.py, lib/sos/plugins/named.py, lib/sos/plugins/samba.py, lib/sos/plugins/squid.py, lib/sos/plugins/x11.py, sos.spec:
- Patch from jwb
-
- * lib/sos/plugins/filesys.py, lib/sos/plugins/kernel.py:
- jwb's patches for kernel.py and filesys.py
-
- * sosreport: minor fix to the dir perms patch
-
- * lib/sos/plugins/bootloader.py, lib/sos/plugins/cluster.py, lib/sos/plugins/filesys.py, lib/sos/plugins/general.py, lib/sos/plugins/hardware.py, lib/sos/plugins/kernel.py, lib/sos/plugins/libraries.py, lib/sos/plugins/memory.py, lib/sos/plugins/networking.py, lib/sos/plugins/pam.py, lib/sos/plugins/process.py, lib/sos/plugins/rhn.py, lib/sos/plugins/rpm.py, lib/sos/plugins/selinux.py, lib/sos/plugins/startup.py, lib/sos/plugins/system.py, lib/sos/plugins/template.py, lib/sos/plugins/x11.py, Changelog, example_plugins/template.py, lib/sos/plugintools.py, setup.py, sosreport:
- Merged all of jwb's weekend patches. Make output dirs world readable, check before
- executing executables, and added a lot of plugins.
-
-2006-05-19 Steve Conklin <sconklin@tintin>
-
- * lib/sos/plugins/template.py: Removed unneeded variabled from plugin.
-
- * Changelog, TODO, example_plugins/example.py, example_plugins/fsusage.py, example_plugins/release.py, example_plugins/runcommand.py, lib/sos/plugins/template.py, lib/sos/plugintools.py, setup.py, sosreport:
- Applied jwb's fix, added his examples, improved html output
-
-2006-05-18 Steve Conklin <sconklin@tintin>
-
- * example_plugins/example.py, example_plugins/runcommand.py, lib/sos/plugins/template.py:
- Put instance variables in plugins in addition to base class
-
- * example_plugins/example.py, example_plugins/runcommand.py, lib/sos/plugins/template.py, lib/sos/plugintools.py, setup.py, sosreport:
- Removed separate pit class, and put everything having to do with the plugin in
- pluginBase. Still incorrectly aggregates data across all plugins.
-
- * README: Added Jwb as a contributor
-
- * Changelog, TODO, lib/sos/plugins/template.py, lib/sos/plugintools.py, sosreport:
- Implemented a base class for plugins
-
-2006-05-17 Steve Conklin <sconklin@tintin>
-
- * Changelog, TODO, lib/sos/helpers.py, lib/sos/plugins/template.py, lib/sos/plugintools.py, sosreport, tests/maketesttree.sh:
- Cleaned up code, added comments, fixed dir copying bug, changed option
- handling. See Changelog
-
-2006-05-16 Steve Conklin <sconklin@tintin>
-
- * lib/sos/helpers.py, lib/sos/plugintools.py:
- Missed an edit to change log file descriptor to the dictionary. Fixed.
-
- * TODO: Added documentation to list
-
- * TODO: Added need for example plugin
-
-2006-05-15 Steve Conklin <sconklin@tintin>
-
- * README, TODO, lib/sos/plugins/template.py, lib/sos/plugintools.py, setup.py, sosreport:
- Added a dictionary of things that need to be known to all, like paths for
- reports.
-
- Added Pierre Amadio's command line arg handling
-
- Fixed incorrect handling of command completion status
-
- Added html generation
-
-2006-05-09 Steve Conklin <sconklin@tintin>
-
- * TODO: changed it
-
- * setup.cfg: removed RFC file
-
- * MANIFEST.in, Notes.txt, README, TODO, lib/sos/__init__.py, lib/sos/helpers.py, lib/sos/plugins/__init__.py, lib/sos/plugins/template.py, lib/sos/plugintools.py, lib/sos/policyredhat.py, setup.cfg, setup.py, sosreport:
- Initial checkin of the sos project
-
- * MANIFEST.in, Notes.txt, README, TODO, lib/sos/__init__.py, lib/sos/helpers.py, lib/sos/plugins/__init__.py, lib/sos/plugins/template.py, lib/sos/plugintools.py, lib/sos/policyredhat.py, setup.cfg, setup.py, sosreport:
- New file.
-
View
44 Makefile
@@ -9,6 +9,10 @@ REPO = http://svn.fedorahosted.org/svn/sos
SUBDIRS = po sos sos/plugins
PYFILES = $(wildcard *.py)
+# OS X via brew
+# MSGCAT = /usr/local/Cellar/gettext/0.18.1.1/bin/msgcat
+MSGCAT = msgcat
+
RPM_BUILD_DIR = rpm-build
RPM_DEFINES = --define "_topdir %(pwd)/$(RPM_BUILD_DIR)" \
@@ -19,6 +23,12 @@ RPM_DEFINES = --define "_topdir %(pwd)/$(RPM_BUILD_DIR)" \
--define "_sourcedir %{_topdir}"
RPM = rpmbuild
RPM_WITH_DIRS = $(RPM) $(RPM_DEFINES)
+ARCHIVE_DIR = $(RPM_BUILD_DIR)/$(NAME)-$(VERSION)
+
+ARCHIVE_NAME = sosreport.zip
+SRC_BUILD = $(RPM_BUILD_DIR)/sdist
+PO_DIR = $(SRC_BUILD)/sos/po
+ZIP_DEST = $(SRC_BUILD)/$(ARCHIVE_NAME)
build:
for d in $(SUBDIRS); do make -C $$d; [ $$? = 0 ] || exit 1 ; done
@@ -37,14 +47,14 @@ install:
install -m644 LICENSE README TODO $(DESTDIR)/usr/share/$(NAME)/.
install -m644 $(NAME).conf $(DESTDIR)/etc/$(NAME).conf
install -m644 gpgkeys/rhsupport.pub $(DESTDIR)/usr/share/$(NAME)/.
- sed 's/@SOSVERSION@/$(VERSION)/g'<sos/__init__.py.in >sos/__init__.py
+ sed 's/@SOSVERSION@/$(VERSION)/g' < sos/__init__.py > sos/__init__.py
for d in $(SUBDIRS); do make DESTDIR=`cd $(DESTDIR); pwd` -C $$d install; [ $$? = 0 ] || exit 1; done
$(NAME)-$(VERSION).tar.gz: clean gpgkey
- @mkdir -p $(RPM_BUILD_DIR)
- @svn export --force $(PWD) $(RPM_BUILD_DIR)/$(NAME)-$(VERSION)
- @mkdir -p $(RPM_BUILD_DIR)/$(NAME)-$(VERSION)/gpgkeys
- @cp gpgkeys/rhsupport.pub $(RPM_BUILD_DIR)/$(NAME)-$(VERSION)/gpgkeys/.
+ @mkdir -p $(ARCHIVE_DIR)
+ @tar -cv sosreport sos doc man po sos.conf TODO LICENSE README sos.spec Makefile | tar -x -C $(ARCHIVE_DIR)
+ @mkdir -p $(ARCHIVE_DIR)/gpgkeys
+ @cp gpgkeys/rhsupport.pub $(ARCHIVE_DIR)/gpgkeys/.
@tar Ccvzf $(RPM_BUILD_DIR) $(RPM_BUILD_DIR)/$(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION)
clean:
@@ -65,3 +75,27 @@ gpgkey:
@echo "Building gpg key"
@test -f gpgkeys/rhsupport.pub && echo "GPG key already exists." || \
gpg --batch --gen-key gpgkeys/gpg.template
+
+po: clean
+ mkdir -p $(PO_DIR)
+ for po in `ls po/*.po`; do \
+ $(MSGCAT) -p -o $(PO_DIR)/$$(basename $$po | awk -F. '{print $$1}').properties $$po; \
+ done; \
+
+ cp $(PO_DIR)/en.properties $(PO_DIR)/en_US.properties
+
+eap6: po
+ cp -r sos/* $(SRC_BUILD)/sos/
+ find $(SRC_BUILD)/sos/plugins/ -not -name "*eap6.py" -not -name "*__init__.py" -type f -delete
+
+zip: po
+ zip -r $(ZIP_DEST) sos
+ zip -r $(ZIP_DEST) __run__.py
+ cd $(SRC_BUILD) && zip -r $(ARCHIVE_NAME) sos
+ cd $(SRC_BUILD) && rm -rf sos
+
+test:
+ @for test in `ls tests/*test*.py`; do \
+ echo $$test; \
+ PYTHONPATH=`pwd` python $$test; \
+ done; \
View
36 README
@@ -1,35 +1,15 @@
-This set of tools is designed to provide information to support
-organizations in an extensible manner, allowing third parties,
-package maintainers, and anyone else to provide plugins that will
-collect, analyze, and report information that is useful for supporting
-software packages.
+This set of tools is designed to provide information to support organizations
+in an extensible manner, allowing third parties, 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://fedorahosted.org/sos
-For the latest version, to contribute, and for more information, please visit there.
+This project is hosted at http://github.com/sosreport/sosreport 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:
- svn export http://svn.fedorahosted.org/svn/sos/trunk sos --username guest
+ git clone git://github.com/sosreport/sosreport.git
to install locally (as root) ==> make install
to build an rpm ==> make rpm
-
-See the Makefile.
-
-Maintainer:
-
- Adam Stokes <ajs@redhat.com>
-
-Developers and Contributors:
-
- Steve Conklin <sconklin@redhat.com>
- Pierre Amadio <pamadio@redhat.com>
- John Berninger <jwb@redhat.com>
- Navid Sheikhol-Eslami <navid at redhat dot 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
+to build a zipfile for use with jython ==> make zip
View
17 __run__.py
@@ -0,0 +1,17 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+from sos.sosreport import main
+import sys
+
+main(sys.argv[1:])
View
2  sos.spec
@@ -46,7 +46,7 @@ rm -rf ${RPM_BUILD_ROOT}
%{python_sitelib}/*
%{_mandir}/man1/*
%{_mandir}/man5/*
-%doc README TODO LICENSE ChangeLog doc/*
+%doc README TODO LICENSE doc/*
%config(noreplace) %{_sysconfdir}/sos.conf
%changelog
View
25 sos/__init__.py.in → sos/__init__.py
@@ -15,13 +15,24 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import gettext
+__version__ = "@SOSVERSION@"
-gettext_dir = "/usr/share/locale"
-gettext_app = "sos"
+try:
+ from java.util import ResourceBundle
-gettext.bindtextdomain(gettext_app, gettext_dir)
+ rb = ResourceBundle.getBundle("sos.po.sos")
-__version__="@SOSVERSION@"
-def _sos(msg):
- return gettext.dgettext(gettext_app, msg)
+ def _sos(msg):
+ try:
+ return rb.getString(msg).encode('utf-8')
+ except:
+ return msg
+except:
+ import gettext
+ gettext_dir = "/usr/share/locale"
+ gettext_app = "sos"
+
+ gettext.bindtextdomain(gettext_app, gettext_dir)
+
+ def _sos(msg):
+ return gettext.dgettext(gettext_app, msg)
View
79 sos/helpers.py
@@ -1,79 +0,0 @@
-## helpers.py
-## Implement policies required for the sos system support tool
-
-## Copyright (C) 2006 Steve Conklin <sconklin@redhat.com>
-
-### This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-## Some code adapted from "Python Cookbook, 2nd ed", by Alex
-## Martelli, Anna Martelli Ravenscroft, and David Ascher
-## (O'Reilly Media, 2005) 0-596-00797-3
-##
-
-"""
-helper functions used by sosreport and plugins
-"""
-import os, sys
-import logging
-from subprocess import Popen, PIPE
-
-def importPlugin(pluginname, name):
- """ Import a plugin to extend capabilities of sosreport
- """
- try:
- plugin = __import__(pluginname, globals(), locals(), [name])
- except ImportError:
- return None
- return getattr(plugin, name)
-
-def sosGetCommandOutput(command, timeout = 300):
- """ 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)
-
- p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, bufsize=-1)
- stdout, stderr = p.communicate()
- return (p.returncode, stdout.strip(), 0)
-
-def commonPrefix(l1, l2, common = []):
- ''' 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]])
-
-def sosRelPath(path1, path2, sep=os.path.sep, pardir=os.path.pardir):
- ''' return a relative path from path1 equivalent to path path2.
- In particular: the empty string, if path1 == path2;
- path2, if path1 and path2 have no common prefix.
- '''
- try:
- common, (u1, u2) = commonPrefix(path1.split(sep), path2.split(sep))
- except AttributeError:
- return path2
-
- if not common:
- return path2 # leave path absolute if nothing at all in common
- return sep.join( [pardir]*len(u1) + u2 )
-
View
615 sos/plugins/__init__.py
@@ -0,0 +1,615 @@
+## This exports methods available for use by plugins for sos
+
+## Copyright (C) 2006 Steve Conklin <sconklin@redhat.com>
+
+### This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# pylint: disable-msg = R0902
+# pylint: disable-msg = R0904
+# pylint: disable-msg = W0702
+# pylint: disable-msg = W0703
+# pylint: disable-msg = R0201
+# pylint: disable-msg = W0611
+# pylint: disable-msg = W0613
+
+from sos.utilities import sosGetCommandOutput, import_module
+from sos import _sos as _
+import inspect
+import os
+import sys
+import string
+import glob
+import re
+import traceback
+import shutil
+from stat import *
+from time import time
+from itertools import *
+from collections import deque
+import logging
+
+
+def commonPrefix(l1, l2, common = None):
+ """
+ Returns a tuple like the following:
+ ([common, elements, from l1, and l2], [[tails, from, l1], [tails, from, l2]])
+
+ >>> commonPrefix(['usr','share','foo'], ['usr','share','bar'])
+ (['usr','share'], [['foo'], ['bar']])
+ """
+ if common is None:
+ common = []
+ 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]])
+
+def sosRelPath(path1, path2, sep=os.path.sep, pardir=os.path.pardir):
+ ''' return a relative path from path1 equivalent to path path2.
+ In particular: the empty string, if path1 == path2;
+ path2, if path1 and path2 have no common prefix.
+ '''
+ try:
+ common, (u1, u2) = commonPrefix(path1.split(sep), path2.split(sep))
+ except AttributeError:
+ return path2
+
+ if not common:
+ return path2 # leave path absolute if nothing at all in common
+ return sep.join( [pardir]*len(u1) + u2 )
+
+
+class PluginException(Exception):
+ pass
+
+
+class Plugin(object):
+ """
+ This is the base class for sosreport plugins. This class should
+ be subclassed by platform specific superclasses. Actual plugins
+ should not subclass this class directly.
+ """
+
+ requires_root = True
+ version = 'unversioned'
+
+ def __init__(self, commons):
+ if not getattr(self, "optionList", False):
+ self.optionList = deque()
+
+ self.copiedFiles = deque()
+ self.executedCommands = deque()
+ self.diagnose_msgs = deque()
+ self.alerts = deque()
+ self.customText = ""
+ self.optNames = deque()
+ self.optParms = deque()
+ self.cInfo = commons
+ self.forbiddenPaths = deque()
+ self.copyPaths = deque()
+ self.copyStrings = deque()
+ self.collectProgs = deque()
+
+ self.packages = deque()
+ self.files = deque()
+
+ self.must_exit = False
+
+ self.soslog = logging.getLogger('sos')
+ self.proflog = logging.getLogger('sosprofile')
+
+ # get the option list into a dictionary
+ for opt in self.optionList:
+ self.optNames.append(opt[0])
+ self.optParms.append({'desc':opt[1], 'speed':opt[2], 'enabled':opt[3]})
+
+ @classmethod
+ def name(class_):
+ "Returns the plugin's name as a string"
+ return class_.__name__.lower()
+
+ def setArchive(self, archive):
+ self.archive = archive
+
+ def policy(self):
+ return self.cInfo["policy"]
+
+ def isInstalled(self, package_name):
+ '''Is the package $package_name installed?
+ '''
+ return (self.policy().pkgByName(package_name) is not None)
+
+ def doRegexSub(self, srcpath, regexp, subst):
+ '''Apply a regexp substitution to a file archived by sosreport.
+ srcpath is the path in the archive where the file can be found.
+ regexp can be a regexp string or a compiled re object.
+ subst is a string to replace each occurance of regexp in the content
+ of srcpath.
+
+ This function returns the number of replacements made.
+ '''
+ try:
+ path = self._get_dest_for_srcpath(srcpath)
+ if not path:
+ return 0
+ readable = self.archive.open_file(path)
+ result, replacements = re.subn(regexp, subst, readable.read())
+ if replacements:
+ self.archive.add_string(result, srcpath)
+ return replacements
+ else:
+ return 0
+ except Exception:
+ return 0
+
+ def doRegexFindAll(self, regex, fname):
+ ''' Return a list of all non overlapping matches in the string(s)
+ '''
+ try:
+ return re.findall(regex, open(fname, 'r').read(), re.MULTILINE)
+ except: # IOError, AttributeError, etc.
+ return []
+
+ def _path_in_path_list(self, path, path_list):
+ for p in path_list:
+ if p in path:
+ return True
+ return False
+
+ def copy_symlink(self, srcpath, sub=None):
+ link = os.readlink(srcpath)
+ if not os.path.isabs(link):
+ link = os.path.normpath(
+ os.path.join(
+ os.path.dirname(srcpath),
+ link)
+ )
+
+ if os.path.isdir(link):
+ self.soslog.debug("link %s is a directory, skipping..." % link)
+ return
+
+ dest = link
+
+ if sub:
+ old, new = sub
+ dest = srcpath.replace(old, new)
+
+ self.archive.add_file(link, dest=dest)
+
+ self.copiedFiles.append({
+ 'srcpath':srcpath,
+ 'dstpath':dest,
+ 'symlink':"yes",
+ 'pointsto':link})
+
+ def copy_dir(self, srcpath, sub=None):
+ for afile in os.listdir(srcpath):
+ self.doCopyFileOrDir(os.path.join(srcpath, afile), dest=None, sub=sub)
+
+ def _get_dest_for_srcpath(self, srcpath):
+ for copied in self.copiedFiles:
+ if srcpath == copied["srcpath"]:
+ return copied["dstpath"]
+ return None
+
+ # Methods for copying files and shelling out
+ def doCopyFileOrDir(self, srcpath, dest=None, sub=None):
+ # pylint: disable-msg = R0912
+ # pylint: disable-msg = R0915
+ '''
+ Copy file or directory to the destination tree. If a directory,
+ then everything below it is recursively copied. A list of copied files
+ are saved for use later in preparing a report. sub can be used to
+ rename the destination of the file, sub should be a two-tuple of
+ (old,new). For example if you passed in ("etc","configurations") for
+ use against /etc/my_file.conf the file would end up at
+ /configurations/my_file.conf.
+ '''
+
+ if self.cInfo['cmdlineopts'].profiler:
+ start_time = time()
+
+ if self._path_in_path_list(srcpath, self.forbiddenPaths):
+ self.soslog.debug("%s is in the forbidden path list" % srcpath)
+ return ''
+
+ if not os.path.exists(srcpath):
+ self.soslog.debug("file or directory %s does not exist" % srcpath)
+ return
+
+ if not dest:
+ dest = srcpath
+
+ if sub:
+ old, new = sub
+ dest = srcpath.replace(old, new)
+
+ if os.path.islink(srcpath):
+ self.copy_symlink(srcpath, sub=sub)
+ return
+ else:
+ if os.path.isdir(srcpath):
+ self.copy_dir(srcpath, sub=sub)
+ return
+
+ # if we get here, it's definitely a regular file (not a symlink or dir)
+ self.soslog.debug("copying file %s to %s" % (srcpath,dest))
+
+ try:
+ self.archive.add_file(srcpath, dest)
+
+ self.copiedFiles.append({
+ 'srcpath':srcpath,
+ 'dstpath':dest,
+ 'symlink':"no"})
+
+ if self.cInfo['cmdlineopts'].profiler:
+ time_passed = time() - start_time
+ self.proflog.debug("copied: %-75s time: %f" % (srcpath, time_passed))
+ except Exception, e:
+ self.soslog.debug(traceback.format_exc())
+
+
+ def addForbiddenPath(self, forbiddenPath):
+ """Specify a path to not copy, even if it's part of a copyPaths[] entry.
+ """
+ # Glob case handling is such that a valid non-glob is a reduced glob
+ for filespec in glob.glob(forbiddenPath):
+ self.forbiddenPaths.append(filespec)
+
+ def getAllOptions(self):
+ """
+ return a list of all options selected
+ """
+ return (self.optNames, self.optParms)
+
+ def setOption(self, optionname, value):
+ ''' set the named option to value.
+ '''
+ for name, parms in izip(self.optNames, self.optParms):
+ if name == optionname:
+ parms['enabled'] = value
+ return True
+ else:
+ return False
+
+ def isOptionEnabled(self, optionname):
+ ''' Deprecated, use getOption() instead
+ '''
+ return self.getOption(optionname)
+
+ def getOption(self, optionname, default=0):
+ """Returns the first value that matches 'optionname' in parameters
+ passed in via the command line or set via set_option or via the
+ global_plugin_options dictionary, in that order.
+
+ optionaname may be iterable, in which case the first option that matches
+ any of the option names is returned."""
+
+ def _check(key):
+ if hasattr(key, "__iter__"):
+ return key in optionname
+ else:
+ return key == optionname
+
+ for name, parms in izip(self.optNames, self.optParms):
+ if _check(name):
+ return parms['enabled']
+
+ for key, value in self.cInfo.get('global_plugin_options', {}).iteritems():
+ if _check(key):
+ return value
+
+ return default
+
+ def getOptionAsList(self, optionname, delimiter=",", default=None):
+ '''Will try to return the option as a list separated by the delimiter'''
+ option = self.getOption(optionname)
+ try:
+ opt_list = [opt.strip() for opt in option.split(delimiter)]
+ return filter(None, opt_list)
+ except Exception:
+ return default
+
+ def addCopySpecLimit(self, fname, sizelimit=None, sub=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
+ limit_reached = False
+ sizelimit *= 1024 * 1024 # in MB
+ for flog in files:
+ cursize += os.stat(flog)[ST_SIZE]
+ if sizelimit and cursize > sizelimit:
+ limit_reached = True
+ break
+ self.addCopySpec(flog, sub)
+ # Truncate the first file (others would likely be compressed),
+ # ensuring we get at least some logs
+ # FIXME: figure this out for jython
+ if flog == files[0] and limit_reached:
+ self.collectExtOutput("tail -c%d %s" % (sizelimit, flog),
+ "tail_" + os.path.basename(flog), flog[1:] + ".tailed")
+
+ def addCopySpecs(self, copyspecs, sub=None):
+ for copyspec in copyspecs:
+ self.addCopySpec(copyspec, sub)
+
+ def addCopySpec(self, copyspec, sub=None):
+ """ 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):
+ if filespec not in self.copyPaths:
+ self.copyPaths.append((filespec, sub))
+
+ def callExtProg(self, prog):
+ """ Execute a command independantly of the output gathering part of
+ sosreport
+ """
+ # pylint: disable-msg = W0612
+ status, shout, runtime = sosGetCommandOutput(prog)
+ return (status, shout, runtime)
+
+ def checkExtprog(self, prog):
+ """ Execute a command independently of the output gathering part of
+ sosreport and check the return code. Return True for a return code of 0
+ and False otherwise."""
+ (status, output, runtime) = self.callExtProg(prog)
+ return (status == 0)
+
+
+ def collectExtOutput(self, exe, suggest_filename = None, root_symlink = None, timeout = 300):
+ """
+ Run a program and collect the output
+ """
+ self.collectProgs.append( (exe, suggest_filename, root_symlink, timeout) )
+
+ def fileGrep(self, regexp, fname):
+ try:
+ return [l for l in open(fname).readlines() if re.match(regexp, l)]
+ except: # IOError, AttributeError, etc.
+ return []
+
+ def mangleCommand(self, exe):
+ # FIXME: this can be improved
+ mangledname = re.sub(r"^/(usr/|)(bin|sbin)/", "", exe)
+ mangledname = re.sub(r"[^\w\-\.\/]+", "_", mangledname)
+ mangledname = re.sub(r"/", ".", mangledname).strip(" ._-")[0:64]
+ return mangledname
+
+ def makeCommandFilename(self, exe):
+ """ The internal function to build up a filename based on a command """
+
+ outfn = os.path.join(self.cInfo['cmddir'], self.name(), self.mangleCommand(exe))
+
+ # check for collisions
+ if os.path.exists(outfn):
+ inc = 2
+ while True:
+ newfn = "%s_%d" % (outfn, inc)
+ if not os.path.exists(newfn):
+ outfn = newfn
+ break
+ inc +=1
+
+ return outfn
+
+ def addStringAsFile(self, content, filename):
+ """Add a string to the archive as a file named `filename`"""
+ self.copyStrings.append((content, filename))
+
+ def collectOutputNow(self, exe, suggest_filename=None, root_symlink=False, timeout=300):
+ """ Execute a command and save the output to a file for inclusion in
+ the report
+ """
+ if self.cInfo['cmdlineopts'].profiler:
+ start_time = time()
+
+ # pylint: disable-msg = W0612
+ status, shout, runtime = sosGetCommandOutput(exe, timeout=timeout)
+
+ if suggest_filename:
+ outfn = self.makeCommandFilename(suggest_filename)
+ else:
+ outfn = self.makeCommandFilename(exe)
+
+ if not (status == 127 or status == 32512): # if not command_not_found
+ outfn_strip = outfn[len(self.cInfo['cmddir'])+1:]
+ self.archive.add_string(shout, outfn)
+ else:
+ self.soslog.debug("could not run command: %s" % exe)
+ outfn = None
+ outfn_strip = None
+
+ # save info for later
+ self.executedCommands.append({'exe': exe, 'file':outfn_strip}) # save in our list
+ self.cInfo['xmlreport'].add_command(cmdline=exe,exitcode=status,f_stdout=outfn_strip,runtime=runtime)
+
+ if self.cInfo['cmdlineopts'].profiler:
+ time_passed = time() - start_time
+ self.proflog.debug("output: %-75s time: %f" % (exe, time_passed))
+
+ return outfn
+
+ # For adding warning messages regarding configuration sanity
+ def addDiagnose(self, alertstring):
+ """ Add a configuration sanity warning for this plugin. These
+ will be displayed on-screen before collection and in the report as well.
+ """
+ self.diagnose_msgs.append(alertstring)
+
+ # For adding output
+ def addAlert(self, alertstring):
+ """ Add an alert to the collection of alerts for this plugin. These
+ will be displayed in the report
+ """
+ self.alerts.append(alertstring)
+
+ def addCustomText(self, text):
+ """ Append text to the custom text that is included in the report. This
+ is freeform and can include html.
+ """
+ self.customText += text
+
+ def copyStuff(self):
+ """
+ Collect the data for a plugin
+ """
+ for path, sub in self.copyPaths:
+ self.doCopyFileOrDir(path, sub=sub)
+
+ for string, file_name in self.copyStrings:
+ try:
+ self.archive.add_string(string,
+ os.path.join('sos_strings', self.name(), file_name))
+ except Exception, e:
+ self.soslog.debug("could not create %s, traceback follows: %s" % (file_name, e))
+
+ for progs in izip(self.collectProgs):
+ prog, suggest_filename, root_symlink, timeout = progs[0]
+ # self.soslog.debug("collecting output of '%s'" % prog)
+ try:
+ self.collectOutputNow(prog, suggest_filename, root_symlink, timeout)
+ except Exception, e:
+ self.soslog.debug("error collection output of '%s', traceback follows: %s" % (prog, e))
+
+ def exit_please(self):
+ """ This function tells the plugin that it should exit ASAP"""
+ self.must_exit = True
+
+ def get_description(self):
+ """ This function will return the description for the plugin"""
+ try:
+ return self.__doc__.strip()
+ except:
+ return "<no description available>"
+
+ def checkenabled(self):
+ """ This function can be overidden to let the plugin decide whether
+ it should run or not.
+ """
+ # 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.isInstalled(pkgname):
+ return True
+ return False
+
+ return True
+
+ def defaultenabled(self):
+ """This devices whether a plugin should be automatically loaded or
+ only if manually specified in the command line."""
+ return True
+
+ def diagnose(self):
+ """This method must be overridden to check the sanity of the system's
+ configuration before the collection begins.
+ """
+ pass
+
+ def setup(self):
+ """This method must be overridden to add the copyPaths, forbiddenPaths,
+ and external programs to be collected at a minimum.
+ """
+ pass
+
+ def analyze(self):
+ """
+ perform any analysis. To be replaced by a plugin if desired
+ """
+ pass
+
+ def postproc(self):
+ """
+ perform any postprocessing. To be replaced by a plugin if desired
+ """
+ pass
+
+ def report(self):
+ """ Present all information that was gathered in an html file that allows browsing
+ the results.
+ """
+ # make this prettier
+ html = '<hr/><a name="%s"></a>\n' % self.name()
+
+ # Intro
+ html = html + "<h2> Plugin <em>" + self.name() + "</em></h2>\n"
+
+ # Files
+ if len(self.copiedFiles):
+ html = html + "<p>Files copied:<br><ul>\n"
+ for afile in self.copiedFiles:
+ html = html + '<li><a href="%s">%s</a>' % (afile['dstpath'], afile['srcpath'])
+ if (afile['symlink'] == "yes"):
+ html = html + " (symlink to %s)" % afile['pointsto']
+ html = html + '</li>\n'
+ html = html + "</ul></p>\n"
+
+ # Command Output
+ if len(self.executedCommands):
+ html = html + "<p>Commands Executed:<br><ul>\n"
+ # convert file name to relative path from our root
+ for cmd in self.executedCommands:
+ 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
+ if len(self.alerts):
+ html = html + "<p>Alerts:<br><ul>\n"
+ for alert in self.alerts:
+ html = html + '<li>%s</li>\n' % alert
+ html = html + "</ul></p>\n"
+
+ # Custom Text
+ if (self.customText != ""):
+ html = html + "<p>Additional Information:<br>\n"
+ html = html + self.customText + "</p>\n"
+
+ return html
+
+
+class RedHatPlugin(object):
+ """Tagging class to indicate that this plugin works with Red Hat Linux"""
+ pass
+
+class IndependentPlugin(object):
+ """Tagging class that indicates this plugin can run on any platform"""
+ pass
+
+def import_plugin(name):
+ """Import name as a module and return a list of all classes defined in that
+ module"""
+ try:
+ plugin_fqname = "sos.plugins.%s" % name
+ return import_module(plugin_fqname, superclass=Plugin)
+ except ImportError, e:
+ return None
View
6 sos/plugins/abrt.py
@@ -14,10 +14,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
from os.path import exists
-class abrt(sos.plugintools.PluginBase):
+class abrt(Plugin, RedHatPlugin):
"""ABRT log dump
"""
@@ -26,7 +26,7 @@ class abrt(sos.plugintools.PluginBase):
def checkenabled(self):
return self.isInstalled("abrt-cli") or \
exists("/var/spool/abrt")
-
+
def do_backtraces(self):
ret, output, rtime = self.callExtProg('/usr/bin/sqlite3 /var/spool/abrt/abrt-db \'select UUID from abrt_v4\'')
try:
View
4 sos/plugins/acpid.py
@@ -12,9 +12,9 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
-class acpid(sos.plugintools.PluginBase):
+class acpid(Plugin, RedHatPlugin):
"""acpid related information
"""
def setup(self):
View
4 sos/plugins/amd.py
@@ -14,10 +14,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
from os.path import exists
-class amd(sos.plugintools.PluginBase):
+class amd(Plugin, RedHatPlugin):
"""Amd automounter information
"""
View
4 sos/plugins/anaconda.py
@@ -12,10 +12,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
from os.path import exists
-class anaconda(sos.plugintools.PluginBase):
+class anaconda(Plugin, RedHatPlugin):
"""Anaconda / Installation information
"""
def checkenabled(self):
View
6 sos/plugins/apache.py
@@ -12,13 +12,13 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
-class apache(sos.plugintools.PluginBase):
+class apache(Plugin, RedHatPlugin):
"""Apache related information
"""
optionList = [("log", "gathers all apache logs", "slow", False)]
-
+
def setup(self):
self.addCopySpecs([
"/etc/httpd/conf/httpd.conf",
View
4 sos/plugins/auditd.py
@@ -12,9 +12,9 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
-class auditd(sos.plugintools.PluginBase):
+class auditd(Plugin, RedHatPlugin):
"""Auditd related information
"""
View
12 sos/plugins/autofs.py
@@ -14,17 +14,17 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
import os, re
-class autofs(sos.plugintools.PluginBase):
+class autofs(Plugin, RedHatPlugin):
"""autofs server-related information
"""
def checkenabled(self):
self.packages = [ "autofs" ]
self.files = [ "/etc/sysconfig/autofs" ]
- return sos.plugintools.PluginBase.checkenabled(self)
-
+ return Plugin.checkenabled(self)
+
def checkdebug(self):
""" testing if autofs debug has been enabled anywhere
"""
@@ -35,14 +35,14 @@ def checkdebug(self):
if opt2 in ("--debug", "debug"):
return True
return False
-
+
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.collectExtOutput("/bin/rpm -qV autofs")
View
4 sos/plugins/bootloader.py
@@ -12,9 +12,9 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
-class bootloader(sos.plugintools.PluginBase):
+class bootloader(Plugin, RedHatPlugin):
"""Bootloader information
"""
def setup(self):
View
12 sos/plugins/cluster.py
@@ -12,11 +12,11 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
import os, re
from glob import glob
-class cluster(sos.plugintools.PluginBase):
+class cluster(Plugin, RedHatPlugin):
"""cluster suite and GFS related information
"""
@@ -26,7 +26,7 @@ class cluster(sos.plugintools.PluginBase):
def checkenabled(self):
rhelver = self.policy().rhelVersion()
if rhelver == 4:
- self.packages = [ "ccs", "cman", "cman-kernel", "magma", "magma-plugins",
+ self.packages = [ "ccs", "cman", "cman-kernel", "magma", "magma-plugins",
"rgmanager", "fence", "dlm", "dlm-kernel", "gulm",
"GFS", "GFS-kernel", "lvm2-cluster" ]
elif rhelver == 5:
@@ -38,7 +38,7 @@ def checkenabled(self):
"cman", "clusterlib", "fence-agents" ]
self.files = [ "/etc/cluster/cluster.conf" ]
- return sos.plugintools.PluginBase.checkenabled(self)
+ return Plugin.checkenabled(self)
def setup(self):
rhelver = self.policy().rhelVersion()
@@ -76,10 +76,10 @@ def setup(self):
if rhelver is 4:
self.addCopySpec("/proc/cluster/*")
self.collectExtOutput("cman_tool nodes")
-
+
if rhelver is not 4: # 5+
self.collectExtOutput("cman_tool -a nodes")
-
+
if rhelver is 5:
self.collectExtOutput("group_tool -v")
self.collectExtOutput("group_tool dump fence")
View
6 sos/plugins/cobbler.py
@@ -12,9 +12,9 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
-class cobbler(sos.plugintools.PluginBase):
+class cobbler(Plugin, RedHatPlugin):
"""cobbler related information
"""
def checkenabled(self):
@@ -23,5 +23,5 @@ def checkenabled(self):
def setup(self):
self.addCopySpec("/etc/cobbler")
self.addCopySpec("/var/log/cobbler")
- self.addCopySpec("/var/lib/rhn/kickstarts")
+ self.addCopySpec("/var/lib/rhn/kickstarts")
self.addCopySpec("/var/lib/cobbler")
View
8 sos/plugins/corosync.py
@@ -12,18 +12,16 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
-import os, re
-import time, libxml2
+from sos.plugins import Plugin, RedHatPlugin
-class corosync(sos.plugintools.PluginBase):
+class corosync(Plugin, RedHatPlugin):
""" corosync information
"""
def checkenabled(self):
self.files = ['/usr/sbin/corosync']
self.packages = ['corosync']
- return sos.plugintools.PluginBase.checkenabled(self)
+ return Plugin.checkenabled(self)
def setup(self):
self.addCopySpecs([
View
4 sos/plugins/crontab.py
@@ -12,10 +12,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
import os
-class crontab(sos.plugintools.PluginBase):
+class crontab(Plugin, RedHatPlugin):
"""Crontab information
"""
def setup(self):
View
4 sos/plugins/cs.py
@@ -16,11 +16,11 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
from os.path import exists
from glob import glob
-class cs(sos.plugintools.PluginBase):
+class cs(Plugin, RedHatPlugin):
"""Red Hat Certificate System 7.1, 7.3, 8.0 and dogtag related information
"""
View
5 sos/plugins/devicemapper.py
@@ -12,11 +12,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
import os
-from sos.helpers import sosGetCommandOutput
+from sos.plugins import Plugin, RedHatPlugin
-class devicemapper(sos.plugintools.PluginBase):
+class devicemapper(Plugin, RedHatPlugin):
"""device-mapper related information (dm, lvm, multipath)
"""
View
8 sos/plugins/dhcp.py
@@ -12,16 +12,16 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
-class dhcp(sos.plugintools.PluginBase):
+class dhcp(Plugin, RedHatPlugin):
"""DHCP related information
"""
def checkenabled(self):
self.files = ['/etc/rc.d/init.d/dhcpd']
self.packages = ['dhcp']
- return sos.plugintools.PluginBase.checkenabled(self)
-
+ return Plugin.checkenabled(self)
+
def setup(self):
self.addCopySpecs([
"/etc/dhcpd.conf",
View
4 sos/plugins/dovecot.py
@@ -12,10 +12,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
import os
-class dovecot(sos.plugintools.PluginBase):
+class dovecot(Plugin, RedHatPlugin):
"""dovecot server related information
"""
def setup(self):
View
4 sos/plugins/ds.py
@@ -14,10 +14,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
import os
-class ds(sos.plugintools.PluginBase):
+class ds(Plugin, RedHatPlugin):
"""Directory Server information
"""
View
339 sos/plugins/eap6.py
@@ -0,0 +1,339 @@
+import os
+import re
+import zipfile
+import urllib2
+
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+from sos.plugins import Plugin, IndependentPlugin
+from sos.utilities import DirTree, find, checksum
+
+class Request(object):
+
+ def __init__(self, resource, operation="read-resource", parameters=None):
+ self.resource = resource
+ self.operation = operation
+ if parameters:
+ self.parameters = parameters
+ else:
+ self.parameters = {}
+
+ def url_parts(self):
+ """Generator function to split a url into (key, value) tuples. The url
+ should contain an even number of pairs. In the case of / the generator
+ will immediately stop iteration."""
+ parts = self.resource.strip("/").split("/")
+
+ if parts == ['']:
+ raise StopIteration
+
+ while parts:
+ yield (parts.pop(0), parts.pop(0))
+
+
+class EAP6(Plugin, IndependentPlugin):
+ """JBoss related information
+ """
+
+ requires_root = False
+
+ version = "1.0"
+
+ optionList = [
+ ("home", "JBoss's installation dir (i.e. JBOSS_HOME)", '', False),
+ ("logsize", 'max size (MiB) to collect per log file', '', 15),
+ ("stdjar", 'Collect jar statistics for standard jars.', '', True),
+ ("host", 'hostname of the management api for jboss', '', 'localhost'),
+ ("port", 'port of the management api for jboss', '', '9990'),
+ ("user", 'username for management console', '', None),
+ ("pass", 'password for management console', '', None),
+ ("appxml", "comma separated list of application's whose XML descriptors you want. The keyword 'all' will collect all descriptors in the designated profile(s).", '', False),
+ ]
+
+ __MD5_CHUNK_SIZE=128
+ __jbossHome=None
+ __haveJava=False
+ __twiddleCmd=None
+ __jbossServerConfigDirs = ["standalone", "domain"]
+ __jbossHTMLBody=None
+
+ def __alert(self, msg):
+ self.soslog.error(msg)
+ self.addAlert(msg)
+
+ def __getJbossHome(self):
+ """
+ Will attempt to locate the JBoss installation dir in either jboss.home or
+ scrape it from the environment variable JBOSS_HOME.
+ Returns:
+ True JBOSS_HOME is set and the path exists. False otherwise.
+ """
+
+ if self.getOption("home"):
+ ## Prefer this value first over the ENV
+ self.__jbossHome=self.getOption(("home", "as7_home"))
+ self.addAlert("INFO: The JBoss installation directory supplied to SOS is " +
+ self.__jbossHome)
+ elif os.environ.get("JBOSS_HOME"):
+ self.__jbossHome=os.environ.get("JBOSS_HOME")
+ self.addAlert("INFO: The JBoss installation directory (i.e. JBOSS_HOME) from the environment is " +
+ self.__jbossHome)
+ else:
+ self.addAlert("ERROR: The JBoss installation directory was not supplied.\
+ The JBoss SOS plug-in cannot continue.")
+ return False
+
+ return True
+
+ def __getMd5(self, file):
+ """Returns the MD5 sum of the specified file."""
+
+ retVal = "?" * 32
+
+ try:
+ retVal = checksum(file, self.__MD5_CHUNK_SIZE)
+ except IOError, ioe:
+ self.__alert("ERROR: Unable to open %s for reading. Error: %s" % (file,ioe))
+
+ return retVal
+
+ def __getManifest(self, jarFile):
+ """
+ Given a jar file, this function will extract the Manifest and return it's contents
+ as a string.
+ """
+ manifest = None
+ try:
+ zf = zipfile.ZipFile(jarFile)
+ try:
+ manifest = zf.read("META-INF/MANIFEST.MF")
+ except Exception, e:
+ self.__alert("ERROR: reading manifest from %s. Error: %s" % (jarFile, e))
+ zf.close()
+ except Exception, e:
+ self.__alert("ERROR: reading contents of %s. Error: %s" % (jarFile, e))
+ return manifest
+
+ def __getStdJarInfo(self):
+ found = False
+ jar_info_list = []
+ for jarFile in find("*.jar", self.__jbossHome):
+ checksum = self.__getMd5(jarFile)
+ manifest = self.__getManifest(jarFile)
+ path = jarFile.replace(self.__jbossHome, 'JBOSSHOME')
+ if manifest:
+ manifest = manifest.strip()
+ jar_info_list.append((path, checksum, manifest))
+ found = True
+ if found:
+ jar_info_list.sort()
+ self.addStringAsFile("\n".join([
+ "%s\n%s\n%s\n" % (name, checksum, manifest)
+ for (name, checksum, manifest) in jar_info_list]),
+ 'jarinfo.txt')
+ else:
+ self.addAlert("WARN: No jars found in JBoss system path (" + self.__jbossHome + ").")
+
+
+ def query(self, request_obj):
+ try:
+ return self.query_java(request_obj)
+ except Exception, e:
+ self.addAlert("JBOSS API call failed, falling back to HTTP: %s" % e)
+ return self.query_http(request_obj)
+
+ def query_java(self, request_obj):
+ from org.jboss.dmr import ModelNode
+ controller_client = self.getOption('controller_client_proxy')
+ if not controller_client:
+ raise AttributeError("Controller Client is not available")
+
+ request = ModelNode()
+ request.get("operation").set(request_obj.operation)
+
+ for key, val in request_obj.url_parts():
+ request.get('address').add(key,val)
+
+ if request_obj.parameters:
+ for key, value in request_obj.parameters.iteritems():
+ request.get(key).set(value)
+
+ return controller_client.execute(request).toJSONString(True)
+
+ def query_http(self, request_obj, postdata=None):
+ host = self.getOption(('host', 'as7_host'))
+ port = self.getOption(('port', 'as7_port'))
+
+ username = self.getOption(('user', 'as7_user'), None)
+ password = self.getOption(('pass', 'as7_pass'), None)
+
+ uri = "http://%s:%s/management" % (host,port)
+
+ json_data = {'operation': request_obj.operation,
+ 'address': []}
+
+ for key, val in request_obj.url_parts():
+ json_data['address'].append({key:val})
+
+ for key, val in request_obj.parameters.iteritems():
+ json_data[key] = val
+
+ postdata = json.dumps(json_data)
+ headers = {'Content-Type': 'application/json',
+ 'Accept': 'application/json'}
+
+ opener = urllib2.build_opener()
+
+ if username and password:
+ passwd_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
+ passwd_manager.add_password(realm="ManagementRealm",
+ uri=uri,
+ user=username,
+ passwd=password)
+ digest_auth_handler = urllib2.HTTPDigestAuthHandler(passwd_manager)
+ basic_auth_handler = urllib2.HTTPBasicAuthHandler(passwd_manager)
+
+ opener.add_handler(digest_auth_handler)
+ opener.add_handler(basic_auth_handler)
+
+ req = urllib2.Request(uri, data=postdata, headers=headers)
+
+ try:
+ resp = opener.open(req)
+ return resp.read()
+ except Exception, e:
+ err_msg = "Could not query url: %s; error: %s" % (uri, e)
+ self.addAlert(err_msg)
+ return err_msg
+
+ def _set_domain_info(self, parameters=None):
+ """This function will add host controller and server instance
+ name data if it is present to the desired resource. This is to support
+ domain-mode operation in AS7"""
+ host_controller_name = self.getOption("as7_host_controller_name")
+ server_name = self.getOption("as7_server_name")
+
+ if host_controller_name and server_name:
+ if not parameters:
+ parameters = {}
+
+ parameters['host'] = host_controller_name
+ parameters['server'] = server_name
+
+ return parameters
+
+
+ def _resource_to_file(self, resource=None, parameters=None, operation='read-resource', outfile=None):
+ parameters = self._set_domain_info(parameters)
+
+ r = Request(resource=resource,
+ parameters=parameters,
+ operation=operation)
+ self.addStringAsFile(self.query(r), filename=outfile)
+
+
+ def get_online_data(self):
+ """
+ This function co-locates calls to the management api that gather
+ information from a running system.
+ """
+ self._resource_to_file(resource="/",
+ parameters={"recursive": "true"},
+ outfile="configuration.json")
+ self._resource_to_file(resource="/core-service/service-container",
+ operation="dump-services",
+ outfile="dump-services.json")
+ self._resource_to_file(resource="/subsystem/modcluster",
+ operation="read-proxies-configuration",
+ outfile="cluster-proxies-configuration.json")
+ self._resource_to_file(resource="/core-service/platform-mbean/type/threading",
+ operation="dump-all-threads",
+ parameters={"locked-synchronizers": "true",
+ "locked-monitors": "true"},
+ outfile="threaddump.json")
+
+ def __getFiles(self, configDirAry):
+ """
+ This function will collect files from JBOSS_HOME for analysis. The scope of files to
+ be collected are determined by options to this SOS plug-in.
+ """
+
+ for dir_ in configDirAry:
+ path = os.path.join(self.__jbossHome, dir_)
+ ## First add forbidden files
+ self.addForbiddenPath(os.path.join(path, "tmp"))
+ self.addForbiddenPath(os.path.join(path, "work"))
+ self.addForbiddenPath(os.path.join(path, "data"))
+
+ if os.path.exists(path):
+ ## First get everything in the conf dir
+ confDir = os.path.join(path, "configuration")
+ self.addForbiddenPath(os.path.join(confDir, 'mgmt-users.properties'))
+
+ self.doCopyFileOrDir(confDir, sub=(self.__jbossHome, 'JBOSSHOME'))
+ ## Log dir next
+ logDir = os.path.join(path, "log")
+
+ for logFile in find("*", logDir):
+ self.addCopySpecLimit(logFile,
+ self.getOption("logsize"),
+ sub=(self.__jbossHome, 'JBOSSHOME'))
+
+ ## Deploy dir
+ deployDir = os.path.join(path, "deployments")
+
+ for deployFile in find("*", deployDir, max_depth=1):
+ self.addCopySpec(deployFile, sub=(self.__jbossHome, 'JBOSSHOME'))
+
+ def setup(self):
+
+ ## We need to know where JBoss is installed and if we can't find it we
+ ## must exit immediately.
+ if not self.__getJbossHome():
+ self.exit_please()
+
+ try:
+ self.get_online_data()
+ except urllib2.URLError:
+ pass
+
+ ## Generate hashes of the stock Jar files for the report.
+ if self.getOption("stdjar"):
+ self.__getStdJarInfo()
+
+ ## Generate a Tree for JBOSS_HOME
+ tree = DirTree(self.__jbossHome).as_string()
+ self.addStringAsFile(tree, "jboss_home_tree.txt")
+
+ self.__getFiles(self.__jbossServerConfigDirs)
+
+ # FIXME: this is still not right, tweak the search paths to pick up the right files
+ def postproc(self):
+ """
+ Obfuscate passwords.
+ """
+
+ password_xml_regex = re.compile(r'<password>.*</password>', re.IGNORECASE)
+
+ for dir_ in self.__jbossServerConfigDirs:
+ path = os.path.join(self.__jbossHome, dir_)
+
+ self.doRegexSub(os.path.join(path,"configuration","*.xml"),
+ password_xml_regex,
+ r'<password>********</password>')
+
+ tmp = os.path.join(path,"configuration")
+ for propFile in find("*-users.properties", tmp):
+ self.doRegexSub(propFile,
+ r"=(.*)",
+ r'=********')
+
+# Remove PW from -ds.xml files
+ tmp = os.path.join(path, "deployments")
+ for dsFile in find("*-ds.xml", tmp):
+ self.doRegexSub(dsFile,
+ password_xml_regex,
+ r"<password>********</password>")
View
8 sos/plugins/emc.py
@@ -16,9 +16,9 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools, os
+from sos.plugins import Plugin, RedHatPlugin, os
-class emc(sos.plugintools.PluginBase):
+class emc(Plugin, RedHatPlugin):
"""EMC related information (PowerPath, Solutions Enabler CLI and Navisphere CLI)
"""
@@ -146,7 +146,7 @@ def get_navicli_SP_info(self,SP_address):
def checkenabled(self):
self.packages = [ "EMCpower" ]
self.files = [ "/opt/Navisphere/bin", "/proc/emcp" ]
- return sos.plugintools.PluginBase.checkenabled(self)
+ return Plugin.checkenabled(self)
def setup(self):
from subprocess import Popen, PIPE
@@ -168,7 +168,7 @@ def setup(self):
self.get_pp_config()
## If Solutions Enabler is installed collect Symmetrix/DMX specific information
- if len(self.allPkgsByNameRegex('[Ss][Yy][Mm][Cc][Ll][Ii]-[Ss][Yy][Mm][Cc][Ll][Ii]')) > 0:
+ if len(self.policy().package_manager.allPkgsByNameRegex('[Ss][Yy][Mm][Cc][Ll][Ii]-[Ss][Yy][Mm][Cc][Ll][Ii]')) > 0:
print "EMC Solutions Enabler SYMCLI is installed."
print " Gathering EMC Solutions Enabler SYMCLI information..."
self.addCustomText("EMC Solutions Enabler is installed.<br>")
View
10 sos/plugins/filesys.py
@@ -12,12 +12,12 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
import os
import re
from itertools import *
-class filesys(sos.plugintools.PluginBase):
+class filesys(Plugin, RedHatPlugin):
"""information on filesystems
"""
optionList = [("lsof", 'gathers information on all open files', 'slow', False)]
@@ -33,14 +33,14 @@ def setup(self):
"/etc/raidtab",
"/etc/mdadm.conf"])
mounts = self.collectOutputNow("/bin/mount -l", root_symlink = "mount")
-
+
self.collectExtOutput("/bin/findmnt")
self.collectExtOutput("/bin/df -al", root_symlink = "df")
self.collectExtOutput("/bin/df -ali")
if self.getOption('lsof'):
self.collectExtOutput("/usr/sbin/lsof -b +M -n -l -P", root_symlink = "lsof")
self.collectExtOutput("/sbin/blkid -c /dev/null")
-
+
part_titlep = re.compile("^major")
blankp = re.compile("^$")
partlist = []
@@ -68,7 +68,7 @@ def setup(self):
if bool(part_in_disk.match(dev)):
devlist.append(dev)
- for i in devlist:
+ for i in devlist:
self.collectExtOutput("/sbin/parted -s %s print" % (i))
if self.getOption('dumpe2fs'):
View
4 sos/plugins/ftp.py
@@ -12,10 +12,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
from os.path import exists
-class ftp(sos.plugintools.PluginBase):
+class ftp(Plugin, RedHatPlugin):
"""FTP server related information
"""
View
4 sos/plugins/gdm.py
@@ -12,9 +12,9 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
-class gdm(sos.plugintools.PluginBase):
+class gdm(Plugin, RedHatPlugin):
"""gdm related information
"""
def setup(self):
View
4 sos/plugins/general.py
@@ -13,10 +13,10 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import os
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
import commands
-class general(sos.plugintools.PluginBase):
+class general(Plugin, RedHatPlugin):
"""basic system information
"""
View
4 sos/plugins/gluster.py
@@ -13,9 +13,9 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import os.path
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
-class gluster(sos.plugintools.PluginBase):
+class gluster(Plugin, RedHatPlugin):
'''gluster related information'''
def checkenabled(self):
View
4 sos/plugins/hardware.py
@@ -12,10 +12,10 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin
from glob import glob
-class hardware(sos.plugintools.PluginBase):
+class hardware(Plugin, RedHatPlugin):
"""hardware related information
"""
def setup(self):
View
4 sos/plugins/hts.py
@@ -12,9 +12,9 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import sos.plugintools
+from sos.plugins import Plugin, RedHatPlugin