setup_unix.go 2.0 KB

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