diff options
author | Jesse Jaggars <jjaggars@redhat.com> | 2012-02-28 12:22:11 -0600 |
---|---|---|
committer | Jesse Jaggars <jjaggars@redhat.com> | 2012-02-29 16:38:33 -0600 |
commit | 4b9412ce0f18da79b71d3abbce343848dfa3a434 (patch) | |
tree | cdbc602c525afd230321e0610c56166904b6b1e7 | |
parent | a0c94dff75fb0ab26e003885379ef6ddd51ca4f0 (diff) | |
download | sos-4b9412ce0f18da79b71d3abbce343848dfa3a434.tar.gz |
Removing many unused bits
-rw-r--r-- | AUTHORS | 3 | ||||
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | TODO | 17 | ||||
-rw-r--r-- | doc/Makefile | 89 | ||||
-rw-r--r-- | doc/conf.py | 194 | ||||
-rw-r--r-- | doc/index.rst | 20 | ||||
-rw-r--r-- | doc/make.bat | 113 | ||||
-rwxr-xr-x | example_plugins/example.py | 58 | ||||
-rw-r--r-- | example_plugins/fsusage.py | 23 | ||||
-rw-r--r-- | example_plugins/release.py | 21 | ||||
-rwxr-xr-x | example_plugins/runcommand.py | 45 | ||||
-rw-r--r-- | sos/plugins/__init__.py | 15 | ||||
-rw-r--r-- | sos/sosreport.py | 2 | ||||
-rw-r--r-- | tests/archive_tests.py | 24 | ||||
-rw-r--r-- | tests/worker.py | 148 | ||||
l--------- | tests/worker_link | 1 | ||||
-rw-r--r-- | tests/ziptest | 0 | ||||
l--------- | tests/ziptest_link | 1 | ||||
-rw-r--r-- | tools/osdetect.py | 87 | ||||
-rwxr-xr-x | tools/profiler/report | 145 | ||||
-rwxr-xr-x | tools/sos-open | 151 | ||||
-rw-r--r-- | worker/specs | 100 | ||||
-rw-r--r-- | worker/worker.py | 150 |
23 files changed, 35 insertions, 1376 deletions
@@ -1,7 +1,9 @@ Adam Stokes <astokes@redhat.com> Ben Turner <bturner@redhat.com> Eugene Teo <eteo@redhat.com> +Jesse Jaggars <jjaggars@redhat.com> Joey Boggs <jboggs@redhat.com> +John Berninger <jwb@redhat.com> Justin Payne <jpayne@redhat.com> Keith Kearnan <kearnan_keith@emc.com> Kent Lamb <klamb@redhat.com> @@ -14,4 +16,3 @@ Sadique Puthen <sputhenp@redhat.com> Shijoe George <spanjikk@redhat.com> Steve Conklin <sconklin@redhat.com> Tomas Smetana <tsmetana@redhat.com> -John Berninger <jwb@redhat.com> @@ -13,7 +13,3 @@ To access to the public source code repository for this project run: to install locally (as root) ==> make install to build an rpm ==> make rpm to build a zipfile for use with jython ==> make zip - -I recommend nose to run the unittests: - -nosetests -v --with-cover --cover-package=sos --cover-html @@ -1,17 +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. - - * Allow to use a different rootdir than / - - * 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/doc/Makefile b/doc/Makefile deleted file mode 100644 index 181ab3ef..00000000 --- a/doc/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SOS.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SOS.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/doc/conf.py b/doc/conf.py deleted file mode 100644 index e7e1c162..00000000 --- a/doc/conf.py +++ /dev/null @@ -1,194 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SOS documentation build configuration file, created by -# sphinx-quickstart on Mon Feb 8 17:58:11 2010. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'SOS' -copyright = u'2010, Adam Stokes' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.9' -# The full version, including alpha/beta/rc tags. -release = '1.9' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# "<project> v<release> documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_use_modindex = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a <link> tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'SOSdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'SOS.tex', u'SOS Documentation', - u'Adam Stokes', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_use_modindex = True diff --git a/doc/index.rst b/doc/index.rst deleted file mode 100644 index cb2cbe67..00000000 --- a/doc/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. SOS documentation master file, created by - sphinx-quickstart on Mon Feb 8 17:58:11 2010. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to SOS's documentation! -=============================== - -Contents: - -.. toctree:: - :maxdepth: 2 - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/doc/make.bat b/doc/make.bat deleted file mode 100644 index 104ca9b0..00000000 --- a/doc/make.bat +++ /dev/null @@ -1,113 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -set SPHINXBUILD=sphinx-build -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^<target^>` where ^<target^> is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\SOS.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\SOS.ghc - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/example_plugins/example.py b/example_plugins/example.py index d4356d1c..4b49e423 100755 --- a/example_plugins/example.py +++ b/example_plugins/example.py @@ -1,6 +1,3 @@ -## 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 @@ -15,22 +12,22 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -import sos.plugintools +from sos.plugins import Plugin, RedHatPlugin -# Class name must be the same as file name and method names must not change -class example(sos.plugintools.PluginBase): - '''dummy example plugin''' +# the class name determines the plugin name +# if you want to override it simply provide a @classmethod name() +# that returns the name you want +class example(Plugin, RedHatPlugin): + '''This is the description for the example plugin''' # Plugin developers want to override setup() from which they will call - # addCopySpec() to collect files and collectExtOutPut() to collect programs + # addCopySpec() to collect files and collectExtOutput() to collect programs # output. - # If you want to go fancy you may also want to override diagnose(), - # analyze() and postproc(). Have a look at the PluginBase definition - # for details. # Add your options here, indicate whether they are slow to run, and set # whether they are enabled by default - # Options are python dictionaries that contain a short name, - # long description, speed, and whether they are enabled by default + # each option is a tuple of the following format: + # (name, description, fast or slow, default value) + # each option will be addressable like -k name=value 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)] @@ -45,39 +42,16 @@ class example(sos.plugintools.PluginBase): ''' # 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") + + with open("/proc/cpuinfo") as f: + for line in f: + if "vendor_id" in line: + self.addAlert("Vendor ID string is: %s <br>\n" % line) # 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.collectExtOutput("/bin/ps -ef") - return + self.collectExtOutput("/bin/ps -ef") - 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 setup() 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 diff --git a/example_plugins/fsusage.py b/example_plugins/fsusage.py deleted file mode 100644 index 2532c5f7..00000000 --- a/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/example_plugins/release.py b/example_plugins/release.py deleted file mode 100644 index db4d7581..00000000 --- a/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/example_plugins/runcommand.py b/example_plugins/runcommand.py deleted file mode 100755 index df8951d2..00000000 --- a/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/sos/plugins/__init__.py b/sos/plugins/__init__.py index dbf3ca1d..a40f26a4 100644 --- a/sos/plugins/__init__.py +++ b/sos/plugins/__init__.py @@ -124,9 +124,6 @@ class Plugin(object): "Returns the plugin's name as a string" return class_.__name__.lower() - def setArchive(self, archive): - self.archive = archive - def policy(self): return self.cInfo["policy"] @@ -518,15 +515,9 @@ class Plugin(object): it should run or not. """ # some files or packages have been specified for this package - if len(self.files) or len(self.packages): - for fname in self.files: - if os.path.exists(fname): - return True - for pkgname in self.packages: - if self.isInstalled(pkgname): - return True - return False - + if self.files or self.packages: + return (any(os.path.exists(fname) for fname in self.files) or + any(self.isInstalled(pkg) for pkg in self.packages)) return True def defaultenabled(self): diff --git a/sos/sosreport.py b/sos/sosreport.py index fb2622ab..5cfa5db8 100644 --- a/sos/sosreport.py +++ b/sos/sosreport.py @@ -644,7 +644,7 @@ class SoSReport(object): def setup(self): for plugname, plug in self.loaded_plugins: try: - plug.setArchive(self.archive) + plug.archive = self.archive plug.setup() except KeyboardInterrupt: raise diff --git a/tests/archive_tests.py b/tests/archive_tests.py index 01c46395..f982be0a 100644 --- a/tests/archive_tests.py +++ b/tests/archive_tests.py @@ -24,28 +24,28 @@ class ZipFileArchiveTest(unittest.TestCase): self.zf.close() def test_add_file(self): - self.zf.add_file('tests/worker.py') + self.zf.add_file('tests/ziptest') self.zf.close() - self.check_for_file('test/tests/worker.py') + self.check_for_file('test/tests/ziptest') def test_add_dir(self): self.zf.add_file('tests/') self.zf.close() - self.check_for_file('test/tests/worker.py') + self.check_for_file('test/tests/ziptest') def test_add_renamed(self): - self.zf.add_file('tests/worker.py', dest='tests/worker_renamed.py') + self.zf.add_file('tests/ziptest', dest='tests/ziptest_renamed') self.zf.close() - self.check_for_file('test/tests/worker_renamed.py') + self.check_for_file('test/tests/ziptest_renamed') def test_add_renamed_dir(self): self.zf.add_file('tests/', 'tests_renamed/') self.zf.close() - self.check_for_file('test/tests_renamed/worker.py') + self.check_for_file('test/tests_renamed/ziptest') def test_add_string(self): self.zf.add_string('this is content', 'tests/string_test.txt') @@ -84,28 +84,28 @@ class TarFileArchiveTest(unittest.TestCase): self.assertTrue(os.path.exists('test.tar')) def test_add_file(self): - self.tf.add_file('tests/worker.py') + self.tf.add_file('tests/ziptest') self.tf.close() - self.check_for_file('test/tests/worker.py') + self.check_for_file('test/tests/ziptest') def test_add_dir(self): self.tf.add_file('tests/') self.tf.close() - self.check_for_file('test/tests/worker.py') + self.check_for_file('test/tests/ziptest') def test_add_renamed(self): - self.tf.add_file('tests/worker.py', dest='tests/worker_renamed.py') + self.tf.add_file('tests/ziptest', dest='tests/ziptest_renamed') self.tf.close() - self.check_for_file('test/tests/worker_renamed.py') + self.check_for_file('test/tests/ziptest_renamed') def test_add_renamed_dir(self): self.tf.add_file('tests/', 'tests_renamed/') self.tf.close() - self.check_for_file('test/tests_renamed/worker.py') + self.check_for_file('test/tests_renamed/ziptest') def test_add_string(self): self.tf.add_string('this is content', 'tests/string_test.txt') diff --git a/tests/worker.py b/tests/worker.py deleted file mode 100644 index cf121f38..00000000 --- a/tests/worker.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python - -import unittest -import pexpect - -from re import search, escape -from os import kill -from signal import SIGINT, SIGUSR1 - -class WorkerTests(unittest.TestCase): - - __exec_echo_lol_output__ = '0\r\n4\r\nlol\r\n\r\n0\r\n\r\n' - - def prompt(self, n): - return ('#%i#\r\n' % n) - - def interrupted(self, n): - return ('#%i# INTERRUPTED\r\n' % n) - - def setUp(self): - self.worker = pexpect.spawn('python ../worker/worker.py') - # worker should always be very fast to span - self.expect(self.prompt(0)) - - def sig(self, sig): - kill(self.worker.pid, sig) - - def lose_expect(self, v, timeout = 3): - self.worker.expect(v, timeout) - - def expect(self, v, timeout = 3): - self.lose_expect(v, timeout) - self.assertEqual(self.worker.before, '') - - def send(self, text): - self.worker.send(text) - self.expect(escape(text)) - - def sendlines(self, lines): - for line in lines: - self.worker.send(line+'\n') - for line in lines: - self.expect(escape(line)+'\r\n') - - def __finishes_ok__(self): - self.expect(pexpect.EOF) - self.worker.close() - self.assertEqual(self.worker.exitstatus, 0) - - def test_exit(self): - self.sendlines(['exit']) - self.__finishes_ok__() - - def test_ctrlc_when_running(self): - self.sendlines(['exec', 'sleep 1; exec echo lol']) - self.sig(SIGINT) - self.expect(self.interrupted(0)+self.prompt(1)) - self.test_exit() - - def test_ctrlc_on_cmd_prompt(self): - self.sig(SIGINT) - self.expect(self.interrupted(0)+self.prompt(1)) - self.test_exit() - - def test_ctrlc_when_entering_command(self): - # "Mon clavier se blo" -- French reference - self.send('glo') - self.sig(SIGINT) - self.expect(self.interrupted(0)+self.prompt(1)) - self.test_exit() - - def test_ctrlc_on_readparms_drops(self): - self.sendlines(['exec']) - self.sig(SIGINT) - self.expect(self.interrupted(0)+self.prompt(1)) - self.sendlines(['glob']) - self.sig(SIGINT) - self.expect(self.interrupted(1)+self.prompt(2)) - self.test_exit() - - def test_basic_noop(self): - self.sendlines(['noop']) - self.expect(self.prompt(1)) - self.test_exit() - - def test_basic_ping(self): - self.sendlines(['ping']) - self.expect('ALIVE\r\n' + self.prompt(1)) - self.test_exit() - - def test_basic_glob(self): - self.sendlines(['glob', '/*bin']) - self.expect('2\r\n(/bin\r\n/sbin|/sbin\r\n/bin)\r\n'+self.prompt(1)) - self.test_exit() - - def test_empty_glob(self): - self.sendlines(['glob', '/?kyzh?']) - self.expect('0\r\n'+self.prompt(1)) - self.test_exit() - - def test_basic_sigusr1(self): - self.sig(SIGUSR1) - self.expect('ALIVE\r\n') - self.test_exit() - - def test_sigusr1_when_entering_command(self): - self.worker.send('pin') - self.sig(SIGUSR1) - self.expect('pinALIVE\r\n') - self.sendlines(['g']) - self.expect('ALIVE\r\n' + self.prompt(1)) - self.test_exit() - - def test_sigusr1_on_readparms(self): - self.worker.send('exec\nech') - self.sig(SIGUSR1) - self.worker.send('o lol\n') - self.expect('exec\r\nechALIVE\r\no lol\r\n'+ - self.__exec_echo_lol_output__ + self.prompt(1)) - self.test_exit() - - def test_exec_continues_after_sigusr1(self): - self.worker.send('exec\nsleep 0.1; exec echo lol\n') - self.sig(SIGUSR1) - self.expect('exec\r\nsleep 0.1; exec echo lol\r\nALIVE\r\n'+ - self.__exec_echo_lol_output__ + self.prompt(1)) - self.test_exit() - - def test_increasing_counter(self): - for req_counter in range(1, 5): - self.sendlines(['noop']) - self.expect(self.prompt(req_counter)) - for req_counter in range(5, 10): - self.sendlines(['ping']) - self.expect('ALIVE\r\n'+self.prompt(req_counter)) - self.test_exit() - - def test_queuecommands(self): - self.worker.send('ping\n'*5) - self.worker.send('exec\necho lol\n'*5) - for req_counter in range(1,6): - self.lose_expect('ALIVE\r\n'+self.prompt(req_counter)) - for req_counter in range(6,11): - self.lose_expect(self.__exec_echo_lol_output__+self.prompt(req_counter)) - self.test_exit() - -if __name__ == '__main__': - unittest.main() diff --git a/tests/worker_link b/tests/worker_link deleted file mode 120000 index 20be81a3..00000000 --- a/tests/worker_link +++ /dev/null @@ -1 +0,0 @@ -worker.py
\ No newline at end of file diff --git a/tests/ziptest b/tests/ziptest new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/ziptest diff --git a/tests/ziptest_link b/tests/ziptest_link new file mode 120000 index 00000000..e99bb13c --- /dev/null +++ b/tests/ziptest_link @@ -0,0 +1 @@ +ziptest
\ No newline at end of file diff --git a/tools/osdetect.py b/tools/osdetect.py deleted file mode 100644 index fea78cc5..00000000 --- a/tools/osdetect.py +++ /dev/null @@ -1,87 +0,0 @@ -''' -Created on Aug 2, 2011 -@author: Keith Robertson -''' - -import pprint -import os -import re - -class OSTypes: - """ - Utility class with enumerations for the various OSes to facilitate - OS detection. - """ - JAVA_OS_NAME_KEY='os.name' - - OS_TYPE_LINUX='Linux' - OS_TYPE_LINUX_PAT=re.compile('^%s$' % OS_TYPE_LINUX, re.I) - OS_TYPE_WIN='Windows' - OS_TYPE_WIN_PAT=re.compile('^%s$' % OS_TYPE_WIN, re.I) - OS_TYPE_AIX='AIX' - OS_TYPE_AIX_PAT=re.compile('^%s$' % OS_TYPE_AIX, re.I) - OS_TYPE_MAC='Mac OS' - OS_TYPE_MAC_PAT=re.compile('^%s$' % OS_TYPE_MAC, re.I) - OS_TYPE_390='OS/390' - OS_TYPE_390_PAT=re.compile('^%s$' % OS_TYPE_390, re.I) - OS_TYPE_HPUX='HP-UX' - OS_TYPE_HPUX_PAT=re.compile('^%s$' % OS_TYPE_HPUX, re.I) - -def printProps(): - try: - from java.lang import System - from java.util import Set - from java.util import Iterator - - set = System.getProperties().entrySet() - it = set.iterator() - while it.hasNext(): - me = it.next(); - print "Key (%s) Value(%s)" % (me.getKey(), me.getValue()) - except Exception, e: - print "ERROR: unable to print Java properties %s" % e - - - -def java_detect_os(): - """ - Try to load Java packages. If successful then we know we are running - in JYthon. Use the JRE to determine what type of OS and return the proper - policy. - """ - try: - from java.lang import System - - ostype = System.getProperty(OSTypes.JAVA_OS_NAME_KEY) - if ostype: - if OSTypes.OS_TYPE_LINUX_PAT.match(ostype): - print "Matched %s" % OSTypes.OS_TYPE_LINUX - # Lots of checks here to determine linux version. - #return proper policy here - elif OSTypes.OS_TYPE_WIN_PAT.match(ostype): - print "Matched %s" % OSTypes.OS_TYPE_WIN - elif OS_TYPE_AIX_PAT.match(ostype): - print "Matched %s" % OSTypes.OS_TYPE_AIX - elif OS_TYPE_MAC_PAT.match(ostype): - print "Matched %s" % OSTypes.OS_TYPE_MAC - elif OS_TYPE_390_PAT.match(ostype): - print "Matched %s" % OSTypes.OS_TYPE_390 - elif OS_TYPE_HPUX_PAT.match(ostype): - print "Matched %s" % OSTypes.OS_TYPE_HPUX - else: - raise Exception("Unsupported OS type of %s." % ostype) - else: - raise Exception("Unable to get %s from JRE's system properties." % OSTypes.JAVA_OS_NAME_KEY) - except Exception, e: - print "WARN: unable to print Java properties %s" % e - -def native_detect_os(): - print "here" - - - -if __name__ == '__main__': - #printProps() - detectOS() - - pass
\ No newline at end of file diff --git a/tools/profiler/report b/tools/profiler/report deleted file mode 100755 index 13577fcc..00000000 --- a/tools/profiler/report +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/python - -# profile reporter - -import sys, os, operator, string -from optparse import OptionParser -from glob import glob -from subprocess import Popen, PIPE -import tarfile - -class GlobalVars: - def __init__(self): - pass - -class MyWriter: - def __init__(self, stdout, filename): - self.stdout = stdout - self.logfile = file(filename, 'w') - - def write(self, text): - self.stdout.write(text) - self.logfile.write(text) - - def close(self): - self.stdout.close() - self.logfile.close() - -def parse_options(opts): - """ parse cmd line opts """ - - parser = OptionParser() - parser.add_option("-f","--filename", dest="filename", - help="write report to FILENAME") - parser.add_option("-t", "--time", dest="rtime", - help="set minimum RUNTIME to report", action="store", - default=float(0.1), type="float") - parser.add_option("-i", "--input", dest="rpt_dir", - help="define directory of sosreport archives", - action="store", default=False) - - GlobalVars.cmdlineopts, GlobalVars.cmdlineargs = parser.parse_args(opts) - - if not GlobalVars.cmdlineopts.rpt_dir: - raise SystemExit("\nPlease make sure to specify --input FILES\n") - -def uncompress_reports(fname): - """ uncompresses the sosreport """ - p = Popen(["xz","-d", fname], stdout=PIPE, stdin=PIPE) - out, err = p.communicate() - if err: - print "Problem extracting %s" % (fname,) - return - -def read_archive(fname): - """ reads tarfile archive and grabs the sosprofile.log fileobj """ - tar = tarfile.open(os.path.abspath(fname), "r:") - for tarinfo in tar.getmembers(): - if 'sosprofile.log' in tarinfo.name: - fobj = tar.extractfile(tarinfo) - buf = fobj.read() - tar.close() - return buf - -def timeoutput(secs): - if secs > 60: - secs = round(secs) / 60 - return (secs, 'm') - elif secs < 60: - return (secs, 's') - -def sort_profile(): - """ provide reports on sosreport profiling """ - # uncompress reports from input files - for rpt in glob(GlobalVars.cmdlineopts.rpt_dir+"/*.xz"): - uncompress_reports(os.path.abspath(rpt)) - GlobalVars.rpt_count = 0 - GlobalVars.timecount = 0 - GlobalVars.lrc = {} - for rpt in glob(GlobalVars.cmdlineopts.rpt_dir+"/*.tar"): - buf = read_archive(rpt) - time_sorts=[] - if not buf: - continue - for line in buf.split("\n"): - try: - cmd, rtime = line.split("time:") - try: - # cmds that span multiple lines still need time calculated - cmd = cmd.split(":")[1] - except IndexError: - cmd, rtime = line.split("time:") - time_sorts.append((cmd.strip(), rtime.strip())) - except ValueError: - continue - time_count = 0 - b_val_count = 0 - write_stats = open(rpt + ".profile_report", 'w') - write_stats.write(28 * ' ' + 'SOSreport Profile Report' + 27 * ' ' + "\n") - write_stats.write(79 * '.' + "\n") - for a,b in sorted(time_sorts, key=operator.itemgetter(1)): - b_val = float(b) - time_count += b_val - if b_val > float(GlobalVars.cmdlineopts.rtime): - b_val_count += b_val - write_stats.write("%-79s %s\n" % (a[:78], b)) - if GlobalVars.lrc.has_key(a) and \ - GlobalVars.lrc[a] < b_val: - GlobalVars.lrc[a] = b_val - else: - GlobalVars.lrc[a] = b_val - # Keep up with total run time for all reports - GlobalVars.timecount += time_count - # Write out totals per report - write_stats.write(79 * '.' + "\n") - write_stats.write("Totals:\n") - secs, fmt = timeoutput(b_val_count) - write_stats.write("cumulative > %s: \t%f%s\n" % (GlobalVars.cmdlineopts.rtime, secs, fmt)) - secs, fmt = timeoutput(time_count) - write_stats.write("cumulative total:\t%f%s\n" % (secs,fmt)) - write_stats.close() - # increment report count so we can get an average runtime - GlobalVars.rpt_count += 1 - -if __name__ == "__main__": - parse_options(sys.argv[1:]) - if GlobalVars.cmdlineopts.filename: - writer = MyWriter(sys.stdout, GlobalVars.cmdlineopts.filename) - sys.stdout = writer - print "Building reports ..." - sort_profile() - print 79 * "-" - print "Total runtime for %d reports is %fs" % (round(GlobalVars.rpt_count, 2), GlobalVars.timecount) - print "Average total runtime of %d reports is %fs" % (round(GlobalVars.rpt_count, 2), GlobalVars.timecount / GlobalVars.rpt_count) - print 79 * "-" - print - print "Longest running commands > %s:" % (GlobalVars.cmdlineopts.rtime,) - print 79 * "-" - for cmd, rtime in sorted(GlobalVars.lrc.iteritems(), key=operator.itemgetter(1)): - print "%-75s %s" % (cmd[:69], rtime) - - if GlobalVars.cmdlineopts.filename: - print 79 * "-" - print "Report log written to: %s" % (GlobalVars.cmdlineopts.filename,) - writer.close() - diff --git a/tools/sos-open b/tools/sos-open deleted file mode 100755 index ffc9f051..00000000 --- a/tools/sos-open +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/python - -import os, commands, getopt, sys, tarfile - -# FILES NEEDED BY CHECKSYSREPORT: /etc/redhat-release /etc/sysconfig/rhn/up2date rpm-Va installed-rpms uname lsmod - -CONFIG = {} -report_dirs = [] - -CONFIG["outdir"] = "/tmp/sysreports" -CONFIG["extract_reports"] = [] -CONFIG["spawn_terminal"] = False -if not sys.stdin.isatty(): CONFIG["spawn_terminal"] = True -else: CONFIG["spawn_terminal"] = False - -def cat(fname): - try: - fp = open(fname,"r") - print fp.read() - fp.close() - except: pass - -try: - opts, args = getopt.getopt(sys.argv[1:], "hi:w:vxf", ["help", "input="]) -except getopt.GetoptError: - # print help information and exit: - usage() - sys.exit(2) - -for o, a in opts: - if o == "-v": - verbose = True - if o == "-f": - CONFIG["spawn_terminal"] = False - if o == "-x": - CONFIG["spawn_terminal"] = True - sys.argv[sys.argv.index("-x")] = "-f" - if o in ("-h", "--help"): - usage() - sys.exit() - if o in ("-d"): - CONFIG["outdir"] = a - if o in ("-w"): - a = os.path.abspath(a) - try: os.stat(a) - except: print "ERROR: could not open", a - else: report_dirs.append(a) - - if o in ("-i"): - a = os.path.abspath(a) - try: os.stat(a) - except: print "ERROR: could not open", a - -if CONFIG["spawn_terminal"]: - print "spawning new terminal" - sys.argv[0] = os.path.abspath(sys.argv[0]) - os.system("gnome-terminal -e '%s'" % (' '.join(sys.argv))) - sys.exit() - -CONFIG["extract_reports"] = [os.path.abspath(a) for a in args] - -if not os.path.isdir(CONFIG["outdir"]): - if not os.path.exists(CONFIG["outdir"]): - exit("ERROR: working directory path exists but it's not a directory") - else: - try: os.mkdir(CONFIG["outdir"]) - except: exit("ERROR: could not create working directory") - -try: os.chdir(CONFIG["outdir"]) -except: exit("ERROR: could not chdir into working directory, please check permissions") - -for report in CONFIG["extract_reports"]: - report_ext = report.rsplit(".",1)[-1] - - if report_ext == "gpg": - clear_fname = os.path.join(CONFIG["outdir"],os.path.basename(report.rsplit(".",1)[0])) - status, output = commands.getstatusoutput("gpg --output %s %s" % (clear_fname,report)) - if status: - sys.exit("ERROR: could not decrypt using gpg" + output ) - report = clear_fname - report_ext = clear_fname.rsplit(".",1)[-1] - del clear_fname - - outdir = None - tar = tarfile.open(report, "r") - for tarinfo in tar: - if tarinfo.isdir(): outdir = tarinfo.name ; break - tar.close() - - if not outdir: - print("INFO: archive doesn't appear to be either a sysreport or sosreport") - cddir = os.path.basename(report) - for sout in [ ".tar.gz", ".tgz", ".tar.bz2" ]: - if cddir.endswith(sout): cddir = cddir[:-len(sout)] - cddir = os.path.abspath(os.path.join(CONFIG["outdir"],"extract_" + cddir)) - outdir = cddir - else: - cddir = CONFIG["outdir"] - outdir = os.path.abspath(os.path.join(CONFIG["outdir"], outdir)) - - extract = True - if os.path.isdir(outdir): - extract = False - yorno = False - print "This report already seems to have been extracted in:" - print " " + outdir - print - while yorno not in ['y','n']: yorno = raw_input("Do you want to replace it with a fresh copy ? (y/n) ").lower() - if yorno == 'y': - print "Deleting previous copy..." - os.system("chmod -R u+rw %s" % outdir) - os.system("rm -rf %s" % outdir) - extract = True - - if extract: - print "Extracting..." - if not os.path.isdir(cddir): - os.mkdir(cddir) - if report_ext == "bz2": - status, output = commands.getstatusoutput("tar xCfj %s %s" % (cddir,report)) - elif report_ext == "gz" or report_ext == "tgz" : - status, output = commands.getstatusoutput("tar xCfz %s %s" % (cddir,report)) - - if status: - print("ERROR: there was some problem extracting the report (%s)" % report) - - report_dirs.append(os.path.abspath(outdir)) - -if len(report_dirs) == 1 and os.path.isdir(report_dirs[0]): - os.chdir(report_dirs[0]) - - if os.path.isfile("sos_reports/diagnose.txt"): - print - print "Diagnostics messages available:" - print - fp = open("sos_reports/diagnose.txt","r") - for line in fp.readlines(): - print " " + line.strip("\n") - fp.close() - print - - report_dirs[0] - - print - print "The extracted report is located in: " - print " " + report_dirs[0] - print "Once finished, press exit to return." - print - cat("uname") - os.system("PS1='[SoS \W]\$ ' HOME='%s' /bin/bash -l" % (report_dirs[0]) ) - sys.exit(-1) diff --git a/worker/specs b/worker/specs deleted file mode 100644 index 0d1b7dd1..00000000 --- a/worker/specs +++ /dev/null @@ -1,100 +0,0 @@ -============== -gatherer specs -============== - -WORK IN PROGRESS - -/When a command is expected, the line "#X#" is printed, where X is the number of -/the request, starting a 0 and incremented after each processed request. -[test_incrementing_counter] - -/Requests are spanned on multiple lines. The first line is the command, the -/following lines are parameters (one parameter per line unless stated otherwise). -[statement] - -/Requests are all blocking. As they are read from stdin using readline(), -/they can be buffered in stdin. -[test_queuecommands] - -/When the number of parameters or returns is variable, it should be indicated -/first. -/When a parameter or returned value is not one line of printable characters, -/its length as returned by len() should be indicated first. -[statement] - -/When gatherer is expected to write in a file, its parent directory should exist -/and it will be opened with the "w" flag (unless stated otherwise). -[statement] - -/No timeout handling should be implemented in gatherer. -[statement] - -SIGINT should stop the current request parsing or execution, -write '#X# INTERRUPTED' to stderr where X is the number of the request, -then continue the normal flow of execution including incrementing the request -number. - -/stderr is only used: -/- by Python to display exceptions; -/- to print "ALIVE" when SIGUSR1 is received or after a "ping" request; -/- to print "UNKNOWN COMMAND" when a command is unknown; -/- to print "INTERRUPTED #X#" when a command is interrupted with SIGINT. -[statement(easy to prove wrong, hard to prove right)] - -Requests --------- - -/Command: "noop" -/Params: -/- None -/Action: -/- None -/Returns: -/- Nothing -[test_basic_noop] - -/Command: "ping" -/Params: -/- None -/Action: -/- Prints "ALIVE" on stderr -/Returns: -/- Nothing -[test_basic_ping NEED(stderr is being used)] - -/Command: "exit" -/Params: -/- None -/Action: -/- The gatherer process returns 0 -/Returns: -/- Nothing -[test_exit] - -/Command: "glob" -/Params: -/- The globbing pattern -/Action: -/- Performs a glob.glob() -/Returns: -/- On the first line, a number of results, n -/- On the following n lines, filenames, line by line -[test_basic_glob, test_empty_glob] - -Command: "exec" -Params: -- The command to send to a shell -Action: -- Executes the command in a shell using subprocess.Popen -Returns: -- The return code of the command -- The length of its stdout output as return by len(), in decimal. -- Its stdout output, followed by a trailing '\n' -- The length of its stderr output as return by len(), in decimal. -- Its stderr output, followed by a trailing '\n' - -Command: "cp" --- to be defined after staring at the current sosreport code. - -Command: "globcp" --- to be defined after staring at the current sosreport code. diff --git a/worker/worker.py b/worker/worker.py deleted file mode 100644 index e9977019..00000000 --- a/worker/worker.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python - -class Request: - Commands = {} - - @staticmethod - def Register(name): - def decorate(cls): - Request.Commands[name] = cls - return cls - return decorate - - @staticmethod - def ReadCommand(shell): - cmd = shell.read_line().strip() - request = Request.Commands[cmd](shell) - return request - - def __init__(self, shell): - self.shell = shell - - def read_params(self): - pass - - def execute(self): - raise NotImplementedError() - - -@Request.Register("noop") -class NoopRequest(Request): - - def execute(self): - pass - -@Request.Register("ping") -class PingRequest(Request): - - def execute(self): - self.shell.status("ALIVE") - - -@Request.Register("exit") -class ExitRequest(Request): - - def execute(self): - self.shell.exit() - - -@Request.Register("glob") -class GlobRequest(Request): - - def read_params(self): - self.pattern = self.shell.read_line() - - def execute(self): - from glob import glob - results = glob(self.pattern) - self.shell.write("%i\n" % len(results)) - for result in results: - self.shell.write(result+"\n") - - -@Request.Register("exec") -class ExecRequest(Request): - - def read_params(self): - self.cmd = self.shell.read_line() - - def execute(self): - from subprocess import Popen, PIPE - proc = Popen(self.cmd, shell=True, stdout=PIPE, stderr=PIPE, bufsize=-1) - stdout, stderr = proc.communicate() - self.shell.write("%i\n" % proc.returncode) - self.shell.write_blob(stdout) - self.shell.write_blob(stderr) - -class Shell: - def __init__(self, input_stream, output_stream, status_stream, - bork_action = None): - self.__input_stream__ = input_stream - self.__output_stream__ = output_stream - self.__status_stream__ = status_stream - self.__bork_action__ = bork_action or self.exit - self.__exit__ = False - self.__req_counter__ = 0 - - def loop(self): - while self.__exit__ == False: - self.show_prompt() - try: request = Request.ReadCommand(self) - except KeyboardInterrupt: - self.exit() - except KeyError: - self.status("UNKNOWN COMMAND"); - self.bork() - else: - try: request.read_params() - except KeyboardInterrupt: - pass - else: - self.__req_counter__ += 1 - try: - request.execute() - except KeyboardInterrupt: - self.status("INTERRUPTED"); - - def exit(self): - self.__exit__ = True - - def bork(self): - self.__bork_action__() - - def show_prompt(self): - self.write("#%i#\n" % self.__req_counter__) - - def status(self, str): - print >> self.__status_stream__, str - - def write(self, msg): - self.__output_stream__.write(msg) - - def write_blob(self, blob): - self.write("%i\n" % len(blob)) - self.write(str(blob)+"\n") - - def read_line(self): - while True: - try: - return self.__input_stream__.readline().strip() - except IOError: - pass - - def read_blob(self, length): - try: - blob = self.__input_stream__.read(length) - assert self.__input_stream__.read(1) == "\n" - except: - raise IOError() - else: - return blob - -if __name__ == "__main__": - from sys import stdin, stdout, stderr, exit - from signal import signal, SIGUSR1 - def handler(signum, frame): - print >> stderr, "ALIVE" - signal(SIGUSR1, handler) - def bork(): - exit(-1) - Shell(stdin, stdout, stderr, bork_action = bork).loop() |