Merge pull request #13791 from fgrzadkowski/fix_secrets_in_docker

Auto commit by PR queue bot
pull/6/head
k8s-merge-robot 2015-09-17 15:13:29 -07:00
commit c1eb1a1b2f
35 changed files with 250 additions and 128 deletions

View File

@ -51,6 +51,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/qos" "k8s.io/kubernetes/pkg/kubelet/qos"
"k8s.io/kubernetes/pkg/master/ports" "k8s.io/kubernetes/pkg/master/ports"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
nodeutil "k8s.io/kubernetes/pkg/util/node" nodeutil "k8s.io/kubernetes/pkg/util/node"
"k8s.io/kubernetes/pkg/util/oom" "k8s.io/kubernetes/pkg/util/oom"
@ -287,9 +288,11 @@ func (s *KubeletServer) KubeletConfig() (*KubeletConfig, error) {
} }
mounter := mount.New() mounter := mount.New()
var writer io.Writer = &io.StdWriter{}
if s.Containerized { if s.Containerized {
glog.V(2).Info("Running kubelet in containerized mode (experimental)") glog.V(2).Info("Running kubelet in containerized mode (experimental)")
mounter = mount.NewNsenterMounter() mounter = mount.NewNsenterMounter()
writer = &io.NsenterWriter{}
} }
tlsOptions, err := s.InitializeTLS() tlsOptions, err := s.InitializeTLS()
@ -384,6 +387,7 @@ func (s *KubeletServer) KubeletConfig() (*KubeletConfig, error) {
SyncFrequency: s.SyncFrequency, SyncFrequency: s.SyncFrequency,
SystemContainer: s.SystemContainer, SystemContainer: s.SystemContainer,
TLSOptions: tlsOptions, TLSOptions: tlsOptions,
Writer: writer,
VolumePlugins: ProbeVolumePlugins(), VolumePlugins: ProbeVolumePlugins(),
}, nil }, nil
} }
@ -592,6 +596,7 @@ func SimpleKubelet(client *client.Client,
DockerFreeDiskMB: 256, DockerFreeDiskMB: 256,
RootFreeDiskMB: 256, RootFreeDiskMB: 256,
} }
kcfg := KubeletConfig{ kcfg := KubeletConfig{
Address: net.ParseIP(address), Address: net.ParseIP(address),
CAdvisorInterface: cadvisorInterface, CAdvisorInterface: cadvisorInterface,
@ -630,6 +635,7 @@ func SimpleKubelet(client *client.Client,
SyncFrequency: syncFrequency, SyncFrequency: syncFrequency,
SystemContainer: "", SystemContainer: "",
TLSOptions: tlsOptions, TLSOptions: tlsOptions,
Writer: &io.StdWriter{},
VolumePlugins: volumePlugins, VolumePlugins: volumePlugins,
} }
return &kcfg return &kcfg
@ -812,6 +818,7 @@ type KubeletConfig struct {
SyncFrequency time.Duration SyncFrequency time.Duration
SystemContainer string SystemContainer string
TLSOptions *kubelet.TLSOptions TLSOptions *kubelet.TLSOptions
Writer io.Writer
VolumePlugins []volume.VolumePlugin VolumePlugins []volume.VolumePlugin
} }
@ -873,6 +880,7 @@ func createAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.Pod
kc.RktPath, kc.RktPath,
kc.RktStage1Image, kc.RktStage1Image,
kc.Mounter, kc.Mounter,
kc.Writer,
kc.DockerDaemonContainer, kc.DockerDaemonContainer,
kc.SystemContainer, kc.SystemContainer,
kc.ConfigureCBR0, kc.ConfigureCBR0,

View File

@ -327,6 +327,7 @@ func (ks *KubeletExecutorServer) createAndInitKubelet(
kc.RktPath, kc.RktPath,
kc.RktStage1Image, kc.RktStage1Image,
kc.Mounter, kc.Mounter,
kc.Writer,
kc.DockerDaemonContainer, kc.DockerDaemonContainer,
kc.SystemContainer, kc.SystemContainer,
kc.ConfigureCBR0, kc.ConfigureCBR0,

View File

@ -30,6 +30,7 @@ import (
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
ioutil "k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/watch" "k8s.io/kubernetes/pkg/watch"
@ -273,14 +274,22 @@ func (f *PersistentVolumeRecycler) GetKubeClient() client.Interface {
return f.kubeClient return f.kubeClient
} }
func (f *PersistentVolumeRecycler) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (f *PersistentVolumeRecycler) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
return nil, fmt.Errorf("NewWrapperBuilder not supported by PVClaimBinder's VolumeHost implementation") return nil, fmt.Errorf("NewWrapperBuilder not supported by PVClaimBinder's VolumeHost implementation")
} }
func (f *PersistentVolumeRecycler) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (f *PersistentVolumeRecycler) NewWrapperCleaner(spec *volume.Spec, podUID types.UID) (volume.Cleaner, error) {
return nil, fmt.Errorf("NewWrapperCleaner not supported by PVClaimBinder's VolumeHost implementation") return nil, fmt.Errorf("NewWrapperCleaner not supported by PVClaimBinder's VolumeHost implementation")
} }
func (f *PersistentVolumeRecycler) GetCloudProvider() cloudprovider.Interface { func (f *PersistentVolumeRecycler) GetCloudProvider() cloudprovider.Interface {
return nil return nil
} }
func (f *PersistentVolumeRecycler) GetMounter() mount.Interface {
return nil
}
func (f *PersistentVolumeRecycler) GetWriter() ioutil.Writer {
return nil
}

View File

@ -60,6 +60,7 @@ import (
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/bandwidth" "k8s.io/kubernetes/pkg/util/bandwidth"
utilErrors "k8s.io/kubernetes/pkg/util/errors" utilErrors "k8s.io/kubernetes/pkg/util/errors"
kubeio "k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/oom" "k8s.io/kubernetes/pkg/util/oom"
"k8s.io/kubernetes/pkg/util/procfs" "k8s.io/kubernetes/pkg/util/procfs"
@ -161,6 +162,7 @@ func NewMainKubelet(
rktPath string, rktPath string,
rktStage1Image string, rktStage1Image string,
mounter mount.Interface, mounter mount.Interface,
writer kubeio.Writer,
dockerDaemonContainer string, dockerDaemonContainer string,
systemContainer string, systemContainer string,
configureCBR0 bool, configureCBR0 bool,
@ -261,6 +263,7 @@ func NewMainKubelet(
oomWatcher: oomWatcher, oomWatcher: oomWatcher,
cgroupRoot: cgroupRoot, cgroupRoot: cgroupRoot,
mounter: mounter, mounter: mounter,
writer: writer,
configureCBR0: configureCBR0, configureCBR0: configureCBR0,
pods: pods, pods: pods,
syncLoopMonitor: util.AtomicValue{}, syncLoopMonitor: util.AtomicValue{},
@ -499,6 +502,9 @@ type Kubelet struct {
// Mounter to use for volumes. // Mounter to use for volumes.
mounter mount.Interface mounter mount.Interface
// Writer interface to use for volumes.
writer kubeio.Writer
// Manager of non-Runtime containers. // Manager of non-Runtime containers.
containerManager containerManager containerManager containerManager

View File

@ -28,6 +28,7 @@ import (
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
) )
@ -56,15 +57,15 @@ func (vh *volumeHost) GetKubeClient() client.Interface {
return vh.kubelet.kubeClient return vh.kubelet.kubeClient
} }
func (vh *volumeHost) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (vh *volumeHost) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, pod, opts, mounter) b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, pod, opts)
if err == nil && b == nil { if err == nil && b == nil {
return nil, errUnsupportedVolumeType return nil, errUnsupportedVolumeType
} }
return b, nil return b, nil
} }
func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID) (volume.Cleaner, error) {
plugin, err := vh.kubelet.volumePluginMgr.FindPluginBySpec(spec) plugin, err := vh.kubelet.volumePluginMgr.FindPluginBySpec(spec)
if err != nil { if err != nil {
return nil, err return nil, err
@ -73,7 +74,7 @@ func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, mou
// Not found but not an error // Not found but not an error
return nil, nil return nil, nil
} }
c, err := plugin.NewCleaner(spec.Name(), podUID, mounter) c, err := plugin.NewCleaner(spec.Name(), podUID)
if err == nil && c == nil { if err == nil && c == nil {
return nil, errUnsupportedVolumeType return nil, errUnsupportedVolumeType
} }
@ -84,7 +85,15 @@ func (vh *volumeHost) GetCloudProvider() cloudprovider.Interface {
return vh.kubelet.cloud return vh.kubelet.cloud
} }
func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (vh *volumeHost) GetMounter() mount.Interface {
return vh.kubelet.mounter
}
func (vh *volumeHost) GetWriter() io.Writer {
return vh.kubelet.writer
}
func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
plugin, err := kl.volumePluginMgr.FindPluginBySpec(spec) plugin, err := kl.volumePluginMgr.FindPluginBySpec(spec)
if err != nil { if err != nil {
return nil, fmt.Errorf("can't use volume plugins for %s: %v", spec.Name(), err) return nil, fmt.Errorf("can't use volume plugins for %s: %v", spec.Name(), err)
@ -93,7 +102,7 @@ func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod,
// Not found but not an error // Not found but not an error
return nil, nil return nil, nil
} }
builder, err := plugin.NewBuilder(spec, pod, opts, mounter) builder, err := plugin.NewBuilder(spec, pod, opts)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to instantiate volume plugin for %s: %v", spec.Name(), err) return nil, fmt.Errorf("failed to instantiate volume plugin for %s: %v", spec.Name(), err)
} }
@ -113,7 +122,7 @@ func (kl *Kubelet) mountExternalVolumes(pod *api.Pod) (kubecontainer.VolumeMap,
// Try to use a plugin for this volume. // Try to use a plugin for this volume.
internal := volume.NewSpecFromVolume(volSpec) internal := volume.NewSpecFromVolume(volSpec)
builder, err := kl.newVolumeBuilderFromPlugins(internal, pod, volume.VolumeOptions{RootContext: rootContext}, kl.mounter) builder, err := kl.newVolumeBuilderFromPlugins(internal, pod, volume.VolumeOptions{RootContext: rootContext})
if err != nil { if err != nil {
glog.Errorf("Could not create volume builder for pod %s: %v", pod.UID, err) glog.Errorf("Could not create volume builder for pod %s: %v", pod.UID, err)
return nil, err return nil, err
@ -180,7 +189,7 @@ func (kl *Kubelet) getPodVolumesFromDisk() map[string]volume.Cleaner {
// or volume objects. // or volume objects.
// Try to use a plugin for this volume. // Try to use a plugin for this volume.
cleaner, err := kl.newVolumeCleanerFromPlugins(volume.Kind, volume.Name, podUID, kl.mounter) cleaner, err := kl.newVolumeCleanerFromPlugins(volume.Kind, volume.Name, podUID)
if err != nil { if err != nil {
glog.Errorf("Could not create volume cleaner for %s: %v", volume.Name, err) glog.Errorf("Could not create volume cleaner for %s: %v", volume.Name, err)
continue continue
@ -195,7 +204,7 @@ func (kl *Kubelet) getPodVolumesFromDisk() map[string]volume.Cleaner {
return currentVolumes return currentVolumes
} }
func (kl *Kubelet) newVolumeCleanerFromPlugins(kind string, name string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (kl *Kubelet) newVolumeCleanerFromPlugins(kind string, name string, podUID types.UID) (volume.Cleaner, error) {
plugName := util.UnescapeQualifiedNameForDisk(kind) plugName := util.UnescapeQualifiedNameForDisk(kind)
plugin, err := kl.volumePluginMgr.FindPluginByName(plugName) plugin, err := kl.volumePluginMgr.FindPluginByName(plugName)
if err != nil { if err != nil {
@ -206,7 +215,7 @@ func (kl *Kubelet) newVolumeCleanerFromPlugins(kind string, name string, podUID
// Not found but not an error. // Not found but not an error.
return nil, nil return nil, nil
} }
cleaner, err := plugin.NewCleaner(name, podUID, mounter) cleaner, err := plugin.NewCleaner(name, podUID)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to instantiate volume plugin for %s/%s: %v", podUID, kind, err) return nil, fmt.Errorf("failed to instantiate volume plugin for %s/%s: %v", podUID, kind, err)
} }

View File

@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package io package io_test
import ( import (
"fmt" "fmt"
"github.com/pborman/uuid" "github.com/pborman/uuid"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"os" "os"
"testing" "testing"
@ -36,11 +37,11 @@ func TestSavePodToFile(t *testing.T) {
path := fmt.Sprintf("/tmp/kube-io-test-%s", uuid.New()) path := fmt.Sprintf("/tmp/kube-io-test-%s", uuid.New())
defer os.Remove(path) defer os.Remove(path)
if err := SavePodToFile(pod, path, 777); err != nil { if err := io.SavePodToFile(pod, path, 777); err != nil {
t.Fatalf("failed to save pod to file: %v", err) t.Fatalf("failed to save pod to file: %v", err)
} }
podFromFile, err := LoadPodFromFile(path) podFromFile, err := io.LoadPodFromFile(path)
if err != nil { if err != nil {
t.Fatalf("failed to load pod from file: %v", err) t.Fatalf("failed to load pod from file: %v", err)
} }

77
pkg/util/io/writer.go Normal file
View File

@ -0,0 +1,77 @@
/*
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 io
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"github.com/golang/glog"
)
// Writer is an interface which allows to write data to a file.
type Writer interface {
WriteFile(filename string, data []byte, perm os.FileMode) error
}
// StdWriter implements Writer interface and uses standard libraries
// for writing data to files.
type StdWriter struct {
}
func (writer *StdWriter) WriteFile(filename string, data []byte, perm os.FileMode) error {
return ioutil.WriteFile(filename, data, perm)
}
// Alternative implementation of Writer interface that allows writing data to file
// using nsenter command.
// If a program (e.g. kubelet) runs in a container it may want to write data to
// a mounted device. Since in Docker, mount propagation mode is set to private,
// it will not see the mounted device in its own namespace. To work around this
// limitaion one has to first enter hosts namespace (by using 'nsenter') and only
// then write data.
type NsenterWriter struct {
}
func (writer *NsenterWriter) WriteFile(filename string, data []byte, perm os.FileMode) error {
cmd := "nsenter"
base_args := []string{
"--mount=/rootfs/proc/1/ns/mnt",
"--",
}
echo_args := append(base_args, "sh", "-c",
fmt.Sprintf("echo %q | cat > %s", data, filename))
glog.V(5).Infof("Command to write data to file: %v %v", cmd, echo_args)
outputBytes, err := exec.Command(cmd, echo_args...).CombinedOutput()
if err != nil {
glog.Errorf("Output from writing to %q: %v", filename, string(outputBytes))
return err
}
chmod_args := append(base_args, "chmod", fmt.Sprintf("%o", perm), filename)
glog.V(5).Infof("Command to change permissions to file: %v %v", cmd, chmod_args)
outputBytes, err = exec.Command(cmd, chmod_args...).CombinedOutput()
if err != nil {
glog.Errorf("Output from chmod command: %v", string(outputBytes))
return err
}
return nil
}

View File

@ -69,9 +69,9 @@ func (plugin *awsElasticBlockStorePlugin) GetAccessModes() []api.PersistentVolum
} }
} }
func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, pod.UID, &AWSDiskUtil{}, mounter) return plugin.newBuilderInternal(spec, pod.UID, &AWSDiskUtil{}, plugin.host.GetMounter())
} }
func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager ebsManager, mounter mount.Interface) (volume.Builder, error) { func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager ebsManager, mounter mount.Interface) (volume.Builder, error) {
@ -106,12 +106,12 @@ func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec,
fsType: fsType, fsType: fsType,
partition: partition, partition: partition,
readOnly: readOnly, readOnly: readOnly,
diskMounter: &mount.SafeFormatAndMount{mounter, exec.New()}}, nil diskMounter: &mount.SafeFormatAndMount{plugin.host.GetMounter(), exec.New()}}, nil
} }
func (plugin *awsElasticBlockStorePlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *awsElasticBlockStorePlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, &AWSDiskUtil{}, mounter) return plugin.newCleanerInternal(volName, podUID, &AWSDiskUtil{}, plugin.host.GetMounter())
} }
func (plugin *awsElasticBlockStorePlugin) newCleanerInternal(volName string, podUID types.UID, manager ebsManager, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *awsElasticBlockStorePlugin) newCleanerInternal(volName string, podUID types.UID, manager ebsManager, mounter mount.Interface) (volume.Cleaner, error) {

View File

@ -201,7 +201,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
// readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes
spec := volume.NewSpecFromPersistentVolume(pv, true) spec := volume.NewSpecFromPersistentVolume(pv, true)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if !builder.IsReadOnly() { if !builder.IsReadOnly() {
t.Errorf("Expected true for builder.IsReadOnly") t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -63,7 +63,7 @@ func (plugin *cephfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
} }
} }
func (plugin *cephfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *cephfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
cephvs := plugin.getVolumeSource(spec) cephvs := plugin.getVolumeSource(spec)
secret := "" secret := ""
if cephvs.SecretRef != nil { if cephvs.SecretRef != nil {
@ -82,7 +82,7 @@ func (plugin *cephfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume
glog.V(1).Infof("found ceph secret info: %s", name) glog.V(1).Infof("found ceph secret info: %s", name)
} }
} }
return plugin.newBuilderInternal(spec, pod.UID, mounter, secret) return plugin.newBuilderInternal(spec, pod.UID, plugin.host.GetMounter(), secret)
} }
func (plugin *cephfsPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, mounter mount.Interface, secret string) (volume.Builder, error) { func (plugin *cephfsPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, mounter mount.Interface, secret string) (volume.Builder, error) {
@ -110,8 +110,8 @@ func (plugin *cephfsPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U
}, nil }, nil
} }
func (plugin *cephfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *cephfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mounter) return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter())
} }
func (plugin *cephfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *cephfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {

View File

@ -62,8 +62,8 @@ func (plugin *cinderPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
} }
} }
func (plugin *cinderPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *cinderPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, pod.UID, &CinderDiskUtil{}, mounter) return plugin.newBuilderInternal(spec, pod.UID, &CinderDiskUtil{}, plugin.host.GetMounter())
} }
func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager cdManager, mounter mount.Interface) (volume.Builder, error) { func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager cdManager, mounter mount.Interface) (volume.Builder, error) {
@ -92,8 +92,8 @@ func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U
blockDeviceMounter: &cinderSafeFormatAndMount{mounter, exec.New()}}, nil blockDeviceMounter: &cinderSafeFormatAndMount{mounter, exec.New()}}, nil
} }
func (plugin *cinderPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *cinderPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, &CinderDiskUtil{}, mounter) return plugin.newCleanerInternal(volName, podUID, &CinderDiskUtil{}, plugin.host.GetMounter())
} }
func (plugin *cinderPlugin) newCleanerInternal(volName string, podUID types.UID, manager cdManager, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *cinderPlugin) newCleanerInternal(volName string, podUID types.UID, manager cdManager, mounter mount.Interface) (volume.Cleaner, error) {

View File

@ -30,7 +30,6 @@ import (
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
utilErrors "k8s.io/kubernetes/pkg/util/errors" utilErrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"github.com/golang/glog" "github.com/golang/glog"
@ -64,13 +63,12 @@ func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.DownwardAPI != nil return spec.Volume != nil && spec.Volume.DownwardAPI != nil
} }
func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (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,
mounter: mounter,
} }
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,8 +79,8 @@ func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opt
opts: &opts}, nil opts: &opts}, nil
} }
func (plugin *downwardAPIPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *downwardAPIPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return &downwardAPIVolumeCleaner{&downwardAPIVolume{volName: volName, podUID: podUID, plugin: plugin, mounter: mounter}}, 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. // downwardAPIVolume retrieves downward API data and placing them into the volume on the host.
@ -92,7 +90,6 @@ type downwardAPIVolume struct {
pod *api.Pod pod *api.Pod
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
mounter mount.Interface
} }
// This is the spec for the volume that this plugin wraps. // This is the spec for the volume that this plugin wraps.
@ -121,7 +118,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, b.mounter) wrapped, err := b.plugin.host.NewWrapperBuilder(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
@ -360,7 +357,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, c.mounter) wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID)
if err != nil { if err != nil {
return err return err
} }

View File

@ -27,7 +27,6 @@ import (
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/client/unversioned/testclient"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/empty_dir" "k8s.io/kubernetes/pkg/volume/empty_dir"
) )
@ -64,7 +63,7 @@ func TestCanSupport(t *testing.T) {
} }
func CleanEverything(plugin volume.VolumePlugin, testVolumeName, volumePath string, testPodUID types.UID, t *testing.T) { func CleanEverything(plugin volume.VolumePlugin, testVolumeName, volumePath string, testPodUID types.UID, t *testing.T) {
cleaner, err := plugin.NewCleaner(testVolumeName, testPodUID, mount.New()) cleaner, err := plugin.NewCleaner(testVolumeName, testPodUID)
if err != nil { if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err) t.Errorf("Failed to make a new Cleaner: %v", err)
} }
@ -117,7 +116,7 @@ func TestLabels(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
@ -182,7 +181,7 @@ func TestAnnotations(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Annotations: annotations}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Annotations: annotations}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -242,7 +241,7 @@ func TestName(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Name: testName}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Name: testName}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -303,7 +302,7 @@ func TestNamespace(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Namespace: testNamespace}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Namespace: testNamespace}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -366,7 +365,7 @@ func TestWriteTwiceNoUpdate(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
@ -450,7 +449,7 @@ func TestWriteTwiceWithUpdate(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
@ -556,7 +555,7 @@ func TestWriteWithUnixPath(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels, Annotations: annotations}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels, Annotations: annotations}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
@ -627,7 +626,7 @@ func TestWriteWithUnixPathBadPath(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)

View File

@ -69,8 +69,8 @@ func (plugin *emptyDirPlugin) CanSupport(spec *volume.Spec) bool {
return false return false
} }
func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, pod, mounter, &realMountDetector{mounter}, opts, newChconRunner()) return plugin.newBuilderInternal(spec, pod, plugin.host.GetMounter(), &realMountDetector{plugin.host.GetMounter()}, opts, newChconRunner())
} }
func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions, chconRunner chconRunner) (volume.Builder, error) { func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions, chconRunner chconRunner) (volume.Builder, error) {
@ -90,9 +90,9 @@ func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod
}, nil }, nil
} }
func (plugin *emptyDirPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *emptyDirPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, mounter, &realMountDetector{mounter}) return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter(), &realMountDetector{plugin.host.GetMounter()})
} }
func (plugin *emptyDirPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface, mountDetector mountDetector) (volume.Cleaner, error) { func (plugin *emptyDirPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface, mountDetector mountDetector) (volume.Cleaner, error) {

View File

@ -288,7 +288,7 @@ func TestPluginBackCompat(t *testing.T) {
Name: "vol1", Name: "vol1",
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{RootContext: ""}, nil) builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{RootContext: ""})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }

View File

@ -66,9 +66,9 @@ func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.PersistentVolumeAc
} }
} }
func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, pod.UID, &GCEDiskUtil{}, mounter) return plugin.newBuilderInternal(spec, pod.UID, &GCEDiskUtil{}, plugin.host.GetMounter())
} }
func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) { func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) {
@ -107,9 +107,9 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod
diskMounter: &mount.SafeFormatAndMount{mounter, exec.New()}}, nil diskMounter: &mount.SafeFormatAndMount{mounter, exec.New()}}, nil
} }
func (plugin *gcePersistentDiskPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *gcePersistentDiskPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, &GCEDiskUtil{}, mounter) return plugin.newCleanerInternal(volName, podUID, &GCEDiskUtil{}, plugin.host.GetMounter())
} }
func (plugin *gcePersistentDiskPlugin) newCleanerInternal(volName string, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *gcePersistentDiskPlugin) newCleanerInternal(volName string, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Cleaner, error) {

View File

@ -215,7 +215,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
// readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes
spec := volume.NewSpecFromPersistentVolume(pv, true) spec := volume.NewSpecFromPersistentVolume(pv, true)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if !builder.IsReadOnly() { if !builder.IsReadOnly() {
t.Errorf("Expected true for builder.IsReadOnly") t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -25,7 +25,6 @@ import (
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
) )
@ -57,12 +56,11 @@ func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.GitRepo != nil return spec.Volume != nil && spec.Volume.GitRepo != nil
} }
func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (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,
mounter: mounter,
plugin: plugin, plugin: plugin,
}, },
pod: *pod, pod: *pod,
@ -73,12 +71,11 @@ func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts vo
}, nil }, nil
} }
func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (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,
mounter: mounter,
plugin: plugin, plugin: plugin,
}, },
}, nil }, nil
@ -89,7 +86,6 @@ func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID, mounte
type gitRepoVolume struct { type gitRepoVolume struct {
volName string volName string
podUID types.UID podUID types.UID
mounter mount.Interface
plugin *gitRepoPlugin plugin *gitRepoPlugin
} }
@ -134,7 +130,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, b.mounter) wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, b.opts)
if err != nil { if err != nil {
return err return err
} }
@ -196,7 +192,7 @@ 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, c.mounter) wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID)
if err != nil { if err != nil {
return err return err
} }

View File

@ -27,7 +27,6 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/empty_dir" "k8s.io/kubernetes/pkg/volume/empty_dir"
) )
@ -120,7 +119,7 @@ func TestPlugin(t *testing.T) {
}, },
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{RootContext: ""}, mount.New()) builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{RootContext: ""})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -142,7 +141,7 @@ func TestPlugin(t *testing.T) {
} }
} }
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), mount.New()) cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"))
if err != nil { if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err) t.Errorf("Failed to make a new Cleaner: %v", err)
} }

View File

@ -66,7 +66,7 @@ func (plugin *glusterfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode
} }
} }
func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
source, _ := plugin.getGlusterVolumeSource(spec) source, _ := plugin.getGlusterVolumeSource(spec)
ep_name := source.EndpointsName ep_name := source.EndpointsName
ns := pod.Namespace ns := pod.Namespace
@ -76,7 +76,7 @@ func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ vol
return nil, err return nil, err
} }
glog.V(1).Infof("Glusterfs: endpoints %v", ep) glog.V(1).Infof("Glusterfs: endpoints %v", ep)
return plugin.newBuilderInternal(spec, ep, pod, mounter, exec.New()) return plugin.newBuilderInternal(spec, ep, pod, plugin.host.GetMounter(), exec.New())
} }
func (plugin *glusterfsPlugin) getGlusterVolumeSource(spec *volume.Spec) (*api.GlusterfsVolumeSource, bool) { func (plugin *glusterfsPlugin) getGlusterVolumeSource(spec *volume.Spec) (*api.GlusterfsVolumeSource, bool) {
@ -104,8 +104,8 @@ func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.End
exe: exe}, nil exe: exe}, nil
} }
func (plugin *glusterfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *glusterfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mounter) return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter())
} }
func (plugin *glusterfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *glusterfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {

View File

@ -210,7 +210,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
// readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes
spec := volume.NewSpecFromPersistentVolume(pv, true) spec := volume.NewSpecFromPersistentVolume(pv, true)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if !builder.IsReadOnly() { if !builder.IsReadOnly() {
t.Errorf("Expected true for builder.IsReadOnly") t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -23,7 +23,6 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
) )
@ -89,7 +88,7 @@ func (plugin *hostPathPlugin) GetAccessModes() []api.PersistentVolumeAccessMode
} }
} }
func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, _ mount.Interface) (volume.Builder, error) { func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
if spec.Volume != nil && spec.Volume.HostPath != nil { if spec.Volume != nil && spec.Volume.HostPath != nil {
return &hostPathBuilder{ return &hostPathBuilder{
hostPath: &hostPath{path: spec.Volume.HostPath.Path}, hostPath: &hostPath{path: spec.Volume.HostPath.Path},
@ -103,7 +102,7 @@ func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volu
} }
} }
func (plugin *hostPathPlugin) NewCleaner(volName string, podUID types.UID, _ mount.Interface) (volume.Cleaner, error) { func (plugin *hostPathPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return &hostPathCleaner{&hostPath{""}}, nil return &hostPathCleaner{&hostPath{""}}, nil
} }

View File

@ -156,7 +156,7 @@ func TestPlugin(t *testing.T) {
VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/vol1"}}, VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/vol1"}},
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{}, nil) builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -173,7 +173,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), nil) cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"))
if err != nil { if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err) t.Errorf("Failed to make a new Cleaner: %v", err)
} }
@ -227,7 +227,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
// readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes
spec := volume.NewSpecFromPersistentVolume(pv, true) spec := volume.NewSpecFromPersistentVolume(pv, true)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if !builder.IsReadOnly() { if !builder.IsReadOnly() {
t.Errorf("Expected true for builder.IsReadOnly") t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -75,9 +75,9 @@ func (plugin *iscsiPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
} }
} }
func (plugin *iscsiPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *iscsiPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, pod.UID, &ISCSIUtil{}, mounter) return plugin.newBuilderInternal(spec, pod.UID, &ISCSIUtil{}, plugin.host.GetMounter())
} }
func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Builder, error) { func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Builder, error) {
@ -110,9 +110,9 @@ func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UI
}, nil }, nil
} }
func (plugin *iscsiPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *iscsiPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, &ISCSIUtil{}, mounter) return plugin.newCleanerInternal(volName, podUID, &ISCSIUtil{}, plugin.host.GetMounter())
} }
func (plugin *iscsiPlugin) newCleanerInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *iscsiPlugin) newCleanerInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Cleaner, error) {

View File

@ -244,7 +244,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
// readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes
spec := volume.NewSpecFromPersistentVolume(pv, true) spec := volume.NewSpecFromPersistentVolume(pv, true)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if !builder.IsReadOnly() { if !builder.IsReadOnly() {
t.Errorf("Expected true for builder.IsReadOnly") t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -79,8 +79,8 @@ func (plugin *nfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
} }
} }
func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, pod, mounter) return plugin.newBuilderInternal(spec, pod, plugin.host.GetMounter())
} }
func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface) (volume.Builder, error) { func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface) (volume.Builder, error) {
@ -106,8 +106,8 @@ func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mou
}, nil }, nil
} }
func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mounter) return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter())
} }
func (plugin *nfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *nfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {

View File

@ -245,7 +245,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
// readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes
spec := volume.NewSpecFromPersistentVolume(pv, true) spec := volume.NewSpecFromPersistentVolume(pv, true)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if !builder.IsReadOnly() { if !builder.IsReadOnly() {
t.Errorf("Expected true for builder.IsReadOnly") t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -18,10 +18,10 @@ package persistent_claim
import ( import (
"fmt" "fmt"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
) )
@ -52,7 +52,7 @@ func (plugin *persistentClaimPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.PersistentVolumeClaim != nil return spec.Volume != nil && spec.Volume.PersistentVolumeClaim != nil
} }
func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
claim, err := plugin.host.GetKubeClient().PersistentVolumeClaims(pod.Namespace).Get(spec.Volume.PersistentVolumeClaim.ClaimName) claim, err := plugin.host.GetKubeClient().PersistentVolumeClaims(pod.Namespace).Get(spec.Volume.PersistentVolumeClaim.ClaimName)
if err != nil { if err != nil {
glog.Errorf("Error finding claim: %+v\n", spec.Volume.PersistentVolumeClaim.ClaimName) glog.Errorf("Error finding claim: %+v\n", spec.Volume.PersistentVolumeClaim.ClaimName)
@ -79,7 +79,7 @@ func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod,
return nil, err return nil, err
} }
builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv, spec.ReadOnly), pod, opts, mounter) builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv, spec.ReadOnly), pod, opts)
if err != nil { if err != nil {
glog.Errorf("Error creating builder for claim: %+v\n", claim.Name) glog.Errorf("Error creating builder for claim: %+v\n", claim.Name)
return nil, err return nil, err
@ -92,6 +92,6 @@ func (plugin *persistentClaimPlugin) IsReadOnly() bool {
return plugin.readOnly return plugin.readOnly
} }
func (plugin *persistentClaimPlugin) NewCleaner(_ string, _ types.UID, _ mount.Interface) (volume.Cleaner, error) { func (plugin *persistentClaimPlugin) NewCleaner(_ string, _ types.UID) (volume.Cleaner, error) {
return nil, fmt.Errorf("This will never be called directly. The PV backing this claim has a cleaner. Kubelet uses that cleaner, not this one, when removing orphaned volumes.") return nil, fmt.Errorf("This will never be called directly. The PV backing this claim has a cleaner. Kubelet uses that cleaner, not this one, when removing orphaned volumes.")
} }

View File

@ -249,7 +249,7 @@ func TestNewBuilder(t *testing.T) {
} }
spec := &volume.Spec{Volume: &api.Volume{VolumeSource: item.podVolume}} spec := &volume.Spec{Volume: &api.Volume{VolumeSource: item.podVolume}}
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if !item.expectedFailure { if !item.expectedFailure {
if err != nil { if err != nil {
@ -304,7 +304,7 @@ func TestNewBuilderClaimNotBound(t *testing.T) {
} }
spec := &volume.Spec{Volume: &api.Volume{VolumeSource: podVolume}} spec := &volume.Spec{Volume: &api.Volume{VolumeSource: podVolume}}
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if builder != nil { if builder != nil {
t.Errorf("Expected a nil builder if the claim wasn't bound") t.Errorf("Expected a nil builder if the claim wasn't bound")
} }

View File

@ -27,6 +27,7 @@ import (
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/validation" "k8s.io/kubernetes/pkg/util/validation"
) )
@ -64,12 +65,12 @@ type VolumePlugin interface {
// Ownership of the spec pointer in *not* transferred. // Ownership of the spec pointer in *not* transferred.
// - spec: The api.Volume spec // - spec: The api.Volume spec
// - pod: The enclosing pod // - pod: The enclosing pod
NewBuilder(spec *Spec, podRef *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) NewBuilder(spec *Spec, podRef *api.Pod, opts VolumeOptions) (Builder, error)
// NewCleaner creates a new volume.Cleaner from recoverable state. // NewCleaner creates a new volume.Cleaner from recoverable state.
// - name: The volume name, as per the api.Volume spec. // - name: The volume name, as per the api.Volume spec.
// - podUID: The UID of the enclosing pod // - podUID: The UID of the enclosing pod
NewCleaner(name string, podUID types.UID, mounter mount.Interface) (Cleaner, error) NewCleaner(name string, podUID types.UID) (Cleaner, error)
} }
// PersistentVolumePlugin is an extended interface of VolumePlugin and is used // PersistentVolumePlugin is an extended interface of VolumePlugin and is used
@ -125,15 +126,21 @@ type VolumeHost interface {
// the provided spec. This is used to implement volume plugins which // the provided spec. This is used to implement volume plugins which
// "wrap" other plugins. For example, the "secret" volume is // "wrap" other plugins. For example, the "secret" volume is
// implemented in terms of the "emptyDir" volume. // implemented in terms of the "emptyDir" volume.
NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions) (Builder, error)
// NewWrapperCleaner finds an appropriate plugin with which to handle // NewWrapperCleaner finds an appropriate plugin with which to handle
// the provided spec. See comments on NewWrapperBuilder for more // the provided spec. See comments on NewWrapperBuilder for more
// context. // context.
NewWrapperCleaner(spec *Spec, podUID types.UID, mounter mount.Interface) (Cleaner, error) NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error)
//Get cloud provider from kubelet // Get cloud provider from kubelet.
GetCloudProvider() cloudprovider.Interface GetCloudProvider() cloudprovider.Interface
// Get mounter interface.
GetMounter() mount.Interface
// Get writer interface for writing data to disk.
GetWriter() io.Writer
} }
// VolumePluginMgr tracks registered plugins. // VolumePluginMgr tracks registered plugins.

View File

@ -73,7 +73,7 @@ func (plugin *rbdPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
} }
} }
func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
secret := "" secret := ""
source, _ := plugin.getRBDVolumeSource(spec) source, _ := plugin.getRBDVolumeSource(spec)
@ -95,7 +95,7 @@ func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.Vo
} }
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, pod.UID, &RBDUtil{}, mounter, secret) return plugin.newBuilderInternal(spec, pod.UID, &RBDUtil{}, plugin.host.GetMounter(), secret)
} }
func (plugin *rbdPlugin) getRBDVolumeSource(spec *volume.Spec) (*api.RBDVolumeSource, bool) { func (plugin *rbdPlugin) getRBDVolumeSource(spec *volume.Spec) (*api.RBDVolumeSource, bool) {
@ -142,9 +142,9 @@ func (plugin *rbdPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID,
}, nil }, nil
} }
func (plugin *rbdPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *rbdPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, &RBDUtil{}, mounter) return plugin.newCleanerInternal(volName, podUID, &RBDUtil{}, plugin.host.GetMounter())
} }
func (plugin *rbdPlugin) newCleanerInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *rbdPlugin) newCleanerInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Cleaner, error) {

View File

@ -201,7 +201,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
// readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes
spec := volume.NewSpecFromPersistentVolume(pv, true) spec := volume.NewSpecFromPersistentVolume(pv, true)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{})
if !builder.IsReadOnly() { if !builder.IsReadOnly() {
t.Errorf("Expected true for builder.IsReadOnly") t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -18,7 +18,6 @@ package secret
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path" "path"
@ -26,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
ioutil "k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
@ -59,16 +59,16 @@ func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.Secret != nil return spec.Volume != nil && spec.Volume.Secret != nil
} }
func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (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, mounter}, secretVolume: &secretVolume{spec.Name(), pod.UID, plugin, plugin.host.GetMounter(), plugin.host.GetWriter()},
secretName: spec.Volume.Secret.SecretName, secretName: spec.Volume.Secret.SecretName,
pod: *pod, pod: *pod,
opts: &opts}, nil opts: &opts}, nil
} }
func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return &secretVolumeCleaner{&secretVolume{volName, podUID, plugin, mounter}}, nil return &secretVolumeCleaner{&secretVolume{volName, podUID, plugin, plugin.host.GetMounter(), plugin.host.GetWriter()}}, nil
} }
type secretVolume struct { type secretVolume struct {
@ -76,6 +76,7 @@ type secretVolume struct {
podUID types.UID podUID types.UID
plugin *secretPlugin plugin *secretPlugin
mounter mount.Interface mounter mount.Interface
writer ioutil.Writer
} }
var _ volume.Volume = &secretVolume{} var _ volume.Volume = &secretVolume{}
@ -126,7 +127,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, b.mounter) wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, *b.opts)
if err != nil { if err != nil {
return err return err
} }
@ -155,7 +156,7 @@ func (b *secretVolumeBuilder) SetUpAt(dir string) error {
for name, data := range secret.Data { for name, data := range secret.Data {
hostFilePath := path.Join(dir, name) hostFilePath := path.Join(dir, name)
glog.V(3).Infof("Writing secret data %v/%v/%v (%v bytes) to host file %v", b.pod.Namespace, b.secretName, name, len(data), hostFilePath) glog.V(3).Infof("Writing secret data %v/%v/%v (%v bytes) to host file %v", b.pod.Namespace, b.secretName, name, len(data), hostFilePath)
err := ioutil.WriteFile(hostFilePath, data, 0444) err := b.writer.WriteFile(hostFilePath, data, 0444)
if err != nil { if err != nil {
glog.Errorf("Error writing secret data to host path: %v, %v", hostFilePath, err) glog.Errorf("Error writing secret data to host path: %v, %v", hostFilePath, err)
return err return err
@ -195,7 +196,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, c.mounter) wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID)
if err != nil { if err != nil {
return err return err
} }

View File

@ -85,7 +85,7 @@ func TestPlugin(t *testing.T) {
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -140,14 +140,14 @@ func TestPluginIdempotent(t *testing.T) {
podVolumeDir := fmt.Sprintf("%v/pods/test_pod_uid2/volumes/kubernetes.io~secret/test_volume_name", rootDir) podVolumeDir := fmt.Sprintf("%v/pods/test_pod_uid2/volumes/kubernetes.io~secret/test_volume_name", rootDir)
podMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid2/plugins/kubernetes.io~secret/test_volume_name", rootDir) podMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid2/plugins/kubernetes.io~secret/test_volume_name", rootDir)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}}
mounter := &mount.FakeMounter{} mounter := host.GetMounter().(*mount.FakeMounter)
mounter.MountPoints = []mount.MountPoint{ mounter.MountPoints = []mount.MountPoint{
{ {
Path: podVolumeDir, Path: podVolumeDir,
}, },
} }
util.SetReady(podMetadataDir) util.SetReady(podMetadataDir)
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, mounter) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -199,7 +199,7 @@ func TestPluginReboot(t *testing.T) {
} }
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -275,7 +275,7 @@ func doTestSecretDataInVolume(volumePath string, secret api.Secret, t *testing.T
} }
func doTestCleanAndTeardown(plugin volume.VolumePlugin, podUID types.UID, testVolumeName, volumePath string, t *testing.T) { func doTestCleanAndTeardown(plugin volume.VolumePlugin, podUID types.UID, testVolumeName, volumePath string, t *testing.T) {
cleaner, err := plugin.NewCleaner(testVolumeName, podUID, mount.New()) cleaner, err := plugin.NewCleaner(testVolumeName, podUID)
if err != nil { if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err) t.Errorf("Failed to make a new Cleaner: %v", err)
} }

View File

@ -26,6 +26,7 @@ import (
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
) )
@ -35,10 +36,14 @@ type fakeVolumeHost struct {
kubeClient client.Interface kubeClient client.Interface
pluginMgr VolumePluginMgr pluginMgr VolumePluginMgr
cloud cloudprovider.Interface cloud cloudprovider.Interface
mounter mount.Interface
writer io.Writer
} }
func NewFakeVolumeHost(rootDir string, kubeClient client.Interface, plugins []VolumePlugin) *fakeVolumeHost { func NewFakeVolumeHost(rootDir string, kubeClient client.Interface, plugins []VolumePlugin) *fakeVolumeHost {
host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: nil} host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: nil}
host.mounter = &mount.FakeMounter{}
host.writer = &io.StdWriter{}
host.pluginMgr.InitPlugins(plugins, host) host.pluginMgr.InitPlugins(plugins, host)
return host return host
} }
@ -63,20 +68,28 @@ func (f *fakeVolumeHost) GetCloudProvider() cloudprovider.Interface {
return f.cloud return f.cloud
} }
func (f *fakeVolumeHost) NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) { func (f *fakeVolumeHost) GetMounter() mount.Interface {
plug, err := f.pluginMgr.FindPluginBySpec(spec) return f.mounter
if err != nil {
return nil, err
}
return plug.NewBuilder(spec, pod, opts, mounter)
} }
func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID, mounter mount.Interface) (Cleaner, error) { 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) plug, err := f.pluginMgr.FindPluginBySpec(spec)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return plug.NewCleaner(spec.Name(), podUID, mounter) return plug.NewBuilder(spec, pod, opts)
}
func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error) {
plug, err := f.pluginMgr.FindPluginBySpec(spec)
if err != nil {
return nil, err
}
return plug.NewCleaner(spec.Name(), podUID)
} }
func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin { func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin {
@ -117,11 +130,11 @@ func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool {
return true return true
} }
func (plugin *FakeVolumePlugin) NewBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) { func (plugin *FakeVolumePlugin) NewBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions) (Builder, error) {
return &FakeVolume{pod.UID, spec.Name(), plugin}, nil return &FakeVolume{pod.UID, spec.Name(), plugin}, nil
} }
func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (Cleaner, error) { func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID) (Cleaner, error) {
return &FakeVolume{podUID, volName, plugin}, nil return &FakeVolume{podUID, volName, plugin}, nil
} }