diff --git a/pkg/kubelet/userns/userns_manager.go b/pkg/kubelet/userns/userns_manager.go index 95b08184c95..8e333de7905 100644 --- a/pkg/kubelet/userns/userns_manager.go +++ b/pkg/kubelet/userns/userns_manager.go @@ -96,7 +96,7 @@ func (m *UsernsManager) writeMappingsToFile(pod types.UID, userNs userNamespace) fstore, err := utilstore.NewFileStore(dir, &utilfs.DefaultFs{}) if err != nil { - return err + return fmt.Errorf("create user namespace store: %w", err) } if err := fstore.Write(mappingsFile, data); err != nil { return err @@ -123,7 +123,7 @@ func (m *UsernsManager) readMappingsFromFile(pod types.UID) ([]byte, error) { dir := m.kl.GetPodDir(pod) fstore, err := utilstore.NewFileStore(dir, &utilfs.DefaultFs{}) if err != nil { - return nil, err + return nil, fmt.Errorf("create user namespace store: %w", err) } return fstore.Read(mappingsFile) } @@ -151,13 +151,13 @@ func MakeUserNsManager(kl userNsPodsManager) (*UsernsManager, error) { if os.IsNotExist(err) { return &m, nil } - return nil, fmt.Errorf("user namespace manager can't read pods from disk: %w", err) + return nil, fmt.Errorf("read pods from disk: %w", err) } for _, podUID := range found { klog.V(5).InfoS("reading pod from disk for user namespace", "podUID", podUID) if err := m.recordPodMappings(podUID); err != nil { - return nil, err + return nil, fmt.Errorf("record pod mappings: %w", err) } } @@ -308,7 +308,7 @@ func (m *UsernsManager) releaseWithLock(pod types.UID) { func (m *UsernsManager) parseUserNsFileAndRecord(pod types.UID, content []byte) (userNs userNamespace, err error) { if err = json.Unmarshal([]byte(content), &userNs); err != nil { - err = fmt.Errorf("can't parse file: %w", err) + err = fmt.Errorf("invalid user namespace mappings file: %w", err) return } diff --git a/pkg/kubelet/userns/userns_manager_test.go b/pkg/kubelet/userns/userns_manager_test.go index d2156dd4c6d..cf23967405d 100644 --- a/pkg/kubelet/userns/userns_manager_test.go +++ b/pkg/kubelet/userns/userns_manager_test.go @@ -18,6 +18,7 @@ package userns import ( "fmt" + "os" "testing" "github.com/stretchr/testify/assert" @@ -297,6 +298,7 @@ func TestCleanupOrphanedPodUsernsAllocations(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { testUserNsPodsManager := &testUserNsPodsManager{ + podDir: t.TempDir(), podList: tc.listPods, } m, err := MakeUserNsManager(testUserNsPodsManager) @@ -359,3 +361,38 @@ func TestRecordMaxPods(t *testing.T) { err = m.record(types.UID(fmt.Sprintf("%d", maxPods+1)), uint32((maxPods+1)*65536), 65536) assert.Error(t, err) } + +type failingUserNsPodsManager struct { + testUserNsPodsManager +} + +func (m *failingUserNsPodsManager) ListPodsFromDisk() ([]types.UID, error) { + return nil, os.ErrPermission +} + +func TestMakeUserNsManagerFailsListPod(t *testing.T) { + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.UserNamespacesSupport, true)() + + testUserNsPodsManager := &failingUserNsPodsManager{} + _, err := MakeUserNsManager(testUserNsPodsManager) + assert.Error(t, err) + assert.ErrorContains(t, err, "read pods from disk") +} + +func TestMakeUserNsManagerFailsPodRecord(t *testing.T) { + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.UserNamespacesSupport, true)() + + testUserNsPodsManager := &testUserNsPodsManager{ + podList: []types.UID{"pod-1", "pod-2"}, + podDir: t.TempDir(), + } + + // Remove read/execute permissions from this directory. + if err := os.Chmod(testUserNsPodsManager.podDir, 0222); err != nil { + t.Fatal(err) + } + + _, err := MakeUserNsManager(testUserNsPodsManager) + assert.Error(t, err) + assert.ErrorContains(t, err, "record pod mappings") +}