...

Source file src/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux_test.go

Documentation: k8s.io/kubernetes/pkg/volume/util/hostutil

     1  //go:build linux
     2  // +build linux
     3  
     4  /*
     5  Copyright 2014 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package hostutil
    21  
    22  import (
    23  	"os"
    24  	"path/filepath"
    25  	"testing"
    26  )
    27  
    28  func TestIsSharedSuccess(t *testing.T) {
    29  	successMountInfo :=
    30  		`62 0 253:0 / / rw,relatime shared:1 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
    31  76 62 8:1 / /boot rw,relatime shared:29 - ext4 /dev/sda1 rw,seclabel,data=ordered
    32  78 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel
    33  80 62 0:42 / /var/lib/nfs/rpc_pipefs rw,relatime shared:31 - rpc_pipefs sunrpc rw
    34  82 62 0:43 / /var/lib/foo rw,relatime shared:32 - tmpfs tmpfs rw
    35  83 63 0:44 / /var/lib/bar rw,relatime - tmpfs tmpfs rw
    36  227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
    37  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
    38  `
    39  	tempDir, filename, err := writeFile(successMountInfo)
    40  	if err != nil {
    41  		t.Fatalf("cannot create temporary file: %v", err)
    42  	}
    43  	defer os.RemoveAll(tempDir)
    44  
    45  	tests := []struct {
    46  		name           string
    47  		path           string
    48  		expectedResult bool
    49  	}{
    50  		{
    51  			// /var/lib/kubelet is a directory on mount '/' that is shared
    52  			// This is the most common case.
    53  			"shared",
    54  			"/var/lib/kubelet",
    55  			true,
    56  		},
    57  		{
    58  			// 8a2a... is a directory on mount /var/lib/docker/devicemapper
    59  			// that is private.
    60  			"private",
    61  			"/var/lib/docker/devicemapper/mnt/8a2a5c19eefb06d6f851dfcb240f8c113427f5b49b19658b5c60168e88267693/",
    62  			false,
    63  		},
    64  		{
    65  			// 'directory' is a directory on mount
    66  			// /var/lib/docker/devicemapper/test/shared that is shared, but one
    67  			// of its parent is private.
    68  			"nested-shared",
    69  			"/var/lib/docker/devicemapper/test/shared/my/test/directory",
    70  			true,
    71  		},
    72  		{
    73  			// /var/lib/foo is a mount point and it's shared
    74  			"shared-mount",
    75  			"/var/lib/foo",
    76  			true,
    77  		},
    78  		{
    79  			// /var/lib/bar is a mount point and it's private
    80  			"private-mount",
    81  			"/var/lib/bar",
    82  			false,
    83  		},
    84  	}
    85  	for _, test := range tests {
    86  		ret, err := isShared(test.path, filename)
    87  		if err != nil {
    88  			t.Errorf("test %s got unexpected error: %v", test.name, err)
    89  		}
    90  		if ret != test.expectedResult {
    91  			t.Errorf("test %s expected %v, got %v", test.name, test.expectedResult, ret)
    92  		}
    93  	}
    94  }
    95  
    96  func TestIsSharedFailure(t *testing.T) {
    97  	errorTests := []struct {
    98  		name    string
    99  		content string
   100  	}{
   101  		{
   102  			// the first line is too short
   103  			name: "too-short-line",
   104  			content: `62 0 253:0 / / rw,relatime
   105  76 62 8:1 / /boot rw,relatime shared:29 - ext4 /dev/sda1 rw,seclabel,data=ordered
   106  78 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel
   107  80 62 0:42 / /var/lib/nfs/rpc_pipefs rw,relatime shared:31 - rpc_pipefs sunrpc rw
   108  227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
   109  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
   110  `,
   111  		},
   112  		{
   113  			// there is no root mount
   114  			name: "no-root-mount",
   115  			content: `76 62 8:1 / /boot rw,relatime shared:29 - ext4 /dev/sda1 rw,seclabel,data=ordered
   116  78 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel
   117  80 62 0:42 / /var/lib/nfs/rpc_pipefs rw,relatime shared:31 - rpc_pipefs sunrpc rw
   118  227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
   119  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
   120  `,
   121  		},
   122  	}
   123  	for _, test := range errorTests {
   124  		tempDir, filename, err := writeFile(test.content)
   125  		if err != nil {
   126  			t.Fatalf("cannot create temporary file: %v", err)
   127  		}
   128  		defer os.RemoveAll(tempDir)
   129  
   130  		_, err = isShared("/", filename)
   131  		if err == nil {
   132  			t.Errorf("test %q: expected error, got none", test.name)
   133  		}
   134  	}
   135  }
   136  
   137  func TestGetSELinuxSupport(t *testing.T) {
   138  	info :=
   139  		`62 0 253:0 / / rw,relatime shared:1 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
   140  78 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel
   141  83 63 0:44 / /var/lib/bar rw,relatime - tmpfs tmpfs rw
   142  227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
   143  150 23 1:58 / /media/nfs_vol rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223
   144  `
   145  	tempDir, filename, err := writeFile(info)
   146  	if err != nil {
   147  		t.Fatalf("cannot create temporary file: %v", err)
   148  	}
   149  	defer os.RemoveAll(tempDir)
   150  
   151  	tests := []struct {
   152  		name           string
   153  		mountPoint     string
   154  		selinuxEnabled bool
   155  		expectedResult bool
   156  	}{
   157  		{
   158  			"ext4 on / with disabled SELinux",
   159  			"/",
   160  			false,
   161  			false,
   162  		},
   163  		{
   164  			"ext4 on /",
   165  			"/",
   166  			true,
   167  			true,
   168  		},
   169  		{
   170  			"tmpfs on /var/lib/bar",
   171  			"/var/lib/bar",
   172  			true,
   173  			false,
   174  		},
   175  		{
   176  			"nfsv4",
   177  			"/media/nfs_vol",
   178  			true,
   179  			false,
   180  		},
   181  	}
   182  
   183  	for _, test := range tests {
   184  		out, err := GetSELinux(test.mountPoint, filename, func() bool { return test.selinuxEnabled })
   185  		if err != nil {
   186  			t.Errorf("Test %s failed with error: %s", test.name, err)
   187  		}
   188  		if test.expectedResult != out {
   189  			t.Errorf("Test %s failed: expected %v, got %v", test.name, test.expectedResult, out)
   190  		}
   191  	}
   192  }
   193  
   194  func writeFile(content string) (string, string, error) {
   195  	tempDir, err := os.MkdirTemp("", "mounter_shared_test")
   196  	if err != nil {
   197  		return "", "", err
   198  	}
   199  	filename := filepath.Join(tempDir, "mountinfo")
   200  	err = os.WriteFile(filename, []byte(content), 0600)
   201  	if err != nil {
   202  		os.RemoveAll(tempDir)
   203  		return "", "", err
   204  	}
   205  	return tempDir, filename, nil
   206  }
   207  
   208  func TestGetSELinuxMountContext(t *testing.T) {
   209  	info :=
   210  		`840 60 8:0 / /var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv rw,relatime shared:421 - ext4 /dev/sda rw,context="system_u:object_r:container_file_t:s0:c314,c894"
   211  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
   212  82 62 0:43 / /var/lib/foo rw,relatime shared:32 - tmpfs tmpfs rw
   213  83 63 0:44 / /var/lib/bar rw,relatime - tmpfs tmpfs rw
   214  `
   215  	tempDir, filename, err := writeFile(info)
   216  	if err != nil {
   217  		t.Fatalf("cannot create temporary file: %v", err)
   218  	}
   219  	defer os.RemoveAll(tempDir)
   220  
   221  	tests := []struct {
   222  		name            string
   223  		mountPoint      string
   224  		seLinuxEnabled  bool
   225  		expectedContext string
   226  	}{
   227  		{
   228  			"no context",
   229  			"/var/lib/foo",
   230  			true,
   231  			"",
   232  		},
   233  		{
   234  			"with context with SELinux",
   235  			"/var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv",
   236  			true,
   237  			"system_u:object_r:container_file_t:s0:c314,c894",
   238  		},
   239  		{
   240  			"with context with no SELinux",
   241  			"/var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv",
   242  			false,
   243  			"",
   244  		},
   245  		{
   246  			"no context with seclabel",
   247  			"/var/lib/docker/devicemapper/test/shared",
   248  			true,
   249  			"",
   250  		},
   251  	}
   252  
   253  	for _, test := range tests {
   254  		out, err := getSELinuxMountContext(test.mountPoint, filename, func() bool { return test.seLinuxEnabled })
   255  		if err != nil {
   256  			t.Errorf("Test %s failed with error: %s", test.name, err)
   257  		}
   258  		if test.expectedContext != out {
   259  			t.Errorf("Test %s failed: expected %v, got %v", test.name, test.expectedContext, out)
   260  		}
   261  	}
   262  
   263  }
   264  

View as plain text