mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
rebase: update K8s packages to v0.32.1
Update K8s packages in go.mod to v0.32.1 Signed-off-by: Praveen M <m.praveen@ibm.com>
This commit is contained in:
45
vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go
generated
vendored
Normal file
45
vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
/*
|
||||
Copyright 2018 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// GetBootTime returns the time at which the machine was started, truncated to the nearest second
|
||||
func GetBootTime() (time.Time, error) {
|
||||
output, err := unix.SysctlRaw("kern.boottime")
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
var timeval syscall.Timeval
|
||||
if len(output) != int(unsafe.Sizeof(timeval)) {
|
||||
return time.Time{}, fmt.Errorf("unexpected output when calling syscall kern.bootime. Expected len(output) to be %v, but got %v",
|
||||
int(unsafe.Sizeof(timeval)), len(output))
|
||||
}
|
||||
timeval = *(*syscall.Timeval)(unsafe.Pointer(&output[0]))
|
||||
sec, nsec := timeval.Unix()
|
||||
return time.Unix(sec, nsec).Truncate(time.Second), nil
|
||||
}
|
40
vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
//go:build freebsd
|
||||
// +build freebsd
|
||||
|
||||
/*
|
||||
Copyright 2020 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// GetBootTime returns the time at which the machine was started, truncated to the nearest second
|
||||
func GetBootTime() (time.Time, error) {
|
||||
currentTime := time.Now()
|
||||
ts := &unix.Timeval{}
|
||||
_, _, e1 := unix.Syscall(uintptr(unix.SYS_CLOCK_GETTIME), uintptr(unix.CLOCK_UPTIME), uintptr(unsafe.Pointer(ts)), 0)
|
||||
if e1 != 0 {
|
||||
return time.Time{}, fmt.Errorf("error getting system uptime")
|
||||
}
|
||||
|
||||
return currentTime.Add(-time.Duration(ts.Sec) * time.Second).Truncate(time.Second), nil
|
||||
}
|
74
vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go
generated
vendored
Normal file
74
vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2018 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// GetBootTime returns the time at which the machine was started, truncated to the nearest second.
|
||||
// It uses /proc/stat first, which is more accurate, and falls back to the less accurate
|
||||
// unix.Sysinfo if /proc/stat failed.
|
||||
func GetBootTime() (time.Time, error) {
|
||||
bootTime, err := getBootTimeWithProcStat()
|
||||
if err != nil {
|
||||
klog.InfoS("Failed to get boot time from /proc/uptime. Will retry with unix.Sysinfo.", "error", err)
|
||||
return getBootTimeWithSysinfo()
|
||||
}
|
||||
return bootTime, nil
|
||||
}
|
||||
|
||||
func getBootTimeWithProcStat() (time.Time, error) {
|
||||
raw, err := os.ReadFile("/proc/stat")
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("error getting boot time: %w", err)
|
||||
}
|
||||
rawFields := strings.Fields(string(raw))
|
||||
for i, v := range rawFields {
|
||||
if v == "btime" {
|
||||
if len(rawFields) > i+1 {
|
||||
sec, err := strconv.ParseInt(rawFields[i+1], 10, 64)
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("error parsing boot time %s: %w", rawFields[i+1], err)
|
||||
}
|
||||
return time.Unix(sec, 0), nil
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return time.Time{}, fmt.Errorf("can not find btime from /proc/stat: %s", raw)
|
||||
}
|
||||
|
||||
func getBootTimeWithSysinfo() (time.Time, error) {
|
||||
currentTime := time.Now()
|
||||
var info unix.Sysinfo_t
|
||||
if err := unix.Sysinfo(&info); err != nil {
|
||||
return time.Time{}, fmt.Errorf("error getting system uptime: %w", err)
|
||||
}
|
||||
return currentTime.Add(-time.Duration(info.Uptime) * time.Second).Truncate(time.Second), nil
|
||||
}
|
18
vendor/k8s.io/kubernetes/pkg/kubelet/util/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/kubelet/util/doc.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright 2015 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 util holds utility functions.
|
||||
package util // import "k8s.io/kubernetes/pkg/kubelet/util"
|
41
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go
generated
vendored
Normal file
41
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2015 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 format
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// Pod returns a string representing a pod in a consistent human readable format,
|
||||
// with pod UID as part of the string.
|
||||
func Pod(pod *v1.Pod) string {
|
||||
if pod == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return PodDesc(pod.Name, pod.Namespace, pod.UID)
|
||||
}
|
||||
|
||||
// PodDesc returns a string representing a pod in a consistent human readable format,
|
||||
// with pod UID as part of the string.
|
||||
func PodDesc(podName, podNamespace string, podUID types.UID) string {
|
||||
// Use underscore as the delimiter because it is not allowed in pod name
|
||||
// (DNS subdomain format), while allowed in the container name format.
|
||||
return fmt.Sprintf("%s_%s(%s)", podName, podNamespace, podUID)
|
||||
}
|
103
vendor/k8s.io/kubernetes/pkg/kubelet/util/node_startup_latency_tracker.go
generated
vendored
Normal file
103
vendor/k8s.io/kubernetes/pkg/kubelet/util/node_startup_latency_tracker.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright 2023 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 util
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubelet/metrics"
|
||||
"k8s.io/utils/clock"
|
||||
)
|
||||
|
||||
type NodeStartupLatencyTracker interface {
|
||||
// This function may be called across Kubelet restart.
|
||||
RecordAttemptRegisterNode()
|
||||
// This function should not be called across Kubelet restart.
|
||||
RecordRegisteredNewNode()
|
||||
// This function may be called across Kubelet restart.
|
||||
RecordNodeReady()
|
||||
}
|
||||
|
||||
type basicNodeStartupLatencyTracker struct {
|
||||
lock sync.Mutex
|
||||
|
||||
bootTime time.Time
|
||||
kubeletStartTime time.Time
|
||||
firstRegistrationAttemptTime time.Time
|
||||
firstRegisteredNewNodeTime time.Time
|
||||
firstNodeReadyTime time.Time
|
||||
|
||||
// For testability
|
||||
clock clock.Clock
|
||||
}
|
||||
|
||||
func NewNodeStartupLatencyTracker() NodeStartupLatencyTracker {
|
||||
bootTime, err := GetBootTime()
|
||||
if err != nil {
|
||||
bootTime = time.Time{}
|
||||
}
|
||||
return &basicNodeStartupLatencyTracker{
|
||||
bootTime: bootTime,
|
||||
kubeletStartTime: time.Now(),
|
||||
clock: clock.RealClock{},
|
||||
}
|
||||
}
|
||||
|
||||
func (n *basicNodeStartupLatencyTracker) RecordAttemptRegisterNode() {
|
||||
n.lock.Lock()
|
||||
defer n.lock.Unlock()
|
||||
|
||||
if !n.firstRegistrationAttemptTime.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
n.firstRegistrationAttemptTime = n.clock.Now()
|
||||
}
|
||||
|
||||
func (n *basicNodeStartupLatencyTracker) RecordRegisteredNewNode() {
|
||||
n.lock.Lock()
|
||||
defer n.lock.Unlock()
|
||||
|
||||
if n.firstRegistrationAttemptTime.IsZero() || !n.firstRegisteredNewNodeTime.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
n.firstRegisteredNewNodeTime = n.clock.Now()
|
||||
|
||||
if !n.bootTime.IsZero() {
|
||||
metrics.NodeStartupPreKubeletDuration.Set(n.kubeletStartTime.Sub(n.bootTime).Seconds())
|
||||
}
|
||||
metrics.NodeStartupPreRegistrationDuration.Set(n.firstRegistrationAttemptTime.Sub(n.kubeletStartTime).Seconds())
|
||||
metrics.NodeStartupRegistrationDuration.Set(n.firstRegisteredNewNodeTime.Sub(n.firstRegistrationAttemptTime).Seconds())
|
||||
}
|
||||
|
||||
func (n *basicNodeStartupLatencyTracker) RecordNodeReady() {
|
||||
n.lock.Lock()
|
||||
defer n.lock.Unlock()
|
||||
|
||||
if n.firstRegisteredNewNodeTime.IsZero() || !n.firstNodeReadyTime.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
n.firstNodeReadyTime = n.clock.Now()
|
||||
|
||||
metrics.NodeStartupPostRegistrationDuration.Set(n.firstNodeReadyTime.Sub(n.firstRegisteredNewNodeTime).Seconds())
|
||||
if !n.bootTime.IsZero() {
|
||||
metrics.NodeStartupDuration.Set(n.firstNodeReadyTime.Sub(n.bootTime).Seconds())
|
||||
}
|
||||
}
|
55
vendor/k8s.io/kubernetes/pkg/kubelet/util/nodelease.go
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/pkg/kubelet/util/nodelease.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2020 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 util
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
coordinationv1 "k8s.io/api/coordination/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// SetNodeOwnerFunc helps construct a newLeasePostProcessFunc which sets
|
||||
// a node OwnerReference to the given lease object
|
||||
func SetNodeOwnerFunc(c clientset.Interface, nodeName string) func(lease *coordinationv1.Lease) error {
|
||||
return func(lease *coordinationv1.Lease) error {
|
||||
// Setting owner reference needs node's UID. Note that it is different from
|
||||
// kubelet.nodeRef.UID. When lease is initially created, it is possible that
|
||||
// the connection between master and node is not ready yet. So try to set
|
||||
// owner reference every time when renewing the lease, until successful.
|
||||
if len(lease.OwnerReferences) == 0 {
|
||||
if node, err := c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}); err == nil {
|
||||
lease.OwnerReferences = []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: corev1.SchemeGroupVersion.WithKind("Node").Version,
|
||||
Kind: corev1.SchemeGroupVersion.WithKind("Node").Kind,
|
||||
Name: nodeName,
|
||||
UID: node.UID,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
klog.ErrorS(err, "Failed to get node when trying to set owner ref to the node lease", "node", klog.KRef("", nodeName))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
196
vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go
generated
vendored
Normal file
196
vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go
generated
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
Copyright 2022 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 util
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubernetes/pkg/kubelet/metrics"
|
||||
"k8s.io/utils/clock"
|
||||
)
|
||||
|
||||
// PodStartupLatencyTracker records key moments for startup latency calculation,
|
||||
// e.g. image pulling or pod observed running on watch.
|
||||
type PodStartupLatencyTracker interface {
|
||||
ObservedPodOnWatch(pod *v1.Pod, when time.Time)
|
||||
RecordImageStartedPulling(podUID types.UID)
|
||||
RecordImageFinishedPulling(podUID types.UID)
|
||||
RecordStatusUpdated(pod *v1.Pod)
|
||||
DeletePodStartupState(podUID types.UID)
|
||||
}
|
||||
|
||||
type basicPodStartupLatencyTracker struct {
|
||||
// protect against concurrent read and write on pods map
|
||||
lock sync.Mutex
|
||||
pods map[types.UID]*perPodState
|
||||
// metrics for the first network pod only
|
||||
firstNetworkPodSeen bool
|
||||
// For testability
|
||||
clock clock.Clock
|
||||
}
|
||||
|
||||
type perPodState struct {
|
||||
firstStartedPulling time.Time
|
||||
lastFinishedPulling time.Time
|
||||
// first time, when pod status changed into Running
|
||||
observedRunningTime time.Time
|
||||
// log, if pod latency was already Observed
|
||||
metricRecorded bool
|
||||
}
|
||||
|
||||
// NewPodStartupLatencyTracker creates an instance of PodStartupLatencyTracker
|
||||
func NewPodStartupLatencyTracker() PodStartupLatencyTracker {
|
||||
return &basicPodStartupLatencyTracker{
|
||||
pods: map[types.UID]*perPodState{},
|
||||
clock: clock.RealClock{},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *basicPodStartupLatencyTracker) ObservedPodOnWatch(pod *v1.Pod, when time.Time) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
// if the pod is terminal, we do not have to track it anymore for startup
|
||||
if pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded {
|
||||
delete(p.pods, pod.UID)
|
||||
return
|
||||
}
|
||||
|
||||
state := p.pods[pod.UID]
|
||||
if state == nil {
|
||||
// create a new record for pod, only if it was not yet acknowledged by the Kubelet
|
||||
// this is required, as we want to log metric only for those pods, that where scheduled
|
||||
// after Kubelet started
|
||||
if pod.Status.StartTime.IsZero() {
|
||||
p.pods[pod.UID] = &perPodState{}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if state.observedRunningTime.IsZero() {
|
||||
// skip, pod didn't start yet
|
||||
return
|
||||
}
|
||||
|
||||
if state.metricRecorded {
|
||||
// skip, pod's latency already recorded
|
||||
return
|
||||
}
|
||||
|
||||
if hasPodStartedSLO(pod) {
|
||||
podStartingDuration := when.Sub(pod.CreationTimestamp.Time)
|
||||
imagePullingDuration := state.lastFinishedPulling.Sub(state.firstStartedPulling)
|
||||
podStartSLOduration := (podStartingDuration - imagePullingDuration).Seconds()
|
||||
|
||||
klog.InfoS("Observed pod startup duration",
|
||||
"pod", klog.KObj(pod),
|
||||
"podStartSLOduration", podStartSLOduration,
|
||||
"podStartE2EDuration", podStartingDuration,
|
||||
"podCreationTimestamp", pod.CreationTimestamp.Time,
|
||||
"firstStartedPulling", state.firstStartedPulling,
|
||||
"lastFinishedPulling", state.lastFinishedPulling,
|
||||
"observedRunningTime", state.observedRunningTime,
|
||||
"watchObservedRunningTime", when)
|
||||
|
||||
metrics.PodStartSLIDuration.WithLabelValues().Observe(podStartSLOduration)
|
||||
metrics.PodStartTotalDuration.WithLabelValues().Observe(podStartingDuration.Seconds())
|
||||
state.metricRecorded = true
|
||||
// if is the first Pod with network track the start values
|
||||
// these metrics will help to identify problems with the CNI plugin
|
||||
if !pod.Spec.HostNetwork && !p.firstNetworkPodSeen {
|
||||
metrics.FirstNetworkPodStartSLIDuration.Set(podStartSLOduration)
|
||||
p.firstNetworkPodSeen = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *basicPodStartupLatencyTracker) RecordImageStartedPulling(podUID types.UID) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
state := p.pods[podUID]
|
||||
if state == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if state.firstStartedPulling.IsZero() {
|
||||
state.firstStartedPulling = p.clock.Now()
|
||||
}
|
||||
}
|
||||
|
||||
func (p *basicPodStartupLatencyTracker) RecordImageFinishedPulling(podUID types.UID) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
state := p.pods[podUID]
|
||||
if state == nil {
|
||||
return
|
||||
}
|
||||
|
||||
state.lastFinishedPulling = p.clock.Now() // Now is always grater than values from the past.
|
||||
}
|
||||
|
||||
func (p *basicPodStartupLatencyTracker) RecordStatusUpdated(pod *v1.Pod) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
state := p.pods[pod.UID]
|
||||
if state == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if state.metricRecorded {
|
||||
// skip, pod latency already recorded
|
||||
return
|
||||
}
|
||||
|
||||
if !state.observedRunningTime.IsZero() {
|
||||
// skip, pod already started
|
||||
return
|
||||
}
|
||||
|
||||
if hasPodStartedSLO(pod) {
|
||||
klog.V(3).InfoS("Mark when the pod was running for the first time", "pod", klog.KObj(pod), "rv", pod.ResourceVersion)
|
||||
state.observedRunningTime = p.clock.Now()
|
||||
}
|
||||
}
|
||||
|
||||
// hasPodStartedSLO, check if for given pod, each container has been started at least once
|
||||
//
|
||||
// This should reflect "Pod startup latency SLI" definition
|
||||
// ref: https://github.com/kubernetes/community/blob/master/sig-scalability/slos/pod_startup_latency.md
|
||||
func hasPodStartedSLO(pod *v1.Pod) bool {
|
||||
for _, cs := range pod.Status.ContainerStatuses {
|
||||
if cs.State.Running == nil || cs.State.Running.StartedAt.IsZero() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *basicPodStartupLatencyTracker) DeletePodStartupState(podUID types.UID) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
delete(p.pods, podUID)
|
||||
}
|
18
vendor/k8s.io/kubernetes/pkg/kubelet/util/store/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/kubelet/util/store/doc.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright 2015 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 store hosts a Store interface and its implementations.
|
||||
package store // import "k8s.io/kubernetes/pkg/kubelet/util/store"
|
158
vendor/k8s.io/kubernetes/pkg/kubelet/util/store/filestore.go
generated
vendored
Normal file
158
vendor/k8s.io/kubernetes/pkg/kubelet/util/store/filestore.go
generated
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
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 store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
utilfs "k8s.io/kubernetes/pkg/util/filesystem"
|
||||
)
|
||||
|
||||
const (
|
||||
// Name prefix for the temporary files.
|
||||
tmpPrefix = "."
|
||||
)
|
||||
|
||||
// FileStore is an implementation of the Store interface which stores data in files.
|
||||
type FileStore struct {
|
||||
// Absolute path to the base directory for storing data files.
|
||||
directoryPath string
|
||||
|
||||
// filesystem to use.
|
||||
filesystem utilfs.Filesystem
|
||||
}
|
||||
|
||||
// NewFileStore returns an instance of FileStore.
|
||||
func NewFileStore(path string, fs utilfs.Filesystem) (Store, error) {
|
||||
if err := fs.MkdirAll(path, 0755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &FileStore{directoryPath: path, filesystem: fs}, nil
|
||||
}
|
||||
|
||||
// Write writes the given data to a file named key.
|
||||
func (f *FileStore) Write(key string, data []byte) error {
|
||||
if err := ValidateKey(key); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.filesystem.MkdirAll(f.directoryPath, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeFile(f.filesystem, f.getPathByKey(key), data)
|
||||
}
|
||||
|
||||
// Read reads the data from the file named key.
|
||||
func (f *FileStore) Read(key string) ([]byte, error) {
|
||||
if err := ValidateKey(key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bytes, err := f.filesystem.ReadFile(f.getPathByKey(key))
|
||||
if os.IsNotExist(err) {
|
||||
return bytes, ErrKeyNotFound
|
||||
}
|
||||
return bytes, err
|
||||
}
|
||||
|
||||
// Delete deletes the key file.
|
||||
func (f *FileStore) Delete(key string) error {
|
||||
if err := ValidateKey(key); err != nil {
|
||||
return err
|
||||
}
|
||||
return removePath(f.filesystem, f.getPathByKey(key))
|
||||
}
|
||||
|
||||
// List returns all keys in the store.
|
||||
func (f *FileStore) List() ([]string, error) {
|
||||
keys := make([]string, 0)
|
||||
files, err := f.filesystem.ReadDir(f.directoryPath)
|
||||
if err != nil {
|
||||
return keys, err
|
||||
}
|
||||
for _, f := range files {
|
||||
if !strings.HasPrefix(f.Name(), tmpPrefix) {
|
||||
keys = append(keys, f.Name())
|
||||
}
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
// getPathByKey returns the full path of the file for the key.
|
||||
func (f *FileStore) getPathByKey(key string) string {
|
||||
return filepath.Join(f.directoryPath, key)
|
||||
}
|
||||
|
||||
// writeFile writes data to path in a single transaction.
|
||||
func writeFile(fs utilfs.Filesystem, path string, data []byte) (retErr error) {
|
||||
// Create a temporary file in the base directory of `path` with a prefix.
|
||||
tmpFile, err := fs.TempFile(filepath.Dir(path), tmpPrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpPath := tmpFile.Name()
|
||||
shouldClose := true
|
||||
|
||||
defer func() {
|
||||
// Close the file.
|
||||
if shouldClose {
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
if retErr == nil {
|
||||
retErr = fmt.Errorf("close error: %v", err)
|
||||
} else {
|
||||
retErr = fmt.Errorf("failed to close temp file after error %v; close error: %v", retErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up the temp file on error.
|
||||
if retErr != nil && tmpPath != "" {
|
||||
if err := removePath(fs, tmpPath); err != nil {
|
||||
retErr = fmt.Errorf("failed to remove the temporary file (%q) after error %v; remove error: %v", tmpPath, retErr, err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Write data.
|
||||
if _, err := tmpFile.Write(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Sync file.
|
||||
if err := tmpFile.Sync(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Closing the file before renaming.
|
||||
err = tmpFile.Close()
|
||||
shouldClose = false
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return fs.Rename(tmpPath, path)
|
||||
}
|
||||
|
||||
func removePath(fs utilfs.Filesystem, path string) error {
|
||||
if err := fs.Remove(path); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
64
vendor/k8s.io/kubernetes/pkg/kubelet/util/store/store.go
generated
vendored
Normal file
64
vendor/k8s.io/kubernetes/pkg/kubelet/util/store/store.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
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 store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const (
|
||||
keyMaxLength = 250
|
||||
|
||||
keyCharFmt string = "[A-Za-z0-9]"
|
||||
keyExtCharFmt string = "[-A-Za-z0-9_.]"
|
||||
qualifiedKeyFmt string = "(" + keyCharFmt + keyExtCharFmt + "*)?" + keyCharFmt
|
||||
)
|
||||
|
||||
var (
|
||||
// Key must consist of alphanumeric characters, '-', '_' or '.', and must start
|
||||
// and end with an alphanumeric character.
|
||||
keyRegex = regexp.MustCompile("^" + qualifiedKeyFmt + "$")
|
||||
|
||||
// ErrKeyNotFound is the error returned if key is not found in Store.
|
||||
ErrKeyNotFound = fmt.Errorf("key is not found")
|
||||
)
|
||||
|
||||
// Store provides the interface for storing keyed data.
|
||||
// Store must be thread-safe
|
||||
type Store interface {
|
||||
// key must contain one or more characters in [A-Za-z0-9]
|
||||
// Write writes data with key.
|
||||
Write(key string, data []byte) error
|
||||
// Read retrieves data with key
|
||||
// Read must return ErrKeyNotFound if key is not found.
|
||||
Read(key string) ([]byte, error)
|
||||
// Delete deletes data by key
|
||||
// Delete must not return error if key does not exist
|
||||
Delete(key string) error
|
||||
// List lists all existing keys.
|
||||
List() ([]string, error)
|
||||
}
|
||||
|
||||
// ValidateKey returns an error if the given key does not meet the requirement
|
||||
// of the key format and length.
|
||||
func ValidateKey(key string) error {
|
||||
if len(key) <= keyMaxLength && keyRegex.MatchString(key) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid key: %q", key)
|
||||
}
|
149
vendor/k8s.io/kubernetes/pkg/kubelet/util/swap/swap_util.go
generated
vendored
Normal file
149
vendor/k8s.io/kubernetes/pkg/kubelet/util/swap/swap_util.go
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
Copyright 2024 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 swap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
sysruntime "runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
inuserns "github.com/moby/sys/userns"
|
||||
"k8s.io/apimachinery/pkg/util/version"
|
||||
"k8s.io/klog/v2"
|
||||
utilkernel "k8s.io/kubernetes/pkg/util/kernel"
|
||||
"k8s.io/mount-utils"
|
||||
)
|
||||
|
||||
var (
|
||||
tmpfsNoswapOptionSupported bool
|
||||
tmpfsNoswapOptionAvailabilityOnce sync.Once
|
||||
swapOn bool
|
||||
swapOnErr error
|
||||
swapOnOnce sync.Once
|
||||
)
|
||||
|
||||
const TmpfsNoswapOption = "noswap"
|
||||
|
||||
func IsTmpfsNoswapOptionSupported(mounter mount.Interface, mountPath string) bool {
|
||||
isTmpfsNoswapOptionSupportedHelper := func() bool {
|
||||
if sysruntime.GOOS == "windows" {
|
||||
return false
|
||||
}
|
||||
|
||||
if inuserns.RunningInUserNS() {
|
||||
// Turning off swap in unprivileged tmpfs mounts unsupported
|
||||
// https://github.com/torvalds/linux/blob/v6.8/mm/shmem.c#L4004-L4011
|
||||
// https://github.com/kubernetes/kubernetes/issues/125137
|
||||
klog.InfoS("Running under a user namespace - tmpfs noswap is not supported")
|
||||
return false
|
||||
}
|
||||
|
||||
kernelVersion, err := utilkernel.GetVersion()
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot determine kernel version, unable to determine is tmpfs noswap is supported")
|
||||
return false
|
||||
}
|
||||
|
||||
if kernelVersion.AtLeast(version.MustParseGeneric(utilkernel.TmpfsNoswapSupportKernelVersion)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if mountPath == "" {
|
||||
klog.ErrorS(errors.New("mount path is empty, falling back to /tmp"), "")
|
||||
}
|
||||
|
||||
mountPath, err = os.MkdirTemp(mountPath, "tmpfs-noswap-test-")
|
||||
if err != nil {
|
||||
klog.InfoS("error creating dir to test if tmpfs noswap is enabled. Assuming not supported", "mount path", mountPath, "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err = os.RemoveAll(mountPath)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "error removing test tmpfs dir", "mount path", mountPath)
|
||||
}
|
||||
}()
|
||||
|
||||
err = mounter.MountSensitiveWithoutSystemd("tmpfs", mountPath, "tmpfs", []string{TmpfsNoswapOption}, nil)
|
||||
if err != nil {
|
||||
klog.InfoS("error mounting tmpfs with the noswap option. Assuming not supported", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
err = mounter.Unmount(mountPath)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "error unmounting test tmpfs dir", "mount path", mountPath)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
tmpfsNoswapOptionAvailabilityOnce.Do(func() {
|
||||
tmpfsNoswapOptionSupported = isTmpfsNoswapOptionSupportedHelper()
|
||||
})
|
||||
|
||||
return tmpfsNoswapOptionSupported
|
||||
}
|
||||
|
||||
// gets /proc/swaps's content as an input, returns true if swap is enabled.
|
||||
func isSwapOnAccordingToProcSwaps(procSwapsContent []byte) bool {
|
||||
procSwapsContent = bytes.TrimSpace(procSwapsContent) // extra trailing \n
|
||||
procSwapsStr := string(procSwapsContent)
|
||||
procSwapsLines := strings.Split(procSwapsStr, "\n")
|
||||
|
||||
// If there is more than one line (table headers) in /proc/swaps then swap is enabled
|
||||
isSwapOn := len(procSwapsLines) > 1
|
||||
if isSwapOn {
|
||||
klog.InfoS("Swap is on", "/proc/swaps contents", procSwapsStr)
|
||||
}
|
||||
|
||||
return isSwapOn
|
||||
}
|
||||
|
||||
// IsSwapOn detects whether swap in enabled on the system by inspecting
|
||||
// /proc/swaps. If the file does not exist, an os.NotFound error will be returned.
|
||||
// If running on windows, swap is assumed to always be false.
|
||||
func IsSwapOn() (bool, error) {
|
||||
isSwapOnHelper := func() (bool, error) {
|
||||
if sysruntime.GOOS == "windows" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
const swapFilePath = "/proc/swaps"
|
||||
procSwapsContent, err := os.ReadFile(swapFilePath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
klog.InfoS("File does not exist, assuming that swap is disabled", "path", swapFilePath)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
return isSwapOnAccordingToProcSwaps(procSwapsContent), nil
|
||||
}
|
||||
|
||||
swapOnOnce.Do(func() {
|
||||
swapOn, swapOnErr = isSwapOnHelper()
|
||||
})
|
||||
|
||||
return swapOn, swapOnErr
|
||||
}
|
62
vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go
generated
vendored
Normal file
62
vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/util/filesystem"
|
||||
)
|
||||
|
||||
// FromApiserverCache modifies <opts> so that the GET request will
|
||||
// be served from apiserver cache instead of from etcd.
|
||||
func FromApiserverCache(opts *metav1.GetOptions) {
|
||||
opts.ResourceVersion = "0"
|
||||
}
|
||||
|
||||
var IsUnixDomainSocket = filesystem.IsUnixDomainSocket
|
||||
|
||||
// GetNodenameForKernel gets hostname value to set in the hostname field (the nodename field of struct utsname) of the pod.
|
||||
func GetNodenameForKernel(hostname string, hostDomainName string, setHostnameAsFQDN *bool) (string, error) {
|
||||
kernelHostname := hostname
|
||||
// FQDN has to be 64 chars to fit in the Linux nodename kernel field (specification 64 chars and the null terminating char).
|
||||
const fqdnMaxLen = 64
|
||||
if len(hostDomainName) > 0 && setHostnameAsFQDN != nil && *setHostnameAsFQDN {
|
||||
fqdn := fmt.Sprintf("%s.%s", hostname, hostDomainName)
|
||||
// FQDN has to be shorter than hostnameMaxLen characters.
|
||||
if len(fqdn) > fqdnMaxLen {
|
||||
return "", fmt.Errorf("failed to construct FQDN from pod hostname and cluster domain, FQDN %s is too long (%d characters is the max, %d characters requested)", fqdn, fqdnMaxLen, len(fqdn))
|
||||
}
|
||||
kernelHostname = fqdn
|
||||
}
|
||||
return kernelHostname, nil
|
||||
}
|
||||
|
||||
// GetContainerByIndex validates and extracts the container at index "idx" from
|
||||
// "containers" with respect to "statuses".
|
||||
// It returns true if the container is valid, else returns false.
|
||||
func GetContainerByIndex(containers []v1.Container, statuses []v1.ContainerStatus, idx int) (v1.Container, bool) {
|
||||
if idx < 0 || idx >= len(containers) || idx >= len(statuses) {
|
||||
return v1.Container{}, false
|
||||
}
|
||||
if statuses[idx].Name != containers[idx].Name {
|
||||
return v1.Container{}, false
|
||||
}
|
||||
return containers[idx], true
|
||||
}
|
29
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go
generated
vendored
Normal file
29
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
libcontainercgroups "github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
)
|
||||
|
||||
// IsCgroup2UnifiedMode returns true if the cgroup v2 unified mode is enabled
|
||||
func IsCgroup2UnifiedMode() bool {
|
||||
return libcontainercgroups.IsCgroup2UnifiedMode()
|
||||
}
|
25
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go
generated
vendored
Normal file
25
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
//go:build !linux && !windows
|
||||
// +build !linux,!windows
|
||||
|
||||
/*
|
||||
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 util
|
||||
|
||||
// IsCgroup2UnifiedMode is a no-op for other OSes.
|
||||
func IsCgroup2UnifiedMode() bool {
|
||||
return false
|
||||
}
|
44
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go
generated
vendored
Normal file
44
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
//go:build freebsd || linux || darwin
|
||||
// +build freebsd linux darwin
|
||||
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const (
|
||||
// unixProtocol is the network protocol of unix socket.
|
||||
unixProtocol = "unix"
|
||||
)
|
||||
|
||||
// LocalEndpoint returns the full path to a unix socket at the given endpoint
|
||||
func LocalEndpoint(path, file string) (string, error) {
|
||||
u := url.URL{
|
||||
Scheme: unixProtocol,
|
||||
Path: path,
|
||||
}
|
||||
return filepath.Join(u.String(), file+".sock"), nil
|
||||
}
|
||||
|
||||
// NormalizePath is a no-op for Linux for now
|
||||
func NormalizePath(path string) string {
|
||||
return path
|
||||
}
|
44
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go
generated
vendored
Normal file
44
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
//go:build !freebsd && !linux && !windows && !darwin
|
||||
// +build !freebsd,!linux,!windows,!darwin
|
||||
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// LockAndCheckSubPath empty implementation
|
||||
func LockAndCheckSubPath(volumePath, subPath string) ([]uintptr, error) {
|
||||
return []uintptr{}, nil
|
||||
}
|
||||
|
||||
// UnlockPath empty implementation
|
||||
func UnlockPath(fileHandles []uintptr) {
|
||||
}
|
||||
|
||||
// LocalEndpoint empty implementation
|
||||
func LocalEndpoint(path, file string) (string, error) {
|
||||
return "", fmt.Errorf("LocalEndpoints are unsupported in this build")
|
||||
}
|
||||
|
||||
// GetBootTime empty implementation
|
||||
func GetBootTime() (time.Time, error) {
|
||||
return time.Time{}, fmt.Errorf("GetBootTime is unsupported in this build")
|
||||
}
|
80
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go
generated
vendored
Normal file
80
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const npipeProtocol = "npipe"
|
||||
|
||||
// LocalEndpoint returns the full path to a named pipe at the given endpoint - unlike on unix, we can't use sockets.
|
||||
func LocalEndpoint(path, file string) (string, error) {
|
||||
// extract the podresources config name from the path. We only need this on windows because the preferred layout of pipes,
|
||||
// this is why we have the extra logic in here instead of changing the function signature. Join the file to make sure the
|
||||
// last path component is a file, so the operation chain works..
|
||||
podResourcesDir := filepath.Base(filepath.Dir(filepath.Join(path, file)))
|
||||
if podResourcesDir == "" {
|
||||
// should not happen because the user can configure a root directory, and we expected a subdirectory inside
|
||||
// the user supplied root directory named like "pod-resources" or so.
|
||||
return "", fmt.Errorf("cannot infer the podresources directory from path %q", path)
|
||||
}
|
||||
// windows pipes are expected to use forward slashes: https://learn.microsoft.com/windows/win32/ipc/pipe-names
|
||||
// so using `url` like we do on unix gives us unclear benefits - see https://github.com/kubernetes/kubernetes/issues/78628
|
||||
// So we just construct the path from scratch.
|
||||
// Format: \\ServerName\pipe\PipeName
|
||||
// Where where ServerName is either the name of a remote computer or a period, to specify the local computer.
|
||||
// We only consider PipeName as regular windows path, while the pipe path components are fixed, hence we use constants.
|
||||
serverPart := `\\.`
|
||||
pipePart := "pipe"
|
||||
pipeName := "kubelet-" + podResourcesDir
|
||||
return npipeProtocol + "://" + filepath.Join(serverPart, pipePart, pipeName), nil
|
||||
}
|
||||
|
||||
var tickCount = syscall.NewLazyDLL("kernel32.dll").NewProc("GetTickCount64")
|
||||
|
||||
// GetBootTime returns the time at which the machine was started, truncated to the nearest second
|
||||
func GetBootTime() (time.Time, error) {
|
||||
currentTime := time.Now()
|
||||
output, _, err := tickCount.Call()
|
||||
if errno, ok := err.(syscall.Errno); !ok || errno != 0 {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return currentTime.Add(-time.Duration(output) * time.Millisecond).Truncate(time.Second), nil
|
||||
}
|
||||
|
||||
// NormalizePath converts FS paths returned by certain go frameworks (like fsnotify)
|
||||
// to native Windows paths that can be passed to Windows specific code
|
||||
func NormalizePath(path string) string {
|
||||
path = strings.ReplaceAll(path, "/", "\\")
|
||||
if strings.HasPrefix(path, "\\") {
|
||||
path = "c:" + path
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// IsCgroup2UnifiedMode is a no-op for Windows for now
|
||||
func IsCgroup2UnifiedMode() bool {
|
||||
return false
|
||||
}
|
Reference in New Issue
Block a user