diff options
Diffstat (limited to 'trunk/src')
60 files changed, 0 insertions, 5657 deletions
diff --git a/trunk/src/ChangeLog b/trunk/src/ChangeLog deleted file mode 100644 index 92947fd9..00000000 --- a/trunk/src/ChangeLog +++ /dev/null @@ -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. - diff --git a/trunk/src/LICENSE b/trunk/src/LICENSE deleted file mode 100644 index 7a8e8abf..00000000 --- a/trunk/src/LICENSE +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/trunk/src/Makefile b/trunk/src/Makefile deleted file mode 100644 index 99d2ed5d..00000000 --- a/trunk/src/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -# -# Makefile for sos system support tools -# - -NAME = sos -VERSION = $(shell awk '/^%define version / { print $$3 }' sos.spec) -REPO = https://sos.108.redhat.com/svn/sos -SVNTAG = r$(subst .,-,$(VERSION)) -SRCDIR = $(PWD) -TOPDIR = $(PWD)/build/rpm-$(NAME)-$(VERSION) - - -all: - -.PHONY: tag-release tarball release install version clean - -diff-tag: - svn diff $(REPO)/trunk/src $(REPO)/tags/$(SVNTAG) - -tag: - @if ( svn list $(REPO)/tags/$(SVNTAG)/Makefile &> /dev/null ); then \ - echo "The repository already contains a tag for version $(VERSION)"; \ - exit 1; \ - fi - @svn copy $(REPO)/trunk/src $(REPO)/tags/$(SVNTAG) \ - -m "Tagging the $(SVNTAG) release of the sos project" - @echo "Tagged as $(SVNTAG)" - -tag-force: - @echo svn del $(REPO)/tags/$(SVNTAG) - @echo make diff-tag - -tarball: clean - @echo "Creating an archive from HEAD of development" - @rm -rf /tmp/$(NAME) - @svn export -q $(REPO)/trunk/src /tmp/$(NAME) \ - || echo GRRRrrrrr -- ignore [export aborted] - @mv /tmp/$(NAME) /tmp/$(NAME)-$(VERSION) - @cd /tmp; tar --bzip2 -cSpf $(NAME)-$(VERSION).tar.bz2 $(NAME)-$(VERSION) - @rm -rf /tmp/$(NAME)-$(VERSION) - @mv /tmp/$(NAME)-$(VERSION).tar.bz2 . - @echo " " - @echo "The final archive is ./$(NAME)-$(VERSION).tar.bz2." - -release: clean - @if ( ! svn list $(REPO)/tags/$(SVNTAG)/Makefile &> /dev/null ); then \ - echo "There is no tag in the repository for this version, must be tagged before release"; \ - exit 1; \ - fi - @echo "Creating an archive from tag $(SVNTAG)" - @rm -rf /tmp/$(NAME) - @svn export -q $(REPO)/tags/$(SVNTAG) /tmp/$(NAME) \ - || echo GRRRrrrrr -- ignore [export aborted] - @mv /tmp/$(NAME) /tmp/$(NAME)-$(VERSION) - @cd /tmp; tar --bzip2 -cSpf $(NAME)-$(VERSION).tar.bz2 $(NAME)-$(VERSION) - @rm -rf /tmp/$(NAME)-$(VERSION) - @cp /tmp/$(NAME)-$(VERSION).tar.bz2 . - @rm -f /tmp/$(NAME)-$(VERSION).tar.bz2 - @echo " " - @echo "The final archive is ./$(NAME)-$(VERSION).tar.bz2." - -install:mo - python setup.py install - -version: - @echo "The version is $(NAME)-$(VERSION)" - -clean: - @rm -fv *~ .*~ changenew ChangeLog.old $(NAME)-$(VERSION).tar.bz2 sosreport.1.gz - -rpm: mo - @test -f sos.spec - @mkdir -p $(TOPDIR)/SOURCES $(TOPDIR)/SRPMS $(TOPDIR)/RPMS $(TOPDIR)/BUILD - -# 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 \ - -chSpf $(TOPDIR)/SOURCES/$(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION) ; \ - rm -f $(NAME)-$(VERSION) - -# this builds an RPM from HEAD -# @rm -rf $(TOPDIR)/BUILD/$(NAME)-$(VERSION) -# @svn export -q $(REPO)/trunk/src $(TOPDIR)/BUILD/$(NAME)-$(VERSION) -# @cd $(TOPDIR)/BUILD ; tar --gzip -cSpf $(TOPDIR)/SOURCES/$(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION); rm -rf $(NAME)-$(VERSION) - - rpmbuild -ba --define="_topdir $(TOPDIR)" sos.spec - @mv $(TOPDIR)/RPMS/noarch/$(NAME)-$(VERSION)*.rpm $(TOPDIR)/SRPMS/$(NAME)-$(VERSION)*.rpm $(TOPDIR)/SOURCES/$(NAME)-$(VERSION).tar.gz dist/ - -pot: - python tools/pygettext.py -o locale/sos.pot sosreport - -mo: - python tools/msgfmt.py locale/*/LC_MESSAGES/sos.po diff --git a/trunk/src/README b/trunk/src/README deleted file mode 100644 index b65b07ed..00000000 --- a/trunk/src/README +++ /dev/null @@ -1,24 +0,0 @@ -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://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: - - svn checkout https://sos.108.redhat.com/svn/sos/trunk sos - -(all the following as root) -to install locally ==> python setup.py install -to build an rpm ==> make rpm - -See the Makefile. - -Contributors: -Steve Conklin <sconklin@redhat.com> -Pierre Amadio <pamadio@redhat.com> -John Berninger <jwb@redhat.com> -Navid Sheikhol-Eslami <navid@redhat.com> diff --git a/trunk/src/TODO b/trunk/src/TODO deleted file mode 100644 index 2f2d323f..00000000 --- a/trunk/src/TODO +++ /dev/null @@ -1,21 +0,0 @@ -To Do List: - - * Gather statistics (time, files collected, commands run) per plugin - - * Choose sane defaults to satisfy Red Hat support requirements (ie. what - plugins should be loaded by default, with what options, etc) - - * Display on screen what files/commands are being gathered. - - * Make sosreport a drop-in replacement for sysreport - - * Allow to use a different rootdir than / - - * Add support for distributions other than Fedora. - - * Make it easier to select a policy module and perhaps optionally include - plugins from the library, to allow per-distribution customization. - - * Documentation - plugin howto doc, inline doc in plugin template - - * Review and test error handling for things like a full tmp file system diff --git a/trunk/src/example_plugins/example.py b/trunk/src/example_plugins/example.py deleted file mode 100755 index 1e650417..00000000 --- a/trunk/src/example_plugins/example.py +++ /dev/null @@ -1,94 +0,0 @@ -## example.py -## An example sos plugin - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -# Class name must be the same as file name and method names must not change -class example(sos.plugintools.PluginBase): - """This is an example plugin for sos. Plugins gather, analyze, and report on various aspects - of system operation that are of interest. plugins are based on the PluginBase class, which - you should inspect if you wish to override any methods in your plugin. The methods of use - to plugin developers are: - collect() - use the functions sosCp and sosRunExe to gether information - analyze() - perform any special analysis you require beyond just saving the - information gathered by collect(). Use sosAlert() and sosAddCustomText() - to add information to the report. - report() - override this method if you wish to replace the default reporting - - All plugins will use collect(), some will use analyze(), few will override report() - """ - - # Add your options here, indicate whether they are slow to run, and set whether they are enabled by default - # Options are python dictionaries that conatin a short name, long description, speed, and whether they are enabled by default - optionList = [("init.d", 'Gathers the init.d directory', 'slow', 0), - ('follicles', 'Gathers information about each follicle on every toe', 'slow', 0), - ('color', 'Gathers toenail polish color', 'fast', 0)] - - def setup(self): - ''' First phase - Collect all the information we need. - Directories are copied recursively. arbitrary commands may be - executed using the susRunExe method. Information is automatically saved, and - links are presented in the report to each file or directory which has been - copied to the saved tree. Also, links are provided to the output from each command. - ''' - # Here's how to copy files and directory trees - self.addCopySpec("/etc/hosts") - # this one saves a file path to the copy for later analysis - # FIXME: Need to figure out how to do this - # self.fooFilePath = self.copyFileOrDir("/proc/cpuinfo") - - # Here's how to test your options and execute if enabled - if self.isOptionEnabled("init.d"): - self.addCopySpec("/etc/init.d") # copies a whole directory tree - - # Here's how to execute a command - # you can save the path to the copied file for later analysis if desired - # FIXME: Need to figure out how to do this - self.psCmdDstFileName = self.runExe("/bin/ps -ef") - return - - def analyze(self): - ''' This is optional and need not be defined. - If you wish to perform some analysis on either files - that were gathered or on the output of commands, then save the filenames on the - destination file system when gathering that information in the collect() method - and use them here - ''' - # This is an example of opening and reading the output of a command that - # was run in the collect() method. Note that the output of the command is - # included in the report anyway - fd = open(self.fooFilePath) - lines = fd.readlines() - fd.close() - for line in lines: - if line.count("vendor_id"): - self.addCustomText("Vendor ID string is: %s <br>\n" % line) - # - # Alerts can optionally be generated, and will be included in the - # report automatically - # - self.addAlert("This is an alert") - return - -# def report(self): -# """ Usually, this doesn't even need to be defined, and you can inherit the -# base class, unless you want to replace what sosGetResults() -# does with your own custom report generator. If you are going to do that, have a good -# look at that method to see what it does. Custom text and alerts can still be added -# here using sosAddCustomText() and sosAddAlert() -# This method returns html that will be included inline in the report -# """ diff --git a/trunk/src/example_plugins/fsusage.py b/trunk/src/example_plugins/fsusage.py deleted file mode 100644 index 2532c5f7..00000000 --- a/trunk/src/example_plugins/fsusage.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -# Class name must be the same as file name and method names must not change -class fsusage(sos.plugintools.PluginBase): - def setup(self): - self.psCmdDstFileName = self.collectExtOutput("/bin/df -al") - return diff --git a/trunk/src/example_plugins/release.py b/trunk/src/example_plugins/release.py deleted file mode 100644 index db4d7581..00000000 --- a/trunk/src/example_plugins/release.py +++ /dev/null @@ -1,21 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -# Class name must be the same as file name and method names must not change -class release(sos.plugintools.PluginBase): - def setup(self): - self.addCopySpec("/etc/redhat-release") - return diff --git a/trunk/src/example_plugins/runcommand.py b/trunk/src/example_plugins/runcommand.py deleted file mode 100755 index df8951d2..00000000 --- a/trunk/src/example_plugins/runcommand.py +++ /dev/null @@ -1,45 +0,0 @@ -## runcommand.py -## An example plugin for sos - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -# Class name must be the same as file name and method names must not change -class runcommand(sos.plugintools.PluginBase): - """This is a very simple example plugin that just runs one command in a shell. That - command could be a script supplied with your package which outputs information of interest - to support. When the script or command is run, stdout is collected and included in the - report generated by sosreport, and stderr is collected and copied into the sos log. - - This is useful for people who have minimal knowledge of python, who wish to write - collection tools in other languages, or who have existing tools. - - If your script or command generates output files that you want included in the sosreport - collection of files, include sosCp calls to include them. - - The only method required for this simple plugin is collect(). - - Your finished plugin should be included with your package and installed in python's - site-packages/sos/plugins/ directory - """ - def setup(self): - ''' Run a command. Output is automatically included in the report. - ''' - self.collectExtOutput("/path/to/my/script --myoption --anotheroption") - - # if (for example) that command created files /foo/bar/baz.txt and - # we want to include that in our report, we include the next line: - #self.pit.sosCp("/foo/bar/baz.txt") diff --git a/trunk/src/lib/sos/__init__.py b/trunk/src/lib/sos/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/trunk/src/lib/sos/__init__.py +++ /dev/null diff --git a/trunk/src/lib/sos/helpers.py b/trunk/src/lib/sos/helpers.py deleted file mode 100755 index 54a86dba..00000000 --- a/trunk/src/lib/sos/helpers.py +++ /dev/null @@ -1,120 +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, popen2, fcntl, select, itertools, sys, commands -from time import time -from tempfile import mkdtemp - -def importPlugin(pluginname, name): - """ Import a plugin to extend capabilities of sosreport - """ - try: - plugin = __import__(pluginname, globals(), locals(), [name]) - except ImportError: - return None - return getattr(plugin, name) - - -def sosFindTmpDir(): - """Find a temp directory to form the root for our gathered information - and reports. - """ - workingBase = mkdtemp("","sos_") - return workingBase - - -def makeNonBlocking(afd): - """ Make the file descriptor non-blocking. This prevents deadlocks. - """ - fl = fcntl.fcntl(afd, fcntl.F_GETFL) - try: - fcntl.fcntl(afd, fcntl.F_SETFL, fl | os.O_NDELAY) - except AttributeError: - fcntl.fcntl(afd, fcntl.F_SETFL, fl | os.FNDELAY) - - -def sosGetCommandOutput(command): - """ Execute a command and gather stdin, stdout, and return status. - Adapted from Python Cookbook - O'Reilly - """ - stime = time() - errdata = '' - status,outdata=commands.getstatusoutput(command) - return (status, outdata, time()-stime) - - -# FIXME: this needs to be made clean and moved to the plugin tools, so -# that it prints nice color output like sysreport if the progress bar -# is not enabled. -def sosStatus(stat): - """ Complete a status line that has been output to the console, - providing pass/fail indication. - """ - if not stat: - print " [ OK ]" - else: - print " [ FAILED ]" - sys.stdout.flush() - return - - -def allEqual(elements): - ''' return True if all the elements are equal, otherwise False. ''' - first_element = elements[0] - for other_element in elements[1:]: - if other_element != first_element: - return False - return True - - -def commonPrefix(*sequences): - ''' return a list of common elements at the start of all sequences, - then a list of lists that are the unique tails of each sequence. ''' - # if there are no sequences at all, we're done - if not sequences: - return [], [] - # loop in parallel on the sequences - common = [] - for elements in itertools.izip(*sequences): - # unless all elements are equal, bail out of the loop - if not allEqual(elements): - break - # got one more common element, append it and keep looping - common.append(elements[0]) - # return the common prefix and unique tails - return common, [ sequence[len(common):] for sequence in sequences ] - -def sosRelPath(path1, path2, sep=os.path.sep, pardir=os.path.pardir): - ''' return a relative path from path1 equivalent to path path2. - In particular: the empty string, if path1 == path2; - path2, if path1 and path2 have no common prefix. - ''' - common, (u1, u2) = commonPrefix(path1.split(sep), path2.split(sep)) - if not common: - return path2 # leave path absolute if nothing at all in common - return sep.join( [pardir]*len(u1) + u2 ) - diff --git a/trunk/src/lib/sos/plugins/__init__.py b/trunk/src/lib/sos/plugins/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/trunk/src/lib/sos/plugins/__init__.py +++ /dev/null diff --git a/trunk/src/lib/sos/plugins/amd.py b/trunk/src/lib/sos/plugins/amd.py deleted file mode 100644 index 1b1375cc..00000000 --- a/trunk/src/lib/sos/plugins/amd.py +++ /dev/null @@ -1,31 +0,0 @@ -## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class amd(sos.plugintools.PluginBase): - """Amd automounter information - """ - def setup(self): - self.addCopySpec("/etc/amd.*") - self.addCopySpec("/etc/rc.d/init.d/amd") - self.addCopySpec("/etc/sysconfig/amd") - self.collectExtOutput("/bin/rpm -qV am-utils") - self.collectExtOutput("/bin/egrep -e 'automount|pid.*nfs' /proc/mounts") - self.collectExtOutput("/bin/mount | egrep -e 'automount|pid.*nfs'") - self.collectExtOutput("/sbin/chkconfig --list amd") - return - diff --git a/trunk/src/lib/sos/plugins/apache.py b/trunk/src/lib/sos/plugins/apache.py deleted file mode 100644 index c5250fd9..00000000 --- a/trunk/src/lib/sos/plugins/apache.py +++ /dev/null @@ -1,26 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -from threading import Thread - -class apache(sos.plugintools.PluginBase): - """Apache related information - """ - def setup(self): - self.addCopySpec("/etc/httpd/conf/httpd.conf") - self.addCopySpec("/etc/httpd/conf.d/*.conf") - self.addCopySpec("/var/log/httpd/*") - return - diff --git a/trunk/src/lib/sos/plugins/bootloader.py b/trunk/src/lib/sos/plugins/bootloader.py deleted file mode 100644 index a820069e..00000000 --- a/trunk/src/lib/sos/plugins/bootloader.py +++ /dev/null @@ -1,31 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class bootloader(sos.plugintools.PluginBase): - """Bootloader information - """ - def setup(self): - self.addCopySpec("/etc/lilo.conf") - self.addCopySpec("/etc/milo.conf") - self.addCopySpec("/etc/silo.conf") - self.addCopySpec("/boot/grub/grub.conf") - self.addCopySpec("/boot/grub/device.map") - self.addCopySpec("/boot/efi/elilo.conf") - self.addCopySpec("/boot/yaboot.conf") - - self.collectExtOutput("/sbin/lilo -q") - return - diff --git a/trunk/src/lib/sos/plugins/cluster.py b/trunk/src/lib/sos/plugins/cluster.py deleted file mode 100644 index 595d940a..00000000 --- a/trunk/src/lib/sos/plugins/cluster.py +++ /dev/null @@ -1,78 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import commands, os - -class cluster(sos.plugintools.PluginBase): - """cluster suite and GFS related information - """ - def checkenabled(self): - # enable if any related package is installed - for pkg in [ "ccs", "cman", "cman-kernel", "magma", "magma-plugins", - "rgmanager", "fence", "dlm", "dlm-kernel", "gulm", - "GFS", "GFS-kernel", "lvm2-cluster" ]: - if self.cInfo["policy"].pkgByName(pkg) != None: - return True - - # enable if any related file is present - for fname in [ "/etc/cluster/cluster.conf" ]: - try: os.stat(fname) - except:pass - else: return True - - # no data related to RHCS/GFS exists - return False - - def diagnose(self): - rhelver = self.cInfo["policy"].pkgDictByName("fedora-release")[0] - if rhelver == "6": - # check if the minimum set of packages is installed - # for RHEL4 RHCS(ccs, cman, cman-kernel, magma, magma-plugins, (dlm, dlm-kernel) || gulm, perl-Net-Telnet, rgmanager, fence) - # RHEL4 GFS (GFS, GFS-kernel, ccs, lvm2-cluster, fence) - for pkg in [ "ccs", "cman", "cman-kernel", "magma", "magma-plugins", "perl-Net-Telnet", "rgmanager", "fence" ]: - if self.cInfo["policy"].pkgByName(pkg) == None: - self.addDiagnose("required package is missing: %s" % pkg) - - # check if all the needed daemons are active at sosreport time - # check if they are started at boot time in RHEL4 RHCS (cman, ccsd, rgmanager, fenced) - # and GFS (gfs, ccsd, clvmd, fenced) - for service in [ "cman", "ccsd", "rgmanager", "fence" ]: - if commands.getstatus("/sbin/service %s status" % service): - self.addDiagnose("service %s is not running" % service) - - if not self.cInfo["policy"].runlevelDefault() in self.cInfo["policy"].runlevelByService(service): - self.addDiagnose("service %s is not started in default runlevel" % service) - - # FIXME: what locking are we using ? check if packages exist -# if self.cInfo["policy"].pkgByName(pkg) and self.cInfo["policy"].pkgByName(pkg) and not self.cInfo["policy"].pkgByName(pkg) - - def setup(self): - self.collectExtOutput("/sbin/fdisk -l") - self.addCopySpec("/etc/cluster.conf") - self.addCopySpec("/etc/cluster.xml") - self.addCopySpec("/etc/cluster") - self.collectExtOutput("/usr/sbin/rg_test test /etc/cluster/cluster.conf") - self.addCopySpec("/proc/cluster") - self.collectExtOutput("/usr/bin/cman_tool status") - self.collectExtOutput("/usr/bin/cman_tool services") - self.collectExtOutput("/usr/bin/cman_tool -af nodes") - self.collectExtOutput("/usr/bin/ccs_tool lsnode") - self.collectExtOutput("/usr/bin/openais-cfgtool -s") - self.collectExtOutput("/usr/bin/clustat") - return - - def postproc(self): - self.doRegexSub("/etc/cluster/cluster.conf", r"(\s*\<fencedevice\s*.*\s*passwd\s*=\s*)\S+(\")", r"\1***") - return diff --git a/trunk/src/lib/sos/plugins/devicemapper.py b/trunk/src/lib/sos/plugins/devicemapper.py deleted file mode 100644 index e517aa3d..00000000 --- a/trunk/src/lib/sos/plugins/devicemapper.py +++ /dev/null @@ -1,38 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class devicemapper(sos.plugintools.PluginBase): - """device-mapper related information (dm, lvm, multipath) - """ - def setup(self): - self.collectExtOutput("/sbin/dmsetup info -c") - self.collectExtOutput("/sbin/dmsetup table") - self.collectExtOutput("/sbin/dmsetup status") - - self.collectExtOutput("/usr/sbin/vgscan -vvv") - self.collectExtOutput("/usr/sbin/vgdisplay -vv", root_symlink = "vgdisplay") - self.collectExtOutput("/usr/sbin/pvscan -v") - self.collectExtOutput("/usr/sbin/lvs -a -o +devices") - self.collectExtOutput("/usr/sbin/pvs -a -v") - self.collectExtOutput("/usr/sbin/vgs -v") - - self.addCopySpec("/etc/lvm/lvm.conf") - - self.addCopySpec("/etc/multipath.conf") - self.addCopySpec("/var/lib/multipath/bindings") - self.collectExtOutput("/sbin/multipath -v4 -ll") - - return diff --git a/trunk/src/lib/sos/plugins/filesys.py b/trunk/src/lib/sos/plugins/filesys.py deleted file mode 100644 index 02bde2eb..00000000 --- a/trunk/src/lib/sos/plugins/filesys.py +++ /dev/null @@ -1,47 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import commands - -class filesys(sos.plugintools.PluginBase): - """information on filesystems - """ - def setup(self): - self.addCopySpec("/proc/filesystems") - self.addCopySpec("/etc/fstab") - self.addCopySpec("/proc/self/mounts") - self.addCopySpec("/proc/mounts") - self.addCopySpec("/proc/mdstat") - self.addCopySpec("/etc/raidtab") - self.addCopySpec("/etc/mdadm.conf") - self.addCopySpec("/etc/auto.master") - self.addCopySpec("/etc/auto.misc") - self.addCopySpec("/etc/auto.net") - - self.collectExtOutput("/bin/df -al", root_symlink = "df") - self.collectExtOutput("/usr/sbin/lsof -b +M -n -l", root_symlink = "lsof") - self.collectExtOutput("/bin/mount -l", root_symlink = "mount") - self.collectExtOutput("/sbin/blkid") - - raiddevs = commands.getoutput("/bin/cat /proc/partitions | /bin/egrep -v \"^major|^$\" | /bin/awk '{print $4}' | /bin/grep \/ | /bin/egrep -v \"p[0123456789]$\"") - disks = commands.getoutput("/bin/cat /proc/partitions | /bin/egrep -v \"^major|^$\" | /bin/awk '{print $4}' | /bin/grep -v / | /bin/egrep -v \"[0123456789]$\"") - for disk in raiddevs.split('\n'): - if '' != disk.strip(): - self.collectExtOutput("/sbin/fdisk -l /dev/%s" % (disk,)) - for disk in disks.split('\n'): - if '' != disk.strip(): - self.collectExtOutput("/sbin/fdisk -l /dev/%s" % (disk,)) - return - diff --git a/trunk/src/lib/sos/plugins/ftp.py b/trunk/src/lib/sos/plugins/ftp.py deleted file mode 100644 index 026954c0..00000000 --- a/trunk/src/lib/sos/plugins/ftp.py +++ /dev/null @@ -1,24 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class ftp(sos.plugintools.PluginBase): - """FTP server related information - """ - def setup(self): - self.addCopySpec("/etc/ftp*") - self.addCopySpec("/etc/vsftpd") - return - diff --git a/trunk/src/lib/sos/plugins/general.py b/trunk/src/lib/sos/plugins/general.py deleted file mode 100644 index 06f55228..00000000 --- a/trunk/src/lib/sos/plugins/general.py +++ /dev/null @@ -1,43 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import glob - -class general(sos.plugintools.PluginBase): - """very basic system information - """ - - optionList = [("syslogsize", "maximum size (in MiB) of logs to collect per syslog file", "", 15)] - - def setup(self): - self.addCopySpec("/etc/redhat-release") - self.addCopySpec("/etc/sysconfig") - self.addCopySpec("/proc/stat") - self.addCopySpec("/var/log/dmesg") - self.addCopySpec("/var/log/messages") - self.addCopySpecLimit("/var/log/messages.*", sizelimit = self.isOptionEnabled("syslogsize")) - self.addCopySpec("/var/log/secure") - self.addCopySpecLimit("/var/log/secure.*", sizelimit = self.isOptionEnabled("syslogsize")) - self.addCopySpec("/var/log/sa") - self.addCopySpec("/var/log/up2date") - self.addCopySpec("/etc/exports") - self.collectExtOutput("/bin/hostname", root_symlink = "hostname") - self.collectExtOutput("/bin/date", root_symlink = "date") - self.collectExtOutput("/usr/bin/uptime", root_symlink = "uptime") - return - - def postproc(self): - self.doRegexSub("/etc/sysconfig/rhn/up2date", r"(\s*proxyPassword\s*=\s*)\S+", r"\1***") - return diff --git a/trunk/src/lib/sos/plugins/hardware.py b/trunk/src/lib/sos/plugins/hardware.py deleted file mode 100644 index f8eeda88..00000000 --- a/trunk/src/lib/sos/plugins/hardware.py +++ /dev/null @@ -1,55 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import commands - -class hardware(sos.plugintools.PluginBase): - """hardware related information - """ - def setup(self): - self.addCopySpec("/proc/partitions") - self.addCopySpec("/proc/cpuinfo") - self.addCopySpec("/proc/meminfo") - self.addCopySpec("/proc/ioports") - self.addCopySpec("/proc/interrupts") - self.addCopySpec("/proc/scsi") - self.addCopySpec("/proc/dma") - self.addCopySpec("/proc/devices") - self.addCopySpec("/proc/rtc") - self.addCopySpec("/proc/ide") - self.addCopySpec("/proc/bus") - self.addCopySpec("/etc/stinit.def") - self.addCopySpec("/etc/sysconfig/hwconf") - self.addCopySpec("/proc/chandev") - self.addCopySpec("/proc/dasd") - self.addCopySpec("/proc/s390dbf/tape") - self.collectExtOutput("/usr/share/rhn/up2dateclient/hardware.py") - self.collectExtOutput("""/bin/echo "lspci" ; /bin/echo ; /sbin/lspci ; /bin/echo ; /bin/echo ; /bin/echo "lspci -nvv" ; /bin/echo ; /sbin/lspci -nvv""", suggest_filename = "lspci", root_symlink = "lspci") - - # FIXME: what is this for? - self.collectExtOutput("/bin/dmesg | /bin/grep -e 'e820.' -e 'agp.'") - - # FIXME: what is this for? - tmpreg = "" - for hwmodule in commands.getoutput('cat /lib/modules/$(uname -r)/modules.pcimap | cut -d " " -f 1 | grep "[:alpha:]" | sort -u').split("\n"): - hwmodule = hwmodule.strip() - if len(hwmodule): - tmpreg = tmpreg + "|" + hwmodule - self.collectExtOutput("/bin/dmesg | /bin/egrep '(%s)'" % tmpreg[1:]) - - self.collectExtOutput("/sbin/lsusb") - self.collectExtOutput("/usr/bin/lshal") - return - diff --git a/trunk/src/lib/sos/plugins/initrd.py b/trunk/src/lib/sos/plugins/initrd.py deleted file mode 100644 index 83356548..00000000 --- a/trunk/src/lib/sos/plugins/initrd.py +++ /dev/null @@ -1,28 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import glob - -class initrd(sos.plugintools.PluginBase): - """initrd related information - """ - def setup(self): - for initrd in glob.glob('/boot/initrd-*.img'): - self.collectExtOutput("/bin/zcat "+initrd+" | /bin/cpio "+ - "--extract --to-stdout init" ) - return - - def defaultenabled(self): - return False diff --git a/trunk/src/lib/sos/plugins/kernel.py b/trunk/src/lib/sos/plugins/kernel.py deleted file mode 100644 index 09381b38..00000000 --- a/trunk/src/lib/sos/plugins/kernel.py +++ /dev/null @@ -1,131 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import commands, os, re - -class kernel(sos.plugintools.PluginBase): - """kernel related information - """ - optionList = [("modinfo", 'Gathers module information on all modules', 'fast', 1), - ('sysrq', 'Trigger SysRq dumps', 'fast', 0)] - moduleFile = "" - taintList = [ - {'regex':'mvfs*', 'description':'Clearcase module'}, - {'regex':'vnode*', 'description':'Clearcase module'}, - {'regex':'vxfs*', 'description':'Veritas file system module'}, - {'regex':'vxportal*', 'description':'Veritas module'}, - {'regex':'vxdmp*', 'description':'Veritas dynamic multipathing module'}, - {'regex':'vxio*', 'description':'Veritas module'}, - {'regex':'vxspec*"', 'description':'Veritas module'}, - {'regex':'dcd*', 'description':'Dell OpenManage Server Administrator module'}, - {'regex':'ocfs', 'description':'Oracle cluster filesystem module'}, - {'regex':'oracle*', 'description':'Oracle module'}, - {'regex':'vmnet*', 'description':'VMware module'}, - {'regex':'vmmon*', 'description':'VMware module'}, - {'regex':'egenera*', 'description':'Egenera module'}, - {'regex':'emcp*', 'description':'EMC module'}, - {'regex':'ocfs*', 'description':'OCFS module'}, - {'regex':'nvidia', 'description':'NVidia module'}, - {'regex':'ati-', 'description':'ATI module'} - ] - - # HP - # - # - - - def setup(self): - self.collectExtOutput("/bin/uname -a", root_symlink = "uname") - self.moduleFile = self.collectOutputNow("/sbin/lsmod", root_symlink = "lsmod") - if self.isOptionEnabled('modinfo'): - runcmd = "" - for kmod in commands.getoutput('/sbin/lsmod | /bin/cut -f1 -d" " 2>/dev/null | /bin/grep -v Module 2>/dev/null').split('\n'): - if '' != kmod.strip(): - runcmd = runcmd + " " + kmod - if len(runcmd): - self.collectExtOutput("/sbin/modinfo " + runcmd) - self.collectExtOutput("/sbin/ksyms") - self.addCopySpec("/proc/filesystems") - self.addCopySpec("/proc/ksyms") - self.addCopySpec("/proc/slabinfo") - kver = commands.getoutput('/bin/uname -r') - depfile = "/lib/modules/%s/modules.dep" % (kver,) - self.addCopySpec(depfile) - self.addCopySpec("/etc/conf.modules") - self.addCopySpec("/etc/modules.conf") - self.addCopySpec("/etc/modprobe.conf") - self.collectExtOutput("/usr/sbin/dmidecode", root_symlink = "dmidecode") - self.collectExtOutput("/usr/sbin/dkms status") - self.addCopySpec("/proc/cmdline") - self.addCopySpec("/proc/driver") - self.addCopySpec("/proc/sys/kernel/tainted") - # trigger some sysrq's. I'm not sure I like doing it this way, but - # since we end up with the sysrq dumps in syslog whether we run the - # syslog report before or after this, I suppose I can live with it. - if self.isOptionEnabled('sysrq') and os.access("/proc/sysrq-trigger", os.W_OK) and os.access("/proc/sys/kernel/sysrq", os.R_OK): - sysrq_state = commands.getoutput("/bin/cat /proc/sys/kernel/sysrq") - commands.getoutput("/bin/echo 1 > /proc/sys/kernel/sysrq") - for key in ['m', 'p', 't']: - commands.getoutput("/bin/echo %s > /proc/sysrq-trigger" % (key,)) - commands.getoutput("/bin/echo %s > /proc/sys/kernel/sysrq" % (sysrq_state,)) - # No need to grab syslog here if we can't trigger sysrq, so keep this - # inside the if - self.addCopySpec("/var/log/messages") - - return - - def analyze(self): - infd = open("/proc/modules", "r") - modules = infd.readlines() - infd.close() - - for modname in modules: - modname=modname.split(" ")[0] - modinfo_srcver = commands.getoutput("/sbin/modinfo -F srcversion %s" % modname) - if not os.access("/sys/module/%s/srcversion" % modname, os.R_OK): - continue - infd = open("/sys/module/%s/srcversion" % modname, "r") - sys_srcver = infd.read().strip("\n") - infd.close() - if modinfo_srcver != sys_srcver: - self.addAlert("Loaded module %s differs from the one present on the file-system") - - # this would be a good moment to check the module's signature - # but at the moment there's no easy way to do that outside of - # the kernel. i will probably need to write a C lib (derived from - # the kernel sources to do this verification. - - savedtaint = os.path.join(self.cInfo['dstroot'], "/proc/sys/kernel/tainted") - infd = open(savedtaint, "r") - line = infd.read() - infd.close() - line = line.strip() - if (line != "0"): - self.addAlert("Kernel taint flag is <%s>\n" % line) - - - infd = open(self.moduleFile, "r") - modules = infd.readlines() - infd.close() - - #print(modules) - for tainter in self.taintList: - p = re.compile(tainter['regex']) - for line in modules: - if p.match(line) != None: - # found a taint match, create an alert - moduleName = line.split()[0] - self.addAlert("Check for tainted kernel by module %s, which is %s" % (moduleName, tainter['description'])) - return diff --git a/trunk/src/lib/sos/plugins/ldap.py b/trunk/src/lib/sos/plugins/ldap.py deleted file mode 100644 index 318a3ba9..00000000 --- a/trunk/src/lib/sos/plugins/ldap.py +++ /dev/null @@ -1,27 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class ldap(sos.plugintools.PluginBase): - """LDAP related information - """ - def setup(self): - self.addCopySpec("/etc/ldap.conf") - self.addCopySpec("/etc/openldap") - return - - def postproc(self): - self.doRegexSub("/etc/ldap.conf", r"(\s*bindpw\s*)\S+", r"\1***") - return diff --git a/trunk/src/lib/sos/plugins/libraries.py b/trunk/src/lib/sos/plugins/libraries.py deleted file mode 100644 index 70b63dba..00000000 --- a/trunk/src/lib/sos/plugins/libraries.py +++ /dev/null @@ -1,24 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class libraries(sos.plugintools.PluginBase): - """information on shared libraries - """ - def setup(self): - self.addCopySpec("/etc/ld.so.conf") - self.addCopySpec("/etc/ld.so.conf.d") - return - diff --git a/trunk/src/lib/sos/plugins/mail.py b/trunk/src/lib/sos/plugins/mail.py deleted file mode 100644 index 0d4dda29..00000000 --- a/trunk/src/lib/sos/plugins/mail.py +++ /dev/null @@ -1,25 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class mail(sos.plugintools.PluginBase): - """mail server related information - """ - def setup(self): - self.addCopySpec("/etc/mail") - self.addCopySpec("/etc/postfix/main.cf") - self.addCopySpec("/etc/postfix/master.cf") - return - diff --git a/trunk/src/lib/sos/plugins/memory.py b/trunk/src/lib/sos/plugins/memory.py deleted file mode 100644 index 7fbe39c3..00000000 --- a/trunk/src/lib/sos/plugins/memory.py +++ /dev/null @@ -1,30 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class memory(sos.plugintools.PluginBase): - """memory usage information - """ - def setup(self): - self.addCopySpec("/proc/pci") - self.addCopySpec("/proc/meminfo") - self.addCopySpec("/proc/vmstat") - self.addCopySpec("/proc/slabinfo") - - self.collectExtOutput("/bin/dmesg | grep -e 'e820.' -e 'aperature.'") - self.collectExtOutput("/usr/bin/free", root_symlink = "free") - self.collectExtOutput("/usr/bin/free -m") - return - diff --git a/trunk/src/lib/sos/plugins/named.py b/trunk/src/lib/sos/plugins/named.py deleted file mode 100644 index 68d56ca0..00000000 --- a/trunk/src/lib/sos/plugins/named.py +++ /dev/null @@ -1,36 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import commands -import os - -class named(sos.plugintools.PluginBase): - """named related information - """ - def setup(self): - dnsdir = "" - self.addCopySpec("/etc/named.boot") - self.addCopySpec("/etc/named.conf") - self.addCopySpec("/etc/sysconfig/named") - if os.access("/etc/named.conf", os.R_OK): - dnsdir = commands.getoutput("/bin/grep -i directory /etc/named.conf | /bin/gawk '{print $2}' | /bin/sed 's/\\\"//g' | /bin/sed 's/\;//g'") - if os.access("/etc/named.boot", os.R_OK): - dnsdir = commands.getoutput("/bin/grep -i directory /etc/named.boot | /bin/gawk '{print $2}' | /bin/sed 's/\\\"//g' | /bin/sed 's/\;//g'") - if '' != dnsdir.strip(): - self.addCopySpec(dnsdir) - self.addForbiddenPath('/var/named/chroot/proc') - self.addForbiddenPath('/var/named/chroot/dev') - return - diff --git a/trunk/src/lib/sos/plugins/networking.py b/trunk/src/lib/sos/plugins/networking.py deleted file mode 100644 index 54723663..00000000 --- a/trunk/src/lib/sos/plugins/networking.py +++ /dev/null @@ -1,75 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import os,re,commands - -class networking(sos.plugintools.PluginBase): - """network related information - """ - optionList = [("traceroute", "collects a traceroute to rhn.redhat.com", "slow", 0)] - - def get_interface_name(self,ifconfigFile): - """Return a dictionary for which key are interface name according to the - output of ifconifg-a stored in ifconfigFile. - """ - out={} - if(os.path.isfile(ifconfigFile)): - f=open(ifconfigFile,'r') - content=f.read() - f.close() - reg=re.compile(r"^(eth\d+)\D",re.MULTILINE) - for name in reg.findall(content): - out[name]=1 - return out - - def collectIPTable(self,tablename): - """ When running the iptables command, it unfortunately auto-loads - the modules before trying to get output. Some people explicitly - don't want this, so check if the modules are loaded before running - the command. If they aren't loaded, there can't possibly be any - relevant rules in that table """ - - cmd = "/sbin/iptables -t "+tablename+" -nvL" - - (status, output) = commands.getstatusoutput("/sbin/lsmod | grep -q "+tablename) - if status == 0: - self.collectExtOutput(cmd) - else: - self.writeTextToCommand(cmd,"IPTables module "+tablename+" not loaded\n") - - def setup(self): - self.addCopySpec("/etc/nsswitch.conf") - self.addCopySpec("/etc/yp.conf") - self.addCopySpec("/etc/inetd.conf") - self.addCopySpec("/etc/xinetd.conf") - self.addCopySpec("/etc/xinetd.d") - self.addCopySpec("/etc/host*") - self.addCopySpec("/etc/resolv.conf") - ifconfigFile=self.collectExtOutput("/sbin/ifconfig -a", root_symlink = "ifconfig") - self.collectExtOutput("/sbin/route -n", root_symlink = "route") - self.collectExtOutput("/sbin/ipchains -nvL") - self.collectIPTable("filter") - self.collectIPTable("nat") - self.collectIPTable("mangle") - self.collectExtOutput("/bin/netstat -nap") - if ifconfigFile: - for eth in self.get_interface_name(ifconfigFile): - self.collectExtOutput("/sbin/ethtool "+eth) - if self.isOptionEnabled("traceroute"): - # The semicolon prevents the browser from thinking this is a link when viewing the report - self.collectExtOutput("/bin/traceroute rhn.redhat.com;") - - return - diff --git a/trunk/src/lib/sos/plugins/nfsserver.py b/trunk/src/lib/sos/plugins/nfsserver.py deleted file mode 100644 index 6c894177..00000000 --- a/trunk/src/lib/sos/plugins/nfsserver.py +++ /dev/null @@ -1,27 +0,0 @@ -## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class nfsserver(sos.plugintools.PluginBase): - """NFS server-related information - """ - def setup(self): - self.addCopySpec("/etc/exports") - self.collectExtOutput("/usr/sbin/rpcinfo -p localhost") - self.collectExtOutput("/usr/sbin/nfsstat") - return - diff --git a/trunk/src/lib/sos/plugins/pam.py b/trunk/src/lib/sos/plugins/pam.py deleted file mode 100644 index 8164bba3..00000000 --- a/trunk/src/lib/sos/plugins/pam.py +++ /dev/null @@ -1,25 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class pam(sos.plugintools.PluginBase): - """PAM related information - """ - def setup(self): - self.addCopySpec("/etc/pam.d") - self.addCopySpec("/etc/security") - self.collectExtOutput("/bin/ls -laF /lib/security/pam_*so") - return - diff --git a/trunk/src/lib/sos/plugins/printing.py b/trunk/src/lib/sos/plugins/printing.py deleted file mode 100644 index 76a476eb..00000000 --- a/trunk/src/lib/sos/plugins/printing.py +++ /dev/null @@ -1,24 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class printing(sos.plugintools.PluginBase): - """printing related information (cups) - """ - def setup(self): - self.addCopySpec("/etc/cups/*.conf") - self.addCopySpec("/var/log/cups") - return - diff --git a/trunk/src/lib/sos/plugins/process.py b/trunk/src/lib/sos/plugins/process.py deleted file mode 100644 index 7ed13a5e..00000000 --- a/trunk/src/lib/sos/plugins/process.py +++ /dev/null @@ -1,24 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class process(sos.plugintools.PluginBase): - """process information - """ - def setup(self): - self.collectExtOutput("/bin/ps auxww", root_symlink = "ps") - self.collectExtOutput("/usr/bin/pstree", root_symlink = "pstree") - return - diff --git a/trunk/src/lib/sos/plugins/radius.py b/trunk/src/lib/sos/plugins/radius.py deleted file mode 100644 index 7ab53810..00000000 --- a/trunk/src/lib/sos/plugins/radius.py +++ /dev/null @@ -1,29 +0,0 @@ -## Copyright (C) 2007 Navid Sheikhol-Eslami <navid@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class radius(sos.plugintools.PluginBase): - """radius related information - """ - def setup(self): - self.addCopySpec("/etc/raddb") - self.addCopySpec("/etc/pam.d/radiusd") - return - - def postproc(self): - self.doRegexSub("/etc/raddb/sql.conf", r"(\s*password\s*=\s*)\S+", r"\1***") - return diff --git a/trunk/src/lib/sos/plugins/rhn.py b/trunk/src/lib/sos/plugins/rhn.py deleted file mode 100644 index 049e51bc..00000000 --- a/trunk/src/lib/sos/plugins/rhn.py +++ /dev/null @@ -1,91 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -from sos.plugintools import PluginBase - -class rhn(PluginBase): - """RHN server related information - """ - def checkenabled(self): - # XXX check for the presence of requisite packages - satellite = self.cInfo["policy"].pkgByName("rhns-satellite-tools") - proxy = self.cInfo["policy"].pkgByName("rhns-proxy-tools") - if not satellite and not proxy: - return False - return True - - def setup(self): - # - # First, grab things needed from both Satellite and Proxy systems - # - # TODO: add chain load so we can use existing modules for httpd, &c. - # - - # basic RHN logs and configs - self.addCopySpec("/var/log/rhn*") - self.addCopySpec("/etc/rhn") - self.collectExtOutput("/usr/share/rhn/up2date_client/hardware.py") - - # httpd - self.addCopySpec("/etc/httpd/conf") - self.addCopySpec("/var/log/httpd") - - # RPM manifests - self.collectExtOutput("/bin/rpm -qa --last | sort") - - # monitoring scout logs - self.addCopySpec("/home/nocpulse/var/*.log*") - self.addCopySpec("/home/nocpulse/var/commands/*.log*") - - satellite = self.cInfo["policy"].pkgByName("rhns-satellite-tools") - proxy = self.cInfo["policy"].pkgByName("rhns-proxy-tools") - - # - # Now, go for product-specific data - # - if satellite: - self.setupSatellite(satellite) - - if proxy: - self.setupProxy(proxy) - - def setupSatellite(self, satellite): - self.collectExtOutput("/usr/bin/rhn-schema-version") - self.collectExtOutput("/usr/bin/rhn-charsets") - - # oracle - self.addCopySpec("/etc/tnsnames.ora") - - # tomcat (4.x and newer satellites only) - if not self.cInfo["policy"].pkgNVRA(satellite)[1].startswith("3."): - self.addCopySpec("/etc/tomcat5") - self.addCopySpec("/var/log/tomcat5") - - # jabberd - # - logs to /var/log/messages - self.addCopySpec("/etc/jabberd") - - # SSL build - self.addCopySpec("/root/ssl-build") - - # monitoring logs - self.addCopySpec("/opt/notification/var/*.log*") - self.addCopySpec("/var/tmp/ack_handler.log*") - self.addCopySpec("/var/tmp/enqueue.log*") - - def setupProxy(self, proxy): - # squid - self.addCopySpec("/etc/squid") - self.addCopySpec("/var/log/squid") - diff --git a/trunk/src/lib/sos/plugins/rpm.py b/trunk/src/lib/sos/plugins/rpm.py deleted file mode 100644 index b6fdb699..00000000 --- a/trunk/src/lib/sos/plugins/rpm.py +++ /dev/null @@ -1,33 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class rpm(sos.plugintools.PluginBase): - """RPM information - """ - optionList = [("rpmq", "Queries for package information via rpm -q", "fast", 1), - ("rpmva", "Runs a verify on all packages", "slow", 1)] - - def setup(self): - self.addCopySpec("/var/log/rpmpkgs") - - if self.isOptionEnabled("rpmq"): - self.collectExtOutput("/bin/rpm -qa --qf \"%{NAME}-%{VERSION}-%{RELEASE}-%{ARCH}\n\"", root_symlink = "installed-rpms") - - if self.isOptionEnabled("rpmva"): - self.eta_weight += 800 # this plugins takes 200x longer (for ETA) - self.collectExtOutput("/bin/rpm -Va", root_symlink = "rpm-Va") - return - diff --git a/trunk/src/lib/sos/plugins/samba.py b/trunk/src/lib/sos/plugins/samba.py deleted file mode 100644 index ec65370e..00000000 --- a/trunk/src/lib/sos/plugins/samba.py +++ /dev/null @@ -1,26 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class samba(sos.plugintools.PluginBase): - """Samba related information - """ - def setup(self): - self.addCopySpec("/etc/samba") - self.addCopySpec("/var/log/samba/*") - self.collectExtOutput("/usr/bin/wbinfo -g") - self.collectExtOutput("/usr/bin/wbinfo -u") - return - diff --git a/trunk/src/lib/sos/plugins/satellite.py b/trunk/src/lib/sos/plugins/satellite.py deleted file mode 100644 index 930d11b0..00000000 --- a/trunk/src/lib/sos/plugins/satellite.py +++ /dev/null @@ -1,53 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class satellite(sos.plugintools.PluginBase): - """RHN Satellite related information - """ - - def defaultenabled(self): - return False - - def setup(self): - self.addCopySpec("/etc/httpd/conf") - self.addCopySpec("/etc/rhn") - self.addCopySpec("/etc/sysconfig/rhn") - self.addCopySpec("/etc/tnsnames.ora") - self.addCopySpec("/var/log/httpd") # httpd-logs - self.addCopySpec("/var/log/rhn*") # rhn-logs - self.addCopySpec("/var/log/rhn/rhn-database-installation.log") - self.addCopySpec("/etc/jabberd") - - # tomcat for satellite 400+ - self.addCopySpec("/etc/tomcat5") - self.addCopySpec("/var/log/tomcat5") - - # all these used to go in $DIR/mon-logs - self.addCopySpec("/opt/notification/var/*.log*") - self.addCopySpec("/var/tmp/ack_handler.log*") - self.addCopySpec("/var/tmp/enqueue.log*") - - self.addCopySpec("/home/nocpulse/var/*.log*") - self.addCopySpec("/home/nocpulse/var/commands/*.log*") - self.addCopySpec("/var/tmp/ack_handler.log*") - self.addCopySpec("/var/tmp/enqueue.log*") - - self.addCopySpec("/root/ssl-build") - self.addCopySpec("rpm -qa --last") # $DIR/rpm-manifest - self.addCopySpec("/usr/bin/rhn-schema-version") # $DIR/database-schema-version - self.addCopySpec("/usr/bin/rhn-charsets") # $DIR/database-character-sets - - return diff --git a/trunk/src/lib/sos/plugins/selinux.py b/trunk/src/lib/sos/plugins/selinux.py deleted file mode 100644 index 897c3991..00000000 --- a/trunk/src/lib/sos/plugins/selinux.py +++ /dev/null @@ -1,36 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import commands - -class selinux(sos.plugintools.PluginBase): - """selinux related information - """ - def setup(self): - self.addCopySpec("/etc/selinux/*") - self.collectExtOutput("/usr/bin/selinuxconfig") - self.collectExtOutput("/usr/sbin/sestatus", root_symlink = "sestatus") - self.collectExtOutput("/bin/rpm -q -V selinux-policy-targeted") - self.collectExtOutput("/bin/rpm -q -V selinux-policy-strict") - return - - def checkenabled(self): - # is selinux enabled ? - try: - if commands.getoutput("/usr/sbin/sestatus").split(":")[1].strip() == "disabled": - return False - except: - pass - return True diff --git a/trunk/src/lib/sos/plugins/sendmail.py b/trunk/src/lib/sos/plugins/sendmail.py deleted file mode 100644 index d95b5d7b..00000000 --- a/trunk/src/lib/sos/plugins/sendmail.py +++ /dev/null @@ -1,27 +0,0 @@ -## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class sendmail(sos.plugintools.PluginBase): - """sendmail information - """ - def setup(self): - self.addCopySpec("/etc/mail/*") - self.addCopySpec("/var/log/maillog") - self.collectExtOutput("/sbin/chkconfig --list sendmail") - return - diff --git a/trunk/src/lib/sos/plugins/squid.py b/trunk/src/lib/sos/plugins/squid.py deleted file mode 100644 index 4544ef9a..00000000 --- a/trunk/src/lib/sos/plugins/squid.py +++ /dev/null @@ -1,23 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class squid(sos.plugintools.PluginBase): - """squid related information - """ - def setup(self): - self.addCopySpec("/etc/squid/squid.conf") - return - diff --git a/trunk/src/lib/sos/plugins/ssh.py b/trunk/src/lib/sos/plugins/ssh.py deleted file mode 100644 index 92a4c9e5..00000000 --- a/trunk/src/lib/sos/plugins/ssh.py +++ /dev/null @@ -1,27 +0,0 @@ -## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class ssh(sos.plugintools.PluginBase): - """ssh-related information - """ - def setup(self): - self.addCopySpec("/etc/ssh/ssh_config") - self.addCopySpec("/etc/ssh/sshd_config") - self.collectExtOutput("/sbin/chkconfig --list sshd") - return - diff --git a/trunk/src/lib/sos/plugins/startup.py b/trunk/src/lib/sos/plugins/startup.py deleted file mode 100644 index 02361393..00000000 --- a/trunk/src/lib/sos/plugins/startup.py +++ /dev/null @@ -1,25 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class startup(sos.plugintools.PluginBase): - """startup information - """ - def setup(self): - self.addCopySpec("/etc/rc.d") - - self.collectExtOutput("/sbin/chkconfig --list", root_symlink = "chkconfig") - return - diff --git a/trunk/src/lib/sos/plugins/system.py b/trunk/src/lib/sos/plugins/system.py deleted file mode 100644 index 19d7859e..00000000 --- a/trunk/src/lib/sos/plugins/system.py +++ /dev/null @@ -1,31 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class system(sos.plugintools.PluginBase): - """core system related information - """ - def setup(self): - self.addCopySpec("/proc/sys") - self.addCopySpec("/etc/sysctl.conf") - self.addCopySpec("/etc/cron*") - self.addCopySpec("/etc/syslog.conf") - self.addCopySpec("/etc/ntp.conf") - self.addCopySpec("/etc/ntp/step-tickers") - self.addCopySpec("/etc/ntp/ntpservers") - self.addCopySpec("/etc/auto.*") - - return - diff --git a/trunk/src/lib/sos/plugins/systemtap.py b/trunk/src/lib/sos/plugins/systemtap.py deleted file mode 100644 index b99ce0cf..00000000 --- a/trunk/src/lib/sos/plugins/systemtap.py +++ /dev/null @@ -1,29 +0,0 @@ -## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class systemtap(sos.plugintools.PluginBase): - """SystemTap pre-requisites information - """ - def setup(self): - # requires systemtap, systemtap-runtime, kernel-devel, - # kernel-debuginfo, kernel-debuginfo-common - self.collectExtOutput("/bin/rpm -qa | /bin/egrep -e kernel.*`uname -r` -e systemtap -e elfutils | sort") - self.collectExtOutput("/usr/bin/stap -V 2") - self.collectExtOutput("/bin/uname -r") - return - diff --git a/trunk/src/lib/sos/plugins/x11.py b/trunk/src/lib/sos/plugins/x11.py deleted file mode 100644 index 9b7b7ac9..00000000 --- a/trunk/src/lib/sos/plugins/x11.py +++ /dev/null @@ -1,26 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class x11(sos.plugintools.PluginBase): - """X related information - """ - def setup(self): - self.addCopySpec("/etc/X11") - self.addCopySpec("/var/log/Xorg.*.log") - self.addCopySpec("/var/log/XFree86.*.log") - self.collectExtOutput("/bin/dmesg | grep -e 'agpgart.'") - return - diff --git a/trunk/src/lib/sos/plugins/xen.py b/trunk/src/lib/sos/plugins/xen.py deleted file mode 100644 index d6daec63..00000000 --- a/trunk/src/lib/sos/plugins/xen.py +++ /dev/null @@ -1,82 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools -import os, commands -from stat import * - -class xen(sos.plugintools.PluginBase): - """Xen related information - """ - def determineXenHost(self): - if os.access("/proc/acpi/dsdt", os.R_OK): - (status, output) = commands.getstatusoutput("/usr/bin/strings /proc/acpi/dsdt | grep -q int-xen") - if status == 0: - return "hvm" - - if os.access("/proc/xen/capabilities", os.R_OK): - (status, output) = commands.getstatusoutput("grep -q control_d /proc/xen/capabilities") - if status == 0: - return "dom0" - else: - return "domU" - return "baremetal" - - def checkenabled(self): - if self.determineXenHost() == "baremetal": - return False - return True - - def domCollectProc(self): - self.addCopySpec("/proc/xen/balloon") - self.addCopySpec("/proc/xen/capabilities") - self.addCopySpec("/proc/xen/xsd_kva") - self.addCopySpec("/proc/xen/xsd_port") - # determine if CPU has PAE support - self.collectExtOutput("/bin/grep pae /proc/cpuinfo") - # determine if CPU has Intel-VT or AMD-V support - self.collectExtOutput("/bin/egrep -e 'vmx|svm' /proc/cpuinfo") - - def setup(self): - host_type = self.determineXenHost() - if host_type == "domU": - # we should collect /proc/xen and /sys/hypervisor - self.domCollectProc() - # determine if hardware virtualization support is enabled - # in BIOS: /sys/hypervisor/properties/capabilities - self.addCopySpec("/sys/hypervisor") - elif host_type == "hvm": - # what do we collect here??? - pass - elif host_type == "dom0": - # default of dom0, collect lots of system information - self.addCopySpec("/var/log/xen") - self.addCopySpec("/etc/xen") - self.collectExtOutput("/usr/bin/xenstore-ls") - self.collectExtOutput("/usr/sbin/xm dmesg") - self.collectExtOutput("/usr/sbin/xm info") - self.collectExtOutput("/usr/sbin/brctl show") - self.domCollectProc() - self.addCopySpec("/sys/hypervisor") - # FIXME: we *might* want to collect things in /sys/bus/xen*, - # /sys/class/xen*, /sys/devices/xen*, /sys/modules/blk*, - # /sys/modules/net*, but I've never heard of them actually being - # useful, so I'll leave it out for now - else: - # for bare-metal, we don't have to do anything special - return - - self.addCustomText("Xen hostType: "+host_type) - return - diff --git a/trunk/src/lib/sos/plugins/xinetd.py b/trunk/src/lib/sos/plugins/xinetd.py deleted file mode 100644 index 715c831f..00000000 --- a/trunk/src/lib/sos/plugins/xinetd.py +++ /dev/null @@ -1,27 +0,0 @@ -## Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class xinetd(sos.plugintools.PluginBase): - """xinetd information - """ - def setup(self): - self.addCopySpec("/etc/xinetd.conf") - self.addCopySpec("/etc/xinetd.d/*") - self.collectExtOutput("/sbin/chkconfig --list xinetd") - return - diff --git a/trunk/src/lib/sos/plugins/yum.py b/trunk/src/lib/sos/plugins/yum.py deleted file mode 100644 index 89102c38..00000000 --- a/trunk/src/lib/sos/plugins/yum.py +++ /dev/null @@ -1,37 +0,0 @@ -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import sos.plugintools - -class yum(sos.plugintools.PluginBase): - """yum information - """ - - def defaultenabled(self): - # enable with -e or -o - return False - - def setup(self): - # Pull all yum related information - self.addCopySpec("/etc/yum") - self.addCopySpec("/etc/yum.repos.d") - self.addCopySpec("/etc/yum.conf") - self.addCopySpec("/var/log/yum.log") - - # Get a list of channels the machine is subscribed to. - self.collectExtOutput("/bin/echo \"repo list\" | /usr/bin/yum shell") - # List various information about available packages - self.collectExtOutput("/usr/bin/yum list") - - return diff --git a/trunk/src/lib/sos/plugintools.py b/trunk/src/lib/sos/plugintools.py deleted file mode 100644 index 238036ce..00000000 --- a/trunk/src/lib/sos/plugintools.py +++ /dev/null @@ -1,568 +0,0 @@ -## plugintools.py -## This exports methods available for use by plugins for sos - -## Copyright (C) 2006 Steve Conklin <sconklin@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -# pylint: disable-msg = R0902 -# pylint: disable-msg = R0904 -# pylint: disable-msg = W0702 -# pylint: disable-msg = W0703 -# pylint: disable-msg = R0201 -# pylint: disable-msg = W0611 -# pylint: disable-msg = W0613 - -""" -This is the base class for sosreport plugins -""" -from sos.helpers import * -from threading import Thread, activeCount -import os, os.path, sys, string, itertools, glob, re, traceback -import logging -from stat import * -from time import time - -class PluginBase: - """ - Base class for plugins - """ - def __init__(self, pluginname, commons): - # pylint: disable-msg = E0203 - try: - len(self.optionList) - except: - self.optionList = [] - # pylint: enable-msg = E0203 - self.copiedFiles = [] - self.copiedDirs = [] - self.executedCommands = [] - self.diagnose_msgs = [] - self.alerts = [] - self.customText = "" - self.optNames = [] - self.optParms = [] - self.piName = pluginname - self.cInfo = commons - self.forbiddenPaths = [] - self.copyPaths = [] - self.collectProgs = [] - self.thread = None - self.pid = None - self.eta_weight = 1 - self.time_start = None - self.time_stop = None - - self.soslog = logging.getLogger('sos') - - # get the option list into a dictionary - for opt in self.optionList: - self.optNames.append(opt[0]) - self.optParms.append({'desc':opt[1], 'speed':opt[2], 'enabled':opt[3]}) - - # Method for applying regexp substitutions - def doRegexSub(self, srcpath, regexp, subst): - '''Apply a regexp substitution to a file archived by sosreport. - ''' - if len(self.copiedFiles): - for afile in self.copiedFiles: - if afile['srcpath'] == srcpath: - abspath = os.path.join(self.cInfo['dstroot'], srcpath.lstrip(os.path.sep)) - try: - fp = open(abspath, 'r') - tmpout, occurs = re.subn( regexp, subst, fp.read() ) - fp.close() - if occurs > 0: - fp = open(abspath,'w') - fp.write(tmpout) - fp.close() - return occurs - except SystemExit: - raise SystemExit - except KeyboardInterrupt: - raise KeyboardInterrupt - except Exception, e: - self.soslog.log(logging.VERBOSE, "Problem at path %s (%s)" % (abspath,e)) - break - return False - - # Methods for copying files and shelling out - def doCopyFileOrDir(self, srcpath): - # pylint: disable-msg = R0912 - # pylint: disable-msg = R0915 - ''' Copy file or directory to the destination tree. If a directory, then everything - below it is recursively copied. A list of copied files are saved for use later - in preparing a report - ''' - copyProhibited = 0 - for path in self.forbiddenPaths: - if ( srcpath.count(path) > 0 ): - copyProhibited = 1 - - if copyProhibited: - return '' - - if os.path.islink(srcpath): - # This is a symlink - We need to also copy the file that it points to - # file and dir symlinks ar ehandled the same - link = os.readlink(srcpath) - if os.path.isabs(link): - # the link was an absolute path, and will not point to the new - # tree. We must adjust it. - - # What's the name of the symlink on the dest tree? - dstslname = os.path.join(self.cInfo['dstroot'], srcpath.lstrip(os.path.sep)) - - # make sure the dst dir exists - if not (os.path.exists(os.path.dirname(dstslname)) and os.path.isdir(os.path.dirname(dstslname))): - # create the directory - os.makedirs(os.path.dirname(dstslname)) - - dstsldir = os.path.join(self.cInfo['dstroot'], link.lstrip(os.path.sep)) - # Create the symlink on the dst tree - rpth = sosRelPath(os.path.dirname(dstslname), dstsldir) - os.symlink(rpth, dstslname) - else: - # no adjustment, symlink is the relative path - dstslname = link - - if os.path.isdir(srcpath): - for afile in os.listdir(srcpath): - if afile == '.' or afile == '..': - pass - else: - try: - abspath = self.doCopyFileOrDir(srcpath+'/'+afile) - except SystemExit: - raise SystemExit - except KeyboardInterrupt: - raise KeyboardInterrupt - except Exception, e: - self.soslog.warning(traceback.format_exc()) - - # if on forbidden list, abspath is null - if not abspath == '': - dstslname = sosRelPath(self.cInfo['rptdir'], abspath) - self.copiedDirs.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link}) - else: - try: - dstslname, abspath = self.__copyFile(srcpath) - self.copiedFiles.append({'srcpath':srcpath, 'dstpath':dstslname, 'symlink':"yes", 'pointsto':link}) - self.cInfo['xmlreport'].add_file(srcpath,os.stat(srcpath)) - except SystemExit: - raise SystemExit - except KeyboardInterrupt: - raise KeyboardInterrupt - except Exception, e: - self.soslog.log(logging.VERBOSE, "Problem at path %s (%s)" % (srcpath, e)) - - return abspath - - else: - if not os.path.exists(srcpath): - self.soslog.debug("File or directory %s does not exist\n" % srcpath) - elif os.path.isdir(srcpath): - for afile in os.listdir(srcpath): - if afile == '.' or afile == '..': - pass - else: - self.doCopyFileOrDir(srcpath+'/'+afile) - else: - # This is not a directory or a symlink - tdstpath, abspath = self.__copyFile(srcpath) - self.copiedFiles.append({'srcpath':srcpath, 'dstpath':tdstpath, 'symlink':"no"}) # save in our list - return abspath - - def __copyFile(self, src): - """ call cp to copy a file, collect return status and output. Returns the - destination file name. - """ - try: - # pylint: disable-msg = W0612 - status, shout, runtime = sosGetCommandOutput("/bin/cp --parents -P --preserve=mode,ownership,timestamps,links " + src +" " + self.cInfo['dstroot']) - if status: - self.soslog.debug(shout) - abspath = os.path.join(self.cInfo['dstroot'], src.lstrip(os.path.sep)) - relpath = sosRelPath(self.cInfo['rptdir'], abspath) - return relpath, abspath - except SystemExit: - raise SystemExit - except KeyboardInterrupt: - raise KeyboardInterrupt - except Exception,e: - self.soslog.warning("Problem copying file %s (%s)" % (src, e)) - - def addForbiddenPath(self, forbiddenPath): - """Specify a path to not copy, even if it's part of a copyPaths[] entry. - Note: do NOT use globs here. - """ - self.forbiddenPaths.append(forbiddenPath) - - def getAllOptions(self): - """ - return a list of all options selected - """ - return (self.optNames, self.optParms) - - def setOption(self, optionname, enable): - ''' enable or disable the named option. - ''' - for name, parms in zip(self.optNames, self.optParms): - if name == optionname: - parms['enabled'] = enable - - def isOptionEnabled(self, optionname): - ''' see whether the named option is enabled. - ''' - for name, parms in zip(self.optNames, self.optParms): - if name == optionname: - return parms['enabled'] - # nonexistent options aren't enabled. - return 0 - - def addCopySpecLimit(self,fname,sizelimit = None): - """Add a file specification (with limits) - """ - files = glob.glob(fname) - files.sort() - cursize = 0 - for flog in files: - cursize += os.stat(flog)[ST_SIZE] - if sizelimit and (cursize / 1024 / 1024) > sizelimit: - break - self.addCopySpec(flog) - - def addCopySpec(self, copyspec): - """ Add a file specification (can be file, dir,or shell glob) to be - copied into the sosreport by this module - """ - # Glob case handling is such that a valid non-glob is a reduced glob - for filespec in glob.glob(copyspec): - self.copyPaths.append(filespec) - - def copyFileGlob(self, srcglob): - """ Deprecated - please modify modules to use addCopySpec() - """ - sys.stderr.write("Warning: thecopyFileGlob() function has been deprecated. Please") - sys.stderr.write("use addCopySpec() instead. Calling addCopySpec() now.") - self.addCopySpec(srcglob) - - def copyFileOrDir(self, srcpath): - """ Deprecated - please modify modules to use addCopySpec() - """ - sys.stderr.write("Warning: the copyFileOrDir() function has been deprecated. Please\n") - sys.stderr.write("use addCopySpec() instead. Calling addCopySpec() now.\n") - raise ValueError - #self.addCopySpec(srcpath) - - def runExeInd(self, exe): - """ Deprecated - use callExtProg() - """ - sys.stderr.write("Warning: the runExeInd() function has been deprecated. Please use\n") - sys.stderr.write("the callExtProg() function. This should only be called\n") - sys.stderr.write("if collect() is overridden.") - pass - - def callExtProg(self, prog): - """ Execute a command independantly of the output gathering part of - sosreport - """ - # Log if binary is not runnable or does not exist - if not os.access(prog.split()[0], os.X_OK): - self.soslog.log(logging.VERBOSE, "binary '%s' does not exist or is not runnable" % prog.split()[0]) - - # pylint: disable-msg = W0612 - status, shout, runtime = sosGetCommandOutput(prog) - return status - - def runExe(self, exe): - """ Deprecated - use collectExtOutput() - """ - sys.stderr.write("Warning: the runExe() function has been deprecated. Please use\n") - sys.stderr.write("the collectExtOutput() function.\n") - pass - - def collectExtOutput(self, exe, suggest_filename = None, root_symlink = None): - """ - Run a program and collect the output - """ - self.collectProgs.append( (exe,suggest_filename,root_symlink) ) - - def makeCommandFilename(self, exe): - """ The internal function to build up a filename based on a command """ - - mangledname = re.sub(r"[^\w\-\.\/]+", "_", exe) - mangledname = re.sub(r"/", ".", mangledname).strip(" ._-")[0:64] - - outfn = self.cInfo['cmddir'] + "/" + self.piName + "/" + mangledname - - # check for collisions - inc = 0 - if os.path.exists(outfn): - inc = 2 - while True: - newfn = outfn + "_" + inc - if not os.path.exists(newfn): - break - inc +=1 - - return outfn - - def collectOutputNow(self, exe, suggest_filename = None, root_symlink = False): - """ Execute a command and save the output to a file for inclusion in - the report - """ - # First check to make sure the binary exists and is runnable. - if not os.access(exe.split()[0], os.X_OK): - self.soslog.log(logging.VERBOSE, "binary '%s' does not exist or is not runnable, trying anyways" % exe.split()[0]) - - # pylint: disable-msg = W0612 - status, shout, runtime = sosGetCommandOutput(exe) - - if suggest_filename: - outfn = self.makeCommandFilename(suggest_filename) - else: - outfn = self.makeCommandFilename(exe) - - if not os.path.isdir(os.path.dirname(outfn)): - os.mkdir(os.path.dirname(outfn)) - - outfd = open(outfn, "w") - if status == 127: outfd.write("# the command returned exit status 127, this normally means that the command was not found.\n\n") - if len(shout): outfd.write(shout+"\n") - outfd.close() - - if root_symlink: - curdir = os.getcwd() - os.chdir(self.cInfo['dstroot']) - os.symlink(outfn[len(self.cInfo['dstroot'])+1:], root_symlink.strip("/.")) - os.chdir(curdir) - - outfn = outfn[len(self.cInfo['cmddir'])+1:] - - # sosStatus(status) - # save info for later - self.executedCommands.append({'exe': exe, 'file':outfn}) # save in our list - self.cInfo['xmlreport'].add_command(cmdline=exe,exitcode=status,f_stdout=outfn,runtime=runtime) - return outfn - - def writeTextToCommand(self, exe, text): - """ A function that allows you to write a random text string to the - command output location referenced by exe; this is useful if you want - to conditionally collect information, but still want the output file - to exist so as not to confuse readers """ - - outfn = self.makeCommandFilename(exe) - - if not os.path.isdir(os.path.dirname(outfn)): - os.mkdir(os.path.dirname(outfn)) - - outfd = open(outfn, "w") - outfd.write(text) - outfd.close() - - self.executedCommands.append({'exe': exe, 'file': outfn}) # save in our list - return outfn - - # For adding warning messages regarding configuration sanity - def addDiagnose(self, alertstring): - """ Add a configuration sanity warning for this plugin. These - will be displayed on-screen before collection and in the report as well. - """ - self.diagnose_msgs.append(alertstring) - return - - # For adding output - def addAlert(self, alertstring): - """ Add an alert to the collection of alerts for this plugin. These - will be displayed in the report - """ - self.alerts.append(alertstring) - return - - - def addCustomText(self, text): - """ Append text to the custom text that is included in the report. This - is freeform and can include html. - """ - self.customText = self.customText + text - return - - def doCollect(self): - """ This function has been replaced with copyStuff(threaded = True). Please change your - module calls. Calling setup() now. - """ - return self.copyStuff(threaded = True) - - def isRunning(self): - """ - if threaded, is thread running ? - """ - if self.thread: return self.thread.isAlive() - return None - - def wait(self,timeout=None): - """ - wait for a thread to complete - only called for threaded execution - """ - self.thread.join(timeout) - return self.thread.isAlive() - - def copyStuff(self, threaded = False, semaphore = None): - """ - Collect the data for a plugin - """ - if threaded and self.thread == None: - self.thread = Thread(target=self.copyStuff, name=self.piName+'-thread', args = [True, semaphore] ) - self.thread.start() - return self.thread - - if semaphore: semaphore.acquire() - - self.soslog.log(logging.VERBOSE, "starting threaded plugin %s" % self.piName) - - self.time_start = time() - self.time_stop = None - - for path in self.copyPaths: - self.soslog.debug("copying pathspec %s" % path) - try: - self.doCopyFileOrDir(path) - except SystemExit: - raise SystemExit - except KeyboardInterrupt: - raise KeyboardInterrupt - except Exception, e: - self.soslog.log(logging.VERBOSE, "error copying from pathspec %s (%s), traceback follows:" % (path,e)) - self.soslog.log(logging.VERBOSE, traceback.format_exc()) - for (prog,suggest_filename,root_symlink) in self.collectProgs: - self.soslog.debug("collecting output of '%s'" % prog) - try: - self.collectOutputNow(prog, suggest_filename, root_symlink) - except SystemExit: - raise SystemExit - except KeyboardInterrupt: - raise KeyboardInterrupt - except: - self.soslog.log(logging.VERBOSE, "error collection output of '%s', traceback follows:" % prog) - self.soslog.log(logging.VERBOSE, traceback.format_exc()) - - self.time_stop = time() - - if semaphore: semaphore.release() - self.soslog.log(logging.VERBOSE, "plugin %s returning" % self.piName) - - def get_description(self): - """ This function will return the description for the plugin""" - try: - return self.__doc__.strip() - except: - return "<no description available>" - - def checkenabled(self): - """ This function can be overidden to let the plugin decide whether - it should run or not. - """ - return True - - def defaultenabled(self): - """This devices whether a plugin should be automatically loaded or - only if manually specified in the command line.""" - return True - - def collect(self): - """ This function has been replaced with setup(). Please change your - module calls. Calling setup() now. - """ - self.setup() - - def diagnose(self): - """This class must be overridden to check the sanity of the system's - configuration before the collection begins. - """ - pass - - def setup(self): - """This class must be overridden to add the copyPaths, forbiddenPaths, - and external programs to be collected at a minimum. - """ - pass - - def analyze(self): - """ - perform any analysis. To be replaced by a plugin if desired - """ - pass - - def postproc(self): - """ - perform any postprocessing. To be replaced by a plugin if desired - """ - pass - - def report(self): - """ Present all information that was gathered in an html file that allows browsing - the results. - """ - # make this prettier - html = '<hr/><a name="%s"></a>\n' % self.piName - - # Intro - html = html + "<h2> Plugin <em>" + self.piName + "</em></h2>\n" - - # Files - if len(self.copiedFiles): - html = html + "<p>Files copied:<br><ul>\n" - for afile in self.copiedFiles: - html = html + '<li><a href="%s">%s</a>' % (afile['dstpath'], afile['srcpath']) - if (afile['symlink'] == "yes"): - html = html + " (symlink to %s)" % afile['pointsto'] - html = html + '</li>\n' - html = html + "</ul></p>\n" - - # Dirs - if len(self.copiedDirs): - html = html + "<p>Directories Copied:<br><ul>\n" - for adir in self.copiedDirs: - html = html + '<li><a href="%s">%s</a>\n' % (adir['dstpath'], adir['srcpath']) - if (adir['symlink'] == "yes"): - html = html + " (symlink to %s)" % adir['pointsto'] - html = html + '</li>\n' - html = html + "</ul></p>\n" - - # Command Output - if len(self.executedCommands): - html = html + "<p>Commands Executed:<br><ul>\n" - # convert file name to relative path from our root - for cmd in self.executedCommands: - cmdOutRelPath = sosRelPath(self.cInfo['rptdir'], cmd['file']) - html = html + '<li><a href="%s">%s</a></li>\n' % (cmdOutRelPath, cmd['exe']) - html = html + "</ul></p>\n" - - # Alerts - if len(self.alerts): - html = html + "<p>Alerts:<br><ul>\n" - for alert in self.alerts: - html = html + '<li>%s</li>\n' % alert - html = html + "</ul></p>\n" - - # Custom Text - if (self.customText != ""): - html = html + "<p>Additional Information:<br>\n" - html = html + self.customText + "</p>\n" - - return html - - diff --git a/trunk/src/lib/sos/policyredhat.py b/trunk/src/lib/sos/policyredhat.py deleted file mode 100755 index d4a4074d..00000000 --- a/trunk/src/lib/sos/policyredhat.py +++ /dev/null @@ -1,151 +0,0 @@ -## policy-redhat.py -## Implement policies required for the sos system support tool - -## Copyright (C) Steve Conklin <sconklin@redhat.com> - -### This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. - -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. - -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -import os -import commands -import sys -import string -from tempfile import gettempdir -from sos.helpers import * -import random - -SOME_PATH = "/tmp/SomePath" - -#class SosError(Exception): -# def __init__(self, code, message): -# self.code = code -# self.message = message -# -# def __str__(self): -# return 'Sos Error %s: %s' % (self.code, self.message) - - -class SosPolicy: - "This class implements various policies for sos" - def __init__(self): - #print "Policy init" - return - - def setCommons(self, commons): - self.cInfo = commons - return - - def validatePlugin(self, pluginpath): - "Validates the plugin as being acceptable to run" - # return value - # TODO implement this - #print "validating %s" % pluginpath - return True - - def allPkgsByName(self, name): - # FIXME: we're relying on rpm to sort the output list - cmd = "/bin/rpm --qf '%%{N}-%%{V}-%%{R}-%%{ARCH}\n' -q %s" % (name,) - pkgs = os.popen(cmd).readlines() - return [pkg[:-1] for pkg in pkgs if pkg.startswith(name)] - - def pkgByName(self, name): - # TODO: do a full NEVRA compare and return newest version, best arch - try: - # lame attempt at locating newest - pkg = self.allPkgsByName(name)[-1] - except IndexError: - pkg = None - - return pkg - - def pkgDictByName(self, name): - pkgName = self.pkgByName(name) - if pkgName and len(pkgName) > len(name): - return pkgName[len(name)+1:].split("-") - else: - return None - - def runlevelByService(self, name): - ret = [] - try: - for tabs in commands.getoutput("/sbin/chkconfig --list %s" % name).split(): - (runlevel, onoff) = tabs.split(":") - if onoff == "on": - ret.append(int(runlevel)) - except: - pass - return ret - - def runlevelDefault(self): - # FIXME: get this from /etc/inittab - return 3 - - def pkgNVRA(self, pkg): - fields = pkg.split("-") - version, release, arch = fields[-3:] - name = "-".join(fields[:-3]) - return (name, version, release, arch) - - def packageResults(self): - localname = commands.getoutput("/bin/uname -n").split(".")[0] - - try: - name = raw_input("Please enter your first initial and last name [%s]: " % localname) - if len(name) == 0: name = localname - - ticketNumber = raw_input("Please enter the case number that you are generating this report for: ") - except KeyboardInterrupt: - print _("<interrupted>") - print _("Temporary files have been stored in ") % self.cInfo['dstroot'] - return - - if len(ticketNumber): - namestr = name + "." + ticketNumber - else: - namestr = name - - ourtempdir = gettempdir() - tarballName = os.path.join(ourtempdir, "sosreport-" + namestr + ".tar.bz2") - - namestr = namestr + "-" + str(random.randint(1, 999999)) - - aliasdir = os.path.join(ourtempdir, namestr) - - tarcmd = "/bin/tar -jcf %s %s" % (tarballName, namestr) - - print - print "Creating compressed tar archive..." - if not os.access(string.split(tarcmd)[0], os.X_OK): - print "Unable to create tarball" - return - - # FIXME: gotta be a better way... - os.system("/bin/mv %s %s" % (self.cInfo['dstroot'], aliasdir)) - curwd = os.getcwd() - os.chdir(ourtempdir) - oldmask = os.umask(077) - # pylint: disable-msg = W0612 - status, shout, runtime = sosGetCommandOutput(tarcmd) - os.umask(oldmask) - os.chdir(curwd) - # FIXME: use python internal command - os.system("/bin/mv %s %s" % (aliasdir, self.cInfo['dstroot'])) - - sys.stdout.write("\n") - print "Your sosreport has been generated and saved in %s" % tarballName - print "Please send this file to your support representative." - sys.stdout.write("\n") - - return - diff --git a/trunk/src/locale/en/LC_MESSAGES/sos.po b/trunk/src/locale/en/LC_MESSAGES/sos.po deleted file mode 100644 index c103a495..00000000 --- a/trunk/src/locale/en/LC_MESSAGES/sos.po +++ /dev/null @@ -1,99 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2007-07-14 11:57\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: utf-8\n" -"Generated-By: pygettext.py 1.5\n" - - -#: sosreport:399 -msgid "sosreport (version %s)" -msgstr "" - -#: sosreport:417 -msgid "plugin %s does not validate, skipping" -msgstr "" - -#: sosreport:421 -msgid "plug %s skipped (noplugins)" -msgstr "" - -#: sosreport:425 -msgid "plugin %s is inactive (use -e or -o to enable)." -msgstr "" - -#: sosreport:433 -msgid "plugin %s not specified in --onlyplugin list" -msgstr "" - -#: sosreport:438 -msgid "Plugin %s does not install, skipping" -msgstr "" - -#: sosreport:441 -msgid "plugin load failed for %s" -msgstr "" - -#: sosreport:447 -msgid "processing options from plugin: %s" -msgstr "" - -#: sosreport:454 -msgid "no valid plugins found" -msgstr "" - -#: sosreport:457 -msgid "The following plugins are currently enabled:" -msgstr "" - -#: sosreport:463 -msgid "The following plugin options are available:" -msgstr "" - -#: sosreport:469 -msgid "The following plugins are currently disabled:" -msgstr "" - -#: sosreport:480 -msgid "sosreport requires root permissions to run." -msgstr "" - -#: sosreport:487 -msgid "no valid plugins were enabled" -msgstr "" - -#: sosreport:491 -msgid "" -"This utility will collect some detailed information about the\n" -"hardware and setup of your Red Hat Enterprise Linux system.\n" -"This information will be used to diagnose problems with your \n" -"system and will be considered confidential information.\n" -"Red Hat will use this information for diagnostic purposes ONLY.\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 "" - -#: sosreport:529 -msgid "Exiting." -msgstr "" - -#: sosreport:676 -msgid "Collected information is in " -msgstr "" - -#: sosreport:677 -msgid "Your html report is in " -msgstr "" - diff --git a/trunk/src/locale/it/LC_MESSAGES/sos.po b/trunk/src/locale/it/LC_MESSAGES/sos.po deleted file mode 100644 index 0b5e2b32..00000000 --- a/trunk/src/locale/it/LC_MESSAGES/sos.po +++ /dev/null @@ -1,99 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2007-07-14 12:17\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: utf-8\n" -"Generated-By: pygettext.py 1.5\n" - - -#: sosreport:399 -msgid "sosreport (version %s)" -msgstr "sosreport (versione %s)" - -#: sosreport:417 -msgid "plugin %s does not validate, skipping" -msgstr "" - -#: sosreport:421 -msgid "plug %s skipped (noplugins)" -msgstr "" - -#: sosreport:425 -msgid "plugin %s is inactive (use -e or -o to enable)." -msgstr "" - -#: sosreport:433 -msgid "plugin %s not specified in --onlyplugin list" -msgstr "" - -#: sosreport:438 -msgid "Plugin %s does not install, skipping" -msgstr "" - -#: sosreport:441 -msgid "plugin load failed for %s" -msgstr "" - -#: sosreport:447 -msgid "processing options from plugin: %s" -msgstr "" - -#: sosreport:454 -msgid "no valid plugins found" -msgstr "" - -#: sosreport:457 -msgid "The following plugins are currently enabled:" -msgstr "" - -#: sosreport:463 -msgid "The following plugin options are available:" -msgstr "" - -#: sosreport:469 -msgid "The following plugins are currently disabled:" -msgstr "" - -#: sosreport:480 -msgid "sosreport requires root permissions to run." -msgstr "" - -#: sosreport:487 -msgid "no valid plugins were enabled" -msgstr "" - -#: sosreport:491 -msgid "" -"This utility will collect some detailed information about the\n" -"hardware and setup of your Red Hat Enterprise Linux system.\n" -"This information will be used to diagnose problems with your \n" -"system and will be considered confidential information.\n" -"Red Hat will use this information for diagnostic purposes ONLY.\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 "" - -#: sosreport:529 -msgid "Exiting." -msgstr "" - -#: sosreport:676 -msgid "Collected information is in " -msgstr "" - -#: sosreport:677 -msgid "Your html report is in " -msgstr "" - diff --git a/trunk/src/pylintrc b/trunk/src/pylintrc deleted file mode 100644 index 934f5255..00000000 --- a/trunk/src/pylintrc +++ /dev/null @@ -1,354 +0,0 @@ -# lint Python modules using external checkers. -# -# This is the main checker controling the other ones and the reports -# generation. It is itself both a raw checker and an astng checker in order -# to: -# * handle message activation / deactivation at the module level -# * handle some basic but necessary stats'data (number of classes, methods...) -# -# This checker also defines the following reports: -# * R0001: Total errors / warnings -# * R0002: % errors / warnings by module -# * R0003: Messages -# * R0004: Global evaluation -[MASTER] - -# Profiled execution. -profile=no - -# Add <file or directory> to the black list. It should be a base name, not a -# path. You may set this option multiple times. -ignore=CVS - -# Pickle collected data for later comparisons. -persistent=yes - -# Set the cache size for astng objects. -cache-size=500 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - - -[REPORTS] - -# Tells wether to display a full report or only the messages -reports=yes - -# Use HTML as output format instead of text -html=no - -# Use a parseable text output format, so your favorite text editor will be able -# to jump to the line corresponding to a message. -parseable=yes - -# Colorizes text output using ansi escape codes -color=no - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=no - -# Python expression which should return a note less than 10 (10 is the highest -# note).You have access to the variables errors warning, statement which -# respectivly contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (R0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Add a comment according to your evaluation note. This is used by the global -# evaluation report (R0004). -comment=no - -# Include message's id in output -include-ids=yes - - -# checks for -# * unused variables / imports -# * undefined variables -# * redefinition of variable from builtins or from an outer scope -# * use of variable before assigment -# -[VARIABLES] - -# Enable / disable this checker -enable-variables=yes - -# Tells wether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching names used for dummy variables (i.e. not used). -dummy-variables-rgx=_|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - - -# try to find bugs in the code using type inference -# -[TYPECHECK] - -# Enable / disable this checker -enable-typecheck=yes - -# Tells wether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# When zope mode is activated, consider the acquired-members option to ignore -# access to some undefined attributes. -zope=no - -# List of members which are usually get through zope's acquisition mecanism and -# so shouldn't trigger E0201 when accessed (need zope=yes to be considered. -acquired-members=REQUEST,acl_users,aq_parent - - -# checks for : -# * doc strings -# * modules / classes / functions / methods / arguments / variables name -# * number of arguments, local variables, branchs, returns and statements in -# functions, methods -# * required module attributes -# * dangerous default values as arguments -# * redefinition of function / method / class -# * uses of the global statement -# -# This checker also defines the following reports: -# * R0101: Statistics by type -[BASIC] - -# Enable / disable this checker -enable-basic=yes - -#disable-msg=C0121 - -# Required attributes for module, separated by a comma -required-attributes= - -# Regular expression which should only match functions or classes name which do -# not require a docstring -no-docstring-rgx=__.*__ - -# Regular expression which should only match correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression which should only match correct module level names -const-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__))$ - -# Regular expression which should only match correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression which should only match correct function names -function-rgx=[a-z_][A-Za-z0-9_]{2,30}$ - -# Regular expression which should only match correct method names -method-rgx=[a-z_][A-Za-z0-9_]{2,30}$ - -# Regular expression which should only match correct instance attribute names -attr-rgx=[a-z_][A-Za-z0-9_]{2,30}$ - -# Regular expression which should only match correct argument names -argument-rgx=[a-z_][A-Za-z0-9_]{2,30}$ - -# Regular expression which should only match correct variable names -variable-rgx=[a-z_][A-Za-z0-9_]{0,30}$ - -# Regular expression which should only match correct list comprehension / -# generator expression variable names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# List of builtins function names that should not be used, separated by a comma -bad-functions=map,filter,apply,input - - -# checks for sign of poor/misdesign: -# * number of methods, attributes, local variables... -# * size, complexity of functions, methods -# -[DESIGN] - -# Enable / disable this checker -enable-design=yes - -# Maximum number of arguments for function / method -max-args=5 - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branchs=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - - -# checks for : -# * methods without self as first argument -# * overriden methods signature -# * access only to existant members via self -# * attributes not defined in the __init__ method -# * supported interfaces implementation -# * unreachable code -# -[CLASSES] - -# Enable / disable this checker -enable-classes=yes - -# List of interface methods to ignore, separated by a comma. This is used for -# instance to not check methods defines in Zope's Interface base class. -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - - -# checks for -# * external modules dependencies -# * relative / wildcard imports -# * cyclic imports -# * uses of deprecated modules -# -# This checker also defines the following reports: -# * R0401: External dependencies -# * R0402: Modules dependencies graph -[IMPORTS] - -# Enable / disable this checker -enable-imports=no - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,string,TERMIOS,Bastion,rexec - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report R0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report R0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report R0402 must -# not be disabled) -int-import-graph= - - -# checks for usage of new style capabilities on old style classes and -# other new/old styles conflicts problems -# * use of property, __slots__, super -# * "super" usage -# * raising a new style class as exception -# -[NEWSTYLE] - -# Enable / disable this checker -enable-newstyle=yes - - -# checks for -# * excepts without exception filter -# * string exceptions -# -[EXCEPTIONS] - -# Enable / disable this checker -enable-exceptions=yes - - -# checks for : -# * unauthorized constructions -# * strict indentation -# * line length -# * use of <> instead of != -# -[FORMAT] - -# Enable / disable this checker -enable-format=yes - -# Maximum number of characters on a single line. -max-line-length=132 - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - - -# checks for similarities and duplicated code. This computation may be -# memory / CPU intensive, so you should disable it if you experiments some -# problems. -# -# This checker also defines the following reports: -# * R0801: Duplication -[SIMILARITIES] - -# Enable / disable this checker -enable-similarities=yes - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - - -# checks for: -# * warning notes in the code like FIXME, XXX -# * PEP 263: source code with non ascii character but no encoding declaration -# -[MISCELLANEOUS] - -# Enable / disable this checker -enable-miscellaneous=yes - -# List of note tags to take in consideration, separated by a comma. Default to -# FIXME, XXX, TODO -notes=FIXME,XXX,TODO - - -# does not check anything but gives some raw metrics : -# * total number of lines -# * total number of code lines -# * total number of docstring lines -# * total number of comments lines -# * total number of empty lines -# -# This checker also defines the following reports: -# * R0701: Raw metrics -[METRICS] - -# Enable / disable this checker -enable-metrics=no diff --git a/trunk/src/setup.py b/trunk/src/setup.py deleted file mode 100644 index 26504147..00000000 --- a/trunk/src/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -setup.py - Setup package with the help from Python's DistUtils -""" - -from distutils.core import setup - -setup( - name = 'sos', - packages = ['sos', 'sos.plugins'], - scripts = [], - package_dir = {'': 'lib',}, - data_files = [ ('/usr/sbin', ['sosreport']), ('/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']) - ] -) diff --git a/trunk/src/sos.spec b/trunk/src/sos.spec deleted file mode 100644 index 4b4237d7..00000000 --- a/trunk/src/sos.spec +++ /dev/null @@ -1,145 +0,0 @@ -%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} - -%define name sos -%define version 1.7 -%define release 1 - -%define _localedir %_datadir/locale - -Summary: A set of tools to gather troubleshooting information from a system -Name: %{name} -Version: %{version} -Release: %{release}%{?dist} -# 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-6 sos-1.6 -# tar -czvf sos-1.6.tar.gz sos-1.6 -Source0: %{name}-%{version}.tar.gz -License: GPL -Group: Development/Libraries -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -BuildArch: noarch -Url: http://sos.108.redhat.com/ -BuildRequires: python-devel - -%description -Sos is a set of tools that gathers information about system -hardware and configuration. The information can then be used for -diagnostic purposes and debugging. Sos is commonly used to help -support technicians and developers. - -%prep -%setup -q - -%build -python setup.py build - -%install -rm -rf ${RPM_BUILD_ROOT} -python setup.py install --optimize 1 --root=$RPM_BUILD_ROOT - -%clean -rm -rf ${RPM_BUILD_ROOT} - -%files -%defattr(-,root,root,-) -%{_sbindir}/sosreport -%{python_sitelib}/sos/ -%{_mandir}/man1/sosreport.1* -%{_localedir}/*/LC_MESSAGES/sos.mo -%doc README TODO LICENSE ChangeLog - -%changelog -* Mon Jul 5 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.6-5 -- Yet more fixes to make package Fedora compliant. - -* Mon Jul 5 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.6-4 -- More fixes to make package Fedora compliant. - -* Mon Jul 2 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.6-3 -- Other fixes to make package Fedora compliant. - -* Mon Jul 2 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.6-2 -- Minor fixes. - -* Mon Jul 2 2007 Navid Sheikhol-Eslami <navid at redhat dot com> - 1.6-1 -- Beautified output of --list-plugins. -- GPL licence is now included in the package. -- added python-devel requirement for building package -- fixed incompatibility with python from RHEL4 - -* Fri May 25 2007 Steve Conklin <sconklin at redhat dot com> - 1.5-1 -- Bumped version - -* Fri May 25 2007 Steve Conklin <sconklin at redhat dot com> - 1.4-2 -- Fixed a backtrace on nonexistent file in kernel plugin (thanks, David Robinson) - -* Mon Apr 30 2007 Steve Conklin <sconklin at redhat dot com> - 1.4-1 -- Fixed an error in option handling -- Forced the file generated by traceroute to not end in .com -- Fixed a problem with manpage -- Added optional traceroute collection to networking plugin -- Added clalance's patch to gather iptables info. -- Fixes to the device-mapper plugin -- Fixed a problem with installation of man page - -* Mon Apr 16 2007 Steve Conklin <sconklin at redhat dot com> - 1.3-3 -- including patches to fix the following: -- Resolves: bz219745 sosreport needs a man page -- Resolves: bz219667 sosreport does not terminate cleanly on ^C -- Resolves: bz233375 Make SOS flag the situation when running on a fully virtu... -- Resolves: bz234873 rhel5 sos needs to include rpm-va by default -- Resolves: bz219669 sosreport multi-threaded option sometimes fails -- Resolves: bz219671 RFE for sosreport - allow specification of plugins to be run -- Resolves: bz219672 RFE - show progress while sosreport is running -- Resolves: bz219673 Add xen information gathering to sosreport -- Resolves: bz219675 Collect information related to the new driver update model -- Resolves: bz219877 'Cancel' button during option selection only cancels sele... - -* Tue Feb 20 2007 John Berninger <jwb at redhat dot com> - 1.3-2 -- Add man page - -* Fri Dec 15 2006 Steve Conklin <sconklin at redhat dot com> - 1.3-1 -- really fixed bz_219654 - -* Fri Dec 15 2006 Steve Conklin <sconklin at redhat dot com> - 1.2-1 -- fixed a build problem - -* Fri Dec 15 2006 Steve Conklin <sconklin at redhat dot com> - 1.1-1 -- Tighten permissions of tmp directory so only readable by creator bz_219657 -- Don't print message 'Problem at path ...' bz_219654 -- Removed useless message bz_219670 -- Preserve file modification times bz_219674 -- Removed unneeded message about files on copyProhibitedList bz_219712 - -* Wed Aug 30 2006 Steve Conklin <sconklin at redhat dot com> - 1.0-1 -- Seperated upstream and RPM versioning - -* Mon Aug 21 2006 Steve Conklin <sconklin at redhat dot com> - 0.1-11 -- Code cleanup, fixed a regression in threading - -* Mon Aug 14 2006 Steve Conklin <sconklin at redhat dot com> - 0.1-10 -- minor bugfixes, added miltithreading option, setup now quiet - -* Mon Jul 17 2006 Steve Conklin <sconklin at redhat dot com> - 0.1-9 -- migrated to svn on 108.redhat.com, fixed a problem with command output linking in report - -* Mon Jun 19 2006 Steve Conklin <sconklin at redhat dot com> - 0.1-6 -- Added LICENSE file containing GPL - -* Wed May 31 2006 Steve Conklin <sconklin at redhat dot com> - 0.1-5 -- Added fixes to network plugin and prepped for Fedora submission - -* Wed May 31 2006 John Berninger <jwb at redhat dot com> - 0.1-4 -- Reconsolidated subpackages into one package per discussion with sconklin - -* Mon May 22 2006 John Berninger <jwb at redhat dot com> - 0.1-3 -- Added ftp, ldap, mail, named, samba, squid SOS plugins -- Fixed various errors in kernel and hardware plugins - -* Mon May 22 2006 John Benringer <jwb at redhat dot com> - 0.1-2 -- split off cluster plugin into subpackage -- correct file payload lists - -* Mon May 22 2006 John Berninger <jwb at redhat dot com> - 0.1-1 -- initial package build diff --git a/trunk/src/sosreport b/trunk/src/sosreport deleted file mode 100755 index 86d66b4d..00000000 --- a/trunk/src/sosreport +++ /dev/null @@ -1,725 +0,0 @@ -#!/usr/bin/env python -""" -Gather information about a system and report it using plugins -supplied for application-specific information -""" -## sosreport.py -## gather information about a system and report it - -## 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 = W0611 -# pylint: disable-msg = W0702 - -import sys -import os -#import curses -from optparse import OptionParser, Option -import sos.policyredhat -from sos.helpers import * -from snack import * -from threading import Thread, activeCount, enumerate -import signal -import logging -from stat import * -from time import strftime, localtime, time -from pwd import getpwuid -import gettext -from threading import Semaphore - -__version__ = 1.7 - -__breakHits__ = 0 # Use this to track how many times we enter the exit routine - -## Set up routines to be linked to signals for termination handling -def exittermhandler(signum, frame): - doExitCode() - -def doExitCode(): - global __breakHits__ - __breakHits__ += 1 - if ( ( activeCount() > 1 ) and ( __breakHits__ == 1 ) ): - print "SIGTERM received, multiple threads detected, waiting for all threads to exit" - for thread in enumerate(): - if thread.getName() != "MainThread": - thread.join() - print "All threads ended, cleaning up." - 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) - print "Threads dead, cleaning up." - if ( ( activeCount() == 1 ) and ( __breakHits__ > 2 ) ): - print "Multiple SIGTERMs, single thread, exiting without cleaning up." - 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) -signal.signal(signal.SIGTERM, exittermhandler) - -## FIXME: Need to figure out how to IPC with child threads in case of -## multiple SIGTERMs. -## FIXME: Need to figure out how to handle SIGKILL - we can't intercept it. - -# for debugging -__raisePlugins__ = 1 - -class SosOption (Option): - """Allow to specify comma delimited list of plugins""" - ACTIONS = Option.ACTIONS + ("extend",) - STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",) - TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",) - - def take_action(self, action, dest, opt, value, values, parser): - if action == "extend": - try: lvalue = value.split(",") - except: pass - else: values.ensure_value(dest, []).extend(lvalue) - else: - Option.take_action(self, action, dest, opt, value, values, parser) - -__cmdParser__ = OptionParser(option_class=SosOption) -__cmdParser__.add_option("-a", "--alloptions", action="store_true", \ - dest="usealloptions", default=False, \ - help="Use all options for loaded plugins") -__cmdParser__.add_option("-f", "--fastoptions", action="store_true", \ - dest="fastoptions", default=False, \ - help="Use only fast options for loaded plugins") -__cmdParser__.add_option("-g", "--gatheronly", action="store_true", \ - dest="gatheronly", default=False, \ - help="Gather information locally but don't package or submit") -__cmdParser__.add_option("-l", "--list-plugins", action="store_true", \ - dest="listPlugins", default=False, \ - help="list existing plugins") -__cmdParser__.add_option("-n", "--noplugin", action="extend", \ - dest="noplugins", type="string", \ - help="skip these plugins", default = []) -__cmdParser__.add_option("-o", "--onlyplugin", action="extend", \ - dest="onlyplugins", type="string", \ - help="enable these plugins only", default = []) -__cmdParser__.add_option("-e", "--enableplugin", action="extend", \ - dest="enableplugins", type="string", \ - help="list of inactive plugins to be enabled", default = []) -__cmdParser__.add_option("-k", "--pluginopts", action="extend", \ - dest="plugopts", type="string", \ - help="plugin options in plugin_name.option=value format") -__cmdParser__.add_option("-v", "--verbose", action="count", \ - dest="verbosity", \ - help="How obnoxious we're being about telling the user what we're doing.") -__cmdParser__.add_option("-c", "--curses", action="store_true", \ - dest="use_curses", default=False, \ - help="Display a text GUI menu to modify plugin options.") -__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) -(__cmdLineOpts__, __cmdLineArgs__)=__cmdParser__.parse_args() - -def textcolor(text, fg, bg=None, raw=0): - 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", - "lcyan":"1;36", "white":"1;37" } - opencol = "\033[" - closecol = "m" - clear = opencol + "0" + closecol - f = opencol + colors[fg] + closecol - return "%s%s%s" % (f, text, clear) - -def get_curse_options(alloptions): - """ - use curses to enable the user to select some options - """ - # alloptions is an array of (plug, plugname, optname, parms(dictionary)) tuples - plugName = [] - out = [] - - # get a sorted list of all plugin names - for rrr in alloptions: - if rrr[1] not in plugName: - plugName.append(rrr[1]) - - plugName.sort() - plugCbox = CheckboxTree(height=5, scroll=1) - - countOpt = -1 - - optDic = {} - optDicCounter = 0 - - # iterate over all plugins with options - for curPlugName in plugName: - plugCbox.addItem(curPlugName, (snackArgs['append'],)) - countOpt = countOpt+1 - - for opt in alloptions: - if opt[1] != curPlugName: - continue - - snt = opt[2] + " ("+opt[3]['desc']+") is " + opt[3]['speed'] - plugCbox.addItem(snt, (countOpt, snackArgs['append']), item = optDicCounter, selected = opt[3]['enabled']) - optDic[optDicCounter] = opt - optDicCounter += 1 - - - screen = SnackScreen() - bb = ButtonBar(screen, (("Ok", "ok"), ("Cancel", "cancel"))) - g = GridForm(screen, "Select Sosreport Options", 1, 10) - g.add(plugCbox, 0, 0) - g.add(bb, 0, 1, growx = 1) - result = g.runOnce() - - screen.finish() - - if bb.buttonPressed(result) == "cancel": - raise "Cancelled" - - for rrr in range(0, optDicCounter): - optDic[rrr][3]['enabled'] = plugCbox.getEntryValue(rrr)[1] - out.append((optDic[rrr])) - - return out - -class progressBar: - def __init__(self, minValue = 0, maxValue = 10, totalWidth=40): - self.progBar = "[]" # This holds the progress bar string - self.min = minValue - self.max = maxValue - self.width = totalWidth - self.amount = 0 # When amount == max, we are 100% done - self.time_start = time() - self.eta = 0 - self.last_amount_update = time() - self.update() - - def updateAmount(self, newAmount = 0): - if newAmount < self.min: newAmount = self.min - if newAmount > self.max: newAmount = self.max - if self.amount != newAmount: - self.last_amount_update = time() - self.amount = newAmount - last_update_relative = round(self.last_amount_update - self.time_start) - self.eta = round(last_update_relative * self.max / self.amount) - - # generate ETA - timeElapsed = round(time() - self.time_start) - last_update_relative = round(self.last_amount_update - self.time_start) - if timeElapsed >= 10 and self.amount > 0: - percentDone = round(timeElapsed * 100 / self.eta) - if percentDone > 100: - percentDone = 100 - ETA = timeElapsed - elif self.eta < timeElapsed: - ETA = timeElapsed - else: - ETA = self.eta - ETA = "[%02d:%02d/%02d:%02d]" % (round(timeElapsed/60), timeElapsed % 60, round(ETA/60), ETA % 60) - else: - ETA = "[%02d:%02d/--:--]" % (round(timeElapsed/60), timeElapsed % 60) - if self.amount < self.max: - percentDone = 0 - else: - percentDone = 100 - - # Figure out how many hash bars the percentage should be - allFull = self.width - 2 - numHashes = (percentDone / 100.0) * allFull - numHashes = int(round(numHashes)) - - # build a progress bar with hashes and spaces - self.progBar = " [" + '#'*numHashes + ' '*(allFull-numHashes) + "]" - - # figure out where to put the percentage, roughly centered - percentPlace = (len(self.progBar) / 2) - len(str(percentDone)) - percentString = str(percentDone) + "%" - - # slice the percentage into the bar - self.progBar = " Progress" + self.progBar[0:percentPlace] + percentString + self.progBar[percentPlace+len(percentString):] + ETA - - def incAmount(self, toInc = 1): - self.updateAmount(self.amount+toInc) - - def finished(self): - self.updateAmount(self.max) - sys.stdout.write(self.progBar + '\n') - sys.stdout.flush() - - def update(self): - self.updateAmount(self.amount) - sys.stdout.write(self.progBar + '\r') - sys.stdout.flush() - -class XmlReport: - def __init__(self): - try: - import libxml2 - except: - self.enabled = False - return - else: - self.enabled = True - self.doc = libxml2.newDoc("1.0") - self.root = self.doc.newChild(None, "sos", None) - self.commands = self.root.newChild(None, "commands", None) - self.files = self.root.newChild(None, "files", None) - - def add_command(self,cmdline,exitcode,stdout = None,stderr = None,f_stdout=None,f_stderr=None, runtime=None): - if not self.enabled: return - - cmd = self.commands.newChild(None, "cmd", None) - - cmd.setNsProp(None, "cmdline", cmdline) - - cmdchild = cmd.newChild(None, "exitcode", str(exitcode)) - - if runtime: - cmd.newChild(None, "runtime", str(runtime)) - - if stdout or f_stdout: - cmdchild = cmd.newChild(None, "stdout", stdout) - if f_stdout: - cmdchild.setNsProp(None, "file", f_stdout) - - if stderr or f_stderr: - cmdchild = cmd.newChild(None, "stderr", stderr) - if f_stderr: - cmdchild.setNsProp(None, "file", f_stderr) - - def add_file(self,fname,stats): - if not self.enabled: return - - cfile = self.files.newChild(None,"file",None) - - cfile.setNsProp(None, "fname", fname) - - cchild = cfile.newChild(None, "uid", str(stats[ST_UID])) - cchild.setNsProp(None,"name", getpwuid(stats[ST_UID])[0]) - cchild = cfile.newChild(None, "gid", str(stats[ST_GID])) - cchild.setNsProp(None,"name", getpwuid(stats[ST_GID])[0]) - cfile.newChild(None, "mode", str(oct(S_IMODE(stats[ST_MODE])))) - cchild = cfile.newChild(None, "ctime", strftime('%a %b %d %H:%M:%S %Y', localtime(stats[ST_CTIME]))) - cchild.setNsProp(None,"tstamp", str(stats[ST_CTIME])) - cchild = cfile.newChild(None, "atime", strftime('%a %b %d %H:%M:%S %Y', localtime(stats[ST_ATIME]))) - cchild.setNsProp(None,"tstamp", str(stats[ST_ATIME])) - cchild = cfile.newChild(None, "mtime", strftime('%a %b %d %H:%M:%S %Y', localtime(stats[ST_MTIME]))) - cchild.setNsProp(None,"tstamp", str(stats[ST_MTIME])) - - def serialize(self): - if not self.enabled: return - - print self.doc.serialize(None, 1) - - def serialize_to_file(self,fname): - if not self.enabled: return - - outfn = open(fname,"w") - outfn.write(self.doc.serialize(None,1)) - outfn.close() - -def sosreport(): - # pylint: disable-msg = R0912 - # pylint: disable-msg = R0914 - # pylint: disable-msg = R0915 - """ - This is the top-level function that gathers and processes all sosreport information - """ - loadedplugins = [] - skippedplugins = [] - alloptions = [] - - # perhaps we should automatically locate the policy module?? - policy = sos.policyredhat.SosPolicy() - - # find the plugins path - paths = sys.path - for path in paths: - if path.strip()[-len("site-packages"):] == "site-packages": - pluginpath = path + "/sos/plugins" - reporterpath = path + "/sos/reporters" - - # Set up common info and create destinations - - dstroot = sosFindTmpDir() - cmddir = os.path.join(dstroot, "sos_commands") - logdir = os.path.join(dstroot, "sos_logs") - rptdir = os.path.join(dstroot, "sos_reports") - os.mkdir(cmddir, 0755) - os.mkdir(logdir, 0755) - os.mkdir(rptdir, 0755) - - # initialize i18n language localization - gettext.install('sos', '/usr/share/locale', unicode=False) - - # initialize logging - soslog = logging.getLogger('sos') - soslog.setLevel(logging.DEBUG) - - # log to a file - flog = logging.FileHandler(logdir + "/sos.log") - flog.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s')) - flog.setLevel(logging.DEBUG) - soslog.addHandler(flog) - - # define a Handler which writes INFO messages or higher to the sys.stderr - console = logging.StreamHandler(sys.stderr) - if __cmdLineOpts__.verbosity > 0: - console.setLevel(20 - __cmdLineOpts__.verbosity) - __cmdLineOpts__.progressbar = False - else: - console.setLevel(logging.INFO) - console.setFormatter(logging.Formatter('%(message)s')) - soslog.addHandler(console) - - logging.VERBOSE = logging.INFO - 1 - logging.VERBOSE2 = logging.INFO - 2 - logging.VERBOSE3 = logging.INFO - 3 - logging.addLevelName(logging.VERBOSE, "verbose") - logging.addLevelName(logging.VERBOSE2,"verbose2") - logging.addLevelName(logging.VERBOSE3,"verbose3") - - xmlrep = XmlReport() - - # 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 } - - # Make policy aware of the commons - policy.setCommons(commons) - - print - soslog.info ( _("sosreport (version %s)") % __version__) - print - - # generate list of available plugins - plugins = os.listdir(pluginpath) - plugins.sort() - - # validate and load plugins - for plug in plugins: - plugbase = plug[:-3] - if not plug[-3:] == '.py' or plugbase == "__init__": - continue - try: - #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, _("plug %s skipped (noplugins)") % 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 --onlyplugin 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(_("could not load plugin %s") % plug) - if __raisePlugins__: - raise - - # First, gather and process options - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE3, _("processing options from plugin: %s") % plugname) - names, parms = plug.getAllOptions() - for optname, optparm in zip(names, parms): - alloptions.append((plug, plugname, optname, optparm)) - - if __cmdLineOpts__.listPlugins: - if not len(loadedplugins) and not len(skippedplugins): - soslog.error(_("no valid plugins found")) - sys.exit(1) - - if len(loadedplugins): - print _("The following plugins are currently enabled:") - print - for (plugname,plug) in loadedplugins: - print " %-25s %s" % (textcolor(plugname,"lblue"),plug.get_description()) - else: - print _("No plugin enabled.") - print - - if len(alloptions): - print _("The following plugin options are available:") - print - for (plug, plugname, optname, optparm) in alloptions: - print " %-25s %s [%d]" % (plugname + "." + optname, optparm["desc"], optparm["enabled"]) - else: - print _("No plugin options available.") - - if len(skippedplugins): - print - print _("The following plugins are currently disabled:") - print - for (plugname,plugclass) in skippedplugins: - print " %-25s %s" % (textcolor(plugname,"blue"),plugclass.get_description()) - - print - 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.') - 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")) - sys.exit(1) - - try: - raw_input(_("""This utility will collect some detailed information about the -hardware and setup of your Red Hat Enterprise Linux system. -This information will be used to diagnose problems with your -system and will be considered confidential information. -Red Hat will use this information for diagnostic purposes ONLY. - -This process may take a while to complete. -No changes will be made to your system. - -Press ENTER to continue, or CTRL-C to quit. -""")) - except KeyboardInterrupt: - print - sys.exit(0) - - # setup plugin options - if __cmdLineOpts__.plugopts: - opts = {} - for opt in __cmdLineOpts__.plugopts: - try: opt, val = opt.split("=") - except: val=1 - plug, opt = opt.split(".") - try: val = int(val) # try to convert string "val" to int() - except: pass - try: opts[plug] - except KeyError: opts[plug] = [] - opts[plug].append( (opt,val) ) - 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)) - plug.setOption(opt,val) - del opt,opts,val - elif not __cmdLineOpts__.fastoptions and not __cmdLineOpts__.usealloptions: - if len(alloptions) and __cmdLineOpts__.use_curses: - try: - get_curse_options(alloptions) - except "Cancelled": - sys.exit(_("Exiting.")) - elif __cmdLineOpts__.fastoptions: - for i in range(len(alloptions)): - for plug, plugname, optname, optparm in alloptions: - if optparm['speed'] == 'fast': - plug.setOption(optname, 1) - else: - plug.setOption(optname, 0) - elif __cmdLineOpts__.usealloptions: - for i in range(len(alloptions)): - for plug, plugname, optname, optparm in alloptions: - plug.setOption(optname, 1) - - # Call the diagnose() method for each plugin - tmpcount = 0 - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE2, "Performing sanity check for plugin %s" % plugname) - plug.diagnose() - tmpcount += len(plug.diagnose_msgs) - if tmpcount > 0: - print _("One or more plugin has detected a problem in your configuration.") - print _("Please review the following messages:") - print - for plugname, plug in loadedplugins: - for msg in plug.diagnose_msgs: - soslog.warning(" * %s: %s", plugname, msg) - print - try: - raw_input( _("Press ENTER to continue, or CTRL-C to quit.\n") ) - except KeyboardInterrupt: - print - sys.exit(0) - - # 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) - plug.setup() - - # Setup the progress bar - if __cmdLineOpts__.progressbar: - # gather information useful for generating ETA - eta_weight = len(loadedplugins) - for plugname, plug in loadedplugins: - eta_weight += plug.eta_weight - pbar = progressBar(minValue = 0, maxValue = eta_weight) - # pbar.max = number_of_plugins + weight (default 1 per plugin) - - if __cmdLineOpts__.nomultithread: - soslog.log(logging.VERBOSE, "using single-threading") - else: - soslog.log(logging.VERBOSE, "using multi-threading") - - # Call the collect method for each plugin - plugrunning = Semaphore(2) - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE, "executing plugin %s" % plugname) - if not __cmdLineOpts__.nomultithread: - plug.copyStuff(threaded = True, semaphore = plugrunning) - else: - plug.copyStuff() - if __cmdLineOpts__.progressbar: - pbar.incAmount(plug.eta_weight) - pbar.update() - del plugrunning - - # Wait for all the collection threads to exit - if not __cmdLineOpts__.nomultithread: - finishedplugins = [] - while len(loadedplugins) > 0: - plugname, plug = loadedplugins.pop(0) - if not plug.wait(0.5): - finishedplugins.append((plugname,plug)) - soslog.log(logging.VERBOSE2, "plugin %s has returned" % plugname) - if __cmdLineOpts__.progressbar: - pbar.incAmount(plug.eta_weight) - else: - soslog.log(logging.VERBOSE3, "plugin %s still hasn't returned" % plugname) - loadedplugins.append((plugname,plug)) - if __cmdLineOpts__.progressbar: - pbar.update() - loadedplugins = finishedplugins - del finishedplugins - - xmlrep.serialize_to_file(rptdir + "/" + "sosreport.xml") - - # Call the analyze method for each plugin - for plugname, plug in loadedplugins: - soslog.log(logging.VERBOSE2, "Analyzing results of plugin %s" % plugname,) - try: - plug.analyze() - except: - # catch exceptions in analyse() and keep working - pass - if __cmdLineOpts__.progressbar: - pbar.incAmount() - pbar.update() - - if __cmdLineOpts__.progressbar: - pbar.finished() - sys.stdout.write("\n") - - # Generate the header for the html output file - rfd = open(rptdir + "/" + "sosreport.html", "w") - rfd.write(""" - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> - <head> - <link rel="stylesheet" type="text/css" media="screen" href="donot.css" /> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title>Sos System Report</title> - </head> - - <body> - """) - - - # Make a pass to gather Alerts and a list of module names - allAlerts = [] - plugNames = [] - for plugname, plug in loadedplugins: - for alert in plug.alerts: - allAlerts.append('<a href="#%s">%s</a>: %s' % (plugname, plugname, alert)) - plugNames.append(plugname) - - - - # Create a table of links to the module info - rfd.write("<hr/><h3>Loaded Plugins:</h3>") - rfd.write("<table><tr>\n") - rr = 0 - for i in range(len(plugNames)): - rfd.write('<td><a href="#%s">%s</a></td>\n' % (plugNames[i], plugNames[i])) - rr = divmod(i, 4)[1] - if (rr == 3): - rfd.write('</tr>') - if not (rr == 3): - rfd.write('</tr>') - rfd.write('</table>\n') - - rfd.write('<hr/><h3>Alerts:</h3>') - rfd.write('<ul>') - for alert in allAlerts: - rfd.write('<li>%s</li>' % alert) - rfd.write('</ul>') - - - # Call the report method for each plugin - for plugname, plug in loadedplugins: - html = plug.report() - rfd.write(html) - - rfd.write("</body></html>") - - rfd.close() - - # Collect any needed user information (name, etc) - - # Call the postproc method for each plugin - for plugname, plug in loadedplugins: - plug.postproc() - - if __cmdLineOpts__.gatheronly: - soslog.info(_("Collected information is in ") + dstroot) - soslog.info(_("Your html report is in ") + rptdir + "/" + "sosreport.html") - else: - # package up the results for the support organization - policy.packageResults() - # delete gathered files - os.system("/bin/rm -rf %s" % dstroot) - # automated submission will go here - - # Close all log files and perform any cleanup - logging.shutdown() - - -if __name__ == '__main__': - try: - sosreport() - except KeyboardInterrupt: - doExitCode() diff --git a/trunk/src/sosreport.1 b/trunk/src/sosreport.1 deleted file mode 100644 index cf76afdb..00000000 --- a/trunk/src/sosreport.1 +++ /dev/null @@ -1,55 +0,0 @@ -.TH SOSREPORT 1 "Tue Feb 20 2007" -.SH NAME -sosreport \- Generate debugging information for this system -.SH SYNOPSIS -.B sosreport -[-a|--alloptions] [-f|--fastoptions] [-g|--gatheronly] - [-l|--list-plugins] [-n|--noplugin \fIplugin-name\fR] - [-o|--onlyplugin \fIplugin-name\fR] - [-v|--verbose [...]] [-m|--multithreaded] -.SH DESCRIPTION -\fBsosreport\fR generates a compressed tarball of debugging information -for the system it is run on that can be sent to technical support -reps that will give them a more complete view of the overall system -status. -.SH OPTIONS -.TP -.B \-a, \--alloptions -Enable all options for all loaded plugins -.TP -.B \-f, \--fastoptions -Enable all options marked as "fast" for loaded plugins. This will -reduce running time while still gathering helpful information, but -you may be asked to re-run later with some or all "slow" options -enabled depending on the specific issue. -.TP -.B \-g, \--gatheronly -Gather the diagnostic data and bundle it up, but do not attempt to -send it to any support site. This option currently has no effect as -sosreport currently does not support report transmission. -.TP -.B \-l, \--list-plugins -List available plugins -.TP -.B \-n, \--noplugin -Do not load specified plugin(s) -.TP -.B \-o, \--onlyplugin -Load only the specified plugin(s), all otherplugins should be disabled -.TP -.B \-v, \--verbose -Increase the verbosity of the output as sosreport is running. This option -can be specified more than once. -.TP -.B \-m, \--multithreaded -Enable a multithreaded collection and analysis of the sosreport data. Please -note that this option is experimental and is known to have intermittent issues. -.SH BUGS -The multithreaded option can fail intermittently, please use it with care. -.SH AUTHORS -.nf -Steve Conklin <sconklin@redhat.com> -John Berninger <jwb@redhat.com> -Navid Sheikhol-Eslami <navid@redhat.com> -Pierre Amadio <pamadio@redhat.com> -.fi diff --git a/trunk/src/tools/msgfmt.py b/trunk/src/tools/msgfmt.py deleted file mode 100644 index 8a2d4e66..00000000 --- a/trunk/src/tools/msgfmt.py +++ /dev/null @@ -1,203 +0,0 @@ -#! /usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Written by Martin v. Löwis <loewis@informatik.hu-berlin.de> - -"""Generate binary message catalog from textual translation description. - -This program converts a textual Uniforum-style message catalog (.po file) into -a binary GNU catalog (.mo file). This is essentially the same function as the -GNU msgfmt program, however, it is a simpler implementation. - -Usage: msgfmt.py [OPTIONS] filename.po - -Options: - -o file - --output-file=file - Specify the output file to write to. If omitted, output will go to a - file named filename.mo (based off the input file name). - - -h - --help - Print this message and exit. - - -V - --version - Display version information and exit. -""" - -import sys -import os -import getopt -import struct -import array - -__version__ = "1.1" - -MESSAGES = {} - - - -def usage(code, msg=''): - print >> sys.stderr, __doc__ - if msg: - print >> sys.stderr, msg - sys.exit(code) - - - -def add(id, str, fuzzy): - "Add a non-fuzzy translation to the dictionary." - global MESSAGES - if not fuzzy and str: - MESSAGES[id] = str - - - -def generate(): - "Return the generated output." - global MESSAGES - keys = MESSAGES.keys() - # the keys are sorted in the .mo file - keys.sort() - offsets = [] - ids = strs = '' - for id in keys: - # For each string, we need size and file offset. Each string is NUL - # terminated; the NUL does not count into the size. - offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) - ids += id + '\0' - strs += MESSAGES[id] + '\0' - output = '' - # The header is 7 32-bit unsigned integers. We don't use hash tables, so - # the keys start right after the index tables. - # translated string. - keystart = 7*4+16*len(keys) - # and the values start after the keys - valuestart = keystart + len(ids) - koffsets = [] - voffsets = [] - # The string table first has the list of keys, then the list of values. - # Each entry has first the size of the string, then the file offset. - for o1, l1, o2, l2 in offsets: - koffsets += [l1, o1+keystart] - voffsets += [l2, o2+valuestart] - offsets = koffsets + voffsets - output = struct.pack("Iiiiiii", - 0x950412deL, # Magic - 0, # Version - len(keys), # # of entries - 7*4, # start of key index - 7*4+len(keys)*8, # start of value index - 0, 0) # size and offset of hash table - output += array.array("i", offsets).tostring() - output += ids - output += strs - return output - - - -def make(filename, outfile): - ID = 1 - STR = 2 - - # Compute .mo name from .po name and arguments - if filename.endswith('.po'): - infile = filename - else: - infile = filename + '.po' - if outfile is None: - outfile = os.path.splitext(infile)[0] + '.mo' - - try: - lines = open(infile).readlines() - except IOError, msg: - print >> sys.stderr, msg - sys.exit(1) - - section = None - fuzzy = 0 - - # Parse the catalog - lno = 0 - for l in lines: - lno += 1 - # If we get a comment line after a msgstr, this is a new entry - if l[0] == '#' and section == STR: - add(msgid, msgstr, fuzzy) - section = None - fuzzy = 0 - # Record a fuzzy mark - if l[:2] == '#,' and l.find('fuzzy'): - fuzzy = 1 - # Skip comments - if l[0] == '#': - continue - # Now we are in a msgid section, output previous section - if l.startswith('msgid'): - if section == STR: - add(msgid, msgstr, fuzzy) - section = ID - l = l[5:] - msgid = msgstr = '' - # Now we are in a msgstr section - elif l.startswith('msgstr'): - section = STR - l = l[6:] - # Skip empty lines - l = l.strip() - if not l: - continue - # XXX: Does this always follow Python escape semantics? - l = eval(l) - if section == ID: - msgid += l - elif section == STR: - msgstr += l - else: - print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \ - 'before:' - print >> sys.stderr, l - sys.exit(1) - # Add last entry - if section == STR: - add(msgid, msgstr, fuzzy) - - # Compute output - output = generate() - - try: - open(outfile,"wb").write(output) - except IOError,msg: - print >> sys.stderr, msg - - - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], 'hVo:', - ['help', 'version', 'output-file=']) - except getopt.error, msg: - usage(1, msg) - - outfile = None - # parse options - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt in ('-V', '--version'): - print >> sys.stderr, "msgfmt.py", __version__ - sys.exit(0) - elif opt in ('-o', '--output-file'): - outfile = arg - # do it - if not args: - print >> sys.stderr, 'No input file given' - print >> sys.stderr, "Try `msgfmt --help' for more information." - return - - for filename in args: - make(filename, outfile) - - -if __name__ == '__main__': - main() diff --git a/trunk/src/tools/pygettext.py b/trunk/src/tools/pygettext.py deleted file mode 100644 index 040b5c7f..00000000 --- a/trunk/src/tools/pygettext.py +++ /dev/null @@ -1,762 +0,0 @@ -#! /usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Originally written by Barry Warsaw <barry@zope.com> -# -# Minimally patched to make it even more xgettext compatible -# by Peter Funk <pf@artcom-gmbh.de> -# -# 2002-11-22 Jürgen Hermann <jh@web.de> -# Added checks that _() only contains string literals, and -# command line args are resolved to module lists, i.e. you -# can now pass a filename, a module or package name, or a -# directory (including globbing chars, important for Win32). -# Made docstring fit in 80 chars wide displays using pydoc. -# - -import codecs - -# for selftesting -import re -try: - import fintl - _ = fintl.gettext -except ImportError: - _ = lambda s: s - -__doc__ = _("""pygettext -- Python equivalent of xgettext(1) - -Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the -internationalization of C programs. Most of these tools are independent of -the programming language and can be used from within Python programs. -Martin von Loewis' work[1] helps considerably in this regard. - -There's one problem though; xgettext is the program that scans source code -looking for message strings, but it groks only C (or C++). Python -introduces a few wrinkles, such as dual quoting characters, triple quoted -strings, and raw strings. xgettext understands none of this. - -Enter pygettext, which uses Python's standard tokenize module to scan -Python source code, generating .pot files identical to what GNU xgettext[2] -generates for C and C++ code. From there, the standard GNU tools can be -used. - -A word about marking Python strings as candidates for translation. GNU -xgettext recognizes the following keywords: gettext, dgettext, dcgettext, -and gettext_noop. But those can be a lot of text to include all over your -code. C and C++ have a trick: they use the C preprocessor. Most -internationalized C source includes a #define for gettext() to _() so that -what has to be written in the source is much less. Thus these are both -translatable strings: - - gettext("Translatable String") - _("Translatable String") - -Python of course has no preprocessor so this doesn't work so well. Thus, -pygettext searches only for _() by default, but see the -k/--keyword flag -below for how to augment this. - - [1] http://www.python.org/workshops/1997-10/proceedings/loewis.html - [2] http://www.gnu.org/software/gettext/gettext.html - -NOTE: pygettext attempts to be option and feature compatible with GNU -xgettext where ever possible. However some options are still missing or are -not fully implemented. Also, xgettext's use of command line switches with -option arguments is broken, and in these cases, pygettext just defines -additional switches. - -Usage: pygettext [options] inputfile ... - -Options: - - -a - --extract-all - Extract all strings. - - -d name - --default-domain=name - Rename the default output file from messages.pot to name.pot. - - -E - --escape - Replace non-ASCII characters with octal escape sequences. - - -D - --docstrings - Extract module, class, method, and function docstrings. These do - not need to be wrapped in _() markers, and in fact cannot be for - Python to consider them docstrings. (See also the -X option). - - -h - --help - Print this help message and exit. - - -k word - --keyword=word - Keywords to look for in addition to the default set, which are: - %(DEFAULTKEYWORDS)s - - You can have multiple -k flags on the command line. - - -K - --no-default-keywords - Disable the default set of keywords (see above). Any keywords - explicitly added with the -k/--keyword option are still recognized. - - --no-location - Do not write filename/lineno location comments. - - -n - --add-location - Write filename/lineno location comments indicating where each - extracted string is found in the source. These lines appear before - each msgid. The style of comments is controlled by the -S/--style - option. This is the default. - - -o filename - --output=filename - Rename the default output file from messages.pot to filename. If - filename is `-' then the output is sent to standard out. - - -p dir - --output-dir=dir - Output files will be placed in directory dir. - - -S stylename - --style stylename - Specify which style to use for location comments. Two styles are - supported: - - Solaris # File: filename, line: line-number - GNU #: filename:line - - The style name is case insensitive. GNU style is the default. - - -v - --verbose - Print the names of the files being processed. - - -V - --version - Print the version of pygettext and exit. - - -w columns - --width=columns - Set width of output to columns. - - -x filename - --exclude-file=filename - Specify a file that contains a list of strings that are not be - extracted from the input files. Each string to be excluded must - appear on a line by itself in the file. - - -X filename - --no-docstrings=filename - Specify a file that contains a list of files (one per line) that - should not have their docstrings extracted. This is only useful in - conjunction with the -D option above. - -If `inputfile' is -, standard input is read. -""") - -import os -import imp -import sys -import glob -import time -import getopt -import token -import tokenize -import operator -import codecs - -from elementtree.ElementTree import ElementTree, XML - -__version__ = '1.5' - -default_keywords = ['_'] -DEFAULTKEYWORDS = ', '.join(default_keywords) - -EMPTYSTRING = '' - - - -# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's -# there. -pot_header = _('''\ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\\n" -"POT-Creation-Date: %(time)s\\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=%(charset)s\\n" -"Content-Transfer-Encoding: %(charset)s\\n" -"Generated-By: pygettext.py %(version)s\\n" - -''') - - -def usage(code, msg=''): - print >> sys.stderr, __doc__ % globals() - if msg: - print >> sys.stderr, msg - sys.exit(code) - - - -escapes = [] - -def make_escapes(pass_iso8859): - global escapes - if pass_iso8859: - # Allow iso-8859 characters to pass through so that e.g. 'msgid - # "Höhe"' would result not result in 'msgid "H\366he"'. Otherwise we - # escape any character outside the 32..126 range. - mod = 128 - else: - mod = 256 - for i in range(256): - if 32 <= (i % mod) <= 126: - escapes.append(chr(i)) - else: - escapes.append("\\%03o" % i) - escapes[ord('\\')] = '\\\\' - escapes[ord('\t')] = '\\t' - escapes[ord('\r')] = '\\r' - escapes[ord('\n')] = '\\n' - escapes[ord('\"')] = '\\"' - - -def escape_ascii(s): - "Escapes all text outside of 7bit ASCII plus control characters and Python literals." - global escapes - s = list(s) - for i in range(len(s)): - s[i] = escapes[ord(s[i])] - return EMPTYSTRING.join(s) - -def escape_unicode(s): - "Escapes control characters and Python literals only leaving non-ascii text intact." - #for sp in ('\t', '\r', '\n', '\"', '\\'): - s = s.replace('\\', '\\\\') - s = s.replace('\t', '\\t') - s = s.replace('\r', '\\r') - s = s.replace('\n', '\\n') - s = s.replace('\"', '\\"') - # escape control chars - def repl(m): return "\\%03o" % ord(m.group(0)) - s = re.sub('[\001-\037]', repl, s) - return s - -def safe_eval(s): - # unwrap quotes, safely - return eval(s, {'__builtins__':{}}, {}) - - -def normalize(s, escape=False): - # This converts the various Python string types into a format that is - # appropriate for .po files, namely much closer to C style. - lines = s.split('\n') - if len(lines) == 1: - s = '"' + escape_unicode(s) + '"' - else: - if not lines[-1]: - del lines[-1] - lines[-1] = lines[-1] + '\n' - for i in range(len(lines)): - lines[i] = escape_unicode(lines[i]) - lineterm = '\\n"\n"' - s = '""\n"' + lineterm.join(lines) + '"' - if isinstance(s, unicode): - s = s.encode('utf-8') - if escape: - def repl(m): return "\\%03o" % ord(m.group(0)) - s = re.sub('[\200-\377]', repl, s) - return s - - -def containsAny(str, set): - """Check whether 'str' contains ANY of the chars in 'set'""" - return 1 in [c in str for c in set] - - -def _visit_pyfiles(list, dirname, names): - """Helper for getFilesForName().""" - # get extension for python source files - if not globals().has_key('_py_ext'): - global _py_ext - _py_ext = [triple[0] for triple in imp.get_suffixes() - if triple[2] == imp.PY_SOURCE][0] - - # don't recurse into CVS directories - if 'CVS' in names: - names.remove('CVS') - if '.svn' in names: - names.remove('.svn') - - # add all *.py files to list - list.extend( - [os.path.join(dirname, file) for file in names - if os.path.splitext(file)[1] == _py_ext] - ) - - -def _get_modpkg_path(dotted_name, pathlist=None): - """Get the filesystem path for a module or a package. - - Return the file system path to a file for a module, and to a directory for - a package. Return None if the name is not found, or is a builtin or - extension module. - """ - # split off top-most name - parts = dotted_name.split('.', 1) - - if len(parts) > 1: - # we have a dotted path, import top-level package - try: - file, pathname, description = imp.find_module(parts[0], pathlist) - if file: file.close() - except ImportError: - return None - - # check if it's indeed a package - if description[2] == imp.PKG_DIRECTORY: - # recursively handle the remaining name parts - pathname = _get_modpkg_path(parts[1], [pathname]) - else: - pathname = None - else: - # plain name - try: - file, pathname, description = imp.find_module( - dotted_name, pathlist) - if file: - file.close() - if description[2] not in [imp.PY_SOURCE, imp.PKG_DIRECTORY]: - pathname = None - except ImportError: - pathname = None - - return pathname - - -def getFilesForName(name): - """Get a list of module files for a filename, a module or package name, - or a directory. - """ - if not os.path.exists(name): - # check for glob chars - if containsAny(name, "*?[]"): - files = glob.glob(name) - list = [] - for file in files: - list.extend(getFilesForName(file)) - return list - - # try to find module or package - name = _get_modpkg_path(name) - if not name: - return [] - - if os.path.isdir(name): - # find all python files in directory - list = [] - os.path.walk(name, _visit_pyfiles, list) - return list - elif os.path.exists(name): - # a single file - return [name] - - return [] - - -class TokenEater: - def __init__(self, options): - self.__options = options - self.__messages = {} - self.__state = self.__waiting - self.__data = [] - self.__lineno = -1 - self.__freshmodule = 1 - self.__curfile = None - self.__encoding = None - - def __call__(self, ttype, tstring, stup, etup, line): - # dispatch -## import token -## print >> sys.stderr, 'ttype:', token.tok_name[ttype], \ -## 'tstring:', tstring - self.__state(ttype, tstring, stup[0]) - - def __waiting(self, ttype, tstring, lineno): - opts = self.__options - # Do docstring extractions, if enabled - if opts.docstrings and not opts.nodocstrings.get(self.__curfile): - # module docstring? - if self.__freshmodule: - if ttype == tokenize.STRING: - self.__addentry(safe_eval(tstring), lineno, isdocstring=1) - self.__freshmodule = 0 - elif ttype not in (tokenize.COMMENT, tokenize.NL): - self.__freshmodule = 0 - return - # class docstring? - if ttype == tokenize.NAME and tstring in ('class', 'def'): - self.__state = self.__suiteseen - return - if ttype == tokenize.NAME and tstring in opts.keywords: - self.__state = self.__keywordseen - - def __suiteseen(self, ttype, tstring, lineno): - # ignore anything until we see the colon - if ttype == tokenize.OP and tstring == ':': - self.__state = self.__suitedocstring - - def __suitedocstring(self, ttype, tstring, lineno): - # ignore any intervening noise - if ttype == tokenize.STRING: - self.__addentry(safe_eval(tstring), lineno, isdocstring=1) - self.__state = self.__waiting - elif ttype not in (tokenize.NEWLINE, tokenize.INDENT, - tokenize.COMMENT): - # there was no class docstring - self.__state = self.__waiting - - def __keywordseen(self, ttype, tstring, lineno): - if ttype == tokenize.OP and tstring == '(': - self.__data = [] - self.__lineno = lineno - self.__state = self.__openseen - else: - self.__state = self.__waiting - - def __openseen(self, ttype, tstring, lineno): - if ttype == tokenize.OP and tstring == ')': - # We've seen the last of the translatable strings. Record the - # line number of the first line of the strings and update the list - # of messages seen. Reset state for the next batch. If there - # were no strings inside _(), then just ignore this entry. - if self.__data: - self.__addentry(EMPTYSTRING.join(self.__data)) - self.__state = self.__waiting - elif ttype == tokenize.STRING: - self.__data.append(safe_eval(tstring)) - elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT, - token.NEWLINE, tokenize.NL]: - # warn if we see anything else than STRING or whitespace - print >> sys.stderr, _( - '*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"' - ) % { - 'token': tstring, - 'file': self.__curfile, - 'lineno': self.__lineno - } - self.__state = self.__waiting - - def __addentry(self, msg, lineno=None, isdocstring=0, iskidstring=0): - # tokenize module always return unicode strings - # even when they are in fact coded string instances - # to deal with this we use a hack: - # evaluate string's representation without leading "u" - # to force interpration as coded string - # then we decode it using already known file's encoding - if not iskidstring: - if type(msg) is str: - msg = eval(repr(msg)) - else: - msg = eval(repr(msg)[1:]) - msg = msg.decode(self.__encoding) - if lineno is None: - lineno = self.__lineno - if not msg in self.__options.toexclude: - entry = (self.__curfile, lineno) - self.__messages.setdefault(msg, {})[entry] = isdocstring - - def set_filename(self, filename): - self.__curfile = filename - self.__freshmodule = 1 - - def set_file_encoding(self, fp): - """Searches for -*- coding: -*- magic comment to find out file encoding.""" - self.__encoding = 'utf-8' # reset to default for each new file - for line in fp.readlines()[:5]: - m = re.match('#\s*-\*-\s+coding:\s+(\w+)\s+-\*-', line) - if m: - self.__encoding = m.group(1) - break - fp.seek(0) - - def contains_inline_python(self,msg): - if '${' in msg and not '$${' in msg: return True - return False - - def strip_namespace_uri(self,tag): - return tag.split('}')[-1] - - def get_text_node(self,node): - tag = re.sub('({[^}]+})?(\w+)', '\\2', node.tag) - - if node.text: - msg = node.text.strip() - if msg and not self.contains_inline_python(msg): - if tag not in ['script','style']: - self.__addentry(msg,self.strip_namespace_uri(node.tag), iskidstring=1) - - if node.getchildren(): - for child in node: self.get_text_node(child) - - if node.tail: - msg = node.tail.strip() - if msg and not self.contains_inline_python(msg): - self.__addentry(msg,self.strip_namespace_uri(node.tag), iskidstring=1) - - def extract_kid_strings(self): - if not self.__curfile: return - f = None - try: - file = open(self.__curfile) - f = ElementTree(XML( fixentities(file.read() ))) - except Exception, e: - print 'Skip %s: %s' % (self.__curfile, e) - return - - node = f.getroot() - self.get_text_node(node) - - def write(self, fp): - options = self.__options - # format without tz information - # because %Z is timezone's name, not offset - # and, say, on localized Windows XP this is non-ascii string - timestamp = time.strftime('%Y-%m-%d %H:%M') - # The time stamp in the header doesn't have the same format as that - # generated by xgettext... - t = {'time': timestamp, 'version': __version__, 'charset':'utf-8'} - print >> fp, pot_header % t - # Sort the entries. First sort each particular entry's keys, then - # sort all the entries by their first item. - reverse = {} - for k, v in self.__messages.items(): - keys = v.keys() - keys.sort() - reverse.setdefault(tuple(keys), []).append((k, v)) - rkeys = reverse.keys() - rkeys.sort() - for rkey in rkeys: - rentries = reverse[rkey] - rentries.sort() - for k, v in rentries: - isdocstring = 0 - # If the entry was gleaned out of a docstring, then add a - # comment stating so. This is to aid translators who may wish - # to skip translating some unimportant docstrings. - if reduce(operator.__add__, v.values()): - isdocstring = 1 - # k is the message string, v is a dictionary-set of (filename, - # lineno) tuples. We want to sort the entries in v first by - # file name and then by line number. - v = v.keys() - v.sort() - if not options.writelocations: - pass - # location comments are different b/w Solaris and GNU: - elif options.locationstyle == options.SOLARIS: - for filename, lineno in v: - d = {'filename': filename, 'lineno': lineno} - print >>fp, _( - '# File: %(filename)s, line: %(lineno)s') % d - elif options.locationstyle == options.GNU: - # fit as many locations on one line, as long as the - # resulting line length doesn't exceeds 'options.width' - locline = '#:' - for filename, lineno in v: - d = {'filename': filename, 'lineno': lineno} - s = _(' %(filename)s:%(lineno)s') % d - if len(locline) + len(s) <= options.width: - locline = locline + s - else: - print >> fp, locline - locline = "#:" + s - if len(locline) > 2: - print >> fp, locline - if isdocstring: - print >> fp, '#, docstring' - if k: # do not output empty msgid - print >> fp, 'msgid', normalize(k, options.escape) - print >> fp, 'msgstr ""\n' - - -def main(): - global default_keywords - try: - opts, args = getopt.getopt( - sys.argv[1:], - 'ad:UDEhk:Kno:p:S:Vvw:x:X:', - ['extract-all', 'default-domain=', 'escape', 'help', - 'keyword=', 'no-default-keywords', - 'add-location', 'no-location', 'output=', 'output-dir=', - 'style=', 'verbose', 'version', 'width=', 'exclude-file=', - 'docstrings', 'no-docstrings', 'support-unicode', - ]) - except getopt.error, msg: - usage(1, msg) - - # for holding option values - class Options: - # constants - GNU = 1 - SOLARIS = 2 - # defaults - extractall = 0 # FIXME: currently this option has no effect at all. - escape = 0 - keywords = [] - outpath = '' - outfile = 'messages.pot' - writelocations = 1 - locationstyle = GNU - verbose = 0 - width = 78 - excludefilename = '' - docstrings = 0 - nodocstrings = {} - - options = Options() - locations = {'gnu' : options.GNU, - 'solaris' : options.SOLARIS, - } - - # parse options - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt in ('-a', '--extract-all'): - options.extractall = 1 - elif opt in ('-d', '--default-domain'): - options.outfile = arg + '.pot' - elif opt in ('-E', '--escape'): - options.escape = 1 - elif opt in ('-D', '--docstrings'): - options.docstrings = 1 - elif opt in ('-k', '--keyword'): - options.keywords.append(arg) - elif opt in ('-K', '--no-default-keywords'): - default_keywords = [] - elif opt in ('-n', '--add-location'): - options.writelocations = 1 - elif opt in ('--no-location',): - options.writelocations = 0 - elif opt in ('-S', '--style'): - options.locationstyle = locations.get(arg.lower()) - if options.locationstyle is None: - usage(1, _('Invalid value for --style: %s') % arg) - elif opt in ('-o', '--output'): - options.outfile = arg - elif opt in ('-p', '--output-dir'): - options.outpath = arg - elif opt in ('-v', '--verbose'): - options.verbose = 1 - elif opt in ('-V', '--version'): - print _('pygettext.py (xgettext for Python) %s') % __version__ - sys.exit(0) - elif opt in ('-w', '--width'): - try: - options.width = int(arg) - except ValueError: - usage(1, _('--width argument must be an integer: %s') % arg) - elif opt in ('-x', '--exclude-file'): - options.excludefilename = arg - elif opt in ('-X', '--no-docstrings'): - fp = open(arg) - try: - while 1: - line = fp.readline() - if not line: - break - options.nodocstrings[line[:-1]] = 1 - finally: - fp.close() - - # calculate escapes - make_escapes(0) - - # calculate all keywords - options.keywords.extend(default_keywords) - - # initialize list of strings to exclude - if options.excludefilename: - try: - fp = open(options.excludefilename) - options.toexclude = fp.readlines() - fp.close() - except IOError: - print >> sys.stderr, _( - "Can't read --exclude-file: %s") % options.excludefilename - sys.exit(1) - else: - options.toexclude = [] - - # resolve args to module lists - expanded = [] - for arg in args: - if arg == '-': - expanded.append(arg) - else: - expanded.extend(getFilesForName(arg)) - args = expanded - - # slurp through all the files - eater = TokenEater(options) - for filename in args: - if filename == '-': - if options.verbose: - print _('Reading standard input') - fp = sys.stdin - closep = 0 - else: - if options.verbose: - print _('Working on %s') % filename - fp = open(filename) - eater.set_file_encoding(fp) - closep = 1 - try: - eater.set_filename(filename) - try: - tokenize.tokenize(fp.readline, eater) - except tokenize.TokenError, e: - print >> sys.stderr, '%s: %s, line %d, column %d' % ( - e[0], filename, e[1][0], e[1][1]) - finally: - if closep: - fp.close() - - if os.path.splitext(filename)[-1].lower() == '.kid': eater.extract_kid_strings() - - # write the output - if options.outfile == '-': - fp = sys.stdout - closep = 0 - else: - if options.outpath: - options.outfile = os.path.join(options.outpath, options.outfile) - fp = open(options.outfile, 'wt') - closep = 1 - try: - eater.write(fp) - finally: - if closep: - fp.close() - - -if __name__ == '__main__': - main() - # some more test strings - _(u'a unicode string') - # this one creates a warning - _('*** Seen unexpected token "%(token)s"') % {'token': 'test'} - _('more' 'than' 'one' 'string') |