Allow cache mounts to be stages or additional build contexts

Allow cache mounts (RUN --mount=type=cache) to refer to other stages or
additional build contexts.

Update the build-check-cve-2024-9675 integration test to use different
directories for its main build context and the additional build context
that it uses for its final run.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Signed-off-by: David Shea <dshea@redhat.com>
Signed-off-by: Vivek Naruka <vnaruka@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2025-01-06 13:47:31 -05:00 committed by Chris Evich
parent b294434927
commit 250174ede2
No known key found for this signature in database
GPG Key ID: 03EDC70FD578067F
4 changed files with 30 additions and 13 deletions

View File

@ -517,7 +517,12 @@ func (s *StageExecutor) runStageMountPoints(mountList []string) (map[string]inte
// to `mountPoint` replaced from additional
// build-context. Reason: Parser will use this
// `from` to refer from stageMountPoints map later.
stageMountPoints[from] = internal.StageMountDetails{IsStage: false, DidExecute: true, MountPoint: mountPoint}
stageMountPoints[from] = internal.StageMountDetails{
IsAdditionalBuildContext: true,
DidExecute: true,
IsImage: true,
MountPoint: mountPoint,
}
break
} else {
// Most likely this points to path on filesystem
@ -549,7 +554,11 @@ func (s *StageExecutor) runStageMountPoints(mountList []string) (map[string]inte
mountPoint = additionalBuildContext.DownloadedCache
}
}
stageMountPoints[from] = internal.StageMountDetails{IsStage: true, DidExecute: true, MountPoint: mountPoint}
stageMountPoints[from] = internal.StageMountDetails{
IsAdditionalBuildContext: true,
DidExecute: true,
MountPoint: mountPoint,
}
break
}
}
@ -560,14 +569,22 @@ func (s *StageExecutor) runStageMountPoints(mountList []string) (map[string]inte
return nil, err
}
if otherStage, ok := s.executor.stages[from]; ok && otherStage.index < s.index {
stageMountPoints[from] = internal.StageMountDetails{IsStage: true, DidExecute: otherStage.didExecute, MountPoint: otherStage.mountPoint}
stageMountPoints[from] = internal.StageMountDetails{
IsStage: true,
DidExecute: otherStage.didExecute,
MountPoint: otherStage.mountPoint,
}
break
} else {
mountPoint, err := s.getImageRootfs(s.ctx, from)
if err != nil {
return nil, fmt.Errorf("%s from=%s: no stage or image found with that name", flag, from)
}
stageMountPoints[from] = internal.StageMountDetails{IsStage: false, DidExecute: true, MountPoint: mountPoint}
stageMountPoints[from] = internal.StageMountDetails{
IsImage: true,
DidExecute: true,
MountPoint: mountPoint,
}
break
}
default:

View File

@ -166,7 +166,7 @@ func GetBindMount(ctx *types.SystemContext, args []string, contextDir string, st
// buildkit parity: support absolute path for sources from current build context
if contextDir != "" {
// path should be /contextDir/specified path
evaluated, err := copier.Eval(contextDir, newMount.Source, copier.EvalOptions{})
evaluated, err := copier.Eval(contextDir, string(filepath.Separator)+newMount.Source, copier.EvalOptions{})
if err != nil {
return newMount, "", err
}
@ -328,12 +328,10 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a
}
if fromStage != "" {
// do not create cache on host
// instead use read-only mounted stage as cache
mountPoint := ""
if additionalMountPoints != nil {
if val, ok := additionalMountPoints[fromStage]; ok {
if val.IsStage {
if !val.IsImage {
mountPoint = val.MountPoint
}
}
@ -341,7 +339,7 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a
// Cache does not supports using image so if not stage found
// return with error
if mountPoint == "" {
return newMount, nil, fmt.Errorf("no stage found with name %s", fromStage)
return newMount, nil, fmt.Errorf("no stage or additional build context found with name %s", fromStage)
}
// path should be /contextDir/specified path
evaluated, err := copier.Eval(mountPoint, string(filepath.Separator)+newMount.Source, copier.EvalOptions{})

View File

@ -13,6 +13,8 @@ const (
// automatically clean them up.
type StageMountDetails struct {
DidExecute bool // tells if the stage which is being mounted was freshly executed or was part of older cache
IsStage bool // tells if mountpoint returned from stage executor is stage or image
MountPoint string // mountpoint of stage/image
IsStage bool // true if the mountpoint is a stage's rootfs
IsImage bool // true if the mountpoint is an image's rootfs
IsAdditionalBuildContext bool // true if the mountpoint is an additional build context
MountPoint string // mountpoint of the stage or image's root directory or path of the additional build context
}

View File

@ -5738,8 +5738,8 @@ _EOF
run_buildah build -t buildkitbase $WITH_POLICY_JSON -f $contextdir/Dockerfilebuildkitbase $contextdir/
# try reading something from persistent cache in a different build
run_buildah 125 build -t testbud $WITH_POLICY_JSON -f $contextdir/Dockerfilecachefromimage
expect_output --substring "no stage found with name buildkitbase"
run_buildah 125 build -t testbud $WITH_POLICY_JSON -f ${TEST_SCRATCH_DIR}/bud/buildkit-mount-from/Dockerfilecachefromimage
expect_output --substring "no stage or additional build context found with name buildkitbase"
run_buildah rmi -f buildkitbase
}