 e634f04d8c
			
		
	
	e634f04d8c
	
	
	
		
			
			This brings in some cri api changes for cgroups, Windows pod sandbox security context changes and some new fields for the Windows version of a privileged container. This also unfortunately bumps the prometheus client, grpc middleware, bolt and klog :( Signed-off-by: Daniel Canter <dcanter@microsoft.com>
		
			
				
	
	
		
			244 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2019 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 metrics
 | |
| 
 | |
| import (
 | |
| 	"sync"
 | |
| 
 | |
| 	"github.com/blang/semver"
 | |
| 	"github.com/prometheus/client_golang/prometheus"
 | |
| 	dto "github.com/prometheus/client_model/go"
 | |
| 
 | |
| 	"k8s.io/klog/v2"
 | |
| )
 | |
| 
 | |
| /*
 | |
| kubeCollector extends the prometheus.Collector interface to allow customization of the metric
 | |
| registration process. Defer metric initialization until Create() is called, which then
 | |
| delegates to the underlying metric's initializeMetric or initializeDeprecatedMetric
 | |
| method call depending on whether the metric is deprecated or not.
 | |
| */
 | |
| type kubeCollector interface {
 | |
| 	Collector
 | |
| 	lazyKubeMetric
 | |
| 	DeprecatedVersion() *semver.Version
 | |
| 	// Each collector metric should provide an initialization function
 | |
| 	// for both deprecated and non-deprecated variants of a metric. This
 | |
| 	// is necessary since metric instantiation will be deferred
 | |
| 	// until the metric is actually registered somewhere.
 | |
| 	initializeMetric()
 | |
| 	initializeDeprecatedMetric()
 | |
| }
 | |
| 
 | |
| /*
 | |
| lazyKubeMetric defines our metric registration interface. lazyKubeMetric objects are expected
 | |
| to lazily instantiate metrics (i.e defer metric instantiation until when
 | |
| the Create() function is explicitly called).
 | |
| */
 | |
| type lazyKubeMetric interface {
 | |
| 	Create(*semver.Version) bool
 | |
| 	IsCreated() bool
 | |
| 	IsHidden() bool
 | |
| 	IsDeprecated() bool
 | |
| }
 | |
| 
 | |
| /*
 | |
| lazyMetric implements lazyKubeMetric. A lazy metric is lazy because it waits until metric
 | |
| registration time before instantiation. Add it as an anonymous field to a struct that
 | |
| implements kubeCollector to get deferred registration behavior. You must call lazyInit
 | |
| with the kubeCollector itself as an argument.
 | |
| */
 | |
| type lazyMetric struct {
 | |
| 	fqName              string
 | |
| 	isDeprecated        bool
 | |
| 	isHidden            bool
 | |
| 	isCreated           bool
 | |
| 	createLock          sync.RWMutex
 | |
| 	markDeprecationOnce sync.Once
 | |
| 	createOnce          sync.Once
 | |
| 	self                kubeCollector
 | |
| }
 | |
| 
 | |
| func (r *lazyMetric) IsCreated() bool {
 | |
| 	r.createLock.RLock()
 | |
| 	defer r.createLock.RUnlock()
 | |
| 	return r.isCreated
 | |
| }
 | |
| 
 | |
| // lazyInit provides the lazyMetric with a reference to the kubeCollector it is supposed
 | |
| // to allow lazy initialization for. It should be invoked in the factory function which creates new
 | |
| // kubeCollector type objects.
 | |
| func (r *lazyMetric) lazyInit(self kubeCollector, fqName string) {
 | |
| 	r.fqName = fqName
 | |
| 	r.self = self
 | |
| }
 | |
| 
 | |
| // preprocessMetric figures out whether the lazy metric should be hidden or not.
 | |
| // This method takes a Version argument which should be the version of the binary in which
 | |
| // this code is currently being executed. A metric can be hidden under two conditions:
 | |
| //      1.  if the metric is deprecated and is outside the grace period (i.e. has been
 | |
| // 			deprecated for more than one release
 | |
| //		2. if the metric is manually disabled via a CLI flag.
 | |
| //
 | |
| // Disclaimer:  disabling a metric via a CLI flag has higher precedence than
 | |
| // 			  	deprecation and will override show-hidden-metrics for the explicitly
 | |
| //				disabled metric.
 | |
| func (r *lazyMetric) preprocessMetric(version semver.Version) {
 | |
| 	disabledMetricsLock.RLock()
 | |
| 	defer disabledMetricsLock.RUnlock()
 | |
| 	// disabling metrics is higher in precedence than showing hidden metrics
 | |
| 	if _, ok := disabledMetrics[r.fqName]; ok {
 | |
| 		r.isHidden = true
 | |
| 		return
 | |
| 	}
 | |
| 	selfVersion := r.self.DeprecatedVersion()
 | |
| 	if selfVersion == nil {
 | |
| 		return
 | |
| 	}
 | |
| 	r.markDeprecationOnce.Do(func() {
 | |
| 		if selfVersion.LTE(version) {
 | |
| 			r.isDeprecated = true
 | |
| 		}
 | |
| 
 | |
| 		if ShouldShowHidden() {
 | |
| 			klog.Warningf("Hidden metrics (%s) have been manually overridden, showing this very deprecated metric.", r.fqName)
 | |
| 			return
 | |
| 		}
 | |
| 		if shouldHide(&version, selfVersion) {
 | |
| 			// TODO(RainbowMango): Remove this log temporarily. https://github.com/kubernetes/kubernetes/issues/85369
 | |
| 			// klog.Warningf("This metric has been deprecated for more than one release, hiding.")
 | |
| 			r.isHidden = true
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func (r *lazyMetric) IsHidden() bool {
 | |
| 	return r.isHidden
 | |
| }
 | |
| 
 | |
| func (r *lazyMetric) IsDeprecated() bool {
 | |
| 	return r.isDeprecated
 | |
| }
 | |
| 
 | |
| // Create forces the initialization of metric which has been deferred until
 | |
| // the point at which this method is invoked. This method will determine whether
 | |
| // the metric is deprecated or hidden, no-opting if the metric should be considered
 | |
| // hidden. Furthermore, this function no-opts and returns true if metric is already
 | |
| // created.
 | |
| func (r *lazyMetric) Create(version *semver.Version) bool {
 | |
| 	if version != nil {
 | |
| 		r.preprocessMetric(*version)
 | |
| 	}
 | |
| 	// let's not create if this metric is slated to be hidden
 | |
| 	if r.IsHidden() {
 | |
| 		return false
 | |
| 	}
 | |
| 	r.createOnce.Do(func() {
 | |
| 		r.createLock.Lock()
 | |
| 		defer r.createLock.Unlock()
 | |
| 		r.isCreated = true
 | |
| 		if r.IsDeprecated() {
 | |
| 			r.self.initializeDeprecatedMetric()
 | |
| 		} else {
 | |
| 			r.self.initializeMetric()
 | |
| 		}
 | |
| 	})
 | |
| 	return r.IsCreated()
 | |
| }
 | |
| 
 | |
| // ClearState will clear all the states marked by Create.
 | |
| // It intends to be used for re-register a hidden metric.
 | |
| func (r *lazyMetric) ClearState() {
 | |
| 	r.createLock.Lock()
 | |
| 	defer r.createLock.Unlock()
 | |
| 
 | |
| 	r.isDeprecated = false
 | |
| 	r.isHidden = false
 | |
| 	r.isCreated = false
 | |
| 	r.markDeprecationOnce = *(new(sync.Once))
 | |
| 	r.createOnce = *(new(sync.Once))
 | |
| }
 | |
| 
 | |
| // FQName returns the fully-qualified metric name of the collector.
 | |
| func (r *lazyMetric) FQName() string {
 | |
| 	return r.fqName
 | |
| }
 | |
| 
 | |
| /*
 | |
| This code is directly lifted from the prometheus codebase. It's a convenience struct which
 | |
| allows you satisfy the Collector interface automatically if you already satisfy the Metric interface.
 | |
| 
 | |
| For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/collector.go#L98-L120
 | |
| */
 | |
| type selfCollector struct {
 | |
| 	metric prometheus.Metric
 | |
| }
 | |
| 
 | |
| func (c *selfCollector) initSelfCollection(m prometheus.Metric) {
 | |
| 	c.metric = m
 | |
| }
 | |
| 
 | |
| func (c *selfCollector) Describe(ch chan<- *prometheus.Desc) {
 | |
| 	ch <- c.metric.Desc()
 | |
| }
 | |
| 
 | |
| func (c *selfCollector) Collect(ch chan<- prometheus.Metric) {
 | |
| 	ch <- c.metric
 | |
| }
 | |
| 
 | |
| // no-op vecs for convenience
 | |
| var noopCounterVec = &prometheus.CounterVec{}
 | |
| var noopHistogramVec = &prometheus.HistogramVec{}
 | |
| var noopGaugeVec = &prometheus.GaugeVec{}
 | |
| var noopObserverVec = &noopObserverVector{}
 | |
| 
 | |
| // just use a convenience struct for all the no-ops
 | |
| var noop = &noopMetric{}
 | |
| 
 | |
| type noopMetric struct{}
 | |
| 
 | |
| func (noopMetric) Inc()                             {}
 | |
| func (noopMetric) Add(float64)                      {}
 | |
| func (noopMetric) Dec()                             {}
 | |
| func (noopMetric) Set(float64)                      {}
 | |
| func (noopMetric) Sub(float64)                      {}
 | |
| func (noopMetric) Observe(float64)                  {}
 | |
| func (noopMetric) SetToCurrentTime()                {}
 | |
| func (noopMetric) Desc() *prometheus.Desc           { return nil }
 | |
| func (noopMetric) Write(*dto.Metric) error          { return nil }
 | |
| func (noopMetric) Describe(chan<- *prometheus.Desc) {}
 | |
| func (noopMetric) Collect(chan<- prometheus.Metric) {}
 | |
| 
 | |
| type noopObserverVector struct{}
 | |
| 
 | |
| func (noopObserverVector) GetMetricWith(prometheus.Labels) (prometheus.Observer, error) {
 | |
| 	return noop, nil
 | |
| }
 | |
| func (noopObserverVector) GetMetricWithLabelValues(...string) (prometheus.Observer, error) {
 | |
| 	return noop, nil
 | |
| }
 | |
| func (noopObserverVector) With(prometheus.Labels) prometheus.Observer    { return noop }
 | |
| func (noopObserverVector) WithLabelValues(...string) prometheus.Observer { return noop }
 | |
| func (noopObserverVector) CurryWith(prometheus.Labels) (prometheus.ObserverVec, error) {
 | |
| 	return noopObserverVec, nil
 | |
| }
 | |
| func (noopObserverVector) MustCurryWith(prometheus.Labels) prometheus.ObserverVec {
 | |
| 	return noopObserverVec
 | |
| }
 | |
| func (noopObserverVector) Describe(chan<- *prometheus.Desc) {}
 | |
| func (noopObserverVector) Collect(chan<- prometheus.Metric) {}
 |