2021-08-23 09:14:53 -04:00
|
|
|
//go:build linux || freebsd
|
2016-12-12 18:05:53 -05:00
|
|
|
// +build linux freebsd
|
|
|
|
|
2018-02-05 16:05:59 -05:00
|
|
|
package initlayer // import "github.com/docker/docker/daemon/initlayer"
|
2016-12-12 18:05:53 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
|
2017-08-03 20:22:00 -04:00
|
|
|
"github.com/docker/docker/pkg/containerfs"
|
2016-12-12 18:05:53 -05:00
|
|
|
"github.com/docker/docker/pkg/idtools"
|
2017-05-23 10:22:32 -04:00
|
|
|
"golang.org/x/sys/unix"
|
2016-12-12 18:05:53 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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.
|
2017-11-16 01:20:33 -05:00
|
|
|
func Setup(initLayerFs containerfs.ContainerFS, rootIdentity idtools.Identity) error {
|
2017-08-03 20:22:00 -04:00
|
|
|
// Since all paths are local to the container, we can just extract initLayerFs.Path()
|
|
|
|
initLayer := initLayerFs.Path()
|
|
|
|
|
2016-12-12 18:05:53 -05:00
|
|
|
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)
|
2017-05-23 10:22:32 -04:00
|
|
|
unix.Unlink(filepath.Join(initLayer, prev))
|
2016-12-12 18:05:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil {
|
|
|
|
if os.IsNotExist(err) {
|
2017-11-16 01:20:33 -05:00
|
|
|
if err := idtools.MkdirAllAndChownNew(filepath.Join(initLayer, filepath.Dir(pth)), 0755, rootIdentity); err != nil {
|
2016-12-12 18:05:53 -05:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
switch typ {
|
|
|
|
case "dir":
|
2017-11-16 01:20:33 -05:00
|
|
|
if err := idtools.MkdirAllAndChownNew(filepath.Join(initLayer, pth), 0755, rootIdentity); err != nil {
|
2016-12-12 18:05:53 -05:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
case "file":
|
|
|
|
f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-11-16 01:20:33 -05:00
|
|
|
f.Chown(rootIdentity.UID, rootIdentity.GID)
|
2016-12-12 18:05:53 -05:00
|
|
|
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
|
|
|
|
}
|