From bc8f010a102e6b923ea489c27ed2b7e63fa87c6d Mon Sep 17 00:00:00 2001 From: Paul Morie Date: Wed, 22 Apr 2015 10:48:23 -0400 Subject: [PATCH] Make secret volume plugin idempotent --- pkg/volume/git_repo/git_repo.go | 38 +++----------------- pkg/volume/secret/secret.go | 11 ++++++ pkg/volume/util/doc.go | 18 ++++++++++ pkg/volume/util/util.go | 62 +++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 34 deletions(-) create mode 100644 pkg/volume/util/doc.go create mode 100644 pkg/volume/util/util.go diff --git a/pkg/volume/git_repo/git_repo.go b/pkg/volume/git_repo/git_repo.go index a55d6b0df12..24c463819df 100644 --- a/pkg/volume/git_repo/git_repo.go +++ b/pkg/volume/git_repo/git_repo.go @@ -19,7 +19,6 @@ package git_repo import ( "fmt" "io/ioutil" - "os" "path" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" @@ -27,7 +26,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec" "github.com/GoogleCloudPlatform/kubernetes/pkg/volume" - "github.com/golang/glog" + volumeutil "github.com/GoogleCloudPlatform/kubernetes/pkg/volume/util" ) // This is the primary entrypoint for volume plugins. @@ -123,7 +122,7 @@ var wrappedVolumeSpec = &volume.Spec{ // SetUpAt creates new directory and clones a git repo. func (gr *gitRepo) SetUpAt(dir string) error { - if gr.isReady() { + if volumeutil.IsReady(gr.getMetaDir()) { return nil } if gr.legacyMode { @@ -152,7 +151,7 @@ func (gr *gitRepo) SetUpAt(dir string) error { } if len(gr.revision) == 0 { // Done! - gr.setReady() + volumeutil.SetReady(gr.getMetaDir()) return nil } @@ -164,7 +163,7 @@ func (gr *gitRepo) SetUpAt(dir string) error { return fmt.Errorf("failed to exec 'git reset --hard': %s: %v", output, err) } - gr.setReady() + volumeutil.SetReady(gr.getMetaDir()) return nil } @@ -172,35 +171,6 @@ func (gr *gitRepo) getMetaDir() string { return path.Join(gr.plugin.host.GetPodPluginDir(gr.podRef.UID, util.EscapeQualifiedNameForDisk(gitRepoPluginName)), gr.volName) } -func (gr *gitRepo) isReady() bool { - metaDir := gr.getMetaDir() - readyFile := path.Join(metaDir, "ready") - s, err := os.Stat(readyFile) - if err != nil { - return false - } - if !s.Mode().IsRegular() { - glog.Errorf("GitRepo ready-file is not a file: %s", readyFile) - return false - } - return true -} - -func (gr *gitRepo) setReady() { - metaDir := gr.getMetaDir() - if err := os.MkdirAll(metaDir, 0750); err != nil && !os.IsExist(err) { - glog.Errorf("Can't mkdir %s: %v", metaDir, err) - return - } - readyFile := path.Join(metaDir, "ready") - file, err := os.Create(readyFile) - if err != nil { - glog.Errorf("Can't touch %s: %v", readyFile, err) - return - } - file.Close() -} - func (gr *gitRepo) execCommand(command string, args []string, dir string) ([]byte, error) { cmd := gr.exec.Command(command, args...) cmd.SetDir(dir) diff --git a/pkg/volume/secret/secret.go b/pkg/volume/secret/secret.go index 54b3385012f..32c23781bf2 100644 --- a/pkg/volume/secret/secret.go +++ b/pkg/volume/secret/secret.go @@ -25,6 +25,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/volume" + volumeutil "github.com/GoogleCloudPlatform/kubernetes/pkg/volume/util" "github.com/golang/glog" ) @@ -91,6 +92,10 @@ var wrappedVolumeSpec = &volume.Spec{ } func (sv *secretVolume) SetUpAt(dir string) error { + if volumeutil.IsReady(sv.getMetaDir()) { + return nil + } + glog.V(3).Infof("Setting up volume %v for pod %v at %v", sv.volName, sv.podRef.UID, dir) // Wrap EmptyDir, let it do the setup. @@ -130,6 +135,8 @@ func (sv *secretVolume) SetUpAt(dir string) error { } } + volumeutil.SetReady(sv.getMetaDir()) + return nil } @@ -160,3 +167,7 @@ func (sv *secretVolume) TearDownAt(dir string) error { } return wrapped.TearDownAt(dir) } + +func (sv *secretVolume) getMetaDir() string { + return path.Join(sv.plugin.host.GetPodPluginDir(sv.podRef.UID, util.EscapeQualifiedNameForDisk(secretPluginName)), sv.volName) +} diff --git a/pkg/volume/util/doc.go b/pkg/volume/util/doc.go new file mode 100644 index 00000000000..2bf31e8532d --- /dev/null +++ b/pkg/volume/util/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Contains utility code for use by volume plugins. +package util diff --git a/pkg/volume/util/util.go b/pkg/volume/util/util.go new file mode 100644 index 00000000000..24523a87413 --- /dev/null +++ b/pkg/volume/util/util.go @@ -0,0 +1,62 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "os" + "path" + + "github.com/golang/glog" +) + +const readyFileName = "ready" + +// IsReady checks for the existence of a regular file +// called 'ready' in the given directory and returns +// true if that file exists. +func IsReady(dir string) bool { + readyFile := path.Join(dir, readyFileName) + s, err := os.Stat(readyFile) + if err != nil { + return false + } + + if !s.Mode().IsRegular() { + glog.Errorf("ready-file is not a file: %s", readyFile) + return false + } + + return true +} + +// SetReady creates a file called 'ready' in the given +// directory. It logs an error if the file cannot be +// created. +func SetReady(dir string) { + if err := os.MkdirAll(dir, 0750); err != nil && !os.IsExist(err) { + glog.Errorf("Can't mkdir %s: %v", dir, err) + return + } + + readyFile := path.Join(dir, readyFileName) + file, err := os.Create(readyFile) + if err != nil { + glog.Errorf("Can't touch %s: %v", readyFile, err) + return + } + file.Close() +}