123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /*
- Copyright 2017 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 reconciler implements interfaces that attempt to reconcile the
- // desired state of the with the actual state of the world by triggering
- // actions.
- package expand
- import (
- "fmt"
- "time"
- "k8s.io/klog"
- "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/util/wait"
- clientset "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/kubernetes/scheme"
- v1core "k8s.io/client-go/kubernetes/typed/core/v1"
- corelisters "k8s.io/client-go/listers/core/v1"
- "k8s.io/client-go/tools/record"
- "k8s.io/kubernetes/pkg/controller/volume/events"
- "k8s.io/kubernetes/pkg/controller/volume/expand/cache"
- "k8s.io/kubernetes/pkg/volume"
- "k8s.io/kubernetes/pkg/volume/util"
- )
- // PVCPopulator iterates through PVCs and checks if for bound PVCs
- // their size doesn't match with Persistent Volume size
- type PVCPopulator interface {
- Run(stopCh <-chan struct{})
- }
- type pvcPopulator struct {
- loopPeriod time.Duration
- resizeMap cache.VolumeResizeMap
- pvcLister corelisters.PersistentVolumeClaimLister
- pvLister corelisters.PersistentVolumeLister
- kubeClient clientset.Interface
- volumePluginMgr *volume.VolumePluginMgr
- recorder record.EventRecorder
- }
- func NewPVCPopulator(
- loopPeriod time.Duration,
- resizeMap cache.VolumeResizeMap,
- pvcLister corelisters.PersistentVolumeClaimLister,
- pvLister corelisters.PersistentVolumeLister,
- volumePluginMgr *volume.VolumePluginMgr,
- kubeClient clientset.Interface) PVCPopulator {
- populator := &pvcPopulator{
- loopPeriod: loopPeriod,
- pvcLister: pvcLister,
- pvLister: pvLister,
- resizeMap: resizeMap,
- volumePluginMgr: volumePluginMgr,
- kubeClient: kubeClient,
- }
- eventBroadcaster := record.NewBroadcaster()
- eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.CoreV1().Events("")})
- populator.recorder = eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "volume_expand"})
- return populator
- }
- func (populator *pvcPopulator) Run(stopCh <-chan struct{}) {
- wait.Until(populator.Sync, populator.loopPeriod, stopCh)
- }
- func (populator *pvcPopulator) Sync() {
- pvcs, err := populator.pvcLister.List(labels.Everything())
- if err != nil {
- klog.Errorf("Listing PVCs failed in populator : %v", err)
- return
- }
- for _, pvc := range pvcs {
- pv, err := getPersistentVolume(pvc, populator.pvLister)
- if err != nil {
- klog.V(5).Infof("Error getting persistent volume for PVC %q : %v", pvc.UID, err)
- continue
- }
- // Filter PVCs for which the corresponding volume plugins don't allow expansion.
- pvcSize := pvc.Spec.Resources.Requests[v1.ResourceStorage]
- pvcStatusSize := pvc.Status.Capacity[v1.ResourceStorage]
- volumeSpec := volume.NewSpecFromPersistentVolume(pv, false)
- volumePlugin, err := populator.volumePluginMgr.FindExpandablePluginBySpec(volumeSpec)
- if (err != nil || volumePlugin == nil) && pvcStatusSize.Cmp(pvcSize) < 0 {
- retErr := fmt.Errorf("didn't find a plugin capable of expanding the volume; " +
- "waiting for an external controller to process this PVC")
- eventType := v1.EventTypeNormal
- if err != nil {
- eventType = v1.EventTypeWarning
- }
- populator.recorder.Event(pvc, eventType, events.ExternalExpanding,
- fmt.Sprintf("Ignoring the PVC: %v.", retErr))
- klog.V(3).Infof("Ignoring the PVC %q (uid: %q) : %v.",
- util.GetPersistentVolumeClaimQualifiedName(pvc), pvc.UID, retErr)
- continue
- }
- // We are only going to add PVCs which are:
- // - bound
- // - pvc.Spec.Size > pvc.Status.Size
- // These 2 checks are already performed in AddPVCUpdate function before adding pvc for resize
- // and hence we do not repeat those checks here.
- populator.resizeMap.AddPVCUpdate(pvc, pv)
- }
- }
|