123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- // +build linux freebsd
- package initlayer
- import (
- "os"
- "path/filepath"
- "strings"
- "syscall"
- "github.com/docker/docker/pkg/idtools"
- )
- // Setup populates a directory with mountpoints suitable
- // for bind-mounting things into the container.
- //
- // This extra layer is used by all containers as the top-most ro layer. It protects
- // the container from unwanted side-effects on the rw layer.
- func Setup(initLayer string, rootUID, rootGID int) error {
- for pth, typ := range map[string]string{
- "/dev/pts": "dir",
- "/dev/shm": "dir",
- "/proc": "dir",
- "/sys": "dir",
- "/.dockerenv": "file",
- "/etc/resolv.conf": "file",
- "/etc/hosts": "file",
- "/etc/hostname": "file",
- "/dev/console": "file",
- "/etc/mtab": "/proc/mounts",
- } {
- parts := strings.Split(pth, "/")
- prev := "/"
- for _, p := range parts[1:] {
- prev = filepath.Join(prev, p)
- syscall.Unlink(filepath.Join(initLayer, prev))
- }
- if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil {
- if os.IsNotExist(err) {
- if err := idtools.MkdirAllNewAs(filepath.Join(initLayer, filepath.Dir(pth)), 0755, rootUID, rootGID); err != nil {
- return err
- }
- switch typ {
- case "dir":
- if err := idtools.MkdirAllNewAs(filepath.Join(initLayer, pth), 0755, rootUID, rootGID); err != nil {
- return err
- }
- case "file":
- f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755)
- if err != nil {
- return err
- }
- f.Chown(rootUID, rootGID)
- f.Close()
- default:
- if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil {
- return err
- }
- }
- } else {
- return err
- }
- }
- }
- // Layer is ready to use, if it wasn't before.
- return nil
- }
|