k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kube-controller-manager/app/plugins.go (about)

     1  /*
     2  Copyright 2014 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 app
    18  
    19  import (
    20  	// This file exists to force the desired plugin implementations to be linked.
    21  	// This should probably be part of some configuration fed into the build for a
    22  	// given binary target.
    23  
    24  	"fmt"
    25  
    26  	"k8s.io/klog/v2"
    27  
    28  	// Volume plugins
    29  	"k8s.io/kubernetes/pkg/volume"
    30  	"k8s.io/kubernetes/pkg/volume/csi"
    31  	"k8s.io/kubernetes/pkg/volume/fc"
    32  	"k8s.io/kubernetes/pkg/volume/flexvolume"
    33  	"k8s.io/kubernetes/pkg/volume/hostpath"
    34  	"k8s.io/kubernetes/pkg/volume/iscsi"
    35  	"k8s.io/kubernetes/pkg/volume/local"
    36  	"k8s.io/kubernetes/pkg/volume/nfs"
    37  	volumeutil "k8s.io/kubernetes/pkg/volume/util"
    38  
    39  	utilfeature "k8s.io/apiserver/pkg/util/feature"
    40  	persistentvolumeconfig "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/config"
    41  	"k8s.io/utils/exec"
    42  )
    43  
    44  // ProbeAttachableVolumePlugins collects all volume plugins for the attach/
    45  // detach controller.
    46  // The list of plugins is manually compiled. This code and the plugin
    47  // initialization code for kubelet really, really need a through refactor.
    48  func ProbeAttachableVolumePlugins(logger klog.Logger) ([]volume.VolumePlugin, error) {
    49  	var err error
    50  	allPlugins := []volume.VolumePlugin{}
    51  	allPlugins, err = appendAttachableLegacyProviderVolumes(logger, allPlugins, utilfeature.DefaultFeatureGate)
    52  	if err != nil {
    53  		return allPlugins, err
    54  	}
    55  	allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...)
    56  	allPlugins = append(allPlugins, iscsi.ProbeVolumePlugins()...)
    57  	allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...)
    58  	return allPlugins, nil
    59  }
    60  
    61  // GetDynamicPluginProber gets the probers of dynamically discoverable plugins
    62  // for the attach/detach controller.
    63  // Currently only Flexvolume plugins are dynamically discoverable.
    64  func GetDynamicPluginProber(config persistentvolumeconfig.VolumeConfiguration) volume.DynamicPluginProber {
    65  	return flexvolume.GetDynamicPluginProber(config.FlexVolumePluginDir, exec.New() /*exec.Interface*/)
    66  }
    67  
    68  // ProbeExpandableVolumePlugins returns volume plugins which are expandable
    69  func ProbeExpandableVolumePlugins(logger klog.Logger, config persistentvolumeconfig.VolumeConfiguration) ([]volume.VolumePlugin, error) {
    70  	var err error
    71  	allPlugins := []volume.VolumePlugin{}
    72  	allPlugins, err = appendExpandableLegacyProviderVolumes(logger, allPlugins, utilfeature.DefaultFeatureGate)
    73  	if err != nil {
    74  		return allPlugins, err
    75  	}
    76  	allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...)
    77  	return allPlugins, nil
    78  }
    79  
    80  // ProbeControllerVolumePlugins collects all persistent volume plugins into an
    81  // easy to use list. Only volume plugins that implement any of
    82  // provisioner/recycler/deleter interface should be returned.
    83  func ProbeControllerVolumePlugins(logger klog.Logger, config persistentvolumeconfig.VolumeConfiguration) ([]volume.VolumePlugin, error) {
    84  	allPlugins := []volume.VolumePlugin{}
    85  
    86  	// The list of plugins to probe is decided by this binary, not
    87  	// by dynamic linking or other "magic".  Plugins will be analyzed and
    88  	// initialized later.
    89  
    90  	// Each plugin can make use of VolumeConfig.  The single arg to this func contains *all* enumerated
    91  	// options meant to configure volume plugins.  From that single config, create an instance of volume.VolumeConfig
    92  	// for a specific plugin and pass that instance to the plugin's ProbeVolumePlugins(config) func.
    93  
    94  	// HostPath recycling is for testing and development purposes only!
    95  	hostPathConfig := volume.VolumeConfig{
    96  		RecyclerMinimumTimeout:   int(config.PersistentVolumeRecyclerConfiguration.MinimumTimeoutHostPath),
    97  		RecyclerTimeoutIncrement: int(config.PersistentVolumeRecyclerConfiguration.IncrementTimeoutHostPath),
    98  		RecyclerPodTemplate:      volume.NewPersistentVolumeRecyclerPodTemplate(),
    99  		ProvisioningEnabled:      config.EnableHostPathProvisioning,
   100  	}
   101  	if err := AttemptToLoadRecycler(config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, &hostPathConfig); err != nil {
   102  		logger.Error(err, "Could not create hostpath recycler pod from file", "path", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath)
   103  		klog.FlushAndExit(klog.ExitFlushTimeout, 1)
   104  	}
   105  	allPlugins = append(allPlugins, hostpath.ProbeVolumePlugins(hostPathConfig)...)
   106  
   107  	nfsConfig := volume.VolumeConfig{
   108  		RecyclerMinimumTimeout:   int(config.PersistentVolumeRecyclerConfiguration.MinimumTimeoutNFS),
   109  		RecyclerTimeoutIncrement: int(config.PersistentVolumeRecyclerConfiguration.IncrementTimeoutNFS),
   110  		RecyclerPodTemplate:      volume.NewPersistentVolumeRecyclerPodTemplate(),
   111  	}
   112  	if err := AttemptToLoadRecycler(config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, &nfsConfig); err != nil {
   113  		logger.Error(err, "Could not create NFS recycler pod from file", "path", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS)
   114  		klog.FlushAndExit(klog.ExitFlushTimeout, 1)
   115  	}
   116  	allPlugins = append(allPlugins, nfs.ProbeVolumePlugins(nfsConfig)...)
   117  
   118  	var err error
   119  	allPlugins, err = appendExpandableLegacyProviderVolumes(logger, allPlugins, utilfeature.DefaultFeatureGate)
   120  	if err != nil {
   121  		return allPlugins, err
   122  	}
   123  
   124  	allPlugins = append(allPlugins, local.ProbeVolumePlugins()...)
   125  	allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...)
   126  
   127  	return allPlugins, nil
   128  }
   129  
   130  // AttemptToLoadRecycler tries decoding a pod from a filepath for use as a recycler for a volume.
   131  // If successful, this method will set the recycler on the config.
   132  // If unsuccessful, an error is returned. Function is exported for reuse downstream.
   133  func AttemptToLoadRecycler(path string, config *volume.VolumeConfig) error {
   134  	if path != "" {
   135  		recyclerPod, err := volumeutil.LoadPodFromFile(path)
   136  		if err != nil {
   137  			return err
   138  		}
   139  		if err = volume.ValidateRecyclerPodTemplate(recyclerPod); err != nil {
   140  			return fmt.Errorf("pod specification (%v): %v", path, err)
   141  		}
   142  		config.RecyclerPodTemplate = recyclerPod
   143  	}
   144  	return nil
   145  }