Skip to content

Commit

Permalink
bib: check that architecture is expected arch
Browse files Browse the repository at this point in the history
When trying to build an image with an incompatible target arch
bib will currently not error because the container resolver is
not very strict about the architecture request.

This commit fixes this by double checking that the resolved
container is actually of the expected architecture.

This requires osbuild/images#585
  • Loading branch information
mvo5 committed Apr 23, 2024
1 parent 2bc76a6 commit 3c84943
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
23 changes: 16 additions & 7 deletions bib/cmd/bootc-image-builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
25 changes: 25 additions & 0 deletions test/test_manifest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import platform
import subprocess
import textwrap

Expand Down Expand Up @@ -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

0 comments on commit 3c84943

Please sign in to comment.