Skip to content

Commit

Permalink
[libdnf, actions plugin] Support for action options, option enabled
Browse files Browse the repository at this point in the history
The fourth item in the action definition has been reserved. It is now
used to set additional action options. Options are separated by spaces.
A space within an option can be written using escaping.

One option is now supported - `enabled=<value>`.
Supported values of `value`:
* `1` - action is always enabled
* `host-only` - the action is only enabled for operations on the host
* `installroot-only` - the action is only enabled for operations in
                       the alternative "installroot"

Action can allways be disabled by commenting out the action line.
  • Loading branch information
jrohel committed Nov 8, 2023
1 parent 03c2a50 commit 466770d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
15 changes: 11 additions & 4 deletions doc/libdnf5_plugins/actions.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Actions file format

Empty lines and lines that start with a '#' character (comment line) are ignored.

Each non-comment line defines an action and consists of five items separated by colons: ``callback_name:package_filter:direction:reserved:command``.
Each non-comment line defines an action and consists of five items separated by colons: ``callback_name:package_filter:direction:options:command``.

``callback_name``

Expand All @@ -69,6 +69,15 @@ Each non-comment line defines an action and consists of five items separated by
* ``in`` - packages coming to the system (downgrade, install, reinstall, upgrade)
* ``out`` - packages going out of the system (upgraded, downgraded, reinstalled, removed, replaced/obsoleted)

``options``
Options are separated by spaces. A space within an option can be written using escaping.

* ``enabled=<value>`` - the value specifies when the action is enabled (added in version 0.3.0)

* ``1`` - action is always enabled
* ``host-only`` - the action is only enabled for operations on the host
* ``installroot-only`` - the action is only enabled for operations in the alternative "installroot"

``command``
Any executable file with arguments.

Expand Down Expand Up @@ -119,9 +128,6 @@ Each non-comment line defines an action and consists of five items separated by
of when a particular ``package_filter`` is invoked depends on the position
of the corresponding package in the transaction.

``reserved``
Reserved for future use. Now empty.


Action standard output format
=============================
Expand All @@ -146,6 +152,7 @@ An example actions file:
pre_base_setup::::/usr/bin/sh -c echo\ -------------------------------------\ >>/tmp/actions-trans.log
pre_base_setup::::/usr/bin/sh -c date\ >>/tmp/actions-trans.log
pre_base_setup::::/usr/bin/sh -c echo\ libdnf5\ pre_base_setup\ was\ called.\ Process\ ID\ =\ '${pid}'.\ >>/tmp/actions-trans.log
pre_base_setup:::enabled=installroot-only:/usr/bin/sh -c echo\ run\ in\ alternative\ "installroot":\ installroot\ =\ '${conf.installroot}'\ >>/tmp/actions-trans.log
# Prints the value of the configuration option "defaultyes".
pre_base_setup::::/bin/sh -c echo\ 'pre_base_setup:\ conf.defaultyes=${{conf.defaultyes}}'\ >>\ {context.dnf.installroot}/actions.log
Expand Down
50 changes: 40 additions & 10 deletions libdnf5-plugins/actions/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ using namespace libdnf5;
namespace {

constexpr const char * PLUGIN_NAME = "actions";
constexpr plugin::Version PLUGIN_VERSION{0, 2, 0};
constexpr plugin::Version PLUGIN_VERSION{0, 3, 0};

constexpr const char * attrs[]{"author.name", "author.email", "description", nullptr};
constexpr const char * attrs_value[]{"Jaroslav Rohel", "[email protected]", "Actions Plugin."};
Expand Down Expand Up @@ -394,36 +394,66 @@ void Actions::parse_action_files() {
auto pkg_filter_pos = line.find(':');
if (pkg_filter_pos == std::string::npos) {
throw ActionsPluginError(
M_("Error in file \"{}\" on line {}: \"HOOK:PKG_FILTER:DIRECTION::CMD\" format expected"),
M_("Error in file \"{}\" on line {}: \"HOOK:PKG_FILTER:DIRECTION:OPTIONS:CMD\" format expected"),
path.native(),
line_number);
}
++pkg_filter_pos;
auto direction_pos = line.find(':', pkg_filter_pos);
if (direction_pos == std::string::npos) {
throw ActionsPluginError(
M_("Error in file \"{}\" on line {}: \"HOOK:PKG_FILTER:DIRECTION::CMD\" format expected"),
M_("Error in file \"{}\" on line {}: \"HOOK:PKG_FILTER:DIRECTION:OPTIONS:CMD\" format expected"),
path.native(),
line_number);
}
++direction_pos;
auto reserved_pos = line.find(':', direction_pos);
if (reserved_pos == std::string::npos) {
auto options_pos = line.find(':', direction_pos);
if (options_pos == std::string::npos) {
throw ActionsPluginError(
M_("Error in file \"{}\" on line {}: \"HOOK:PKG_FILTER:DIRECTION::CMD\" format expected"),
M_("Error in file \"{}\" on line {}: \"HOOK:PKG_FILTER:DIRECTION:OPTIONS:CMD\" format expected"),
path.native(),
line_number);
}
++reserved_pos;
auto command_pos = line.find(':', reserved_pos);
++options_pos;
auto command_pos = line.find(':', options_pos);
if (command_pos == std::string::npos) {
throw ActionsPluginError(
M_("Error in file \"{}\" on line {}: \"HOOK:PKG_FILTER:DIRECTION::CMD\" format expected"),
M_("Error in file \"{}\" on line {}: \"HOOK:PKG_FILTER:DIRECTION:OPTIONS:CMD\" format expected"),
path.native(),
line_number);
}
++command_pos;

bool action_enabled{true};
auto options_str = line.substr(options_pos, command_pos - options_pos - 1);
const auto options = split(options_str);
for (const auto & opt : options) {
if (opt.starts_with("enabled=")) {
const auto value = opt.substr(8);
auto installroot_path = config.get_installroot_option().get_value();
bool installroot = installroot_path != "/";
if (value == "1") {
action_enabled = true;
} else if (value == "host-only") {
action_enabled = !installroot;
} else if (value == "installroot-only") {
action_enabled = installroot;
} else {
throw ActionsPluginError(
M_("Error in file \"{}\" on line {}: Unknown \"enabled\" option value \"{}\""),
path.native(),
line_number,
value);
}
} else {
throw ActionsPluginError(
M_("Error in file \"{}\" on line {}: Unknown option \"{}\""), path.native(), line_number, opt);
}
}
if (!action_enabled) {
continue;
}

enum class Hooks { PRE_BASE_SETUP, POST_BASE_SETUP, PRE_TRANS, POST_TRANS } hook;
if (line.starts_with("pre_base_setup:")) {
hook = Hooks::PRE_BASE_SETUP;
Expand Down Expand Up @@ -452,7 +482,7 @@ void Actions::parse_action_files() {
}
}

auto direction = line.substr(direction_pos, reserved_pos - direction_pos - 1);
auto direction = line.substr(direction_pos, options_pos - direction_pos - 1);
if (pkg_filter.empty() && !direction.empty()) {
throw ActionsPluginError(
M_("Error in file \"{}\" on line {}: Cannot use direction without package filter"),
Expand Down

0 comments on commit 466770d

Please sign in to comment.