diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index f5098d9bf99..358f560ab9a 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -183,12 +183,6 @@ const ( // Enable nodes to exclude themselves from network disruption checks NodeDisruptionExclusion featuregate.Feature = "NodeDisruptionExclusion" - // owner: @jsafrane - // alpha: v1.9 - // - // Enable running mount utilities in containers. - MountContainers featuregate.Feature = "MountContainers" - // owner: @saad-ali // alpha: v1.12 // beta: v1.14 @@ -532,7 +526,6 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS TopologyManager: {Default: false, PreRelease: featuregate.Alpha}, ServiceNodeExclusion: {Default: false, PreRelease: featuregate.Alpha}, NodeDisruptionExclusion: {Default: false, PreRelease: featuregate.Alpha}, - MountContainers: {Default: false, PreRelease: featuregate.Alpha}, CSIDriverRegistry: {Default: true, PreRelease: featuregate.Beta}, CSINodeInfo: {Default: true, PreRelease: featuregate.Beta}, BlockVolume: {Default: true, PreRelease: featuregate.Beta}, diff --git a/pkg/kubelet/BUILD b/pkg/kubelet/BUILD index 74580901464..93b5aa8a45a 100644 --- a/pkg/kubelet/BUILD +++ b/pkg/kubelet/BUILD @@ -63,7 +63,6 @@ go_library( "//pkg/kubelet/logs:go_default_library", "//pkg/kubelet/metrics:go_default_library", "//pkg/kubelet/metrics/collectors:go_default_library", - "//pkg/kubelet/mountpod:go_default_library", "//pkg/kubelet/network/dns:go_default_library", "//pkg/kubelet/nodelease:go_default_library", "//pkg/kubelet/nodestatus:go_default_library", @@ -109,7 +108,6 @@ go_library( "//pkg/volume:go_default_library", "//pkg/volume/csi:go_default_library", "//pkg/volume/util:go_default_library", - "//pkg/volume/util/exec:go_default_library", "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/subpath:go_default_library", "//pkg/volume/util/types:go_default_library", @@ -293,7 +291,6 @@ filegroup( "//pkg/kubelet/lifecycle:all-srcs", "//pkg/kubelet/logs:all-srcs", "//pkg/kubelet/metrics:all-srcs", - "//pkg/kubelet/mountpod:all-srcs", "//pkg/kubelet/network:all-srcs", "//pkg/kubelet/nodelease:all-srcs", "//pkg/kubelet/nodestatus:all-srcs", diff --git a/pkg/kubelet/mountpod/BUILD b/pkg/kubelet/mountpod/BUILD deleted file mode 100644 index bcb1961dd77..00000000000 --- a/pkg/kubelet/mountpod/BUILD +++ /dev/null @@ -1,44 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -go_library( - name = "go_default_library", - srcs = ["mount_pod.go"], - importpath = "k8s.io/kubernetes/pkg/kubelet/mountpod", - visibility = ["//visibility:public"], - deps = [ - "//pkg/kubelet/config:go_default_library", - "//pkg/kubelet/pod:go_default_library", - "//staging/src/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/utils/strings:go_default_library", - ], -) - -go_test( - name = "go_default_test", - srcs = ["mount_pod_test.go"], - embed = [":go_default_library"], - deps = [ - "//pkg/kubelet/configmap:go_default_library", - "//pkg/kubelet/pod:go_default_library", - "//pkg/kubelet/pod/testing:go_default_library", - "//pkg/kubelet/secret:go_default_library", - "//staging/src/k8s.io/api/core/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/client-go/util/testing:go_default_library", - "//vendor/k8s.io/klog:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], - visibility = ["//visibility:public"], -) diff --git a/pkg/kubelet/mountpod/mount_pod.go b/pkg/kubelet/mountpod/mount_pod.go deleted file mode 100644 index 2adb3e9bfbb..00000000000 --- a/pkg/kubelet/mountpod/mount_pod.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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 mountpod - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path" - - "k8s.io/api/core/v1" - "k8s.io/kubernetes/pkg/kubelet/config" - kubepod "k8s.io/kubernetes/pkg/kubelet/pod" - utilstrings "k8s.io/utils/strings" -) - -// Manager is an interface that tracks pods with mount utilities for individual -// volume plugins. -type Manager interface { - GetMountPod(pluginName string) (pod *v1.Pod, container string, err error) -} - -// basicManager is simple implementation of Manager. Pods with mount utilities -// are registered by placing a JSON file into -// /var/lib/kubelet/plugin-containers/.json and this manager just -// finds them there. -type basicManager struct { - registrationDirectory string - podManager kubepod.Manager -} - -// volumePluginRegistration specified format of the json files placed in -// /var/lib/kubelet/plugin-containers/ -type volumePluginRegistration struct { - PodName string `json:"podName"` - PodNamespace string `json:"podNamespace"` - PodUID string `json:"podUID"` - ContainerName string `json:"containerName"` -} - -// NewManager returns a new mount pod manager. -func NewManager(rootDirectory string, podManager kubepod.Manager) (Manager, error) { - regPath := path.Join(rootDirectory, config.DefaultKubeletPluginContainersDirName) - - // Create the directory on startup - os.MkdirAll(regPath, 0700) - - return &basicManager{ - registrationDirectory: regPath, - podManager: podManager, - }, nil -} - -func (m *basicManager) getVolumePluginRegistrationPath(pluginName string) string { - // sanitize plugin name so it does not escape directory - safePluginName := utilstrings.EscapeQualifiedName(pluginName) + ".json" - return path.Join(m.registrationDirectory, safePluginName) -} - -func (m *basicManager) GetMountPod(pluginName string) (pod *v1.Pod, containerName string, err error) { - // Read /var/lib/kubelet/plugin-containers/.json - regPath := m.getVolumePluginRegistrationPath(pluginName) - regBytes, err := ioutil.ReadFile(regPath) - if err != nil { - if os.IsNotExist(err) { - // No pod is registered for this plugin - return nil, "", nil - } - return nil, "", fmt.Errorf("cannot read %s: %v", regPath, err) - } - - // Parse json - var reg volumePluginRegistration - if err := json.Unmarshal(regBytes, ®); err != nil { - return nil, "", fmt.Errorf("unable to parse %s: %s", regPath, err) - } - if len(reg.ContainerName) == 0 { - return nil, "", fmt.Errorf("unable to parse %s: \"containerName\" is not set", regPath) - } - if len(reg.PodUID) == 0 { - return nil, "", fmt.Errorf("unable to parse %s: \"podUID\" is not set", regPath) - } - if len(reg.PodNamespace) == 0 { - return nil, "", fmt.Errorf("unable to parse %s: \"podNamespace\" is not set", regPath) - } - if len(reg.PodName) == 0 { - return nil, "", fmt.Errorf("unable to parse %s: \"podName\" is not set", regPath) - } - - pod, ok := m.podManager.GetPodByName(reg.PodNamespace, reg.PodName) - if !ok { - return nil, "", fmt.Errorf("unable to process %s: pod %s/%s not found", regPath, reg.PodNamespace, reg.PodName) - } - if string(pod.UID) != reg.PodUID { - return nil, "", fmt.Errorf("unable to process %s: pod %s/%s has unexpected UID", regPath, reg.PodNamespace, reg.PodName) - } - // make sure that reg.ContainerName exists in the pod - for i := range pod.Spec.Containers { - if pod.Spec.Containers[i].Name == reg.ContainerName { - return pod, reg.ContainerName, nil - } - } - return nil, "", fmt.Errorf("unable to process %s: pod %s/%s has no container named %q", regPath, reg.PodNamespace, reg.PodName, reg.ContainerName) - -} diff --git a/pkg/kubelet/mountpod/mount_pod_test.go b/pkg/kubelet/mountpod/mount_pod_test.go deleted file mode 100644 index e248b5e3df5..00000000000 --- a/pkg/kubelet/mountpod/mount_pod_test.go +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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 mountpod - -import ( - "io/ioutil" - "os" - "path" - "testing" - - "k8s.io/klog" - - "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - utiltesting "k8s.io/client-go/util/testing" - "k8s.io/kubernetes/pkg/kubelet/configmap" - kubepod "k8s.io/kubernetes/pkg/kubelet/pod" - podtest "k8s.io/kubernetes/pkg/kubelet/pod/testing" - "k8s.io/kubernetes/pkg/kubelet/secret" -) - -func TestGetVolumeExec(t *testing.T) { - // prepare PodManager - pods := []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{ - UID: "12345678", - Name: "foo", - Namespace: "bar", - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - {Name: "baz"}, - }, - }, - }, - } - fakeSecretManager := secret.NewFakeManager() - fakeConfigMapManager := configmap.NewFakeManager() - podManager := kubepod.NewBasicPodManager( - podtest.NewFakeMirrorClient(), fakeSecretManager, fakeConfigMapManager, podtest.NewMockCheckpointManager()) - podManager.SetPods(pods) - - // Prepare fake /var/lib/kubelet - basePath, err := utiltesting.MkTmpdir("kubelet") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(basePath) - regPath := path.Join(basePath, "plugin-containers") - - mgr, err := NewManager(basePath, podManager) - if err != nil { - t.Fatal(err) - } - - tests := []struct { - name string - json string - expectError bool - }{ - { - "invalid json", - "{{{}", - true, - }, - { - "missing json", - "", // this means no json file should be created - false, - }, - { - "missing podNamespace", - `{"podName": "foo", "podUID": "87654321", "containerName": "baz"}`, - true, - }, - { - "missing podName", - `{"podNamespace": "bar", "podUID": "87654321", "containerName": "baz"}`, - true, - }, - { - "missing containerName", - `{"podNamespace": "bar", "podName": "foo", "podUID": "87654321"}`, - true, - }, - { - "missing podUID", - `{"podNamespace": "bar", "podName": "foo", "containerName": "baz"}`, - true, - }, - { - "missing pod", - `{"podNamespace": "bar", "podName": "non-existing-pod", "podUID": "12345678", "containerName": "baz"}`, - true, - }, - { - "invalid uid", - `{"podNamespace": "bar", "podName": "foo", "podUID": "87654321", "containerName": "baz"}`, - true, - }, - { - "invalid container", - `{"podNamespace": "bar", "podName": "foo", "podUID": "12345678", "containerName": "invalid"}`, - true, - }, - { - "valid pod", - `{"podNamespace": "bar", "podName": "foo", "podUID": "12345678", "containerName": "baz"}`, - false, - }, - } - for _, test := range tests { - p := path.Join(regPath, "kubernetes.io~glusterfs.json") - if len(test.json) > 0 { - if err := ioutil.WriteFile(p, []byte(test.json), 0600); err != nil { - t.Errorf("test %q: error writing %s: %v", test.name, p, err) - continue - } - } else { - // "" means no JSON file - os.Remove(p) - } - pod, container, err := mgr.GetMountPod("kubernetes.io/glusterfs") - if err != nil { - klog.V(5).Infof("test %q returned error %s", test.name, err) - } - if err == nil && test.expectError { - t.Errorf("test %q: expected error, got none", test.name) - } - if err != nil && !test.expectError { - t.Errorf("test %q: unexpected error: %v", test.name, err) - } - - if err == nil { - // Pod must be returned when the json file was not empty - if pod == nil && len(test.json) != 0 { - t.Errorf("test %q: expected exec, got nil", test.name) - } - // Both pod and container must be returned - if pod != nil && len(container) == 0 { - t.Errorf("test %q: expected container name, got %q", test.name, container) - } - } - } -} diff --git a/pkg/kubelet/volume_host.go b/pkg/kubelet/volume_host.go index 7135a1300c0..964b11a5c78 100644 --- a/pkg/kubelet/volume_host.go +++ b/pkg/kubelet/volume_host.go @@ -36,14 +36,11 @@ import ( cloudprovider "k8s.io/cloud-provider" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/configmap" - "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/mountpod" "k8s.io/kubernetes/pkg/kubelet/secret" "k8s.io/kubernetes/pkg/kubelet/token" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" - execmnt "k8s.io/kubernetes/pkg/volume/util/exec" "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" ) @@ -80,20 +77,16 @@ func NewInitializedVolumePluginMgr( } } - mountPodManager, err := mountpod.NewManager(kubelet.getRootDir(), kubelet.podManager) - if err != nil { - return nil, err - } kvh := &kubeletVolumeHost{ kubelet: kubelet, volumePluginMgr: volume.VolumePluginMgr{}, secretManager: secretManager, configMapManager: configMapManager, tokenManager: tokenManager, - mountPodManager: mountPodManager, informerFactory: informerFactory, csiDriverLister: csiDriverLister, csiDriversSynced: csiDriversSynced, + exec: mount.NewOSExec(), } if err := kvh.volumePluginMgr.InitPlugins(plugins, prober, kvh); err != nil { @@ -119,10 +112,10 @@ type kubeletVolumeHost struct { secretManager secret.Manager tokenManager *token.Manager configMapManager configmap.Manager - mountPodManager mountpod.Manager informerFactory informers.SharedInformerFactory csiDriverLister storagelisters.CSIDriverLister csiDriversSynced cache.InformerSynced + exec mount.Exec } func (kvh *kubeletVolumeHost) SetKubeletError(err error) { @@ -227,16 +220,7 @@ func (kvh *kubeletVolumeHost) GetCloudProvider() cloudprovider.Interface { } func (kvh *kubeletVolumeHost) GetMounter(pluginName string) mount.Interface { - exec, err := kvh.getMountExec(pluginName) - if err != nil { - klog.V(2).Infof("Error finding mount pod for plugin %s: %s", pluginName, err.Error()) - // Use the default mounter - exec = nil - } - if exec == nil { - return kvh.kubelet.mounter - } - return execmnt.NewExecMounter(exec, kvh.kubelet.mounter) + return kvh.kubelet.mounter } func (kvh *kubeletVolumeHost) GetHostName() string { @@ -288,56 +272,5 @@ func (kvh *kubeletVolumeHost) GetEventRecorder() record.EventRecorder { } func (kvh *kubeletVolumeHost) GetExec(pluginName string) mount.Exec { - exec, err := kvh.getMountExec(pluginName) - if err != nil { - klog.V(2).Infof("Error finding mount pod for plugin %s: %s", pluginName, err.Error()) - // Use the default exec - exec = nil - } - if exec == nil { - return mount.NewOSExec() - } - return exec -} - -// getMountExec returns mount.Exec implementation that leads to pod with mount -// utilities. It returns nil,nil when there is no such pod and default mounter / -// os.Exec should be used. -func (kvh *kubeletVolumeHost) getMountExec(pluginName string) (mount.Exec, error) { - if !utilfeature.DefaultFeatureGate.Enabled(features.MountContainers) { - klog.V(5).Infof("using default mounter/exec for %s", pluginName) - return nil, nil - } - - pod, container, err := kvh.mountPodManager.GetMountPod(pluginName) - if err != nil { - return nil, err - } - if pod == nil { - // Use default mounter/exec for this plugin - klog.V(5).Infof("using default mounter/exec for %s", pluginName) - return nil, nil - } - klog.V(5).Infof("using container %s/%s/%s to execute mount utilities for %s", pod.Namespace, pod.Name, container, pluginName) - return &containerExec{ - pod: pod, - containerName: container, - kl: kvh.kubelet, - }, nil -} - -// containerExec is implementation of mount.Exec that executes commands in given -// container in given pod. -type containerExec struct { - pod *v1.Pod - containerName string - kl *Kubelet -} - -var _ mount.Exec = &containerExec{} - -func (e *containerExec) Run(cmd string, args ...string) ([]byte, error) { - cmdline := append([]string{cmd}, args...) - klog.V(5).Infof("Exec mounter running in pod %s/%s/%s: %v", e.pod.Namespace, e.pod.Name, e.containerName, cmdline) - return e.kl.RunInContainer(container.GetPodFullName(e.pod), e.pod.UID, e.containerName, cmdline) + return kvh.exec } diff --git a/pkg/volume/util/BUILD b/pkg/volume/util/BUILD index 55d9a2ecfbc..0a68bb95d56 100644 --- a/pkg/volume/util/BUILD +++ b/pkg/volume/util/BUILD @@ -91,7 +91,6 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", - "//pkg/volume/util/exec:all-srcs", "//pkg/volume/util/fs:all-srcs", "//pkg/volume/util/fsquota:all-srcs", "//pkg/volume/util/hostutil:all-srcs", diff --git a/pkg/volume/util/exec/BUILD b/pkg/volume/util/exec/BUILD deleted file mode 100644 index 5f4fd655ac6..00000000000 --- a/pkg/volume/util/exec/BUILD +++ /dev/null @@ -1,74 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -go_library( - name = "go_default_library", - srcs = [ - "exec_mount.go", - "exec_mount_unsupported.go", - ], - importpath = "k8s.io/kubernetes/pkg/volume/util/exec", - visibility = ["//visibility:public"], - deps = select({ - "@io_bazel_rules_go//go/platform:android": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:darwin": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:dragonfly": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:freebsd": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:linux": [ - "//pkg/util/mount:go_default_library", - "//vendor/k8s.io/klog:go_default_library", - ], - "@io_bazel_rules_go//go/platform:nacl": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:netbsd": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:openbsd": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:plan9": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:solaris": [ - "//pkg/util/mount:go_default_library", - ], - "@io_bazel_rules_go//go/platform:windows": [ - "//pkg/util/mount:go_default_library", - ], - "//conditions:default": [], - }), -) - -go_test( - name = "go_default_test", - srcs = ["exec_mount_test.go"], - embed = [":go_default_library"], - deps = select({ - "@io_bazel_rules_go//go/platform:linux": [ - "//pkg/util/mount:go_default_library", - ], - "//conditions:default": [], - }), -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], - visibility = ["//visibility:public"], -) diff --git a/pkg/volume/util/exec/exec_mount.go b/pkg/volume/util/exec/exec_mount.go deleted file mode 100644 index 868f989ecea..00000000000 --- a/pkg/volume/util/exec/exec_mount.go +++ /dev/null @@ -1,101 +0,0 @@ -// +build linux - -/* -Copyright 2017 The Kubernetes Authors. - -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 exec - -import ( - "fmt" - - "k8s.io/klog" - - "k8s.io/kubernetes/pkg/util/mount" -) - -// ExecMounter is a mounter that uses provided Exec interface to mount and -// unmount a filesystem. For all other calls it uses a wrapped mounter. -type execMounter struct { - wrappedMounter mount.Interface - exec mount.Exec -} - -// NewExecMounter returns a mounter that uses provided Exec interface to mount and -// unmount a filesystem. For all other calls it uses a wrapped mounter. -func NewExecMounter(exec mount.Exec, wrapped mount.Interface) mount.Interface { - return &execMounter{ - wrappedMounter: wrapped, - exec: exec, - } -} - -// execMounter implements mount.Interface -var _ mount.Interface = &execMounter{} - -// Mount runs mount(8) using given exec interface. -func (m *execMounter) Mount(source string, target string, fstype string, options []string) error { - bind, bindOpts, bindRemountOpts := mount.MakeBindOpts(options) - - if bind { - err := m.doExecMount(source, target, fstype, bindOpts) - if err != nil { - return err - } - return m.doExecMount(source, target, fstype, bindRemountOpts) - } - - return m.doExecMount(source, target, fstype, options) -} - -// doExecMount calls exec(mount ) using given exec interface. -func (m *execMounter) doExecMount(source, target, fstype string, options []string) error { - klog.V(5).Infof("Exec Mounting %s %s %s %v", source, target, fstype, options) - mountArgs := mount.MakeMountArgs(source, target, fstype, options) - output, err := m.exec.Run("mount", mountArgs...) - klog.V(5).Infof("Exec mounted %v: %v: %s", mountArgs, err, string(output)) - if err != nil { - return fmt.Errorf("mount failed: %v\nMounting command: %s\nMounting arguments: %s %s %s %v\nOutput: %s", - err, "mount", source, target, fstype, options, string(output)) - } - - return err -} - -// Unmount runs umount(8) using given exec interface. -func (m *execMounter) Unmount(target string) error { - outputBytes, err := m.exec.Run("umount", target) - if err == nil { - klog.V(5).Infof("Exec unmounted %s: %s", target, string(outputBytes)) - } else { - klog.V(5).Infof("Failed to exec unmount %s: err: %q, umount output: %s", target, err, string(outputBytes)) - } - - return err -} - -// List returns a list of all mounted filesystems. -func (m *execMounter) List() ([]mount.MountPoint, error) { - return m.wrappedMounter.List() -} - -// IsLikelyNotMountPoint determines whether a path is a mountpoint. -func (m *execMounter) IsLikelyNotMountPoint(file string) (bool, error) { - return m.wrappedMounter.IsLikelyNotMountPoint(file) -} - -func (m *execMounter) GetMountRefs(pathname string) ([]string, error) { - return m.wrappedMounter.GetMountRefs(pathname) -} diff --git a/pkg/volume/util/exec/exec_mount_test.go b/pkg/volume/util/exec/exec_mount_test.go deleted file mode 100644 index f25485e0f25..00000000000 --- a/pkg/volume/util/exec/exec_mount_test.go +++ /dev/null @@ -1,119 +0,0 @@ -// +build linux - -/* -Copyright 2017 The Kubernetes Authors. - -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 exec - -import ( - "fmt" - "reflect" - "strings" - "testing" - - "k8s.io/kubernetes/pkg/util/mount" -) - -var ( - sourcePath = "/mnt/srv" - destinationPath = "/mnt/dst" - fsType = "xfs" - mountOptions = []string{"vers=1", "foo=bar"} -) - -func TestMount(t *testing.T) { - exec := mount.NewFakeExec(func(cmd string, args ...string) ([]byte, error) { - if cmd != "mount" { - t.Errorf("expected mount command, got %q", cmd) - } - // mount -t fstype -o options source target - expectedArgs := []string{"-t", fsType, "-o", strings.Join(mountOptions, ","), sourcePath, destinationPath} - if !reflect.DeepEqual(expectedArgs, args) { - t.Errorf("expected arguments %q, got %q", strings.Join(expectedArgs, " "), strings.Join(args, " ")) - } - return nil, nil - }) - - wrappedMounter := &fakeMounter{FakeMounter: &mount.FakeMounter{}, t: t} - mounter := NewExecMounter(exec, wrappedMounter) - - mounter.Mount(sourcePath, destinationPath, fsType, mountOptions) -} - -func TestBindMount(t *testing.T) { - cmdCount := 0 - exec := mount.NewFakeExec(func(cmd string, args ...string) ([]byte, error) { - cmdCount++ - if cmd != "mount" { - t.Errorf("expected mount command, got %q", cmd) - } - var expectedArgs []string - switch cmdCount { - case 1: - // mount -t fstype -o "bind" source target - expectedArgs = []string{"-t", fsType, "-o", "bind", sourcePath, destinationPath} - case 2: - // mount -t fstype -o "remount,opts" source target - expectedArgs = []string{"-t", fsType, "-o", "bind,remount," + strings.Join(mountOptions, ","), sourcePath, destinationPath} - } - if !reflect.DeepEqual(expectedArgs, args) { - t.Errorf("expected arguments %q, got %q", strings.Join(expectedArgs, " "), strings.Join(args, " ")) - } - return nil, nil - }) - - wrappedMounter := &fakeMounter{FakeMounter: &mount.FakeMounter{}, t: t} - mounter := NewExecMounter(exec, wrappedMounter) - bindOptions := append(mountOptions, "bind") - mounter.Mount(sourcePath, destinationPath, fsType, bindOptions) -} - -func TestUnmount(t *testing.T) { - exec := mount.NewFakeExec(func(cmd string, args ...string) ([]byte, error) { - if cmd != "umount" { - t.Errorf("expected unmount command, got %q", cmd) - } - // unmount $target - expectedArgs := []string{destinationPath} - if !reflect.DeepEqual(expectedArgs, args) { - t.Errorf("expected arguments %q, got %q", strings.Join(expectedArgs, " "), strings.Join(args, " ")) - } - return nil, nil - }) - - wrappedMounter := &fakeMounter{&mount.FakeMounter{}, t} - mounter := NewExecMounter(exec, wrappedMounter) - - mounter.Unmount(destinationPath) -} - -/* Fake wrapped mounter */ -type fakeMounter struct { - *mount.FakeMounter - t *testing.T -} - -func (fm *fakeMounter) Mount(source string, target string, fstype string, options []string) error { - // Mount() of wrapped mounter should never be called. We call exec instead. - fm.t.Errorf("Unexpected wrapped mount call") - return fmt.Errorf("Unexpected wrapped mount call") -} - -func (fm *fakeMounter) Unmount(target string) error { - // umount() of wrapped mounter should never be called. We call exec instead. - fm.t.Errorf("Unexpected wrapped mount call") - return fmt.Errorf("Unexpected wrapped mount call") -} diff --git a/pkg/volume/util/exec/exec_mount_unsupported.go b/pkg/volume/util/exec/exec_mount_unsupported.go deleted file mode 100644 index 1c4f8ecf38c..00000000000 --- a/pkg/volume/util/exec/exec_mount_unsupported.go +++ /dev/null @@ -1,55 +0,0 @@ -// +build !linux - -/* -Copyright 2017 The Kubernetes Authors. - -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 exec - -import ( - "errors" - - "k8s.io/kubernetes/pkg/util/mount" -) - -type execMounter struct{} - -var _ = mount.Interface(&execMounter{}) - -// NewExecMounter returns a mounter that uses provided Exec interface to mount and -// unmount a filesystem. For all other calls it uses a wrapped mounter. -func NewExecMounter(exec mount.Exec, wrapped mount.Interface) mount.Interface { - return &execMounter{} -} - -func (mounter *execMounter) Mount(source string, target string, fstype string, options []string) error { - return nil -} - -func (mounter *execMounter) Unmount(target string) error { - return nil -} - -func (mounter *execMounter) List() ([]mount.MountPoint, error) { - return []mount.MountPoint{}, nil -} - -func (mounter *execMounter) IsLikelyNotMountPoint(file string) (bool, error) { - return true, nil -} - -func (mounter *execMounter) GetMountRefs(pathname string) ([]string, error) { - return nil, errors.New("not implemented") -}