mirror of https://github.com/k3s-io/k3s
Remove controller node plugin driver dependency for non-attachable flex volume drivers (Ex: NFS).
parent
289de0ee14
commit
894b9b2add
|
@ -83,7 +83,7 @@ unmount() {
|
|||
op=$1
|
||||
|
||||
if [ "$op" = "init" ]; then
|
||||
log "{\"status\": \"Success\"}"
|
||||
log "{\"status\": \"Success\", \"capabilities\": {\"attach\": false}}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
@ -100,9 +100,6 @@ case "$op" in
|
|||
unmount)
|
||||
unmount $*
|
||||
;;
|
||||
getvolumename)
|
||||
getvolumename $*
|
||||
;;
|
||||
*)
|
||||
log "{ \"status\": \"Not supported\" }"
|
||||
exit 0
|
||||
|
|
|
@ -17,8 +17,6 @@ limitations under the License.
|
|||
package flexvolume
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
@ -33,30 +31,24 @@ type attacherDefaults flexVolumeAttacher
|
|||
|
||||
// Attach is part of the volume.Attacher interface
|
||||
func (a *attacherDefaults) Attach(spec *volume.Spec, hostName types.NodeName) (string, error) {
|
||||
glog.Warning(logPrefix(a.plugin), "using default Attach for volume ", spec.Name, ", host ", hostName)
|
||||
glog.Warning(logPrefix(a.plugin.flexVolumePlugin), "using default Attach for volume ", spec.Name, ", host ", hostName)
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// WaitForAttach is part of the volume.Attacher interface
|
||||
func (a *attacherDefaults) WaitForAttach(spec *volume.Spec, devicePath string, timeout time.Duration) (string, error) {
|
||||
glog.Warning(logPrefix(a.plugin), "using default WaitForAttach for volume ", spec.Name, ", device ", devicePath)
|
||||
glog.Warning(logPrefix(a.plugin.flexVolumePlugin), "using default WaitForAttach for volume ", spec.Name, ", device ", devicePath)
|
||||
return devicePath, nil
|
||||
}
|
||||
|
||||
// GetDeviceMountPath is part of the volume.Attacher interface
|
||||
func (a *attacherDefaults) GetDeviceMountPath(spec *volume.Spec, mountsDir string) (string, error) {
|
||||
glog.Warning(logPrefix(a.plugin), "using default GetDeviceMountPath for volume ", spec.Name, ", mountsDir ", mountsDir)
|
||||
volumeName, err := a.plugin.GetVolumeName(spec)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("GetVolumeName failed from GetDeviceMountPath: %s", err)
|
||||
}
|
||||
|
||||
return path.Join(mountsDir, volumeName), nil
|
||||
return a.plugin.getDeviceMountPath(spec)
|
||||
}
|
||||
|
||||
// MountDevice is part of the volume.Attacher interface
|
||||
func (a *attacherDefaults) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string, mounter mount.Interface) error {
|
||||
glog.Warning(logPrefix(a.plugin), "using default MountDevice for volume ", spec.Name, ", device ", devicePath, ", deviceMountPath ", deviceMountPath)
|
||||
glog.Warning(logPrefix(a.plugin.flexVolumePlugin), "using default MountDevice for volume ", spec.Name, ", device ", devicePath, ", deviceMountPath ", deviceMountPath)
|
||||
volSource, readOnly := getVolumeSource(spec)
|
||||
|
||||
options := make([]string, 0)
|
||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package flexvolume
|
||||
|
||||
import (
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
@ -26,7 +25,7 @@ import (
|
|||
)
|
||||
|
||||
type flexVolumeAttacher struct {
|
||||
plugin *flexVolumePlugin
|
||||
plugin *flexVolumeAttachablePlugin
|
||||
}
|
||||
|
||||
var _ volume.Attacher = &flexVolumeAttacher{}
|
||||
|
@ -64,9 +63,7 @@ func (a *flexVolumeAttacher) WaitForAttach(spec *volume.Spec, devicePath string,
|
|||
|
||||
// GetDeviceMountPath is part of the volume.Attacher interface
|
||||
func (a *flexVolumeAttacher) GetDeviceMountPath(spec *volume.Spec) (string, error) {
|
||||
mountsDir := path.Join(a.plugin.host.GetPluginDir(flexVolumePluginName), a.plugin.driverName, "mounts")
|
||||
|
||||
return (*attacherDefaults)(a).GetDeviceMountPath(spec, mountsDir)
|
||||
return a.plugin.getDeviceMountPath(spec)
|
||||
}
|
||||
|
||||
// MountDevice is part of the volume.Attacher interface
|
||||
|
|
|
@ -28,16 +28,18 @@ import (
|
|||
volumetesting "k8s.io/kubernetes/pkg/volume/testing"
|
||||
)
|
||||
|
||||
func testPlugin() (*flexVolumePlugin, string) {
|
||||
func testPlugin() (*flexVolumeAttachablePlugin, string) {
|
||||
rootDir, err := utiltesting.MkTmpdir("flexvolume_test")
|
||||
if err != nil {
|
||||
panic("error creating temp dir: " + err.Error())
|
||||
}
|
||||
return &flexVolumePlugin{
|
||||
driverName: "test",
|
||||
execPath: "/plugin",
|
||||
host: volumetesting.NewFakeVolumeHost(rootDir, nil, nil),
|
||||
unsupportedCommands: []string{},
|
||||
return &flexVolumeAttachablePlugin{
|
||||
flexVolumePlugin: &flexVolumePlugin{
|
||||
driverName: "test",
|
||||
execPath: "/plugin",
|
||||
host: volumetesting.NewFakeVolumeHost(rootDir, nil, nil),
|
||||
unsupportedCommands: []string{},
|
||||
},
|
||||
}, rootDir
|
||||
}
|
||||
|
||||
|
@ -77,11 +79,11 @@ func fakeResultOutput(result interface{}) exec.FakeCombinedOutputAction {
|
|||
}
|
||||
|
||||
func successOutput() exec.FakeCombinedOutputAction {
|
||||
return fakeResultOutput(&DriverStatus{StatusSuccess, "", "", "", true})
|
||||
return fakeResultOutput(&DriverStatus{StatusSuccess, "", "", "", true, nil})
|
||||
}
|
||||
|
||||
func notSupportedOutput() exec.FakeCombinedOutputAction {
|
||||
return fakeResultOutput(&DriverStatus{StatusNotSupported, "", "", "", false})
|
||||
return fakeResultOutput(&DriverStatus{StatusNotSupported, "", "", "", false, nil})
|
||||
}
|
||||
|
||||
func sameArgs(args, expectedArgs []string) bool {
|
||||
|
@ -126,7 +128,7 @@ func fakePersistentVolumeSpec() *volume.Spec {
|
|||
return volume.NewSpecFromPersistentVolume(vol, false)
|
||||
}
|
||||
|
||||
func specJson(plugin *flexVolumePlugin, spec *volume.Spec, extraOptions map[string]string) string {
|
||||
func specJson(plugin *flexVolumeAttachablePlugin, spec *volume.Spec, extraOptions map[string]string) string {
|
||||
o, err := NewOptionsForDriver(spec, plugin.host, extraOptions)
|
||||
if err != nil {
|
||||
panic("Failed to convert spec: " + err.Error())
|
||||
|
|
|
@ -28,18 +28,18 @@ type detacherDefaults flexVolumeDetacher
|
|||
|
||||
// Detach is part of the volume.Detacher interface.
|
||||
func (d *detacherDefaults) Detach(deviceName string, hostName types.NodeName) error {
|
||||
glog.Warning(logPrefix(d.plugin), "using default Detach for device ", deviceName, ", host ", hostName)
|
||||
glog.Warning(logPrefix(d.plugin.flexVolumePlugin), "using default Detach for device ", deviceName, ", host ", hostName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForDetach is part of the volume.Detacher interface.
|
||||
func (d *detacherDefaults) WaitForDetach(devicePath string, timeout time.Duration) error {
|
||||
glog.Warning(logPrefix(d.plugin), "using default WaitForDetach for device ", devicePath)
|
||||
glog.Warning(logPrefix(d.plugin.flexVolumePlugin), "using default WaitForDetach for device ", devicePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmountDevice is part of the volume.Detacher interface.
|
||||
func (d *detacherDefaults) UnmountDevice(deviceMountPath string) error {
|
||||
glog.Warning(logPrefix(d.plugin), "using default UnmountDevice for device mount path ", deviceMountPath)
|
||||
glog.Warning(logPrefix(d.plugin.flexVolumePlugin), "using default UnmountDevice for device mount path ", deviceMountPath)
|
||||
return util.UnmountPath(deviceMountPath, d.plugin.host.GetMounter())
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
)
|
||||
|
||||
type flexVolumeDetacher struct {
|
||||
plugin *flexVolumePlugin
|
||||
plugin *flexVolumeAttachablePlugin
|
||||
}
|
||||
|
||||
var _ volume.Detacher = &flexVolumeDetacher{}
|
||||
|
|
|
@ -58,6 +58,8 @@ const (
|
|||
optionKeyPodUID = "kubernetes.io/pod.uid"
|
||||
|
||||
optionKeyServiceAccountName = "kubernetes.io/serviceAccount.name"
|
||||
|
||||
attachCapability = "attach"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -201,6 +203,10 @@ type DriverStatus struct {
|
|||
VolumeName string `json:"volumeName,omitempty"`
|
||||
// Represents volume is attached on the node
|
||||
Attached bool `json:"attached,omitempty"`
|
||||
// Returns capabilities of the driver.
|
||||
// By default we assume all the capabilities are supported.
|
||||
// If the plugin does not support a capability, it can return false for that capability.
|
||||
Capabilities map[string]bool
|
||||
}
|
||||
|
||||
// isCmdNotSupportedErr checks if the error corresponds to command not supported by
|
||||
|
|
|
@ -17,8 +17,6 @@ limitations under the License.
|
|||
package flexvolume
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
@ -32,13 +30,9 @@ type mounterDefaults flexVolumeMounter
|
|||
func (f *mounterDefaults) SetUpAt(dir string, fsGroup *types.UnixGroupID) error {
|
||||
glog.Warning(logPrefix(f.plugin), "using default SetUpAt to ", dir)
|
||||
|
||||
a, err := f.plugin.NewAttacher()
|
||||
src, err := f.plugin.getDeviceMountPath(f.spec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("NewAttacher failed: %v", err)
|
||||
}
|
||||
src, err := a.GetDeviceMountPath(f.spec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetDeviceMountPath failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := doMount(f.mounter, src, dir, "auto", []string{"bind"}); err != nil {
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package flexvolume
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -27,6 +28,7 @@ import (
|
|||
api "k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/util/exec"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
utilstrings "k8s.io/kubernetes/pkg/util/strings"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
)
|
||||
|
||||
|
@ -43,9 +45,56 @@ type flexVolumePlugin struct {
|
|||
unsupportedCommands []string
|
||||
}
|
||||
|
||||
var _ volume.AttachableVolumePlugin = &flexVolumePlugin{}
|
||||
type flexVolumeAttachablePlugin struct {
|
||||
*flexVolumePlugin
|
||||
}
|
||||
|
||||
var _ volume.AttachableVolumePlugin = &flexVolumeAttachablePlugin{}
|
||||
var _ volume.PersistentVolumePlugin = &flexVolumePlugin{}
|
||||
|
||||
func NewFlexVolumePlugin(pluginDir, name string) (volume.VolumePlugin, error) {
|
||||
execPath := path.Join(pluginDir, name)
|
||||
|
||||
driverName := utilstrings.UnescapePluginName(name)
|
||||
|
||||
flexPlugin := &flexVolumePlugin{
|
||||
driverName: driverName,
|
||||
execPath: execPath,
|
||||
runner: exec.New(),
|
||||
unsupportedCommands: []string{},
|
||||
}
|
||||
|
||||
// Check whether the plugin is attachable.
|
||||
ok, err := isAttachable(flexPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ok {
|
||||
// Plugin supports attach/detach, so return flexVolumeAttachablePlugin
|
||||
return &flexVolumeAttachablePlugin{flexVolumePlugin: flexPlugin}, nil
|
||||
} else {
|
||||
return flexPlugin, nil
|
||||
}
|
||||
}
|
||||
|
||||
func isAttachable(plugin *flexVolumePlugin) (bool, error) {
|
||||
call := plugin.NewDriverCall(initCmd)
|
||||
res, err := call.Run()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// By default all plugins are attachable, unless they report otherwise.
|
||||
cap, ok := res.Capabilities[attachCapability]
|
||||
if ok {
|
||||
// cap is false, so plugin does not support attach/detach calls.
|
||||
return cap, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Init is part of the volume.VolumePlugin interface.
|
||||
func (plugin *flexVolumePlugin) Init(host volume.VolumeHost) error {
|
||||
plugin.host = host
|
||||
|
@ -155,12 +204,12 @@ func (plugin *flexVolumePlugin) newUnmounterInternal(volName string, podUID type
|
|||
}
|
||||
|
||||
// NewAttacher is part of the volume.AttachableVolumePlugin interface.
|
||||
func (plugin *flexVolumePlugin) NewAttacher() (volume.Attacher, error) {
|
||||
func (plugin *flexVolumeAttachablePlugin) NewAttacher() (volume.Attacher, error) {
|
||||
return &flexVolumeAttacher{plugin}, nil
|
||||
}
|
||||
|
||||
// NewDetacher is part of the volume.AttachableVolumePlugin interface.
|
||||
func (plugin *flexVolumePlugin) NewDetacher() (volume.Detacher, error) {
|
||||
func (plugin *flexVolumeAttachablePlugin) NewDetacher() (volume.Detacher, error) {
|
||||
return &flexVolumeDetacher{plugin}, nil
|
||||
}
|
||||
|
||||
|
@ -208,3 +257,13 @@ func (plugin *flexVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([]st
|
|||
mounter := plugin.host.GetMounter()
|
||||
return mount.GetMountRefs(mounter, deviceMountPath)
|
||||
}
|
||||
|
||||
func (plugin *flexVolumePlugin) getDeviceMountPath(spec *volume.Spec) (string, error) {
|
||||
volumeName, err := plugin.GetVolumeName(spec)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("GetVolumeName failed from getDeviceMountPath: %s", err)
|
||||
}
|
||||
|
||||
mountsDir := path.Join(plugin.host.GetPluginDir(flexVolumePluginName), plugin.driverName, "mounts")
|
||||
return path.Join(mountsDir, volumeName), nil
|
||||
}
|
||||
|
|
|
@ -18,10 +18,7 @@ package flexvolume
|
|||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/exec"
|
||||
utilstrings "k8s.io/kubernetes/pkg/util/strings"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
)
|
||||
|
||||
|
@ -37,13 +34,12 @@ func ProbeVolumePlugins(pluginDir string) []volume.VolumePlugin {
|
|||
// e.g. dirname = vendor~cifs
|
||||
// then, executable will be pluginDir/dirname/cifs
|
||||
if f.IsDir() {
|
||||
execPath := path.Join(pluginDir, f.Name())
|
||||
plugins = append(plugins, &flexVolumePlugin{
|
||||
driverName: utilstrings.UnescapePluginName(f.Name()),
|
||||
execPath: execPath,
|
||||
runner: exec.New(),
|
||||
unsupportedCommands: []string{},
|
||||
})
|
||||
plugin, err := NewFlexVolumePlugin(pluginDir, f.Name())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
plugins = append(plugins, plugin)
|
||||
}
|
||||
}
|
||||
return plugins
|
||||
|
|
Loading…
Reference in New Issue