From 56543ed0a2ae89f2fbc09fd93d60425b0de8a56d Mon Sep 17 00:00:00 2001 From: Avi Deitcher Date: Thu, 22 Feb 2024 14:16:38 +0200 Subject: [PATCH] add support for build-arg files Signed-off-by: Avi Deitcher --- src/cmd/linuxkit/pkg_build.go | 21 +++++++++++++++++++ src/cmd/linuxkit/pkglib/build.go | 21 +++++++++++++++++++ src/cmd/linuxkit/pkglib/docker.go | 3 ++- .../000_build_arg_yaml/Dockerfile | 2 ++ .../000_build_arg_yaml/build.yml | 4 ++++ .../056_build_args/000_build_arg_yaml/test.sh | 13 ++++++++++++ .../001_build_arg_cli/Dockerfile | 2 ++ .../001_build_arg_cli/build-args | 1 + .../001_build_arg_cli/build.yml | 2 ++ .../056_build_args/001_build_arg_cli/test.sh | 13 ++++++++++++ .../002_build_arg_cli_over_yaml/Dockerfile | 2 ++ .../002_build_arg_cli_over_yaml/build-args | 1 + .../002_build_arg_cli_over_yaml/build.yml | 4 ++++ .../002_build_arg_cli_over_yaml/test.sh | 13 ++++++++++++ 14 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 test/cases/000_build/056_build_args/000_build_arg_yaml/Dockerfile create mode 100644 test/cases/000_build/056_build_args/000_build_arg_yaml/build.yml create mode 100644 test/cases/000_build/056_build_args/000_build_arg_yaml/test.sh create mode 100644 test/cases/000_build/056_build_args/001_build_arg_cli/Dockerfile create mode 100644 test/cases/000_build/056_build_args/001_build_arg_cli/build-args create mode 100644 test/cases/000_build/056_build_args/001_build_arg_cli/build.yml create mode 100644 test/cases/000_build/056_build_args/001_build_arg_cli/test.sh create mode 100644 test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/Dockerfile create mode 100644 test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/build-args create mode 100644 test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/build.yml create mode 100644 test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/test.sh diff --git a/src/cmd/linuxkit/pkg_build.go b/src/cmd/linuxkit/pkg_build.go index db057c531..4c3973db6 100644 --- a/src/cmd/linuxkit/pkg_build.go +++ b/src/cmd/linuxkit/pkg_build.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "errors" "fmt" "os" @@ -46,6 +47,7 @@ func addCmdRunPkgBuildPush(cmd *cobra.Command, withPush bool) *cobra.Command { cacheDir = flagOverEnvVarOverDefaultString{def: defaultLinuxkitCache(), envVar: envVarCacheDir} sbomScanner string dockerfile string + buildArgFiles []string ) cmd.RunE = func(cmd *cobra.Command, args []string) error { @@ -95,6 +97,24 @@ func addCmdRunPkgBuildPush(cmd *cobra.Command, withPush bool) *cobra.Command { } opts = append(opts, pkglib.WithDockerfile(dockerfile)) + // read any build arg files + var buildArgs []string + for _, filename := range buildArgFiles { + f, err := os.Open(filename) + if err != nil { + return fmt.Errorf("error opening build args file %s: %w", filename, err) + } + defer f.Close() + scanner := bufio.NewScanner(f) + for scanner.Scan() { + buildArgs = append(buildArgs, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return fmt.Errorf("error reading build args file %s: %w", filename, err) + } + } + opts = append(opts, pkglib.WithBuildArgs(buildArgs)) + // skipPlatformsMap contains platforms that should be skipped skipPlatformsMap := make(map[string]bool) if skipPlatforms != "" { @@ -205,6 +225,7 @@ func addCmdRunPkgBuildPush(cmd *cobra.Command, withPush bool) *cobra.Command { cmd.Flags().BoolVar(&manifest, "manifest", true, "Create and push multi-arch manifest") cmd.Flags().StringVar(&sbomScanner, "sbom-scanner", "", "SBOM scanner to use, must match the buildkit spec; set to blank to use the buildkit default; set to 'false' for no scanning") cmd.Flags().StringVar(&dockerfile, "dockerfile", "", "Dockerfile to use for building the image, must be in this directory or below, overrides what is in build.yml") + cmd.Flags().StringArrayVar(&buildArgFiles, "build-arg-file", nil, "Files containing build arguments, one key=value per line, contents augment and override buildArgs in build.yml. Can be specified multiple times. File is relative to working directory when running `linuxkit pkg build`") return cmd } diff --git a/src/cmd/linuxkit/pkglib/build.go b/src/cmd/linuxkit/pkglib/build.go index 63e8fa0fd..8c138f6a7 100644 --- a/src/cmd/linuxkit/pkglib/build.go +++ b/src/cmd/linuxkit/pkglib/build.go @@ -44,6 +44,7 @@ type buildOpts struct { sbomScan bool sbomScannerImage string dockerfile string + buildArgs []string } // BuildOpt allows callers to specify options to Build @@ -195,6 +196,16 @@ func WithDockerfile(dockerfile string) BuildOpt { } } +// WithBuildArgs add build args to use when building the package +func WithBuildArgs(args []string) BuildOpt { + return func(bo *buildOpts) error { + // we copy the contents, rather than the reference to the slice, to be safe + bo.buildArgs = make([]string, len(args)) + copy(bo.buildArgs, args) + return nil + } +} + // Build builds the package func (p Pkg) Build(bos ...BuildOpt) error { var bo buildOpts @@ -380,6 +391,7 @@ func (p Pkg) Build(bos ...BuildOpt) error { imageBuildOpts.Labels["org.mobyproject.linuxkit.version"] = version.Version imageBuildOpts.Labels["org.mobyproject.linuxkit.revision"] = version.GitCommit + // add build args from the build.yml file if p.buildArgs != nil { for _, buildArg := range *p.buildArgs { parts := strings.SplitN(buildArg, "=", 2) @@ -389,6 +401,15 @@ func (p Pkg) Build(bos ...BuildOpt) error { imageBuildOpts.BuildArgs[parts[0]] = &parts[1] } } + // add build args from other files + for _, buildArg := range bo.buildArgs { + parts := strings.SplitN(buildArg, "=", 2) + if len(parts) != 2 { + return fmt.Errorf("invalid build-arg, must be in format 'arg=value': %s", buildArg) + } + imageBuildOpts.BuildArgs[parts[0]] = &parts[1] + } + // add in information about the build process that might be useful if _, ok := imageBuildOpts.BuildArgs["SOURCE"]; !ok && p.gitRepo != "" { imageBuildOpts.BuildArgs["SOURCE"] = &p.gitRepo diff --git a/src/cmd/linuxkit/pkglib/docker.go b/src/cmd/linuxkit/pkglib/docker.go index a61ce203c..aca436ba7 100644 --- a/src/cmd/linuxkit/pkglib/docker.go +++ b/src/cmd/linuxkit/pkglib/docker.go @@ -473,10 +473,11 @@ func (dr *dockerRunnerImpl) build(ctx context.Context, tag, pkg, dockerfile, doc solveOpts.Session = append(solveOpts.Session, up) } else { solveOpts.LocalDirs = map[string]string{ - builder.DefaultLocalNameDockerfile: path.Join(pkg, dockerfile), + builder.DefaultLocalNameDockerfile: pkg, builder.DefaultLocalNameContext: pkg, } } + frontendAttrs["filename"] = dockerfile // go through the dockerfile to see if we have any provided images cached if c != nil { diff --git a/test/cases/000_build/056_build_args/000_build_arg_yaml/Dockerfile b/test/cases/000_build/056_build_args/000_build_arg_yaml/Dockerfile new file mode 100644 index 000000000..9a3a30e78 --- /dev/null +++ b/test/cases/000_build/056_build_args/000_build_arg_yaml/Dockerfile @@ -0,0 +1,2 @@ +ARG IMAGE +FROM ${IMAGE} diff --git a/test/cases/000_build/056_build_args/000_build_arg_yaml/build.yml b/test/cases/000_build/056_build_args/000_build_arg_yaml/build.yml new file mode 100644 index 000000000..9c970a2bd --- /dev/null +++ b/test/cases/000_build/056_build_args/000_build_arg_yaml/build.yml @@ -0,0 +1,4 @@ +org: linuxkit +image: image-in-build-args +buildArgs: +- IMAGE=alpine:3.19 diff --git a/test/cases/000_build/056_build_args/000_build_arg_yaml/test.sh b/test/cases/000_build/056_build_args/000_build_arg_yaml/test.sh new file mode 100644 index 000000000..4fb6ae22c --- /dev/null +++ b/test/cases/000_build/056_build_args/000_build_arg_yaml/test.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# SUMMARY: Check that tar output format build is reproducible +# LABELS: + +set -e + +# Source libraries. Uncomment if needed/defined +#. "${RT_LIB}" +. "${RT_PROJECT_ROOT}/_lib/lib.sh" + +linuxkit pkg build --force . + +exit 0 diff --git a/test/cases/000_build/056_build_args/001_build_arg_cli/Dockerfile b/test/cases/000_build/056_build_args/001_build_arg_cli/Dockerfile new file mode 100644 index 000000000..9a3a30e78 --- /dev/null +++ b/test/cases/000_build/056_build_args/001_build_arg_cli/Dockerfile @@ -0,0 +1,2 @@ +ARG IMAGE +FROM ${IMAGE} diff --git a/test/cases/000_build/056_build_args/001_build_arg_cli/build-args b/test/cases/000_build/056_build_args/001_build_arg_cli/build-args new file mode 100644 index 000000000..bdd1c6fb6 --- /dev/null +++ b/test/cases/000_build/056_build_args/001_build_arg_cli/build-args @@ -0,0 +1 @@ +IMAGE=alpine:3.19 diff --git a/test/cases/000_build/056_build_args/001_build_arg_cli/build.yml b/test/cases/000_build/056_build_args/001_build_arg_cli/build.yml new file mode 100644 index 000000000..87c0bb62f --- /dev/null +++ b/test/cases/000_build/056_build_args/001_build_arg_cli/build.yml @@ -0,0 +1,2 @@ +org: linuxkit +image: test-image-in-yaml-build-args diff --git a/test/cases/000_build/056_build_args/001_build_arg_cli/test.sh b/test/cases/000_build/056_build_args/001_build_arg_cli/test.sh new file mode 100644 index 000000000..8a7f111f0 --- /dev/null +++ b/test/cases/000_build/056_build_args/001_build_arg_cli/test.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# SUMMARY: Check that tar output format build is reproducible +# LABELS: + +set -e + +# Source libraries. Uncomment if needed/defined +#. "${RT_LIB}" +. "${RT_PROJECT_ROOT}/_lib/lib.sh" + +linuxkit pkg build --force --build-arg-file build-args . + +exit 0 diff --git a/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/Dockerfile b/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/Dockerfile new file mode 100644 index 000000000..9a3a30e78 --- /dev/null +++ b/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/Dockerfile @@ -0,0 +1,2 @@ +ARG IMAGE +FROM ${IMAGE} diff --git a/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/build-args b/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/build-args new file mode 100644 index 000000000..bdd1c6fb6 --- /dev/null +++ b/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/build-args @@ -0,0 +1 @@ +IMAGE=alpine:3.19 diff --git a/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/build.yml b/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/build.yml new file mode 100644 index 000000000..e31110883 --- /dev/null +++ b/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/build.yml @@ -0,0 +1,4 @@ +org: linuxkit +image: test-image-in-yaml-build-args-with-cli-override +buildArgs: +- IMAGE=non-existent:foo diff --git a/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/test.sh b/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/test.sh new file mode 100644 index 000000000..8a7f111f0 --- /dev/null +++ b/test/cases/000_build/056_build_args/002_build_arg_cli_over_yaml/test.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# SUMMARY: Check that tar output format build is reproducible +# LABELS: + +set -e + +# Source libraries. Uncomment if needed/defined +#. "${RT_LIB}" +. "${RT_PROJECT_ROOT}/_lib/lib.sh" + +linuxkit pkg build --force --build-arg-file build-args . + +exit 0