Source code for insights.parsers.initscript

"""
InitScript - files ``/etc/rc.d/init.d/*``
=========================================

InitScript is a parser for the initscripts in ``/etc/rc.d/init.d``.

Because this parser read multiple files, the initscripts are stored as a list
within the parser and need to be iterated through in order to find specific
initscripts.

Examples:

    >>> for initscript in shared[InitScript]: # Parser contains list of all initscripts
    ...     print "Name:", initscript.file_name
    ...
    Name: netconsole
    Name: rhnsd

"""
import re

from insights.core import Parser
from insights.core.exceptions import ParseException
from insights.core.plugins import parser
from insights.specs import Specs

CHKCONFIG_REGEX = re.compile(r"^#\s+chkconfig:\s+.*$")
LSB_REGEX = re.compile(r"^#\s+Provides:\s+.*$")

SHEBANG_REGEX = re.compile(r"^#!\s*/.*$")
COMMENT_REGEX = re.compile(r"^\s*#.*$")
STARTSTOPSTATUS_REGEX = re.compile(r"\b(start|stop|status)\b")


[docs] class EmptyFileException(ParseException): pass
[docs] class NotInitscriptException(ParseException): pass
[docs] @parser(Specs.initscript) class InitScript(Parser): """ Parse initscript files. Each item is a dictionary with following fields: Attributes: file_name (str): initscript name file_path (str): initscript path without leading '/' file_content (list): initscript content, line by line Because some files may not be real initscripts, to determine whether a file in ``etc/rc.d/init.d/`` is an initscript, the parser checks for ``# chkconfig: <values>`` or ``# Provides: <names>`` strings in the script. If that matches, then it assumes it is an initscript. Otherwise, it tries to find out if it is by searching for * shebang (e.g. ``#!/bin/bash``) on first line * ``start``/``stop``/``status`` tokens in non-commented out lines If 3 or more items are found (half the items searched for + 1), called *confidence* in the code (e.g. shebang + start + stop), then we assume it is an initscript. Otherwise the parser raises a ``ParseException``. """
[docs] def parse_content(self, content): """ Raises: EmptyFileException: Raised if file is empty. NotInitscriptException: Raised if likely not an initscript. """ self.file_content = content # If we find 'chkconfig: XYZ' or 'Provides: NAME', assume we have an # initscript for line in content: if CHKCONFIG_REGEX.match(line) or LSB_REGEX.match(line): return # Otherwise, check for hints (shebang + presence of start/stop/status # keywords) # # Allocate 1 point for each item found. And declare as valid if # confidence >= 3 (half of the number of items + 1). confidence = 0 try: line = content[0] if SHEBANG_REGEX.match(line): confidence += 1 except IndexError: raise EmptyFileException(self.file_path) key = {'start': 0, 'stop': 0, 'status': 0} for line in content: if COMMENT_REGEX.match(line): continue m = STARTSTOPSTATUS_REGEX.search(line) if m: key[m.group(1)] += 1 confidence += len([v for v in key.values() if v != 0]) if confidence < 3: raise NotInitscriptException("path: %s, confidence: %d" % (self.file_path, confidence))