setup_unix.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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/idtools"
  9. "golang.org/x/sys/unix"
  10. )
  11. // Setup populates a directory with mountpoints suitable
  12. // for bind-mounting things into the container.
  13. //
  14. // This extra layer is used by all containers as the top-most ro layer. It protects
  15. // the container from unwanted side-effects on the rw layer.
  16. func Setup(initLayerFs string, rootIdentity idtools.Identity) error {
  17. // Since all paths are local to the container, we can just extract initLayerFs.Path()
  18. initLayer := initLayerFs
  19. for pth, typ := range map[string]string{
  20. "/dev/pts": "dir",
  21. "/dev/shm": "dir",
  22. "/proc": "dir",
  23. "/sys": "dir",
  24. "/.dockerenv": "file",
  25. "/etc/resolv.conf": "file",
  26. "/etc/hosts": "file",
  27. "/etc/hostname": "file",
  28. "/dev/console": "file",
  29. "/etc/mtab": "/proc/mounts",
  30. } {
  31. parts := strings.Split(pth, "/")
  32. prev := "/"
  33. for _, p := range parts[1:] {
  34. prev = filepath.Join(prev, p)
  35. unix.Unlink(filepath.Join(initLayer, prev))
  36. }
  37. if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil {
  38. if os.IsNotExist(err) {
  39. if err := idtools.MkdirAllAndChownNew(filepath.Join(initLayer, filepath.Dir(pth)), 0o755, rootIdentity); err != nil {
  40. return err
  41. }
  42. switch typ {
  43. case "dir":
  44. if err := idtools.MkdirAllAndChownNew(filepath.Join(initLayer, pth), 0o755, rootIdentity); err != nil {
  45. return err
  46. }
  47. case "file":
  48. f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0o755)
  49. if err != nil {
  50. return err
  51. }
  52. f.Chown(rootIdentity.UID, rootIdentity.GID)
  53. f.Close()
  54. default:
  55. if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil {
  56. return err
  57. }
  58. }
  59. } else {
  60. return err
  61. }
  62. }
  63. }
  64. // Layer is ready to use, if it wasn't before.
  65. return nil
  66. }