summaryrefslogtreecommitdiffstats
path: root/src/lib/Server/Lint/__init__.py
blob: 4e6d03fb5bcdd09d4bd7fdd32252a6b7c05b4bf3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
__revision__ = '$Revision$'

__all__ = ['Bundles',
           'Comments',
           'Duplicates',
           'InfoXML',
           'Pkgmgr',
           'RequiredAttrs',
           'Validate']

import logging
import os.path
from copy import copy
import lxml.etree
import Bcfg2.Logger

def returnErrors(fn):
    """ Decorator for Run method that returns error counts """
    def run(self, *args, **kwargs):
        fn(self, *args, **kwargs)
        return (self.error_count, self.warning_count)

    return run

class Plugin (object):
    """ base class for ServerlessPlugin and ServerPlugin """
    def __init__(self, config, files=None):
        self.files = files
        self.error_count = 0
        self.warning_count = 0
        self.config = config
        Bcfg2.Logger.setup_logging('bcfg2-info', to_syslog=False)
        self.logger = logging.getLogger('bcfg2-lint')

    def Run(self):
        """ run the plugin.  must be overloaded by child classes """
        pass

    def HandlesFile(self, fname):
        """ returns true if the given file should be handled by the
        plugin according to the files list, false otherwise """
        return (self.files is None or
                fname in self.files or
                os.path.join(self.config['repo'], fname) in self.files or
                os.path.abspath(fname) in self.files or
                os.path.abspath(os.path.join(self.config['repo'],
                                             fname)) in self.files)
    
    def LintError(self, msg):
        """ log an error condition """
        self.error_count += 1
        lines = msg.splitlines()
        self.logger.error("ERROR: %s" % lines.pop())
        [self.logger.error("  %s" % l) for l in lines]

    def LintWarning(self, msg):
        """ log a warning condition """
        self.warning_count += 1
        lines = msg.splitlines()
        self.logger.warning("WARNING: %s" % lines.pop())
        [self.logger.warning("  %s" % l) for l in lines]

    def RenderXML(self, element):
        """render an XML element for error output -- line number
        prefixed, no children"""
        xml = None
        if len(element) or element.text:
            el = copy(element)
            if el.text:
                el.text = '...'
            [el.remove(c) for c in el.iterchildren()]
            xml = lxml.etree.tostring(el).strip()
        else:
            xml = lxml.etree.tostring(element).strip()
        return "   line %s: %s" % (element.sourceline, xml)

class ServerlessPlugin (Plugin):
    """ base class for plugins that are run before the server starts
    up (i.e., plugins that check things that may prevent the server
    from starting up) """
    pass

class ServerPlugin (Plugin):
    """ base class for plugins that check things that require the
    running Bcfg2 server """
    def __init__(self, lintCore, config, files=None):
        Plugin.__init__(self, config, files=files)
        self.core = lintCore
        self.logger = self.core.logger
        self.metadata = self.core.metadata