Change:
Often observed in logs: However: Which probably means we'd be ok unmounting it: This probably also means we don't delete orphaned mirror pods, which is the next step in SyncPods ().

Discussion:
return desiredVolumes } <del> func (kl *Kubelet) cleanupOrphanedPodDirs(pods []*api.Pod) error { desired := util.NewStringSet() </del> <ins> // cleanupOrphanedPodDirs removes a pod directory if the pod is not in the // desired set of pods and there is no running containers in the pod. func (kl *Kubelet) cleanupOrphanedPodDirs(pods []*api.Pod, runningPods []*kubecontainer.Pod) error { active := util.NewStringSet() </ins> for _, pod := range pods { <del> desired.Insert(string(pod.UID)) </del> <ins> active.Insert(string(pod.UID)) </ins> } <ins> for _, pod := range runningPods { active.Insert(string(pod.ID)) } </ins> found, err := kl.listPodsFromDisk() if err != nil { return err } errlist := []error{} for i := range found { <del> if !desired.Has(string(found[i])) { </del> <ins> if !active.Has(string(found[i])) { </ins> glog.V(3).Infof("Orphaned pod %q found, removing", found[i]) if err := os.RemoveAll(kl.getPodDir(found[i])); err != nil { errlist = append(errlist, err)

// Note that we pass all pods (including terminated pods) to the function, // so that we don't remove directories associated with terminated but not yet // deleted pods. <del> err = kl.cleanupOrphanedPodDirs(allPods) </del> <ins> err = kl.cleanupOrphanedPodDirs(allPods, runningPods) </ins> if err != nil { glog.Errorf("Failed cleaning up orphaned pod directories: %v", err) return err

} } <ins> func syncAndVerifyPodDir(t *testing.T, testKubelet *TestKubelet, pods []*api.Pod, podsToCheck []*api.Pod, shouldExist bool) { kl := testKubelet.kubelet kl.podManager.SetPods(pods) kl.HandlePodSyncs(pods) kl.HandlePodCleanups() for i, pod := range podsToCheck { exist := dirExists(kl.getPodDir(pod.UID)) if shouldExist && !exist { t.Errorf("expected directory to exist for pod %d", i) } else if !shouldExist && exist { t.Errorf("expected directory to be removed for pod %d", i) } } } </ins> func TestDoesNotDeletePodDirsForTerminatedPods(t *testing.T) { testKubelet := newTestKubelet(t) testKubelet.fakeCadvisor.On("MachineInfo").Return(&cadvisorApi.MachineInfo{}, nil)

}, } <del> kl.podManager.SetPods(pods) // Sync to create pod directories. kl.HandlePodSyncs(pods) for i := range pods { if !dirExists(kl.getPodDir(pods[i].UID)) { t.Errorf("expected directory to exist for pod %d", i) } } </del> <ins> syncAndVerifyPodDir(t, testKubelet, pods, pods, true) </ins> // Pod 1 failed, and pod 2 succeeded. None of the pod directories should be // deleted. kl.statusManager.SetPodStatus(pods[1], api.PodStatus{Phase: api.PodFailed}) kl.statusManager.SetPodStatus(pods[2], api.PodStatus{Phase: api.PodSucceeded}) <del> kl.HandlePodCleanups() for i := range pods { if !dirExists(kl.getPodDir(pods[i].UID)) { t.Errorf("expected directory to exist for pod %d", i) } </del> <ins> syncAndVerifyPodDir(t, testKubelet, pods, pods, true) } func TestDoesNotDeletePodDirsIfContainerIsRunning(t *testing.T) { testKubelet := newTestKubelet(t) testKubelet.fakeCadvisor.On("MachineInfo").Return(&cadvisorApi.MachineInfo{}, nil) testKubelet.fakeCadvisor.On("DockerImagesFsInfo").Return(cadvisorApiv2.FsInfo{}, nil) testKubelet.fakeCadvisor.On("RootFsInfo").Return(cadvisorApiv2.FsInfo{}, nil) runningPod := &kubecontainer.Pod{ ID:        "12345678", Name:      "pod1", Namespace: "ns", </ins> } <ins> apiPod := &api.Pod{ ObjectMeta: api.ObjectMeta{ UID:       runningPod.ID, Name:      runningPod.Name, Namespace: runningPod.Namespace, }, } // Sync once to create pod directory; confirm that the pod directory has // already been created. pods := []*api.Pod{apiPod} syncAndVerifyPodDir(t, testKubelet, pods, []*api.Pod{apiPod}, true) // Pretend the pod is deleted from apiserver, but is still active on the node. // The pod directory should not be removed. pods = []*api.Pod{} testKubelet.fakeRuntime.PodList = []*kubecontainer.Pod{runningPod} syncAndVerifyPodDir(t, testKubelet, pods, []*api.Pod{apiPod}, true) // The pod is deleted and also not active on the node. The pod directory // should be removed. pods = []*api.Pod{} testKubelet.fakeRuntime.PodList = []*kubecontainer.Pod{} syncAndVerifyPodDir(t, testKubelet, pods, []*api.Pod{apiPod}, false) </ins> }