| /* |
| Copyright 2014 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 app |
| |
| import ( |
| // This file exists to force the desired plugin implementations to be linked. |
| // This should probably be part of some configuration fed into the build for a |
| // given binary target. |
| |
| "fmt" |
| |
| "k8s.io/klog" |
| |
| // Cloud providers |
| cloudprovider "k8s.io/cloud-provider" |
| _ "k8s.io/kubernetes/pkg/cloudprovider/providers" |
| // Volume plugins |
| "k8s.io/kubernetes/pkg/volume" |
| "k8s.io/kubernetes/pkg/volume/awsebs" |
| "k8s.io/kubernetes/pkg/volume/azure_dd" |
| "k8s.io/kubernetes/pkg/volume/azure_file" |
| "k8s.io/kubernetes/pkg/volume/cinder" |
| "k8s.io/kubernetes/pkg/volume/csi" |
| "k8s.io/kubernetes/pkg/volume/fc" |
| "k8s.io/kubernetes/pkg/volume/flexvolume" |
| "k8s.io/kubernetes/pkg/volume/flocker" |
| "k8s.io/kubernetes/pkg/volume/gcepd" |
| "k8s.io/kubernetes/pkg/volume/glusterfs" |
| "k8s.io/kubernetes/pkg/volume/host_path" |
| "k8s.io/kubernetes/pkg/volume/iscsi" |
| "k8s.io/kubernetes/pkg/volume/local" |
| "k8s.io/kubernetes/pkg/volume/nfs" |
| "k8s.io/kubernetes/pkg/volume/photon_pd" |
| "k8s.io/kubernetes/pkg/volume/portworx" |
| "k8s.io/kubernetes/pkg/volume/quobyte" |
| "k8s.io/kubernetes/pkg/volume/rbd" |
| "k8s.io/kubernetes/pkg/volume/scaleio" |
| "k8s.io/kubernetes/pkg/volume/storageos" |
| volumeutil "k8s.io/kubernetes/pkg/volume/util" |
| "k8s.io/kubernetes/pkg/volume/vsphere_volume" |
| |
| utilfeature "k8s.io/apiserver/pkg/util/feature" |
| kubectrlmgrconfig "k8s.io/kubernetes/pkg/controller/apis/config" |
| "k8s.io/kubernetes/pkg/features" |
| "k8s.io/utils/exec" |
| ) |
| |
| // ProbeAttachableVolumePlugins collects all volume plugins for the attach/ |
| // detach controller. |
| // The list of plugins is manually compiled. This code and the plugin |
| // initialization code for kubelet really, really need a through refactor. |
| func ProbeAttachableVolumePlugins() []volume.VolumePlugin { |
| allPlugins := []volume.VolumePlugin{} |
| |
| allPlugins = append(allPlugins, awsebs.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, gcepd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, portworx.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, iscsi.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...) |
| if utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) { |
| allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...) |
| } |
| return allPlugins |
| } |
| |
| // GetDynamicPluginProber gets the probers of dynamically discoverable plugins |
| // for the attach/detach controller. |
| // Currently only Flexvolume plugins are dynamically discoverable. |
| func GetDynamicPluginProber(config kubectrlmgrconfig.VolumeConfiguration) volume.DynamicPluginProber { |
| return flexvolume.GetDynamicPluginProber(config.FlexVolumePluginDir, exec.New() /*exec.Interface*/) |
| } |
| |
| // ProbeExpandableVolumePlugins returns volume plugins which are expandable |
| func ProbeExpandableVolumePlugins(config kubectrlmgrconfig.VolumeConfiguration) []volume.VolumePlugin { |
| allPlugins := []volume.VolumePlugin{} |
| |
| allPlugins = append(allPlugins, awsebs.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, gcepd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, portworx.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, azure_file.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...) |
| return allPlugins |
| } |
| |
| // ProbeControllerVolumePlugins collects all persistent volume plugins into an |
| // easy to use list. Only volume plugins that implement any of |
| // provisioner/recycler/deleter interface should be returned. |
| func ProbeControllerVolumePlugins(cloud cloudprovider.Interface, config kubectrlmgrconfig.VolumeConfiguration) []volume.VolumePlugin { |
| allPlugins := []volume.VolumePlugin{} |
| |
| // The list of plugins to probe is decided by this binary, not |
| // by dynamic linking or other "magic". Plugins will be analyzed and |
| // initialized later. |
| |
| // Each plugin can make use of VolumeConfig. The single arg to this func contains *all* enumerated |
| // options meant to configure volume plugins. From that single config, create an instance of volume.VolumeConfig |
| // for a specific plugin and pass that instance to the plugin's ProbeVolumePlugins(config) func. |
| |
| // HostPath recycling is for testing and development purposes only! |
| hostPathConfig := volume.VolumeConfig{ |
| RecyclerMinimumTimeout: int(config.PersistentVolumeRecyclerConfiguration.MinimumTimeoutHostPath), |
| RecyclerTimeoutIncrement: int(config.PersistentVolumeRecyclerConfiguration.IncrementTimeoutHostPath), |
| RecyclerPodTemplate: volume.NewPersistentVolumeRecyclerPodTemplate(), |
| ProvisioningEnabled: config.EnableHostPathProvisioning, |
| } |
| if err := AttemptToLoadRecycler(config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, &hostPathConfig); err != nil { |
| klog.Fatalf("Could not create hostpath recycler pod from file %s: %+v", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, err) |
| } |
| allPlugins = append(allPlugins, host_path.ProbeVolumePlugins(hostPathConfig)...) |
| |
| nfsConfig := volume.VolumeConfig{ |
| RecyclerMinimumTimeout: int(config.PersistentVolumeRecyclerConfiguration.MinimumTimeoutNFS), |
| RecyclerTimeoutIncrement: int(config.PersistentVolumeRecyclerConfiguration.IncrementTimeoutNFS), |
| RecyclerPodTemplate: volume.NewPersistentVolumeRecyclerPodTemplate(), |
| } |
| if err := AttemptToLoadRecycler(config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, &nfsConfig); err != nil { |
| klog.Fatalf("Could not create NFS recycler pod from file %s: %+v", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, err) |
| } |
| allPlugins = append(allPlugins, nfs.ProbeVolumePlugins(nfsConfig)...) |
| allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...) |
| // add rbd provisioner |
| allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, quobyte.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, azure_file.ProbeVolumePlugins()...) |
| |
| allPlugins = append(allPlugins, flocker.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, portworx.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, local.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) |
| |
| allPlugins = append(allPlugins, awsebs.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, gcepd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...) |
| allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...) |
| |
| return allPlugins |
| } |
| |
| // AttemptToLoadRecycler tries decoding a pod from a filepath for use as a recycler for a volume. |
| // If successful, this method will set the recycler on the config. |
| // If unsuccessful, an error is returned. Function is exported for reuse downstream. |
| func AttemptToLoadRecycler(path string, config *volume.VolumeConfig) error { |
| if path != "" { |
| recyclerPod, err := volumeutil.LoadPodFromFile(path) |
| if err != nil { |
| return err |
| } |
| if err = volume.ValidateRecyclerPodTemplate(recyclerPod); err != nil { |
| return fmt.Errorf("Pod specification (%v): %v", path, err) |
| } |
| config.RecyclerPodTemplate = recyclerPod |
| } |
| return nil |
| } |