Source code for insights.parsers.alternatives

"""
Alternatives - command ``/usr/bin/alternatives`` output
=======================================================
"""

from insights import parser, CommandParser
from insights.core import ParseException
from insights.specs import Specs


[docs]class AlternativesOutput(CommandParser): """ Read the output of ``/usr/sbin/alternatives --display *program*`` and convert into information about the given program's alternatives. Typical input is:: java - status is auto. link currently points to /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-1.b15.el7_2.x86_64/jre/bin/java /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.111-2.6.7.2.el7_2.x86_64/jre/bin/java - priority 1700111 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-1.b15.el7_2.x86_64/jre/bin/java - priority 1800111 /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/java - priority 16091 slave ControlPanel: /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/ControlPanel slave keytool: /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/keytool slave policytool: /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/policytool slave rmid: /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/rmid Current `best' version is /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/java. Lines are interpreted this way: * Program lines are of the form '*name* - status is *status*', and start the information for a program. Lines before this are ignored. * The current link to this program is found on lines starting with 'link currently points to'. * Lines starting with '/' and with ' - priority ' in them record an alternative path and its priority. * Lines starting with 'slave *program*: *path*' are recorded against the alternative path. * Lines starting with 'Current \`best' version is' indicate the default choice of an 'auto' status alternative. The output of ``alternatives --display *program*`` can only ever list one program, so as long as one 'status is' line is found (as described above), the content of the object displays that program. Attributes: program (str): The name of the program found in the 'status is' line. This attribute is set to ``None`` if a status line is not found. status (str): The status of the program, or ``None`` if not found. link (str): The link to this program, or ``None`` if the 'link currently points to`` line is not found. best (str): The 'best choice' path that ``alternatives`` would use, or ``None`` if the 'best choice' line is not found. paths (dict): The alternative paths for this program. Each path is a dictionary containing the following keys: * ``path``: the actual path of this alternative for the program * ``priority``: the priority, as an integer (e.g. 1700111) * ``slave``: a dictionary of programs dependent on this alternative - the key is the program name (e.g. 'ControlPanel') and the value is the path to that program for this alternative path. Examples: >>> java_alt.program 'java' >>> java_alt.link '/usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/java' >>> len(java_alt.paths) 2 >>> java_alt.paths[0]['path'] '/usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/java' >>> java_alt.paths[0]['priority'] 16091 >>> java_alt.paths[0]['slave']['ControlPanel'] '/usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/ControlPanel' """
[docs] def parse_content(self, content): """ Parse the output of the ``alternatives`` command. """ self.program = None self.status = None self.link = None self.best = None self.paths = [] current_path = None # Set up instance variable for line in content: words = line.split(None) if ' - status is' in line: # alternatives only displays one program, so finding # this line again is an error. if self.program: raise ParseException( "Program line for {newprog} found in output for {oldprog}".format( newprog=words[0], oldprog=self.program ) ) # Set up new program data self.program = words[0] self.status = words[4][:-1] # remove trailing . self.alternatives = [] current_path = {} elif not self.program: # Lines before 'status is' line are ignored continue elif line.startswith(' link currently points to ') and len(words) == 5: # line: ' link currently points to /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-1.b15.el7_2.x86_64/jre/bin/java' self.link = words[4] elif ' - priority ' in line and len(words) == 4 and words[3].isdigit(): # line: /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/java - priority 16091 # New path - save current path if set self.paths.append({ 'path': words[0], 'priority': int(words[3]), 'slave': {}, }) current_path = self.paths[-1] elif line.startswith(' slave ') and len(words) == 3 and current_path: # line: ' slave ControlPanel: /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/ControlPanel' current_path['slave'][words[1][:-1]] = words[2] # remove final : from program elif line.startswith("Current `best' version is ") and len(words) == 5: # line: 'Current `best' version is /usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/java.' self.best = words[4][:-1] # strip trailing . from path
[docs]@parser(Specs.display_java) class JavaAlternatives(AlternativesOutput): """ Class to read the ``/usr/sbin/alternatives --display java`` output. Uses the ``AlternativesOutput`` base class to get information about the alternatives for ``java`` available and which one is currently in use. Examples: >>> java_alt.program 'java' >>> java_alt.link '/usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/java' >>> len(java_alt.paths) 2 >>> java_alt.paths[0]['path'] '/usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/java' >>> java_alt.paths[0]['priority'] 16091 >>> java_alt.paths[0]['slave']['ControlPanel'] '/usr/lib/jvm/jre-1.6.0-ibm.x86_64/bin/ControlPanel' """ pass
[docs]@parser(Specs.alternatives_display_python) class PythonAlternatives(AlternativesOutput): """ Class to read the ``/usr/sbin/alternatives --display python`` output. Uses the ``AlternativesOutput`` base class to get information about the alternatives for ``best`` available and which one is currently in use. Examples: >>> python_alt.program 'python' >>> python_alt.link '/usr/bin/python3' >>> len(python_alt.paths) 2 >>> python_alt.paths[0]['path'] '/usr/libexec/no-python' >>> python_alt.paths[0]['priority'] 404 """ pass