Skip to content

oci-runtime-tools: fix packaging bugs - #30305

Merged
dangowrt merged 5 commits into
openwrt:masterfrom
dangowrt:oci-runtime-tools-fixes
Aug 23, 2026
Merged

oci-runtime-tools: fix packaging bugs#30305
dangowrt merged 5 commits into
openwrt:masterfrom
dangowrt:oci-runtime-tools-fixes

Conversation

@dangowrt

Copy link
Copy Markdown
Member

📦 Package Details

Maintainer: @dangowrt

Description:
Two improvements making the test-suite of OCI runtime tests more useful.

🧪 Run Testing Details

  • OpenWrt Version: snapshot
  • OpenWrt Target/Subtarget: x86/64
  • OpenWrt Device: QEMU (x86/64)

✅ Formalities

  • I have reviewed the CONTRIBUTING.md file for detailed contributing guidelines.

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 new commits. Nothing here blocks a merge — both inline remarks are optional.

I checked the substance of each fix against the sources and they hold up:

  • CONFIG_x86 is indeed not a symbol OpenWrt ever sets (targets select the arch name, so it is i386 / x86_64 / aarch64), and the new per-arch keying matches what the tests actually look for: validation/util/test.go:130 untars fmt.Sprintf("rootfs-%s.tar.gz", runtime.GOARCH), i.e. rootfs-386, rootfs-amd64, rootfs-arm64. Both rootfs-386.tar.gz and rootfs-amd64.tar.gz exist in the pinned source tree, so the CONFIG_i386 branch will find its file.
  • +unshare is satisfiable — unshare is a util-linux subpackage in openwrt core — and validation/linux_ns_path{,_type} do shell out to unshare <opt> --fork sleep 10000.
  • The second golang-build.sh build invocation looks correct: GO_BUILD_PKG and CGO_ENABLED both appear after the blocks that already set them, and the last assignment in a command prefix wins; GO_PKG_VARS still pulls in the package's GO111MODULE=auto via GO_PKG_BUILD_VARS; and GO_BUILD_BIN_DIR is the same for both builds, so the static runtimetest overwrites the dynamic one before Install/Bin runs.

CI was still pending at 1517c90, so nothing to report there.


Generated by Claude Code

TITLE:=OCI runtimetest tool
URL:=https://github.com/opencontainers/runtime-tools
DEPENDS:=@(aarch64||i386||i686||x86_64) oci-runtime-tool +tar
DEPENDS:=@(aarch64||i386||i686||x86_64) oci-runtime-tool +tar +unshare

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the arch guard still allows i686, but after this series the 386 archive is keyed off CONFIG_i386 only (line 109), so an i686 build would package no rootfs archive at all and land right back on the rootfs-386.tar.gz: Cannot open failure 9abc8d8 fixes. The symbol is declared (target/Config.in:161) but no in-tree target selects it — every target sets ARCH:=i386 or ARCH:=x86_64 and target-metadata.pl:121 turns that into the select. So this is dormant rather than broken; is leaving i686 in the guard deliberate, or should it be dropped now that the install recipe enumerates the exact arch symbols?


Generated by Claude Code

$(GO_PKG_BUILD_CONFIG_VARS) \
GO_BUILD_PKG="$(GO_PKG)cmd/runtimetest" \
$(GO_PKG_VARS) \
CGO_ENABLED=0 \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 9a4d4c3's message says building "with cgo disabled ... is what the upstream Makefile does for it", but upstream keeps cgo enabled and gets the static binary through the linker instead: STATIC_BUILD_FLAGS at Makefile:11 is -tags "$(BUILDTAGS) netgo osusergo" -ldflags "-extldflags -static ...", used by the runtimetest target at Makefile:20-21.

CGO_ENABLED=0 does yield a pure-Go static binary here (and it sidesteps the -linkmode external that GO_PKG_INSTALL_ARGS would otherwise force), so the change itself looks right — only the "what upstream does" justification in the commit body is off. Worth rewording to say the static build is equivalent to upstream's rather than identical.


Generated by Claude Code

runtimetest is copied into the validation bundle, whose rootfs carries a
static busybox and no dynamic loader, so the dynamically linked binary the
generic Go recipe produces fails to execute and every validation test that
inspects the container from the inside aborts.

Build that one command again as the static binary upstream's own runtimetest
target produces. Upstream gets there by asking the external linker for a
static link, while disabling cgo reaches the same result without fighting the
-linkmode external that the generic Go recipe would otherwise impose.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
@dangowrt
dangowrt force-pushed the oci-runtime-tools-fixes branch from f3a0848 to a0d3c33 Compare August 19, 2026 06:27

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed at a0d3c33. All three commits were rewritten since 1517c90, but only 7496839 changed content: the arch → archive choice moved out of Package/oci-runtime-tests/install into top-level ifdef blocks, and CONFIG_i686 was added. The other two are message-only rewordings with identical diffs.

Nothing here blocks a merge — the one inline remark is optional.

I checked the new construct and it holds up:

  • The stated reason for moving the conditional out of the define is correct, and it is not merely stylistic. Inside a define body GNU make only recognises a directive at the very start of the line; with leading spaces it is kept as literal text and ends up in the recipe. Reproduced on GNU Make 4.3 — an indented ifdef inside a define yields make: ifdef: No such file or directory. So there really was no way to indent it in place.
  • The new block sits above include $(INCLUDE_DIR)/package.mk, but CONFIG_* is already available there: rules.mk:9-11 pulls in $(TOPDIR)/.config, and the only case where it does not (DUMP=1 metadata scan) never evaluates the install recipe. ROOTFS_ARCHIVE does not collide with anything in include/ or in lang/golang/.
  • CONFIG_i686 is a real symbol — target/Config.in:161 — and matches the i686 already present in the package's own DEPENDS and in GO_ARCH_DEPENDS. No in-tree target sets ARCH:=i686 today, so the branch is inert for now, but it does keep the guard and the archive list in sync as the commit message claims.
  • $(if $(ROOTFS_ARCHIVE),...) behaves in both directions: with the variable set it expands to the $(INSTALL_DATA) command with $(1) correctly substituted from the enclosing $(call ...); empty, it leaves a tab-only line that make ignores. Verified both cases with a standalone reproducer.
  • +unshare resolves — unshare is a util-linux subpackage in openwrt core (package/utils/util-linux/Makefile, BuildPackage,unshare).

Generated by Claude Code

Comment thread utils/oci-runtime-tools/Makefile Outdated
ifdef CONFIG_aarch64
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rootfs-arm64.tar.gz $(1)/usr/libexec/oci-runtime-test
endif
$(if $(ROOTFS_ARCHIVE),$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ROOTFS_ARCHIVE) $(1)/usr/libexec/oci-runtime-test)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional, non-blocking: the $(if ...) guard reintroduces the silent-no-op that this commit is fixing. Package/oci-runtime-tests/install only runs when the package is selected, and selection is gated by DEPENDS:=@(aarch64||i386||i686||x86_64) — the same four symbols the block at lines 27-38 keys on. So ROOTFS_ARCHIVE is never empty here today, and the guard only masks the case where the two lists drift apart again (e.g. riscv64 added to DEPENDS but not to the arch block), producing exactly the "package builds fine, ships no rootfs, every test aborts at Cannot open" failure the commit message describes.

Installing unconditionally makes the two lists self-checking: a missing mapping fails the build instead of shipping a broken package.

Suggested change
$(if $(ROOTFS_ARCHIVE),$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ROOTFS_ARCHIVE) $(1)/usr/libexec/oci-runtime-test)
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ROOTFS_ARCHIVE) $(1)/usr/libexec/oci-runtime-test

Generated by Claude Code

The install recipe guarded both archives with CONFIG_x86, a symbol OpenWrt
never defines: the target symbol is CONFIG_TARGET_x86 and the architecture
symbols are CONFIG_i386 and CONFIG_x86_64. No archive was therefore packaged
and every validation test stopped at "rootfs-amd64.tar.gz: Cannot open".
Key each archive off the architecture symbol that matches it, i686 included,
so the package's own architecture guard and the archive it installs cannot
disagree.

The choice moves out of the install recipe, since a conditional inside a
define has to start at the beginning of the line to be a directive at all,
which leaves no way to indent it as the packaging guidelines ask for.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Some of the tests require 'unshare' on the host. Select it.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
main.version was linked to PKG_SOURCE_VERSION, the upstream commit
hash, rather than PKG_VERSION, the human-readable string everything
else (the tarball name, the package version, CI's own version probe)
actually means by "version". oci-runtime-tool --version therefore
printed the commit hash twice ("<hash>, commit: <hash>") and never
the string 1.3.0.20260316, which is what CI's generic runtime test
greps stdout for, so the check failed on every push regardless of
this PR's actual content.

gitCommit stays on PKG_SOURCE_VERSION, since that is genuinely what
it is; only version was wrong.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
@dangowrt
dangowrt force-pushed the oci-runtime-tools-fixes branch from a0d3c33 to 5e2fac3 Compare August 23, 2026 18:30
@dangowrt

Copy link
Copy Markdown
Member Author

CI failure: real bug, fixed as a new commit 5e2fac3c ("report the real version string"). GO_PKG_LDFLAGS_X linked main.version to PKG_SOURCE_VERSION (the upstream commit hash) instead of PKG_VERSION, so oci-runtime-tool --version printed the commit hash twice and never the string 1.3.0.20260316 that CI's generic runtime test greps stdout for. That's independent of anything else in this PR, hence the separate commit. Verified natively: rebuilding with the corrected -X flags now prints oci-runtime-tool version 1.3.0.20260316, commit: 8a4db579f5c88af5a0d036fad34bddc9c1f703f3.

On the three inline points:

  • The $(if $(ROOTFS_ARCHIVE),...) guard: applied the suggested diff, folded into 749683980 via fixup/autosquash rather than left as a separate patch, since it's a correction to that same commit's own change. Agreed on the reasoning, an unconditional install makes a future drift between DEPENDS and the arch block a build failure instead of a silent no-op.
  • The upstream-cgo wording in bbce113d0: already reworded in an earlier round (now reads "reaches the same result without fighting..." rather than claiming to do what upstream does), nothing further needed there.
  • The dormant i686 guard: leaving it is deliberate rather than an oversight. DEPENDS and the ROOTFS_ARCHIVE block both key off the same four arch symbols now, so they can't drift apart even though no in-tree target currently selects CONFIG_i686; dropping it would just be removing forward-compatible symmetry that costs nothing while it's unused.

runtimetest and the ~60 validation/*.go binaries oci-runtime-tests
installs are OCI compliance tests, not user-facing tools, and none
of them has a version flag. Probing one runs the test it implements
instead: CI's generic check reported 58 of 60 missing the version
string and failed the build, and the one it did run tried to read
rootfs-386.tar.gz relative to the probe's working directory rather
than /usr/libexec/oci-runtime-test, so it also failed outright.

Add a test.sh: skip oci-runtime-tests outright, since none of its
binaries can report a version, and keep the generic check for
oci-runtime-tool by replicating it directly now that --version
reports the right string.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
@dangowrt

Copy link
Copy Markdown
Member Author

That run (32658277989) was accurate: oci-runtime-tool now passes the generic check on every architecture (confirming the ldflags fix), but oci-runtime-tests still failed it, on aarch64_generic, i386_pentium-mmx and x86_64 alike. Root cause: it installs runtimetest plus ~60 validation/*.go compliance-test binaries, none of which has a version flag - probing one runs the OCI test it implements instead of printing anything version-like, which is also why the log shows one of them trying and failing to read rootfs-386.tar.gz from the wrong working directory. Not a real functional problem, a testing-harness mismatch (these are meant to be driven by a TAP consumer, not invoked bare with a version flag).

Added test.sh (0127f31d): skips the check for oci-runtime-tests outright, since nothing in it can report a version, and keeps a real check for oci-runtime-tool by replicating its now-correct --version output directly.

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed at 0127f31. Since a0d3c33 two commits were added (5e2fac3 version string, 0127f31 test script) and cb2ea11 picked up the un-guarding of the archive install; both new commit messages match their diffs.

One finding, and it is worth fixing before merge because it defeats the purpose of the commit that introduces it: the new script has to be test-version.sh, not test.sh, or the generic version probe still runs over the ~60 binaries in /usr/libexec/oci-runtime-test. Details inline. Everything else here looks right.

What I checked:

  • 5e2fac3: main.version was indeed the only wrong -X; gitCommit legitimately stays on PKG_SOURCE_VERSION. GO_PKG_LDFLAGS_X is consumed both by the generic Go recipe and by the second golang-build.sh build this PR adds for runtimetest, so both binaries pick up the corrected value, and PKG_VERSION (1.3.0.20260316) is the string the generic probe greps for.
  • The unconditional $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ROOTFS_ARCHIVE) that replaced the $(if …) guard: consistent with the four ifdef arms and with DEPENDS:=@(aarch64||i386||i686||x86_64), and per your comment the loud failure on a future drift is the point. rootfs-arm64.tar.gz is produced by Build/Prepare under the same CONFIG_aarch64, so the aarch64 arm has its file too.
  • CI on 0127f31 was still queued at review time (FormalityCheck green, the ten Feeds Package Test Build jobs not started), so nothing to report from it.

Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be named test-version.sh, not test.sh — as written it will not suppress the generic version probe, so oci-runtime-tests should fail on the next run exactly as it did on the previous one.

In actions-shared-workflows' .github/scripts/test_entrypoint.sh the per-file probe is gated on the version override script alone:

if [ -f "$test_version_script" ]; then
        check_exec "$file" 1 || ret_exec=$?

check_exec()'s second argument is skip_version_check, and = 1 takes the status_skip "Version check ($file)" path. test_version_script comes from TEST_VERSION_SCRIPT="/ci/$PKG_SOURCE/test-version.sh"; TEST_SCRIPT="/ci/$PKG_SOURCE/test.sh" is a separate custom-test hook and never feeds that decision, and the generic tests are forced by default (generic_tests_forced()), so adding a test.sh does not turn them off. is_in_exec_path() matches ^(/bin/|/sbin/|/usr/bin/|/usr/sbin/|/usr/libexec/), which is why all ~60 *.t binaries under /usr/libexec/oci-runtime-test get probed in the first place.

In-tree precedent says the same thing explicitly — openzwave: rename version check test.sh to test-version.sh: "In actions-shared-workflows the version is now checked in test-version.sh, while test.sh is left for the generic tests… the presence check was already there for that reason, it just could not suppress the probe from test.sh." Same story in domoticz, and utils/dbus shows the finished split: version arms (including a bare exit 0 for the sub-packages with no version-capable binary) in test-version.sh, unrelated runtime assertions in test.sh.

The content here is already exactly the test-version.sh shape — $1/$2, one arm per sub-package, loud *) default — cf. utils/attr/test-version.sh, so a plain rename should be the whole fix. It also matches the commit message's own reasoning: replicating the check for oci-runtime-tool by hand is only necessary under test-version.sh semantics, where the override suppresses the probe for every sub-package built from this source. Under test.sh that arm is just a duplicate of a probe that still runs.

Minor, while renaming: the recent overrides carry # shellcheck shell=busybox under the shebang.


Generated by Claude Code

@dangowrt
dangowrt merged commit 5117f9b into openwrt:master Aug 23, 2026
11 of 14 checks passed
@dangowrt
dangowrt deleted the oci-runtime-tools-fixes branch August 23, 2026 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants