From dfc9cb86f014b59d1800c3015ecdb781e897fded Mon Sep 17 00:00:00 2001 From: Danny Jones Date: Fri, 25 Jul 2014 13:16:59 -0700 Subject: [PATCH] Initial reconciliation loop. Determines the set of active volumes versus the set of valid volumes defined by the manifests. If there is an active volume that is not defined in any of the manifests, deletes and cleans up that volume. --- pkg/kubelet/kubelet.go | 49 ++++++++++++++++++++++++++++++++++++++++++ pkg/volume/volume.go | 10 ++++----- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 6729fb15afc..84f5f03d53d 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -21,6 +21,8 @@ import ( "errors" "fmt" "net/http" + "os" + "path/filepath" "strconv" "strings" "sync" @@ -449,6 +451,52 @@ type podContainer struct { containerName string } +func determineValidVolumes(pods []Pod) map[string]api.Volume { + validVolumes := make(map[string]api.Volume) + for _, pod := range pods { + for _, volume := range pod.Manifest.Volumes { + identifier := pod.Manifest.ID + volume.Name + validVolumes[identifier] = volume + } + } + return validVolumes +} + +func (kl *Kubelet) determineActiveVolumes() map[string]volume.Interface { + activeVolumes := make(map[string]volume.Interface) + filepath.Walk(kl.rootDirectory, func(path string, info os.FileInfo, err error) error { + var name string + var podID string + dir := getDir(path) + glog.Infof("Traversing filepath %s", path) + if dir == "empty" { + name = info.Name() + podID = getDir(filepath.Dir(filepath.Dir(path))) + glog.Infof("Adding active volume %s of pod %s", name, podID) + activeVolumes[podID+name] = &volume.EmptyDirectory{name, podID, kl.rootDirectory} + } + return nil + }) + return activeVolumes +} + +func getDir(path string) string { + return filepath.Base(filepath.Dir(path)) +} + +func (kl *Kubelet) reconcileVolumes(pods []Pod) error { + validVolumes := determineValidVolumes(pods) + activeVolumes := kl.determineActiveVolumes() + glog.Infof("ValidVolumes: %v \n ActiveVolumes: %v", validVolumes, activeVolumes) + for name, volume := range activeVolumes { + if _, ok := validVolumes[name]; !ok { + glog.Infof("Volume found with no respective pod, tearing down volume %s", name) + volume.TearDown() + } + } + return nil +} + // SyncPods synchronizes the configured list of pods (desired state) with the host current state. func (kl *Kubelet) SyncPods(pods []Pod) error { glog.Infof("Desired [%s]: %+v", kl.hostname, pods) @@ -480,6 +528,7 @@ func (kl *Kubelet) SyncPods(pods []Pod) error { } }) } + kl.reconcileVolumes(pods) // Kill any containers we don't need existingContainers, err := getKubeletDockerContainers(kl.dockerClient) diff --git a/pkg/volume/volume.go b/pkg/volume/volume.go index 0675d33160a..1cdd58e782d 100644 --- a/pkg/volume/volume.go +++ b/pkg/volume/volume.go @@ -80,7 +80,7 @@ func (emptyDir *EmptyDirectory) SetUp() error { // TODO(jonesdl) when we can properly invoke TearDown(), we should delete // the directory created by SetUp. func (emptyDir *EmptyDirectory) TearDown() error { - return nil + return os.RemoveAll(emptyDir.GetPath()) } func (emptyDir *EmptyDirectory) GetPath() string { @@ -88,12 +88,12 @@ func (emptyDir *EmptyDirectory) GetPath() string { } // Interprets API volume as a HostDirectory -func createHostDirectory(volume *api.Volume) *HostDirectory { +func CreateHostDirectory(volume *api.Volume) *HostDirectory { return &HostDirectory{volume.Source.HostDirectory.Path} } // Interprets API volume as an EmptyDirectory -func createEmptyDirectory(volume *api.Volume, podID string, rootDir string) *EmptyDirectory { +func CreateEmptyDirectory(volume *api.Volume, podID string, rootDir string) *EmptyDirectory { return &EmptyDirectory{volume.Name, podID, rootDir} } @@ -110,9 +110,9 @@ func CreateVolume(volume *api.Volume, podID string, rootDir string) (Interface, // TODO(jonesdl) We should probably not check every pointer and directly // resolve these types instead. if source.HostDirectory != nil { - vol = createHostDirectory(volume) + vol = CreateHostDirectory(volume) } else if source.EmptyDirectory != nil { - vol = createEmptyDirectory(volume, podID, rootDir) + vol = CreateEmptyDirectory(volume, podID, rootDir) } else { return nil, ErrUnsupportedVolumeType }