Commit 282404cb authored by Jan Safranek's avatar Jan Safranek

Add Exec interface to VolumeHost

This exec should be used by volume plugins to execute mount utilities. It will eventually execute things in mount containers.
parent 41933572
...@@ -571,6 +571,10 @@ func (adc *attachDetachController) GetConfigMapFunc() func(namespace, name strin ...@@ -571,6 +571,10 @@ func (adc *attachDetachController) GetConfigMapFunc() func(namespace, name strin
} }
} }
func (adc *attachDetachController) GetExec(pluginName string) mount.Exec {
return mount.NewOsExec()
}
func (adc *attachDetachController) addNodeToDswp(node *v1.Node, nodeName types.NodeName) { func (adc *attachDetachController) addNodeToDswp(node *v1.Node, nodeName types.NodeName) {
if _, exists := node.Annotations[volumehelper.ControllerManagedAttachAnnotation]; exists { if _, exists := node.Annotations[volumehelper.ControllerManagedAttachAnnotation]; exists {
keepTerminatedPodVolumes := false keepTerminatedPodVolumes := false
......
...@@ -93,6 +93,10 @@ func (adc *PersistentVolumeController) GetConfigMapFunc() func(namespace, name s ...@@ -93,6 +93,10 @@ func (adc *PersistentVolumeController) GetConfigMapFunc() func(namespace, name s
} }
} }
func (adc *PersistentVolumeController) GetExec(pluginName string) mount.Exec {
return mount.NewOsExec()
}
func (ctrl *PersistentVolumeController) GetNodeLabels() (map[string]string, error) { func (ctrl *PersistentVolumeController) GetNodeLabels() (map[string]string, error) {
return nil, fmt.Errorf("GetNodeLabels() unsupported in PersistentVolumeController") return nil, fmt.Errorf("GetNodeLabels() unsupported in PersistentVolumeController")
} }
...@@ -156,3 +156,7 @@ func (kvh *kubeletVolumeHost) GetNodeLabels() (map[string]string, error) { ...@@ -156,3 +156,7 @@ func (kvh *kubeletVolumeHost) GetNodeLabels() (map[string]string, error) {
} }
return node.Labels, nil return node.Labels, nil
} }
func (kvh *kubeletVolumeHost) GetExec(pluginName string) mount.Exec {
return mount.NewOsExec()
}
...@@ -10,6 +10,7 @@ go_library( ...@@ -10,6 +10,7 @@ go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
"doc.go", "doc.go",
"exec.go",
"fake.go", "fake.go",
"mount.go", "mount.go",
"mount_unsupported.go", "mount_unsupported.go",
......
/*
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 mount
import "k8s.io/utils/exec"
func NewOsExec() Exec {
return &osExec{}
}
// Real implementation of Exec interface that uses simple util.Exec
type osExec struct{}
var _ Exec = &osExec{}
func (e *osExec) Run(cmd string, args ...string) ([]byte, error) {
exe := exec.New()
return exe.Command(cmd, args...).CombinedOutput()
}
func NewFakeExec(run runHook) *FakeExec {
return &FakeExec{runHook: run}
}
// Fake for testing.
type FakeExec struct {
runHook runHook
}
type runHook func(cmd string, args ...string) ([]byte, error)
func (f *FakeExec) Run(cmd string, args ...string) ([]byte, error) {
if f.runHook != nil {
return f.runHook(cmd, args...)
}
return nil, nil
}
...@@ -70,6 +70,16 @@ type Interface interface { ...@@ -70,6 +70,16 @@ type Interface interface {
GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error)
} }
// Exec executes command where mount utilities are. This can be either the host,
// container where kubelet runs or even a remote pod with mount utilities.
// Usual pkg/util/exec interface is not used because kubelet.RunInContainer does
// not provide stdin/stdout/stderr streams.
type Exec interface {
// Run executes a command and returns its stdout + stderr combined in one
// stream.
Run(cmd string, args ...string) ([]byte, error)
}
// Compile-time check to ensure all Mounter implementations satisfy // Compile-time check to ensure all Mounter implementations satisfy
// the mount interface // the mount interface
var _ Interface = &Mounter{} var _ Interface = &Mounter{}
......
...@@ -244,6 +244,9 @@ type VolumeHost interface { ...@@ -244,6 +244,9 @@ type VolumeHost interface {
// Returns a function that returns a configmap. // Returns a function that returns a configmap.
GetConfigMapFunc() func(namespace, name string) (*v1.ConfigMap, error) GetConfigMapFunc() func(namespace, name string) (*v1.ConfigMap, error)
// Returns an interface that should be used to execute any utilities in volume plugins
GetExec(pluginName string) mount.Exec
// Returns the labels on the node // Returns the labels on the node
GetNodeLabels() (map[string]string, error) GetNodeLabels() (map[string]string, error)
} }
......
...@@ -49,6 +49,7 @@ type fakeVolumeHost struct { ...@@ -49,6 +49,7 @@ type fakeVolumeHost struct {
pluginMgr VolumePluginMgr pluginMgr VolumePluginMgr
cloud cloudprovider.Interface cloud cloudprovider.Interface
mounter mount.Interface mounter mount.Interface
exec mount.Exec
writer io.Writer writer io.Writer
} }
...@@ -64,6 +65,7 @@ func newFakeVolumeHost(rootDir string, kubeClient clientset.Interface, plugins [ ...@@ -64,6 +65,7 @@ func newFakeVolumeHost(rootDir string, kubeClient clientset.Interface, plugins [
host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: cloud} host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: cloud}
host.mounter = &mount.FakeMounter{} host.mounter = &mount.FakeMounter{}
host.writer = &io.StdWriter{} host.writer = &io.StdWriter{}
host.exec = mount.NewFakeExec(nil)
host.pluginMgr.InitPlugins(plugins, host) host.pluginMgr.InitPlugins(plugins, host)
return host return host
} }
...@@ -142,6 +144,10 @@ func (f *fakeVolumeHost) GetSecretFunc() func(namespace, name string) (*v1.Secre ...@@ -142,6 +144,10 @@ func (f *fakeVolumeHost) GetSecretFunc() func(namespace, name string) (*v1.Secre
} }
} }
func (f *fakeVolumeHost) GetExec(pluginName string) mount.Exec {
return f.exec
}
func (f *fakeVolumeHost) GetConfigMapFunc() func(namespace, name string) (*v1.ConfigMap, error) { func (f *fakeVolumeHost) GetConfigMapFunc() func(namespace, name string) (*v1.ConfigMap, error) {
return func(namespace, name string) (*v1.ConfigMap, error) { return func(namespace, name string) (*v1.ConfigMap, error) {
return f.kubeClient.Core().ConfigMaps(namespace).Get(name, metav1.GetOptions{}) return f.kubeClient.Core().ConfigMaps(namespace).Get(name, metav1.GetOptions{})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment