diff --git a/doc/03-omnifest/01-directive.md b/doc/03-omnifest/01-directive.md index 51128b37..fa0097ec 100644 --- a/doc/03-omnifest/01-directive.md +++ b/doc/03-omnifest/01-directive.md @@ -200,7 +200,7 @@ otk.meta.kiwi: External directives. Directives starting with `otk.external` are redirected to `/usr/libexec/otk/`-binaries. For example the directive -`otk.external.osbuild.depsolve_dnf4` will execute `otk-osbuild depsolve_dnf4` +`otk.external.osbuild_depsolve_dnf4` will execute `otk_external_osbuild_depsolve_dnf4` with the tree under the directive on stdin and expect a new tree to replace the directive with on stdout. diff --git a/doc/03-omnifest/02-external.md b/doc/03-omnifest/02-external.md index 5672870e..888cb0ab 100644 --- a/doc/03-omnifest/02-external.md +++ b/doc/03-omnifest/02-external.md @@ -79,16 +79,12 @@ it finds the first match: - `/usr/lib/otk` The filename for an external executable is based on the external name. When the -following directive is encountered: `otk.external..` then -`otk` will try to find an executable called `otk_external_` in the previously +following directive is encountered: `otk.external.` then `otk` will try to +try to find an executable called `otk_external_` in the previously mentioned search paths. -It will call this executable with `` as its first argument. Here are -some examples: - - `otk.external.foo` -> `otk_external_foo` -- `otk.external.foo.bar_baz` -> `otk_external_foo bar_baz` -- `otk.external.foo.bar.baz` -> `otk_external_foo bar baz` +- `otk.external.foo_baz` -> `otk_external_foo_baz` ## Implementations @@ -99,19 +95,19 @@ These directives can be used as children under an `otk.target.osbuild` tree. These directives are only allowed within a [`otk.target.osbuild.`](./01-directive.md#otktargetconsumername). -#### `otk.external.osbuild.depsolve_dnf4` +#### `otk.external.osbuild_depsolve_dnf4` Solves a list of package specifications to RPMs and specifies them in the osbuild manifest as sources. -#### `otk.external.osbuild.depsolve_dnf5` +#### `otk.external.osbuild_depsolve_dnf5` 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](../04-best-practices.md). -#### `otk.external.osbuild.file_from_text` +#### `otk.external.osbuild_file_from_text` Write inline text to a file. Creates a source in the manifest and copies that source to the destination in the tree. @@ -119,13 +115,13 @@ source to the destination in the tree. Path components up to the destination must be pre-existing in the tree. ```yaml -otk.external.osbuild.file_from_text: +otk.external.osbuild_file_from_text: destination: /path/to text: | Hello, World! ``` -#### `otk.external.osbuild.file_from_path` +#### `otk.external.osbuild_file_from_path` 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. @@ -133,7 +129,7 @@ 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. ```yaml -otk.external.osbuild.file_from_path: +otk.external.osbuild_file_from_path: source: README.md destination: /path/to ``` diff --git a/example/centos/centos-9-x86_64-ami.yaml b/example/centos/centos-9-x86_64-ami.yaml index 6993b1a1..7aae9c3b 100644 --- a/example/centos/centos-9-x86_64-ami.yaml +++ b/example/centos/centos-9-x86_64-ami.yaml @@ -31,7 +31,7 @@ otk.define.centos-9-x86_64-ami: # [list_item1, list_item2, ..]" # (i.e. define the partition table as a map of root/boot/boot-efi vars) # *and* it needs to undstand modifications (e.g. adding extra parititions somehow, size contraints) - otk.external.osbuild.create_partition_table_defines: + otk.external.osbuild_create_partition_table_defines: total_size: 10G otk.include.centos-9-x86_64: "common/centos-9.yaml" diff --git a/example/centos/centos-9-x86_64-qcow2.yaml b/example/centos/centos-9-x86_64-qcow2.yaml index ece07d20..9f5f5e3d 100644 --- a/example/centos/centos-9-x86_64-qcow2.yaml +++ b/example/centos/centos-9-x86_64-qcow2.yaml @@ -14,7 +14,7 @@ otk.define.centos-9-x86_64-qcow2: # [list_item1, list_item2, ..]" # (i.e. define the partition table as a map of root/boot/boot-efi vars) # *and* it needs to undstand modifications (e.g. adding extra parititions somehow, size contraints) - otk.external.osbuild.create_partition_table_defines: + otk.external.osbuild_create_partition_table_defines: total_size: 10G otk.include.centos-9-x86_64: "common/centos-9.yaml" diff --git a/example/centos/fragment/files.yaml b/example/centos/fragment/files.yaml index e59a848b..fd7ddf72 100644 --- a/example/centos/fragment/files.yaml +++ b/example/centos/fragment/files.yaml @@ -1,7 +1,7 @@ otk.op.loop: item: ${modfication.files} foreach: - - otk.external.osbuild.embed_file: + - otk.external.osbuild_embed_file: text: ${item.text} path: ${item.path} - type: org.osbuild.chmod diff --git a/example/centos/pipeline/build.yaml b/example/centos/pipeline/build.yaml index 39165129..0f5b4062 100644 --- a/example/centos/pipeline/build.yaml +++ b/example/centos/pipeline/build.yaml @@ -4,7 +4,7 @@ name: build source-epoch: ${source_epoch} runner: "org.osbuild.centos9" stages: - - otk.external.osbuild.depsolve_dnf4: + - otk.external.osbuild_depsolve_dnf4: architecture: ${architecture} releasever: ${version} module_platform_id: platform:el${version} diff --git a/example/centos/pipeline/image.yaml b/example/centos/pipeline/image.yaml index 76b6617c..bb0c526d 100644 --- a/example/centos/pipeline/image.yaml +++ b/example/centos/pipeline/image.yaml @@ -2,11 +2,11 @@ name: image build: "name:build" stages: - - otk.external.osbuild_partition_table.gen_truncate_stage: + - otk.external.osbuild_partition_table_gen_truncate_stage: from: filesystems - - otk.external.osbuild_partition_table.gen_sfdisk_stage: + - otk.external.osbuild_partition_table_gen_sfdisk_stage: from: filesystems - - otk.external.osbuild_partition_table.gen_mkfs_stages: + - otk.external.osbuild_partition_table_gen_mkfs_stages: from: filesystems - type: org.osbuild.copy options: @@ -14,10 +14,10 @@ stages: from: input://root-tree/ to: mount://-/ devices: - otk.external.osbuild.partition_table.gen_devices: + otk.external.osbuild_partition_table_gen_devices: from: filesystems mounts: - otk.external.osbuild.partition_table.gen_mounts: + otk.external.osbuild_partition_table_gen_mounts: from: filesystems # TODO drop this stage conditionally on legacy boot support (or not) [is this our use-case for conditionals?] - type: org.osbuild.grub2.inst diff --git a/example/centos/pipeline/os-ostree.yaml b/example/centos/pipeline/os-ostree.yaml index 4eb7954b..85a456ac 100644 --- a/example/centos/pipeline/os-ostree.yaml +++ b/example/centos/pipeline/os-ostree.yaml @@ -3,7 +3,7 @@ build: "name:build" stages: # Install RPMs - - otk.external.osbuild.depsolve_dnf4: + - otk.external.osbuild_depsolve_dnf4: architecture: ${architecture} releasever: ${version} module_platform_id: platform:el${version} @@ -14,7 +14,7 @@ stages: packages: ${packages.os.packages} # Disk bits - - otk.external.osbuild.partition_table.gen_fstab_stage: + - otk.external.osbuild_partition_table_gen_fstab_stage: source: ${filesystem} # Boot bits diff --git a/example/centos/pipeline/os.yaml b/example/centos/pipeline/os.yaml index a20e7de4..a5d8fd0a 100644 --- a/example/centos/pipeline/os.yaml +++ b/example/centos/pipeline/os.yaml @@ -3,7 +3,7 @@ build: "name:build" stages: # Install RPMs - - otk.external.osbuild.depsolve_dnf4: + - otk.external.osbuild_depsolve_dnf4: architecture: ${architecture} releasever: ${version} module_platform_id: platform:el${version} @@ -14,7 +14,7 @@ stages: packages: ${packages.os.packages} # Disk bits - - otk.external.osbuild.partition_table.gen_fstab_stage: + - otk.external.osbuild_partition_table_gen_fstab_stage: source: ${filesystem} # Boot bits diff --git a/example/fedora/osbuild/buildroot.yaml b/example/fedora/osbuild/buildroot.yaml index 24324b58..c61c9bb2 100644 --- a/example/fedora/osbuild/buildroot.yaml +++ b/example/fedora/osbuild/buildroot.yaml @@ -2,7 +2,7 @@ name: buildroot source-epoch: 1659397331 stages: - - otk.external.osbuild.depsolve_dnf4: + - otk.external.osbuild_depsolve_dnf4: architecture: ${architecture} releasever: "40" module_platform_id: f${version} diff --git a/example/fedora/osbuild/pipeline/raw.yaml b/example/fedora/osbuild/pipeline/raw.yaml index 3e4e44f8..1ee5af72 100644 --- a/example/fedora/osbuild/pipeline/raw.yaml +++ b/example/fedora/osbuild/pipeline/raw.yaml @@ -1,7 +1,7 @@ name: raw source-epoch: 1659397331 stages: - # - otk.external.osbuild.depsolve_dnf4: + # - otk.external.osbuild_depsolve_dnf4: # architecture: ${architecture} # module_platform_id: f${version} # repositories: ${repositories} diff --git a/example/fedora/osbuild/pipeline/tree.yaml b/example/fedora/osbuild/pipeline/tree.yaml index 403e2f97..1d6b1f0a 100644 --- a/example/fedora/osbuild/pipeline/tree.yaml +++ b/example/fedora/osbuild/pipeline/tree.yaml @@ -1,7 +1,7 @@ name: tree build: name:root stages: - - otk.external.osbuild.depsolve_dnf4: + - otk.external.osbuild_depsolve_dnf4: architecture: ${architecture} releasever: "40" module_platform_id: f${version} diff --git a/src/otk/external.py b/src/otk/external.py index bb7a8884..8a2e2eec 100644 --- a/src/otk/external.py +++ b/src/otk/external.py @@ -5,6 +5,7 @@ import json import logging import pathlib +import re import subprocess import sys import os @@ -47,8 +48,12 @@ def call(context: Context, directive: str, tree: Any) -> Any: def convert(directive): - exe, *args = directive.removeprefix(PREFIX_EXTERNAL).split(".") - return (f"otk_external_{exe}", args) + exe = directive.removeprefix(PREFIX_EXTERNAL) + + if not re.fullmatch("[a-zA-Z_]+", exe): + raise RuntimeError("Invalid name {exe!r}") + + return f"otk_external_{exe}" def search(exe): diff --git a/test/test_external.py b/test/test_external.py index e89e6472..805d1dd8 100644 --- a/test/test_external.py +++ b/test/test_external.py @@ -3,11 +3,15 @@ from otk.external import convert -@pytest.mark.parametrize("text,exe,args", [ - ("otk.external.osbuild.foo", "otk_external_osbuild", ["foo",]), - ("otk.external.osbuild.foo.bar", "otk_external_osbuild", ["foo", "bar",]), - ("otk.external.foo.bar", "otk_external_foo", ["bar",]), - ("otk.external.foo", "otk_external_foo", []), +@pytest.mark.parametrize("text,exe", [ + ("otk.external.osbuild_foo", "otk_external_osbuild_foo",), ]) -def test_convert(text, exe, args): - assert convert(text) == (exe, args) +def test_convert(text, exe): + assert convert(text) == exe + +@pytest.mark.parametrize("text", [ + "otk.external.osbuild.foo", +]) +def test_convert_validate(text): + with pytest.raises(RuntimeError): + assert convert(text)