2018-01-09 18:57:14 +00:00
|
|
|
/*
|
|
|
|
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"
|
|
|
|
|
2018-11-26 18:23:56 +00:00
|
|
|
"k8s.io/klog"
|
|
|
|
|
2018-01-09 18:57:14 +00:00
|
|
|
// Cloud providers
|
2018-11-26 18:23:56 +00:00
|
|
|
cloudprovider "k8s.io/cloud-provider"
|
2018-01-09 18:57:14 +00:00
|
|
|
_ "k8s.io/kubernetes/pkg/cloudprovider/providers"
|
|
|
|
// Volume plugins
|
|
|
|
"k8s.io/kubernetes/pkg/volume"
|
2018-11-26 18:23:56 +00:00
|
|
|
"k8s.io/kubernetes/pkg/volume/awsebs"
|
2018-01-09 18:57:14 +00:00
|
|
|
"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"
|
2018-11-26 18:23:56 +00:00
|
|
|
"k8s.io/kubernetes/pkg/volume/gcepd"
|
2018-01-09 18:57:14 +00:00
|
|
|
"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"
|
2018-11-26 18:23:56 +00:00
|
|
|
kubectrlmgrconfig "k8s.io/kubernetes/pkg/controller/apis/config"
|
2018-01-09 18:57:14 +00:00
|
|
|
"k8s.io/kubernetes/pkg/features"
|
2018-11-26 18:23:56 +00:00
|
|
|
"k8s.io/utils/exec"
|
2018-01-09 18:57:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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{}
|
|
|
|
|
2018-11-26 18:23:56 +00:00
|
|
|
allPlugins = append(allPlugins, awsebs.ProbeVolumePlugins()...)
|
|
|
|
allPlugins = append(allPlugins, gcepd.ProbeVolumePlugins()...)
|
2018-01-09 18:57:14 +00:00
|
|
|
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.
|
2018-11-26 18:23:56 +00:00
|
|
|
func GetDynamicPluginProber(config kubectrlmgrconfig.VolumeConfiguration) volume.DynamicPluginProber {
|
|
|
|
return flexvolume.GetDynamicPluginProber(config.FlexVolumePluginDir, exec.New() /*exec.Interface*/)
|
2018-01-09 18:57:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ProbeExpandableVolumePlugins returns volume plugins which are expandable
|
2018-11-26 18:23:56 +00:00
|
|
|
func ProbeExpandableVolumePlugins(config kubectrlmgrconfig.VolumeConfiguration) []volume.VolumePlugin {
|
2018-01-09 18:57:14 +00:00
|
|
|
allPlugins := []volume.VolumePlugin{}
|
|
|
|
|
2018-11-26 18:23:56 +00:00
|
|
|
allPlugins = append(allPlugins, awsebs.ProbeVolumePlugins()...)
|
|
|
|
allPlugins = append(allPlugins, gcepd.ProbeVolumePlugins()...)
|
2018-01-09 18:57:14 +00:00
|
|
|
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()...)
|
2018-03-06 22:33:18 +00:00
|
|
|
allPlugins = append(allPlugins, azure_file.ProbeVolumePlugins()...)
|
2018-01-09 18:57:14 +00:00
|
|
|
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.
|
2018-11-26 18:23:56 +00:00
|
|
|
func ProbeControllerVolumePlugins(cloud cloudprovider.Interface, config kubectrlmgrconfig.VolumeConfiguration) []volume.VolumePlugin {
|
2018-01-09 18:57:14 +00:00
|
|
|
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 {
|
2018-11-26 18:23:56 +00:00
|
|
|
klog.Fatalf("Could not create hostpath recycler pod from file %s: %+v", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, err)
|
2018-01-09 18:57:14 +00:00
|
|
|
}
|
|
|
|
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 {
|
2018-11-26 18:23:56 +00:00
|
|
|
klog.Fatalf("Could not create NFS recycler pod from file %s: %+v", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, err)
|
2018-01-09 18:57:14 +00:00
|
|
|
}
|
|
|
|
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()...)
|
|
|
|
|
2018-11-26 18:23:56 +00:00
|
|
|
allPlugins = append(allPlugins, awsebs.ProbeVolumePlugins()...)
|
|
|
|
allPlugins = append(allPlugins, gcepd.ProbeVolumePlugins()...)
|
2018-01-09 18:57:14 +00:00
|
|
|
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
|
|
|
|
}
|