From c0d49450e48723b4c38a688c7c9c76bffc2a54d2 Mon Sep 17 00:00:00 2001 From: harry Date: Thu, 10 Dec 2015 18:07:17 +0800 Subject: [PATCH] Fix volume wrapper doesn't have name Integration test --- cmd/integration/integration.go | 91 +++++++++++++++++++++- pkg/volume/downwardapi/downwardapi.go | 26 ++++--- pkg/volume/downwardapi/downwardapi_test.go | 42 +++++++--- pkg/volume/git_repo/git_repo.go | 31 ++++---- pkg/volume/git_repo/git_repo_test.go | 26 +++++-- pkg/volume/secret/secret.go | 39 +++++++--- pkg/volume/secret/secret_test.go | 20 +++-- pkg/volume/volume.go | 24 ++++++ 8 files changed, 234 insertions(+), 65 deletions(-) diff --git a/cmd/integration/integration.go b/cmd/integration/integration.go index ca5804a6751..b6d5d693b13 100644 --- a/cmd/integration/integration.go +++ b/cmd/integration/integration.go @@ -55,7 +55,10 @@ import ( "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/wait" + "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/empty_dir" + "k8s.io/kubernetes/pkg/volume/git_repo" + "k8s.io/kubernetes/pkg/volume/secret" "k8s.io/kubernetes/plugin/pkg/scheduler" _ "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider" "k8s.io/kubernetes/plugin/pkg/scheduler/factory" @@ -211,7 +214,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string 10250, /* KubeletPort */ 0, /* ReadOnlyPort */ api.NamespaceDefault, - empty_dir.ProbeVolumePlugins(), + probeVolumePlugins(), nil, cadvisorInterface, configFilePath, @@ -244,7 +247,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string 10251, /* KubeletPort */ 0, /* ReadOnlyPort */ api.NamespaceDefault, - empty_dir.ProbeVolumePlugins(), + probeVolumePlugins(), nil, cadvisorInterface, "", @@ -265,6 +268,16 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string return apiServer.URL, configFilePath } +// The list of plugins to probe in this test +func probeVolumePlugins() []volume.VolumePlugin { + allPlugins := []volume.VolumePlugin{} + + allPlugins = append(allPlugins, empty_dir.ProbeVolumePlugins()...) + allPlugins = append(allPlugins, git_repo.ProbeVolumePlugins()...) + allPlugins = append(allPlugins, secret.ProbeVolumePlugins()...) + return allPlugins +} + func makeTempDirOrDie(prefix string, baseDir string) string { if baseDir == "" { baseDir = "/tmp" @@ -989,6 +1002,7 @@ func main() { runServiceTest, runAPIVersionsTest, runMasterServiceTest, + runWrapperVolumesPluginsTest, func(c *client.Client) { runSelfLinkTestOnNamespace(c, api.NamespaceDefault) runSelfLinkTestOnNamespace(c, "other") @@ -1038,8 +1052,8 @@ func main() { // 1 pod infra container + 1 container from the service test. // The total number of container created is 9 - if len(createdConts) != 12 { - glog.Fatalf("Expected 12 containers; got %v\n\nlist of created containers:\n\n%#v\n\nDocker 1 Created:\n\n%#v\n\nDocker 2 Created:\n\n%#v\n\n", len(createdConts), createdConts.List(), fakeDocker1.Created, fakeDocker2.Created) + if len(createdConts) != 14 { + glog.Fatalf("Expected 14 containers; got %v\n\nlist of created containers:\n\n%#v\n\nDocker 1 Created:\n\n%#v\n\nDocker 2 Created:\n\n%#v\n\n", len(createdConts), createdConts.List(), fakeDocker1.Created, fakeDocker2.Created) } glog.Infof("OK - found created containers: %#v", createdConts.List()) @@ -1097,3 +1111,72 @@ const ( } }` ) + +// This is a test to make sure multiple empty_dir wrapper based volumes should not affect each other +func runWrapperVolumesPluginsTest(client *client.Client) { + // Make a secret object. + ns := api.NamespaceDefault + s := api.Secret{ + ObjectMeta: api.ObjectMeta{ + Name: "secret-name", + Namespace: ns, + }, + Data: map[string][]byte{ + "data": []byte("value1\n"), + }, + } + + if _, err := client.Secrets(s.Namespace).Create(&s); err != nil { + glog.Fatalf("unable to create test secret: %v", err) + } + + pod := &api.Pod{ + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "vol-container", + Image: "kubernetes/pause", + VolumeMounts: []api.VolumeMount{ + { + Name: "vol-secret", + MountPath: "/fake/path-1", + ReadOnly: true, + }, + { + Name: "vol-git", + MountPath: "/fake/path-2", + }, + }, + }, + }, + Volumes: []api.Volume{ + { + Name: "vol-secret", + VolumeSource: api.VolumeSource{ + Secret: &api.SecretVolumeSource{ + SecretName: "secret-name", + }, + }, + }, + { + Name: "vol-git", + VolumeSource: api.VolumeSource{ + GitRepo: &api.GitRepoVolumeSource{ + Repository: "https://github.com/kubernetes/kubedash", + }, + }, + }, + }, + }, + } + + pod.ObjectMeta.Name = "wrappedvolumes.foo" + foo, err := client.Pods(api.NamespaceDefault).Create(pod) + if err != nil { + glog.Fatalf("Failed to create pod: %v, %v", pod, err) + } + if err := wait.Poll(time.Second, longTestTimeout, podRunning(client, foo.Namespace, foo.Name)); err != nil { + glog.Fatalf("FAILED: pod never started running %v", err) + } + glog.Info("empty_dir wrapper based volumes doesn't affect each other: test passed.") +} diff --git a/pkg/volume/downwardapi/downwardapi.go b/pkg/volume/downwardapi/downwardapi.go index be71ab431c4..eb2602bfc90 100644 --- a/pkg/volume/downwardapi/downwardapi.go +++ b/pkg/volume/downwardapi/downwardapi.go @@ -66,10 +66,11 @@ func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { v := &downwardAPIVolume{ - volName: spec.Name(), - pod: pod, - podUID: pod.UID, - plugin: plugin, + volName: spec.Name(), + pod: pod, + podUID: pod.UID, + plugin: plugin, + wrappedVolumeSpec: volume.GetWrappedVolumeSpec(spec.Name(), downwardAPIPluginName), } v.fieldReferenceFileNames = make(map[string]string) for _, fileInfo := range spec.Volume.DownwardAPI.Items { @@ -81,7 +82,12 @@ func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opt } func (plugin *downwardAPIPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { - return &downwardAPIVolumeCleaner{&downwardAPIVolume{volName: volName, podUID: podUID, plugin: plugin}}, nil + return &downwardAPIVolumeCleaner{&downwardAPIVolume{ + volName: volName, + podUID: podUID, + plugin: plugin, + wrappedVolumeSpec: volume.GetWrappedVolumeSpec(volName, downwardAPIPluginName)}, + }, nil } // downwardAPIVolume retrieves downward API data and placing them into the volume on the host. @@ -92,11 +98,7 @@ type downwardAPIVolume struct { podUID types.UID // TODO: remove this redundancy as soon NewCleaner func will have *api.POD and not only types.UID plugin *downwardAPIPlugin volume.MetricsNil -} - -// This is the spec for the volume that this plugin wraps. -var wrappedVolumeSpec = &volume.Spec{ - Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}}}, + wrappedVolumeSpec *volume.Spec } // downwardAPIVolumeBuilder fetches info from downward API from the pod @@ -130,7 +132,7 @@ func (b *downwardAPIVolumeBuilder) SetUp() error { func (b *downwardAPIVolumeBuilder) SetUpAt(dir string) error { glog.V(3).Infof("Setting up a downwardAPI volume %v for pod %v/%v at %v", b.volName, b.pod.Namespace, b.pod.Name, dir) // Wrap EmptyDir. Here we rely on the idempotency of the wrapped plugin to avoid repeatedly mounting - wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, b.pod, *b.opts) + wrapped, err := b.plugin.host.NewWrapperBuilder(b.wrappedVolumeSpec, b.pod, *b.opts) if err != nil { glog.Errorf("Couldn't setup downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err @@ -364,7 +366,7 @@ func (c *downwardAPIVolumeCleaner) TearDownAt(dir string) error { glog.V(3).Infof("Tearing down volume %v for pod %v at %v", c.volName, c.podUID, dir) // Wrap EmptyDir, let it do the teardown. - wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID) + wrapped, err := c.plugin.host.NewWrapperCleaner(c.wrappedVolumeSpec, c.podUID) if err != nil { return err } diff --git a/pkg/volume/downwardapi/downwardapi_test.go b/pkg/volume/downwardapi/downwardapi_test.go index 6c2559e38d4..cec87886011 100644 --- a/pkg/volume/downwardapi/downwardapi_test.go +++ b/pkg/volume/downwardapi/downwardapi_test.go @@ -39,12 +39,12 @@ func formatMap(m map[string]string) (fmtstr string) { return } -func newTestHost(t *testing.T, client client.Interface, basePath string) volume.VolumeHost { +func newTestHost(t *testing.T, client client.Interface, basePath string) (string, volume.VolumeHost) { tempDir, err := ioutil.TempDir(basePath, "downwardApi_volume_test.") if err != nil { t.Fatalf("can't make a temp rootdir: %v", err) } - return volume.NewFakeVolumeHost(tempDir, client, empty_dir.ProbeVolumePlugins()) + return tempDir, volume.NewFakeVolumeHost(tempDir, client, empty_dir.ProbeVolumePlugins()) } func TestCanSupport(t *testing.T) { @@ -54,7 +54,8 @@ func TestCanSupport(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, nil, tmpDir)) + _, host := newTestHost(t, nil, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) if err != nil { @@ -110,7 +111,8 @@ func TestLabels(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir)) + rootDir, host := newTestHost(t, fake, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) volumeSpec := &api.Volume{ Name: testVolumeName, @@ -141,6 +143,17 @@ func TestLabels(t *testing.T) { t.Errorf("Failed to setup volume: %v", err) } + // gitRepo volume should create it's own empty wrapper path + podWrapperMetadataDir := fmt.Sprintf("%v/pods/%v/plugins/kubernetes.io~empty-dir/wrapped_%v", rootDir, testPodUID, testVolumeName) + + if _, err := os.Stat(podWrapperMetadataDir); err != nil { + if os.IsNotExist(err) { + t.Errorf("SetUp() failed, empty-dir wrapper path was not created: %s", podWrapperMetadataDir) + } else { + t.Errorf("SetUp() failed: %v", err) + } + } + var data []byte data, err = ioutil.ReadFile(path.Join(volumePath, "labels")) if err != nil { @@ -189,7 +202,8 @@ func TestAnnotations(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir)) + _, host := newTestHost(t, fake, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) if err != nil { t.Errorf("Can't find the plugin by name") @@ -254,7 +268,8 @@ func TestName(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir)) + _, host := newTestHost(t, fake, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) if err != nil { t.Errorf("Can't find the plugin by name") @@ -320,7 +335,8 @@ func TestNamespace(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir)) + _, host := newTestHost(t, fake, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) if err != nil { t.Errorf("Can't find the plugin by name") @@ -379,7 +395,8 @@ func TestWriteTwiceNoUpdate(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir)) + _, host := newTestHost(t, fake, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) volumeSpec := &api.Volume{ Name: testVolumeName, @@ -468,7 +485,8 @@ func TestWriteTwiceWithUpdate(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir)) + _, host := newTestHost(t, fake, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) volumeSpec := &api.Volume{ Name: testVolumeName, @@ -577,7 +595,8 @@ func TestWriteWithUnixPath(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir)) + _, host := newTestHost(t, fake, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) volumeSpec := &api.Volume{ Name: testVolumeName, @@ -656,7 +675,8 @@ func TestWriteWithUnixPathBadPath(t *testing.T) { } defer os.RemoveAll(tmpDir) pluginMgr := volume.VolumePluginMgr{} - pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir)) + _, host := newTestHost(t, fake, tmpDir) + pluginMgr.InitPlugins(ProbeVolumePlugins(), host) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) if err != nil { t.Errorf("Can't find the plugin by name") diff --git a/pkg/volume/git_repo/git_repo.go b/pkg/volume/git_repo/git_repo.go index cd6bd05c5a6..5c329eddac8 100644 --- a/pkg/volume/git_repo/git_repo.go +++ b/pkg/volume/git_repo/git_repo.go @@ -61,9 +61,10 @@ func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { return &gitRepoVolumeBuilder{ gitRepoVolume: &gitRepoVolume{ - volName: spec.Name(), - podUID: pod.UID, - plugin: plugin, + volName: spec.Name(), + podUID: pod.UID, + plugin: plugin, + wrappedVolumeSpec: volume.GetWrappedVolumeSpec(spec.Name(), gitRepoPluginName), }, pod: *pod, source: spec.Volume.GitRepo.Repository, @@ -77,9 +78,10 @@ func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts vo func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { return &gitRepoVolumeCleaner{ &gitRepoVolume{ - volName: volName, - podUID: podUID, - plugin: plugin, + volName: volName, + podUID: podUID, + plugin: plugin, + wrappedVolumeSpec: volume.GetWrappedVolumeSpec(volName, gitRepoPluginName), }, }, nil } @@ -87,9 +89,10 @@ func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID) (volum // gitRepo volumes are directories which are pre-filled from a git repository. // These do not persist beyond the lifetime of a pod. type gitRepoVolume struct { - volName string - podUID types.UID - plugin *gitRepoPlugin + volName string + podUID types.UID + plugin *gitRepoPlugin + wrappedVolumeSpec *volume.Spec volume.MetricsNil } @@ -128,11 +131,6 @@ func (b *gitRepoVolumeBuilder) SetUp() error { return b.SetUpAt(b.GetPath()) } -// This is the spec for the volume that this plugin wraps. -var wrappedVolumeSpec = &volume.Spec{ - Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}, -} - // SetUpAt creates new directory and clones a git repo. func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error { if volumeutil.IsReady(b.getMetaDir()) { @@ -140,7 +138,7 @@ func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error { } // Wrap EmptyDir, let it do the setup. - wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, b.opts) + wrapped, err := b.plugin.host.NewWrapperBuilder(b.wrappedVolumeSpec, &b.pod, b.opts) if err != nil { return err } @@ -218,8 +216,9 @@ func (c *gitRepoVolumeCleaner) TearDown() error { // TearDownAt simply deletes everything in the directory. func (c *gitRepoVolumeCleaner) TearDownAt(dir string) error { + // Wrap EmptyDir, let it do the teardown. - wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID) + wrapped, err := c.plugin.host.NewWrapperCleaner(c.wrappedVolumeSpec, c.podUID) if err != nil { return err } diff --git a/pkg/volume/git_repo/git_repo_test.go b/pkg/volume/git_repo/git_repo_test.go index e4c588d9dfa..d2deab7df92 100644 --- a/pkg/volume/git_repo/git_repo_test.go +++ b/pkg/volume/git_repo/git_repo_test.go @@ -32,17 +32,18 @@ import ( "k8s.io/kubernetes/pkg/volume/empty_dir" ) -func newTestHost(t *testing.T) volume.VolumeHost { +func newTestHost(t *testing.T) (string, volume.VolumeHost) { tempDir, err := ioutil.TempDir("/tmp", "git_repo_test.") if err != nil { t.Fatalf("can't make a temp rootdir: %v", err) } - return volume.NewFakeVolumeHost(tempDir, nil, empty_dir.ProbeVolumePlugins()) + return tempDir, volume.NewFakeVolumeHost(tempDir, nil, empty_dir.ProbeVolumePlugins()) } func TestCanSupport(t *testing.T) { plugMgr := volume.VolumePluginMgr{} - plugMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t)) + _, host := newTestHost(t) + plugMgr.InitPlugins(ProbeVolumePlugins(), host) plug, err := plugMgr.FindPluginByName("kubernetes.io/git-repo") if err != nil { @@ -218,7 +219,8 @@ func doTestPlugin(scenario struct { allErrs := []error{} plugMgr := volume.VolumePluginMgr{} - plugMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t)) + rootDir, host := newTestHost(t) + plugMgr.InitPlugins(ProbeVolumePlugins(), host) plug, err := plugMgr.FindPluginByName("kubernetes.io/git-repo") if err != nil { @@ -241,7 +243,8 @@ func doTestPlugin(scenario struct { } path := builder.GetPath() - if !strings.HasSuffix(path, "pods/poduid/volumes/kubernetes.io~git-repo/vol1") { + suffix := fmt.Sprintf("pods/poduid/volumes/kubernetes.io~git-repo/%v", scenario.vol.Name) + if !strings.HasSuffix(path, suffix) { allErrs = append(allErrs, fmt.Errorf("Got unexpected path: %s", path)) return allErrs @@ -263,6 +266,19 @@ func doTestPlugin(scenario struct { } } + // gitRepo volume should create it's own empty wrapper path + podWrapperMetadataDir := fmt.Sprintf("%v/pods/poduid/plugins/kubernetes.io~empty-dir/wrapped_%v", rootDir, scenario.vol.Name) + + if _, err := os.Stat(podWrapperMetadataDir); err != nil { + if os.IsNotExist(err) { + allErrs = append(allErrs, + fmt.Errorf("SetUp() failed, empty-dir wrapper path is not created: %s", podWrapperMetadataDir)) + } else { + allErrs = append(allErrs, + fmt.Errorf("SetUp() failed: %v", err)) + } + } + cleaner, err := plug.NewCleaner("vol1", types.UID("poduid")) if err != nil { allErrs = append(allErrs, diff --git a/pkg/volume/secret/secret.go b/pkg/volume/secret/secret.go index 2bb426d3c60..5a9ed5b8908 100644 --- a/pkg/volume/secret/secret.go +++ b/pkg/volume/secret/secret.go @@ -62,14 +62,33 @@ func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { return &secretVolumeBuilder{ - secretVolume: &secretVolume{spec.Name(), pod.UID, plugin, plugin.host.GetMounter(), plugin.host.GetWriter(), volume.MetricsNil{}}, - secretName: spec.Volume.Secret.SecretName, - pod: *pod, - opts: &opts}, nil + secretVolume: &secretVolume{ + spec.Name(), + pod.UID, + plugin, + plugin.host.GetMounter(), + plugin.host.GetWriter(), + volume.MetricsNil{}, + volume.GetWrappedVolumeSpec(spec.Name(), secretPluginName), + }, + secretName: spec.Volume.Secret.SecretName, + pod: *pod, + opts: &opts, + }, nil } func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { - return &secretVolumeCleaner{&secretVolume{volName, podUID, plugin, plugin.host.GetMounter(), plugin.host.GetWriter(), volume.MetricsNil{}}}, nil + return &secretVolumeCleaner{ + &secretVolume{ + volName, + podUID, + plugin, + plugin.host.GetMounter(), + plugin.host.GetWriter(), + volume.MetricsNil{}, + volume.GetWrappedVolumeSpec(volName, secretPluginName), + }, + }, nil } type secretVolume struct { @@ -79,6 +98,7 @@ type secretVolume struct { mounter mount.Interface writer ioutil.Writer volume.MetricsNil + wrappedVolumeSpec *volume.Spec } var _ volume.Volume = &secretVolume{} @@ -111,11 +131,6 @@ func (b *secretVolumeBuilder) SetUp() error { return b.SetUpAt(b.GetPath()) } -// This is the spec for the volume that this plugin wraps. -var wrappedVolumeSpec = &volume.Spec{ - Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}}}, -} - func (b *secretVolumeBuilder) getMetaDir() string { return path.Join(b.plugin.host.GetPodPluginDir(b.podUID, util.EscapeQualifiedNameForDisk(secretPluginName)), b.volName) } @@ -137,7 +152,7 @@ func (b *secretVolumeBuilder) SetUpAt(dir string) error { glog.V(3).Infof("Setting up volume %v for pod %v at %v", b.volName, b.pod.UID, dir) // Wrap EmptyDir, let it do the setup. - wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, *b.opts) + wrapped, err := b.plugin.host.NewWrapperBuilder(b.wrappedVolumeSpec, &b.pod, *b.opts) if err != nil { return err } @@ -202,7 +217,7 @@ func (c *secretVolumeCleaner) TearDownAt(dir string) error { glog.V(3).Infof("Tearing down volume %v for pod %v at %v", c.volName, c.podUID, dir) // Wrap EmptyDir, let it do the teardown. - wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID) + wrapped, err := c.plugin.host.NewWrapperCleaner(c.wrappedVolumeSpec, c.podUID) if err != nil { return err } diff --git a/pkg/volume/secret/secret_test.go b/pkg/volume/secret/secret_test.go index 5ccc6aa7654..b5d49fb9fb7 100644 --- a/pkg/volume/secret/secret_test.go +++ b/pkg/volume/secret/secret_test.go @@ -70,11 +70,11 @@ func TestPlugin(t *testing.T) { testNamespace = "test_secret_namespace" testName = "test_secret_name" - volumeSpec = volumeSpec(testVolumeName, testName) - secret = secret(testNamespace, testName) - client = testclient.NewSimpleFake(&secret) - pluginMgr = volume.VolumePluginMgr{} - _, host = newTestHost(t, client) + volumeSpec = volumeSpec(testVolumeName, testName) + secret = secret(testNamespace, testName) + client = testclient.NewSimpleFake(&secret) + pluginMgr = volume.VolumePluginMgr{} + rootDir, host = newTestHost(t, client) ) pluginMgr.InitPlugins(ProbeVolumePlugins(), host) @@ -110,6 +110,16 @@ func TestPlugin(t *testing.T) { } } + // secret volume should create it's own empty wrapper path + podWrapperMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid/plugins/kubernetes.io~empty-dir/wrapped_test_volume_name", rootDir) + + if _, err := os.Stat(podWrapperMetadataDir); err != nil { + if os.IsNotExist(err) { + t.Errorf("SetUp() failed, empty-dir wrapper path is not created: %s", podWrapperMetadataDir) + } else { + t.Errorf("SetUp() failed: %v", err) + } + } doTestSecretDataInVolume(volumePath, secret, t) doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t) } diff --git a/pkg/volume/volume.go b/pkg/volume/volume.go index aab01158f2b..7ff136b40a4 100644 --- a/pkg/volume/volume.go +++ b/pkg/volume/volume.go @@ -17,6 +17,7 @@ limitations under the License. package volume import ( + "fmt" "io/ioutil" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" @@ -24,6 +25,10 @@ import ( "path" ) +const ( + randomLength = 5 +) + // Volume represents a directory used by pods or hosts on a node. // All method implementations of methods in the volume interface must be idempotent. type Volume interface { @@ -132,3 +137,22 @@ func RenameDirectory(oldPath, newName string) (string, error) { } return newPath, nil } + +// Return the wrapper volume spec of specific volume plugin +func GetWrappedVolumeSpec(volName string, pluginName string) *Spec { + // The name of wrapper volume is set to "wrapped_{wrapped_volume_name}" + wrapperVolumeName := fmt.Sprintf("wrapped_%v", volName) + + var volumeSpec *Spec + switch pluginName { + case "kubernetes.io/downward-api", "kubernetes.io/secret": + volumeSpec = &Spec{ + Volume: &api.Volume{Name: wrapperVolumeName, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}}}, + } + case "kubernetes.io/git-repo": + volumeSpec = &Spec{ + Volume: &api.Volume{Name: wrapperVolumeName, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}, + } + } + return volumeSpec +}