Share /var/lib/kubernetes on startup
Kubelet makes sure that /var/lib/kubelet is rshared when it starts. If not, it bind-mounts it with rshared propagation to containers that mount volumes to /var/lib/kubelet can benefit from mount propagation.
This commit is contained in:
@@ -19,32 +19,23 @@ limitations under the License.
|
||||
package mount
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReadProcMountsFrom(t *testing.T) {
|
||||
successCase :=
|
||||
`/dev/0 /path/to/0 type0 flags 0 0
|
||||
/dev/1 /path/to/1 type1 flags 1 1
|
||||
/dev/2 /path/to/2 type2 flags,1,2=3 2 2
|
||||
`
|
||||
/dev/1 /path/to/1 type1 flags 1 1
|
||||
/dev/2 /path/to/2 type2 flags,1,2=3 2 2
|
||||
`
|
||||
// NOTE: readProcMountsFrom has been updated to using fnv.New32a()
|
||||
hash, err := readProcMountsFrom(strings.NewReader(successCase), nil)
|
||||
mounts, err := parseProcMounts([]byte(successCase))
|
||||
if err != nil {
|
||||
t.Errorf("expected success")
|
||||
}
|
||||
if hash != 0xa290ff0b {
|
||||
t.Errorf("expected 0xa290ff0b, got %#x", hash)
|
||||
}
|
||||
mounts := []MountPoint{}
|
||||
hash, err = readProcMountsFrom(strings.NewReader(successCase), &mounts)
|
||||
if err != nil {
|
||||
t.Errorf("expected success")
|
||||
}
|
||||
if hash != 0xa290ff0b {
|
||||
t.Errorf("expected 0xa290ff0b, got %#x", hash)
|
||||
t.Errorf("expected success, got %v", err)
|
||||
}
|
||||
if len(mounts) != 3 {
|
||||
t.Fatalf("expected 3 mounts, got %d", len(mounts))
|
||||
@@ -68,7 +59,7 @@ func TestReadProcMountsFrom(t *testing.T) {
|
||||
"/dev/2 /path/to/mount type flags 0 b\n",
|
||||
}
|
||||
for _, ec := range errorCases {
|
||||
_, err := readProcMountsFrom(strings.NewReader(ec), &mounts)
|
||||
_, err := parseProcMounts([]byte(ec))
|
||||
if err == nil {
|
||||
t.Errorf("expected error")
|
||||
}
|
||||
@@ -208,3 +199,126 @@ func TestGetMountRefsByDev(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func writeFile(content string) (string, string, error) {
|
||||
tempDir, err := ioutil.TempDir("", "mounter_shared_test")
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
filename := filepath.Join(tempDir, "mountinfo")
|
||||
err = ioutil.WriteFile(filename, []byte(content), 0600)
|
||||
if err != nil {
|
||||
os.RemoveAll(tempDir)
|
||||
return "", "", err
|
||||
}
|
||||
return tempDir, filename, nil
|
||||
}
|
||||
|
||||
func TestIsSharedSuccess(t *testing.T) {
|
||||
successMountInfo :=
|
||||
`62 0 253:0 / / rw,relatime shared:1 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
76 62 8:1 / /boot rw,relatime shared:29 - ext4 /dev/sda1 rw,seclabel,data=ordered
|
||||
78 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel
|
||||
80 62 0:42 / /var/lib/nfs/rpc_pipefs rw,relatime shared:31 - rpc_pipefs sunrpc rw
|
||||
82 62 0:43 / /var/lib/foo rw,relatime shared:32 - tmpfs tmpfs rw
|
||||
83 63 0:44 / /var/lib/bar rw,relatime - tmpfs tmpfs rw
|
||||
227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
224 62 253:0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
`
|
||||
tempDir, filename, err := writeFile(successMountInfo)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create temporary file: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
// /var/lib/kubelet is a directory on mount '/' that is shared
|
||||
// This is the most common case.
|
||||
"shared",
|
||||
"/var/lib/kubelet",
|
||||
true,
|
||||
},
|
||||
{
|
||||
// 8a2a... is a directory on mount /var/lib/docker/devicemapper
|
||||
// that is private.
|
||||
"private",
|
||||
"/var/lib/docker/devicemapper/mnt/8a2a5c19eefb06d6f851dfcb240f8c113427f5b49b19658b5c60168e88267693/",
|
||||
false,
|
||||
},
|
||||
{
|
||||
// 'directory' is a directory on mount
|
||||
// /var/lib/docker/devicemapper/test/shared that is shared, but one
|
||||
// of its parent is private.
|
||||
"nested-shared",
|
||||
"/var/lib/docker/devicemapper/test/shared/my/test/directory",
|
||||
true,
|
||||
},
|
||||
{
|
||||
// /var/lib/foo is a mount point and it's shared
|
||||
"shared-mount",
|
||||
"/var/lib/foo",
|
||||
true,
|
||||
},
|
||||
{
|
||||
// /var/lib/bar is a mount point and it's private
|
||||
"private-mount",
|
||||
"/var/lib/bar",
|
||||
false,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
ret, err := isShared(test.path, filename)
|
||||
if err != nil {
|
||||
t.Errorf("test %s got unexpected error: %v", test.name, err)
|
||||
}
|
||||
if ret != test.expectedResult {
|
||||
t.Errorf("test %s expected %v, got %v", test.name, test.expectedResult, ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSharedFailure(t *testing.T) {
|
||||
errorTests := []struct {
|
||||
name string
|
||||
content string
|
||||
}{
|
||||
{
|
||||
// the first line is too short
|
||||
name: "too-short-line",
|
||||
content: `62 0 253:0 / / rw,relatime
|
||||
76 62 8:1 / /boot rw,relatime shared:29 - ext4 /dev/sda1 rw,seclabel,data=ordered
|
||||
78 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel
|
||||
80 62 0:42 / /var/lib/nfs/rpc_pipefs rw,relatime shared:31 - rpc_pipefs sunrpc rw
|
||||
227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
224 62 253:0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
`,
|
||||
},
|
||||
{
|
||||
// there is no root mount
|
||||
name: "no-root-mount",
|
||||
content: `76 62 8:1 / /boot rw,relatime shared:29 - ext4 /dev/sda1 rw,seclabel,data=ordered
|
||||
78 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel
|
||||
80 62 0:42 / /var/lib/nfs/rpc_pipefs rw,relatime shared:31 - rpc_pipefs sunrpc rw
|
||||
227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
224 62 253:0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
`,
|
||||
},
|
||||
}
|
||||
for _, test := range errorTests {
|
||||
tempDir, filename, err := writeFile(test.content)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create temporary file: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
_, err = isShared("/", filename)
|
||||
if err == nil {
|
||||
t.Errorf("test %q: expected error, got none", test.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user