sigs.k8s.io/kueue@v0.6.2/pkg/util/kubeversion/kubeversion.go (about)

     1  package kubeversion
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  	"time"
     7  
     8  	versionutil "k8s.io/apimachinery/pkg/util/version"
     9  	"k8s.io/client-go/discovery"
    10  	ctrl "sigs.k8s.io/controller-runtime"
    11  )
    12  
    13  const fetchServerVersionInterval = time.Minute * 10
    14  
    15  var (
    16  	KubeVersion1_27 = versionutil.MustParseSemantic("1.27.0")
    17  )
    18  
    19  type ServerVersionFetcher struct {
    20  	dc            discovery.DiscoveryInterface
    21  	ticker        *time.Ticker
    22  	serverVersion *versionutil.Version
    23  	rwm           sync.RWMutex
    24  }
    25  
    26  type Options struct {
    27  	Interval time.Duration
    28  }
    29  
    30  type Option func(*Options)
    31  
    32  var defaultOptions = Options{
    33  	Interval: fetchServerVersionInterval,
    34  }
    35  
    36  func WithInterval(interval time.Duration) Option {
    37  	return func(o *Options) {
    38  		o.Interval = interval
    39  	}
    40  }
    41  
    42  func NewServerVersionFetcher(dc discovery.DiscoveryInterface, opts ...Option) *ServerVersionFetcher {
    43  	options := defaultOptions
    44  	for _, opt := range opts {
    45  		opt(&options)
    46  	}
    47  	return &ServerVersionFetcher{
    48  		dc:            dc,
    49  		ticker:        time.NewTicker(options.Interval),
    50  		serverVersion: &versionutil.Version{},
    51  	}
    52  }
    53  
    54  // Start implements the Runnable interface to run ServerVersionFetcher as a controller.
    55  func (s *ServerVersionFetcher) Start(ctx context.Context) error {
    56  	log := ctrl.LoggerFrom(ctx).WithName("serverVersionFetcher")
    57  	ctx = ctrl.LoggerInto(ctx, log)
    58  
    59  	if err := s.FetchServerVersion(); err != nil {
    60  		log.Error(err, "Unable to fetch server version")
    61  	}
    62  
    63  	defer s.ticker.Stop()
    64  
    65  	for {
    66  		select {
    67  		case <-ctx.Done():
    68  			log.V(5).Info("Context cancelled; stop fetching server version")
    69  			return nil
    70  		case <-s.ticker.C:
    71  			if err := s.FetchServerVersion(); err != nil {
    72  				log.Error(err, "Unable to fetch server version")
    73  			} else {
    74  				log.V(5).Info("Fetch server version", "serverVersion", s.serverVersion)
    75  			}
    76  		}
    77  	}
    78  }
    79  
    80  // FetchServerVersion gets API server version
    81  func (s *ServerVersionFetcher) FetchServerVersion() error {
    82  	v, err := FetchServerVersion(s.dc)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	s.rwm.Lock()
    87  	defer s.rwm.Unlock()
    88  	s.serverVersion = v
    89  	return nil
    90  }
    91  
    92  func (s *ServerVersionFetcher) GetServerVersion() versionutil.Version {
    93  	s.rwm.RLock()
    94  	defer s.rwm.RUnlock()
    95  	return *s.serverVersion
    96  }
    97  
    98  func FetchServerVersion(d discovery.DiscoveryInterface) (*versionutil.Version, error) {
    99  	clusterVersionInfo, err := d.ServerVersion()
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  	return versionutil.ParseSemantic(clusterVersionInfo.String())
   104  }