RPM Plugin Interface (DRAFT)

The current plugin interface is concentrated around what goes on inside rpmtsRun(), and there’s little that happens outside it. There’s no reason the interface could not be enhanced to other directions, this is just a consequence of one of the primary motivations behind the plugins: enabling other projects like SELinux and MSSF to handle the area they know best, and without having to support a dozen different security “frameworks” within rpm itself.

The plugin API consists of a set of hooks that mostly come in pairs. All hooks receive the plugin itself as the first argument, similarly to this of C++ or self in Python. As of RPM 4.12.0 the following hooks exist:

struct rpmPluginHooks_s { 
    /* plugin constructor and destructor hooks */
    plugin_init_func                    init;
    plugin_cleanup_func                 cleanup;
    /* per transaction plugin hooks */
    plugin_tsm_pre_func                 tsm_pre;
    plugin_tsm_post_func                tsm_post;
    /* per transaction element hooks */
    plugin_psm_pre_func                 psm_pre;
    plugin_psm_post_func                psm_post;
    /* per scriptlet hooks */
    plugin_scriptlet_pre_func           scriptlet_pre;
    plugin_scriptlet_fork_post_func     scriptlet_fork_post;
    plugin_scriptlet_post_func          scriptlet_post;
    /* per file hooks */
    plugin_fsm_file_pre_func            fsm_file_pre;
    plugin_fsm_file_post_func           fsm_file_post;
    plugin_fsm_file_prepare_func        fsm_file_prepare;
};

Initialization and cleanup

Hooks init and cleanup should be fairly obvious. Init occurs at the time of first transaction element addition, whether its for install, erase or reinstall.

Cleanup occurs on rpmtsFree() call.

Per transaction hooks

Hooks tsm_pre and tsm_post occur before and after execution of a transaction. More precisely, pre runs before any scripts have been executed or files laid down, and post runs after all scripts have executed and files have been laid down.

Post hook is guaranteed to execute whenever pre hook was executed.

Per transaction element hooks

Hooks psm_pre and psm_post occur before and after the processing of single transaction element within the transaction. Both hooks can get executed multiple times for a single element as these hooks get called separately for %pretrans and %posttrans scriptlets in addition to the main package install or erase action.

Post hook is guaranteed to execute whenever pre hook was executed.

Per scriptlet hooks

Hooks scriptlet_pre and scriptlet_post occur just before and immediately after the execution of any rpm scriptlets, so these hooks can get called multiple times for a single element.

Post hook is guaranteed to execute whenever pre hook was executed.

The scriptlet_fork_post hook is special in since it occurs in the forked child just before exec() of the scriptlet interpreter, and in that it has no pairing pre-hook. The scriptlet_fork_post hook only ever executes if scriptlet_pre was successful.

Per file hooks

Hooks fsm_file_pre, fsm_file_post and fsm_file_prepare execute for each individual file of all the transaction elements. Pre hook runs before a file (or directory) is created, post hook runs once rpm has done all its processing on the file. In between, fsm_file_prepare might be called. The prepare hook runs just after the file has been fully created and normal metadata such as ownership, permissions etc set, but before the file is moved into its final location. Note that prepare will sometimes be skipped, notably for hardlinked files where prepare gets called just once per hardlink set.

In most cases the fi argument is the handle to all the information on the file that rpm has, but it can be NULL in the case of unowned directories. The path argument might seem redundant for owned files but in fsm_file_pre and fsm_file_prepare it holds the temporary file name which is not accessible through fi

Post hook is is guaranteed to execute whenever pre hook was executed.

Warning: The exact relations and semantics of these hooks is subject to change as there are plans to improve rpms ability to undo file operations in case of failure.

Examples

For a few simple examples, see the plugins shipped with rpm itself: https://github.com/rpm-software-management/rpm/tree/master/plugins