mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	Fix volume wrapper doesn't have name
Integration test
This commit is contained in:
		| @@ -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.") | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| 	} | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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 | ||||
| 	} | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 | ||||
| 	} | ||||
|   | ||||
| @@ -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) | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 harry
					harry