mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 18:43:34 +00:00
build: move e2e dependencies into e2e/go.mod
Several packages are only used while running the e2e suite. These packages are less important to update, as the they can not influence the final executable that is part of the Ceph-CSI container-image. By moving these dependencies out of the main Ceph-CSI go.mod, it is easier to identify if a reported CVE affects Ceph-CSI, or only the testing (like most of the Kubernetes CVEs). Signed-off-by: Niels de Vos <ndevos@ibm.com>
This commit is contained in:
committed by
mergify[bot]
parent
15da101b1b
commit
bec6090996
32
vendor/k8s.io/kubernetes/pkg/util/hash/hash.go
generated
vendored
32
vendor/k8s.io/kubernetes/pkg/util/hash/hash.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
/*
|
||||
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 hash
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/dump"
|
||||
)
|
||||
|
||||
// DeepHashObject writes specified object to hash using the spew library
|
||||
// which follows pointers and prints actual values of the nested objects
|
||||
// ensuring the hash does not change when a pointer changes.
|
||||
func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) {
|
||||
hasher.Reset()
|
||||
fmt.Fprintf(hasher, "%v", dump.ForHash(objectToWrite))
|
||||
}
|
8
vendor/k8s.io/kubernetes/pkg/util/kernel/OWNERS
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/util/kernel/OWNERS
generated
vendored
@ -1,8 +0,0 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
reviewers:
|
||||
- sig-network-reviewers
|
||||
- sig-node-reviewers
|
||||
approvers:
|
||||
- sig-network-approvers
|
||||
- sig-node-approvers
|
64
vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go
generated
vendored
64
vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
/*
|
||||
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 kernel
|
||||
|
||||
// IPLocalReservedPortsNamespacedKernelVersion is the kernel version in which net.ipv4.ip_local_reserved_ports was namespaced(netns).
|
||||
// (ref: https://github.com/torvalds/linux/commit/122ff243f5f104194750ecbc76d5946dd1eec934)
|
||||
const IPLocalReservedPortsNamespacedKernelVersion = "3.16"
|
||||
|
||||
// IPVSConnReuseModeMinSupportedKernelVersion is the minium kernel version supporting net.ipv4.vs.conn_reuse_mode.
|
||||
// (ref: https://github.com/torvalds/linux/commit/d752c364571743d696c2a54a449ce77550c35ac5)
|
||||
const IPVSConnReuseModeMinSupportedKernelVersion = "4.1"
|
||||
|
||||
// TCPKeepAliveTimeNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_keepalive_time was namespaced(netns).
|
||||
// (ref: https://github.com/torvalds/linux/commit/13b287e8d1cad951634389f85b8c9b816bd3bb1e)
|
||||
const TCPKeepAliveTimeNamespacedKernelVersion = "4.5"
|
||||
|
||||
// TCPKeepAliveIntervalNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_keepalive_intvl was namespaced(netns).
|
||||
// (ref: https://github.com/torvalds/linux/commit/b840d15d39128d08ed4486085e5507d2617b9ae1)
|
||||
const TCPKeepAliveIntervalNamespacedKernelVersion = "4.5"
|
||||
|
||||
// TCPKeepAliveProbesNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_keepalive_probes was namespaced(netns).
|
||||
// (ref: https://github.com/torvalds/linux/commit/9bd6861bd4326e3afd3f14a9ec8a723771fb20bb)
|
||||
const TCPKeepAliveProbesNamespacedKernelVersion = "4.5"
|
||||
|
||||
// TCPFinTimeoutNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_fin_timeout was namespaced(netns).
|
||||
// (ref: https://github.com/torvalds/linux/commit/1e579caa18b96f9eb18f4f5416658cd15f37c062)
|
||||
const TCPFinTimeoutNamespacedKernelVersion = "4.6"
|
||||
|
||||
// IPVSConnReuseModeFixedKernelVersion is the kernel version in which net.ipv4.vs.conn_reuse_mode was fixed.
|
||||
// (ref: https://github.com/torvalds/linux/commit/35dfb013149f74c2be1ff9c78f14e6a3cd1539d1)
|
||||
const IPVSConnReuseModeFixedKernelVersion = "5.9"
|
||||
|
||||
// UserNamespacesSupportKernelVersion is the kernel version where idmap for tmpfs support was added
|
||||
// (ref: https://github.com/torvalds/linux/commit/05e6295f7b5e05f09e369a3eb2882ec5b40fff20)
|
||||
const UserNamespacesSupportKernelVersion = "6.3"
|
||||
|
||||
const TmpfsNoswapSupportKernelVersion = "6.4"
|
||||
|
||||
// NFTablesKubeProxyKernelVersion is the lowest kernel version kube-proxy supports using
|
||||
// nftables mode with by default. This is not directly related to any specific kernel
|
||||
// commit; see https://issues.k8s.io/122743#issuecomment-1893922424
|
||||
const NFTablesKubeProxyKernelVersion = "5.13"
|
||||
|
||||
// TCPReceiveMemoryNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_rmem was namespaced(netns).
|
||||
// (ref: https://github.com/torvalds/linux/commit/356d1833b638bd465672aefeb71def3ab93fc17d)
|
||||
const TCPReceiveMemoryNamespacedKernelVersion = "4.15"
|
||||
|
||||
// TCPTransmitMemoryNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_wmem was namespaced(netns).
|
||||
// (ref: https://github.com/torvalds/linux/commit/356d1833b638bd465672aefeb71def3ab93fc17d)
|
||||
const TCPTransmitMemoryNamespacedKernelVersion = "4.15"
|
48
vendor/k8s.io/kubernetes/pkg/util/kernel/version.go
generated
vendored
48
vendor/k8s.io/kubernetes/pkg/util/kernel/version.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
/*
|
||||
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 kernel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/version"
|
||||
)
|
||||
|
||||
type readFileFunc func(string) ([]byte, error)
|
||||
|
||||
// GetVersion returns currently running kernel version.
|
||||
func GetVersion() (*version.Version, error) {
|
||||
return getVersion(os.ReadFile)
|
||||
}
|
||||
|
||||
// getVersion reads os release file from the give readFile function.
|
||||
func getVersion(readFile readFileFunc) (*version.Version, error) {
|
||||
kernelVersionFile := "/proc/sys/kernel/osrelease"
|
||||
fileContent, err := readFile(kernelVersionFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read os-release file: %s", err.Error())
|
||||
}
|
||||
|
||||
kernelVersion, err := version.ParseGeneric(strings.TrimSpace(string(fileContent)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse kernel version: %s", err.Error())
|
||||
}
|
||||
|
||||
return kernelVersion, nil
|
||||
}
|
0
vendor/k8s.io/kubernetes/pkg/util/labels/.readonly
generated
vendored
0
vendor/k8s.io/kubernetes/pkg/util/labels/.readonly
generated
vendored
18
vendor/k8s.io/kubernetes/pkg/util/labels/doc.go
generated
vendored
18
vendor/k8s.io/kubernetes/pkg/util/labels/doc.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 labels provides utilities to work with Kubernetes labels.
|
||||
package labels // import "k8s.io/kubernetes/pkg/util/labels"
|
124
vendor/k8s.io/kubernetes/pkg/util/labels/labels.go
generated
vendored
124
vendor/k8s.io/kubernetes/pkg/util/labels/labels.go
generated
vendored
@ -1,124 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 labels
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Clones the given map and returns a new map with the given key and value added.
|
||||
// Returns the given map, if labelKey is empty.
|
||||
func CloneAndAddLabel(labels map[string]string, labelKey, labelValue string) map[string]string {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return labels
|
||||
}
|
||||
// Clone.
|
||||
newLabels := map[string]string{}
|
||||
for key, value := range labels {
|
||||
newLabels[key] = value
|
||||
}
|
||||
newLabels[labelKey] = labelValue
|
||||
return newLabels
|
||||
}
|
||||
|
||||
// CloneAndRemoveLabel clones the given map and returns a new map with the given key removed.
|
||||
// Returns the given map, if labelKey is empty.
|
||||
func CloneAndRemoveLabel(labels map[string]string, labelKey string) map[string]string {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return labels
|
||||
}
|
||||
// Clone.
|
||||
newLabels := map[string]string{}
|
||||
for key, value := range labels {
|
||||
newLabels[key] = value
|
||||
}
|
||||
delete(newLabels, labelKey)
|
||||
return newLabels
|
||||
}
|
||||
|
||||
// AddLabel returns a map with the given key and value added to the given map.
|
||||
func AddLabel(labels map[string]string, labelKey, labelValue string) map[string]string {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return labels
|
||||
}
|
||||
if labels == nil {
|
||||
labels = make(map[string]string)
|
||||
}
|
||||
labels[labelKey] = labelValue
|
||||
return labels
|
||||
}
|
||||
|
||||
// Clones the given selector and returns a new selector with the given key and value added.
|
||||
// Returns the given selector, if labelKey is empty.
|
||||
func CloneSelectorAndAddLabel(selector *metav1.LabelSelector, labelKey, labelValue string) *metav1.LabelSelector {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return selector
|
||||
}
|
||||
|
||||
// Clone.
|
||||
newSelector := new(metav1.LabelSelector)
|
||||
|
||||
// TODO(madhusudancs): Check if you can use deepCopy_extensions_LabelSelector here.
|
||||
newSelector.MatchLabels = make(map[string]string)
|
||||
if selector.MatchLabels != nil {
|
||||
for key, val := range selector.MatchLabels {
|
||||
newSelector.MatchLabels[key] = val
|
||||
}
|
||||
}
|
||||
newSelector.MatchLabels[labelKey] = labelValue
|
||||
|
||||
if selector.MatchExpressions != nil {
|
||||
newMExps := make([]metav1.LabelSelectorRequirement, len(selector.MatchExpressions))
|
||||
for i, me := range selector.MatchExpressions {
|
||||
newMExps[i].Key = me.Key
|
||||
newMExps[i].Operator = me.Operator
|
||||
if me.Values != nil {
|
||||
newMExps[i].Values = make([]string, len(me.Values))
|
||||
copy(newMExps[i].Values, me.Values)
|
||||
} else {
|
||||
newMExps[i].Values = nil
|
||||
}
|
||||
}
|
||||
newSelector.MatchExpressions = newMExps
|
||||
} else {
|
||||
newSelector.MatchExpressions = nil
|
||||
}
|
||||
|
||||
return newSelector
|
||||
}
|
||||
|
||||
// AddLabelToSelector returns a selector with the given key and value added to the given selector's MatchLabels.
|
||||
func AddLabelToSelector(selector *metav1.LabelSelector, labelKey, labelValue string) *metav1.LabelSelector {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return selector
|
||||
}
|
||||
if selector.MatchLabels == nil {
|
||||
selector.MatchLabels = make(map[string]string)
|
||||
}
|
||||
selector.MatchLabels[labelKey] = labelValue
|
||||
return selector
|
||||
}
|
||||
|
||||
// SelectorHasLabel checks if the given selector contains the given label key in its MatchLabels
|
||||
func SelectorHasLabel(selector *metav1.LabelSelector, labelKey string) bool {
|
||||
return len(selector.MatchLabels[labelKey]) > 0
|
||||
}
|
18
vendor/k8s.io/kubernetes/pkg/util/oom/doc.go
generated
vendored
18
vendor/k8s.io/kubernetes/pkg/util/oom/doc.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
/*
|
||||
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 oom implements utility functions relating to out of memory management.
|
||||
package oom // import "k8s.io/kubernetes/pkg/util/oom"
|
26
vendor/k8s.io/kubernetes/pkg/util/oom/oom.go
generated
vendored
26
vendor/k8s.io/kubernetes/pkg/util/oom/oom.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
/*
|
||||
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 oom
|
||||
|
||||
// This is a struct instead of an interface to allow injection of process ID listers and
|
||||
// applying OOM score in tests.
|
||||
// TODO: make this an interface, and inject a mock ioutil struct for testing.
|
||||
type OOMAdjuster struct {
|
||||
pidLister func(cgroupName string) ([]int, error)
|
||||
ApplyOOMScoreAdj func(pid int, oomScoreAdj int) error
|
||||
ApplyOOMScoreAdjContainer func(cgroupName string, oomScoreAdj, maxTries int) error
|
||||
}
|
35
vendor/k8s.io/kubernetes/pkg/util/oom/oom_fake.go
generated
vendored
35
vendor/k8s.io/kubernetes/pkg/util/oom/oom_fake.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
/*
|
||||
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 oom
|
||||
|
||||
type FakeOOMAdjuster struct{}
|
||||
|
||||
func NewFakeOOMAdjuster() *OOMAdjuster {
|
||||
return &OOMAdjuster{
|
||||
pidLister: func(cgroupName string) ([]int, error) { return make([]int, 0), nil },
|
||||
ApplyOOMScoreAdj: fakeApplyOOMScoreAdj,
|
||||
ApplyOOMScoreAdjContainer: fakeApplyOOMScoreAdjContainer,
|
||||
}
|
||||
}
|
||||
|
||||
func fakeApplyOOMScoreAdj(pid int, oomScoreAdj int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func fakeApplyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error {
|
||||
return nil
|
||||
}
|
130
vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go
generated
vendored
130
vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go
generated
vendored
@ -1,130 +0,0 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
/*
|
||||
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 oom
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
cmutil "k8s.io/kubernetes/pkg/kubelet/cm/util"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func NewOOMAdjuster() *OOMAdjuster {
|
||||
oomAdjuster := &OOMAdjuster{
|
||||
pidLister: getPids,
|
||||
ApplyOOMScoreAdj: applyOOMScoreAdj,
|
||||
}
|
||||
oomAdjuster.ApplyOOMScoreAdjContainer = oomAdjuster.applyOOMScoreAdjContainer
|
||||
return oomAdjuster
|
||||
}
|
||||
|
||||
func getPids(cgroupName string) ([]int, error) {
|
||||
return cmutil.GetPids(filepath.Join("/", cgroupName))
|
||||
}
|
||||
|
||||
// Writes 'value' to /proc/<pid>/oom_score_adj. PID = 0 means self
|
||||
// Returns os.ErrNotExist if the `pid` does not exist.
|
||||
func applyOOMScoreAdj(pid int, oomScoreAdj int) error {
|
||||
if pid < 0 {
|
||||
return fmt.Errorf("invalid PID %d specified for oom_score_adj", pid)
|
||||
}
|
||||
|
||||
var pidStr string
|
||||
if pid == 0 {
|
||||
pidStr = "self"
|
||||
} else {
|
||||
pidStr = strconv.Itoa(pid)
|
||||
}
|
||||
|
||||
maxTries := 2
|
||||
oomScoreAdjPath := path.Join("/proc", pidStr, "oom_score_adj")
|
||||
value := strconv.Itoa(oomScoreAdj)
|
||||
klog.V(4).Infof("attempting to set %q to %q", oomScoreAdjPath, value)
|
||||
var err error
|
||||
for i := 0; i < maxTries; i++ {
|
||||
err = os.WriteFile(oomScoreAdjPath, []byte(value), 0700)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
klog.V(2).Infof("%q does not exist", oomScoreAdjPath)
|
||||
return os.ErrNotExist
|
||||
}
|
||||
|
||||
klog.V(3).Info(err)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
klog.V(2).Infof("failed to set %q to %q: %v", oomScoreAdjPath, value, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Writes 'value' to /proc/<pid>/oom_score_adj for all processes in cgroup cgroupName.
|
||||
// Keeps trying to write until the process list of the cgroup stabilizes, or until maxTries tries.
|
||||
func (oomAdjuster *OOMAdjuster) applyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error {
|
||||
adjustedProcessSet := make(map[int]bool)
|
||||
for i := 0; i < maxTries; i++ {
|
||||
continueAdjusting := false
|
||||
pidList, err := oomAdjuster.pidLister(cgroupName)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// Nothing to do since the container doesn't exist anymore.
|
||||
return os.ErrNotExist
|
||||
}
|
||||
continueAdjusting = true
|
||||
klog.V(10).Infof("Error getting process list for cgroup %s: %+v", cgroupName, err)
|
||||
} else if len(pidList) == 0 {
|
||||
klog.V(10).Infof("Pid list is empty")
|
||||
continueAdjusting = true
|
||||
} else {
|
||||
for _, pid := range pidList {
|
||||
if !adjustedProcessSet[pid] {
|
||||
klog.V(10).Infof("pid %d needs to be set", pid)
|
||||
if err = oomAdjuster.ApplyOOMScoreAdj(pid, oomScoreAdj); err == nil {
|
||||
adjustedProcessSet[pid] = true
|
||||
} else if err == os.ErrNotExist {
|
||||
continue
|
||||
} else {
|
||||
klog.V(10).Infof("cannot adjust oom score for pid %d - %v", pid, err)
|
||||
continueAdjusting = true
|
||||
}
|
||||
// Processes can come and go while we try to apply oom score adjust value. So ignore errors here.
|
||||
}
|
||||
}
|
||||
}
|
||||
if !continueAdjusting {
|
||||
return nil
|
||||
}
|
||||
// There's a slight race. A process might have forked just before we write its OOM score adjust.
|
||||
// The fork might copy the parent process's old OOM score, then this function might execute and
|
||||
// update the parent's OOM score, but the forked process id might not be reflected in cgroup.procs
|
||||
// for a short amount of time. So this function might return without changing the forked process's
|
||||
// OOM score. Very unlikely race, so ignoring this for now.
|
||||
}
|
||||
return fmt.Errorf("exceeded maxTries, some processes might not have desired OOM score")
|
||||
}
|
41
vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go
generated
vendored
41
vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go
generated
vendored
@ -1,41 +0,0 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
/*
|
||||
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 oom
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var unsupportedErr = errors.New("setting OOM scores is unsupported in this build")
|
||||
|
||||
func NewOOMAdjuster() *OOMAdjuster {
|
||||
return &OOMAdjuster{
|
||||
ApplyOOMScoreAdj: unsupportedApplyOOMScoreAdj,
|
||||
ApplyOOMScoreAdjContainer: unsupportedApplyOOMScoreAdjContainer,
|
||||
}
|
||||
}
|
||||
|
||||
func unsupportedApplyOOMScoreAdj(pid int, oomScoreAdj int) error {
|
||||
return unsupportedErr
|
||||
}
|
||||
|
||||
func unsupportedApplyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error {
|
||||
return unsupportedErr
|
||||
}
|
54
vendor/k8s.io/kubernetes/pkg/util/parsers/parsers.go
generated
vendored
54
vendor/k8s.io/kubernetes/pkg/util/parsers/parsers.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
/*
|
||||
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 parsers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
// Import the crypto sha256 algorithm for the docker image parser to work
|
||||
_ "crypto/sha256"
|
||||
// Import the crypto/sha512 algorithm for the docker image parser to work with 384 and 512 sha hashes
|
||||
_ "crypto/sha512"
|
||||
|
||||
dockerref "github.com/distribution/reference"
|
||||
)
|
||||
|
||||
// ParseImageName parses a docker image string into three parts: repo, tag and digest.
|
||||
// If both tag and digest are empty, a default image tag will be returned.
|
||||
func ParseImageName(image string) (string, string, string, error) {
|
||||
named, err := dockerref.ParseNormalizedNamed(image)
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("couldn't parse image name %q: %v", image, err)
|
||||
}
|
||||
|
||||
repoToPull := named.Name()
|
||||
var tag, digest string
|
||||
|
||||
tagged, ok := named.(dockerref.Tagged)
|
||||
if ok {
|
||||
tag = tagged.Tag()
|
||||
}
|
||||
|
||||
digested, ok := named.(dockerref.Digested)
|
||||
if ok {
|
||||
digest = digested.Digest().String()
|
||||
}
|
||||
// If no tag was specified, use the default "latest".
|
||||
if len(tag) == 0 && len(digest) == 0 {
|
||||
tag = "latest"
|
||||
}
|
||||
return repoToPull, tag, digest, nil
|
||||
}
|
81
vendor/k8s.io/kubernetes/pkg/util/pod/pod.go
generated
vendored
81
vendor/k8s.io/kubernetes/pkg/util/pod/pod.go
generated
vendored
@ -1,81 +0,0 @@
|
||||
/*
|
||||
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 pod
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
)
|
||||
|
||||
// PatchPodStatus patches pod status. It returns true and avoids an update if the patch contains no changes.
|
||||
func PatchPodStatus(ctx context.Context, c clientset.Interface, namespace, name string, uid types.UID, oldPodStatus, newPodStatus v1.PodStatus) (*v1.Pod, []byte, bool, error) {
|
||||
patchBytes, unchanged, err := preparePatchBytesForPodStatus(namespace, name, uid, oldPodStatus, newPodStatus)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
if unchanged {
|
||||
return nil, patchBytes, true, nil
|
||||
}
|
||||
|
||||
updatedPod, err := c.CoreV1().Pods(namespace).Patch(ctx, name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status")
|
||||
if err != nil {
|
||||
return nil, nil, false, fmt.Errorf("failed to patch status %q for pod %q/%q: %v", patchBytes, namespace, name, err)
|
||||
}
|
||||
return updatedPod, patchBytes, false, nil
|
||||
}
|
||||
|
||||
func preparePatchBytesForPodStatus(namespace, name string, uid types.UID, oldPodStatus, newPodStatus v1.PodStatus) ([]byte, bool, error) {
|
||||
oldData, err := json.Marshal(v1.Pod{
|
||||
Status: oldPodStatus,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("failed to Marshal oldData for pod %q/%q: %v", namespace, name, err)
|
||||
}
|
||||
|
||||
newData, err := json.Marshal(v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{UID: uid}, // only put the uid in the new object to ensure it appears in the patch as a precondition
|
||||
Status: newPodStatus,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("failed to Marshal newData for pod %q/%q: %v", namespace, name, err)
|
||||
}
|
||||
|
||||
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, v1.Pod{})
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("failed to CreateTwoWayMergePatch for pod %q/%q: %v", namespace, name, err)
|
||||
}
|
||||
return patchBytes, bytes.Equal(patchBytes, []byte(fmt.Sprintf(`{"metadata":{"uid":%q}}`, uid))), nil
|
||||
}
|
||||
|
||||
// ReplaceOrAppendPodCondition replaces the first pod condition with equal type or appends if there is none
|
||||
func ReplaceOrAppendPodCondition(conditions []v1.PodCondition, condition *v1.PodCondition) []v1.PodCondition {
|
||||
if i, _ := podutil.GetPodConditionFromList(conditions, condition.Type); i >= 0 {
|
||||
conditions[i] = *condition
|
||||
} else {
|
||||
conditions = append(conditions, *condition)
|
||||
}
|
||||
return conditions
|
||||
}
|
75
vendor/k8s.io/kubernetes/pkg/util/slice/slice.go
generated
vendored
75
vendor/k8s.io/kubernetes/pkg/util/slice/slice.go
generated
vendored
@ -1,75 +0,0 @@
|
||||
/*
|
||||
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 slice provides utility methods for common operations on slices.
|
||||
package slice
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// CopyStrings copies the contents of the specified string slice
|
||||
// into a new slice.
|
||||
func CopyStrings(s []string) []string {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
c := make([]string, len(s))
|
||||
copy(c, s)
|
||||
return c
|
||||
}
|
||||
|
||||
// SortStrings sorts the specified string slice in place. It returns the same
|
||||
// slice that was provided in order to facilitate method chaining.
|
||||
func SortStrings(s []string) []string {
|
||||
sort.Strings(s)
|
||||
return s
|
||||
}
|
||||
|
||||
// ContainsString checks if a given slice of strings contains the provided string.
|
||||
// If a modifier func is provided, it is called with the slice item before the comparation.
|
||||
func ContainsString(slice []string, s string, modifier func(s string) string) bool {
|
||||
for _, item := range slice {
|
||||
if item == s {
|
||||
return true
|
||||
}
|
||||
if modifier != nil && modifier(item) == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveString returns a newly created []string that contains all items from slice that
|
||||
// are not equal to s and modifier(s) in case modifier func is provided.
|
||||
func RemoveString(slice []string, s string, modifier func(s string) string) []string {
|
||||
newSlice := make([]string, 0)
|
||||
for _, item := range slice {
|
||||
if item == s {
|
||||
continue
|
||||
}
|
||||
if modifier != nil && modifier(item) == s {
|
||||
continue
|
||||
}
|
||||
newSlice = append(newSlice, item)
|
||||
}
|
||||
if len(newSlice) == 0 {
|
||||
// Sanitize for unit tests so we don't need to distinguish empty array
|
||||
// and nil.
|
||||
newSlice = nil
|
||||
}
|
||||
return newSlice
|
||||
}
|
289
vendor/k8s.io/kubernetes/pkg/util/taints/taints.go
generated
vendored
289
vendor/k8s.io/kubernetes/pkg/util/taints/taints.go
generated
vendored
@ -1,289 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 taints implements utilities for working with taints
|
||||
package taints
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
)
|
||||
|
||||
const (
|
||||
MODIFIED = "modified"
|
||||
TAINTED = "tainted"
|
||||
UNTAINTED = "untainted"
|
||||
)
|
||||
|
||||
// parseTaint parses a taint from a string, whose form must be either
|
||||
// '<key>=<value>:<effect>', '<key>:<effect>', or '<key>'.
|
||||
func parseTaint(st string) (v1.Taint, error) {
|
||||
var taint v1.Taint
|
||||
|
||||
var key string
|
||||
var value string
|
||||
var effect v1.TaintEffect
|
||||
|
||||
parts := strings.Split(st, ":")
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
key = parts[0]
|
||||
case 2:
|
||||
effect = v1.TaintEffect(parts[1])
|
||||
if err := validateTaintEffect(effect); err != nil {
|
||||
return taint, err
|
||||
}
|
||||
|
||||
partsKV := strings.Split(parts[0], "=")
|
||||
if len(partsKV) > 2 {
|
||||
return taint, fmt.Errorf("invalid taint spec: %v", st)
|
||||
}
|
||||
key = partsKV[0]
|
||||
if len(partsKV) == 2 {
|
||||
value = partsKV[1]
|
||||
if errs := validation.IsValidLabelValue(value); len(errs) > 0 {
|
||||
return taint, fmt.Errorf("invalid taint spec: %v, %s", st, strings.Join(errs, "; "))
|
||||
}
|
||||
}
|
||||
default:
|
||||
return taint, fmt.Errorf("invalid taint spec: %v", st)
|
||||
}
|
||||
|
||||
if errs := validation.IsQualifiedName(key); len(errs) > 0 {
|
||||
return taint, fmt.Errorf("invalid taint spec: %v, %s", st, strings.Join(errs, "; "))
|
||||
}
|
||||
|
||||
taint.Key = key
|
||||
taint.Value = value
|
||||
taint.Effect = effect
|
||||
|
||||
return taint, nil
|
||||
}
|
||||
|
||||
func validateTaintEffect(effect v1.TaintEffect) error {
|
||||
if effect != v1.TaintEffectNoSchedule && effect != v1.TaintEffectPreferNoSchedule && effect != v1.TaintEffectNoExecute {
|
||||
return fmt.Errorf("invalid taint effect: %v, unsupported taint effect", effect)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseTaints takes a spec which is an array and creates slices for new taints to be added, taints to be deleted.
|
||||
// It also validates the spec. For example, the form `<key>` may be used to remove a taint, but not to add one.
|
||||
func ParseTaints(spec []string) ([]v1.Taint, []v1.Taint, error) {
|
||||
var taints, taintsToRemove []v1.Taint
|
||||
uniqueTaints := map[v1.TaintEffect]sets.String{}
|
||||
|
||||
for _, taintSpec := range spec {
|
||||
if strings.HasSuffix(taintSpec, "-") {
|
||||
taintToRemove, err := parseTaint(strings.TrimSuffix(taintSpec, "-"))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
taintsToRemove = append(taintsToRemove, v1.Taint{Key: taintToRemove.Key, Effect: taintToRemove.Effect})
|
||||
} else {
|
||||
newTaint, err := parseTaint(taintSpec)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// validate that the taint has an effect, which is required to add the taint
|
||||
if len(newTaint.Effect) == 0 {
|
||||
return nil, nil, fmt.Errorf("invalid taint spec: %v", taintSpec)
|
||||
}
|
||||
// validate if taint is unique by <key, effect>
|
||||
if len(uniqueTaints[newTaint.Effect]) > 0 && uniqueTaints[newTaint.Effect].Has(newTaint.Key) {
|
||||
return nil, nil, fmt.Errorf("duplicated taints with the same key and effect: %v", newTaint)
|
||||
}
|
||||
// add taint to existingTaints for uniqueness check
|
||||
if len(uniqueTaints[newTaint.Effect]) == 0 {
|
||||
uniqueTaints[newTaint.Effect] = sets.String{}
|
||||
}
|
||||
uniqueTaints[newTaint.Effect].Insert(newTaint.Key)
|
||||
|
||||
taints = append(taints, newTaint)
|
||||
}
|
||||
}
|
||||
return taints, taintsToRemove, nil
|
||||
}
|
||||
|
||||
// CheckIfTaintsAlreadyExists checks if the node already has taints that we want to add and returns a string with taint keys.
|
||||
func CheckIfTaintsAlreadyExists(oldTaints []v1.Taint, taints []v1.Taint) string {
|
||||
var existingTaintList = make([]string, 0)
|
||||
for _, taint := range taints {
|
||||
for _, oldTaint := range oldTaints {
|
||||
if taint.Key == oldTaint.Key && taint.Effect == oldTaint.Effect {
|
||||
existingTaintList = append(existingTaintList, taint.Key)
|
||||
}
|
||||
}
|
||||
}
|
||||
return strings.Join(existingTaintList, ",")
|
||||
}
|
||||
|
||||
// DeleteTaintsByKey removes all the taints that have the same key to given taintKey
|
||||
func DeleteTaintsByKey(taints []v1.Taint, taintKey string) ([]v1.Taint, bool) {
|
||||
newTaints := []v1.Taint{}
|
||||
deleted := false
|
||||
for i := range taints {
|
||||
if taintKey == taints[i].Key {
|
||||
deleted = true
|
||||
continue
|
||||
}
|
||||
newTaints = append(newTaints, taints[i])
|
||||
}
|
||||
return newTaints, deleted
|
||||
}
|
||||
|
||||
// DeleteTaint removes all the taints that have the same key and effect to given taintToDelete.
|
||||
func DeleteTaint(taints []v1.Taint, taintToDelete *v1.Taint) ([]v1.Taint, bool) {
|
||||
newTaints := []v1.Taint{}
|
||||
deleted := false
|
||||
for i := range taints {
|
||||
if taintToDelete.MatchTaint(&taints[i]) {
|
||||
deleted = true
|
||||
continue
|
||||
}
|
||||
newTaints = append(newTaints, taints[i])
|
||||
}
|
||||
return newTaints, deleted
|
||||
}
|
||||
|
||||
// RemoveTaint tries to remove a taint from annotations list. Returns a new copy of updated Node and true if something was updated
|
||||
// false otherwise.
|
||||
func RemoveTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
|
||||
newNode := node.DeepCopy()
|
||||
nodeTaints := newNode.Spec.Taints
|
||||
if len(nodeTaints) == 0 {
|
||||
return newNode, false, nil
|
||||
}
|
||||
|
||||
if !TaintExists(nodeTaints, taint) {
|
||||
return newNode, false, nil
|
||||
}
|
||||
|
||||
newTaints, _ := DeleteTaint(nodeTaints, taint)
|
||||
newNode.Spec.Taints = newTaints
|
||||
return newNode, true, nil
|
||||
}
|
||||
|
||||
// AddOrUpdateTaint tries to add a taint to annotations list. Returns a new copy of updated Node and true if something was updated
|
||||
// false otherwise.
|
||||
func AddOrUpdateTaint(node *v1.Node, taint *v1.Taint) (*v1.Node, bool, error) {
|
||||
newNode := node.DeepCopy()
|
||||
nodeTaints := newNode.Spec.Taints
|
||||
|
||||
var newTaints []v1.Taint
|
||||
updated := false
|
||||
for i := range nodeTaints {
|
||||
if taint.MatchTaint(&nodeTaints[i]) {
|
||||
if helper.Semantic.DeepEqual(*taint, nodeTaints[i]) {
|
||||
return newNode, false, nil
|
||||
}
|
||||
newTaints = append(newTaints, *taint)
|
||||
updated = true
|
||||
continue
|
||||
}
|
||||
|
||||
newTaints = append(newTaints, nodeTaints[i])
|
||||
}
|
||||
|
||||
if !updated {
|
||||
newTaints = append(newTaints, *taint)
|
||||
}
|
||||
|
||||
newNode.Spec.Taints = newTaints
|
||||
return newNode, true, nil
|
||||
}
|
||||
|
||||
// TaintExists checks if the given taint exists in list of taints. Returns true if exists false otherwise.
|
||||
func TaintExists(taints []v1.Taint, taintToFind *v1.Taint) bool {
|
||||
for _, taint := range taints {
|
||||
if taint.MatchTaint(taintToFind) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// TaintKeyExists checks if the given taint key exists in list of taints. Returns true if exists false otherwise.
|
||||
func TaintKeyExists(taints []v1.Taint, taintKeyToMatch string) bool {
|
||||
for _, taint := range taints {
|
||||
if taint.Key == taintKeyToMatch {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// TaintSetDiff finds the difference between two taint slices and
|
||||
// returns all new and removed elements of the new slice relative to the old slice.
|
||||
// for example:
|
||||
// input: taintsNew=[a b] taintsOld=[a c]
|
||||
// output: taintsToAdd=[b] taintsToRemove=[c]
|
||||
func TaintSetDiff(taintsNew, taintsOld []v1.Taint) (taintsToAdd []*v1.Taint, taintsToRemove []*v1.Taint) {
|
||||
for _, taint := range taintsNew {
|
||||
if !TaintExists(taintsOld, &taint) {
|
||||
t := taint
|
||||
taintsToAdd = append(taintsToAdd, &t)
|
||||
}
|
||||
}
|
||||
|
||||
for _, taint := range taintsOld {
|
||||
if !TaintExists(taintsNew, &taint) {
|
||||
t := taint
|
||||
taintsToRemove = append(taintsToRemove, &t)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// TaintSetFilter filters from the taint slice according to the passed fn function to get the filtered taint slice.
|
||||
func TaintSetFilter(taints []v1.Taint, fn func(*v1.Taint) bool) []v1.Taint {
|
||||
res := []v1.Taint{}
|
||||
|
||||
for _, taint := range taints {
|
||||
if fn(&taint) {
|
||||
res = append(res, taint)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// CheckTaintValidation checks if the given taint is valid.
|
||||
// Returns error if the given taint is invalid.
|
||||
func CheckTaintValidation(taint v1.Taint) error {
|
||||
if errs := validation.IsQualifiedName(taint.Key); len(errs) > 0 {
|
||||
return fmt.Errorf("invalid taint key: %s", strings.Join(errs, "; "))
|
||||
}
|
||||
if taint.Value != "" {
|
||||
if errs := validation.IsValidLabelValue(taint.Value); len(errs) > 0 {
|
||||
return fmt.Errorf("invalid taint value: %s", strings.Join(errs, "; "))
|
||||
}
|
||||
}
|
||||
if taint.Effect != "" {
|
||||
if err := validateTaintEffect(taint.Effect); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user