Skip to content

Latest commit

 

History

History
37 lines (22 loc) · 3.53 KB

02_plugins.md

File metadata and controls

37 lines (22 loc) · 3.53 KB

Plugins

Plugins were an essentially unused feature of Focker 1 and one that arrived very late - just prior to starting the work on Focker 2. Plugins in Focker 2 are quite different in a number of ways but most importantly the built-in functionality of the CLI is now provided by means of the plugins mechanism. Namely, every top level command (jail, image, volume, bootstrap, compose) along with all its subcommands is provided by a separate plugin. Thanks to this approach, the framework will undoubtedly stay fully functional whether 3rd party plugins start arriving sooner or later.

Plugin detection

In order for a plugin to be detected by Focker it has to adhere to certain formal requirements:

  • it must be a class descending from focker.plugin.Plugin.
  • the name of the class must end with Plugin, e.g. BootstrapPlugin.
  • it can be contained in an arbitrarily nested module but the top-level module/package name must start with focker_

Anatomy of a plugin

The Plugin class currently defines 5 static methods, some of which should be overriden by the descendant class. These are:

  • provide_parsers()
  • extend_parsers()
  • change_defaults()
  • install_pre_hooks()
  • install_post_hooks()

All methods share the same signature. They do not accept arguments and must return a dictionary. The meaning of the dictionary is different depending on the method.

The provide_parsers() method should return definitions of one or more new parsers for the CLI provided by the plugin. Care must be taken not to cause collision with the built-in commands or other plugins. The content of the dictionary from the provide_parsers() method will shallowly overwrite existing keys in the parser definition dictionary. For an example, please take a look at any of the built-in plugins, e.g. BootstrapPlugin. The order in which the plugins are loaded is not defined, therefore it is not possible to make the overwriting behavior controlled - collisions must be currently avoided.

The extend_parsers() method can be used to extend existing (sub)parsers with new subcommands and parameters. It should as well return a dictionary. The difference compared to provide_parsers() is such that the extend_parsers() methods are executed after all the "new" parsers have been provided and the definitions from extend_parsers() are merged with the existing ones rather than overwrite them.

The change_defaults() method provides a formalism for changing the default values of parameters in a dynamic way. The dictionary returned is merged with the FockerConfig singleton. Valid keys are currently: jail.default_params, jail.name_prefix, zfs.root_dataset, zfs.root_mountpoint, command.overrides.

The install_pre_hooks() method is supposed to provide hooks which are executed before the given CLI action. Keys should specify the first and second subcommand using the dot-notation, e.g. "jail.list". The hook function will be called with one argument - args - coming from ArgumentParser.parse().

The install_post_hooks() method provides hooks which are executed after the given CLI action. Keys should specify the first and second subcommand using the dot-notation, e.g. "jail.list". The hook function will be called with one argument - args - coming from ArgumentParser.parse().

Examples

For examples, one can study the cmdmodule module, as well as the unit tests.