mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
rebase: bump k8s.io/kubernetes in the k8s-dependencies group
Bumps the k8s-dependencies group with 1 update: [k8s.io/kubernetes](https://github.com/kubernetes/kubernetes). Updates `k8s.io/kubernetes` from 1.32.3 to 1.33.0 - [Release notes](https://github.com/kubernetes/kubernetes/releases) - [Commits](https://github.com/kubernetes/kubernetes/compare/v1.32.3...v1.33.0) --- updated-dependencies: - dependency-name: k8s.io/kubernetes dependency-version: 1.33.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: k8s-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Niels de Vos <ndevos@ibm.com>
This commit is contained in:
committed by
mergify[bot]
parent
4147d5d15a
commit
51895f8619
2
vendor/k8s.io/kubernetes/pkg/features/client_adapter.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/features/client_adapter.go
generated
vendored
@ -65,7 +65,7 @@ func (a *clientAdapter) Add(in map[clientfeatures.Feature]clientfeatures.Feature
|
||||
}
|
||||
out[featuregate.Feature(name)] = converted
|
||||
}
|
||||
return a.mfg.Add(out)
|
||||
return a.mfg.Add(out) //nolint:forbidigo // No need to support versioned feature gates in client adapter
|
||||
}
|
||||
|
||||
// Set implements the unexported interface that client-go feature gate testing expects for
|
||||
|
1170
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
1170
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
File diff suppressed because it is too large
Load Diff
841
vendor/k8s.io/kubernetes/pkg/features/versioned_kube_features.go
generated
vendored
841
vendor/k8s.io/kubernetes/pkg/features/versioned_kube_features.go
generated
vendored
@ -1,841 +0,0 @@
|
||||
/*
|
||||
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 features
|
||||
|
||||
import (
|
||||
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
|
||||
"k8s.io/apimachinery/pkg/util/version"
|
||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/component-base/featuregate"
|
||||
zpagesfeatures "k8s.io/component-base/zpages/features"
|
||||
kcmfeatures "k8s.io/controller-manager/pkg/features"
|
||||
)
|
||||
|
||||
// defaultVersionedKubernetesFeatureGates consists of all known Kubernetes-specific feature keys with VersionedSpecs.
|
||||
// To add a new feature, define a key for it in pkg/features/kube_features.go and add it here. The features will be
|
||||
// available throughout Kubernetes binaries.
|
||||
// For features available via specific kubernetes components like apiserver,
|
||||
// cloud-controller-manager, etc find the respective kube_features.go file
|
||||
// (eg:staging/src/apiserver/pkg/features/kube_features.go), define the versioned
|
||||
// feature gate there, and reference it in this file.
|
||||
// To support n-3 compatibility version, features may only be removed 3 releases after graduation.
|
||||
//
|
||||
// Entries are alphabetized.
|
||||
var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate.VersionedSpecs{
|
||||
AllowDNSOnlyNodeCSR: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Deprecated},
|
||||
},
|
||||
|
||||
AllowInsecureKubeletCertificateSigningRequests: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Deprecated},
|
||||
},
|
||||
|
||||
AllowOverwriteTerminationGracePeriodSeconds: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Deprecated},
|
||||
},
|
||||
|
||||
AllowServiceLBStatusOnNonLB: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Deprecated},
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Deprecated, LockToDefault: true}, // remove in 1.35
|
||||
},
|
||||
|
||||
AnyVolumeDataSource: {
|
||||
{Version: version.MustParse("1.18"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.24"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
AppArmor: {
|
||||
{Version: version.MustParse("1.4"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
},
|
||||
|
||||
AppArmorFields: {
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
},
|
||||
|
||||
AuthorizeNodeWithSelectors: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
kcmfeatures.CloudControllerManagerWebhook: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
ClusterTrustBundle: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
ClusterTrustBundleProjection: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
ContainerCheckpoint: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
CPUCFSQuotaPeriod: {
|
||||
{Version: version.MustParse("1.12"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
CPUManager: {
|
||||
{Version: version.MustParse("1.8"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.10"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.26"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.26
|
||||
},
|
||||
|
||||
CPUManagerPolicyAlphaOptions: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
CPUManagerPolicyBetaOptions: {
|
||||
{Version: version.MustParse("1.23"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
CPUManagerPolicyOptions: {
|
||||
{Version: version.MustParse("1.22"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.23"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
CronJobsScheduledAnnotation: {
|
||||
{Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.35
|
||||
},
|
||||
|
||||
// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
apiextensionsfeatures.CRDValidationRatcheting: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
CrossNamespaceVolumeDataSource: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
CSIMigrationPortworx: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta}, // On by default (requires Portworx CSI driver)
|
||||
},
|
||||
|
||||
CSIVolumeHealth: {
|
||||
{Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
apiextensionsfeatures.CustomResourceFieldSelectors: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, LockToDefault: true, PreRelease: featuregate.GA},
|
||||
},
|
||||
|
||||
DevicePluginCDIDevices: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
},
|
||||
|
||||
DisableAllocatorDualWrite: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha}, // remove after MultiCIDRServiceAllocator is GA
|
||||
},
|
||||
|
||||
DisableCloudProviders: {
|
||||
{Version: version.MustParse("1.22"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
DisableKubeletCloudCredentialProviders: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
DisableNodeKubeProxyVersion: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Deprecated},
|
||||
},
|
||||
|
||||
DRAAdminAccess: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
DynamicResourceAllocation: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
DRAResourceClaimDeviceStatus: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
KubeletCrashLoopBackOffMax: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
ElasticIndexedJob: {
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.31, remove in 1.32
|
||||
},
|
||||
|
||||
EventedPLEG: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
ExecProbeTimeout: {
|
||||
{Version: version.MustParse("1.20"), Default: true, PreRelease: featuregate.GA}, // lock to default and remove after v1.22 based on KEP #1972 update
|
||||
},
|
||||
|
||||
ExternalServiceAccountTokenSigner: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
genericfeatures.AdmissionWebhookMatchConditions: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.AggregatedDiscoveryEndpoint: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.AllowUnsafeMalformedObjectDeletion: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
genericfeatures.AnonymousAuthConfigurableEndpoints: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.APIListChunking: {
|
||||
{Version: version.MustParse("1.8"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.9"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.APIResponseCompression: {
|
||||
{Version: version.MustParse("1.8"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.16"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.APIServerIdentity: {
|
||||
{Version: version.MustParse("1.20"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.26"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.APIServerTracing: {
|
||||
{Version: version.MustParse("1.22"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.APIServingWithRoutine: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
genericfeatures.AuthorizeWithSelectors: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.BtreeWatchCache: {
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.CBORServingAndStorage: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
genericfeatures.ConcurrentWatchObjectDecode: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.ConsistentListFromCache: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.CoordinatedLeaderElection: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
genericfeatures.EfficientWatchResumption: {
|
||||
{Version: version.MustParse("1.20"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.21"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.24"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.KMSv1: {
|
||||
{Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Deprecated},
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Deprecated},
|
||||
},
|
||||
|
||||
genericfeatures.MutatingAdmissionPolicy: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
genericfeatures.OpenAPIEnums: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.24"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.RemainingItemCount: {
|
||||
{Version: version.MustParse("1.15"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.16"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.RemoteRequestHeaderUID: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
genericfeatures.ResilientWatchCacheInitialization: {
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.RetryGenerateName: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, LockToDefault: true, PreRelease: featuregate.GA},
|
||||
},
|
||||
|
||||
genericfeatures.SeparateCacheWatchRPC: {
|
||||
{Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.StorageVersionAPI: {
|
||||
{Version: version.MustParse("1.20"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
genericfeatures.StorageVersionHash: {
|
||||
{Version: version.MustParse("1.14"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.15"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.StrictCostEnforcementForVAP: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.StrictCostEnforcementForWebhooks: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.StructuredAuthenticationConfiguration: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.StructuredAuthorizationConfiguration: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.UnauthenticatedHTTP2DOSMitigation: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.WatchBookmark: {
|
||||
{Version: version.MustParse("1.15"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.16"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.17"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
genericfeatures.WatchCacheInitializationPostStartHook: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.WatchFromStorageWithoutResourceVersion: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
genericfeatures.WatchList: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
GracefulNodeShutdown: {
|
||||
{Version: version.MustParse("1.20"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.21"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
GracefulNodeShutdownBasedOnPodPriority: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.24"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
HonorPVReclaimPolicy: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
HPAScaleToZero: {
|
||||
{Version: version.MustParse("1.16"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
ImageMaximumGCAge: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ImageVolume: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
InPlacePodVerticalScaling: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
InPlacePodVerticalScalingAllocatedStatus: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
InPlacePodVerticalScalingExclusiveCPUs: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
InTreePluginPortworxUnregister: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
JobBackoffLimitPerIndex: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
JobManagedBy: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
JobPodFailurePolicy: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.26"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
},
|
||||
|
||||
JobPodReplacementPolicy: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
JobSuccessPolicy: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
KubeletCgroupDriverFromCRI: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
KubeletFineGrainedAuthz: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
KubeletInUserNamespace: {
|
||||
{Version: version.MustParse("1.22"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
KubeletPodResourcesDynamicResources: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
KubeletPodResourcesGet: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
KubeletRegistrationGetOnExistsOnly: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Deprecated},
|
||||
},
|
||||
|
||||
KubeletSeparateDiskGC: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
KubeletTracing: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
KubeProxyDrainingTerminatingNodes: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.31; remove in 1.33
|
||||
},
|
||||
|
||||
LoadBalancerIPMode: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
LocalStorageCapacityIsolationFSQuotaMonitoring: {
|
||||
{Version: version.MustParse("1.15"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
LogarithmicScaleDown: {
|
||||
{Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
MatchLabelKeysInPodAffinity: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
MatchLabelKeysInPodTopologySpread: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
MaxUnavailableStatefulSet: {
|
||||
{Version: version.MustParse("1.24"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
MemoryManager: {
|
||||
{Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
},
|
||||
|
||||
MemoryQoS: {
|
||||
{Version: version.MustParse("1.22"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
MultiCIDRServiceAllocator: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
NFTablesProxyMode: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
NodeInclusionPolicyInPodTopologySpread: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.26"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
NodeLogQuery: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
NodeSwap: {
|
||||
{Version: version.MustParse("1.22"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
OrderedNamespaceDeletion: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
PDBUnhealthyPodEvictionPolicy: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
},
|
||||
|
||||
PersistentVolumeLastPhaseTransitionTime: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
},
|
||||
|
||||
PodAndContainerStatsFromCRI: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
PodDeletionCost: {
|
||||
{Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
PodDisruptionConditions: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.26"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
},
|
||||
|
||||
PodIndexLabel: {
|
||||
{Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.35
|
||||
},
|
||||
|
||||
PodLevelResources: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
PodLifecycleSleepAction: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
PodReadyToStartContainersCondition: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
PodLifecycleSleepActionAllowZero: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
PodSchedulingReadiness: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.30; remove in 1.32
|
||||
},
|
||||
|
||||
PortForwardWebsockets: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ProcMountType: {
|
||||
{Version: version.MustParse("1.12"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
QOSReserved: {
|
||||
{Version: version.MustParse("1.11"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
RecoverVolumeExpansionFailure: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
RecursiveReadOnlyMounts: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
RelaxedDNSSearchValidation: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
RelaxedEnvironmentVariableValidation: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ReloadKubeletServerCertificateFile: {
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ResourceHealthStatus: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
RotateKubeletServerCertificate: {
|
||||
{Version: version.MustParse("1.7"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.12"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
RuntimeClassInImageCriAPI: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
SchedulerAsyncPreemption: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
SchedulerQueueingHints: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
SELinuxChangePolicy: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
SELinuxMount: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
SELinuxMountReadWriteOncePod: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
SeparateTaintEvictionController: {
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
StorageNamespaceIndex: {
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ServiceAccountNodeAudienceRestriction: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ServiceAccountTokenJTI: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.34
|
||||
},
|
||||
|
||||
ServiceAccountTokenNodeBinding: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ServiceAccountTokenNodeBindingValidation: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.34
|
||||
},
|
||||
|
||||
ServiceAccountTokenPodNodeInfo: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.34
|
||||
},
|
||||
|
||||
ServiceTrafficDistribution: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
SidecarContainers: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.29"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
SizeMemoryBackedVolumes: {
|
||||
{Version: version.MustParse("1.20"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, LockToDefault: true, PreRelease: featuregate.GA},
|
||||
},
|
||||
|
||||
PodLogsQuerySplitStreams: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
StatefulSetAutoDeletePVC: {
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.32, remove in 1.35
|
||||
},
|
||||
|
||||
StatefulSetStartOrdinal: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.31, remove in 1.33
|
||||
},
|
||||
|
||||
StorageVersionMigrator: {
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
SupplementalGroupsPolicy: {
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
SystemdWatchdog: {
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
TopologyAwareHints: {
|
||||
{Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.24"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
TopologyManagerPolicyAlphaOptions: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
TopologyManagerPolicyBetaOptions: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
TopologyManagerPolicyOptions: {
|
||||
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA},
|
||||
},
|
||||
|
||||
TranslateStreamCloseWebsocketRequests: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
UnknownVersionInteroperabilityProxy: {
|
||||
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
UserNamespacesPodSecurityStandards: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
UserNamespacesSupport: {
|
||||
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
VolumeAttributesClass: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
VolumeCapacityPriority: {
|
||||
{Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
WinDSR: {
|
||||
{Version: version.MustParse("1.14"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
WindowsGracefulNodeShutdown: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
WinOverlay: {
|
||||
{Version: version.MustParse("1.14"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.20"), Default: true, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
WindowsCPUAndMemoryAffinity: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
WindowsHostNetwork: {
|
||||
{Version: version.MustParse("1.26"), Default: true, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
zpagesfeatures.ComponentFlagz: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
|
||||
zpagesfeatures.ComponentStatusz: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
},
|
||||
}
|
111
vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go
generated
vendored
Normal file
111
vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
Copyright 2014 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 events
|
||||
|
||||
// Container event reason list
|
||||
const (
|
||||
CreatedContainer = "Created"
|
||||
StartedContainer = "Started"
|
||||
FailedToCreateContainer = "Failed"
|
||||
FailedToStartContainer = "Failed"
|
||||
KillingContainer = "Killing"
|
||||
PreemptContainer = "Preempting"
|
||||
BackOffStartContainer = "BackOff"
|
||||
ExceededGracePeriod = "ExceededGracePeriod"
|
||||
)
|
||||
|
||||
// Pod event reason list
|
||||
const (
|
||||
FailedToKillPod = "FailedKillPod"
|
||||
FailedToCreatePodContainer = "FailedCreatePodContainer"
|
||||
FailedToMakePodDataDirectories = "Failed"
|
||||
NetworkNotReady = "NetworkNotReady"
|
||||
ResizeDeferred = "ResizeDeferred"
|
||||
ResizeInfeasible = "ResizeInfeasible"
|
||||
)
|
||||
|
||||
// Image event reason list
|
||||
const (
|
||||
PullingImage = "Pulling"
|
||||
PulledImage = "Pulled"
|
||||
FailedToPullImage = "Failed"
|
||||
FailedToInspectImage = "InspectFailed"
|
||||
ErrImageNeverPullPolicy = "ErrImageNeverPull"
|
||||
BackOffPullImage = "BackOff"
|
||||
)
|
||||
|
||||
// kubelet event reason list
|
||||
const (
|
||||
NodeReady = "NodeReady"
|
||||
NodeNotReady = "NodeNotReady"
|
||||
NodeSchedulable = "NodeSchedulable"
|
||||
NodeNotSchedulable = "NodeNotSchedulable"
|
||||
StartingKubelet = "Starting"
|
||||
KubeletSetupFailed = "KubeletSetupFailed"
|
||||
FailedAttachVolume = "FailedAttachVolume"
|
||||
FailedMountVolume = "FailedMount"
|
||||
VolumeResizeFailed = "VolumeResizeFailed"
|
||||
VolumeResizeSuccess = "VolumeResizeSuccessful"
|
||||
FileSystemResizeFailed = "FileSystemResizeFailed"
|
||||
VolumePermissionChangeInProgress = "VolumePermissionChangeInProgress"
|
||||
FileSystemResizeSuccess = "FileSystemResizeSuccessful"
|
||||
FailedMapVolume = "FailedMapVolume"
|
||||
WarnAlreadyMountedVolume = "AlreadyMountedVolume"
|
||||
SuccessfulAttachVolume = "SuccessfulAttachVolume"
|
||||
SuccessfulMountVolume = "SuccessfulMountVolume"
|
||||
NodeRebooted = "Rebooted"
|
||||
NodeShutdown = "Shutdown"
|
||||
ContainerGCFailed = "ContainerGCFailed"
|
||||
ImageGCFailed = "ImageGCFailed"
|
||||
FailedNodeAllocatableEnforcement = "FailedNodeAllocatableEnforcement"
|
||||
SuccessfulNodeAllocatableEnforcement = "NodeAllocatableEnforced"
|
||||
SandboxChanged = "SandboxChanged"
|
||||
FailedCreatePodSandBox = "FailedCreatePodSandBox"
|
||||
FailedStatusPodSandBox = "FailedPodSandBoxStatus"
|
||||
FailedMountOnFilesystemMismatch = "FailedMountOnFilesystemMismatch"
|
||||
FailedPrepareDynamicResources = "FailedPrepareDynamicResources"
|
||||
PossibleMemoryBackedVolumesOnDisk = "PossibleMemoryBackedVolumesOnDisk"
|
||||
CgroupV1 = "CgroupV1"
|
||||
)
|
||||
|
||||
// Image manager event reason list
|
||||
const (
|
||||
InvalidDiskCapacity = "InvalidDiskCapacity"
|
||||
FreeDiskSpaceFailed = "FreeDiskSpaceFailed"
|
||||
)
|
||||
|
||||
// Probe event reason list
|
||||
const (
|
||||
ContainerUnhealthy = "Unhealthy"
|
||||
ContainerProbeWarning = "ProbeWarning"
|
||||
)
|
||||
|
||||
// Pod worker event reason list
|
||||
const (
|
||||
FailedSync = "FailedSync"
|
||||
)
|
||||
|
||||
// Config event reason list
|
||||
const (
|
||||
FailedValidation = "FailedValidation"
|
||||
)
|
||||
|
||||
// Lifecycle hooks
|
||||
const (
|
||||
FailedPostStartHook = "FailedPostStartHook"
|
||||
FailedPreStopHook = "FailedPreStopHook"
|
||||
)
|
172
vendor/k8s.io/kubernetes/pkg/util/filesystem/defaultfs.go
generated
vendored
172
vendor/k8s.io/kubernetes/pkg/util/filesystem/defaultfs.go
generated
vendored
@ -1,172 +0,0 @@
|
||||
/*
|
||||
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 filesystem
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DefaultFs implements Filesystem using same-named functions from "os" and "io"
|
||||
type DefaultFs struct {
|
||||
root string
|
||||
}
|
||||
|
||||
var _ Filesystem = &DefaultFs{}
|
||||
|
||||
// NewTempFs returns a fake Filesystem in temporary directory, useful for unit tests
|
||||
func NewTempFs() Filesystem {
|
||||
path, _ := os.MkdirTemp("", "tmpfs")
|
||||
return &DefaultFs{
|
||||
root: path,
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *DefaultFs) prefix(path string) string {
|
||||
if len(fs.root) == 0 {
|
||||
return path
|
||||
}
|
||||
return filepath.Join(fs.root, path)
|
||||
}
|
||||
|
||||
// Stat via os.Stat
|
||||
func (fs *DefaultFs) Stat(name string) (os.FileInfo, error) {
|
||||
return os.Stat(fs.prefix(name))
|
||||
}
|
||||
|
||||
// Create via os.Create
|
||||
func (fs *DefaultFs) Create(name string) (File, error) {
|
||||
file, err := os.Create(fs.prefix(name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &defaultFile{file}, nil
|
||||
}
|
||||
|
||||
// Rename via os.Rename
|
||||
func (fs *DefaultFs) Rename(oldpath, newpath string) error {
|
||||
if !strings.HasPrefix(oldpath, fs.root) {
|
||||
oldpath = fs.prefix(oldpath)
|
||||
}
|
||||
if !strings.HasPrefix(newpath, fs.root) {
|
||||
newpath = fs.prefix(newpath)
|
||||
}
|
||||
return os.Rename(oldpath, newpath)
|
||||
}
|
||||
|
||||
func (fs *DefaultFs) MkdirAll(path string, perm os.FileMode) error {
|
||||
return MkdirAll(fs.prefix(path), perm)
|
||||
}
|
||||
|
||||
// MkdirAllWithPathCheck checks if path exists already. If not, it creates a directory
|
||||
// named path, along with any necessary parents, and returns nil, or else returns an error.
|
||||
// Permission bits perm (before umask) are used for all directories that
|
||||
// MkdirAllWithPathCheck creates.
|
||||
// If path is already a directory, MkdirAllWithPathCheck does nothing and returns nil.
|
||||
// NOTE: In case of Windows NTFS, mount points are implemented as reparse-point
|
||||
// (similar to symlink) and do not represent actual directory. Hence Directory existence
|
||||
// check for windows NTFS will NOT check for dir, but for symlink presence.
|
||||
func MkdirAllWithPathCheck(path string, perm os.FileMode) error {
|
||||
if dir, err := os.Lstat(path); err == nil {
|
||||
// If the path exists already,
|
||||
// 1. for Unix/Linux OS, check if the path is directory.
|
||||
// 2. for windows NTFS, check if the path is symlink instead of directory.
|
||||
if dir.IsDir() ||
|
||||
(runtime.GOOS == "windows" && (dir.Mode()&os.ModeSymlink != 0)) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("path %v exists but is not a directory", path)
|
||||
}
|
||||
// If existence of path not known, attempt to create it.
|
||||
if err := MkdirAll(path, perm); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chtimes via os.Chtimes
|
||||
func (fs *DefaultFs) Chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||
return os.Chtimes(fs.prefix(name), atime, mtime)
|
||||
}
|
||||
|
||||
// RemoveAll via os.RemoveAll
|
||||
func (fs *DefaultFs) RemoveAll(path string) error {
|
||||
return os.RemoveAll(fs.prefix(path))
|
||||
}
|
||||
|
||||
// Remove via os.Remove
|
||||
func (fs *DefaultFs) Remove(name string) error {
|
||||
return os.Remove(fs.prefix(name))
|
||||
}
|
||||
|
||||
// ReadFile via os.ReadFile
|
||||
func (fs *DefaultFs) ReadFile(filename string) ([]byte, error) {
|
||||
return os.ReadFile(fs.prefix(filename))
|
||||
}
|
||||
|
||||
// TempDir via os.MkdirTemp
|
||||
func (fs *DefaultFs) TempDir(dir, prefix string) (string, error) {
|
||||
return os.MkdirTemp(fs.prefix(dir), prefix)
|
||||
}
|
||||
|
||||
// TempFile via os.CreateTemp
|
||||
func (fs *DefaultFs) TempFile(dir, prefix string) (File, error) {
|
||||
file, err := os.CreateTemp(fs.prefix(dir), prefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &defaultFile{file}, nil
|
||||
}
|
||||
|
||||
// ReadDir via os.ReadDir
|
||||
func (fs *DefaultFs) ReadDir(dirname string) ([]os.DirEntry, error) {
|
||||
return os.ReadDir(fs.prefix(dirname))
|
||||
}
|
||||
|
||||
// Walk via filepath.Walk
|
||||
func (fs *DefaultFs) Walk(root string, walkFn filepath.WalkFunc) error {
|
||||
return filepath.Walk(fs.prefix(root), walkFn)
|
||||
}
|
||||
|
||||
// defaultFile implements File using same-named functions from "os"
|
||||
type defaultFile struct {
|
||||
file *os.File
|
||||
}
|
||||
|
||||
// Name via os.File.Name
|
||||
func (file *defaultFile) Name() string {
|
||||
return file.file.Name()
|
||||
}
|
||||
|
||||
// Write via os.File.Write
|
||||
func (file *defaultFile) Write(b []byte) (n int, err error) {
|
||||
return file.file.Write(b)
|
||||
}
|
||||
|
||||
// Sync via os.File.Sync
|
||||
func (file *defaultFile) Sync() error {
|
||||
return file.file.Sync()
|
||||
}
|
||||
|
||||
// Close via os.File.Close
|
||||
func (file *defaultFile) Close() error {
|
||||
return file.file.Close()
|
||||
}
|
52
vendor/k8s.io/kubernetes/pkg/util/filesystem/filesystem.go
generated
vendored
52
vendor/k8s.io/kubernetes/pkg/util/filesystem/filesystem.go
generated
vendored
@ -1,52 +0,0 @@
|
||||
/*
|
||||
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 filesystem
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Filesystem is an interface that we can use to mock various filesystem operations
|
||||
type Filesystem interface {
|
||||
// from "os"
|
||||
Stat(name string) (os.FileInfo, error)
|
||||
Create(name string) (File, error)
|
||||
Rename(oldpath, newpath string) error
|
||||
MkdirAll(path string, perm os.FileMode) error
|
||||
Chtimes(name string, atime time.Time, mtime time.Time) error
|
||||
RemoveAll(path string) error
|
||||
Remove(name string) error
|
||||
|
||||
// from "os"
|
||||
ReadFile(filename string) ([]byte, error)
|
||||
TempDir(dir, prefix string) (string, error)
|
||||
TempFile(dir, prefix string) (File, error)
|
||||
ReadDir(dirname string) ([]os.DirEntry, error)
|
||||
Walk(root string, walkFn filepath.WalkFunc) error
|
||||
}
|
||||
|
||||
// File is an interface that we can use to mock various filesystem operations typically
|
||||
// accessed through the File object from the "os" package
|
||||
type File interface {
|
||||
// for now, the only os.File methods used are those below, add more as necessary
|
||||
Name() string
|
||||
Write(b []byte) (n int, err error)
|
||||
Sync() error
|
||||
Close() error
|
||||
}
|
27
vendor/k8s.io/kubernetes/pkg/util/filesystem/util.go
generated
vendored
27
vendor/k8s.io/kubernetes/pkg/util/filesystem/util.go
generated
vendored
@ -1,27 +0,0 @@
|
||||
/*
|
||||
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 filesystem
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// IsPathClean will replace slashes to Separator (which is OS-specific).
|
||||
// This will make sure that all slashes are the same before comparing.
|
||||
func IsPathClean(path string) bool {
|
||||
return filepath.ToSlash(filepath.Clean(path)) == filepath.ToSlash(path)
|
||||
}
|
53
vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go
generated
vendored
53
vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
//go:build freebsd || linux || darwin
|
||||
// +build freebsd linux darwin
|
||||
|
||||
/*
|
||||
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 filesystem
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// IsUnixDomainSocket returns whether a given file is a AF_UNIX socket file
|
||||
func IsUnixDomainSocket(filePath string) (bool, error) {
|
||||
fi, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("stat file %s failed: %v", filePath, err)
|
||||
}
|
||||
if fi.Mode()&os.ModeSocket == 0 {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Chmod is the same as os.Chmod on Unix.
|
||||
func Chmod(name string, mode os.FileMode) error {
|
||||
return os.Chmod(name, mode)
|
||||
}
|
||||
|
||||
// MkdirAll is same as os.MkdirAll on Unix.
|
||||
func MkdirAll(path string, perm os.FileMode) error {
|
||||
return os.MkdirAll(path, perm)
|
||||
}
|
||||
|
||||
// IsAbs is same as filepath.IsAbs on Unix.
|
||||
func IsAbs(path string) bool {
|
||||
return filepath.IsAbs(path)
|
||||
}
|
255
vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go
generated
vendored
255
vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go
generated
vendored
@ -1,255 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
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 filesystem
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
// Amount of time to wait between attempting to use a Unix domain socket.
|
||||
// As detailed in https://github.com/kubernetes/kubernetes/issues/104584
|
||||
// the first attempt will most likely fail, hence the need to retry
|
||||
socketDialRetryPeriod = 1 * time.Second
|
||||
// Overall timeout value to dial a Unix domain socket, including retries
|
||||
socketDialTimeout = 4 * time.Second
|
||||
)
|
||||
|
||||
// IsUnixDomainSocket returns whether a given file is a AF_UNIX socket file
|
||||
// Note that due to the retry logic inside, it could take up to 4 seconds
|
||||
// to determine whether or not the file path supplied is a Unix domain socket
|
||||
func IsUnixDomainSocket(filePath string) (bool, error) {
|
||||
// Due to the absence of golang support for os.ModeSocket in Windows (https://github.com/golang/go/issues/33357)
|
||||
// we need to dial the file and check if we receive an error to determine if a file is Unix Domain Socket file.
|
||||
|
||||
// Note that querrying for the Reparse Points (https://docs.microsoft.com/en-us/windows/win32/fileio/reparse-points)
|
||||
// for the file (using FSCTL_GET_REPARSE_POINT) and checking for reparse tag: reparseTagSocket
|
||||
// does NOT work in 1809 if the socket file is created within a bind mounted directory by a container
|
||||
// and the FSCTL is issued in the host by the kubelet.
|
||||
|
||||
// If the file does not exist, it cannot be a Unix domain socket.
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
return false, fmt.Errorf("File %s not found. Err: %v", filePath, err)
|
||||
}
|
||||
|
||||
klog.V(6).InfoS("Function IsUnixDomainSocket starts", "filePath", filePath)
|
||||
// As detailed in https://github.com/kubernetes/kubernetes/issues/104584 we cannot rely
|
||||
// on the Unix Domain socket working on the very first try, hence the potential need to
|
||||
// dial multiple times
|
||||
var lastSocketErr error
|
||||
err := wait.PollImmediate(socketDialRetryPeriod, socketDialTimeout,
|
||||
func() (bool, error) {
|
||||
klog.V(6).InfoS("Dialing the socket", "filePath", filePath)
|
||||
var c net.Conn
|
||||
c, lastSocketErr = net.Dial("unix", filePath)
|
||||
if lastSocketErr == nil {
|
||||
c.Close()
|
||||
klog.V(6).InfoS("Socket dialed successfully", "filePath", filePath)
|
||||
return true, nil
|
||||
}
|
||||
klog.V(6).InfoS("Failed the current attempt to dial the socket, so pausing before retry",
|
||||
"filePath", filePath, "err", lastSocketErr, "socketDialRetryPeriod",
|
||||
socketDialRetryPeriod)
|
||||
return false, nil
|
||||
})
|
||||
|
||||
// PollImmediate will return "timed out waiting for the condition" if the function it
|
||||
// invokes never returns true
|
||||
if err != nil {
|
||||
klog.V(2).InfoS("Failed all attempts to dial the socket so marking it as a non-Unix Domain socket. Last socket error along with the error from PollImmediate follow",
|
||||
"filePath", filePath, "lastSocketErr", lastSocketErr, "err", err)
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// On Windows os.Mkdir all doesn't set any permissions so call the Chown function below to set
|
||||
// permissions once the directory is created.
|
||||
func MkdirAll(path string, perm os.FileMode) error {
|
||||
klog.V(6).InfoS("Function MkdirAll starts", "path", path, "perm", perm)
|
||||
err := os.MkdirAll(path, perm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating directory %s: %v", path, err)
|
||||
}
|
||||
|
||||
err = Chmod(path, perm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error setting permissions for directory %s: %v", path, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
// These aren't defined in the syscall package for Windows :(
|
||||
USER_READ = 0x100
|
||||
USER_WRITE = 0x80
|
||||
USER_EXECUTE = 0x40
|
||||
GROUP_READ = 0x20
|
||||
GROUP_WRITE = 0x10
|
||||
GROUP_EXECUTE = 0x8
|
||||
OTHERS_READ = 0x4
|
||||
OTHERS_WRITE = 0x2
|
||||
OTHERS_EXECUTE = 0x1
|
||||
USER_ALL = USER_READ | USER_WRITE | USER_EXECUTE
|
||||
GROUP_ALL = GROUP_READ | GROUP_WRITE | GROUP_EXECUTE
|
||||
OTHERS_ALL = OTHERS_READ | OTHERS_WRITE | OTHERS_EXECUTE
|
||||
)
|
||||
|
||||
// On Windows os.Chmod only sets the read-only flag on files, so we need to use Windows APIs to set the desired access on files / directories.
|
||||
// The OWNER mode will set file permissions for the file owner SID, the GROUP mode will set file permissions for the file group SID,
|
||||
// and the OTHERS mode will set file permissions for BUILTIN\Users.
|
||||
// Please note that Windows containers can be run as one of two user accounts; ContainerUser or ContainerAdministrator.
|
||||
// Containers run as ContainerAdministrator will inherit permissions from BUILTIN\Administrators,
|
||||
// while containers run as ContainerUser will inherit permissions from BUILTIN\Users.
|
||||
// Windows containers do not have the ability to run as a custom user account that is known to the host so the OTHERS group mode
|
||||
// is used to grant / deny permissions of files on the hosts to the ContainerUser account.
|
||||
func Chmod(path string, filemode os.FileMode) error {
|
||||
klog.V(6).InfoS("Function Chmod starts", "path", path, "filemode", filemode)
|
||||
// Get security descriptor for the file
|
||||
sd, err := windows.GetNamedSecurityInfo(
|
||||
path,
|
||||
windows.SE_FILE_OBJECT,
|
||||
windows.DACL_SECURITY_INFORMATION|windows.PROTECTED_DACL_SECURITY_INFORMATION|windows.OWNER_SECURITY_INFORMATION|windows.GROUP_SECURITY_INFORMATION)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting security descriptor for file %s: %v", path, err)
|
||||
}
|
||||
|
||||
// Get owner SID from the security descriptor for assigning USER permissions
|
||||
owner, _, err := sd.Owner()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting owner SID for file %s: %v", path, err)
|
||||
}
|
||||
ownerString := owner.String()
|
||||
|
||||
// Get the group SID from the security descriptor for assigning GROUP permissions
|
||||
group, _, err := sd.Group()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting group SID for file %s: %v", path, err)
|
||||
}
|
||||
groupString := group.String()
|
||||
|
||||
mask := uint32(windows.ACCESS_MASK(filemode))
|
||||
|
||||
// Build a new Discretionary Access Control List (DACL) with the desired permissions using
|
||||
//the Security Descriptor Definition Language (SDDL) format.
|
||||
// https://learn.microsoft.com/windows/win32/secauthz/security-descriptor-definition-language
|
||||
// the DACL is a list of Access Control Entries (ACEs) where each ACE represents the permissions (Allow or Deny) for a specific SID.
|
||||
// Each ACE has the following format:
|
||||
// (AceType;AceFlags;Rights;ObjectGuid;InheritObjectGuid;AccountSid)
|
||||
// We can leave ObjectGuid and InheritObjectGuid empty for our purposes.
|
||||
|
||||
dacl := "D:"
|
||||
|
||||
// build the owner ACE
|
||||
dacl += "(A;OICI;"
|
||||
if mask&USER_ALL == USER_ALL {
|
||||
dacl += "FA"
|
||||
} else {
|
||||
if mask&USER_READ == USER_READ {
|
||||
dacl += "FR"
|
||||
}
|
||||
if mask&USER_WRITE == USER_WRITE {
|
||||
dacl += "FW"
|
||||
}
|
||||
if mask&USER_EXECUTE == USER_EXECUTE {
|
||||
dacl += "FX"
|
||||
}
|
||||
}
|
||||
dacl += ";;;" + ownerString + ")"
|
||||
|
||||
// Build the group ACE
|
||||
dacl += "(A;OICI;"
|
||||
if mask&GROUP_ALL == GROUP_ALL {
|
||||
dacl += "FA"
|
||||
} else {
|
||||
if mask&GROUP_READ == GROUP_READ {
|
||||
dacl += "FR"
|
||||
}
|
||||
if mask&GROUP_WRITE == GROUP_WRITE {
|
||||
dacl += "FW"
|
||||
}
|
||||
if mask&GROUP_EXECUTE == GROUP_EXECUTE {
|
||||
dacl += "FX"
|
||||
}
|
||||
}
|
||||
dacl += ";;;" + groupString + ")"
|
||||
|
||||
// Build the others ACE
|
||||
dacl += "(A;OICI;"
|
||||
if mask&OTHERS_ALL == OTHERS_ALL {
|
||||
dacl += "FA"
|
||||
} else {
|
||||
if mask&OTHERS_READ == OTHERS_READ {
|
||||
dacl += "FR"
|
||||
}
|
||||
if mask&OTHERS_WRITE == OTHERS_WRITE {
|
||||
dacl += "FW"
|
||||
}
|
||||
if mask&OTHERS_EXECUTE == OTHERS_EXECUTE {
|
||||
dacl += "FX"
|
||||
}
|
||||
}
|
||||
dacl += ";;;BU)"
|
||||
|
||||
klog.V(6).InfoS("Setting new DACL for path", "path", path, "dacl", dacl)
|
||||
|
||||
// create a new security descriptor from the DACL string
|
||||
newSD, err := windows.SecurityDescriptorFromString(dacl)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating new security descriptor from DACL string: %v", err)
|
||||
}
|
||||
|
||||
// get the DACL in binary format from the newly created security descriptor
|
||||
newDACL, _, err := newSD.DACL()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting DACL from new security descriptor: %v", err)
|
||||
}
|
||||
|
||||
// Write the new security descriptor to the file
|
||||
return windows.SetNamedSecurityInfo(
|
||||
path,
|
||||
windows.SE_FILE_OBJECT,
|
||||
windows.DACL_SECURITY_INFORMATION|windows.PROTECTED_DACL_SECURITY_INFORMATION,
|
||||
nil, // owner SID
|
||||
nil, // group SID
|
||||
newDACL,
|
||||
nil) // SACL
|
||||
}
|
||||
|
||||
// IsAbs returns whether the given path is absolute or not.
|
||||
// On Windows, filepath.IsAbs will not return True for paths prefixed with a slash, even
|
||||
// though they can be used as absolute paths (https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats).
|
||||
//
|
||||
// WARN: It isn't safe to use this for API values which will propagate across systems (e.g. REST API values
|
||||
// that get validated on Unix, persisted, then consumed by Windows, etc).
|
||||
func IsAbs(path string) bool {
|
||||
return filepath.IsAbs(path) || strings.HasPrefix(path, `\`) || strings.HasPrefix(path, `/`)
|
||||
}
|
216
vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go
generated
vendored
216
vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go
generated
vendored
@ -1,216 +0,0 @@
|
||||
/*
|
||||
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 filesystem
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
// FSWatcher is a callback-based filesystem watcher abstraction for fsnotify.
|
||||
type FSWatcher interface {
|
||||
// Initializes the watcher with the given watch handlers.
|
||||
// Called before all other methods.
|
||||
Init(FSEventHandler, FSErrorHandler) error
|
||||
|
||||
// Starts listening for events and errors.
|
||||
// When an event or error occurs, the corresponding handler is called.
|
||||
Run()
|
||||
|
||||
// Add a filesystem path to watch
|
||||
AddWatch(path string) error
|
||||
}
|
||||
|
||||
// FSEventHandler is called when a fsnotify event occurs.
|
||||
type FSEventHandler func(event fsnotify.Event)
|
||||
|
||||
// FSErrorHandler is called when a fsnotify error occurs.
|
||||
type FSErrorHandler func(err error)
|
||||
|
||||
type fsnotifyWatcher struct {
|
||||
watcher *fsnotify.Watcher
|
||||
eventHandler FSEventHandler
|
||||
errorHandler FSErrorHandler
|
||||
}
|
||||
|
||||
var _ FSWatcher = &fsnotifyWatcher{}
|
||||
|
||||
// NewFsnotifyWatcher returns an implementation of FSWatcher that continuously listens for
|
||||
// fsnotify events and calls the event handler as soon as an event is received.
|
||||
func NewFsnotifyWatcher() FSWatcher {
|
||||
return &fsnotifyWatcher{}
|
||||
}
|
||||
|
||||
func (w *fsnotifyWatcher) AddWatch(path string) error {
|
||||
return w.watcher.Add(path)
|
||||
}
|
||||
|
||||
func (w *fsnotifyWatcher) Init(eventHandler FSEventHandler, errorHandler FSErrorHandler) error {
|
||||
var err error
|
||||
w.watcher, err = fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.eventHandler = eventHandler
|
||||
w.errorHandler = errorHandler
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *fsnotifyWatcher) Run() {
|
||||
go func() {
|
||||
defer w.watcher.Close()
|
||||
for {
|
||||
select {
|
||||
case event := <-w.watcher.Events:
|
||||
if w.eventHandler != nil {
|
||||
w.eventHandler(event)
|
||||
}
|
||||
case err := <-w.watcher.Errors:
|
||||
if w.errorHandler != nil {
|
||||
w.errorHandler(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
type watchAddRemover interface {
|
||||
Add(path string) error
|
||||
Remove(path string) error
|
||||
}
|
||||
type noopWatcher struct{}
|
||||
|
||||
func (noopWatcher) Add(path string) error { return nil }
|
||||
func (noopWatcher) Remove(path string) error { return nil }
|
||||
|
||||
// WatchUntil watches the specified path for changes and blocks until ctx is canceled.
|
||||
// eventHandler() must be non-nil, and pollInterval must be greater than 0.
|
||||
// eventHandler() is invoked whenever a change event is observed or pollInterval elapses.
|
||||
// errorHandler() is invoked (if non-nil) whenever an error occurs initializing or watching the specified path.
|
||||
//
|
||||
// If path is a directory, only the directory and immediate children are watched.
|
||||
//
|
||||
// If path does not exist or cannot be watched, an error is passed to errorHandler() and eventHandler() is called at pollInterval.
|
||||
//
|
||||
// Multiple observed events may collapse to a single invocation of eventHandler().
|
||||
//
|
||||
// eventHandler() is invoked immediately after successful initialization of the filesystem watch,
|
||||
// in case the path changed concurrent with calling WatchUntil().
|
||||
func WatchUntil(ctx context.Context, pollInterval time.Duration, path string, eventHandler func(), errorHandler func(err error)) {
|
||||
if pollInterval <= 0 {
|
||||
panic(fmt.Errorf("pollInterval must be > 0"))
|
||||
}
|
||||
if eventHandler == nil {
|
||||
panic(fmt.Errorf("eventHandler must be non-nil"))
|
||||
}
|
||||
if errorHandler == nil {
|
||||
errorHandler = func(err error) {}
|
||||
}
|
||||
|
||||
// Initialize watcher, fall back to no-op
|
||||
var (
|
||||
eventsCh chan fsnotify.Event
|
||||
errorCh chan error
|
||||
watcher watchAddRemover
|
||||
)
|
||||
if w, err := fsnotify.NewWatcher(); err != nil {
|
||||
errorHandler(fmt.Errorf("error creating file watcher, falling back to poll at interval %s: %w", pollInterval, err))
|
||||
watcher = noopWatcher{}
|
||||
} else {
|
||||
watcher = w
|
||||
eventsCh = w.Events
|
||||
errorCh = w.Errors
|
||||
defer func() {
|
||||
_ = w.Close()
|
||||
}()
|
||||
}
|
||||
|
||||
// Initialize background poll
|
||||
t := time.NewTicker(pollInterval)
|
||||
defer t.Stop()
|
||||
|
||||
attemptPeriodicRewatch := false
|
||||
|
||||
// Start watching the path
|
||||
if err := watcher.Add(path); err != nil {
|
||||
errorHandler(err)
|
||||
attemptPeriodicRewatch = true
|
||||
} else {
|
||||
// Invoke handle() at least once after successfully registering the listener,
|
||||
// in case the file changed concurrent with calling WatchUntil.
|
||||
eventHandler()
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
|
||||
case <-t.C:
|
||||
// Prioritize exiting if context is canceled
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Try to re-establish the watcher if we previously got a watch error
|
||||
if attemptPeriodicRewatch {
|
||||
_ = watcher.Remove(path)
|
||||
if err := watcher.Add(path); err != nil {
|
||||
errorHandler(err)
|
||||
} else {
|
||||
attemptPeriodicRewatch = false
|
||||
}
|
||||
}
|
||||
|
||||
// Handle
|
||||
eventHandler()
|
||||
|
||||
case e := <-eventsCh:
|
||||
// Prioritize exiting if context is canceled
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Try to re-establish the watcher for events which dropped the existing watch
|
||||
if e.Name == path && (e.Has(fsnotify.Remove) || e.Has(fsnotify.Rename)) {
|
||||
_ = watcher.Remove(path)
|
||||
if err := watcher.Add(path); err != nil {
|
||||
errorHandler(err)
|
||||
attemptPeriodicRewatch = true
|
||||
}
|
||||
}
|
||||
|
||||
// Handle
|
||||
eventHandler()
|
||||
|
||||
case err := <-errorCh:
|
||||
// Prioritize exiting if context is canceled
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// If the error occurs in response to calling watcher.Add, re-adding here could hot-loop.
|
||||
// The periodic poll will attempt to re-establish the watch.
|
||||
errorHandler(err)
|
||||
attemptPeriodicRewatch = true
|
||||
}
|
||||
}
|
||||
}
|
2
vendor/k8s.io/kubernetes/pkg/volume/doc.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/volume/doc.go
generated
vendored
@ -16,4 +16,4 @@ limitations under the License.
|
||||
|
||||
// Package volume includes internal representations of external volume types
|
||||
// as well as utility methods required to mount/unmount volumes to kubelets.
|
||||
package volume // import "k8s.io/kubernetes/pkg/volume"
|
||||
package volume
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/volume/metrics_block.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/volume/metrics_block.go
generated
vendored
@ -37,7 +37,7 @@ type metricsBlock struct {
|
||||
device string
|
||||
}
|
||||
|
||||
// NewMetricsStatfs creates a new metricsBlock with the device node of the
|
||||
// NewMetricsBlock creates a new metricsBlock with the device node of the
|
||||
// Volume.
|
||||
func NewMetricsBlock(device string) MetricsProvider {
|
||||
return &metricsBlock{device}
|
||||
|
4
vendor/k8s.io/kubernetes/pkg/volume/metrics_errors.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/volume/metrics_errors.go
generated
vendored
@ -23,7 +23,11 @@ import (
|
||||
const (
|
||||
// ErrCodeNotSupported code for NotSupported Errors.
|
||||
ErrCodeNotSupported int = iota + 1
|
||||
|
||||
// ErrCodeNoPathDefined code for NoPathDefined Errors.
|
||||
ErrCodeNoPathDefined
|
||||
|
||||
// ErrCodeFsInfoFailed code for FsInfoFailed Errors.
|
||||
ErrCodeFsInfoFailed
|
||||
)
|
||||
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/volume/metrics_statfs.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/volume/metrics_statfs.go
generated
vendored
@ -34,7 +34,7 @@ type metricsStatFS struct {
|
||||
path string
|
||||
}
|
||||
|
||||
// NewMetricsStatfs creates a new metricsStatFS with the Volume path.
|
||||
// NewMetricsStatFS creates a new metricsStatFS with the Volume path.
|
||||
func NewMetricsStatFS(path string) MetricsProvider {
|
||||
return &metricsStatFS{path}
|
||||
}
|
||||
|
58
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
58
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
@ -44,7 +44,10 @@ import (
|
||||
"k8s.io/kubernetes/pkg/volume/util/subpath"
|
||||
)
|
||||
|
||||
// ProbeOperation represents a type of operation for probing volume plugins.
|
||||
type ProbeOperation uint32
|
||||
|
||||
// ProbeEvent represents an event triggered during a volume plugin probe operation.
|
||||
type ProbeEvent struct {
|
||||
Plugin VolumePlugin // VolumePlugin that was added/updated/removed. if ProbeEvent.Op is 'ProbeRemove', Plugin should be nil
|
||||
PluginName string
|
||||
@ -52,17 +55,22 @@ type ProbeEvent struct {
|
||||
}
|
||||
|
||||
const (
|
||||
// Common parameter which can be specified in StorageClass to specify the desired FSType
|
||||
// VolumeParameterFSType is a common parameter which can be specified in StorageClass to specify the desired FSType
|
||||
// Provisioners SHOULD implement support for this if they are block device based
|
||||
// Must be a filesystem type supported by the host operating system.
|
||||
// Ex. "ext4", "xfs", "ntfs". Default value depends on the provisioner
|
||||
VolumeParameterFSType = "fstype"
|
||||
|
||||
// ProbeAddOrUpdate represents an operation where a probe is added or updated.
|
||||
ProbeAddOrUpdate ProbeOperation = 1 << iota
|
||||
|
||||
// ProbeRemove represents an operation to remove a probe.
|
||||
// This operation is used to indicate that a previously added probe should be removed.
|
||||
ProbeRemove
|
||||
)
|
||||
|
||||
var ErrNoPluiginMatched = errors.New("no volume plugin matched")
|
||||
// ErrNoPluginMatched is used to return when no volume plugin matches the requested type.
|
||||
var ErrNoPluginMatched = errors.New("no volume plugin matched")
|
||||
|
||||
// VolumeOptions contains option information about a volume.
|
||||
type VolumeOptions struct {
|
||||
@ -108,6 +116,7 @@ type NodeResizeOptions struct {
|
||||
OldSize resource.Quantity
|
||||
}
|
||||
|
||||
// DynamicPluginProber is an interface that defines methods for probing dynamic volume plugins.
|
||||
type DynamicPluginProber interface {
|
||||
Init() error
|
||||
|
||||
@ -225,6 +234,7 @@ type AttachableVolumePlugin interface {
|
||||
NewDetacher() (Detacher, error)
|
||||
// CanAttach tests if provided volume spec is attachable
|
||||
CanAttach(spec *Spec) (bool, error)
|
||||
VerifyExhaustedResource(spec *Spec, nodeName types.NodeName)
|
||||
}
|
||||
|
||||
// DeviceMountableVolumePlugin is an extended interface of VolumePlugin and is used
|
||||
@ -628,9 +638,8 @@ func (pm *VolumePluginMgr) initProbedPlugin(probedPlugin VolumePlugin) error {
|
||||
// specification. If no plugins can support or more than one plugin can
|
||||
// support it, return error.
|
||||
func (pm *VolumePluginMgr) FindPluginBySpec(spec *Spec) (VolumePlugin, error) {
|
||||
pm.mutex.RLock()
|
||||
defer pm.mutex.RUnlock()
|
||||
|
||||
pm.mutex.Lock()
|
||||
defer pm.mutex.Unlock()
|
||||
if spec == nil {
|
||||
return nil, fmt.Errorf("could not find plugin because volume spec is nil")
|
||||
}
|
||||
@ -643,8 +652,8 @@ func (pm *VolumePluginMgr) FindPluginBySpec(spec *Spec) (VolumePlugin, error) {
|
||||
matchedPluginNames = append(matchedPluginNames, v.GetPluginName())
|
||||
}
|
||||
}
|
||||
|
||||
pm.refreshProbedPlugins()
|
||||
|
||||
for _, plugin := range pm.probedPlugins {
|
||||
if plugin.CanSupport(spec) {
|
||||
match = plugin
|
||||
@ -653,7 +662,7 @@ func (pm *VolumePluginMgr) FindPluginBySpec(spec *Spec) (VolumePlugin, error) {
|
||||
}
|
||||
|
||||
if len(matchedPluginNames) == 0 {
|
||||
return nil, ErrNoPluiginMatched
|
||||
return nil, ErrNoPluginMatched
|
||||
}
|
||||
if len(matchedPluginNames) > 1 {
|
||||
return nil, fmt.Errorf("multiple volume plugins matched: %s", strings.Join(matchedPluginNames, ","))
|
||||
@ -664,14 +673,13 @@ func (pm *VolumePluginMgr) FindPluginBySpec(spec *Spec) (VolumePlugin, error) {
|
||||
|
||||
// FindPluginByName fetches a plugin by name. If no plugin is found, returns error.
|
||||
func (pm *VolumePluginMgr) FindPluginByName(name string) (VolumePlugin, error) {
|
||||
pm.mutex.RLock()
|
||||
defer pm.mutex.RUnlock()
|
||||
pm.mutex.Lock()
|
||||
defer pm.mutex.Unlock()
|
||||
|
||||
var match VolumePlugin
|
||||
if v, found := pm.plugins[name]; found {
|
||||
match = v
|
||||
}
|
||||
|
||||
pm.refreshProbedPlugins()
|
||||
if plugin, found := pm.probedPlugins[name]; found {
|
||||
if match != nil {
|
||||
@ -698,6 +706,7 @@ func (pm *VolumePluginMgr) refreshProbedPlugins() {
|
||||
// because the probe function can return a list of valid plugins
|
||||
// even when an error is present we still must add the plugins
|
||||
// or they will be skipped because each event only fires once
|
||||
|
||||
for _, event := range events {
|
||||
if event.Op == ProbeAddOrUpdate {
|
||||
if err := pm.initProbedPlugin(event.Plugin); err != nil {
|
||||
@ -730,7 +739,7 @@ func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *Spec) (PersistentVol
|
||||
return nil, fmt.Errorf("no persistent volume plugin matched")
|
||||
}
|
||||
|
||||
// FindPersistentPluginByName fetches a persistent volume plugin by name. If
|
||||
// FindPersistentPluginByName fetches a recyclable persistent volume plugin by name. If
|
||||
// no plugin is found, returns error.
|
||||
func (pm *VolumePluginMgr) FindPersistentPluginByName(name string) (PersistentVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginByName(name)
|
||||
@ -743,7 +752,7 @@ func (pm *VolumePluginMgr) FindPersistentPluginByName(name string) (PersistentVo
|
||||
return nil, fmt.Errorf("no persistent volume plugin matched")
|
||||
}
|
||||
|
||||
// FindRecyclablePluginByName fetches a persistent volume plugin by name. If
|
||||
// FindRecyclablePluginBySpec fetches a recyclable persistent volume plugin by spec. If
|
||||
// no plugin is found, returns error.
|
||||
func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginBySpec(spec)
|
||||
@ -756,7 +765,7 @@ func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVol
|
||||
return nil, fmt.Errorf("no recyclable volume plugin matched")
|
||||
}
|
||||
|
||||
// FindProvisionablePluginByName fetches a persistent volume plugin by name. If
|
||||
// FindProvisionablePluginByName fetches a provisionable persistent volume plugin by name. If
|
||||
// no plugin is found, returns error.
|
||||
func (pm *VolumePluginMgr) FindProvisionablePluginByName(name string) (ProvisionableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginByName(name)
|
||||
@ -769,7 +778,7 @@ func (pm *VolumePluginMgr) FindProvisionablePluginByName(name string) (Provision
|
||||
return nil, fmt.Errorf("no provisionable volume plugin matched")
|
||||
}
|
||||
|
||||
// FindDeletablePluginBySpec fetches a persistent volume plugin by spec. If
|
||||
// FindDeletablePluginBySpec fetches a provisionable persistent volume plugin by spec. If
|
||||
// no plugin is found, returns error.
|
||||
func (pm *VolumePluginMgr) FindDeletablePluginBySpec(spec *Spec) (DeletableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginBySpec(spec)
|
||||
@ -782,7 +791,7 @@ func (pm *VolumePluginMgr) FindDeletablePluginBySpec(spec *Spec) (DeletableVolum
|
||||
return nil, fmt.Errorf("no deletable volume plugin matched")
|
||||
}
|
||||
|
||||
// FindDeletablePluginByName fetches a persistent volume plugin by name. If
|
||||
// FindDeletablePluginByName fetches a deleteable persistent volume plugin by name. If
|
||||
// no plugin is found, returns error.
|
||||
func (pm *VolumePluginMgr) FindDeletablePluginByName(name string) (DeletableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginByName(name)
|
||||
@ -829,7 +838,7 @@ func (pm *VolumePluginMgr) FindAttachablePluginByName(name string) (AttachableVo
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindDeviceMountablePluginBySpec fetches a persistent volume plugin by spec.
|
||||
// FindDeviceMountablePluginBySpec fetches a devicemountable persistent volume plugin by spec.
|
||||
func (pm *VolumePluginMgr) FindDeviceMountablePluginBySpec(spec *Spec) (DeviceMountableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginBySpec(spec)
|
||||
if err != nil {
|
||||
@ -845,7 +854,7 @@ func (pm *VolumePluginMgr) FindDeviceMountablePluginBySpec(spec *Spec) (DeviceMo
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindDeviceMountablePluginByName fetches a devicemountable volume plugin by name.
|
||||
// FindDeviceMountablePluginByName fetches a devicemountable persistent volume plugin by name.
|
||||
func (pm *VolumePluginMgr) FindDeviceMountablePluginByName(name string) (DeviceMountableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginByName(name)
|
||||
if err != nil {
|
||||
@ -857,7 +866,7 @@ func (pm *VolumePluginMgr) FindDeviceMountablePluginByName(name string) (DeviceM
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindExpandablePluginBySpec fetches a persistent volume plugin by spec.
|
||||
// FindExpandablePluginBySpec fetches an expandable persistent volume plugin by spec.
|
||||
func (pm *VolumePluginMgr) FindExpandablePluginBySpec(spec *Spec) (ExpandableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginBySpec(spec)
|
||||
if err != nil {
|
||||
@ -867,7 +876,7 @@ 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) {
|
||||
if errors.Is(err, ErrNoPluginMatched) {
|
||||
return nil, nil
|
||||
}
|
||||
klog.V(4).InfoS("FindExpandablePluginBySpec -> err", "specName", spec.Name(), "err", err)
|
||||
@ -880,7 +889,7 @@ func (pm *VolumePluginMgr) FindExpandablePluginBySpec(spec *Spec) (ExpandableVol
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindExpandablePluginBySpec fetches a persistent volume plugin by name.
|
||||
// FindExpandablePluginByName fetches an expandable persistent volume plugin by name.
|
||||
func (pm *VolumePluginMgr) FindExpandablePluginByName(name string) (ExpandableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginByName(name)
|
||||
if err != nil {
|
||||
@ -919,7 +928,7 @@ func (pm *VolumePluginMgr) FindMapperPluginByName(name string) (BlockVolumePlugi
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindNodeExpandablePluginBySpec fetches a persistent volume plugin by spec
|
||||
// FindNodeExpandablePluginBySpec fetches a node expandable persistent volume plugin by spec
|
||||
func (pm *VolumePluginMgr) FindNodeExpandablePluginBySpec(spec *Spec) (NodeExpandableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginBySpec(spec)
|
||||
if err != nil {
|
||||
@ -931,7 +940,7 @@ func (pm *VolumePluginMgr) FindNodeExpandablePluginBySpec(spec *Spec) (NodeExpan
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindNodeExpandablePluginByName fetches a persistent volume plugin by name
|
||||
// FindNodeExpandablePluginByName fetches a node expandable persistent volume plugin by name
|
||||
func (pm *VolumePluginMgr) FindNodeExpandablePluginByName(name string) (NodeExpandableVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginByName(name)
|
||||
if err != nil {
|
||||
@ -945,6 +954,9 @@ func (pm *VolumePluginMgr) FindNodeExpandablePluginByName(name string) (NodeExpa
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Run starts the volume plugin manager, initializing and running the necessary
|
||||
// tasks for managing volume plugins. This method is typically called to begin
|
||||
// the plugin management lifecycle.
|
||||
func (pm *VolumePluginMgr) Run(stopCh <-chan struct{}) {
|
||||
kletHost, ok := pm.Host.(KubeletVolumeHost)
|
||||
if ok {
|
||||
@ -1007,7 +1019,7 @@ func NewPersistentVolumeRecyclerPodTemplate() *v1.Pod {
|
||||
return pod
|
||||
}
|
||||
|
||||
// Check validity of recycle pod template
|
||||
// ValidateRecyclerPodTemplate checks validity of recycle pod template
|
||||
// List of checks:
|
||||
// - at least one volume is defined in the recycle pod template
|
||||
// If successful, returns nil
|
||||
|
5
vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go
generated
vendored
@ -85,6 +85,11 @@ func diskUsage(currPath string, info os.FileInfo) (int64, error) {
|
||||
return size, nil
|
||||
}
|
||||
|
||||
// go1.23 behavior change: https://github.com/golang/go/issues/63703#issuecomment-2535941458
|
||||
if info.Mode()&os.ModeIrregular != 0 {
|
||||
return size, nil
|
||||
}
|
||||
|
||||
size += info.Size()
|
||||
|
||||
if !info.IsDir() {
|
||||
|
6
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil.go
generated
vendored
@ -19,8 +19,6 @@ package hostutil
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/mount-utils"
|
||||
)
|
||||
|
||||
// FileType enumerates the known set of possible file types.
|
||||
@ -52,10 +50,6 @@ type HostUtils interface {
|
||||
DeviceOpened(pathname string) (bool, error)
|
||||
// PathIsDevice determines if a path is a device.
|
||||
PathIsDevice(pathname string) (bool, error)
|
||||
// GetDeviceNameFromMount finds the device name by checking the mount path
|
||||
// to get the global mount path within its plugin directory.
|
||||
// TODO: Remove this method once the rbd and vsphere plugins are removed from in-tree.
|
||||
GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error)
|
||||
// MakeRShared checks that given path is on a mount with 'rshared' mount
|
||||
// propagation. If not, it bind-mounts the path as rshared.
|
||||
MakeRShared(path string) error
|
||||
|
10
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux.go
generated
vendored
10
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux.go
generated
vendored
@ -66,7 +66,7 @@ func (hu *HostUtil) PathIsDevice(pathname string) (bool, error) {
|
||||
return isDevice, err
|
||||
}
|
||||
|
||||
// ExclusiveOpenFailsOnDevice is shared with NsEnterMounter
|
||||
// ExclusiveOpenFailsOnDevice checks if block device in use by calling Open with O_EXCL flag.
|
||||
func ExclusiveOpenFailsOnDevice(pathname string) (bool, error) {
|
||||
var isDevice bool
|
||||
finfo, err := os.Stat(pathname)
|
||||
@ -154,8 +154,6 @@ func (hu *HostUtil) PathExists(pathname string) (bool, error) {
|
||||
}
|
||||
|
||||
// EvalHostSymlinks returns the path name after evaluating symlinks.
|
||||
// TODO once the nsenter implementation is removed, this method can be removed
|
||||
// from the interface and filepath.EvalSymlinks used directly
|
||||
func (hu *HostUtil) EvalHostSymlinks(pathname string) (string, error) {
|
||||
return filepath.EvalSymlinks(pathname)
|
||||
}
|
||||
@ -280,8 +278,8 @@ func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
return GetModeLinux(pathname)
|
||||
}
|
||||
|
||||
// GetOwnerLinux is shared between Linux and NsEnterMounter
|
||||
// pathname must already be evaluated for symlinks
|
||||
// pathname must already be evaluated for symlinks.
|
||||
// GetOwnerLinux returns the integer ID for the user and group of the given path.
|
||||
func GetOwnerLinux(pathname string) (int64, int64, error) {
|
||||
info, err := os.Stat(pathname)
|
||||
if err != nil {
|
||||
@ -291,7 +289,7 @@ func GetOwnerLinux(pathname string) (int64, int64, error) {
|
||||
return int64(stat.Uid), int64(stat.Gid), nil
|
||||
}
|
||||
|
||||
// GetModeLinux is shared between Linux and NsEnterMounter
|
||||
// GetModeLinux returns permissions of the pathname.
|
||||
func GetModeLinux(pathname string) (os.FileMode, error) {
|
||||
info, err := os.Stat(pathname)
|
||||
if err != nil {
|
||||
|
9
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go
generated
vendored
@ -29,7 +29,6 @@ import (
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubernetes/pkg/util/filesystem"
|
||||
"k8s.io/mount-utils"
|
||||
utilpath "k8s.io/utils/path"
|
||||
)
|
||||
@ -103,14 +102,6 @@ func isSystemCannotAccessErr(err error) bool {
|
||||
func (hu *(HostUtil)) GetFileType(pathname string) (FileType, error) {
|
||||
filetype, err := getFileType(pathname)
|
||||
|
||||
// os.Stat will return a 1920 error (windows.ERROR_CANT_ACCESS_FILE) if we use it on a Unix Socket
|
||||
// on Windows. In this case, we need to use a different method to check if it's a Unix Socket.
|
||||
if err == errUnknownFileType || isSystemCannotAccessErr(err) {
|
||||
if isSocket, errSocket := filesystem.IsUnixDomainSocket(pathname); errSocket == nil && isSocket {
|
||||
return FileTypeSocket, nil
|
||||
}
|
||||
}
|
||||
|
||||
return filetype, err
|
||||
}
|
||||
|
||||
|
14
vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_linux.go
generated
vendored
14
vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_linux.go
generated
vendored
@ -78,7 +78,7 @@ func (sp *subpath) PrepareSafeSubpath(subPath Subpath) (newHostPath string, clea
|
||||
return newHostPath, cleanupAction, err
|
||||
}
|
||||
|
||||
// This implementation is shared between Linux and NsEnter
|
||||
// safeOpenSubPath opens subpath and returns its fd.
|
||||
func safeOpenSubPath(mounter mount.Interface, subpath Subpath) (int, error) {
|
||||
if !mount.PathWithinBase(subpath.Path, subpath.VolumePath) {
|
||||
return -1, fmt.Errorf("subpath %q not within volume path %q", subpath.Path, subpath.VolumePath)
|
||||
@ -92,11 +92,6 @@ func safeOpenSubPath(mounter mount.Interface, subpath Subpath) (int, error) {
|
||||
|
||||
// prepareSubpathTarget creates target for bind-mount of subpath. It returns
|
||||
// "true" when the target already exists and something is mounted there.
|
||||
// Given Subpath must have all paths with already resolved symlinks and with
|
||||
// paths relevant to kubelet (when it runs in a container).
|
||||
// This function is called also by NsEnterMounter. It works because
|
||||
// /var/lib/kubelet is mounted from the host into the container with Kubelet as
|
||||
// /var/lib/kubelet too.
|
||||
func prepareSubpathTarget(mounter mount.Interface, subpath Subpath) (bool, string, error) {
|
||||
// Early check for already bind-mounted subpath.
|
||||
bindPathTarget := getSubpathBindTarget(subpath)
|
||||
@ -237,7 +232,7 @@ func doBindSubPath(mounter mount.Interface, subpath Subpath) (hostPath string, e
|
||||
return bindPathTarget, nil
|
||||
}
|
||||
|
||||
// This implementation is shared between Linux and NsEnter
|
||||
// doCleanSubPaths tears down the subpath bind mounts for a pod
|
||||
func doCleanSubPaths(mounter mount.Interface, podDir string, volumeName string) error {
|
||||
// scan /var/lib/kubelet/pods/<uid>/volume-subpaths/<volume>/*
|
||||
subPathDir := filepath.Join(podDir, containerSubPathDirectoryName, volumeName)
|
||||
@ -372,9 +367,7 @@ func removeEmptyDirs(baseDir, endDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// This implementation is shared between Linux and NsEnterMounter. Both pathname
|
||||
// and base must be either already resolved symlinks or thet will be resolved in
|
||||
// kubelet's mount namespace (in case it runs containerized).
|
||||
// doSafeMakeDir creates a directory at pathname, but only if it is within base.
|
||||
func doSafeMakeDir(pathname string, base string, perm os.FileMode) error {
|
||||
klog.V(4).Infof("Creating directory %q within base %q", pathname, base)
|
||||
|
||||
@ -523,7 +516,6 @@ func findExistingPrefix(base, pathname string) (string, []string, error) {
|
||||
return pathname, []string{}, nil
|
||||
}
|
||||
|
||||
// This implementation is shared between Linux and NsEnterMounter
|
||||
// Open path and return its fd.
|
||||
// Symlinks are disallowed (pathname must already resolve symlinks),
|
||||
// and the path must be within the base directory.
|
||||
|
7
vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_unsupported.go
generated
vendored
7
vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_unsupported.go
generated
vendored
@ -24,7 +24,6 @@ import (
|
||||
"os"
|
||||
|
||||
"k8s.io/mount-utils"
|
||||
"k8s.io/utils/nsenter"
|
||||
)
|
||||
|
||||
type subpath struct{}
|
||||
@ -36,12 +35,6 @@ func New(mount.Interface) Interface {
|
||||
return &subpath{}
|
||||
}
|
||||
|
||||
// NewNSEnter is to satisfy the compiler for having NewSubpathNSEnter exist for all
|
||||
// OS choices. however, NSEnter is only valid on Linux
|
||||
func NewNSEnter(mounter mount.Interface, ne *nsenter.Nsenter, rootDir string) Interface {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sp *subpath) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) {
|
||||
return subPath.Path, nil, errUnsupported
|
||||
}
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go
generated
vendored
@ -29,7 +29,6 @@ import (
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/mount-utils"
|
||||
"k8s.io/utils/nsenter"
|
||||
)
|
||||
|
||||
// MaxPathLength is the maximum length of Windows path. Normally, it is 260, but if long path is enable,
|
||||
@ -43,12 +42,6 @@ func New(mount.Interface) Interface {
|
||||
return &subpath{}
|
||||
}
|
||||
|
||||
// NewNSEnter is to satisfy the compiler for having NewSubpathNSEnter exist for all
|
||||
// OS choices. however, NSEnter is only valid on Linux
|
||||
func NewNSEnter(mounter mount.Interface, ne *nsenter.Nsenter, rootDir string) Interface {
|
||||
return nil
|
||||
}
|
||||
|
||||
// isDriveLetterPath returns true if the given path is empty or it ends with ":" or ":\" or ":\\"
|
||||
func isDriveLetterorEmptyPath(path string) bool {
|
||||
if path == "" || strings.HasSuffix(path, ":\\\\") || strings.HasSuffix(path, ":") || strings.HasSuffix(path, ":\\") {
|
||||
@ -208,6 +201,12 @@ func lockAndCheckSubPathWithoutSymlink(volumePath, subPath string) ([]uintptr, e
|
||||
break
|
||||
}
|
||||
|
||||
// go1.23 behavior change: https://github.com/golang/go/issues/63703#issuecomment-2535941458
|
||||
if stat.Mode()&os.ModeIrregular != 0 {
|
||||
errorResult = fmt.Errorf("subpath %q is an unexpected irregular file after EvalSymlinks", currentFullPath)
|
||||
break
|
||||
}
|
||||
|
||||
if !mount.PathWithinBase(currentFullPath, volumePath) {
|
||||
errorResult = fmt.Errorf("SubPath %q not within volume path %q", currentFullPath, volumePath)
|
||||
break
|
||||
@ -342,6 +341,10 @@ func doSafeMakeDir(pathname string, base string, perm os.FileMode) error {
|
||||
if stat.Mode()&os.ModeSymlink != 0 {
|
||||
return fmt.Errorf("subpath %q is an unexpected symlink after Mkdir", currentPath)
|
||||
}
|
||||
// go1.23 behavior change: https://github.com/golang/go/issues/63703#issuecomment-2535941458
|
||||
if stat.Mode()&os.ModeIrregular != 0 {
|
||||
return fmt.Errorf("subpath %q is an unexpected irregular file after Mkdir", currentPath)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/volume/volume.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/volume/volume.go
generated
vendored
@ -17,12 +17,15 @@ limitations under the License.
|
||||
package volume
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/record"
|
||||
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
|
||||
)
|
||||
|
||||
// Volume represents a directory used by pods or hosts on a node. All method
|
||||
@ -130,6 +133,20 @@ type MounterArgs struct {
|
||||
FSGroupChangePolicy *v1.PodFSGroupChangePolicy
|
||||
DesiredSize *resource.Quantity
|
||||
SELinuxLabel string
|
||||
Recorder record.EventRecorder
|
||||
}
|
||||
|
||||
type VolumeOwnership struct {
|
||||
mounter Mounter
|
||||
dir string
|
||||
fsGroup *int64
|
||||
fsGroupChangePolicy *v1.PodFSGroupChangePolicy
|
||||
completionCallback func(volumetypes.CompleteFuncParam)
|
||||
|
||||
// for monitoring progress of permission change operation
|
||||
pod *v1.Pod
|
||||
fileCounter atomic.Int64
|
||||
recorder record.EventRecorder
|
||||
}
|
||||
|
||||
// Mounter interface provides methods to set up/mount the volume.
|
||||
|
107
vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go
generated
vendored
107
vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go
generated
vendored
@ -20,14 +20,19 @@ limitations under the License.
|
||||
package volume
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"os"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubernetes/pkg/kubelet/events"
|
||||
"k8s.io/kubernetes/pkg/volume/util/types"
|
||||
)
|
||||
|
||||
@ -37,38 +42,110 @@ const (
|
||||
execMask = os.FileMode(0110)
|
||||
)
|
||||
|
||||
// SetVolumeOwnership modifies the given volume to be owned by
|
||||
// fsGroup, and sets SetGid so that newly created files are owned by
|
||||
// fsGroup. If fsGroup is nil nothing is done.
|
||||
func SetVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) error {
|
||||
if fsGroup == nil {
|
||||
var (
|
||||
// function that will be used for changing file permissions on linux
|
||||
// mainly stored here as a variable so as it can replaced in tests
|
||||
filePermissionChangeFunc = changeFilePermission
|
||||
progressReportDuration = 60 * time.Second
|
||||
firstEventReportDuration = 30 * time.Second
|
||||
)
|
||||
|
||||
// NewVolumeOwnership returns an interface that can be used to recursively change volume permissions and ownership
|
||||
func NewVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) *VolumeOwnership {
|
||||
vo := &VolumeOwnership{
|
||||
mounter: mounter,
|
||||
dir: dir,
|
||||
fsGroup: fsGroup,
|
||||
fsGroupChangePolicy: fsGroupChangePolicy,
|
||||
completionCallback: completeFunc,
|
||||
}
|
||||
vo.fileCounter.Store(0)
|
||||
return vo
|
||||
}
|
||||
|
||||
func (vo *VolumeOwnership) AddProgressNotifier(pod *v1.Pod, recorder record.EventRecorder) *VolumeOwnership {
|
||||
vo.pod = pod
|
||||
vo.recorder = recorder
|
||||
return vo
|
||||
}
|
||||
|
||||
func (vo *VolumeOwnership) ChangePermissions() error {
|
||||
if vo.fsGroup == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
timer := time.AfterFunc(30*time.Second, func() {
|
||||
klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", dir)
|
||||
if skipPermissionChange(vo.mounter, vo.dir, vo.fsGroup, vo.fsGroupChangePolicy) {
|
||||
klog.V(3).InfoS("Skipping permission and ownership change for volume", "path", vo.dir)
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
timer := time.AfterFunc(firstEventReportDuration, func() {
|
||||
vo.initiateProgressMonitor(ctx)
|
||||
})
|
||||
defer timer.Stop()
|
||||
|
||||
if skipPermissionChange(mounter, dir, fsGroup, fsGroupChangePolicy) {
|
||||
klog.V(3).InfoS("Skipping permission and ownership change for volume", "path", dir)
|
||||
return nil
|
||||
}
|
||||
return vo.changePermissionsRecursively()
|
||||
}
|
||||
|
||||
err := walkDeep(dir, func(path string, info os.FileInfo, err error) error {
|
||||
func (vo *VolumeOwnership) initiateProgressMonitor(ctx context.Context) {
|
||||
klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", vo.dir)
|
||||
if vo.pod != nil {
|
||||
go vo.monitorProgress(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func (vo *VolumeOwnership) changePermissionsRecursively() error {
|
||||
err := walkDeep(vo.dir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return changeFilePermission(path, fsGroup, mounter.GetAttributes().ReadOnly, info)
|
||||
vo.fileCounter.Add(1)
|
||||
return filePermissionChangeFunc(path, vo.fsGroup, vo.mounter.GetAttributes().ReadOnly, info)
|
||||
})
|
||||
if completeFunc != nil {
|
||||
completeFunc(types.CompleteFuncParam{
|
||||
|
||||
if vo.completionCallback != nil {
|
||||
vo.completionCallback(types.CompleteFuncParam{
|
||||
Err: &err,
|
||||
})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (vo *VolumeOwnership) monitorProgress(ctx context.Context) {
|
||||
dirName := getDirnameToReport(vo.dir, string(vo.pod.UID))
|
||||
msg := fmt.Sprintf("Setting volume ownership for %s is taking longer than expected, consider using OnRootMismatch - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#configure-volume-permission-and-ownership-change-policy-for-pods", dirName)
|
||||
vo.recorder.Event(vo.pod, v1.EventTypeWarning, events.VolumePermissionChangeInProgress, msg)
|
||||
ticker := time.NewTicker(progressReportDuration)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
vo.logWarning()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// report everything after podUID in dir string, including podUID
|
||||
func getDirnameToReport(dir, podUID string) string {
|
||||
podUIDIndex := strings.Index(dir, podUID)
|
||||
if podUIDIndex == -1 {
|
||||
return dir
|
||||
}
|
||||
return dir[podUIDIndex:]
|
||||
}
|
||||
|
||||
func (vo *VolumeOwnership) logWarning() {
|
||||
dirName := getDirnameToReport(vo.dir, string(vo.pod.UID))
|
||||
msg := fmt.Sprintf("Setting volume ownership for %s, processed %d files.", dirName, vo.fileCounter.Load())
|
||||
klog.Warning(msg)
|
||||
vo.recorder.Event(vo.pod, v1.EventTypeWarning, events.VolumePermissionChangeInProgress, msg)
|
||||
}
|
||||
|
||||
func changeFilePermission(filename string, fsGroup *int64, readonly bool, info os.FileInfo) error {
|
||||
err := os.Lchown(filename, -1, int(*fsGroup))
|
||||
if err != nil {
|
||||
|
12
vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go
generated
vendored
@ -21,9 +21,19 @@ package volume
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/pkg/volume/util/types"
|
||||
)
|
||||
|
||||
func SetVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) error {
|
||||
// NewVolumeOwnership returns an interface that can be used to recursively change volume permissions and ownership
|
||||
func NewVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) *VolumeOwnership {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vo *VolumeOwnership) AddProgressNotifier(pod *v1.Pod, recorder record.EventRecorder) *VolumeOwnership {
|
||||
return vo
|
||||
}
|
||||
|
||||
func (vo *VolumeOwnership) ChangePermissions() error {
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user