github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/daemon/initlayer/setup_unix.go (about) 1 // +build linux freebsd 2 3 package initlayer 4 5 import ( 6 "os" 7 "path/filepath" 8 "strings" 9 "syscall" 10 11 "github.com/docker/docker/pkg/idtools" 12 ) 13 14 // Setup populates a directory with mountpoints suitable 15 // for bind-mounting things into the container. 16 // 17 // This extra layer is used by all containers as the top-most ro layer. It protects 18 // the container from unwanted side-effects on the rw layer. 19 func Setup(initLayer string, rootUID, rootGID int) error { 20 for pth, typ := range map[string]string{ 21 "/dev/pts": "dir", 22 "/dev/shm": "dir", 23 "/proc": "dir", 24 "/sys": "dir", 25 "/.dockerenv": "file", 26 "/etc/resolv.conf": "file", 27 "/etc/hosts": "file", 28 "/etc/hostname": "file", 29 "/dev/console": "file", 30 "/etc/mtab": "/proc/mounts", 31 } { 32 parts := strings.Split(pth, "/") 33 prev := "/" 34 for _, p := range parts[1:] { 35 prev = filepath.Join(prev, p) 36 syscall.Unlink(filepath.Join(initLayer, prev)) 37 } 38 39 if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil { 40 if os.IsNotExist(err) { 41 if err := idtools.MkdirAllNewAs(filepath.Join(initLayer, filepath.Dir(pth)), 0755, rootUID, rootGID); err != nil { 42 return err 43 } 44 switch typ { 45 case "dir": 46 if err := idtools.MkdirAllNewAs(filepath.Join(initLayer, pth), 0755, rootUID, rootGID); err != nil { 47 return err 48 } 49 case "file": 50 f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755) 51 if err != nil { 52 return err 53 } 54 f.Chown(rootUID, rootGID) 55 f.Close() 56 default: 57 if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil { 58 return err 59 } 60 } 61 } else { 62 return err 63 } 64 } 65 } 66 67 // Layer is ready to use, if it wasn't before. 68 return nil 69 }