diff --git a/pkg/volume/flexvolume/driver-call.go b/pkg/volume/flexvolume/driver-call.go index 4640c51d8bb..aad05eeb159 100644 --- a/pkg/volume/flexvolume/driver-call.go +++ b/pkg/volume/flexvolume/driver-call.go @@ -59,7 +59,8 @@ const ( optionKeyServiceAccountName = "kubernetes.io/serviceAccount.name" - attachCapability = "attach" + attachCapability = "attach" + selinuxRelabelCapability = "selinuxRelabel" ) const ( @@ -82,6 +83,11 @@ type DriverCall struct { args []string } +type driverCapabilities struct { + attach bool + selinuxRelabel bool +} + func (plugin *flexVolumePlugin) NewDriverCall(command string) *DriverCall { return plugin.NewDriverCallWithTimeout(command, 0) } @@ -235,3 +241,23 @@ func handleCmdResponse(cmd string, output []byte) (*DriverStatus, error) { return &status, nil } + +// getDriverCapabilities returns the reported capabilities as returned by driver's init() function +func (ds *DriverStatus) getDriverCapabilities() *driverCapabilities { + driverCaps := &driverCapabilities{ + attach: true, + selinuxRelabel: true, + } + + // Check if driver supports SELinux Relabeling of mounted volume + if dcap, ok := ds.Capabilities[selinuxRelabelCapability]; ok { + driverCaps.selinuxRelabel = dcap + } + + // Check whether the plugin is attachable. + if dcap, ok := ds.Capabilities[attachCapability]; ok { + driverCaps.attach = dcap + } + + return driverCaps +} diff --git a/pkg/volume/flexvolume/mounter-defaults.go b/pkg/volume/flexvolume/mounter-defaults.go index a8586b46ec9..a3996d4da3c 100644 --- a/pkg/volume/flexvolume/mounter-defaults.go +++ b/pkg/volume/flexvolume/mounter-defaults.go @@ -47,7 +47,7 @@ func (f *mounterDefaults) GetAttributes() volume.Attributes { return volume.Attributes{ ReadOnly: f.readOnly, Managed: !f.readOnly, - SupportsSELinux: true, + SupportsSELinux: f.flexVolume.plugin.capabilities.selinuxRelabel, } } diff --git a/pkg/volume/flexvolume/plugin.go b/pkg/volume/flexvolume/plugin.go index 955a47c3c00..2e54aae964c 100644 --- a/pkg/volume/flexvolume/plugin.go +++ b/pkg/volume/flexvolume/plugin.go @@ -42,6 +42,7 @@ type flexVolumePlugin struct { runner exec.Interface sync.Mutex + capabilities *driverCapabilities unsupportedCommands []string } @@ -64,44 +65,29 @@ func NewFlexVolumePlugin(pluginDir, name string) (volume.VolumePlugin, error) { unsupportedCommands: []string{}, } - // Check whether the plugin is attachable. - ok, err := isAttachable(flexPlugin) + // Retrieve driver reported capabilities + call := flexPlugin.NewDriverCall(initCmd) + ds, err := call.Run() if err != nil { return nil, err } - if ok { - // Plugin supports attach/detach, so return flexVolumeAttachablePlugin + driverCaps := ds.getDriverCapabilities() + flexPlugin.capabilities = driverCaps + + // Check whether the plugin is attachable. + if driverCaps.attach { + // Plugin supports attach/detach by default, 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 - // call the init script - call := plugin.NewDriverCall(initCmd) - _, err := call.Run() - return err + // Hardwired 'success' as any errors from calling init() will be caught by NewFlexVolumePlugin() + return nil } func (plugin *flexVolumePlugin) getExecutable() string {