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

View File

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

View File

@ -30,6 +30,7 @@ import (
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
ioutil "k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/watch"
@ -273,14 +274,22 @@ func (f *PersistentVolumeRecycler) GetKubeClient() client.Interface {
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")
}
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")
}
func (f *PersistentVolumeRecycler) GetCloudProvider() cloudprovider.Interface {
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/bandwidth"
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/oom"
"k8s.io/kubernetes/pkg/util/procfs"
@ -161,6 +162,7 @@ func NewMainKubelet(
rktPath string,
rktStage1Image string,
mounter mount.Interface,
writer kubeio.Writer,
dockerDaemonContainer string,
systemContainer string,
configureCBR0 bool,
@ -261,6 +263,7 @@ func NewMainKubelet(
oomWatcher: oomWatcher,
cgroupRoot: cgroupRoot,
mounter: mounter,
writer: writer,
configureCBR0: configureCBR0,
pods: pods,
syncLoopMonitor: util.AtomicValue{},
@ -499,6 +502,9 @@ type Kubelet struct {
// Mounter to use for volumes.
mounter mount.Interface
// Writer interface to use for volumes.
writer kubeio.Writer
// Manager of non-Runtime containers.
containerManager containerManager

View File

@ -28,6 +28,7 @@ import (
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
)
@ -56,15 +57,15 @@ func (vh *volumeHost) GetKubeClient() client.Interface {
return vh.kubelet.kubeClient
}
func (vh *volumeHost) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, pod, opts, mounter)
func (vh *volumeHost) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, pod, opts)
if err == nil && b == nil {
return nil, errUnsupportedVolumeType
}
return b, nil
}
func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, 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)
if err != nil {
return nil, err
@ -73,7 +74,7 @@ func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, mou
// Not found but not an error
return nil, nil
}
c, err := plugin.NewCleaner(spec.Name(), podUID, mounter)
c, err := plugin.NewCleaner(spec.Name(), podUID)
if err == nil && c == nil {
return nil, errUnsupportedVolumeType
}
@ -84,7 +85,15 @@ func (vh *volumeHost) GetCloudProvider() cloudprovider.Interface {
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)
if err != nil {
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
return nil, nil
}
builder, err := plugin.NewBuilder(spec, pod, opts, mounter)
builder, err := plugin.NewBuilder(spec, pod, opts)
if err != nil {
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.
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 {
glog.Errorf("Could not create volume builder for pod %s: %v", pod.UID, err)
return nil, err
@ -180,7 +189,7 @@ func (kl *Kubelet) getPodVolumesFromDisk() map[string]volume.Cleaner {
// or volume objects.
// 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 {
glog.Errorf("Could not create volume cleaner for %s: %v", volume.Name, err)
continue
@ -195,7 +204,7 @@ func (kl *Kubelet) getPodVolumesFromDisk() map[string]volume.Cleaner {
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)
plugin, err := kl.volumePluginMgr.FindPluginByName(plugName)
if err != nil {
@ -206,7 +215,7 @@ func (kl *Kubelet) newVolumeCleanerFromPlugins(kind string, name string, podUID
// Not found but not an error.
return nil, nil
}
cleaner, err := plugin.NewCleaner(name, podUID, mounter)
cleaner, err := plugin.NewCleaner(name, podUID)
if err != nil {
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.
*/
package io
package io_test
import (
"fmt"
"github.com/pborman/uuid"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/volume"
"os"
"testing"
@ -36,11 +37,11 @@ func TestSavePodToFile(t *testing.T) {
path := fmt.Sprintf("/tmp/kube-io-test-%s", uuid.New())
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)
}
podFromFile, err := LoadPodFromFile(path)
podFromFile, err := io.LoadPodFromFile(path)
if err != nil {
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.
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) {
@ -106,12 +106,12 @@ func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec,
fsType: fsType,
partition: partition,
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.
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) {

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
spec := volume.NewSpecFromPersistentVolume(pv, true)
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() {
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)
secret := ""
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)
}
}
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) {
@ -110,8 +110,8 @@ func (plugin *cephfsPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U
}, nil
}
func (plugin *cephfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mounter)
func (plugin *cephfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter())
}
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) {
return plugin.newBuilderInternal(spec, pod.UID, &CinderDiskUtil{}, mounter)
func (plugin *cinderPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
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) {
@ -92,8 +92,8 @@ func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U
blockDeviceMounter: &cinderSafeFormatAndMount{mounter, exec.New()}}, nil
}
func (plugin *cinderPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, &CinderDiskUtil{}, mounter)
func (plugin *cinderPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
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) {

View File

@ -30,7 +30,6 @@ import (
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util"
utilErrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
"github.com/golang/glog"
@ -64,13 +63,12 @@ func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool {
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{
volName: spec.Name(),
pod: pod,
podUID: pod.UID,
plugin: plugin,
mounter: mounter,
}
v.fieldReferenceFileNames = make(map[string]string)
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
}
func (plugin *downwardAPIPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return &downwardAPIVolumeCleaner{&downwardAPIVolume{volName: volName, podUID: podUID, plugin: plugin, mounter: mounter}}, nil
func (plugin *downwardAPIPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return &downwardAPIVolumeCleaner{&downwardAPIVolume{volName: volName, podUID: podUID, plugin: plugin}}, nil
}
// downwardAPIVolume retrieves downward API data and placing them into the volume on the host.
@ -92,7 +90,6 @@ type downwardAPIVolume struct {
pod *api.Pod
podUID types.UID // TODO: remove this redundancy as soon NewCleaner func will have *api.POD and not only types.UID
plugin *downwardAPIPlugin
mounter mount.Interface
}
// 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 {
glog.V(3).Infof("Setting up a downwardAPI volume %v for pod %v/%v at %v", b.volName, b.pod.Namespace, b.pod.Name, dir)
// Wrap EmptyDir. Here we rely on the idempotency of the wrapped plugin to avoid repeatedly mounting
wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, b.pod, *b.opts, b.mounter)
wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, b.pod, *b.opts)
if err != nil {
glog.Errorf("Couldn't setup downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error())
return err
@ -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)
// 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 {
return err
}

View File

@ -27,7 +27,6 @@ import (
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
"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) {
cleaner, err := plugin.NewCleaner(testVolumeName, testPodUID, mount.New())
cleaner, err := plugin.NewCleaner(testVolumeName, testPodUID)
if err != nil {
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")
}
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 {
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")
}
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 {
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")
}
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 {
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")
}
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 {
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")
}
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 {
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")
}
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 {
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")
}
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 {
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")
}
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 {
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
}
func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, pod, mounter, &realMountDetector{mounter}, opts, newChconRunner())
func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
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) {
@ -90,9 +90,9 @@ func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod
}, 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.
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) {

View File

@ -288,7 +288,7 @@ func TestPluginBackCompat(t *testing.T) {
Name: "vol1",
}
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 {
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.
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) {
@ -107,9 +107,9 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod
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.
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) {

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
spec := volume.NewSpecFromPersistentVolume(pv, true)
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() {
t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -25,7 +25,6 @@ import (
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
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
}
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{
gitRepoVolume: &gitRepoVolume{
volName: spec.Name(),
podUID: pod.UID,
mounter: mounter,
plugin: plugin,
},
pod: *pod,
@ -73,12 +71,11 @@ func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts vo
}, 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{
&gitRepoVolume{
volName: volName,
podUID: podUID,
mounter: mounter,
plugin: plugin,
},
}, nil
@ -89,7 +86,6 @@ func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID, mounte
type gitRepoVolume struct {
volName string
podUID types.UID
mounter mount.Interface
plugin *gitRepoPlugin
}
@ -134,7 +130,7 @@ func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error {
}
// Wrap EmptyDir, let it do the setup.
wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, b.opts, b.mounter)
wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, b.opts)
if err != nil {
return err
}
@ -196,7 +192,7 @@ func (c *gitRepoVolumeCleaner) TearDown() error {
// TearDownAt simply deletes everything in the directory.
func (c *gitRepoVolumeCleaner) TearDownAt(dir string) error {
// Wrap EmptyDir, let it do the teardown.
wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID, c.mounter)
wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID)
if err != nil {
return err
}

View File

@ -27,7 +27,6 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
"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")}}
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 {
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 {
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)
ep_name := source.EndpointsName
ns := pod.Namespace
@ -76,7 +76,7 @@ func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ vol
return nil, err
}
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) {
@ -104,8 +104,8 @@ func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.End
exe: exe}, nil
}
func (plugin *glusterfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mounter)
func (plugin *glusterfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter())
}
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
spec := volume.NewSpecFromPersistentVolume(pv, true)
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() {
t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -23,7 +23,6 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/mount"
"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 {
return &hostPathBuilder{
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
}

View File

@ -156,7 +156,7 @@ func TestPlugin(t *testing.T) {
VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/vol1"}},
}
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 {
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)
}
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), nil)
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"))
if err != nil {
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
spec := volume.NewSpecFromPersistentVolume(pv, true)
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() {
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.
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) {
@ -110,9 +110,9 @@ func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UI
}, 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.
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) {

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
spec := volume.NewSpecFromPersistentVolume(pv, true)
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() {
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) {
return plugin.newBuilderInternal(spec, pod, mounter)
func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, pod, plugin.host.GetMounter())
}
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
}
func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mounter)
func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter())
}
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
spec := volume.NewSpecFromPersistentVolume(pv, true)
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() {
t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -18,10 +18,10 @@ package persistent_claim
import (
"fmt"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/mount"
"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
}
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)
if err != nil {
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
}
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 {
glog.Errorf("Error creating builder for claim: %+v\n", claim.Name)
return nil, err
@ -92,6 +92,6 @@ func (plugin *persistentClaimPlugin) IsReadOnly() bool {
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.")
}

View File

@ -249,7 +249,7 @@ func TestNewBuilder(t *testing.T) {
}
spec := &volume.Spec{Volume: &api.Volume{VolumeSource: item.podVolume}}
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 err != nil {
@ -304,7 +304,7 @@ func TestNewBuilderClaimNotBound(t *testing.T) {
}
spec := &volume.Spec{Volume: &api.Volume{VolumeSource: podVolume}}
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 {
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/types"
"k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/validation"
)
@ -64,12 +65,12 @@ type VolumePlugin interface {
// Ownership of the spec pointer in *not* transferred.
// - spec: The api.Volume spec
// - 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.
// - name: The volume name, as per the api.Volume spec.
// - 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
@ -125,15 +126,21 @@ type VolumeHost interface {
// the provided spec. This is used to implement volume plugins which
// "wrap" other plugins. For example, the "secret" volume is
// implemented in terms of the "emptyDir" volume.
NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error)
NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions) (Builder, error)
// NewWrapperCleaner finds an appropriate plugin with which to handle
// the provided spec. See comments on NewWrapperBuilder for more
// context.
NewWrapperCleaner(spec *Spec, podUID types.UID, 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
// Get mounter interface.
GetMounter() mount.Interface
// Get writer interface for writing data to disk.
GetWriter() io.Writer
}
// 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 := ""
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.
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) {
@ -142,9 +142,9 @@ func (plugin *rbdPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID,
}, 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.
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) {

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
spec := volume.NewSpecFromPersistentVolume(pv, true)
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() {
t.Errorf("Expected true for builder.IsReadOnly")

View File

@ -18,7 +18,6 @@ package secret
import (
"fmt"
"io/ioutil"
"os"
"path"
@ -26,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util"
ioutil "k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
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
}
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{
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,
pod: *pod,
opts: &opts}, nil
}
func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return &secretVolumeCleaner{&secretVolume{volName, podUID, plugin, mounter}}, nil
func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return &secretVolumeCleaner{&secretVolume{volName, podUID, plugin, plugin.host.GetMounter(), plugin.host.GetWriter()}}, nil
}
type secretVolume struct {
@ -76,6 +76,7 @@ type secretVolume struct {
podUID types.UID
plugin *secretPlugin
mounter mount.Interface
writer ioutil.Writer
}
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)
// 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 {
return err
}
@ -155,7 +156,7 @@ func (b *secretVolumeBuilder) SetUpAt(dir string) error {
for name, data := range secret.Data {
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)
err := ioutil.WriteFile(hostFilePath, data, 0444)
err := b.writer.WriteFile(hostFilePath, data, 0444)
if err != nil {
glog.Errorf("Error writing secret data to host path: %v, %v", hostFilePath, 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)
// 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 {
return err
}

View File

@ -85,7 +85,7 @@ func TestPlugin(t *testing.T) {
}
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 {
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)
podMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid2/plugins/kubernetes.io~secret/test_volume_name", rootDir)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}}
mounter := &mount.FakeMounter{}
mounter := host.GetMounter().(*mount.FakeMounter)
mounter.MountPoints = []mount.MountPoint{
{
Path: podVolumeDir,
},
}
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 {
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}}
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 {
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) {
cleaner, err := plugin.NewCleaner(testVolumeName, podUID, mount.New())
cleaner, err := plugin.NewCleaner(testVolumeName, podUID)
if err != nil {
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/types"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/io"
"k8s.io/kubernetes/pkg/util/mount"
)
@ -35,10 +36,14 @@ type fakeVolumeHost struct {
kubeClient client.Interface
pluginMgr VolumePluginMgr
cloud cloudprovider.Interface
mounter mount.Interface
writer io.Writer
}
func NewFakeVolumeHost(rootDir string, kubeClient client.Interface, plugins []VolumePlugin) *fakeVolumeHost {
host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: nil}
host.mounter = &mount.FakeMounter{}
host.writer = &io.StdWriter{}
host.pluginMgr.InitPlugins(plugins, host)
return host
}
@ -63,20 +68,28 @@ func (f *fakeVolumeHost) GetCloudProvider() cloudprovider.Interface {
return f.cloud
}
func (f *fakeVolumeHost) NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) {
plug, err := f.pluginMgr.FindPluginBySpec(spec)
if err != nil {
return nil, err
}
return plug.NewBuilder(spec, pod, opts, mounter)
func (f *fakeVolumeHost) GetMounter() mount.Interface {
return f.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)
if err != nil {
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 {
@ -117,11 +130,11 @@ func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool {
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
}
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
}