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
}
}
func (adc *attachDetachController) GetExec(pluginName string) mount.Exec {
return mount.NewOsExec()
}
func (adc *attachDetachController) addNodeToDswp(node *v1.Node, nodeName types.NodeName) {
if _, exists := node.Annotations[volumehelper.ControllerManagedAttachAnnotation]; exists {
keepTerminatedPodVolumes := false
......
......@@ -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) {
return nil, fmt.Errorf("GetNodeLabels() unsupported in PersistentVolumeController")
}
......@@ -156,3 +156,7 @@ func (kvh *kubeletVolumeHost) GetNodeLabels() (map[string]string, error) {
}
return node.Labels, nil
}
func (kvh *kubeletVolumeHost) GetExec(pluginName string) mount.Exec {
return mount.NewOsExec()
}
......@@ -10,6 +10,7 @@ go_library(
name = "go_default_library",
srcs = [
"doc.go",
"exec.go",
"fake.go",
"mount.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 {
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
// the mount interface
var _ Interface = &Mounter{}
......
......@@ -244,6 +244,9 @@ type VolumeHost interface {
// Returns a function that returns a configmap.
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
GetNodeLabels() (map[string]string, error)
}
......
......@@ -49,6 +49,7 @@ type fakeVolumeHost struct {
pluginMgr VolumePluginMgr
cloud cloudprovider.Interface
mounter mount.Interface
exec mount.Exec
writer io.Writer
}
......@@ -64,6 +65,7 @@ func newFakeVolumeHost(rootDir string, kubeClient clientset.Interface, plugins [
host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: cloud}
host.mounter = &mount.FakeMounter{}
host.writer = &io.StdWriter{}
host.exec = mount.NewFakeExec(nil)
host.pluginMgr.InitPlugins(plugins, host)
return host
}
......@@ -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) {
return func(namespace, name string) (*v1.ConfigMap, error) {
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