github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/daemon/daemon_linux_test.go (about)

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