]>
Commit | Line | Data |
---|---|---|
9b12e4fe JC |
1 | // +build !windows |
2 | ||
3 | package idtools | |
4 | ||
5 | import ( | |
6 | "os" | |
7 | "path/filepath" | |
8 | ||
9 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system" | |
10 | ) | |
11 | ||
12 | func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error { | |
13 | // make an array containing the original path asked for, plus (for mkAll == true) | |
14 | // all path components leading up to the complete path that don't exist before we MkdirAll | |
15 | // so that we can chown all of them properly at the end. If chownExisting is false, we won't | |
16 | // chown the full directory path if it exists | |
17 | var paths []string | |
18 | if _, err := os.Stat(path); err != nil && os.IsNotExist(err) { | |
19 | paths = []string{path} | |
20 | } else if err == nil && chownExisting { | |
21 | if err := os.Chown(path, ownerUID, ownerGID); err != nil { | |
22 | return err | |
23 | } | |
24 | // short-circuit--we were called with an existing directory and chown was requested | |
25 | return nil | |
26 | } else if err == nil { | |
27 | // nothing to do; directory path fully exists already and chown was NOT requested | |
28 | return nil | |
29 | } | |
30 | ||
31 | if mkAll { | |
32 | // walk back to "/" looking for directories which do not exist | |
33 | // and add them to the paths array for chown after creation | |
34 | dirPath := path | |
35 | for { | |
36 | dirPath = filepath.Dir(dirPath) | |
37 | if dirPath == "/" { | |
38 | break | |
39 | } | |
40 | if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) { | |
41 | paths = append(paths, dirPath) | |
42 | } | |
43 | } | |
44 | if err := system.MkdirAll(path, mode); err != nil && !os.IsExist(err) { | |
45 | return err | |
46 | } | |
47 | } else { | |
48 | if err := os.Mkdir(path, mode); err != nil && !os.IsExist(err) { | |
49 | return err | |
50 | } | |
51 | } | |
52 | // even if it existed, we will chown the requested path + any subpaths that | |
53 | // didn't exist when we called MkdirAll | |
54 | for _, pathComponent := range paths { | |
55 | if err := os.Chown(pathComponent, ownerUID, ownerGID); err != nil { | |
56 | return err | |
57 | } | |
58 | } | |
59 | return nil | |
60 | } |