mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #32084 from simonferquel/multi-stage-builds-windows
Multi stage builds cleanup for Windows
This commit is contained in:
commit
a48f4257f0
2 changed files with 109 additions and 5 deletions
|
@ -13,7 +13,6 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -298,16 +297,30 @@ func (b *Builder) download(srcURL string) (fi builder.FileInfo, err error) {
|
||||||
return &builder.HashedFileInfo{FileInfo: builder.PathFileInfo{FileInfo: tmpFileSt, FilePath: tmpFileName}, FileHash: hash}, nil
|
return &builder.HashedFileInfo{FileInfo: builder.PathFileInfo{FileInfo: tmpFileSt, FilePath: tmpFileName}, FileHash: hash}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var windowsBlacklist = map[string]bool{
|
||||||
|
"c:\\": true,
|
||||||
|
"c:\\windows": true,
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Builder) calcCopyInfo(cmdName, origPath string, allowLocalDecompression, allowWildcards bool, imageSource *imageMount) ([]copyInfo, error) {
|
func (b *Builder) calcCopyInfo(cmdName, origPath string, allowLocalDecompression, allowWildcards bool, imageSource *imageMount) ([]copyInfo, error) {
|
||||||
|
|
||||||
// Work in daemon-specific OS filepath semantics
|
// Work in daemon-specific OS filepath semantics
|
||||||
origPath = filepath.FromSlash(origPath)
|
origPath = filepath.FromSlash(origPath)
|
||||||
|
|
||||||
// validate windows paths from other images
|
// validate windows paths from other images
|
||||||
if imageSource != nil && runtime.GOOS == "windows" {
|
if imageSource != nil && runtime.GOOS == "windows" {
|
||||||
forbid := regexp.MustCompile("(?i)^" + string(os.PathSeparator) + "?(windows(" + string(os.PathSeparator) + ".+)?)?$")
|
p := strings.ToLower(filepath.Clean(origPath))
|
||||||
if p := filepath.Clean(origPath); p == "." || forbid.MatchString(p) {
|
if !filepath.IsAbs(p) {
|
||||||
return nil, errors.Errorf("copy from %s is not allowed on windows", origPath)
|
if filepath.VolumeName(p) != "" {
|
||||||
|
if p[len(p)-2:] == ":." { // case where clean returns weird c:. paths
|
||||||
|
p = p[:len(p)-1]
|
||||||
|
}
|
||||||
|
p += "\\"
|
||||||
|
} else {
|
||||||
|
p = filepath.Join("c:\\", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, blacklisted := windowsBlacklist[p]; blacklisted {
|
||||||
|
return nil, errors.New("copy from c:\\ or c:\\windows is not allowed on windows")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6024,6 +6024,97 @@ func (s *DockerTrustSuite) TestCopyFromTrustedBuild(c *check.C) {
|
||||||
dockerCmdWithResult("run", name, "cat", "bar").Assert(c, icmd.Expected{Out: "ok"})
|
dockerCmdWithResult("run", name, "cat", "bar").Assert(c, icmd.Expected{Out: "ok"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestBuildCopyFromPreviousFromWindows(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsWindows)
|
||||||
|
dockerfile := `
|
||||||
|
FROM ` + testEnv.MinimalBaseImage() + `
|
||||||
|
COPY foo c:\\bar`
|
||||||
|
ctx := fakeContext(c, dockerfile, map[string]string{
|
||||||
|
"Dockerfile": dockerfile,
|
||||||
|
"foo": "abc",
|
||||||
|
})
|
||||||
|
defer ctx.Close()
|
||||||
|
|
||||||
|
result := buildImage("build1", withExternalBuildContext(ctx))
|
||||||
|
result.Assert(c, icmd.Success)
|
||||||
|
|
||||||
|
dockerfile = `
|
||||||
|
FROM build1:latest
|
||||||
|
FROM ` + testEnv.MinimalBaseImage() + `
|
||||||
|
COPY --from=0 c:\\bar /
|
||||||
|
COPY foo /`
|
||||||
|
ctx = fakeContext(c, dockerfile, map[string]string{
|
||||||
|
"Dockerfile": dockerfile,
|
||||||
|
"foo": "def",
|
||||||
|
})
|
||||||
|
defer ctx.Close()
|
||||||
|
|
||||||
|
result = buildImage("build2", withExternalBuildContext(ctx))
|
||||||
|
result.Assert(c, icmd.Success)
|
||||||
|
|
||||||
|
out, _ := dockerCmd(c, "run", "build2", "cmd.exe", "/s", "/c", "type", "c:\\bar")
|
||||||
|
c.Assert(strings.TrimSpace(out), check.Equals, "abc")
|
||||||
|
out, _ = dockerCmd(c, "run", "build2", "cmd.exe", "/s", "/c", "type", "c:\\foo")
|
||||||
|
c.Assert(strings.TrimSpace(out), check.Equals, "def")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestBuildCopyFromForbidWindowsSystemPaths(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsWindows)
|
||||||
|
dockerfile := `
|
||||||
|
FROM ` + testEnv.MinimalBaseImage() + `
|
||||||
|
FROM ` + testEnv.MinimalBaseImage() + `
|
||||||
|
COPY --from=0 %s c:\\oscopy
|
||||||
|
`
|
||||||
|
exp := icmd.Expected{
|
||||||
|
ExitCode: 1,
|
||||||
|
Err: "copy from c:\\ or c:\\windows is not allowed on windows",
|
||||||
|
}
|
||||||
|
buildImage("testforbidsystempaths1", build.WithDockerfile(fmt.Sprintf(dockerfile, "c:\\\\"))).Assert(c, exp)
|
||||||
|
buildImage("testforbidsystempaths2", build.WithDockerfile(fmt.Sprintf(dockerfile, "C:\\\\"))).Assert(c, exp)
|
||||||
|
buildImage("testforbidsystempaths3", build.WithDockerfile(fmt.Sprintf(dockerfile, "c:\\\\windows"))).Assert(c, exp)
|
||||||
|
buildImage("testforbidsystempaths4", build.WithDockerfile(fmt.Sprintf(dockerfile, "c:\\\\wInDows"))).Assert(c, exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestBuildCopyFromForbidWindowsRelativePaths(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsWindows)
|
||||||
|
dockerfile := `
|
||||||
|
FROM ` + testEnv.MinimalBaseImage() + `
|
||||||
|
FROM ` + testEnv.MinimalBaseImage() + `
|
||||||
|
COPY --from=0 %s c:\\oscopy
|
||||||
|
`
|
||||||
|
exp := icmd.Expected{
|
||||||
|
ExitCode: 1,
|
||||||
|
Err: "copy from c:\\ or c:\\windows is not allowed on windows",
|
||||||
|
}
|
||||||
|
buildImage("testforbidsystempaths1", build.WithDockerfile(fmt.Sprintf(dockerfile, "c:"))).Assert(c, exp)
|
||||||
|
buildImage("testforbidsystempaths2", build.WithDockerfile(fmt.Sprintf(dockerfile, "."))).Assert(c, exp)
|
||||||
|
buildImage("testforbidsystempaths3", build.WithDockerfile(fmt.Sprintf(dockerfile, "..\\\\"))).Assert(c, exp)
|
||||||
|
buildImage("testforbidsystempaths4", build.WithDockerfile(fmt.Sprintf(dockerfile, ".\\\\windows"))).Assert(c, exp)
|
||||||
|
buildImage("testforbidsystempaths5", build.WithDockerfile(fmt.Sprintf(dockerfile, "\\\\windows"))).Assert(c, exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestBuildCopyFromWindowsIsCaseInsensitive(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsWindows)
|
||||||
|
dockerfile := `
|
||||||
|
FROM ` + testEnv.MinimalBaseImage() + `
|
||||||
|
COPY foo /
|
||||||
|
FROM ` + testEnv.MinimalBaseImage() + `
|
||||||
|
COPY --from=0 c:\\fOo c:\\copied
|
||||||
|
RUN type c:\\copied
|
||||||
|
`
|
||||||
|
ctx := fakeContext(c, dockerfile, map[string]string{
|
||||||
|
"Dockerfile": dockerfile,
|
||||||
|
"foo": "hello world",
|
||||||
|
})
|
||||||
|
defer ctx.Close()
|
||||||
|
exp := icmd.Expected{
|
||||||
|
ExitCode: 0,
|
||||||
|
Out: "hello world",
|
||||||
|
}
|
||||||
|
result := buildImage("copyfrom-windows-insensitive", withExternalBuildContext(ctx))
|
||||||
|
result.Assert(c, exp)
|
||||||
|
}
|
||||||
|
|
||||||
// TestBuildOpaqueDirectory tests that a build succeeds which
|
// TestBuildOpaqueDirectory tests that a build succeeds which
|
||||||
// creates opaque directories.
|
// creates opaque directories.
|
||||||
// See https://github.com/docker/docker/issues/25244
|
// See https://github.com/docker/docker/issues/25244
|
||||||
|
|
Loading…
Reference in a new issue