Plugin Introduction

Let’s have a look at plugins. Each of the six steps defined by Plans supports multiple methods. These methods are implemented by plugins which are dynamically loaded from the standard location under tmt/steps , from all directories provided in the TMT_PLUGINS environment variable and from tmt.plugin entry point.

Changed in version 1.35: warnings.deprecated is used to advertise deprecated APIs. Consider adding a static type checker (e.g. mypy) in your plugin’s CI using the main branch of tmt.

Added in version 1.63: You can use tmt.resources entry point to inject resource files to be used for tmt, e.g. schemas or templates. See Additional resource files for more details.

Inheritance

The plugin is implemented by a class which inherits from the corresponding step class, for example ProvisionPodman inherits from the ProvisionPlugin class. See the Class Overview page for more details about the class structure. The plugin class defines a couple of essential methods:

options()

command line options specific for given plugin

wake()

additional plugin data processing after the wake-up

show()

give a concise overview of the step configuration

go()

the main implementation of the plugin functionality

There may be additional required methods which need to be implemented. See individual plugin examples for details.

Examples

Example plugin skeletons are located in the examples/plugins directory. Get some inspiration for writing plugins there. There is a lot of comments and you can use the examples as a skeleton for your new plugin.

The discover plugin example demonstrates a simple plugin functionality defining an additional tests() method which returns a list of discovered tests.

The provision step example is more complex and consists of two classes. In addition to the provisioning part itself it also implements the GuestExample class which inherits from Guest and overloads its methods to handle special guest features which cannot be covered by generic ssh implementation of the Guest class.

Additional resource files

In order to make resource files available to the base tmt execution, you need to point a tmt.resources entry point to the root python package where the resource files are located from, e.g. with in the examples/plugins:

pyproject.toml
[project.entry-points."tmt.plugin"]
ProvisionExample = "example.provision:ProvisionExample"
DiscoverExample = "example.discover:DiscoverExample"

[project.entry-points."tmt.resources"]
ResourcesExample = "example"

you can, for example, add a json schema file for the plugins implemented above by including the schema files under a schemas folder:

$ tree ./example
./example
├── __init__.py
├── discover.py
├── provision.py
└── schemas
    ├── discover
       └── example.yaml
    └── provision
        └── example.yaml

Note

Both the entry-point entries as well as any resource file under the tmt.resources path must have unique names. Consider namespacing all relevant entries with the name of the project or an unambiguous derivative of it.