Skip to content

Commit c605289

Browse files
committed
fix: dot path normalized correctly for COPY
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` and `""` scenarios. `""`. The `"/"`case is handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation, same to "" -> "./". This is important especially for WORKDIR that are not `/`, so that `COPY --link` operations are handled properly. fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
1 parent 07e2dce commit c605289

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,9 +1763,6 @@ func pathRelativeToWorkingDir(s llb.State, p string, platform ocispecs.Platform)
17631763
return "", err
17641764
}
17651765

1766-
if len(p) == 0 {
1767-
return dir, nil
1768-
}
17691766
p, err = system.CheckSystemDriveAndRemoveDriveLetter(p, platform.OS)
17701767
if err != nil {
17711768
return "", errors.Wrap(err, "removing drive letter")
@@ -1774,6 +1771,12 @@ func pathRelativeToWorkingDir(s llb.State, p string, platform ocispecs.Platform)
17741771
if system.IsAbs(p, platform.OS) {
17751772
return system.NormalizePath("/", p, platform.OS, true)
17761773
}
1774+
1775+
// add slashes for "" and "." paths
1776+
// "" is treated as current directory and not necessariy root
1777+
if p == "." || p == "" {
1778+
p = "./"
1779+
}
17771780
return system.NormalizePath(dir, p, platform.OS, true)
17781781
}
17791782

frontend/dockerfile/dockerfile_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ var allTests = integration.TestFuncs(
142142
testNamedMultiplatformInputContext,
143143
testNamedFilteredContext,
144144
testEmptyDestDir,
145+
testCopyLinkDotDestDir,
146+
testCopyLinkEmptyDestDir,
145147
testCopyChownCreateDest,
146148
testCopyThroughSymlinkContext,
147149
testCopyThroughSymlinkMultiStage,
@@ -447,6 +449,67 @@ RUN [ "$(cat testfile)" == "contents0" ]
447449
require.NoError(t, err)
448450
}
449451

452+
func testCopyLinkDotDestDir(t *testing.T, sb integration.Sandbox) {
453+
integration.SkipOnPlatform(t, "windows")
454+
f := getFrontend(t, sb)
455+
456+
dockerfile := []byte(`
457+
FROM busybox
458+
WORKDIR /var/www
459+
COPY --link testfile .
460+
RUN [ "$(cat testfile)" == "contents0" ]
461+
`)
462+
463+
dir := integration.Tmpdir(
464+
t,
465+
fstest.CreateFile("Dockerfile", dockerfile, 0600),
466+
fstest.CreateFile("testfile", []byte("contents0"), 0600),
467+
)
468+
469+
c, err := client.New(sb.Context(), sb.Address())
470+
require.NoError(t, err)
471+
defer c.Close()
472+
473+
_, err = f.Solve(sb.Context(), c, client.SolveOpt{
474+
LocalMounts: map[string]fsutil.FS{
475+
dockerui.DefaultLocalNameDockerfile: dir,
476+
dockerui.DefaultLocalNameContext: dir,
477+
},
478+
}, nil)
479+
require.NoError(t, err)
480+
}
481+
482+
func testCopyLinkEmptyDestDir(t *testing.T, sb integration.Sandbox) {
483+
integration.SkipOnPlatform(t, "windows")
484+
f := getFrontend(t, sb)
485+
486+
dockerfile := []byte(`
487+
FROM busybox
488+
WORKDIR /var/www
489+
ENV empty=""
490+
COPY --link testfile $empty
491+
RUN [ "$(cat testfile)" == "contents0" ]
492+
`)
493+
494+
dir := integration.Tmpdir(
495+
t,
496+
fstest.CreateFile("Dockerfile", dockerfile, 0600),
497+
fstest.CreateFile("testfile", []byte("contents0"), 0600),
498+
)
499+
500+
c, err := client.New(sb.Context(), sb.Address())
501+
require.NoError(t, err)
502+
defer c.Close()
503+
504+
_, err = f.Solve(sb.Context(), c, client.SolveOpt{
505+
LocalMounts: map[string]fsutil.FS{
506+
dockerui.DefaultLocalNameDockerfile: dir,
507+
dockerui.DefaultLocalNameContext: dir,
508+
},
509+
}, nil)
510+
require.NoError(t, err)
511+
}
512+
450513
func testExportCacheLoop(t *testing.T, sb integration.Sandbox) {
451514
integration.SkipOnPlatform(t, "windows")
452515
workers.CheckFeatureCompat(t, sb, workers.FeatureCacheExport, workers.FeatureCacheImport, workers.FeatureCacheBackendLocal)

0 commit comments

Comments
 (0)