Fix volume wrapper doesn't have name
Integration test
This commit is contained in:
parent
7ca0fa431b
commit
c0d49450e4
@ -55,7 +55,10 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
"k8s.io/kubernetes/pkg/volume/empty_dir"
|
"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"
|
||||||
_ "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider"
|
_ "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider"
|
||||||
"k8s.io/kubernetes/plugin/pkg/scheduler/factory"
|
"k8s.io/kubernetes/plugin/pkg/scheduler/factory"
|
||||||
@ -211,7 +214,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
|
|||||||
10250, /* KubeletPort */
|
10250, /* KubeletPort */
|
||||||
0, /* ReadOnlyPort */
|
0, /* ReadOnlyPort */
|
||||||
api.NamespaceDefault,
|
api.NamespaceDefault,
|
||||||
empty_dir.ProbeVolumePlugins(),
|
probeVolumePlugins(),
|
||||||
nil,
|
nil,
|
||||||
cadvisorInterface,
|
cadvisorInterface,
|
||||||
configFilePath,
|
configFilePath,
|
||||||
@ -244,7 +247,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
|
|||||||
10251, /* KubeletPort */
|
10251, /* KubeletPort */
|
||||||
0, /* ReadOnlyPort */
|
0, /* ReadOnlyPort */
|
||||||
api.NamespaceDefault,
|
api.NamespaceDefault,
|
||||||
empty_dir.ProbeVolumePlugins(),
|
probeVolumePlugins(),
|
||||||
nil,
|
nil,
|
||||||
cadvisorInterface,
|
cadvisorInterface,
|
||||||
"",
|
"",
|
||||||
@ -265,6 +268,16 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
|
|||||||
return apiServer.URL, configFilePath
|
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 {
|
func makeTempDirOrDie(prefix string, baseDir string) string {
|
||||||
if baseDir == "" {
|
if baseDir == "" {
|
||||||
baseDir = "/tmp"
|
baseDir = "/tmp"
|
||||||
@ -989,6 +1002,7 @@ func main() {
|
|||||||
runServiceTest,
|
runServiceTest,
|
||||||
runAPIVersionsTest,
|
runAPIVersionsTest,
|
||||||
runMasterServiceTest,
|
runMasterServiceTest,
|
||||||
|
runWrapperVolumesPluginsTest,
|
||||||
func(c *client.Client) {
|
func(c *client.Client) {
|
||||||
runSelfLinkTestOnNamespace(c, api.NamespaceDefault)
|
runSelfLinkTestOnNamespace(c, api.NamespaceDefault)
|
||||||
runSelfLinkTestOnNamespace(c, "other")
|
runSelfLinkTestOnNamespace(c, "other")
|
||||||
@ -1038,8 +1052,8 @@ func main() {
|
|||||||
// 1 pod infra container + 1 container from the service test.
|
// 1 pod infra container + 1 container from the service test.
|
||||||
// The total number of container created is 9
|
// The total number of container created is 9
|
||||||
|
|
||||||
if len(createdConts) != 12 {
|
if len(createdConts) != 14 {
|
||||||
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)
|
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())
|
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) {
|
func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
|
||||||
v := &downwardAPIVolume{
|
v := &downwardAPIVolume{
|
||||||
volName: spec.Name(),
|
volName: spec.Name(),
|
||||||
pod: pod,
|
pod: pod,
|
||||||
podUID: pod.UID,
|
podUID: pod.UID,
|
||||||
plugin: plugin,
|
plugin: plugin,
|
||||||
|
wrappedVolumeSpec: volume.GetWrappedVolumeSpec(spec.Name(), downwardAPIPluginName),
|
||||||
}
|
}
|
||||||
v.fieldReferenceFileNames = make(map[string]string)
|
v.fieldReferenceFileNames = make(map[string]string)
|
||||||
for _, fileInfo := range spec.Volume.DownwardAPI.Items {
|
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) {
|
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.
|
// 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
|
podUID types.UID // TODO: remove this redundancy as soon NewCleaner func will have *api.POD and not only types.UID
|
||||||
plugin *downwardAPIPlugin
|
plugin *downwardAPIPlugin
|
||||||
volume.MetricsNil
|
volume.MetricsNil
|
||||||
}
|
wrappedVolumeSpec *volume.Spec
|
||||||
|
|
||||||
// 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
|
// 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 {
|
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)
|
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
|
// 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 {
|
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())
|
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
|
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)
|
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.
|
// 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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,12 @@ func formatMap(m map[string]string) (fmtstr string) {
|
|||||||
return
|
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.")
|
tempDir, err := ioutil.TempDir(basePath, "downwardApi_volume_test.")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't make a temp rootdir: %v", err)
|
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) {
|
func TestCanSupport(t *testing.T) {
|
||||||
@ -54,7 +54,8 @@ func TestCanSupport(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
pluginMgr := volume.VolumePluginMgr{}
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, nil, tmpDir))
|
_, host := newTestHost(t, nil, tmpDir)
|
||||||
|
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
|
|
||||||
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -110,7 +111,8 @@ func TestLabels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
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)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
volumeSpec := &api.Volume{
|
volumeSpec := &api.Volume{
|
||||||
Name: testVolumeName,
|
Name: testVolumeName,
|
||||||
@ -141,6 +143,17 @@ func TestLabels(t *testing.T) {
|
|||||||
t.Errorf("Failed to setup volume: %v", err)
|
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
|
var data []byte
|
||||||
data, err = ioutil.ReadFile(path.Join(volumePath, "labels"))
|
data, err = ioutil.ReadFile(path.Join(volumePath, "labels"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -189,7 +202,8 @@ func TestAnnotations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
pluginMgr := volume.VolumePluginMgr{}
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir))
|
_, host := newTestHost(t, fake, tmpDir)
|
||||||
|
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Can't find the plugin by name")
|
t.Errorf("Can't find the plugin by name")
|
||||||
@ -254,7 +268,8 @@ func TestName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
pluginMgr := volume.VolumePluginMgr{}
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir))
|
_, host := newTestHost(t, fake, tmpDir)
|
||||||
|
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Can't find the plugin by name")
|
t.Errorf("Can't find the plugin by name")
|
||||||
@ -320,7 +335,8 @@ func TestNamespace(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
pluginMgr := volume.VolumePluginMgr{}
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir))
|
_, host := newTestHost(t, fake, tmpDir)
|
||||||
|
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Can't find the plugin by name")
|
t.Errorf("Can't find the plugin by name")
|
||||||
@ -379,7 +395,8 @@ func TestWriteTwiceNoUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
pluginMgr := volume.VolumePluginMgr{}
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir))
|
_, host := newTestHost(t, fake, tmpDir)
|
||||||
|
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
volumeSpec := &api.Volume{
|
volumeSpec := &api.Volume{
|
||||||
Name: testVolumeName,
|
Name: testVolumeName,
|
||||||
@ -468,7 +485,8 @@ func TestWriteTwiceWithUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
pluginMgr := volume.VolumePluginMgr{}
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir))
|
_, host := newTestHost(t, fake, tmpDir)
|
||||||
|
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
volumeSpec := &api.Volume{
|
volumeSpec := &api.Volume{
|
||||||
Name: testVolumeName,
|
Name: testVolumeName,
|
||||||
@ -577,7 +595,8 @@ func TestWriteWithUnixPath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
pluginMgr := volume.VolumePluginMgr{}
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir))
|
_, host := newTestHost(t, fake, tmpDir)
|
||||||
|
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
volumeSpec := &api.Volume{
|
volumeSpec := &api.Volume{
|
||||||
Name: testVolumeName,
|
Name: testVolumeName,
|
||||||
@ -656,7 +675,8 @@ func TestWriteWithUnixPathBadPath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
pluginMgr := volume.VolumePluginMgr{}
|
pluginMgr := volume.VolumePluginMgr{}
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake, tmpDir))
|
_, host := newTestHost(t, fake, tmpDir)
|
||||||
|
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Can't find the plugin by name")
|
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) {
|
func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
|
||||||
return &gitRepoVolumeBuilder{
|
return &gitRepoVolumeBuilder{
|
||||||
gitRepoVolume: &gitRepoVolume{
|
gitRepoVolume: &gitRepoVolume{
|
||||||
volName: spec.Name(),
|
volName: spec.Name(),
|
||||||
podUID: pod.UID,
|
podUID: pod.UID,
|
||||||
plugin: plugin,
|
plugin: plugin,
|
||||||
|
wrappedVolumeSpec: volume.GetWrappedVolumeSpec(spec.Name(), gitRepoPluginName),
|
||||||
},
|
},
|
||||||
pod: *pod,
|
pod: *pod,
|
||||||
source: spec.Volume.GitRepo.Repository,
|
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) {
|
func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
|
||||||
return &gitRepoVolumeCleaner{
|
return &gitRepoVolumeCleaner{
|
||||||
&gitRepoVolume{
|
&gitRepoVolume{
|
||||||
volName: volName,
|
volName: volName,
|
||||||
podUID: podUID,
|
podUID: podUID,
|
||||||
plugin: plugin,
|
plugin: plugin,
|
||||||
|
wrappedVolumeSpec: volume.GetWrappedVolumeSpec(volName, gitRepoPluginName),
|
||||||
},
|
},
|
||||||
}, nil
|
}, 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.
|
// gitRepo volumes are directories which are pre-filled from a git repository.
|
||||||
// These do not persist beyond the lifetime of a pod.
|
// These do not persist beyond the lifetime of a pod.
|
||||||
type gitRepoVolume struct {
|
type gitRepoVolume struct {
|
||||||
volName string
|
volName string
|
||||||
podUID types.UID
|
podUID types.UID
|
||||||
plugin *gitRepoPlugin
|
plugin *gitRepoPlugin
|
||||||
|
wrappedVolumeSpec *volume.Spec
|
||||||
volume.MetricsNil
|
volume.MetricsNil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,11 +131,6 @@ func (b *gitRepoVolumeBuilder) SetUp() error {
|
|||||||
return b.SetUpAt(b.GetPath())
|
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.
|
// SetUpAt creates new directory and clones a git repo.
|
||||||
func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error {
|
func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error {
|
||||||
if volumeutil.IsReady(b.getMetaDir()) {
|
if volumeutil.IsReady(b.getMetaDir()) {
|
||||||
@ -140,7 +138,7 @@ func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wrap EmptyDir, let it do the setup.
|
// 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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -218,8 +216,9 @@ func (c *gitRepoVolumeCleaner) TearDown() error {
|
|||||||
|
|
||||||
// TearDownAt simply deletes everything in the directory.
|
// TearDownAt simply deletes everything in the directory.
|
||||||
func (c *gitRepoVolumeCleaner) TearDownAt(dir string) error {
|
func (c *gitRepoVolumeCleaner) TearDownAt(dir string) error {
|
||||||
|
|
||||||
// Wrap EmptyDir, let it do the teardown.
|
// 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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -32,17 +32,18 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/volume/empty_dir"
|
"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.")
|
tempDir, err := ioutil.TempDir("/tmp", "git_repo_test.")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't make a temp rootdir: %v", err)
|
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) {
|
func TestCanSupport(t *testing.T) {
|
||||||
plugMgr := volume.VolumePluginMgr{}
|
plugMgr := volume.VolumePluginMgr{}
|
||||||
plugMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t))
|
_, host := newTestHost(t)
|
||||||
|
plugMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
|
|
||||||
plug, err := plugMgr.FindPluginByName("kubernetes.io/git-repo")
|
plug, err := plugMgr.FindPluginByName("kubernetes.io/git-repo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -218,7 +219,8 @@ func doTestPlugin(scenario struct {
|
|||||||
allErrs := []error{}
|
allErrs := []error{}
|
||||||
|
|
||||||
plugMgr := volume.VolumePluginMgr{}
|
plugMgr := volume.VolumePluginMgr{}
|
||||||
plugMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t))
|
rootDir, host := newTestHost(t)
|
||||||
|
plugMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||||
|
|
||||||
plug, err := plugMgr.FindPluginByName("kubernetes.io/git-repo")
|
plug, err := plugMgr.FindPluginByName("kubernetes.io/git-repo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -241,7 +243,8 @@ func doTestPlugin(scenario struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
path := builder.GetPath()
|
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,
|
allErrs = append(allErrs,
|
||||||
fmt.Errorf("Got unexpected path: %s", path))
|
fmt.Errorf("Got unexpected path: %s", path))
|
||||||
return allErrs
|
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"))
|
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs,
|
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) {
|
func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
|
||||||
return &secretVolumeBuilder{
|
return &secretVolumeBuilder{
|
||||||
secretVolume: &secretVolume{spec.Name(), pod.UID, plugin, plugin.host.GetMounter(), plugin.host.GetWriter(), volume.MetricsNil{}},
|
secretVolume: &secretVolume{
|
||||||
secretName: spec.Volume.Secret.SecretName,
|
spec.Name(),
|
||||||
pod: *pod,
|
pod.UID,
|
||||||
opts: &opts}, nil
|
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) {
|
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 {
|
type secretVolume struct {
|
||||||
@ -79,6 +98,7 @@ type secretVolume struct {
|
|||||||
mounter mount.Interface
|
mounter mount.Interface
|
||||||
writer ioutil.Writer
|
writer ioutil.Writer
|
||||||
volume.MetricsNil
|
volume.MetricsNil
|
||||||
|
wrappedVolumeSpec *volume.Spec
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ volume.Volume = &secretVolume{}
|
var _ volume.Volume = &secretVolume{}
|
||||||
@ -111,11 +131,6 @@ func (b *secretVolumeBuilder) SetUp() error {
|
|||||||
return b.SetUpAt(b.GetPath())
|
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 {
|
func (b *secretVolumeBuilder) getMetaDir() string {
|
||||||
return path.Join(b.plugin.host.GetPodPluginDir(b.podUID, util.EscapeQualifiedNameForDisk(secretPluginName)), b.volName)
|
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)
|
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.
|
// 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 {
|
if err != nil {
|
||||||
return err
|
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)
|
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.
|
// 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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -70,11 +70,11 @@ func TestPlugin(t *testing.T) {
|
|||||||
testNamespace = "test_secret_namespace"
|
testNamespace = "test_secret_namespace"
|
||||||
testName = "test_secret_name"
|
testName = "test_secret_name"
|
||||||
|
|
||||||
volumeSpec = volumeSpec(testVolumeName, testName)
|
volumeSpec = volumeSpec(testVolumeName, testName)
|
||||||
secret = secret(testNamespace, testName)
|
secret = secret(testNamespace, testName)
|
||||||
client = testclient.NewSimpleFake(&secret)
|
client = testclient.NewSimpleFake(&secret)
|
||||||
pluginMgr = volume.VolumePluginMgr{}
|
pluginMgr = volume.VolumePluginMgr{}
|
||||||
_, host = newTestHost(t, client)
|
rootDir, host = newTestHost(t, client)
|
||||||
)
|
)
|
||||||
|
|
||||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
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)
|
doTestSecretDataInVolume(volumePath, secret, t)
|
||||||
doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t)
|
doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package volume
|
package volume
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
@ -24,6 +25,10 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
randomLength = 5
|
||||||
|
)
|
||||||
|
|
||||||
// Volume represents a directory used by pods or hosts on a node.
|
// Volume represents a directory used by pods or hosts on a node.
|
||||||
// All method implementations of methods in the volume interface must be idempotent.
|
// All method implementations of methods in the volume interface must be idempotent.
|
||||||
type Volume interface {
|
type Volume interface {
|
||||||
@ -132,3 +137,22 @@ func RenameDirectory(oldPath, newName string) (string, error) {
|
|||||||
}
|
}
|
||||||
return newPath, nil
|
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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user