daemon_linux_test.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // +build linux
  2. package daemon // import "github.com/docker/docker/daemon"
  3. import (
  4. "strings"
  5. "testing"
  6. containertypes "github.com/docker/docker/api/types/container"
  7. "github.com/docker/docker/container"
  8. "github.com/docker/docker/oci"
  9. "github.com/docker/docker/pkg/idtools"
  10. "github.com/docker/docker/pkg/mount"
  11. "github.com/gotestyourself/gotestyourself/assert"
  12. is "github.com/gotestyourself/gotestyourself/assert/cmp"
  13. )
  14. const mountsFixture = `142 78 0:38 / / rw,relatime - aufs none rw,si=573b861da0b3a05b,dio
  15. 143 142 0:60 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
  16. 144 142 0:67 / /dev rw,nosuid - tmpfs tmpfs rw,mode=755
  17. 145 144 0:78 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
  18. 146 144 0:49 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw
  19. 147 142 0:84 / /sys rw,nosuid,nodev,noexec,relatime - sysfs sysfs rw
  20. 148 147 0:86 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755
  21. 149 148 0:22 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpuset
  22. 150 148 0:25 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/cpu rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpu
  23. 151 148 0:27 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/cpuacct rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpuacct
  24. 152 148 0:28 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,memory
  25. 153 148 0:29 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,devices
  26. 154 148 0:30 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,freezer
  27. 155 148 0:31 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,blkio
  28. 156 148 0:32 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,perf_event
  29. 157 148 0:33 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,hugetlb
  30. 158 148 0:35 /docker/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime - cgroup systemd rw,name=systemd
  31. 159 142 8:4 /home/mlaventure/gopath /home/mlaventure/gopath rw,relatime - ext4 /dev/disk/by-uuid/d99e196c-1fc4-4b4f-bab9-9962b2b34e99 rw,errors=remount-ro,data=ordered
  32. 160 142 8:4 /var/lib/docker/volumes/9a428b651ee4c538130143cad8d87f603a4bf31b928afe7ff3ecd65480692b35/_data /var/lib/docker rw,relatime - ext4 /dev/disk/by-uuid/d99e196c-1fc4-4b4f-bab9-9962b2b34e99 rw,errors=remount-ro,data=ordered
  33. 164 142 8:4 /home/mlaventure/gopath/src/github.com/docker/docker /go/src/github.com/docker/docker rw,relatime - ext4 /dev/disk/by-uuid/d99e196c-1fc4-4b4f-bab9-9962b2b34e99 rw,errors=remount-ro,data=ordered
  34. 165 142 8:4 /var/lib/docker/containers/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/disk/by-uuid/d99e196c-1fc4-4b4f-bab9-9962b2b34e99 rw,errors=remount-ro,data=ordered
  35. 166 142 8:4 /var/lib/docker/containers/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a/hostname /etc/hostname rw,relatime - ext4 /dev/disk/by-uuid/d99e196c-1fc4-4b4f-bab9-9962b2b34e99 rw,errors=remount-ro,data=ordered
  36. 167 142 8:4 /var/lib/docker/containers/5425782a95e643181d8a485a2bab3c0bb21f51d7dfc03511f0e6fbf3f3aa356a/hosts /etc/hosts rw,relatime - ext4 /dev/disk/by-uuid/d99e196c-1fc4-4b4f-bab9-9962b2b34e99 rw,errors=remount-ro,data=ordered
  37. 168 144 0:39 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k
  38. 169 144 0:12 /14 /dev/console rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=000
  39. 83 147 0:10 / /sys/kernel/security rw,relatime - securityfs none rw
  40. 89 142 0:87 / /tmp rw,relatime - tmpfs none rw
  41. 97 142 0:60 / /run/docker/netns/default rw,nosuid,nodev,noexec,relatime - proc proc rw
  42. 100 160 8:4 /var/lib/docker/volumes/9a428b651ee4c538130143cad8d87f603a4bf31b928afe7ff3ecd65480692b35/_data/aufs /var/lib/docker/aufs rw,relatime - ext4 /dev/disk/by-uuid/d99e196c-1fc4-4b4f-bab9-9962b2b34e99 rw,errors=remount-ro,data=ordered
  43. 115 100 0:102 / /var/lib/docker/aufs/mnt/0ecda1c63e5b58b3d89ff380bf646c95cc980252cf0b52466d43619aec7c8432 rw,relatime - aufs none rw,si=573b861dbc01905b,dio
  44. 116 160 0:107 / /var/lib/docker/containers/d045dc441d2e2e1d5b3e328d47e5943811a40819fb47497c5f5a5df2d6d13c37/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k
  45. 118 142 0:102 / /run/docker/libcontainerd/d045dc441d2e2e1d5b3e328d47e5943811a40819fb47497c5f5a5df2d6d13c37/rootfs rw,relatime - aufs none rw,si=573b861dbc01905b,dio
  46. 242 142 0:60 / /run/docker/netns/c3664df2a0f7 rw,nosuid,nodev,noexec,relatime - proc proc rw
  47. 120 100 0:122 / /var/lib/docker/aufs/mnt/03ca4b49e71f1e49a41108829f4d5c70ac95934526e2af8984a1f65f1de0715d rw,relatime - aufs none rw,si=573b861eb147805b,dio
  48. 171 142 0:122 / /run/docker/libcontainerd/e406ff6f3e18516d50e03dbca4de54767a69a403a6f7ec1edc2762812824521e/rootfs rw,relatime - aufs none rw,si=573b861eb147805b,dio
  49. 310 142 0:60 / /run/docker/netns/71a18572176b rw,nosuid,nodev,noexec,relatime - proc proc rw
  50. `
  51. func TestCleanupMounts(t *testing.T) {
  52. d := &Daemon{
  53. root: "/var/lib/docker/",
  54. }
  55. expected := "/var/lib/docker/containers/d045dc441d2e2e1d5b3e328d47e5943811a40819fb47497c5f5a5df2d6d13c37/shm"
  56. var unmounted int
  57. unmount := func(target string) error {
  58. if target == expected {
  59. unmounted++
  60. }
  61. return nil
  62. }
  63. d.cleanupMountsFromReaderByID(strings.NewReader(mountsFixture), "", unmount)
  64. if unmounted != 1 {
  65. t.Fatal("Expected to unmount the shm (and the shm only)")
  66. }
  67. }
  68. func TestCleanupMountsByID(t *testing.T) {
  69. d := &Daemon{
  70. root: "/var/lib/docker/",
  71. }
  72. expected := "/var/lib/docker/aufs/mnt/03ca4b49e71f1e49a41108829f4d5c70ac95934526e2af8984a1f65f1de0715d"
  73. var unmounted int
  74. unmount := func(target string) error {
  75. if target == expected {
  76. unmounted++
  77. }
  78. return nil
  79. }
  80. d.cleanupMountsFromReaderByID(strings.NewReader(mountsFixture), "03ca4b49e71f1e49a41108829f4d5c70ac95934526e2af8984a1f65f1de0715d", unmount)
  81. if unmounted != 1 {
  82. t.Fatal("Expected to unmount the auf root (and that only)")
  83. }
  84. }
  85. func TestNotCleanupMounts(t *testing.T) {
  86. d := &Daemon{
  87. repository: "",
  88. }
  89. var unmounted bool
  90. unmount := func(target string) error {
  91. unmounted = true
  92. return nil
  93. }
  94. mountInfo := `234 232 0:59 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k`
  95. d.cleanupMountsFromReaderByID(strings.NewReader(mountInfo), "", unmount)
  96. if unmounted {
  97. t.Fatal("Expected not to clean up /dev/shm")
  98. }
  99. }
  100. // TestTmpfsDevShmSizeOverride checks that user-specified /dev/tmpfs mount
  101. // size is not overriden by the default shmsize (that should only be used
  102. // for default /dev/shm (as in "shareable" and "private" ipc modes).
  103. // https://github.com/moby/moby/issues/35271
  104. func TestTmpfsDevShmSizeOverride(t *testing.T) {
  105. size := "777m"
  106. mnt := "/dev/shm"
  107. d := Daemon{
  108. idMappings: &idtools.IDMappings{},
  109. }
  110. c := &container.Container{
  111. HostConfig: &containertypes.HostConfig{
  112. ShmSize: 48 * 1024, // size we should NOT end up with
  113. },
  114. }
  115. ms := []container.Mount{
  116. {
  117. Source: "tmpfs",
  118. Destination: mnt,
  119. Data: "size=" + size,
  120. },
  121. }
  122. // convert ms to spec
  123. spec := oci.DefaultSpec()
  124. err := setMounts(&d, &spec, c, ms)
  125. assert.Check(t, err)
  126. // Check the resulting spec for the correct size
  127. found := false
  128. for _, m := range spec.Mounts {
  129. if m.Destination == mnt {
  130. for _, o := range m.Options {
  131. if !strings.HasPrefix(o, "size=") {
  132. continue
  133. }
  134. t.Logf("%+v\n", m.Options)
  135. assert.Check(t, is.Equal("size="+size, o))
  136. found = true
  137. }
  138. }
  139. }
  140. if !found {
  141. t.Fatal("/dev/shm not found in spec, or size option missing")
  142. }
  143. }
  144. func TestValidateContainerIsolationLinux(t *testing.T) {
  145. d := Daemon{}
  146. _, err := d.verifyContainerSettings("linux", &containertypes.HostConfig{Isolation: containertypes.IsolationHyperV}, nil, false)
  147. assert.Check(t, is.Error(err, "invalid isolation 'hyperv' on linux"))
  148. }
  149. func TestShouldUnmountRoot(t *testing.T) {
  150. for _, test := range []struct {
  151. desc string
  152. root string
  153. info *mount.Info
  154. expect bool
  155. }{
  156. {
  157. desc: "root is at /",
  158. root: "/docker",
  159. info: &mount.Info{Root: "/docker", Mountpoint: "/docker"},
  160. expect: true,
  161. },
  162. {
  163. desc: "root is at in a submount from `/`",
  164. root: "/foo/docker",
  165. info: &mount.Info{Root: "/docker", Mountpoint: "/foo/docker"},
  166. expect: true,
  167. },
  168. {
  169. desc: "root is mounted in from a parent mount namespace same root dir", // dind is an example of this
  170. root: "/docker",
  171. info: &mount.Info{Root: "/docker/volumes/1234657/_data", Mountpoint: "/docker"},
  172. expect: false,
  173. },
  174. } {
  175. t.Run(test.desc, func(t *testing.T) {
  176. for _, options := range []struct {
  177. desc string
  178. Optional string
  179. expect bool
  180. }{
  181. {desc: "shared", Optional: "shared:", expect: true},
  182. {desc: "slave", Optional: "slave:", expect: false},
  183. {desc: "private", Optional: "private:", expect: false},
  184. } {
  185. t.Run(options.desc, func(t *testing.T) {
  186. expect := options.expect
  187. if expect {
  188. expect = test.expect
  189. }
  190. if test.info != nil {
  191. test.info.Optional = options.Optional
  192. }
  193. assert.Check(t, is.Equal(expect, shouldUnmountRoot(test.root, test.info)))
  194. })
  195. }
  196. })
  197. }
  198. }