From 425572d16b6f04cc3becfd125df1e2c4e8c0386c Mon Sep 17 00:00:00 2001 From: Aditya R Date: Thu, 3 Feb 2022 15:51:29 +0530 Subject: [PATCH] executor: Add support for inline --platform within Dockerfile Allows end users to configure executor's `OS`, `ARCH`,`VARIANT` via inline `--platform`. Usage ``` FROM --platform=linux/arm64 alpine RUN uname -a ``` While this allows executor to pull base images with custom `OS`, `ARCH`, `VARIANT` it still allows end-users to tag images with different format if they need to. Signed-off-by: Aditya R --- imagebuildah/stage_executor.go | 21 +++++++++++- tests/bud.bats | 56 ++++++++++++++++++++++++++++++++ tests/bud/platform/Dockerfile | 2 ++ tests/bud/platform/Dockerfileamd | 2 ++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 tests/bud/platform/Dockerfile create mode 100644 tests/bud/platform/Dockerfileamd diff --git a/imagebuildah/stage_executor.go b/imagebuildah/stage_executor.go index 1cae210a468..db89bfef4e4 100644 --- a/imagebuildah/stage_executor.go +++ b/imagebuildah/stage_executor.go @@ -16,6 +16,7 @@ import ( "github.com/containers/buildah/define" buildahdocker "github.com/containers/buildah/docker" "github.com/containers/buildah/internal" + "github.com/containers/buildah/pkg/parse" "github.com/containers/buildah/pkg/rusage" "github.com/containers/buildah/util" cp "github.com/containers/image/v5/copy" @@ -595,6 +596,24 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo } } + builderSystemContext := s.executor.systemContext + // get platform string from stage + if stage.Builder.Platform != "" { + os, arch, variant, err := parse.Platform(stage.Builder.Platform) + if err != nil { + return nil, errors.Wrapf(err, "unable to parse platform %q", stage.Builder.Platform) + } + if arch != "" { + builderSystemContext.ArchitectureChoice = arch + } + if os != "" { + builderSystemContext.OSChoice = os + } + if variant != "" { + builderSystemContext.VariantChoice = variant + } + } + builderOptions := buildah.BuilderOptions{ Args: ib.Args, FromImage: from, @@ -604,7 +623,7 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo BlobDirectory: s.executor.blobDirectory, SignaturePolicyPath: s.executor.signaturePolicyPath, ReportWriter: s.executor.reportWriter, - SystemContext: s.executor.systemContext, + SystemContext: builderSystemContext, Isolation: s.executor.isolation, NamespaceOptions: s.executor.namespaceOptions, ConfigureNetwork: s.executor.configureNetwork, diff --git a/tests/bud.bats b/tests/bud.bats index 1eac9962c8a..1726dc99196 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -117,6 +117,62 @@ symlink(subdir)" expect_output --substring $(realpath "${TESTSDIR}/bud/dockerignore3/.dockerignore") } +# Following test must fail since we are trying to run linux/arm64 on linux/amd64 +# Issue: https://github.com/containers/buildah/issues/3712 +@test "build-with-inline-platform" { + # Host arch + run_buildah info --format '{{.host.arch}}' + myarch="$output" + otherarch="arm64" + for try in amd64 arm64 ppc64le s390x; do + if [[ "$otherarch" != "$myarch" ]]; then + otherarch="$otherarch" + break + fi + done + # ...create a Containerfile with --platform=linux/$otherarch + cat > ${TESTSDIR}/bud/platform/Dockerfile << _EOF +FROM --platform=linux/${otherarch} alpine +RUN uname -m +_EOF + + run_buildah '?' build --signature-policy ${TESTSDIR}/policy.json -t test ${TESTSDIR}/bud/platform + if [[ $status -eq 0 ]]; then + # Build succeeded: we must have qemu-user-static installed. Confirm that + # the 'uname' emits what we expect + expect_output --from="${lines[-1]}" "$otherarch" + run_buildah inspect --format '{{ .OCIv1.Architecture }}' test + expect_output --substring "$otherarch" + else + # Build failed: we DO NOT have qemu-user-static installed. + expect_output --substring "format error" + fi +} + +# Following test must pass since we want to tag image as host arch +# Test for use-case described here: https://github.com/containers/buildah/issues/3261 +@test "build-with-inline-platform-amd-but-tag-as-arm" { + # Host arch + run_buildah info --format '{{.host.arch}}' + myarch="$output" + targetarch="arm64" + + if [[ "$targetArch" == "$myarch" ]]; then + targetarch="amd64" + fi + + cat > ${TESTSDIR}/bud/platform/Dockerfile << _EOF +FROM --platform=linux/${myarch} alpine +RUN uname -m +_EOF + + # Tries building image where baseImage has --platform=linux/HostArch + run_buildah '?' build --platform linux/${targetarch} --signature-policy ${TESTSDIR}/policy.json -t test ${TESTSDIR}/bud/platform + run_buildah inspect --format '{{ .OCIv1.Architecture }}' test + # base image is pulled as HostArch but tagged as non host arch + expect_output --substring $targetarch +} + @test "bud-flags-order-verification" { run_buildah 125 build /tmp/tmpdockerfile/ -t blabla check_options_flag_err "-t" diff --git a/tests/bud/platform/Dockerfile b/tests/bud/platform/Dockerfile new file mode 100644 index 00000000000..e121d7b68fd --- /dev/null +++ b/tests/bud/platform/Dockerfile @@ -0,0 +1,2 @@ +FROM --platform=linux/amd64 alpine +RUN uname -m diff --git a/tests/bud/platform/Dockerfileamd b/tests/bud/platform/Dockerfileamd new file mode 100644 index 00000000000..2641c1e80e9 --- /dev/null +++ b/tests/bud/platform/Dockerfileamd @@ -0,0 +1,2 @@ +FROM --platform=linux/amd64 busybox +RUN uname -m