diff --git a/bib/cmd/bootc-image-builder/main.go b/bib/cmd/bootc-image-builder/main.go index a8ae6c66b..78ed5af6d 100644 --- a/bib/cmd/bootc-image-builder/main.go +++ b/bib/cmd/bootc-image-builder/main.go @@ -149,25 +149,34 @@ func makeManifest(c *ManifestConfig, cacheRoot string) (manifest.OSBuildManifest // (including the build-root) with the target arch then, it // is fast enough (given that it's mostly I/O and all I/O is // run naively via syscall translation) - hostArch := arch.Current().String() - targetArch := c.Architecture.String() + hostArch := arch.Current() + targetArch := c.Architecture - var resolver *container.Resolver - if targetArch != "" { - resolver = container.NewResolver(targetArch) + var wantedArch arch.Arch + if targetArch != arch.ARCH_UNSET { + wantedArch = targetArch } else { - resolver = container.NewResolver(hostArch) + wantedArch = hostArch } + // XXX: should NewResolver() take "arch.Arch"? + resolver := container.NewResolver(wantedArch.String()) containerSpecs := make(map[string][]container.Spec) for plName, sourceSpecs := range manifest.GetContainerSourceSpecs() { for _, c := range sourceSpecs { resolver.Add(c) } - containerSpecs[plName], err = resolver.Finish() + + specs, err := resolver.Finish() if err != nil { return nil, nil, fmt.Errorf("cannot resolve containers: %w", err) } + for _, spec := range specs { + if spec.Arch != wantedArch { + return nil, fmt.Errorf("image found is for unexpected architecture %q (expected %q), if that is intentional, please make sure --target-arch matches", spec.Arch, wantedArch) + } + } + containerSpecs[plName] = specs } mf, err := manifest.Serialize(depsolvedSets, containerSpecs, nil, depsolvedRepos) diff --git a/test/test_manifest.py b/test/test_manifest.py index 0b182fbba..7281abc40 100644 --- a/test/test_manifest.py +++ b/test/test_manifest.py @@ -1,4 +1,5 @@ import json +import platform import subprocess import textwrap @@ -109,3 +110,27 @@ def test_manifest_local_checks_containers_storage_works(tmp_path, build_containe f'--entrypoint=["/usr/bin/bootc-image-builder", "manifest", "--local", "localhost/{container_tag}"]', build_container, ], check=True, encoding="utf8") + + +@pytest.mark.skipif(platform.uname().machine != "x86_64", reason="cross build test only runs on x86") +def test_manifest_cross_arch_check(tmp_path, build_container): + cntf_path = tmp_path / "Containerfile" + cntf_path.write_text(textwrap.dedent("""\n + # build for x86_64 only + FROM scratch + """), encoding="utf8") + + with make_container(tmp_path, arch="x86_64") as container_tag: + with pytest.raises(subprocess.CalledProcessError) as exc: + subprocess.run([ + "podman", "run", "--rm", + "--privileged", + "-v", "/var/lib/containers/storage:/var/lib/containers/storage", + "--security-opt", "label=type:unconfined_t", + f'--entrypoint=["/usr/bin/bootc-image-builder", "manifest",\ + "--target-arch=aarch64", "--local", \ + "localhost/{container_tag}"]', + build_container, + ], check=True, capture_output=True, encoding="utf8") + # XXX: make more precise + assert "unexpected architecture" in exc.value.stderr