aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryn M. Reeves <bmr@redhat.com>2013-04-16 15:04:55 +0100
committerBryn M. Reeves <bmr@redhat.com>2013-04-16 15:04:55 +0100
commit260100aea310976b06f015146d03b9f0fcfd707f (patch)
tree61585aac1a4ad7b574d188e48f5c46d3ddf627dd
parent0cf016e03c096451fcf3124670c0a860728cf30c (diff)
downloadsos-260100aea310976b06f015146d03b9f0fcfd707f.tar.gz
Remove jboss and as7 plug-ins and related infrastructure
The JBoss and AS7 plug-ins are among the largest and most complex in the tree: 192 sos/plugins/openstack.py 218 sos/plugins/emc.py 253 sos/plugins/as7.py 713 sos/plugins/jboss.py 861 sos/plugins/__init__.py 6722 total They are not used in any products based on these projects at the current time and are not being maintained or developed for new versions. Signed-off-by: Bryn M. Reeves <bmr@redhat.com>
-rw-r--r--sos/plugins/__init__.py136
-rw-r--r--sos/plugins/as7.py253
-rw-r--r--sos/plugins/jboss.py713
3 files changed, 0 insertions, 1102 deletions
diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py
index b0e3ab3f..24ae7094 100644
--- a/sos/plugins/__init__.py
+++ b/sos/plugins/__init__.py
@@ -714,142 +714,6 @@ class IndependentPlugin(object):
"""Tagging class that indicates this plugin can run on any platform"""
pass
-class AS7Mixin(object):
- """A mixin class that adds some helpful methods for AS7 related plugins"""
-
- class Request(object):
-
- def __init__(self, resource, operation="read-resource", parameters=None):
- self.resource = resource
- self.operation = operation
- if parameters:
- self.parameters = parameters
- else:
- self.parameters = {}
-
- def url_parts(self):
- """Generator function to split a url into (key, value) tuples. The
- url should contain an even number of pairs. In the case of / the
- generator will immediately stop iteration.
- """
- parts = self.resource.strip("/").split("/")
-
- if parts == ['']:
- raise StopIteration
-
- while parts:
- yield (parts.pop(0), parts.pop(0))
-
- def get_jboss_home(self):
- return self._get_opt('home', 'as7_home') or os.getenv("JBOSS_HOME", None)
-
- def query(self, request_obj):
- try:
- return self.query_java(request_obj)
- except Exception, e:
- self.add_alert("JBOSS API call failed, falling back to HTTP: %s" % e)
- return self.query_http(request_obj)
-
- def _get_opt(self, first, second, default=None):
- val = self.get_option(first)
- if val:
- return val
- val = self.get_option(second)
- if val:
- return val
- return default
-
- def query_java(self, request_obj):
- from org.jboss.dmr import ModelNode
- controller_client = self.get_option('controller_client_proxy')
- if not controller_client:
- raise AttributeError("Controller Client is not available")
-
- request = ModelNode()
- request.get("operation").set(request_obj.operation)
-
- for key, val in request_obj.url_parts():
- request.get('address').add(key,val)
-
- if request_obj.parameters:
- for key, value in request_obj.parameters.iteritems():
- request.get(key).set(value)
-
- return controller_client.execute(request).toJSONString(True)
-
- def query_http(self, request_obj, postdata=None):
- host = self._get_opt('host', 'as7_host')
- port = self._get_opt('port', 'as7_port')
-
- username = self._get_opt('user', 'as7_user')
- password = self._get_opt('pass', 'as7_pass')
-
- uri = "http://%s:%s/management" % (host,port)
-
- json_data = {'operation': request_obj.operation,
- 'address': []}
-
- for key, val in request_obj.url_parts():
- json_data['address'].append({key:val})
-
- for key, val in request_obj.parameters.iteritems():
- json_data[key] = val
-
- postdata = json.dumps(json_data)
- headers = {'Content-Type': 'application/json',
- 'Accept': 'application/json'}
-
- opener = urllib2.build_opener()
-
- if username and password:
- passwd_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
- passwd_manager.add_password(realm="ManagementRealm",
- uri=uri,
- user=username,
- passwd=password)
- digest_auth_handler = urllib2.HTTPDigestAuthHandler(passwd_manager)
- basic_auth_handler = urllib2.HTTPBasicAuthHandler(passwd_manager)
-
- opener.add_handler(digest_auth_handler)
- opener.add_handler(basic_auth_handler)
-
- req = urllib2.Request(uri, data=postdata, headers=headers)
-
- try:
- resp = opener.open(req)
- return resp.read()
- except Exception, e:
- err_msg = "Could not query url: %s; error: %s" % (uri, e)
- self.add_alert(err_msg)
- return err_msg
-
- def set_domain_info(self, parameters=None):
- """This function will add host controller and server instance name data
- if it is present to the desired resource. This is to support
- domain-mode operation in AS7.
- """
- host_controller_name = self.get_option("as7_host_controller_name")
- server_name = self.get_option("as7_server_name")
-
- if host_controller_name and server_name:
- if not parameters:
- parameters = {}
-
- parameters['host'] = host_controller_name
- parameters['server'] = server_name
-
- return parameters
-
-
- def resource_to_file(self, resource=None, parameters=None, operation='read-resource', outfile=None):
- parameters = self.set_domain_info(parameters)
-
- r = self.Request(resource=resource,
- parameters=parameters,
- operation=operation)
- self.add_string_as_file(self.query(r), filename=outfile)
-
-
def import_plugin(name, superclasses=None):
"""Import name as a module and return a list of all classes defined in that
module. superclasses should be a tuple of valid superclasses to import,
diff --git a/sos/plugins/as7.py b/sos/plugins/as7.py
deleted file mode 100644
index 52f71203..00000000
--- a/sos/plugins/as7.py
+++ /dev/null
@@ -1,253 +0,0 @@
-import os
-import sys
-import re
-import zipfile
-import urllib2
-import tempfile
-from xml.etree import ElementTree
-from itertools import chain
-
-from sos.plugins import Plugin, IndependentPlugin, AS7Mixin
-from sos.utilities import DirTree, find, checksum
-
-class AS7(Plugin, IndependentPlugin, AS7Mixin):
- """JBoss related information
- """
-
- requires_root = False
-
- version = "1.0"
-
- option_list = [
- ("home", "JBoss's installation dir (i.e. JBOSS_HOME)", '', False),
- ("logsize", 'max size (MiB) to collect per log file', '', 15),
- ("stdjar", 'Collect jar statistics for standard jars.', '', True),
- ("host", 'hostname of the management api for jboss', '', 'localhost'),
- ("port", 'port of the management api for jboss', '', '9990'),
- ("user", 'username for management console', '', None),
- ("pass", 'password for management console', '', None),
- ]
-
- __MD5_CHUNK_SIZE=128
- __jbossHome=None
- __haveJava=False
- __twiddleCmd=None
- __jbossServerConfigDirs = ["standalone", "domain"]
- __jbossHTMLBody=None
-
- def __alert(self, msg):
- self.soslog.error(msg)
- self.add_alert(msg)
-
- def __getJbossHome(self):
-
- self.__jbossHome = self.get_jboss_home()
- if not self.__jbossHome:
- self.add_alert("ERROR: The JBoss installation directory was not supplied.\
- The JBoss SOS plug-in cannot continue.")
- return False
-
- self.add_alert("INFO: The JBoss installation directory supplied to SOS is " +
- self.__jbossHome)
- return True
-
-
- def __getMd5(self, file):
- """Returns the MD5 sum of the specified file."""
-
- retVal = "?" * 32
-
- try:
- retVal = checksum(file, self.__MD5_CHUNK_SIZE)
- except IOError, ioe:
- self.__alert("ERROR: Unable to open %s for reading. Error: %s" % (file,ioe))
-
- return retVal
-
- def __getManifest(self, jarFile):
- """
- Given a jar file, this function will extract the Manifest and return it's contents
- as a string.
- """
- manifest = None
- try:
- zf = zipfile.ZipFile(jarFile)
- try:
- manifest = zf.read("META-INF/MANIFEST.MF")
- except Exception, e:
- self.__alert("ERROR: reading manifest from %s. Error: %s" % (jarFile, e))
- zf.close()
- except Exception, e:
- self.__alert("ERROR: reading contents of %s. Error: %s" % (jarFile, e))
- return manifest
-
- def __getStdJarInfo(self):
- jar_info_list = []
-
- for jarFile in find("*.jar", self.__jbossHome):
- checksum = self.__getMd5(jarFile)
- manifest = self.__getManifest(jarFile)
- path = jarFile.replace(self.__jbossHome, 'JBOSSHOME')
- if manifest:
- manifest = manifest.strip()
- jar_info_list.append((path, checksum, manifest))
-
- if jar_info_list:
- jar_info_list.sort()
- self.add_string_as_file("\n".join([
- "%s\n%s\n%s\n===\n" % (name, checksum, manifest)
- for (name, checksum, manifest) in jar_info_list]),
- 'jarinfo.txt')
- else:
- self.add_alert("WARN: No jars found in JBoss system path (" + self.__jbossHome + ").")
-
- def get_online_data(self):
- """
- This function co-locates calls to the management api that gather
- information from a running system.
- """
- self.resource_to_file(resource="/",
- parameters={"recursive": "true"},
- outfile="configuration.json")
- self.resource_to_file(resource="/core-service/service-container",
- operation="dump-services",
- outfile="dump-services.json")
- self.resource_to_file(resource="/subsystem/modcluster",
- operation="read-proxies-configuration",
- outfile="cluster-proxies-configuration.json")
- self.resource_to_file(resource="/core-service/platform-mbean/type/threading",
- operation="dump-all-threads",
- parameters={"locked-synchronizers": "true",
- "locked-monitors": "true"},
- outfile="threaddump.json")
-
- def __getFiles(self, configDirAry):
- """
- This function will collect files from JBOSS_HOME for analysis. The scope of files to
- be collected are determined by options to this SOS plug-in.
- """
- for dir_ in configDirAry:
- path = os.path.join(self.__jbossHome, dir_)
- ## First add forbidden files
- self.add_forbidden_path(os.path.join(path, "tmp"))
- self.add_forbidden_path(os.path.join(path, "work"))
- self.add_forbidden_path(os.path.join(path, "data"))
-
- if os.path.exists(path):
- ## First get everything in the conf dir
- confDir = os.path.join(path, "configuration")
- self.add_forbidden_path(os.path.join(confDir, 'mgmt-users.properties'))
- self.add_forbidden_path(os.path.join(confDir, 'application-users.properties'))
-
- for logFile in find("*.log", path):
- self.add_copy_spec_limit(logFile,
- self.get_option("logsize"),
- sub=(self.__jbossHome, 'JBOSSHOME'))
-
- for xml in find("*.xml", path):
- self.add_copy_spec(xml, sub=(self.__jbossHome, 'JBOSSHOME'))
-
- for prop in find("*.properties", path):
- self.add_copy_spec(prop, sub=(self.__jbossHome, 'JBOSSHOME'))
-
- deployment_info = self.__get_deployment_info(confDir)
- deployments = self.__get_deployments(path)
- for deployment in deployments:
- self.__get_listing_from_deployment(deployment, deployment_info)
-
- for xml in find("*.xml", os.path.join(self.__jbossHome, 'modules')):
- self.add_copy_spec(xml, sub=(self.__jbossHome, 'JBOSSHOME'))
-
- def __get_deployment_info(self, dir_):
- """Gets the deployment name to sha1 mapping for all deployments defined
- in configs under dir_"""
- deployment_info = {}
- for config in find("*.xml", dir_):
- root = ElementTree.parse(config).getroot()
- # the namespace is harder to fetch than it should be
- ns = root.tag.rpartition("}")[0]
- ns += "}"
- for deployment in root.findall("./%sdeployments/%sdeployment" % (ns, ns)):
- name = deployment.attrib.get("name")
- sha1 = deployment.getchildren()[0].attrib.get("sha1")
- deployment_info[sha1] = name
- return deployment_info
-
- def __get_deployments(self, path):
- return list(chain(
- find("*", os.path.join(path, "deployments")),
- find("content", path)))
-
- def __get_listing_from_deployment(self, path, mapping):
- try:
- zf = zipfile.ZipFile(path)
- contents = []
- for zipinfo in zf.infolist():
- if zipinfo.filename.endswith("/"):
- continue
- contents.append((zipinfo.filename, zipinfo.file_size))
- zf.close()
- contents.sort()
- output = "\n".join(["%s:%d" % (fn, fs) for fn, fs in contents])
-
- path_to = path.replace(self.__jbossHome, '')
- if 'content' in path:
- path_to = path_to.strip(os.path.sep).rstrip("content")
- path_to = os.path.join(*path_to.split(os.path.sep)[:-2])
- sha1 = "".join(path.split(os.path.sep)[-3:-1])
- name = mapping.get(sha1, sha1)
- else:
- path_to, name = os.path.split(path_to)
-
- self.add_string_as_file(output, os.path.join(path_to, "%s.txt" % name))
- except:
- # this is probably not a zipfile so we don't care
- pass
-
- def check_enabled(self):
- return self.__getJbossHome()
-
- def setup(self):
-
- if not self.__getJbossHome():
- self.exit_please()
-
- try:
- self.get_online_data()
- except urllib2.URLError:
- pass
-
- if self.get_option("stdjar"):
- self.__getStdJarInfo()
-
- tree = DirTree(self.__jbossHome).as_string()
- self.add_string_as_file(tree, "jboss_home_tree.txt")
-
- self.__getFiles(self.__jbossServerConfigDirs)
-
- def postproc(self):
- """
- Obfuscate passwords.
- """
-
- password_xml_regex = re.compile(r'<password>.*</password>', re.IGNORECASE)
-
- for dir_ in self.__jbossServerConfigDirs:
- path = os.path.join(self.__jbossHome, dir_)
-
- self.do_file_sub(os.path.join(path,"configuration","*.xml"),
- password_xml_regex,
- r'<password>********</password>')
-
- tmp = os.path.join(path,"configuration")
- for propFile in find("*-users.properties", tmp):
- self.do_file_sub(propFile,
- r"=(.*)",
- r'=********')
-
-# Remove PW from -ds.xml files
- tmp = os.path.join(path, "deployments")
- for dsFile in find("*-ds.xml", tmp):
- self.do_file_sub(dsFile,
- password_xml_regex,
- r"<password>********</password>")
diff --git a/sos/plugins/jboss.py b/sos/plugins/jboss.py
deleted file mode 100644
index f36ba1d0..00000000
--- a/sos/plugins/jboss.py
+++ /dev/null
@@ -1,713 +0,0 @@
-import os
-import zipfile
-import platform
-import fnmatch
-import shlex
-import subprocess
-import string
-import grp, pwd
-
-from sos.plugins import Plugin, RedHatPlugin
-from sos.utilities import DirTree, find
-
-class jboss(Plugin, RedHatPlugin):
- """JBoss related information
- """
-
- option_list = [("home", 'JBoss\'s installation dir (i.e. JBOSS_HOME)', '', False),
- ("javahome", 'Java\'s installation dir (i.e. JAVA_HOME)', '', False),
- ("profile", 'Quoted and space separated list of server profiles to limit collection. \
-Default=\'all default minimal production standard web\'.', '', False),
- ("user", 'JBoss JMX invoker user to be used with twiddle.', '', False),
- ("pass", 'JBoss JMX invoker user\'s password to be used with twiddle.', '', False),
- ("logsize", 'max size (MiB) to collect per log file', '', 15),
- ("stdjar", 'Collect jar statistics for standard jars.', '', True),
- ("servjar", 'Collect jar statistics from any server configuration dirs.', '', True),
- ("twiddle", 'Collect twiddle data.', '', True),
- ("appxml", 'Quoted and space separated list of application\'s whose XML descriptors you want. The keyword \"all\" will collect all descriptors in the designated profile(s).', '', False)]
-
- __MD5_CHUNK_SIZE=128
- __jbossHome=None
- __haveJava=False
- __twiddleCmd=None
- __jbossSystemJarDirs = [ "client", "lib" , "common/lib" ]
- __jbossServerConfigDirs = ["all", "default", "minimal", "production", "standard", "web"]
- __jbossHTMLBody=None
-
- def __getJbossHome(self):
- """
- Will attempt to locate the JBoss installation dir in either jboss.home or
- scrape it from the environment variable JBOSS_HOME.
- Returns:
- True JBOSS_HOME is set and the path exists. False otherwise.
- """
- if self.get_option("home"):
- ## Prefer this value first over the ENV
- self.__jbossHome=self.get_option("home")
- self.add_alert("INFO: The JBoss installation directory supplied to SOS is " +
- self.__jbossHome)
- elif os.environ.get("JBOSS_HOME"):
- self.__jbossHome=os.environ.get("JBOSS_HOME")
- self.add_alert("INFO: The JBoss installation directory (i.e. JBOSS_HOME) from the environment is " +
- self.__jbossHome)
- else:
- self.add_alert("ERROR: The JBoss installation directory was not supplied.\
- The JBoss SOS plug-in cannot continue.")
- return False
-
- if os.path.exists(self.__jbossHome):
- ## We need to set JBOSS_CLASSPATH otherwise some twiddle commands will not work.
- jbossClasspath=None
- tmp=os.path.join(self.__jbossHome, "lib")
- if os.path.exists(tmp):
- jbossClasspath=tmp + os.sep + "*" + os.pathsep
- else:
- self.add_alert("WARN: The JBoss lib directory does not exist. Dir(%s) " % tmp)
-
- tmp=os.path.join(self.__jbossHome, "common" , "lib")
- if os.path.exists(tmp):
- jbossClasspath+=tmp + os.sep + "*"
- else:
- self.add_alert("WARN: The JBoss lib directory does not exist. Dir(%s) " % tmp)
-
- os.environ['JBOSS_CLASSPATH']=jbossClasspath
-
- return True
- else:
- msg = "ERROR: The path to the JBoss installation directory does not exist. Path is: " + self.__jbossHome
- print msg
- self.add_alert(msg)
- return False
-
- def __getJavaHome(self):
- """
- This SOS plug-in makes extensive use of JBoss' twiddle program and twiddle uses Java. As such, we
- need to ensure that java and JAVA_HOME is known to the plug-in so that it can use Java.
- This function will put JAVA_HOME and JAVA_HOME/bin into the environment if they're not already
- there.
- """
- javaHome=None
- java="bin/java"
-
- if self.get_option("javahome"):
- ## Prefer this value first over the ENV
- javaHome=self.get_option("javahome")
- self.add_alert("INFO: The Java installation directory supplied to SOS is " +
- javaHome)
- elif os.environ.get("JAVA_HOME"):
- javaHome=os.environ.get("JAVA_HOME")
- self.add_alert("INFO: The Java installation directory (i.e. JAVA_HOME) from the environment is " +
- javaHome)
- else:
- ## Test to see if Java is already in the PATH
- (status, output, rtime) = self.call_ext_prog("java -version")
- if (status == 0):
- self.add_alert("INFO: The Java installation directory is in the system path.")
- return True
- else:
- self.add_alert("ERROR: The Java installation directory was not supplied.\
- The JBoss SOS plug-in will not collect twiddle data.")
- return False
-
-
- java=os.path.join(javaHome, java)
- if os.path.exists(java) and os.access(java, os.X_OK):
- os.environ['JAVA_HOME']=javaHome
- ## Place the supplied Java at the *head* of the path.
- os.environ['PATH'] = os.path.join(javaHome, "bin") + os.pathsep + os.environ['PATH']
- return True
- else:
- msg = "ERROR: The path to the Java installation directory does not exist. Path is: %s" % (javaHome)
- print msg
- self.add_alert(msg)
- return False
-
-
- def __getJMXCredentials(self):
- """
- Read the JMX credentials from the option list.
- Returns:
- A formatted credential string for twiddle consumption if both user and pass
- are supplied. None otherwise.
- """
- credential = None
- ## Let's make a best effort not to pass expansions or escapes to the shell
- ## by strong quoting the user's input
- if self.get_option("user"):
- credential=" -u '" + self.get_option("user") + "' "
- if self.get_option("pass"):
- credential+=" -p '" + self.get_option("pass") + "' "
- else:
- credential=None
- return credential
-
- def __updateServerConfigDirs(self):
- """
- By default this plug-in will attempt to collect logs from every
- JBoss server configuration directory (i.e. profile). The
- user may have supplied a limited list, as such, we must respect
- that wish.
- Returns:
- Nothing. Will update __jbossServerConfigDirs if the user
- supplied a limited list.
- """
- if self.get_option("profile"):
- profiles=self.get_option("profile")
- ## I'd rather use comma as the delimiter but get_option doesn't seem to be passing it through.
- ## Since we are using spaces as the delimiter, we need to filter out empty list elements
- ## if the user did something like ' all default web '.
- profiles=profiles.split(' ')
- ## Flter(None doesn't work. Allows 0.
- self.__jbossServerConfigDirs=filter(lambda x: len(x), profiles)
- return
-
- def __buildTwiddleCmd(self):
- """
- Utility function to build the twiddle command with/without credentials
- so that it can be used by later fcns. If twiddle is found
- """
- ## In the off-chance that SOS is ever ported to cygwin or this plugin
- ## is ported to win...
- if platform.system() == "Windows":
- self.__twiddleCmd=os.path.join(self.__jbossHome, "bin", "twiddle.bat")
- else:
- self.__twiddleCmd=os.path.join(self.__jbossHome, "bin", "twiddle.sh")
-
- if os.path.exists(self.__twiddleCmd) and os.access(self.__twiddleCmd, os.X_OK):
- credential = self.__getJMXCredentials()
- if credential:
- self.__twiddleCmd += credential
- else:
- ## Reset twiddlecmd to None
- self.add_alert("ERROR: The twiddle program could not be found. Program=%s" % (self.__twiddleCmd))
- self.__twiddleCmd = None
-
- return
-
- def __createHTMLBodyStart(self):
- """
- The free-form HTML that can be inserted into the SOS report with add_custom_text is within
- a <p> block. We need to add a few pieces of HTML so that all of our subsequent data will
- be rendered properly.
- """
- self.__jbossHTMLBody = """
- <br/>
- <br/>
- <script type="text/javascript">
- <!--
- function show(h) {
- var tbl = document.getElementById(h);
- tbl.style.display = 'block';
- }
- function hide(h) {
- var tbl = document.getElementById(h);
- tbl.style.display = 'none';
- }
- // -->
- </script>
- <b>JBoss SOS Report Table of Contents</b>
- <ul style="list-style-type: square">
- <li><a href="#system-jar-info">JBoss System Jar Information</a>
- </li>
- <li><a href="#profile-jar-info">JBoss Server Configurations Jar Information</a>
- </li>
- <li><a href="#jboss-home-directory-tree">JBOSS_HOME Directory Tree</a>
- </li>
- <li><a href="#jboss-system-mbean-data">JBoss JMX MBean Data from <tt>jboss.system:*</tt></a>
- </li>
- <li><a href="#jboss-mbean-data">JBoss JMX MBean Data from <tt>jboss:*</tt></a>
- </li>
- <li><a href="#jboss-mbean-summary">JBoss MBean Summary</a>
- </li>
- <li><a href="#jboss-messaging">JBoss JMX Messaging MBean Data from <tt>jboss.messaging:*</tt></a>
- </li>
- <li><a href="#jboss-j2ee">JBoss JMX J2EE MBean Data from <tt>jboss.j2ee:*</tt></a>
- </li>
- <li><a href="#jboss-vfs">JBoss JMX VFS MBean Data from <tt>jboss.vfs:*</tt></a>
- </li>
- <li><a href="#jboss-jsr77-data">JBoss JSR77 Data</a>
- </li>
- </ul>
- <br/>
- <br/>
- """
-
- def __getMd5(self, file):
- """
- Will perform an MD5 sum on a given file and return the file's message digest. This function
- will not read the entire file into memory, instead, it will consume the file in 128 byte
- chunks. This might be slightly slower but, the intent of a SOS report is to collect data from
- a system that could be under stress and we shouldn't stress it more by loading entire Jars into
- real memory.
-
- Note: This fcn expects hashlib; however, this isn't always available. If it isn't then
- we will use md5sum
- """
-
- retVal="????????????????????????????????"
-
- try:
- import hashlib
- try:
- fd = open(file,"rb")
- except IOError, ioe:
- msg = "ERROR: Unable to open %s for reading. Error: " % (file,ioe)
- print msg
- self.add_alert(msg)
-
- md5 = hashlib.md5()
- data = fd.read(self.__MD5_CHUNK_SIZE)
- while data:
- md5.update(data)
- data = fd.read(self.__MD5_CHUNK_SIZE)
- retVal = md5.hexdigest()
- except ImportError, e:
- process = subprocess.Popen(['md5sum', file],
- shell=False,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- result = process.communicate()
- if (process.returncode == 0):
- retVal = result[0].partition(' ')[0]
- else:
- msg = "ERROR: Unable to compute md5sum of %s. Msg (%s)" % (file, result[1])
- print msg
- self.add_alert(msg)
-
- return retVal
-
-
- def __getManifest(self, jarFile):
- """
- Given a jar file, this function will extract the Manifest and return it's contents
- as a string.
- """
- manifest=None
- try:
- zf = zipfile.ZipFile(jarFile)
- try:
- manifest=zf.read("META-INF/MANIFEST.MF")
- except Exception, e:
- msg="ERROR: reading manifest from %s. Error: %s" % (jarFile, e)
- print msg
- self.add_alert(msg)
- zf.close()
- except Exception, e:
- msg="ERROR: reading contents of %s. Error: %s" % (jarFile, e)
- print msg
- self.add_alert(msg)
- return manifest
-
- def __getStdJarInfo(self):
-
- self.__jbossHTMLBody += """
- <div id="system-jar-info" style="font-weight: bold;">&ndash; JBoss System Jar Information</div>
- """
-
- for dir in self.__jbossSystemJarDirs:
- path=os.path.join(self.__jbossHome, dir)
- if os.path.exists(path):
- nicePath=path.replace(os.sep, "-")
- self.__jbossHTMLBody += """
- <div>
- &mdash; Summary of Jar Files in JBoss System Directory
- <tt>%s</tt>
- ( <a href="javascript:show('%s')">Show</a> / <a
- href="javascript:hide('%s')">Hide</a> ):
- </div>
- <div id="%s" style="overflow: hidden; display: none">
- <ul style="list-style-type: square">
- """ % (path,nicePath,nicePath,nicePath)
-
- found= False
- for jarFile in find("*.jar", path):
- found= True
- nicePath=jarFile.replace(os.sep, "-")
- self.__jbossHTMLBody += """
- <li>Jar File: <tt>%s</tt><br/>
- MD5: <tt>%s</tt>
- <br /> Manifest File (
- <a href="javascript:show('%s')">Show</a> /
- <a href="javascript:hide('%s')">Hide</a> ):<br />
- <div id="%s" style="overflow: hidden; display: none">
- <pre>
- %s
- </pre>
- </div>
- </li>
- """ % (jarFile,
- self.__getMd5(jarFile),
- nicePath,
- nicePath,
- nicePath,
- self.__getManifest(jarFile))
-
- if not found:
- self.add_alert("WARN: No jars found in JBoss system path (" + path + ").")
- self.__jbossHTMLBody += """
- </ul>
- </div>
- """
- else:
- self.add_alert("ERROR: JBoss system path (" + path + ") does not exist.")
- return
-
- def __getServerConfigJarInfo(self, configDirAry):
-
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="profile-jar-info" style="font-weight: bold;">&ndash; JBoss Server Configurations Jar Information</div>
- """
- for dir in configDirAry:
- serverDir = os.path.join("server", dir)
- path=os.path.join(self.__jbossHome, serverDir)
- if os.path.exists(path):
- nicePath=path.replace(os.sep, "-")
- self.__jbossHTMLBody += """
- <div>
- &mdash; Summary of Jar Files in the <tt>%s</tt> JBoss Server Configuration
- ( <a href="javascript:show('%s')">Show</a> / <a
- href="javascript:hide('%s')">Hide</a> ):
- </div>
- <div id="%s" style="overflow: hidden; display: none">
- <ul style="list-style-type: square">
- """ % (dir, nicePath,nicePath,nicePath)
-
- found = False
- for jarFile in find("*.jar", path):
- found = True
- nicePath=jarFile.replace(os.sep, "-")
- self.__jbossHTMLBody += """
- <li id="system-jar-info">Jar File: <tt>%s</tt><br/>
- MD5: <tt>%s</tt>
- <br /> Manifest File (
- <a href="javascript:show('%s')">Show</a> /
- <a href="javascript:hide('%s')">Hide</a> ):<br />
- <div id="%s" style="overflow: hidden; display: none">
- <pre>
- %s
- </pre>
- </div>
- </li>
- """ % (jarFile,
- self.__getMd5(jarFile),
- nicePath,
- nicePath,
- nicePath,
- self.__getManifest(jarFile))
-
- if not found:
- self.add_alert("WARN: No jars found in the JBoss server configuration (%s)." % (path))
-
- self.__jbossHTMLBody += """
- </ul>
-</div>
- """
- else:
- self.add_alert("ERROR: JBoss server configuration path (" + path + ") does not exist.")
-
- return
-
- def __getJBossHomeTree(self):
- """
- This function will execute the "tree" command on JBOSS_HOME.
- """
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="jboss-home-directory-tree" style="font-weight: bold;">&ndash; JBOSS_HOME Directory Tree</div>
-
- <div>
- &mdash; JBOSS_HOME Tree
- ( <a href="javascript:show('jboss-home-tree')">Show</a> / <a
- href="javascript:hide('jboss-home-tree')">Hide</a> ):
- </div>
- <div id="jboss-home-tree" style="overflow: hidden; display: none">
- <pre>
- """
- try:
- output = DirTree(self.__jbossHome).as_string()
- self.__jbossHTMLBody += """
-%s
- </pre>
- </div>
- """ % (output)
- except Exception, e:
- self.__jbossHTMLBody += """
- ERROR: Unable to generate <tt>tree</tt> on JBOSS_HOME.
- Exception: %s
- </pre>
- </div>
- """ % e
- return
-
- def __getMbeanData(self, dataTitle, divId, twiddleOpts):
- credentials = ""
- if self.__haveJava and self.__twiddleCmd:
- self.__jbossHTMLBody += """
- <div>
- &mdash; %s
- ( <a href="javascript:show('%s')">Show</a> / <a
- href="javascript:hide('%s')">Hide</a> ):
- </div>
- <div id="%s" style="overflow: hidden; display: none">
- <table style="margin-left: 30px;font-size:14px">
- <tr>
- <td align="left">
- Twiddle Options:
- </td>
- <td align="left"><tt>%s</tt></td>
- </tr>
- </table>
- <pre>
-
- """ % (dataTitle, divId, divId, divId,twiddleOpts)
- cmd = "%s %s" % (self.__twiddleCmd, twiddleOpts)
-
- proc = subprocess.Popen(shlex.split(cmd), stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
- output = proc.communicate()[0]
- status = proc.returncode
- if status == 0 and output:
- self.__jbossHTMLBody += output.strip()
- else:
- self.__jbossHTMLBody += """
- ERROR: Unable to collect %s data.
- Output: %s
- Status: %d
- """ % (twiddleOpts, output, status)
- else:
- self.__jbossHTMLBody += "ERROR: Unable to collect data twiddle or Java is missing."
-
- self.__jbossHTMLBody += """
- </pre>
- </div>
- """
- return
-
- def __getTwiddleData(self):
- """
- This function co-locates all of the calls to twiddle so that they can be easily disabled.
- """
-
- ## Get jboss.system.* Data
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="jboss-system-mbean-data" style="font-weight: bold;">&ndash; JBoss JMX MBean Data from <tt>jboss.system:*</tt></div>
- """
- self.__getMbeanData("JBoss Server Info",
- "jboss-server-info",
- " get 'jboss.system:type=ServerInfo' ")
- self.__getMbeanData("JBoss Server Config Info",
- "jboss-server-config-info",
- " get 'jboss.system:type=ServerConfig' ")
- self.__getMbeanData("JBoss CXF Server Config Info",
- "jboss-cxfserver-config-info",
- " get 'jboss.ws:service=ServerConfig' ")
- self.__getMbeanData("JBoss Memory Pool Info",
- "jboss-memory-pool-info",
- " invoke 'jboss.system:type=ServerInfo' listMemoryPools true ")
- self.__getMbeanData("JBoss Thread CPU Utilization",
- "jboss-thread-cpu-info",
- " invoke 'jboss.system:type=ServerInfo' listThreadCpuUtilization ")
- self.__getMbeanData("JBoss Thread Dump",
- "jboss-thread-dump",
- " invoke 'jboss.system:type=ServerInfo' listThreadDump ")
- self.__getMbeanData("JBoss Logging Config Info",
- "jboss-logging-config-info",
- " get 'jboss.system:service=Logging,type=Log4jService' ")
-
- ## Get jboss.* Data
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="jboss-mbean-data" style="font-weight: bold;">&ndash; JBoss JMX MBean Data from <tt>jboss:*</tt></div>
- """
- self.__getMbeanData("JBoss System Properties",
- "jboss-system-properties-info",
- " invoke 'jboss:name=SystemProperties,type=Service' showAll ")
-
- self.__getMbeanData("JBoss JNDI List View",
- "jboss-jndi-list-info",
- " invoke 'jboss:service=JNDIView' list true ")
-
- ## MBean Summary
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="jboss-mbean-summary" style="font-weight: bold;">&ndash; JBoss MBean Summary</div>
- """
- self.__getMbeanData("JBoss MBean Vendor/Version Info",
- "jboss-vendor-version",
- " get 'JMImplementation:type=MBeanServerDelegate' ")
- self.__getMbeanData("JBoss MBean Count",
- "jboss-mbean-count",
- " serverinfo -c ")
- self.__getMbeanData("JBoss MBean List",
- "jboss-mbean-list",
- " serverinfo -l ")
-
- ##JBoss Messaging Data
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="jboss-messaging" style="font-weight: bold;">&ndash; JBoss JMX Messaging MBean Data from <tt>jboss.messaging:*</tt></div>
- """
- self.__getMbeanData("JBoss Message Counters",
- "jboss-message-counters",
- " invoke 'jboss.messaging:service=ServerPeer' listMessageCountersAsHTML ")
-
- self.__getMbeanData("JBoss Prepared Transactions Table",
- "jboss-prepared-transactions",
- " invoke 'jboss.messaging:service=ServerPeer' listAllPreparedTransactions ")
-
- self.__getMbeanData("JBoss Active Clients Table",
- "jboss-active-clients",
- " invoke 'jboss.messaging:service=ServerPeer' showActiveClientsAsHTML ")
-
- ## Get j2ee Data query 'jboss.j2ee:*'
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="jboss-j2ee" style="font-weight: bold;">&ndash; JBoss JMX J2EE MBean Data from <tt>jboss.j2ee:*</tt></div>
- """
- self.__getMbeanData("JBoss J2EE MBeans",
- "jboss-j2ee-mbeans",
- " query 'jboss.j2ee:*' ")
-
- ## VFS
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="jboss-vfs" style="font-weight: bold;">&ndash; JBoss JMX VFS MBean Data from <tt>jboss.vfs:*</tt></div>
- """
- self.__getMbeanData("JBoss VFS Cached Contexts",
- "jboss-vfs-contexts",
- " invoke 'jboss.vfs:service=VFSCacheStatistics' listCachedContexts ")
-
- ## Get jsr77 Data
- self.__jbossHTMLBody += """
- <br/>
- <br/>
- <div id="jboss-jsr77-data" style="font-weight: bold;">&ndash; JBoss JSR77 Data</div>
- """
- self.__getMbeanData("JBoss JSR77 Data",
- "jboss-jsr77",
- " jsr77 ")
- return
-
-
- def __getFiles(self, configDirAry):
- """
- This function will collect files from JBOSS_HOME for analysis. The scope of files to
- be collected are determined by options to this SOS plug-in.
- """
-
- for dir in configDirAry:
- path=os.path.join(self.__jbossHome, "server", dir)
- ## First add forbidden files
- self.add_forbidden_path(os.path.join(path, "tmp"))
- self.add_forbidden_path(os.path.join(path, "work"))
- self.add_forbidden_path(os.path.join(path, "data"))
-
- if os.path.exists(path):
- ## First get everything in the conf dir
- confDir=os.path.join(path, "conf")
- self.do_copy_file_or_dir(confDir)
- ## Log dir next
- logDir=os.path.join(path, "log")
-
- for logFile in find("*", logDir):
- self.add_copy_spec_limit(logFile, self.get_option("logsize"))
- ## Deploy dir
- deployDir=os.path.join(path, "deploy")
-
- for deployFile in find("*", deployDir, max_depth=1):
- self.add_copy_spec(deployFile)
-
- ## Get application deployment descriptors if designated.
- if self.option_enabled("appxml"):
- appxml=self.get_option("appxml")
- ## I'd rather use comma as the delimiter but get_option doesn't seem to be passing it through.
- ## Since we are using spaces as the delimiter, we need to filter out empty list elements
- ## if the user did something like ' all default web '.
- appxml=appxml.split(' ')
- ## Flter(None doesn't work. Allows 0.
- appxml=filter(lambda x: len(x), appxml)
- for app in appxml:
- pat = os.path.join("*%s*" % (app,), "WEB-INF")
- for file in find("*.xml", deployDir, path_pattern=pat):
- self.add_copy_spec(file)
- return
-
- def check_enabled(self):
- if not self.__getJbossHome():
- return False
- return True
-
- def setup(self):
-
- ## We need to know where JBoss is installed and if we can't find it we
- ## must exit immediately.
- if not self.__getJbossHome():
- self.exit_please()
- return
-
- ## Check to see if the user passed in a limited list of server config jars.
- self.__updateServerConfigDirs()
-
- ## Generate HTML Body for report
- self.__createHTMLBodyStart()
-
- ## Generate hashes of the stock Jar files for the report.
- if self.get_option("stdjar"):
- self.__getStdJarInfo()
-
- ## Generate hashes for the Jars in the various profiles
- if self.get_option("servjar"):
- self.__getServerConfigJarInfo(self.__jbossServerConfigDirs)
-
- ## Generate a Tree for JBOSS_HOME
- self.__getJBossHomeTree()
-
- if self.get_option("twiddle"):
- ## We need to know where Java is installed or at least ensure that it
- ## is available to the plug-in so that we can run twiddle.
- self.__haveJava = self.__getJavaHome()
- self.__buildTwiddleCmd()
- self.__getTwiddleData()
-
-
- self.add_custom_text(self.__jbossHTMLBody)
-
- self.__getFiles(self.__jbossServerConfigDirs)
-
- return
-
- def postproc(self):
- """
- Obfuscate passwords.
- """
-
- for dir in self.__jbossServerConfigDirs:
- path=os.path.join(self.__jbossHome, "server", dir)
- ## Really annoying that there appears to be no vehicle to
- ## say I want ignore case...argh!
- self.do_file_sub(os.path.join(path,"conf","login-config.xml"),
- r"\"[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]\".*>.*</[Mm][Oo][Dd][Uu][Ll][Ee]-[Oo][Pp][Tt][Ii][Oo][Nn].*>",
- r'"password">********</module-option>')
-
- tmp = os.path.join(path,"conf", "props")
- for propFile in find("*-users.properties", tmp):
- self.do_file_sub(propFile,
- r"=(.*)",
- r'=********')
-
- ## Remove PW from -ds.xml files
- tmp=os.path.join(path, "deploy")
- for dsFile in find("*-ds.xml", tmp):
- self.do_file_sub(dsFile,
- r"<[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd].*>.*</[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd].*>",
- r"<password>********</password>")
- return