diff --git a/cmd/buildah/bud.go b/cmd/buildah/bud.go index 3a257cc4cfa..ec740d3de57 100644 --- a/cmd/buildah/bud.go +++ b/cmd/buildah/bud.go @@ -269,6 +269,7 @@ func budCmd(c *cobra.Command, inputArgs []string, iopts budResults) error { RemoveIntermediateCtrs: iopts.Rm, ForceRmIntermediateCtrs: iopts.ForceRm, BlobDirectory: iopts.BlobCache, + Target: iopts.Target, } if iopts.Quiet { diff --git a/contrib/completions/bash/buildah b/contrib/completions/bash/buildah index 49faccb9272..dc1d44d90d3 100644 --- a/contrib/completions/bash/buildah +++ b/contrib/completions/bash/buildah @@ -414,6 +414,7 @@ return 1 --signature-policy -t --tag + --target --ulimit --userns --userns-uid-map diff --git a/docs/buildah-bud.md b/docs/buildah-bud.md index 4979036b344..43045c5875b 100644 --- a/docs/buildah-bud.md +++ b/docs/buildah-bud.md @@ -385,6 +385,12 @@ Specifies the name which will be assigned to the resulting image if the build process completes successfully. If _imageName_ does not include a registry name, the registry name *localhost* will be prepended to the image name. +**--target** *stageName* + +Set the target build stage to build. When building a Dockerfile with multiple build stages, --target +can be used to specify an intermediate build stage by name as a final stage for the resulting image. +Commands after the target stage will be skipped. + **--tls-verify** *bool-value* Require HTTPS and verify certificates when talking to container registries (defaults to true). diff --git a/imagebuildah/build.go b/imagebuildah/build.go index 56ab7aa5788..da85063a653 100644 --- a/imagebuildah/build.go +++ b/imagebuildah/build.go @@ -171,6 +171,8 @@ type BuildOptions struct { ForceRmIntermediateCtrs bool // BlobDirectory is a directory which we'll use for caching layer blobs. BlobDirectory string + // Target the targeted FROM in the Dockerfile to build + Target string } // Executor is a buildah-based implementation of the imagebuilder.Executor @@ -1441,6 +1443,13 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt if err != nil { return "", nil, errors.Wrap(err, "error reading multiple stages") } + if (options.Target != "") { + stagesTargeted, ok := stages.ByTarget(options.Target) + if !ok { + return "", nil, errors.Wrapf(err, "The target %q was not found in the provided Dockerfile", options.Target) + } + stages = stagesTargeted + } return exec.Build(ctx, stages) } diff --git a/pkg/cli/common.go b/pkg/cli/common.go index bbbbf347644..4f01f7b9904 100644 --- a/pkg/cli/common.go +++ b/pkg/cli/common.go @@ -69,6 +69,7 @@ type BudResults struct { SignaturePolicy string Squash bool Tag []string + Target string TlsVerify bool } @@ -157,6 +158,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet { fs.StringVar(&flags.SignaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)") fs.BoolVar(&flags.Squash, "squash", false, "Squash newly built layers into a single new layer. The build process does not currently support caching so this is a NOOP.") fs.StringSliceVarP(&flags.Tag, "tag", "t", []string{}, "tagged `name` to apply to the built image") + fs.StringVar(&flags.Target, "target", "", "set the target build stage to build") fs.BoolVar(&flags.TlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry") return fs } diff --git a/tests/bud.bats b/tests/bud.bats index 9d22242f9f8..024b51ce213 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -1172,3 +1172,16 @@ load helpers run test -e $mnt/usr/local/bin/composer [ "$status" -eq 0 ] } + +@test "bud-target" { + target=target + run buildah bud --signature-policy ${TESTSDIR}/policy.json -t ${target} --target mytarget ${TESTSDIR}/bud/target + [ "$status" -eq 0 ] + cid=$(buildah from ${target}) + root=$(buildah mount ${cid}) + run ls ${root}/1 + echo "$output" + [ "$status" -eq 0 ] + buildah umount ${cid} + buildah rm ${cid} +} diff --git a/tests/bud/target/Dockerfile b/tests/bud/target/Dockerfile new file mode 100644 index 00000000000..e204590b0f6 --- /dev/null +++ b/tests/bud/target/Dockerfile @@ -0,0 +1,5 @@ +FROM fedora:latest +RUN touch /foo + +FROM alpine:latest AS mytarget +RUN touch /1