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:
Praveen M
2025-01-16 09:41:46 +05:30
committed by mergify[bot]
parent 5aef21ea4e
commit 7eb99fc6c9
2442 changed files with 273386 additions and 47788 deletions

View File

@ -17,12 +17,12 @@ limitations under the License.
package volume
import (
"errors"
"fmt"
"net"
"strings"
"sync"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
"k8s.io/mount-utils"
"k8s.io/utils/exec"
@ -62,6 +62,8 @@ const (
ProbeRemove
)
var ErrNoPluiginMatched = errors.New("no volume plugin matched")
// VolumeOptions contains option information about a volume.
type VolumeOptions struct {
// The attributes below are required by volume.Provisioner
@ -306,15 +308,18 @@ type KubeletVolumeHost interface {
GetTrustAnchorsBySigner(signerName string, labelSelector *metav1.LabelSelector, allowMissing bool) ([]byte, error)
}
// CSIDriverVolumeHost is a volume host that has access to CSIDriverLister
type CSIDriverVolumeHost interface {
// CSIDriverLister returns the informer lister for the CSIDriver API Object
CSIDriverLister() storagelistersv1.CSIDriverLister
}
// AttachDetachVolumeHost is a AttachDetach Controller specific interface that plugins can use
// to access methods on the Attach Detach Controller.
type AttachDetachVolumeHost interface {
CSIDriverVolumeHost
// CSINodeLister returns the informer lister for the CSINode API Object
CSINodeLister() storagelistersv1.CSINodeLister
// CSIDriverLister returns the informer lister for the CSIDriver API Object
CSIDriverLister() storagelistersv1.CSIDriverLister
// VolumeAttachmentLister returns the informer lister for the VolumeAttachment API Object
VolumeAttachmentLister() storagelistersv1.VolumeAttachmentLister
// IsAttachDetachController is an interface marker to strictly tie AttachDetachVolumeHost
@ -414,12 +419,11 @@ type VolumeHost interface {
// VolumePluginMgr tracks registered plugins.
type VolumePluginMgr struct {
mutex sync.RWMutex
plugins map[string]VolumePlugin
prober DynamicPluginProber
probedPlugins map[string]VolumePlugin
loggedDeprecationWarnings sets.Set[string]
Host VolumeHost
mutex sync.RWMutex
plugins map[string]VolumePlugin
prober DynamicPluginProber
probedPlugins map[string]VolumePlugin
Host VolumeHost
}
// Spec is an internal representation of a volume. All API volume types translate to Spec.
@ -560,7 +564,6 @@ func (pm *VolumePluginMgr) InitPlugins(plugins []VolumePlugin, prober DynamicPlu
defer pm.mutex.Unlock()
pm.Host = host
pm.loggedDeprecationWarnings = sets.New[string]()
if prober == nil {
// Use a dummy prober to prevent nil deference.
@ -602,6 +605,7 @@ func (pm *VolumePluginMgr) InitPlugins(plugins []VolumePlugin, prober DynamicPlu
pm.plugins[name] = plugin
klog.V(1).InfoS("Loaded volume plugin", "pluginName", name)
}
pm.refreshProbedPlugins()
return utilerrors.NewAggregate(allErrs)
}
@ -649,7 +653,7 @@ func (pm *VolumePluginMgr) FindPluginBySpec(spec *Spec) (VolumePlugin, error) {
}
if len(matchedPluginNames) == 0 {
return nil, fmt.Errorf("no volume plugin matched")
return nil, ErrNoPluiginMatched
}
if len(matchedPluginNames) > 1 {
return nil, fmt.Errorf("multiple volume plugins matched: %s", strings.Join(matchedPluginNames, ","))
@ -863,6 +867,9 @@ func (pm *VolumePluginMgr) FindExpandablePluginBySpec(spec *Spec) (ExpandableVol
klog.V(4).InfoS("FindExpandablePluginBySpec -> returning noopExpandableVolumePluginInstance", "specName", spec.Name())
return &noopExpandableVolumePluginInstance{spec}, nil
}
if errors.Is(err, ErrNoPluiginMatched) {
return nil, nil
}
klog.V(4).InfoS("FindExpandablePluginBySpec -> err", "specName", spec.Name(), "err", err)
return nil, err
}
@ -984,7 +991,7 @@ func NewPersistentVolumeRecyclerPodTemplate() *v1.Pod {
Containers: []v1.Container{
{
Name: "pv-recycler",
Image: "registry.k8s.io/build-image/debian-base:bookworm-v1.0.3",
Image: "registry.k8s.io/build-image/debian-base:bookworm-v1.0.4",
Command: []string{"/bin/sh"},
Args: []string{"-c", "test -e /scrub && find /scrub -mindepth 1 -delete && test -z \"$(ls -A /scrub)\" || exit 1"},
VolumeMounts: []v1.VolumeMount{

View File

@ -31,8 +31,13 @@ import (
"k8s.io/klog/v2"
)
// FindMultipathDeviceForDevice given a device name like /dev/sdx, find the devicemapper parent
// FindMultipathDeviceForDevice given a device name like /dev/sdx, find the devicemapper parent. If called with a device
// already resolved to devicemapper, do nothing.
func (handler *deviceHandler) FindMultipathDeviceForDevice(device string) string {
if strings.HasPrefix(device, "/dev/dm-") {
return device
}
io := handler.getIo
disk, err := findDeviceForPath(device, io)
if err != nil {

View File

@ -22,4 +22,7 @@ const (
// PVProtectionFinalizer is the name of finalizer on PVs that are bound by PVCs
PVProtectionFinalizer = "kubernetes.io/pv-protection"
// VACProtectionFinalizer is the name of finalizer on VACs that are used by PVs or PVCs
VACProtectionFinalizer = "kubernetes.io/vac-protection"
)

View File

@ -18,11 +18,12 @@ package recyclerclient
import (
"context"
"errors"
"fmt"
"sync"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/watch"
@ -72,7 +73,7 @@ func internalRecycleVolumeByWatchingPodUntilCompletion(pvName string, pod *v1.Po
// Start the pod
_, err = recyclerClient.CreatePod(pod)
if err != nil {
if errors.IsAlreadyExists(err) {
if apierrors.IsAlreadyExists(err) {
deleteErr := recyclerClient.DeletePod(pod.Name, pod.Namespace)
if deleteErr != nil {
return fmt.Errorf("failed to delete old recycler pod %s/%s: %s", pod.Namespace, pod.Name, deleteErr)
@ -89,7 +90,7 @@ func internalRecycleVolumeByWatchingPodUntilCompletion(pvName string, pod *v1.Po
klog.V(2).Infof("deleting recycler pod %s/%s", pod.Namespace, pod.Name)
deleteErr := recyclerClient.DeletePod(pod.Name, pod.Namespace)
if deleteErr != nil {
klog.Errorf("failed to delete recycler pod %s/%s: %v", pod.Namespace, pod.Name, err)
klog.Errorf("failed to delete recycler pod %s/%s: %v", pod.Namespace, pod.Name, deleteErr)
}
// Returning recycler error is preferred, the pod will be deleted again on
@ -128,7 +129,7 @@ func waitForPod(pod *v1.Pod, recyclerClient recyclerClient, podCh <-chan watch.E
}
if pod.Status.Phase == v1.PodFailed {
if pod.Status.Message != "" {
return fmt.Errorf(pod.Status.Message)
return errors.New(pod.Status.Message)
}
return fmt.Errorf("pod failed, pod.Status.Message unknown")
}

View File

@ -17,11 +17,14 @@ limitations under the License.
package util
import (
"errors"
"fmt"
"strings"
"github.com/opencontainers/selinux/go-selinux"
"github.com/opencontainers/selinux/go-selinux/label"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets"
utilfeature "k8s.io/apiserver/pkg/util/feature"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features"
@ -71,7 +74,7 @@ func (l *translator) SELinuxOptionsToFileLabel(opts *v1.SELinuxOptions) (string,
if err != nil {
// In theory, this should be unreachable. InitLabels can fail only when args contain an unknown option,
// and all options returned by contextOptions are known.
return "", err
return "", &SELinuxLabelTranslationError{msg: err.Error()}
}
// InitLabels() may allocate a new unique SELinux label in kubelet memory. The label is *not* allocated
// in the container runtime. Clear it to avoid memory problems.
@ -156,6 +159,19 @@ func (l *fakeTranslator) SELinuxEnabled() bool {
return true
}
type SELinuxLabelTranslationError struct {
msg string
}
func (e *SELinuxLabelTranslationError) Error() string {
return e.msg
}
func IsSELinuxLabelTranslationError(err error) bool {
var seLinuxError *SELinuxLabelTranslationError
return errors.As(err, &seLinuxError)
}
// SupportsSELinuxContextMount checks if the given volumeSpec supports with mount -o context
func SupportsSELinuxContextMount(volumeSpec *volume.Spec, volumePluginMgr *volume.VolumePluginMgr) (bool, error) {
plugin, _ := volumePluginMgr.FindPluginBySpec(volumeSpec)
@ -174,19 +190,41 @@ func VolumeSupportsSELinuxMount(volumeSpec *volume.Spec) bool {
if volumeSpec.PersistentVolume == nil {
return false
}
if len(volumeSpec.PersistentVolume.Spec.AccessModes) != 1 {
return false
}
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMount) {
return true
}
// Only SELinuxMountReadWriteOncePod feature enabled
if !v1helper.ContainsAccessMode(volumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) {
// Only SELinuxMountReadWriteOncePod feature is enabled
if len(volumeSpec.PersistentVolume.Spec.AccessModes) != 1 {
// RWOP volumes must be the only access mode of the volume
return false
}
if !v1helper.ContainsAccessMode(volumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) {
// Not a RWOP volume
return false
}
// RWOP volume
return true
}
// MultipleSELinuxLabelsError tells that one volume in a pod is mounted in multiple containers and each has a different SELinux label.
type MultipleSELinuxLabelsError struct {
labels []string
}
func (e *MultipleSELinuxLabelsError) Error() string {
return fmt.Sprintf("multiple SELinux labels found: %s", strings.Join(e.labels, ","))
}
func (e *MultipleSELinuxLabelsError) Labels() []string {
return e.labels
}
func IsMultipleSELinuxLabelsError(err error) bool {
var multiError *MultipleSELinuxLabelsError
return errors.As(err, &multiError)
}
// AddSELinuxMountOption adds -o context="XYZ" mount option to a given list
func AddSELinuxMountOption(options []string, seLinuxContext string) []string {
if !utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
@ -196,3 +234,80 @@ func AddSELinuxMountOption(options []string, seLinuxContext string) []string {
// For example: dirsync,context="system_u:object_r:container_file_t:s0:c15,c25",noatime
return append(options, fmt.Sprintf("context=%q", seLinuxContext))
}
// SELinuxLabelInfo contains information about SELinux labels that should be used to mount a volume for a Pod.
type SELinuxLabelInfo struct {
// SELinuxMountLabel is the SELinux label that should be used to mount the volume.
// The volume plugin supports SELinuxMount and the Pod did not opt out via SELinuxChangePolicy.
// Empty string otherwise.
SELinuxMountLabel string
// SELinuxProcessLabel is the SELinux label that will the container runtime use for the Pod.
// Regardless if the volume plugin supports SELinuxMount or the Pod opted out via SELinuxChangePolicy.
SELinuxProcessLabel string
// PluginSupportsSELinuxContextMount is true if the volume plugin supports SELinux mount.
PluginSupportsSELinuxContextMount bool
}
// GetMountSELinuxLabel returns SELinux labels that should be used to mount the given volume volumeSpec and podSecurityContext.
// It expects effectiveSELinuxContainerLabels as returned by volumeutil.GetPodVolumeNames, i.e. with all SELinuxOptions
// from all containers that use the volume in the pod, potentially expanded with PodSecurityContext.SELinuxOptions,
// if container's SELinuxOptions are nil.
// It does not evaluate the volume access mode! It's up to the caller to check SELinuxMount feature gate,
// it may need to bump different metrics based on feature gates / access modes / label anyway.
func GetMountSELinuxLabel(volumeSpec *volume.Spec, effectiveSELinuxContainerLabels []*v1.SELinuxOptions, podSecurityContext *v1.PodSecurityContext, volumePluginMgr *volume.VolumePluginMgr, seLinuxTranslator SELinuxLabelTranslator) (SELinuxLabelInfo, error) {
info := SELinuxLabelInfo{}
if !utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
return info, nil
}
if !seLinuxTranslator.SELinuxEnabled() {
return info, nil
}
pluginSupportsSELinuxContextMount, err := SupportsSELinuxContextMount(volumeSpec, volumePluginMgr)
if err != nil {
return info, err
}
info.PluginSupportsSELinuxContextMount = pluginSupportsSELinuxContextMount
// Collect all SELinux options from all containers that use this volume.
// A set will squash any duplicities.
labels := sets.New[string]()
for _, containerLabel := range effectiveSELinuxContainerLabels {
lbl, err := seLinuxTranslator.SELinuxOptionsToFileLabel(containerLabel)
if err != nil {
fullErr := fmt.Errorf("failed to construct SELinux label from context %q: %w", containerLabel, err)
return info, fullErr
}
labels.Insert(lbl)
}
// Ensure that all containers use the same SELinux label.
if labels.Len() > 1 {
// This volume is used with more than one SELinux label in the pod.
return info, &MultipleSELinuxLabelsError{labels: labels.UnsortedList()}
}
if labels.Len() == 0 {
return info, nil
}
lbl, _ := labels.PopAny()
info.SELinuxProcessLabel = lbl
info.SELinuxMountLabel = lbl
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxChangePolicy) &&
podSecurityContext != nil &&
podSecurityContext.SELinuxChangePolicy != nil &&
*podSecurityContext.SELinuxChangePolicy == v1.SELinuxChangePolicyRecursive {
// The pod has opted into recursive SELinux label changes. Do not mount with -o context.
info.SELinuxMountLabel = ""
}
if !pluginSupportsSELinuxContextMount {
// The volume plugin does not support SELinux mount. Do not mount with -o context.
info.SELinuxMountLabel = ""
}
return info, nil
}

View File

@ -32,12 +32,10 @@ import (
utypes "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/api/legacyscheme"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/securitycontext"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/types"
@ -512,19 +510,18 @@ func IsLocalEphemeralVolume(volume v1.Volume) bool {
}
// GetPodVolumeNames returns names of volumes that are used in a pod,
// either as filesystem mount or raw block device, together with list
// of all SELinux contexts of all containers that use the volumes.
func GetPodVolumeNames(pod *v1.Pod) (mounts sets.Set[string], devices sets.Set[string], seLinuxContainerContexts map[string][]*v1.SELinuxOptions) {
// either as filesystem mount or raw block device.
// To save another sweep through containers, SELinux options are optionally collected too.
func GetPodVolumeNames(pod *v1.Pod, collectSELinuxOptions bool) (mounts sets.Set[string], devices sets.Set[string], seLinuxContainerContexts map[string][]*v1.SELinuxOptions) {
mounts = sets.New[string]()
devices = sets.New[string]()
seLinuxContainerContexts = make(map[string][]*v1.SELinuxOptions)
podutil.VisitContainers(&pod.Spec, podutil.AllFeatureEnabledContainers(), func(container *v1.Container, containerType podutil.ContainerType) bool {
var seLinuxOptions *v1.SELinuxOptions
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
if collectSELinuxOptions {
effectiveContainerSecurity := securitycontext.DetermineEffectiveSecurityContext(pod, container)
if effectiveContainerSecurity != nil {
// No DeepCopy, SELinuxOptions is already a copy of Pod's or container's SELinuxOptions
seLinuxOptions = effectiveContainerSecurity.SELinuxOptions
}
}
@ -532,7 +529,7 @@ func GetPodVolumeNames(pod *v1.Pod) (mounts sets.Set[string], devices sets.Set[s
if container.VolumeMounts != nil {
for _, mount := range container.VolumeMounts {
mounts.Insert(mount.Name)
if seLinuxOptions != nil {
if seLinuxOptions != nil && collectSELinuxOptions {
seLinuxContainerContexts[mount.Name] = append(seLinuxContainerContexts[mount.Name], seLinuxOptions.DeepCopy())
}
}

View File

@ -1,72 +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 util
import (
"sort"
storagev1beta1 "k8s.io/api/storage/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
storagev1beta1listers "k8s.io/client-go/listers/storage/v1beta1"
"k8s.io/klog/v2"
)
const (
// AlphaIsDefaultVolumeAttributesClassAnnotation is the alpha version of IsDefaultVolumeAttributesClassAnnotation.
AlphaIsDefaultVolumeAttributesClassAnnotation = "volumeattributesclass.alpha.kubernetes.io/is-default-class"
)
// GetDefaultVolumeAttributesClass returns the default VolumeAttributesClass from the store, or nil.
func GetDefaultVolumeAttributesClass(lister storagev1beta1listers.VolumeAttributesClassLister, driverName string) (*storagev1beta1.VolumeAttributesClass, error) {
list, err := lister.List(labels.Everything())
if err != nil {
return nil, err
}
defaultClasses := []*storagev1beta1.VolumeAttributesClass{}
for _, class := range list {
if IsDefaultVolumeAttributesClassAnnotation(class.ObjectMeta) && class.DriverName == driverName {
defaultClasses = append(defaultClasses, class)
klog.V(4).Infof("GetDefaultVolumeAttributesClass added: %s", class.Name)
}
}
if len(defaultClasses) == 0 {
return nil, nil
}
// Primary sort by creation timestamp, newest first
// Secondary sort by class name, ascending order
sort.Slice(defaultClasses, func(i, j int) bool {
if defaultClasses[i].CreationTimestamp.UnixNano() == defaultClasses[j].CreationTimestamp.UnixNano() {
return defaultClasses[i].Name < defaultClasses[j].Name
}
return defaultClasses[i].CreationTimestamp.UnixNano() > defaultClasses[j].CreationTimestamp.UnixNano()
})
if len(defaultClasses) > 1 {
klog.V(4).Infof("%d default VolumeAttributesClass were found, choosing: %s", len(defaultClasses), defaultClasses[0].Name)
}
return defaultClasses[0], nil
}
// IsDefaultVolumeAttributesClassAnnotation returns a boolean if the default
// volume attributes class annotation is set
func IsDefaultVolumeAttributesClassAnnotation(obj metav1.ObjectMeta) bool {
return obj.Annotations[AlphaIsDefaultVolumeAttributesClassAnnotation] == "true"
}