1
0
mirror of https://github.com/containers/buildah.git synced 2026-02-05 09:45:38 +01:00

Handle RUN --mount with relative targets and no configured workdir

When the target location of a RUN --mount is specified as a relative
path, we normally try to convert it to an absolute path by combining it
with the currently-configured working directory.  If there is no such
value, though, the result is still not an absolute path.  Work around
this by using "/" when the configured working directory is "".

Set this field in the `runMountInfo` struct on FreeBSD, as we already
did on Linux.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai
2024-10-24 15:35:45 -04:00
parent 1752337176
commit 701d6bbe91
5 changed files with 37 additions and 7 deletions

View File

@@ -531,6 +531,7 @@ func GetVolumes(ctx *types.SystemContext, store storage.Store, volumes []string,
// getMounts takes user-provided input from the --mount flag and creates OCI
// spec mounts.
// buildah run --mount type=bind,src=/etc/resolv.conf,target=/etc/resolv.conf ...
// buildah run --mount type=cache,target=/var/cache ...
// buildah run --mount type=tmpfs,target=/dev/shm ...
//
// If this function succeeds, the caller must unlock the returned *lockfile.LockFile s if any (when??).
@@ -590,7 +591,7 @@ func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, c
}
finalMounts[mount.Destination] = mount
case TypeTmpfs:
mount, err := GetTmpfsMount(tokens)
mount, err := GetTmpfsMount(tokens, workDir)
if err != nil {
return nil, mountedImages, nil, err
}
@@ -608,7 +609,7 @@ func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, c
}
// GetTmpfsMount parses a single tmpfs mount entry from the --mount flag
func GetTmpfsMount(args []string) (specs.Mount, error) {
func GetTmpfsMount(args []string, workDir string) (specs.Mount, error) {
newMount := specs.Mount{
Type: TypeTmpfs,
Source: TypeTmpfs,
@@ -646,10 +647,14 @@ func GetTmpfsMount(args []string) (specs.Mount, error) {
if !hasArgValue {
return newMount, fmt.Errorf("%v: %w", argName, errBadOptionArg)
}
if err := parse.ValidateVolumeCtrDir(argValue); err != nil {
targetPath := argValue
if !path.IsAbs(targetPath) {
targetPath = filepath.Join(workDir, targetPath)
}
if err := parse.ValidateVolumeCtrDir(targetPath); err != nil {
return newMount, err
}
newMount.Destination = argValue
newMount.Destination = targetPath
setDest = true
default:
return newMount, fmt.Errorf("%v: %w", argName, errBadMntOption)

View File

@@ -1605,7 +1605,7 @@ func (b *Builder) runSetupRunMounts(mountPoint string, mounts []string, sources
mountImages = append(mountImages, image)
}
case "tmpfs":
mountSpec, err = b.getTmpfsMount(tokens, idMaps)
mountSpec, err = b.getTmpfsMount(tokens, idMaps, sources.WorkDir)
if err != nil {
return nil, nil, err
}
@@ -1665,9 +1665,9 @@ func (b *Builder) getBindMount(tokens []string, context *imageTypes.SystemContex
return &volumes[0], image, nil
}
func (b *Builder) getTmpfsMount(tokens []string, idMaps IDMaps) (*specs.Mount, error) {
func (b *Builder) getTmpfsMount(tokens []string, idMaps IDMaps, workDir string) (*specs.Mount, error) {
var optionMounts []specs.Mount
mount, err := volumes.GetTmpfsMount(tokens)
mount, err := volumes.GetTmpfsMount(tokens, workDir)
if err != nil {
return nil, err
}

View File

@@ -124,10 +124,16 @@ func (b *Builder) Run(command []string, options RunOptions) error {
return err
}
workDir := b.WorkDir()
if options.WorkingDir != "" {
g.SetProcessCwd(options.WorkingDir)
workDir = options.WorkingDir
} else if b.WorkDir() != "" {
g.SetProcessCwd(b.WorkDir())
workDir = b.WorkDir()
}
if workDir == "" {
workDir = string(os.PathSeparator)
}
mountPoint, err := b.Mount(b.MountLabel)
if err != nil {
@@ -249,6 +255,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
}
runMountInfo := runMountInfo{
WorkDir: workDir,
ContextDir: options.ContextDir,
Secrets: options.Secrets,
SSHSources: options.SSHSources,

View File

@@ -237,6 +237,10 @@ func (b *Builder) Run(command []string, options RunOptions) error {
workDir = options.WorkingDir
} else if b.WorkDir() != "" {
g.SetProcessCwd(b.WorkDir())
workDir = b.WorkDir()
}
if workDir == "" {
workDir = string(os.PathSeparator)
}
setupSelinux(g, b.ProcessLabel, b.MountLabel)
mountPoint, err := b.Mount(b.MountLabel)

View File

@@ -7017,3 +7017,17 @@ EOF
run_buildah 1 build --security-opt label=disable --build-context testbuild=${TEST_SCRATCH_DIR}/cve20249675/ --no-cache ${TEST_SCRATCH_DIR}/cve20249675/
expect_output --substring "cat: can't open '/var/tmp/file.txt': No such file or directory"
}
@test "build-mounts-implicit-workdir" {
base=busybox
_prefetch $base
run_buildah inspect --format '{{.Docker.Config.WorkingDir}}' --type=image $base
expect_output "" "test base image needs to not have a default working directory defined in its configuration"
# check that the target for a bind mount can be specified as a relative path even when there's no WorkingDir defined for it to be relative to
echo FROM $base > ${TEST_SCRATCH_DIR}/Containerfile
echo RUN --mount=type=bind,src=Containerfile,target=Containerfile test -s Containerfile >> ${TEST_SCRATCH_DIR}/Containerfile
echo RUN --mount=type=cache,id=cash,target=cachesubdir truncate -s 1024 cachesubdir/cachefile >> ${TEST_SCRATCH_DIR}/Containerfile
echo RUN --mount=type=cache,id=cash,target=cachesubdir2 test -s cachesubdir2/cachefile >> ${TEST_SCRATCH_DIR}/Containerfile
echo RUN --mount=type=tmpfs,target=tmpfssubdir test '`stat -f -c %i .`' '!=' '`stat -f -c %i tmpfssubdir`' >> ${TEST_SCRATCH_DIR}/Containerfile
run_buildah build --security-opt label=disable ${TEST_SCRATCH_DIR}
}