External directives are directives that are implemented externally from otk
.
They are meant to be used to provide target-specific behavior and can be used
to express things where otk
is not expressive enough.
Directives are small executables that receive JSON and are expected to output JSON again in a specific format. Additional keys are not allowed.
When we have an omnifest that looks like this:
otk.external.name:
child:
- 1
options: "are here"
The external gets called with the following JSON:
{
"tree": {
"child": [1],
"options": "are here"
}
}
And is expected to return a JSON dict with a single top-level tree
object that can contain arbitrary values. Additional top-level keys are not allowed. Example:
{
"tree": {
"what": {
"you": "want"
}
}
}
Which will replace the previous otk.external.name
subtree with the output of new subtree from the external command. Example:
tree:
what:
you: "want"
If the external returns {}
, an empty object, otk
will assume that there is
no tree to replace and remove the node instead. This will turn the following
YAML:
dummy:
otk.external.name:
options:
Into this YAML structure:
dummy:
The following example demonstrates how an external can be used to implement string concatenation.
Given the following script called concat
in /usr/local/libexec/otk/concat
:
#!/usr/bin/env bash
output="$(cat - | jq -jr '.tree.parts[]')"
echo "{\"tree\":{\"output\":\"$output\"}}"
and the following directive:
examplestring:
otk.external.concat:
parts:
- list
- of
- strings
the script is called with the following data on stdin:
{
"tree": {
"parts": [
"list",
"of",
"strings"
]
}
}
which results in the following output:
{
"tree": {
"output": "listofstrings"
}
}
and the final omnifest will be:
examplestring:
output: listofstrings
otk
will look for external directives in the following paths, stopping when
it finds the first match:
- A path defined by the
OTK_EXTERNAL_PATH
environment variable. /usr/local/libexec/otk/external
/usr/libexec/otk/external
/usr/local/lib/otk/external
/usr/lib/otk/external
The filename for an external executable is based on the external name. When the
following directive is encountered: otk.external.<name>
then
otk
will try to find an executable called <name>
in the previously
mentioned search paths.
Examples:
otk.external.foo
->foo
otk.external.osbuild_bar
->osbuild_bar
otk
currently ships together with an external implementation for osbuild
.
These directives can be used as children under an otk.target.osbuild
tree.
These directives are only allowed within a otk.target.osbuild.<name>
.
Solves a list of package specifications to RPMs and specifies them in the osbuild manifest as sources.
Expects a map
as its value.
osbuild
directives to write files. If a stage exists for the type of file
you want to write: use it. See the best practices.
Write inline text to a file. Creates a source in the manifest and copies that source to the destination in the tree.
Path components up to the destination must be pre-existing in the tree.
otk.external.osbuild.file_from_text:
destination: /path/to
text: |
Hello, World!
Copy a file. Source is relative to the path of the entrypoint omnifest. Creates a source in the manifest and copies that source to the destination in tree.
Path components up to the destination must be pre-existing in the tree.
otk.external.osbuild_file_from_path:
source: README.md
destination: /path/to