Merge pull request #18445 from resouer/fix-emptydir

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2016-01-26 02:45:54 -08:00
commit 52cb4c1d9d
13 changed files with 334 additions and 65 deletions

View File

@ -473,11 +473,11 @@ func (c *PersistentVolumeProvisionerController) GetKubeClient() client.Interface
return c.client.GetKubeClient()
}
func (c *PersistentVolumeProvisionerController) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
func (c *PersistentVolumeProvisionerController) NewWrapperBuilder(volName string, spec volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
return nil, fmt.Errorf("NewWrapperBuilder not supported by PVClaimBinder's VolumeHost implementation")
}
func (c *PersistentVolumeProvisionerController) NewWrapperCleaner(spec *volume.Spec, podUID types.UID) (volume.Cleaner, error) {
func (c *PersistentVolumeProvisionerController) NewWrapperCleaner(volName string, spec volume.Spec, podUID types.UID) (volume.Cleaner, error) {
return nil, fmt.Errorf("NewWrapperCleaner not supported by PVClaimBinder's VolumeHost implementation")
}

View File

@ -291,11 +291,11 @@ func (f *PersistentVolumeRecycler) GetKubeClient() client.Interface {
return f.kubeClient
}
func (f *PersistentVolumeRecycler) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
func (f *PersistentVolumeRecycler) NewWrapperBuilder(volName string, spec volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
return nil, fmt.Errorf("NewWrapperBuilder not supported by PVClaimBinder's VolumeHost implementation")
}
func (f *PersistentVolumeRecycler) NewWrapperCleaner(spec *volume.Spec, podUID types.UID) (volume.Cleaner, error) {
func (f *PersistentVolumeRecycler) NewWrapperCleaner(volName string, spec volume.Spec, podUID types.UID) (volume.Cleaner, error) {
return nil, fmt.Errorf("NewWrapperCleaner not supported by PVClaimBinder's VolumeHost implementation")
}

View File

@ -58,16 +58,28 @@ func (vh *volumeHost) GetKubeClient() client.Interface {
return vh.kubelet.kubeClient
}
func (vh *volumeHost) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, pod, opts)
func (vh *volumeHost) NewWrapperBuilder(volName string, spec volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName := "wrapped_" + volName
if spec.Volume != nil {
spec.Volume.Name = wrapperVolumeName
}
b, err := vh.kubelet.newVolumeBuilderFromPlugins(&spec, pod, opts)
if err == nil && b == nil {
return nil, errUnsupportedVolumeType
}
return b, nil
}
func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID) (volume.Cleaner, error) {
plugin, err := vh.kubelet.volumePluginMgr.FindPluginBySpec(spec)
func (vh *volumeHost) NewWrapperCleaner(volName string, spec volume.Spec, podUID types.UID) (volume.Cleaner, error) {
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName := "wrapped_" + volName
if spec.Volume != nil {
spec.Volume.Name = wrapperVolumeName
}
plugin, err := vh.kubelet.volumePluginMgr.FindPluginBySpec(&spec)
if err != nil {
return nil, err
}

View File

@ -51,6 +51,10 @@ type downwardAPIPlugin struct {
var _ volume.VolumePlugin = &downwardAPIPlugin{}
var wrappedVolumeSpec = volume.Spec{
Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}}},
}
func (plugin *downwardAPIPlugin) Init(host volume.VolumeHost) error {
plugin.host = host
return nil
@ -77,11 +81,18 @@ func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opt
}
return &downwardAPIVolumeBuilder{
downwardAPIVolume: v,
opts: &opts}, nil
opts: &opts,
}, nil
}
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,
},
}, nil
}
// downwardAPIVolume retrieves downward API data and placing them into the volume on the host.
@ -94,11 +105,6 @@ type downwardAPIVolume struct {
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}}},
}
// downwardAPIVolumeBuilder fetches info from downward API from the pod
// and dumps it in files
type downwardAPIVolumeBuilder struct {
@ -130,7 +136,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.volName, 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 +370,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.volName, wrappedVolumeSpec, c.podUID)
if err != nil {
return err
}

View File

@ -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)
}
// downwardAPI volume should create its 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")

View File

@ -41,6 +41,10 @@ type gitRepoPlugin struct {
var _ volume.VolumePlugin = &gitRepoPlugin{}
var wrappedVolumeSpec = volume.Spec{
Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
}
const (
gitRepoPluginName = "kubernetes.io/git-repo"
)
@ -128,11 +132,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 +139,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.volName, wrappedVolumeSpec, &b.pod, b.opts)
if err != nil {
return err
}
@ -218,8 +217,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.volName, wrappedVolumeSpec, c.podUID)
if err != nil {
return err
}

View File

@ -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 its 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,

View File

@ -80,7 +80,7 @@ func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod,
return nil, err
}
builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv, spec.ReadOnly), pod, opts)
builder, err := plugin.host.NewWrapperBuilder(claim.Spec.VolumeName, *volume.NewSpecFromPersistentVolume(pv, spec.ReadOnly), pod, opts)
if err != nil {
glog.Errorf("Error creating builder for claim: %+v\n", claim.Name)
return nil, err

View File

@ -144,12 +144,12 @@ type VolumeHost interface {
// the provided spec. This is used to implement volume plugins which
// "wrap" other plugins. For example, the "secret" volume is
// implemented in terms of the "emptyDir" volume.
NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions) (Builder, error)
NewWrapperBuilder(volName string, spec Spec, pod *api.Pod, opts VolumeOptions) (Builder, error)
// NewWrapperCleaner finds an appropriate plugin with which to handle
// the provided spec. See comments on NewWrapperBuilder for more
// context.
NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error)
NewWrapperCleaner(volName string, spec Spec, podUID types.UID) (Cleaner, error)
// Get cloud provider from kubelet.
GetCloudProvider() cloudprovider.Interface

View File

@ -47,6 +47,10 @@ type secretPlugin struct {
var _ volume.VolumePlugin = &secretPlugin{}
var wrappedVolumeSpec = volume.Spec{
Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}}},
}
func (plugin *secretPlugin) Init(host volume.VolumeHost) error {
plugin.host = host
return nil
@ -62,14 +66,31 @@ 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{}},
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
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{},
},
}, nil
}
type secretVolume struct {
@ -111,11 +132,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, strings.EscapeQualifiedNameForDisk(secretPluginName)), b.volName)
}
@ -137,7 +153,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.volName, wrappedVolumeSpec, &b.pod, *b.opts)
if err != nil {
return err
}
@ -202,7 +218,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.volName, wrappedVolumeSpec, c.podUID)
if err != nil {
return err
}

View File

@ -74,7 +74,7 @@ func TestPlugin(t *testing.T) {
secret = secret(testNamespace, testName)
client = testclient.NewSimpleFake(&secret)
pluginMgr = volume.VolumePluginMgr{}
_, host = newTestHost(t, client)
rootDir, host = newTestHost(t, client)
)
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
@ -110,6 +110,16 @@ func TestPlugin(t *testing.T) {
}
}
// secret volume should create its 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)
}

View File

@ -81,16 +81,26 @@ func (f *fakeVolumeHost) GetWriter() io.Writer {
return f.writer
}
func (f *fakeVolumeHost) NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions) (Builder, error) {
plug, err := f.pluginMgr.FindPluginBySpec(spec)
func (f *fakeVolumeHost) NewWrapperBuilder(volName string, spec Spec, pod *api.Pod, opts VolumeOptions) (Builder, error) {
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName := "wrapped_" + volName
if spec.Volume != nil {
spec.Volume.Name = wrapperVolumeName
}
plug, err := f.pluginMgr.FindPluginBySpec(&spec)
if err != nil {
return nil, err
}
return plug.NewBuilder(spec, pod, opts)
return plug.NewBuilder(&spec, pod, opts)
}
func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error) {
plug, err := f.pluginMgr.FindPluginBySpec(spec)
func (f *fakeVolumeHost) NewWrapperCleaner(volName string, spec Spec, podUID types.UID) (Cleaner, error) {
// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
wrapperVolumeName := "wrapped_" + volName
if spec.Volume != nil {
spec.Volume.Name = wrapperVolumeName
}
plug, err := f.pluginMgr.FindPluginBySpec(&spec)
if err != nil {
return nil, err
}

View File

@ -0,0 +1,179 @@
/*
Copyright 2015 The Kubernetes Authors 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 e2e
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/intstr"
"strconv"
. "github.com/onsi/ginkgo"
)
// This test will create a pod with a secret volume and gitRepo volume
// Thus requests a secret, a git server pod, and a git server service
var _ = Describe("EmptyDir wrapper volumes", func() {
f := NewFramework("secrets")
It("should becomes running [Conformance]", func() {
name := "secret-test-" + string(util.NewUUID())
volumeName := "secret-volume"
volumeMountPath := "/etc/secret-volume"
secret := &api.Secret{
ObjectMeta: api.ObjectMeta{
Namespace: f.Namespace.Name,
Name: name,
},
Data: map[string][]byte{
"data-1": []byte("value-1\n"),
},
}
var err error
if secret, err = f.Client.Secrets(f.Namespace.Name).Create(secret); err != nil {
Failf("unable to create test secret %s: %v", secret.Name, err)
}
gitServerPodName := "git-server-" + string(util.NewUUID())
containerPort := 8000
labels := map[string]string{"name": gitServerPodName}
gitServerPod := &api.Pod{
ObjectMeta: api.ObjectMeta{
Name: gitServerPodName,
Labels: labels,
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "git-repo",
Image: "gcr.io/google_containers/fakegitserver:0.1",
ImagePullPolicy: "IfNotPresent",
Ports: []api.ContainerPort{
{ContainerPort: containerPort},
},
},
},
},
}
if gitServerPod, err = f.Client.Pods(f.Namespace.Name).Create(gitServerPod); err != nil {
Failf("unable to create test git server pod %s: %v", gitServerPod.Name, err)
}
// Portal IP and port
httpPort := 2345
gitServerSvc := &api.Service{
ObjectMeta: api.ObjectMeta{
Name: "git-server-svc",
},
Spec: api.ServiceSpec{
Selector: labels,
Ports: []api.ServicePort{
{
Name: "http-portal",
Port: httpPort,
TargetPort: intstr.FromInt(containerPort),
},
},
},
}
if gitServerSvc, err = f.Client.Services(f.Namespace.Name).Create(gitServerSvc); err != nil {
Failf("unable to create test git server service %s: %v", gitServerSvc.Name, err)
}
gitVolumeName := "git-volume"
gitVolumeMountPath := "/etc/git-volume"
gitURL := "http://" + gitServerSvc.Spec.ClusterIP + ":" + strconv.Itoa(httpPort)
gitRepo := "test"
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "pod-secrets-" + string(util.NewUUID()),
},
Spec: api.PodSpec{
Volumes: []api.Volume{
{
Name: volumeName,
VolumeSource: api.VolumeSource{
Secret: &api.SecretVolumeSource{
SecretName: name,
},
},
},
{
Name: gitVolumeName,
VolumeSource: api.VolumeSource{
GitRepo: &api.GitRepoVolumeSource{
Repository: gitURL,
Directory: gitRepo,
},
},
},
},
Containers: []api.Container{
{
Name: "secret-test",
Image: "gcr.io/google_containers/test-webserver",
VolumeMounts: []api.VolumeMount{
{
Name: volumeName,
MountPath: volumeMountPath,
ReadOnly: true,
},
{
Name: gitVolumeName,
MountPath: gitVolumeMountPath,
},
},
},
},
},
}
if pod, err = f.Client.Pods(f.Namespace.Name).Create(pod); err != nil {
Failf("unable to create pod %v: %v", pod.Name, err)
}
defer func() {
By("Cleaning up the secret")
if err := f.Client.Secrets(f.Namespace.Name).Delete(secret.Name); err != nil {
Failf("unable to delete secret %v: %v", secret.Name, err)
}
By("Cleaning up the git server pod")
if err = f.Client.Pods(f.Namespace.Name).Delete(gitServerPod.Name, api.NewDeleteOptions(0)); err != nil {
Failf("unable to delete git server pod %v: %v", gitServerPod.Name, err)
}
By("Cleaning up the git server svc")
if err = f.Client.Services(f.Namespace.Name).Delete(gitServerSvc.Name); err != nil {
Failf("unable to delete git server svc %v: %v", gitServerSvc.Name, err)
}
By("Cleaning up the git vol pod")
if err = f.Client.Pods(f.Namespace.Name).Delete(pod.Name, api.NewDeleteOptions(0)); err != nil {
Failf("unable to delete git vol pod %v: %v", pod.Name, err)
}
}()
expectNoError(waitForPodRunningInNamespace(f.Client, pod.Name, f.Namespace.Name))
})
})