sampledoc

bcfg2-lint Plugin Development

bcfg2-lint, like most parts of Bcfg2, has a pluggable backend that lets you easily write your own plugins to verify various parts of your Bcfg2 specification.

Plugins are included in a module of the same name as the plugin class in Bcfg2.Server.Lint, e.g., Bcfg2.Server.Lint.Validate.

Note

It is no longer possible to include lint plugins directly in a Bcfg2 server plugin, e.g., Bcfg2.Server.Plugins.Metadata.MetadataLint.

Plugin Types

There are two types of bcfg2-lint plugins:

Serverless plugins

Serverless plugins are run before bcfg2-lint starts up a local Bcfg2 server, so the amount of introspection they can do is fairly limited. They can directly examine the Bcfg2 specification, of course, but they can’t examine the entries handled by a given plugin or anything that requires a running server.

If a serverless plugin raises a lint error, however, the server will not be started and no Server plugins will be run. This makes them useful to check for the sorts of errors that might prevent the Bcfg2 server from starting properly.

Serverless plugins must subclass Bcfg2.Server.Lint.ServerlessPlugin.

Bcfg2.Server.Lint.Validate is an example of a serverless plugin.

Server plugins

Server plugins are run after a local Bcfg2 server has been started, and have full access to all of the parsed data and so on. Because of this, they tend to be easier to use than Serverless plugins, and thus are more common.

Server plugins are only run if all Serverless plugins run successfully (i.e., raise no errors).

Server plugins must subclass Bcfg2.Server.Lint.ServerPlugin.

Bcfg2.Server.Lint.Genshi is an example of a server plugin.

Error Handling

The job of a bcfg2-lint plugin is to find errors. Each error that a plugin may produce must have a name, a short string that briefly describes the error and will be used to configure error levels in bcfg2.conf. It must also have a default reporting level. Possible reporting levels are “error”, “warning”, or “silent”. All of the errors that may be produced by a plugin must be returned as a dict by Bcfg2.Server.Lint.Plugin.Errors(). For instance, consider Bcfg2.Server.Lint.InfoXML.InfoXML.Errors():

@classmethod
def Errors(cls):
    return {"no-infoxml": "warning",
            "deprecated-info-file": "warning",
            "paranoid-false": "warning",
            "required-infoxml-attrs-missing": "error"}

This means that the Bcfg2.Server.Lint.InfoXML.InfoXML lint plugin can produce five lint errors, although four of them are just warnings by default.

The errors returned by each plugin’s Errors() method will be passed to Bcfg2.Server.Lint.ErrorHandler.RegisterErrors(), which will use that information and the information in the config file to determine how to display (or not display) each error to the end user.

Errors are produced in a plugin with Bcfg2.Server.Lint.Plugin.LintError(), which takes two arguments: the name of the error, which must correspond to a key in the dict returned by Bcfg2.Server.Lint.Plugin.Errors(), and a freeform string that will be displayed to the end user. Note that the error name and its display are thus only tied together when the error is produced; that is, a single error (by name) can have two completely different outputs.

Basics

Existing bcfg2-lint Plugins

AWSTags

Bundler

Comments

Genshi

GroupNames

GroupPatterns

InfoXML

MergeFiles

Metadata

Pkgmgr

RequiredAttrs

TemplateHelper

Validate