...

Source file src/k8s.io/kubernetes/pkg/volume/flexvolume/attacher.go

Documentation: k8s.io/kubernetes/pkg/volume/flexvolume

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package flexvolume
    18  
    19  import (
    20  	"time"
    21  
    22  	v1 "k8s.io/api/core/v1"
    23  	"k8s.io/apimachinery/pkg/types"
    24  	"k8s.io/klog/v2"
    25  	"k8s.io/kubernetes/pkg/volume"
    26  )
    27  
    28  type flexVolumeAttacher struct {
    29  	plugin *flexVolumeAttachablePlugin
    30  }
    31  
    32  var _ volume.Attacher = &flexVolumeAttacher{}
    33  
    34  var _ volume.DeviceMounter = &flexVolumeAttacher{}
    35  
    36  // Attach is part of the volume.Attacher interface
    37  func (a *flexVolumeAttacher) Attach(spec *volume.Spec, hostName types.NodeName) (string, error) {
    38  
    39  	call := a.plugin.NewDriverCall(attachCmd)
    40  	call.AppendSpec(spec, a.plugin.host, nil)
    41  	call.Append(string(hostName))
    42  
    43  	status, err := call.Run()
    44  	if isCmdNotSupportedErr(err) {
    45  		return (*attacherDefaults)(a).Attach(spec, hostName)
    46  	} else if err != nil {
    47  		return "", err
    48  	}
    49  	return status.DevicePath, err
    50  }
    51  
    52  // WaitForAttach is part of the volume.Attacher interface
    53  func (a *flexVolumeAttacher) WaitForAttach(spec *volume.Spec, devicePath string, _ *v1.Pod, timeout time.Duration) (string, error) {
    54  	call := a.plugin.NewDriverCallWithTimeout(waitForAttachCmd, timeout)
    55  	call.Append(devicePath)
    56  	call.AppendSpec(spec, a.plugin.host, nil)
    57  
    58  	status, err := call.Run()
    59  	if isCmdNotSupportedErr(err) {
    60  		return (*attacherDefaults)(a).WaitForAttach(spec, devicePath, timeout)
    61  	} else if err != nil {
    62  		return "", err
    63  	}
    64  	return status.DevicePath, nil
    65  }
    66  
    67  // GetDeviceMountPath is part of the volume.Attacher interface
    68  func (a *flexVolumeAttacher) GetDeviceMountPath(spec *volume.Spec) (string, error) {
    69  	return a.plugin.getDeviceMountPath(spec)
    70  }
    71  
    72  // MountDevice is part of the volume.Attacher interface
    73  func (a *flexVolumeAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string, _ volume.DeviceMounterArgs) error {
    74  	// Mount only once.
    75  	alreadyMounted, err := prepareForMount(a.plugin.host.GetMounter(a.plugin.GetPluginName()), deviceMountPath)
    76  	if err != nil {
    77  		return err
    78  	}
    79  	if alreadyMounted {
    80  		return nil
    81  	}
    82  
    83  	call := a.plugin.NewDriverCall(mountDeviceCmd)
    84  	call.Append(deviceMountPath)
    85  	call.Append(devicePath)
    86  	call.AppendSpec(spec, a.plugin.host, nil)
    87  
    88  	_, err = call.Run()
    89  	if isCmdNotSupportedErr(err) {
    90  		// Devicepath is empty if the plugin does not support attach calls. Ignore mountDevice calls if the
    91  		// plugin does not implement attach interface.
    92  		if devicePath != "" {
    93  			return (*attacherDefaults)(a).MountDevice(spec, devicePath, deviceMountPath, a.plugin.host.GetMounter(a.plugin.GetPluginName()))
    94  		}
    95  		return nil
    96  	}
    97  	return err
    98  }
    99  
   100  func (a *flexVolumeAttacher) VolumesAreAttached(specs []*volume.Spec, nodeName types.NodeName) (map[*volume.Spec]bool, error) {
   101  	volumesAttachedCheck := make(map[*volume.Spec]bool)
   102  	for _, spec := range specs {
   103  		volumesAttachedCheck[spec] = true
   104  
   105  		call := a.plugin.NewDriverCall(isAttached)
   106  		call.AppendSpec(spec, a.plugin.host, nil)
   107  		call.Append(string(nodeName))
   108  
   109  		status, err := call.Run()
   110  		if isCmdNotSupportedErr(err) {
   111  			return nil, nil
   112  		} else if err == nil {
   113  			if !status.Attached {
   114  				volumesAttachedCheck[spec] = false
   115  				klog.V(2).Infof("VolumesAreAttached: check volume (%q) is no longer attached", spec.Name())
   116  			}
   117  		} else {
   118  			return nil, err
   119  		}
   120  	}
   121  	return volumesAttachedCheck, nil
   122  }
   123  

View as plain text