From 523a80bec71533ba6521870c244eb2a0acb1d32d Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 29 Nov 2014 11:02:28 -0800 Subject: [PATCH] Apply more structure to pod data dirs This is makes it possible to read back "known" pods from disk without getting other (non-pod) kubelet dirs in the mix. Ditto for containers within a pod. This is just saner overall. Pods now nest in a pods/ dir. Likewise containers. --- pkg/kubelet/kubelet.go | 48 +++++++++++++++-- pkg/kubelet/kubelet_test.go | 100 ++++++++++++++++++++++++++++++++++-- 2 files changed, 139 insertions(+), 9 deletions(-) diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index cfc7813ac8..a332e97328 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -170,16 +170,30 @@ func (kl *Kubelet) GetRootDir() string { // GetPodsDir returns the full path to the directory under which pod // directories are created. -// TODO(thockin): For now, this is the same as the root because that is assumed -// in other code. Will fix. func (kl *Kubelet) GetPodsDir() string { - return kl.GetRootDir() + return path.Join(kl.GetRootDir(), "pods") } // GetPodDir returns the full path to the per-pod data directory for the // specified pod. This directory may not exist if the pod does not exist. func (kl *Kubelet) GetPodDir(podUID string) string { - return path.Join(kl.GetRootDir(), podUID) + // Backwards compat. The "old" stuff should be removed before 1.0 + // release. The thinking here is this: + // !old && !new = use new + // !old && new = use new + // old && !new = use old + // old && new = use new (but warn) + oldPath := path.Join(kl.GetRootDir(), podUID) + oldExists := dirExists(oldPath) + newPath := path.Join(kl.GetPodsDir(), podUID) + newExists := dirExists(newPath) + if oldExists && !newExists { + return oldPath + } + if oldExists { + glog.Warningf("Data dir for pod %q exists in both old and new form, using new", podUID) + } + return newPath } // GetPodVolumesDir returns the full path to the per-pod data directory under @@ -193,7 +207,31 @@ func (kl *Kubelet) GetPodVolumesDir(podUID string) string { // which container data is held for the specified pod. This directory may not // exist if the pod or container does not exist. func (kl *Kubelet) GetPodContainerDir(podUID, ctrName string) string { - return path.Join(kl.GetPodDir(podUID), ctrName) + // Backwards compat. The "old" stuff should be removed before 1.0 + // release. The thinking here is this: + // !old && !new = use new + // !old && new = use new + // old && !new = use old + // old && new = use new (but warn) + oldPath := path.Join(kl.GetPodDir(podUID), ctrName) + oldExists := dirExists(oldPath) + newPath := path.Join(kl.GetPodDir(podUID), "containers", ctrName) + newExists := dirExists(newPath) + if oldExists && !newExists { + return oldPath + } + if oldExists { + glog.Warningf("Data dir for pod %q, container %q exists in both old and new form, using new", podUID, ctrName) + } + return newPath +} + +func dirExists(path string) bool { + s, err := os.Stat(path) + if err != nil { + return false + } + return s.IsDir() } type ByCreated []*docker.Container diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 5880f3dba4..d23b9e9778 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -98,25 +98,117 @@ func TestKubeletDirs(t *testing.T) { var exp, got string got = kubelet.GetPodsDir() - exp = root + exp = path.Join(root, "pods") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.GetPodDir("abc123") - exp = path.Join(root, "abc123") + exp = path.Join(root, "pods/abc123") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.GetPodVolumesDir("abc123") - exp = path.Join(root, "abc123/volumes") + exp = path.Join(root, "pods/abc123/volumes") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.GetPodContainerDir("abc123", "def456") - exp = path.Join(root, "abc123/def456") + exp = path.Join(root, "pods/abc123/containers/def456") + if got != exp { + t.Errorf("expected %q', got %q", exp, got) + } +} + +func TestKubeletDirsCompat(t *testing.T) { + kubelet, _, _ := newTestKubelet(t) + root := kubelet.rootDirectory + if err := os.MkdirAll(root, 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + + var exp, got string + + // Old-style pod dir. + if err := os.MkdirAll(fmt.Sprintf("%s/oldpod", root), 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + // New-style pod dir. + if err := os.MkdirAll(fmt.Sprintf("%s/pods/newpod", root), 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + // Both-style pod dir. + if err := os.MkdirAll(fmt.Sprintf("%s/bothpod", root), 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + if err := os.MkdirAll(fmt.Sprintf("%s/pods/bothpod", root), 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + + got = kubelet.GetPodDir("oldpod") + exp = path.Join(root, "oldpod") + if got != exp { + t.Errorf("expected %q', got %q", exp, got) + } + + got = kubelet.GetPodDir("newpod") + exp = path.Join(root, "pods/newpod") + if got != exp { + t.Errorf("expected %q', got %q", exp, got) + } + + got = kubelet.GetPodDir("bothpod") + exp = path.Join(root, "pods/bothpod") + if got != exp { + t.Errorf("expected %q', got %q", exp, got) + } + + got = kubelet.GetPodDir("neitherpod") + exp = path.Join(root, "pods/neitherpod") + if got != exp { + t.Errorf("expected %q', got %q", exp, got) + } + + root = kubelet.GetPodDir("newpod") + + // Old-style container dir. + if err := os.MkdirAll(fmt.Sprintf("%s/oldctr", root), 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + // New-style container dir. + if err := os.MkdirAll(fmt.Sprintf("%s/containers/newctr", root), 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + // Both-style container dir. + if err := os.MkdirAll(fmt.Sprintf("%s/bothctr", root), 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + if err := os.MkdirAll(fmt.Sprintf("%s/containers/bothctr", root), 0750); err != nil { + t.Fatalf("can't mkdir(%q): %s", root, err) + } + + got = kubelet.GetPodContainerDir("newpod", "oldctr") + exp = path.Join(root, "oldctr") + if got != exp { + t.Errorf("expected %q', got %q", exp, got) + } + + got = kubelet.GetPodContainerDir("newpod", "newctr") + exp = path.Join(root, "containers/newctr") + if got != exp { + t.Errorf("expected %q', got %q", exp, got) + } + + got = kubelet.GetPodContainerDir("newpod", "bothctr") + exp = path.Join(root, "containers/bothctr") + if got != exp { + t.Errorf("expected %q', got %q", exp, got) + } + + got = kubelet.GetPodContainerDir("newpod", "neitherctr") + exp = path.Join(root, "containers/neitherctr") if got != exp { t.Errorf("expected %q', got %q", exp, got) }