13 // MkdirAll implementation that is volume path aware for Windows.
14 func MkdirAll(path string, perm os.FileMode) error {
15 if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) {
19 // The rest of this method is copied from os.MkdirAll and should be kept
20 // as-is to ensure compatibility.
22 // Fast path: if we can tell whether path is a directory or file, stop with success or error.
23 dir, err := os.Stat(path)
35 // Slow path: make sure parent exists and then call Mkdir for path.
37 for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator.
42 for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element.
48 err = MkdirAll(path[0:j-1], perm)
54 // Parent now exists; invoke Mkdir and use its result.
55 err = os.Mkdir(path, perm)
57 // Handle arguments like "foo/." by
58 // double-checking that directory doesn't exist.
59 dir, err1 := os.Lstat(path)
60 if err1 == nil && dir.IsDir() {
68 // IsAbs is a platform-specific wrapper for filepath.IsAbs. On Windows,
69 // golang filepath.IsAbs does not consider a path \windows\system32 as absolute
70 // as it doesn't start with a drive-letter/colon combination. However, in
71 // docker we need to verify things such as WORKDIR /windows/system32 in
72 // a Dockerfile (which gets translated to \windows\system32 when being processed
73 // by the daemon. This SHOULD be treated as absolute from a docker processing
75 func IsAbs(path string) bool {
76 if !filepath.IsAbs(path) {
77 if !strings.HasPrefix(path, string(os.PathSeparator)) {