k8s.io/perf-tests/clusterloader2@v0.0.0-20240304094227-64bdb12da87e/pkg/measurement/util/wait_for_pvs.go (about)

     1  /*
     2  Copyright 2019 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 util
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  	"time"
    23  
    24  	clientset "k8s.io/client-go/kubernetes"
    25  	"k8s.io/klog/v2"
    26  	"k8s.io/perf-tests/clusterloader2/pkg/util"
    27  )
    28  
    29  // WaitForPVOptions is an options used by WaitForPVs methods.
    30  type WaitForPVOptions struct {
    31  	Selector           *util.ObjectSelector
    32  	DesiredPVCount     int
    33  	Provisioner        string
    34  	CallerName         string
    35  	WaitForPVsInterval time.Duration
    36  }
    37  
    38  func (options WaitForPVOptions) filter() string {
    39  	filter := options.Selector.String()
    40  	if options.Provisioner != "" {
    41  		filter += " && provisioner=" + options.Provisioner
    42  	}
    43  	return filter
    44  }
    45  
    46  // WaitForPVs waits till desired number of PVs is running.
    47  // PVs are be specified by field and/or label selectors.
    48  // If stopCh is closed before all PVs are running, the error will be returned.
    49  func WaitForPVs(clientSet clientset.Interface, stopCh <-chan struct{}, options *WaitForPVOptions) error {
    50  	ps, err := NewPVStore(clientSet, options.Selector, options.Provisioner)
    51  	if err != nil {
    52  		return fmt.Errorf("PV store creation error: %v", err)
    53  	}
    54  	defer ps.Stop()
    55  
    56  	oldPVs := ps.List()
    57  	scaling := uninitialized
    58  	var pvStatus PVsStartupStatus
    59  
    60  	switch {
    61  	case len(oldPVs) == options.DesiredPVCount:
    62  		scaling = none
    63  	case len(oldPVs) < options.DesiredPVCount:
    64  		scaling = up
    65  	case len(oldPVs) > options.DesiredPVCount:
    66  		scaling = down
    67  	}
    68  
    69  	for {
    70  		select {
    71  		case <-stopCh:
    72  			example := ""
    73  			if len(oldPVs) > 0 {
    74  				example = fmt.Sprintf(", first one is %+v", oldPVs[0])
    75  			}
    76  			return fmt.Errorf("timeout while waiting for %d PVs with selector '%s' - only %d found provisioned%s",
    77  				options.DesiredPVCount, options.filter(), pvStatus.Bound+pvStatus.Available, example)
    78  		case <-time.After(options.WaitForPVsInterval):
    79  			pvs := ps.List()
    80  			pvStatus = ComputePVsStartupStatus(pvs, options.DesiredPVCount)
    81  
    82  			diff := DiffPVs(oldPVs, pvs)
    83  			deletedPVs := diff.DeletedPVs()
    84  			if scaling != down && len(deletedPVs) > 0 {
    85  				klog.Errorf("%s: %s: %d PVs disappeared: %v", options.CallerName, options.Selector.String(), len(deletedPVs), strings.Join(deletedPVs, ", "))
    86  			}
    87  			addedPVs := diff.AddedPVs()
    88  			if scaling != up && len(addedPVs) > 0 {
    89  				klog.Errorf("%s: %s: %d PVs appeared: %v", options.CallerName, options.filter(), len(addedPVs), strings.Join(addedPVs, ", "))
    90  			}
    91  			klog.V(2).Infof("%s: %s: %s", options.CallerName, options.filter(), pvStatus.String())
    92  			// We wait until there is a desired number of PVs provisioned and all other PVs are pending.
    93  			if len(pvs) == (pvStatus.Bound+pvStatus.Available+pvStatus.Pending) && pvStatus.Bound+pvStatus.Available == options.DesiredPVCount {
    94  				return nil
    95  			}
    96  			oldPVs = pvs
    97  		}
    98  	}
    99  }