setup_unix.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. //go:build linux || freebsd
  2. // +build linux freebsd
  3. package initlayer // import "github.com/docker/docker/daemon/initlayer"
  4. import (
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "github.com/docker/docker/pkg/containerfs"
  9. "github.com/docker/docker/pkg/idtools"
  10. "golang.org/x/sys/unix"
  11. )
  12. // Setup populates a directory with mountpoints suitable
  13. // for bind-mounting things into the container.
  14. //
  15. // This extra layer is used by all containers as the top-most ro layer. It protects
  16. // the container from unwanted side-effects on the rw layer.
  17. func Setup(initLayerFs containerfs.ContainerFS, rootIdentity idtools.Identity) error {
  18. // Since all paths are local to the container, we can just extract initLayerFs.Path()
  19. initLayer := initLayerFs
  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. unix.Unlink(filepath.Join(initLayer, prev))
  37. }
  38. if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil {
  39. if os.IsNotExist(err) {
  40. if err := idtools.MkdirAllAndChownNew(filepath.Join(initLayer, filepath.Dir(pth)), 0755, rootIdentity); err != nil {
  41. return err
  42. }
  43. switch typ {
  44. case "dir":
  45. if err := idtools.MkdirAllAndChownNew(filepath.Join(initLayer, pth), 0755, rootIdentity); err != nil {
  46. return err
  47. }
  48. case "file":
  49. f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755)
  50. if err != nil {
  51. return err
  52. }
  53. f.Chown(rootIdentity.UID, rootIdentity.GID)
  54. f.Close()
  55. default:
  56. if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil {
  57. return err
  58. }
  59. }
  60. } else {
  61. return err
  62. }
  63. }
  64. }
  65. // Layer is ready to use, if it wasn't before.
  66. return nil
  67. }