mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
rebase: update kubernetes to 1.30
updating kubernetes to 1.30 release Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
62ddcf715b
commit
e727bd351e
101
vendor/k8s.io/kubernetes/pkg/apis/batch/types.go
generated
vendored
101
vendor/k8s.io/kubernetes/pkg/apis/batch/types.go
generated
vendored
@ -51,6 +51,9 @@ const (
|
||||
// to the pod, which don't count towards the backoff limit, according to the
|
||||
// pod failure policy. When the annotation is absent zero is implied.
|
||||
JobIndexIgnoredFailureCountAnnotation = labelPrefix + "job-index-ignored-failure-count"
|
||||
// JobControllerName reserved value for the managedBy field for the built-in
|
||||
// Job controller.
|
||||
JobControllerName = "kubernetes.io/job-controller"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@ -256,6 +259,51 @@ type PodFailurePolicy struct {
|
||||
Rules []PodFailurePolicyRule
|
||||
}
|
||||
|
||||
// SuccessPolicy describes when a Job can be declared as succeeded based on the success of some indexes.
|
||||
type SuccessPolicy struct {
|
||||
// rules represents the list of alternative rules for the declaring the Jobs
|
||||
// as successful before `.status.succeeded >= .spec.completions`. Once any of the rules are met,
|
||||
// the "SucceededCriteriaMet" condition is added, and the lingering pods are removed.
|
||||
// The terminal state for such a Job has the "Complete" condition.
|
||||
// Additionally, these rules are evaluated in order; Once the Job meets one of the rules,
|
||||
// other rules are ignored. At most 20 elements are allowed.
|
||||
// +listType=atomic
|
||||
Rules []SuccessPolicyRule
|
||||
}
|
||||
|
||||
// SuccessPolicyRule describes rule for declaring a Job as succeeded.
|
||||
// Each rule must have at least one of the "succeededIndexes" or "succeededCount" specified.
|
||||
type SuccessPolicyRule struct {
|
||||
// succeededIndexes specifies the set of indexes
|
||||
// which need to be contained in the actual set of the succeeded indexes for the Job.
|
||||
// The list of indexes must be within 0 to ".spec.completions-1" and
|
||||
// must not contain duplicates. At least one element is required.
|
||||
// The indexes are represented as intervals separated by commas.
|
||||
// The intervals can be a decimal integer or a pair of decimal integers separated by a hyphen.
|
||||
// The number are listed in represented by the first and last element of the series,
|
||||
// separated by a hyphen.
|
||||
// For example, if the completed indexes are 1, 3, 4, 5 and 7, they are
|
||||
// represented as "1,3-5,7".
|
||||
// When this field is null, this field doesn't default to any value
|
||||
// and is never evaluated at any time.
|
||||
//
|
||||
// +optional
|
||||
SucceededIndexes *string
|
||||
|
||||
// succeededCount specifies the minimal required size of the actual set of the succeeded indexes
|
||||
// for the Job. When succeededCount is used along with succeededIndexes, the check is
|
||||
// constrained only to the set of indexes specified by succeededIndexes.
|
||||
// For example, given that succeededIndexes is "1-4", succeededCount is "3",
|
||||
// and completed indexes are "1", "3", and "5", the Job isn't declared as succeeded
|
||||
// because only "1" and "3" indexes are considered in that rules.
|
||||
// When this field is null, this doesn't default to any value and
|
||||
// is never evaluated at any time.
|
||||
// When specified it needs to be a positive integer.
|
||||
//
|
||||
// +optional
|
||||
SucceededCount *int32
|
||||
}
|
||||
|
||||
// JobSpec describes how the job execution will look like.
|
||||
type JobSpec struct {
|
||||
|
||||
@ -287,6 +335,17 @@ type JobSpec struct {
|
||||
// +optional
|
||||
PodFailurePolicy *PodFailurePolicy
|
||||
|
||||
// successPolicy specifies the policy when the Job can be declared as succeeded.
|
||||
// If empty, the default behavior applies - the Job is declared as succeeded
|
||||
// only when the number of succeeded pods equals to the completions.
|
||||
// When the field is specified, it must be immutable and works only for the Indexed Jobs.
|
||||
// Once the Job meets the SuccessPolicy, the lingering pods are terminated.
|
||||
//
|
||||
// This field is alpha-level. To use this field, you must enable the
|
||||
// `JobSuccessPolicy` feature gate (disabled by default).
|
||||
// +optional
|
||||
SuccessPolicy *SuccessPolicy
|
||||
|
||||
// Specifies the duration in seconds relative to the startTime that the job
|
||||
// may be continuously active before the system tries to terminate it; value
|
||||
// must be positive integer. If a Job is suspended (at creation or through an
|
||||
@ -409,6 +468,20 @@ type JobSpec struct {
|
||||
// This is on by default.
|
||||
// +optional
|
||||
PodReplacementPolicy *PodReplacementPolicy
|
||||
|
||||
// ManagedBy field indicates the controller that manages a Job. The k8s Job
|
||||
// controller reconciles jobs which don't have this field at all or the field
|
||||
// value is the reserved string `kubernetes.io/job-controller`, but skips
|
||||
// reconciling Jobs with a custom value for this field.
|
||||
// The value must be a valid domain-prefixed path (e.g. acme.io/foo) -
|
||||
// all characters before the first "/" must be a valid subdomain as defined
|
||||
// by RFC 1123. All characters trailing the first "/" must be valid HTTP Path
|
||||
// characters as defined by RFC 3986. The value cannot exceed 64 characters.
|
||||
//
|
||||
// This field is alpha-level. The job controller accepts setting the field
|
||||
// when the feature gate JobManagedBy is enabled (disabled by default).
|
||||
// +optional
|
||||
ManagedBy *string
|
||||
}
|
||||
|
||||
// JobStatus represents the current state of a Job.
|
||||
@ -420,6 +493,12 @@ type JobStatus struct {
|
||||
// status true; when the Job is resumed, the status of this condition will
|
||||
// become false. When a Job is completed, one of the conditions will have
|
||||
// type "Complete" and status true.
|
||||
//
|
||||
// A job is considered finished when it is in a terminal condition, either
|
||||
// "Complete" or "Failed". A Job cannot have both the "Complete" and "Failed" conditions.
|
||||
// Additionally, it cannot be in the "Complete" and "FailureTarget" conditions.
|
||||
// The "Complete", "Failed" and "FailureTarget" conditions cannot be disabled.
|
||||
//
|
||||
// +optional
|
||||
Conditions []JobCondition
|
||||
|
||||
@ -427,17 +506,25 @@ type JobStatus struct {
|
||||
// Job is created in the suspended state, this field is not set until the
|
||||
// first time it is resumed. This field is reset every time a Job is resumed
|
||||
// from suspension. It is represented in RFC3339 form and is in UTC.
|
||||
//
|
||||
// Once set, the field can only be removed when the job is suspended.
|
||||
// The field cannot be modified while the job is unsuspended or finished.
|
||||
//
|
||||
// +optional
|
||||
StartTime *metav1.Time
|
||||
|
||||
// Represents time when the job was completed. It is not guaranteed to
|
||||
// be set in happens-before order across separate operations.
|
||||
// It is represented in RFC3339 form and is in UTC.
|
||||
// The completion time is only set when the job finishes successfully.
|
||||
// The completion time is set when the job finishes successfully, and only then.
|
||||
// The value cannot be updated or removed. The value indicates the same or
|
||||
// later point in time as the startTime field.
|
||||
// +optional
|
||||
CompletionTime *metav1.Time
|
||||
|
||||
// The number of pending and running pods.
|
||||
// The number of pending and running pods which are not terminating (without
|
||||
// a deletionTimestamp).
|
||||
// The value is zero for finished jobs.
|
||||
// +optional
|
||||
Active int32
|
||||
|
||||
@ -454,10 +541,13 @@ type JobStatus struct {
|
||||
Ready *int32
|
||||
|
||||
// The number of pods which reached phase Succeeded.
|
||||
// The value increases monotonically for a given spec. However, it may
|
||||
// decrease in reaction to scale down of elastic indexed jobs.
|
||||
// +optional
|
||||
Succeeded int32
|
||||
|
||||
// The number of pods which reached phase Failed.
|
||||
// The value increases monotonically.
|
||||
// +optional
|
||||
Failed int32
|
||||
|
||||
@ -471,7 +561,7 @@ type JobStatus struct {
|
||||
// +optional
|
||||
CompletedIndexes string
|
||||
|
||||
// FailedIndexes holds the failed indexes when backoffLimitPerIndex=true.
|
||||
// FailedIndexes holds the failed indexes when spec.backoffLimitPerIndex is set.
|
||||
// The indexes are represented in the text format analogous as for the
|
||||
// `completedIndexes` field, ie. they are kept as decimal integers
|
||||
// separated by commas. The numbers are listed in increasing order. Three or
|
||||
@ -479,6 +569,8 @@ type JobStatus struct {
|
||||
// last element of the series, separated by a hyphen.
|
||||
// For example, if the failed indexes are 1, 3, 4, 5 and 7, they are
|
||||
// represented as "1,3-5,7".
|
||||
// The set of failed indexes cannot overlap with the set of completed indexes.
|
||||
//
|
||||
// This field is beta-level. It can be used when the `JobBackoffLimitPerIndex`
|
||||
// feature gate is enabled (enabled by default).
|
||||
// +optional
|
||||
@ -498,6 +590,7 @@ type JobStatus struct {
|
||||
//
|
||||
// Old jobs might not be tracked using this field, in which case the field
|
||||
// remains null.
|
||||
// The structure is empty for finished jobs.
|
||||
// +optional
|
||||
UncountedTerminatedPods *UncountedTerminatedPods
|
||||
}
|
||||
@ -529,6 +622,8 @@ const (
|
||||
JobFailed JobConditionType = "Failed"
|
||||
// FailureTarget means the job is about to fail its execution.
|
||||
JobFailureTarget JobConditionType = "FailureTarget"
|
||||
// JobSuccessCriteriaMet means the Job has reached a success state and will be marked as Completed
|
||||
JobSuccessCriteriaMet JobConditionType = "SuccessCriteriaMet"
|
||||
)
|
||||
|
||||
// JobCondition describes current state of a job.
|
||||
|
59
vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
59
vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
@ -257,6 +257,11 @@ func (in *JobSpec) DeepCopyInto(out *JobSpec) {
|
||||
*out = new(PodFailurePolicy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.SuccessPolicy != nil {
|
||||
in, out := &in.SuccessPolicy, &out.SuccessPolicy
|
||||
*out = new(SuccessPolicy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ActiveDeadlineSeconds != nil {
|
||||
in, out := &in.ActiveDeadlineSeconds, &out.ActiveDeadlineSeconds
|
||||
*out = new(int64)
|
||||
@ -308,6 +313,11 @@ func (in *JobSpec) DeepCopyInto(out *JobSpec) {
|
||||
*out = new(PodReplacementPolicy)
|
||||
**out = **in
|
||||
}
|
||||
if in.ManagedBy != nil {
|
||||
in, out := &in.ManagedBy, &out.ManagedBy
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -481,6 +491,55 @@ func (in *PodFailurePolicyRule) DeepCopy() *PodFailurePolicyRule {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SuccessPolicy) DeepCopyInto(out *SuccessPolicy) {
|
||||
*out = *in
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]SuccessPolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SuccessPolicy.
|
||||
func (in *SuccessPolicy) DeepCopy() *SuccessPolicy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SuccessPolicy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SuccessPolicyRule) DeepCopyInto(out *SuccessPolicyRule) {
|
||||
*out = *in
|
||||
if in.SucceededIndexes != nil {
|
||||
in, out := &in.SucceededIndexes, &out.SucceededIndexes
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.SucceededCount != nil {
|
||||
in, out := &in.SucceededCount, &out.SucceededCount
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SuccessPolicyRule.
|
||||
func (in *SuccessPolicyRule) DeepCopy() *SuccessPolicyRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SuccessPolicyRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UncountedTerminatedPods) DeepCopyInto(out *UncountedTerminatedPods) {
|
||||
*out = *in
|
||||
|
13
vendor/k8s.io/kubernetes/pkg/apis/core/annotation_key_constants.go
generated
vendored
13
vendor/k8s.io/kubernetes/pkg/apis/core/annotation_key_constants.go
generated
vendored
@ -52,6 +52,19 @@ const (
|
||||
// Deprecated: set a pod or container security context `seccompProfile` of type "RuntimeDefault" instead.
|
||||
DeprecatedSeccompProfileDockerDefault string = "docker/default"
|
||||
|
||||
// DeprecatedAppArmorAnnotationKeyPrefix is the prefix to an annotation key specifying a container's apparmor profile.
|
||||
// Deprecated: use a pod or container security context `appArmorProfile` field instead.
|
||||
DeprecatedAppArmorAnnotationKeyPrefix = "container.apparmor.security.beta.kubernetes.io/"
|
||||
|
||||
// DeprecatedAppArmorAnnotationValueRuntimeDefault is the profile specifying the runtime default.
|
||||
DeprecatedAppArmorAnnotationValueRuntimeDefault = "runtime/default"
|
||||
|
||||
// DeprecatedAppArmorAnnotationValueLocalhostPrefix is the prefix for specifying profiles loaded on the node.
|
||||
DeprecatedAppArmorAnnotationValueLocalhostPrefix = "localhost/"
|
||||
|
||||
// DeprecatedAppArmorAnnotationValueUnconfined is the Unconfined AppArmor profile
|
||||
DeprecatedAppArmorAnnotationValueUnconfined = "unconfined"
|
||||
|
||||
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
|
||||
// in the Annotations of a Node.
|
||||
PreferAvoidPodsAnnotationKey string = "scheduler.alpha.kubernetes.io/preferAvoidPods"
|
||||
|
173
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
173
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
@ -508,7 +508,7 @@ type PersistentVolumeClaimSpec struct {
|
||||
// If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
|
||||
// set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
|
||||
// exists.
|
||||
// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
|
||||
// More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
|
||||
// (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
|
||||
// +featureGate=VolumeAttributesClass
|
||||
// +optional
|
||||
@ -2011,6 +2011,26 @@ type VolumeMount struct {
|
||||
// Optional: Defaults to false (read-write).
|
||||
// +optional
|
||||
ReadOnly bool
|
||||
// RecursiveReadOnly specifies whether read-only mounts should be handled
|
||||
// recursively.
|
||||
//
|
||||
// If ReadOnly is false, this field has no meaning and must be unspecified.
|
||||
//
|
||||
// If ReadOnly is true, and this field is set to Disabled, the mount is not made
|
||||
// recursively read-only. If this field is set to IfPossible, the mount is made
|
||||
// recursively read-only, if it is supported by the container runtime. If this
|
||||
// field is set to Enabled, the mount is made recursively read-only if it is
|
||||
// supported by the container runtime, otherwise the pod will not be started and
|
||||
// an error will be generated to indicate the reason.
|
||||
//
|
||||
// If this field is set to IfPossible or Enabled, MountPropagation must be set to
|
||||
// None (or be unspecified, which defaults to None).
|
||||
//
|
||||
// If this field is not specified, it is treated as an equivalent of Disabled.
|
||||
//
|
||||
// +featureGate=RecursiveReadOnlyMounts
|
||||
// +optional
|
||||
RecursiveReadOnly *RecursiveReadOnlyMode
|
||||
// Required. If the path is not an absolute path (e.g. some/path) it
|
||||
// will be prepended with the appropriate root prefix for the operating
|
||||
// system. On Linux this is '/', on Windows this is 'C:\'.
|
||||
@ -2023,6 +2043,8 @@ type VolumeMount struct {
|
||||
// to container and the other way around.
|
||||
// When not set, MountPropagationNone is used.
|
||||
// This field is beta in 1.10.
|
||||
// When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified
|
||||
// (which defaults to None).
|
||||
// +optional
|
||||
MountPropagation *MountPropagationMode
|
||||
// Expanded path within the volume from which the container's volume should be mounted.
|
||||
@ -2058,6 +2080,18 @@ const (
|
||||
MountPropagationBidirectional MountPropagationMode = "Bidirectional"
|
||||
)
|
||||
|
||||
// RecursiveReadOnlyMode describes recursive-readonly mode.
|
||||
type RecursiveReadOnlyMode string
|
||||
|
||||
const (
|
||||
// RecursiveReadOnlyDisabled disables recursive-readonly mode.
|
||||
RecursiveReadOnlyDisabled RecursiveReadOnlyMode = "Disabled"
|
||||
// RecursiveReadOnlyIfPossible enables recursive-readonly mode if possible.
|
||||
RecursiveReadOnlyIfPossible RecursiveReadOnlyMode = "IfPossible"
|
||||
// RecursiveReadOnlyEnabled enables recursive-readonly mode, or raise an error.
|
||||
RecursiveReadOnlyEnabled RecursiveReadOnlyMode = "Enabled"
|
||||
)
|
||||
|
||||
// VolumeDevice describes a mapping of a raw block device within a container.
|
||||
type VolumeDevice struct {
|
||||
// name must match the name of a persistentVolumeClaim in the pod
|
||||
@ -2068,7 +2102,11 @@ type VolumeDevice struct {
|
||||
|
||||
// EnvVar represents an environment variable present in a Container.
|
||||
type EnvVar struct {
|
||||
// Required: This must be a C_IDENTIFIER.
|
||||
// Required: Name of the environment variable.
|
||||
// When the RelaxedEnvironmentVariableValidation feature gate is disabled, this must consist of alphabetic characters,
|
||||
// digits, '_', '-', or '.', and must not start with a digit.
|
||||
// When the RelaxedEnvironmentVariableValidation feature gate is enabled,
|
||||
// this may contain any printable ASCII characters except '='.
|
||||
Name string
|
||||
// Optional: no more than one of the following may be specified.
|
||||
// Optional: Defaults to ""; variable references $(VAR_NAME) are expanded
|
||||
@ -2698,6 +2736,11 @@ type ContainerStatus struct {
|
||||
// +featureGate=InPlacePodVerticalScaling
|
||||
// +optional
|
||||
Resources *ResourceRequirements
|
||||
// Status of volume mounts.
|
||||
// +listType=atomic
|
||||
// +optional
|
||||
// +featureGate=RecursiveReadOnlyMounts
|
||||
VolumeMounts []VolumeMountStatus
|
||||
}
|
||||
|
||||
// PodPhase is a label for the condition of a pod at the current time.
|
||||
@ -2771,6 +2814,23 @@ const (
|
||||
PodResizeStatusInfeasible PodResizeStatus = "Infeasible"
|
||||
)
|
||||
|
||||
// VolumeMountStatus shows status of volume mounts.
|
||||
type VolumeMountStatus struct {
|
||||
// Name corresponds to the name of the original VolumeMount.
|
||||
Name string
|
||||
// MountPath corresponds to the original VolumeMount.
|
||||
MountPath string
|
||||
// ReadOnly corresponds to the original VolumeMount.
|
||||
// +optional
|
||||
ReadOnly bool
|
||||
// RecursiveReadOnly must be set to Disabled, Enabled, or unspecified (for non-readonly mounts).
|
||||
// An IfPossible value in the original VolumeMount must be translated to Disabled or Enabled,
|
||||
// depending on the mount result.
|
||||
// +featureGate=RecursiveReadOnlyMounts
|
||||
// +optional
|
||||
RecursiveReadOnly *RecursiveReadOnlyMode
|
||||
}
|
||||
|
||||
// RestartPolicy describes how the container should be restarted.
|
||||
// Only one of the following restart policies may be specified.
|
||||
// If none of the following policies is specified, the default one
|
||||
@ -3255,7 +3315,7 @@ type PodSpec struct {
|
||||
// +optional
|
||||
Tolerations []Toleration
|
||||
// HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts
|
||||
// file if specified. This is only valid for non-hostNetwork pods.
|
||||
// file if specified.
|
||||
// +optional
|
||||
HostAliases []HostAlias
|
||||
// If specified, indicates the pod's priority. "system-node-critical" and
|
||||
@ -3325,6 +3385,7 @@ type PodSpec struct {
|
||||
// - spec.hostPID
|
||||
// - spec.hostIPC
|
||||
// - spec.hostUsers
|
||||
// - spec.securityContext.appArmorProfile
|
||||
// - spec.securityContext.seLinuxOptions
|
||||
// - spec.securityContext.seccompProfile
|
||||
// - spec.securityContext.fsGroup
|
||||
@ -3334,6 +3395,7 @@ type PodSpec struct {
|
||||
// - spec.securityContext.runAsUser
|
||||
// - spec.securityContext.runAsGroup
|
||||
// - spec.securityContext.supplementalGroups
|
||||
// - spec.containers[*].securityContext.appArmorProfile
|
||||
// - spec.containers[*].securityContext.seLinuxOptions
|
||||
// - spec.containers[*].securityContext.seccompProfile
|
||||
// - spec.containers[*].securityContext.capabilities
|
||||
@ -3352,9 +3414,6 @@ type PodSpec struct {
|
||||
//
|
||||
// SchedulingGates can only be set at pod creation time, and be removed only afterwards.
|
||||
//
|
||||
// This is a beta feature enabled by the PodSchedulingReadiness feature gate.
|
||||
//
|
||||
// +featureGate=PodSchedulingReadiness
|
||||
// +optional
|
||||
SchedulingGates []PodSchedulingGate
|
||||
// ResourceClaims defines which ResourceClaims must be allocated
|
||||
@ -3601,6 +3660,10 @@ type PodSecurityContext struct {
|
||||
// Note that this field cannot be set when spec.os.name is windows.
|
||||
// +optional
|
||||
SeccompProfile *SeccompProfile
|
||||
// appArmorProfile is the AppArmor options to use by the containers in this pod.
|
||||
// Note that this field cannot be set when spec.os.name is windows.
|
||||
// +optional
|
||||
AppArmorProfile *AppArmorProfile
|
||||
}
|
||||
|
||||
// SeccompProfile defines a pod/container's seccomp profile settings.
|
||||
@ -3628,6 +3691,38 @@ const (
|
||||
SeccompProfileTypeLocalhost SeccompProfileType = "Localhost"
|
||||
)
|
||||
|
||||
// AppArmorProfile defines a pod or container's AppArmor settings.
|
||||
// +union
|
||||
type AppArmorProfile struct {
|
||||
// type indicates which kind of AppArmor profile will be applied.
|
||||
// Valid options are:
|
||||
// Localhost - a profile pre-loaded on the node.
|
||||
// RuntimeDefault - the container runtime's default profile.
|
||||
// Unconfined - no AppArmor enforcement.
|
||||
// +unionDescriminator
|
||||
Type AppArmorProfileType
|
||||
|
||||
// localhostProfile indicates a profile loaded on the node that should be used.
|
||||
// The profile must be preconfigured on the node to work.
|
||||
// Must match the loaded name of the profile.
|
||||
// Must be set if and only if type is "Localhost".
|
||||
// +optional
|
||||
LocalhostProfile *string
|
||||
}
|
||||
|
||||
// +enum
|
||||
type AppArmorProfileType string
|
||||
|
||||
const (
|
||||
// AppArmorProfileTypeUnconfined indicates that no AppArmor profile should be enforced.
|
||||
AppArmorProfileTypeUnconfined AppArmorProfileType = "Unconfined"
|
||||
// AppArmorProfileTypeRuntimeDefault indicates that the container runtime's default AppArmor
|
||||
// profile should be used.
|
||||
AppArmorProfileTypeRuntimeDefault AppArmorProfileType = "RuntimeDefault"
|
||||
// AppArmorProfileTypeLocalhost indicates that a profile pre-loaded on the node should be used.
|
||||
AppArmorProfileTypeLocalhost AppArmorProfileType = "Localhost"
|
||||
)
|
||||
|
||||
// PodQOSClass defines the supported qos classes of Pods.
|
||||
type PodQOSClass string
|
||||
|
||||
@ -4166,6 +4261,18 @@ const (
|
||||
ServiceExternalTrafficPolicyLocal ServiceExternalTrafficPolicy = "Local"
|
||||
)
|
||||
|
||||
// These are valid values for the TrafficDistribution field of a Service.
|
||||
const (
|
||||
// Indicates a preference for routing traffic to endpoints that are
|
||||
// topologically proximate to the client. The interpretation of "topologically
|
||||
// proximate" may vary across implementations and could encompass endpoints
|
||||
// within the same node, rack, zone, or even region. Setting this value gives
|
||||
// implementations permission to make different tradeoffs, e.g. optimizing for
|
||||
// proximity rather than equal distribution of load. Users should not set this
|
||||
// value if such tradeoffs are not acceptable.
|
||||
ServiceTrafficDistributionPreferClose = "PreferClose"
|
||||
)
|
||||
|
||||
// These are the valid conditions of a service.
|
||||
const (
|
||||
// LoadBalancerPortsError represents the condition of the requested ports
|
||||
@ -4429,6 +4536,15 @@ type ServiceSpec struct {
|
||||
// (possibly modified by topology and other features).
|
||||
// +optional
|
||||
InternalTrafficPolicy *ServiceInternalTrafficPolicy
|
||||
|
||||
// TrafficDistribution offers a way to express preferences for how traffic is
|
||||
// distributed to Service endpoints. Implementations can use this field as a
|
||||
// hint, but are not required to guarantee strict adherence. If the field is
|
||||
// not set, the implementation will apply its default routing strategy. If set
|
||||
// to "PreferClose", implementations should prioritize endpoints that are
|
||||
// topologically close (e.g., same zone).
|
||||
// +optional
|
||||
TrafficDistribution *string
|
||||
}
|
||||
|
||||
// ServicePort represents the port on which the service is exposed
|
||||
@ -4717,6 +4833,26 @@ type NodeDaemonEndpoints struct {
|
||||
KubeletEndpoint DaemonEndpoint
|
||||
}
|
||||
|
||||
// NodeRuntimeHandlerFeatures is a set of runtime features.
|
||||
type NodeRuntimeHandlerFeatures struct {
|
||||
// RecursiveReadOnlyMounts is set to true if the runtime handler supports RecursiveReadOnlyMounts.
|
||||
// +featureGate=RecursiveReadOnlyMounts
|
||||
// +optional
|
||||
RecursiveReadOnlyMounts *bool
|
||||
// Reserved: UserNamespaces *bool
|
||||
}
|
||||
|
||||
// NodeRuntimeHandler is a set of runtime handler information.
|
||||
type NodeRuntimeHandler struct {
|
||||
// Runtime handler name.
|
||||
// Empty for the default runtime handler.
|
||||
// +optional
|
||||
Name string
|
||||
// Supported features.
|
||||
// +optional
|
||||
Features *NodeRuntimeHandlerFeatures
|
||||
}
|
||||
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
|
||||
type NodeSystemInfo struct {
|
||||
// MachineID reported by the node. For unique machine identification
|
||||
@ -4827,6 +4963,10 @@ type NodeStatus struct {
|
||||
// Status of the config assigned to the node via the dynamic Kubelet config feature.
|
||||
// +optional
|
||||
Config *NodeConfigStatus
|
||||
// The available runtime handlers.
|
||||
// +featureGate=RecursiveReadOnlyMounts
|
||||
// +optional
|
||||
RuntimeHandlers []NodeRuntimeHandler
|
||||
}
|
||||
|
||||
// UniqueVolumeName defines the name of attached volume
|
||||
@ -4900,9 +5040,8 @@ const (
|
||||
// NodeConditionType defines node's condition
|
||||
type NodeConditionType string
|
||||
|
||||
// These are valid conditions of node. Currently, we don't have enough information to decide
|
||||
// node condition. In the future, we will add more. The proposed set of conditions are:
|
||||
// NodeReady, NodeReachable
|
||||
// These are valid but not exhaustive conditions of node. A cloud provider may set a condition not listed here.
|
||||
// Relevant events contain "NodeReady", "NodeNotReady", "NodeSchedulable", and "NodeNotSchedulable".
|
||||
const (
|
||||
// NodeReady means kubelet is healthy and ready to accept pods.
|
||||
NodeReady NodeConditionType = "Ready"
|
||||
@ -4979,14 +5118,6 @@ type NodeAddress struct {
|
||||
Address string
|
||||
}
|
||||
|
||||
// NodeResources is an object for conveying resource information about a node.
|
||||
// see https://kubernetes.io/docs/concepts/architecture/nodes/#capacity for more details.
|
||||
type NodeResources struct {
|
||||
// Capacity represents the available resources of a node
|
||||
// +optional
|
||||
Capacity ResourceList
|
||||
}
|
||||
|
||||
// ResourceName is the name identifying various resources in a ResourceList.
|
||||
type ResourceName string
|
||||
|
||||
@ -5003,7 +5134,6 @@ const (
|
||||
// Volume size, in bytes (e,g. 5Gi = 5GiB = 5 * 1024 * 1024 * 1024)
|
||||
ResourceStorage ResourceName = "storage"
|
||||
// Local ephemeral storage, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
|
||||
// The resource name for ResourceEphemeralStorage is alpha and it can change across releases.
|
||||
ResourceEphemeralStorage ResourceName = "ephemeral-storage"
|
||||
)
|
||||
|
||||
@ -6020,6 +6150,11 @@ type SecurityContext struct {
|
||||
// Note that this field cannot be set when spec.os.name is windows.
|
||||
// +optional
|
||||
SeccompProfile *SeccompProfile
|
||||
// appArmorProfile is the AppArmor options to use by this container. If set, this profile
|
||||
// overrides the pod's appArmorProfile.
|
||||
// Note that this field cannot be set when spec.os.name is windows.
|
||||
// +optional
|
||||
AppArmorProfile *AppArmorProfile
|
||||
}
|
||||
|
||||
// ProcMountType defines the type of proc mount
|
||||
@ -6221,8 +6356,6 @@ type TopologySpreadConstraint struct {
|
||||
// In this situation, new pod with the same labelSelector cannot be scheduled,
|
||||
// because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones,
|
||||
// it will violate MaxSkew.
|
||||
//
|
||||
// This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default).
|
||||
// +optional
|
||||
MinDomains *int32
|
||||
// NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector
|
||||
|
140
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
140
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
@ -62,6 +62,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.AppArmorProfile)(nil), (*core.AppArmorProfile)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_AppArmorProfile_To_core_AppArmorProfile(a.(*v1.AppArmorProfile), b.(*core.AppArmorProfile), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*core.AppArmorProfile)(nil), (*v1.AppArmorProfile)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_core_AppArmorProfile_To_v1_AppArmorProfile(a.(*core.AppArmorProfile), b.(*v1.AppArmorProfile), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.AttachedVolume)(nil), (*core.AttachedVolume)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_AttachedVolume_To_core_AttachedVolume(a.(*v1.AttachedVolume), b.(*core.AttachedVolume), scope)
|
||||
}); err != nil {
|
||||
@ -1052,13 +1062,23 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.NodeResources)(nil), (*core.NodeResources)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_NodeResources_To_core_NodeResources(a.(*v1.NodeResources), b.(*core.NodeResources), scope)
|
||||
if err := s.AddGeneratedConversionFunc((*v1.NodeRuntimeHandler)(nil), (*core.NodeRuntimeHandler)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_NodeRuntimeHandler_To_core_NodeRuntimeHandler(a.(*v1.NodeRuntimeHandler), b.(*core.NodeRuntimeHandler), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*core.NodeResources)(nil), (*v1.NodeResources)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_core_NodeResources_To_v1_NodeResources(a.(*core.NodeResources), b.(*v1.NodeResources), scope)
|
||||
if err := s.AddGeneratedConversionFunc((*core.NodeRuntimeHandler)(nil), (*v1.NodeRuntimeHandler)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_core_NodeRuntimeHandler_To_v1_NodeRuntimeHandler(a.(*core.NodeRuntimeHandler), b.(*v1.NodeRuntimeHandler), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.NodeRuntimeHandlerFeatures)(nil), (*core.NodeRuntimeHandlerFeatures)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_NodeRuntimeHandlerFeatures_To_core_NodeRuntimeHandlerFeatures(a.(*v1.NodeRuntimeHandlerFeatures), b.(*core.NodeRuntimeHandlerFeatures), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*core.NodeRuntimeHandlerFeatures)(nil), (*v1.NodeRuntimeHandlerFeatures)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_core_NodeRuntimeHandlerFeatures_To_v1_NodeRuntimeHandlerFeatures(a.(*core.NodeRuntimeHandlerFeatures), b.(*v1.NodeRuntimeHandlerFeatures), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2097,6 +2117,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.VolumeMountStatus)(nil), (*core.VolumeMountStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_VolumeMountStatus_To_core_VolumeMountStatus(a.(*v1.VolumeMountStatus), b.(*core.VolumeMountStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*core.VolumeMountStatus)(nil), (*v1.VolumeMountStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_core_VolumeMountStatus_To_v1_VolumeMountStatus(a.(*core.VolumeMountStatus), b.(*v1.VolumeMountStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.VolumeNodeAffinity)(nil), (*core.VolumeNodeAffinity)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_VolumeNodeAffinity_To_core_VolumeNodeAffinity(a.(*v1.VolumeNodeAffinity), b.(*core.VolumeNodeAffinity), scope)
|
||||
}); err != nil {
|
||||
@ -2385,6 +2415,28 @@ func Convert_core_Affinity_To_v1_Affinity(in *core.Affinity, out *v1.Affinity, s
|
||||
return autoConvert_core_Affinity_To_v1_Affinity(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_AppArmorProfile_To_core_AppArmorProfile(in *v1.AppArmorProfile, out *core.AppArmorProfile, s conversion.Scope) error {
|
||||
out.Type = core.AppArmorProfileType(in.Type)
|
||||
out.LocalhostProfile = (*string)(unsafe.Pointer(in.LocalhostProfile))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_AppArmorProfile_To_core_AppArmorProfile is an autogenerated conversion function.
|
||||
func Convert_v1_AppArmorProfile_To_core_AppArmorProfile(in *v1.AppArmorProfile, out *core.AppArmorProfile, s conversion.Scope) error {
|
||||
return autoConvert_v1_AppArmorProfile_To_core_AppArmorProfile(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_AppArmorProfile_To_v1_AppArmorProfile(in *core.AppArmorProfile, out *v1.AppArmorProfile, s conversion.Scope) error {
|
||||
out.Type = v1.AppArmorProfileType(in.Type)
|
||||
out.LocalhostProfile = (*string)(unsafe.Pointer(in.LocalhostProfile))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_core_AppArmorProfile_To_v1_AppArmorProfile is an autogenerated conversion function.
|
||||
func Convert_core_AppArmorProfile_To_v1_AppArmorProfile(in *core.AppArmorProfile, out *v1.AppArmorProfile, s conversion.Scope) error {
|
||||
return autoConvert_core_AppArmorProfile_To_v1_AppArmorProfile(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_AttachedVolume_To_core_AttachedVolume(in *v1.AttachedVolume, out *core.AttachedVolume, s conversion.Scope) error {
|
||||
out.Name = core.UniqueVolumeName(in.Name)
|
||||
out.DevicePath = in.DevicePath
|
||||
@ -3317,6 +3369,7 @@ func autoConvert_v1_ContainerStatus_To_core_ContainerStatus(in *v1.ContainerStat
|
||||
out.Started = (*bool)(unsafe.Pointer(in.Started))
|
||||
out.AllocatedResources = *(*core.ResourceList)(unsafe.Pointer(&in.AllocatedResources))
|
||||
out.Resources = (*core.ResourceRequirements)(unsafe.Pointer(in.Resources))
|
||||
out.VolumeMounts = *(*[]core.VolumeMountStatus)(unsafe.Pointer(&in.VolumeMounts))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3341,6 +3394,7 @@ func autoConvert_core_ContainerStatus_To_v1_ContainerStatus(in *core.ContainerSt
|
||||
out.Started = (*bool)(unsafe.Pointer(in.Started))
|
||||
out.AllocatedResources = *(*v1.ResourceList)(unsafe.Pointer(&in.AllocatedResources))
|
||||
out.Resources = (*v1.ResourceRequirements)(unsafe.Pointer(in.Resources))
|
||||
out.VolumeMounts = *(*[]v1.VolumeMountStatus)(unsafe.Pointer(&in.VolumeMounts))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -5049,24 +5103,46 @@ func Convert_url_Values_To_v1_NodeProxyOptions(in *url.Values, out *v1.NodeProxy
|
||||
return autoConvert_url_Values_To_v1_NodeProxyOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_NodeResources_To_core_NodeResources(in *v1.NodeResources, out *core.NodeResources, s conversion.Scope) error {
|
||||
out.Capacity = *(*core.ResourceList)(unsafe.Pointer(&in.Capacity))
|
||||
func autoConvert_v1_NodeRuntimeHandler_To_core_NodeRuntimeHandler(in *v1.NodeRuntimeHandler, out *core.NodeRuntimeHandler, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.Features = (*core.NodeRuntimeHandlerFeatures)(unsafe.Pointer(in.Features))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_NodeResources_To_core_NodeResources is an autogenerated conversion function.
|
||||
func Convert_v1_NodeResources_To_core_NodeResources(in *v1.NodeResources, out *core.NodeResources, s conversion.Scope) error {
|
||||
return autoConvert_v1_NodeResources_To_core_NodeResources(in, out, s)
|
||||
// Convert_v1_NodeRuntimeHandler_To_core_NodeRuntimeHandler is an autogenerated conversion function.
|
||||
func Convert_v1_NodeRuntimeHandler_To_core_NodeRuntimeHandler(in *v1.NodeRuntimeHandler, out *core.NodeRuntimeHandler, s conversion.Scope) error {
|
||||
return autoConvert_v1_NodeRuntimeHandler_To_core_NodeRuntimeHandler(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_NodeResources_To_v1_NodeResources(in *core.NodeResources, out *v1.NodeResources, s conversion.Scope) error {
|
||||
out.Capacity = *(*v1.ResourceList)(unsafe.Pointer(&in.Capacity))
|
||||
func autoConvert_core_NodeRuntimeHandler_To_v1_NodeRuntimeHandler(in *core.NodeRuntimeHandler, out *v1.NodeRuntimeHandler, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.Features = (*v1.NodeRuntimeHandlerFeatures)(unsafe.Pointer(in.Features))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_core_NodeResources_To_v1_NodeResources is an autogenerated conversion function.
|
||||
func Convert_core_NodeResources_To_v1_NodeResources(in *core.NodeResources, out *v1.NodeResources, s conversion.Scope) error {
|
||||
return autoConvert_core_NodeResources_To_v1_NodeResources(in, out, s)
|
||||
// Convert_core_NodeRuntimeHandler_To_v1_NodeRuntimeHandler is an autogenerated conversion function.
|
||||
func Convert_core_NodeRuntimeHandler_To_v1_NodeRuntimeHandler(in *core.NodeRuntimeHandler, out *v1.NodeRuntimeHandler, s conversion.Scope) error {
|
||||
return autoConvert_core_NodeRuntimeHandler_To_v1_NodeRuntimeHandler(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_NodeRuntimeHandlerFeatures_To_core_NodeRuntimeHandlerFeatures(in *v1.NodeRuntimeHandlerFeatures, out *core.NodeRuntimeHandlerFeatures, s conversion.Scope) error {
|
||||
out.RecursiveReadOnlyMounts = (*bool)(unsafe.Pointer(in.RecursiveReadOnlyMounts))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_NodeRuntimeHandlerFeatures_To_core_NodeRuntimeHandlerFeatures is an autogenerated conversion function.
|
||||
func Convert_v1_NodeRuntimeHandlerFeatures_To_core_NodeRuntimeHandlerFeatures(in *v1.NodeRuntimeHandlerFeatures, out *core.NodeRuntimeHandlerFeatures, s conversion.Scope) error {
|
||||
return autoConvert_v1_NodeRuntimeHandlerFeatures_To_core_NodeRuntimeHandlerFeatures(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_NodeRuntimeHandlerFeatures_To_v1_NodeRuntimeHandlerFeatures(in *core.NodeRuntimeHandlerFeatures, out *v1.NodeRuntimeHandlerFeatures, s conversion.Scope) error {
|
||||
out.RecursiveReadOnlyMounts = (*bool)(unsafe.Pointer(in.RecursiveReadOnlyMounts))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_core_NodeRuntimeHandlerFeatures_To_v1_NodeRuntimeHandlerFeatures is an autogenerated conversion function.
|
||||
func Convert_core_NodeRuntimeHandlerFeatures_To_v1_NodeRuntimeHandlerFeatures(in *core.NodeRuntimeHandlerFeatures, out *v1.NodeRuntimeHandlerFeatures, s conversion.Scope) error {
|
||||
return autoConvert_core_NodeRuntimeHandlerFeatures_To_v1_NodeRuntimeHandlerFeatures(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_NodeSelector_To_core_NodeSelector(in *v1.NodeSelector, out *core.NodeSelector, s conversion.Scope) error {
|
||||
@ -5172,6 +5248,7 @@ func autoConvert_v1_NodeStatus_To_core_NodeStatus(in *v1.NodeStatus, out *core.N
|
||||
out.VolumesInUse = *(*[]core.UniqueVolumeName)(unsafe.Pointer(&in.VolumesInUse))
|
||||
out.VolumesAttached = *(*[]core.AttachedVolume)(unsafe.Pointer(&in.VolumesAttached))
|
||||
out.Config = (*core.NodeConfigStatus)(unsafe.Pointer(in.Config))
|
||||
out.RuntimeHandlers = *(*[]core.NodeRuntimeHandler)(unsafe.Pointer(&in.RuntimeHandlers))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -5196,6 +5273,7 @@ func autoConvert_core_NodeStatus_To_v1_NodeStatus(in *core.NodeStatus, out *v1.N
|
||||
out.VolumesInUse = *(*[]v1.UniqueVolumeName)(unsafe.Pointer(&in.VolumesInUse))
|
||||
out.VolumesAttached = *(*[]v1.AttachedVolume)(unsafe.Pointer(&in.VolumesAttached))
|
||||
out.Config = (*v1.NodeConfigStatus)(unsafe.Pointer(in.Config))
|
||||
out.RuntimeHandlers = *(*[]v1.NodeRuntimeHandler)(unsafe.Pointer(&in.RuntimeHandlers))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -6412,6 +6490,7 @@ func autoConvert_v1_PodSecurityContext_To_core_PodSecurityContext(in *v1.PodSecu
|
||||
out.Sysctls = *(*[]core.Sysctl)(unsafe.Pointer(&in.Sysctls))
|
||||
out.FSGroupChangePolicy = (*core.PodFSGroupChangePolicy)(unsafe.Pointer(in.FSGroupChangePolicy))
|
||||
out.SeccompProfile = (*core.SeccompProfile)(unsafe.Pointer(in.SeccompProfile))
|
||||
out.AppArmorProfile = (*core.AppArmorProfile)(unsafe.Pointer(in.AppArmorProfile))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -6436,6 +6515,7 @@ func autoConvert_core_PodSecurityContext_To_v1_PodSecurityContext(in *core.PodSe
|
||||
out.FSGroupChangePolicy = (*v1.PodFSGroupChangePolicy)(unsafe.Pointer(in.FSGroupChangePolicy))
|
||||
out.Sysctls = *(*[]v1.Sysctl)(unsafe.Pointer(&in.Sysctls))
|
||||
out.SeccompProfile = (*v1.SeccompProfile)(unsafe.Pointer(in.SeccompProfile))
|
||||
out.AppArmorProfile = (*v1.AppArmorProfile)(unsafe.Pointer(in.AppArmorProfile))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -7789,6 +7869,7 @@ func autoConvert_v1_SecurityContext_To_core_SecurityContext(in *v1.SecurityConte
|
||||
out.AllowPrivilegeEscalation = (*bool)(unsafe.Pointer(in.AllowPrivilegeEscalation))
|
||||
out.ProcMount = (*core.ProcMountType)(unsafe.Pointer(in.ProcMount))
|
||||
out.SeccompProfile = (*core.SeccompProfile)(unsafe.Pointer(in.SeccompProfile))
|
||||
out.AppArmorProfile = (*core.AppArmorProfile)(unsafe.Pointer(in.AppArmorProfile))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -7809,6 +7890,7 @@ func autoConvert_core_SecurityContext_To_v1_SecurityContext(in *core.SecurityCon
|
||||
out.AllowPrivilegeEscalation = (*bool)(unsafe.Pointer(in.AllowPrivilegeEscalation))
|
||||
out.ProcMount = (*v1.ProcMountType)(unsafe.Pointer(in.ProcMount))
|
||||
out.SeccompProfile = (*v1.SeccompProfile)(unsafe.Pointer(in.SeccompProfile))
|
||||
out.AppArmorProfile = (*v1.AppArmorProfile)(unsafe.Pointer(in.AppArmorProfile))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -8079,6 +8161,7 @@ func autoConvert_v1_ServiceSpec_To_core_ServiceSpec(in *v1.ServiceSpec, out *cor
|
||||
out.AllocateLoadBalancerNodePorts = (*bool)(unsafe.Pointer(in.AllocateLoadBalancerNodePorts))
|
||||
out.LoadBalancerClass = (*string)(unsafe.Pointer(in.LoadBalancerClass))
|
||||
out.InternalTrafficPolicy = (*core.ServiceInternalTrafficPolicy)(unsafe.Pointer(in.InternalTrafficPolicy))
|
||||
out.TrafficDistribution = (*string)(unsafe.Pointer(in.TrafficDistribution))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -8107,6 +8190,7 @@ func autoConvert_core_ServiceSpec_To_v1_ServiceSpec(in *core.ServiceSpec, out *v
|
||||
out.AllocateLoadBalancerNodePorts = (*bool)(unsafe.Pointer(in.AllocateLoadBalancerNodePorts))
|
||||
out.LoadBalancerClass = (*string)(unsafe.Pointer(in.LoadBalancerClass))
|
||||
out.InternalTrafficPolicy = (*v1.ServiceInternalTrafficPolicy)(unsafe.Pointer(in.InternalTrafficPolicy))
|
||||
out.TrafficDistribution = (*string)(unsafe.Pointer(in.TrafficDistribution))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -8502,6 +8586,7 @@ func Convert_core_VolumeDevice_To_v1_VolumeDevice(in *core.VolumeDevice, out *v1
|
||||
func autoConvert_v1_VolumeMount_To_core_VolumeMount(in *v1.VolumeMount, out *core.VolumeMount, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.RecursiveReadOnly = (*core.RecursiveReadOnlyMode)(unsafe.Pointer(in.RecursiveReadOnly))
|
||||
out.MountPath = in.MountPath
|
||||
out.SubPath = in.SubPath
|
||||
out.MountPropagation = (*core.MountPropagationMode)(unsafe.Pointer(in.MountPropagation))
|
||||
@ -8517,6 +8602,7 @@ func Convert_v1_VolumeMount_To_core_VolumeMount(in *v1.VolumeMount, out *core.Vo
|
||||
func autoConvert_core_VolumeMount_To_v1_VolumeMount(in *core.VolumeMount, out *v1.VolumeMount, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.RecursiveReadOnly = (*v1.RecursiveReadOnlyMode)(unsafe.Pointer(in.RecursiveReadOnly))
|
||||
out.MountPath = in.MountPath
|
||||
out.SubPath = in.SubPath
|
||||
out.MountPropagation = (*v1.MountPropagationMode)(unsafe.Pointer(in.MountPropagation))
|
||||
@ -8529,6 +8615,32 @@ func Convert_core_VolumeMount_To_v1_VolumeMount(in *core.VolumeMount, out *v1.Vo
|
||||
return autoConvert_core_VolumeMount_To_v1_VolumeMount(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_VolumeMountStatus_To_core_VolumeMountStatus(in *v1.VolumeMountStatus, out *core.VolumeMountStatus, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.MountPath = in.MountPath
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.RecursiveReadOnly = (*core.RecursiveReadOnlyMode)(unsafe.Pointer(in.RecursiveReadOnly))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_VolumeMountStatus_To_core_VolumeMountStatus is an autogenerated conversion function.
|
||||
func Convert_v1_VolumeMountStatus_To_core_VolumeMountStatus(in *v1.VolumeMountStatus, out *core.VolumeMountStatus, s conversion.Scope) error {
|
||||
return autoConvert_v1_VolumeMountStatus_To_core_VolumeMountStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_VolumeMountStatus_To_v1_VolumeMountStatus(in *core.VolumeMountStatus, out *v1.VolumeMountStatus, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.MountPath = in.MountPath
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.RecursiveReadOnly = (*v1.RecursiveReadOnlyMode)(unsafe.Pointer(in.RecursiveReadOnly))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_core_VolumeMountStatus_To_v1_VolumeMountStatus is an autogenerated conversion function.
|
||||
func Convert_core_VolumeMountStatus_To_v1_VolumeMountStatus(in *core.VolumeMountStatus, out *v1.VolumeMountStatus, s conversion.Scope) error {
|
||||
return autoConvert_core_VolumeMountStatus_To_v1_VolumeMountStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_VolumeNodeAffinity_To_core_VolumeNodeAffinity(in *v1.VolumeNodeAffinity, out *core.VolumeNodeAffinity, s conversion.Scope) error {
|
||||
out.Required = (*core.NodeSelector)(unsafe.Pointer(in.Required))
|
||||
return nil
|
||||
|
333
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
333
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
@ -204,7 +204,7 @@ func ValidatePodSpecificAnnotationUpdates(newPod, oldPod *core.Pod, fldPath *fie
|
||||
if newVal, exists := newAnnotations[k]; exists && newVal == oldVal {
|
||||
continue // No change.
|
||||
}
|
||||
if strings.HasPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
|
||||
if strings.HasPrefix(k, v1.DeprecatedAppArmorBetaContainerAnnotationKeyPrefix) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "may not remove or update AppArmor annotations"))
|
||||
}
|
||||
if k == core.MirrorPodAnnotationKey {
|
||||
@ -216,7 +216,7 @@ func ValidatePodSpecificAnnotationUpdates(newPod, oldPod *core.Pod, fldPath *fie
|
||||
if _, ok := oldAnnotations[k]; ok {
|
||||
continue // No change.
|
||||
}
|
||||
if strings.HasPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
|
||||
if strings.HasPrefix(k, v1.DeprecatedAppArmorBetaContainerAnnotationKeyPrefix) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "may not add AppArmor annotations"))
|
||||
}
|
||||
if k == core.MirrorPodAnnotationKey {
|
||||
@ -942,7 +942,7 @@ func validateKeyToPath(kp *core.KeyToPath, fldPath *field.Path) field.ErrorList
|
||||
if len(kp.Path) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("path"), ""))
|
||||
}
|
||||
allErrs = append(allErrs, validateLocalNonReservedPath(kp.Path, fldPath.Child("path"))...)
|
||||
allErrs = append(allErrs, ValidateLocalNonReservedPath(kp.Path, fldPath.Child("path"))...)
|
||||
if kp.Mode != nil && (*kp.Mode > 0777 || *kp.Mode < 0) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("mode"), *kp.Mode, fileModeErrorMsg))
|
||||
}
|
||||
@ -1050,7 +1050,7 @@ func validateDownwardAPIVolumeFile(file *core.DownwardAPIVolumeFile, fldPath *fi
|
||||
if len(file.Path) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("path"), ""))
|
||||
}
|
||||
allErrs = append(allErrs, validateLocalNonReservedPath(file.Path, fldPath.Child("path"))...)
|
||||
allErrs = append(allErrs, ValidateLocalNonReservedPath(file.Path, fldPath.Child("path"))...)
|
||||
if file.FieldRef != nil {
|
||||
allErrs = append(allErrs, validateObjectFieldSelector(file.FieldRef, &validVolumeDownwardAPIFieldPathExpressions, fldPath.Child("fieldRef"))...)
|
||||
if file.ResourceFieldRef != nil {
|
||||
@ -1153,6 +1153,8 @@ func validateProjectionSources(projection *core.ProjectedVolumeSource, projectio
|
||||
}
|
||||
if source.ServiceAccountToken.Path == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("path"), ""))
|
||||
} else if !opts.AllowNonLocalProjectedTokenPath {
|
||||
allErrs = append(allErrs, ValidateLocalNonReservedPath(source.ServiceAccountToken.Path, fldPath.Child("path"))...)
|
||||
}
|
||||
}
|
||||
if projPath := srcPath.Child("clusterTrustBundlePEM"); source.ClusterTrustBundle != nil {
|
||||
@ -1209,7 +1211,7 @@ func validateProjectionSources(projection *core.ProjectedVolumeSource, projectio
|
||||
allErrs = append(allErrs, field.Required(projPath.Child("path"), ""))
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, validateLocalNonReservedPath(source.ClusterTrustBundle.Path, projPath.Child("path"))...)
|
||||
allErrs = append(allErrs, ValidateLocalNonReservedPath(source.ClusterTrustBundle.Path, projPath.Child("path"))...)
|
||||
|
||||
curPath := source.ClusterTrustBundle.Path
|
||||
if !allPaths.Has(curPath) {
|
||||
@ -1319,11 +1321,37 @@ func validateMountPropagation(mountPropagation *core.MountPropagationMode, conta
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// This validate will make sure targetPath:
|
||||
// validateMountRecursiveReadOnly validates RecursiveReadOnly mounts.
|
||||
func validateMountRecursiveReadOnly(mount core.VolumeMount, fldPath *field.Path) field.ErrorList {
|
||||
if mount.RecursiveReadOnly == nil {
|
||||
return nil
|
||||
}
|
||||
allErrs := field.ErrorList{}
|
||||
switch *mount.RecursiveReadOnly {
|
||||
case core.RecursiveReadOnlyDisabled:
|
||||
// NOP
|
||||
case core.RecursiveReadOnlyEnabled, core.RecursiveReadOnlyIfPossible:
|
||||
if !mount.ReadOnly {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath, "may only be specified when readOnly is true"))
|
||||
}
|
||||
if mount.MountPropagation != nil && *mount.MountPropagation != core.MountPropagationNone {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath, "may only be specified when mountPropagation is None or not specified"))
|
||||
}
|
||||
default:
|
||||
supportedRRO := sets.New(
|
||||
core.RecursiveReadOnlyDisabled,
|
||||
core.RecursiveReadOnlyIfPossible,
|
||||
core.RecursiveReadOnlyEnabled)
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath, *mount.RecursiveReadOnly, sets.List(supportedRRO)))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateLocalNonReservedPath makes sure targetPath:
|
||||
// 1. is not abs path
|
||||
// 2. does not contain any '..' elements
|
||||
// 3. does not start with '..'
|
||||
func validateLocalNonReservedPath(targetPath string, fldPath *field.Path) field.ErrorList {
|
||||
func ValidateLocalNonReservedPath(targetPath string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, validateLocalDescendingPath(targetPath, fldPath)...)
|
||||
// Don't report this error if the check for .. elements already caught it.
|
||||
@ -2555,8 +2583,14 @@ func ValidateEnv(vars []core.EnvVar, fldPath *field.Path, opts PodValidationOpti
|
||||
if len(ev.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(idxPath.Child("name"), ""))
|
||||
} else {
|
||||
for _, msg := range validation.IsEnvVarName(ev.Name) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("name"), ev.Name, msg))
|
||||
if opts.AllowRelaxedEnvironmentVariableValidation {
|
||||
for _, msg := range validation.IsRelaxedEnvVarName(ev.Name) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("name"), ev.Name, msg))
|
||||
}
|
||||
} else {
|
||||
for _, msg := range validation.IsEnvVarName(ev.Name) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("name"), ev.Name, msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
allErrs = append(allErrs, validateEnvVarValueFrom(ev, idxPath.Child("valueFrom"), opts)...)
|
||||
@ -2701,13 +2735,19 @@ func validateContainerResourceFieldSelector(fs *core.ResourceFieldSelector, expr
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateEnvFrom(vars []core.EnvFromSource, fldPath *field.Path) field.ErrorList {
|
||||
func ValidateEnvFrom(vars []core.EnvFromSource, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for i, ev := range vars {
|
||||
idxPath := fldPath.Index(i)
|
||||
if len(ev.Prefix) > 0 {
|
||||
for _, msg := range validation.IsEnvVarName(ev.Prefix) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("prefix"), ev.Prefix, msg))
|
||||
if opts.AllowRelaxedEnvironmentVariableValidation {
|
||||
for _, msg := range validation.IsRelaxedEnvVarName(ev.Prefix) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("prefix"), ev.Prefix, msg))
|
||||
}
|
||||
} else {
|
||||
for _, msg := range validation.IsEnvVarName(ev.Prefix) {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("prefix"), ev.Prefix, msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2895,6 +2935,7 @@ func ValidateVolumeMounts(mounts []core.VolumeMount, voldevices map[string]strin
|
||||
if mnt.MountPropagation != nil {
|
||||
allErrs = append(allErrs, validateMountPropagation(mnt.MountPropagation, container, fldPath.Child("mountPropagation"))...)
|
||||
}
|
||||
allErrs = append(allErrs, validateMountRecursiveReadOnly(mnt, fldPath.Child("recursiveReadOnly"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
@ -3348,7 +3389,7 @@ func validateResizePolicy(policyList []core.ContainerResizePolicy, fldPath *fiel
|
||||
|
||||
// validateEphemeralContainers is called by pod spec and template validation to validate the list of ephemeral containers.
|
||||
// Note that this is called for pod template even though ephemeral containers aren't allowed in pod templates.
|
||||
func validateEphemeralContainers(ephemeralContainers []core.EphemeralContainer, containers, initContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy) field.ErrorList {
|
||||
func validateEphemeralContainers(ephemeralContainers []core.EphemeralContainer, containers, initContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy, hostUsers bool) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
if len(ephemeralContainers) == 0 {
|
||||
@ -3369,7 +3410,7 @@ func validateEphemeralContainers(ephemeralContainers []core.EphemeralContainer,
|
||||
idxPath := fldPath.Index(i)
|
||||
|
||||
c := (*core.Container)(&ec.EphemeralContainerCommon)
|
||||
allErrs = append(allErrs, validateContainerCommon(c, volumes, podClaimNames, idxPath, opts, podRestartPolicy)...)
|
||||
allErrs = append(allErrs, validateContainerCommon(c, volumes, podClaimNames, idxPath, opts, podRestartPolicy, hostUsers)...)
|
||||
// Ephemeral containers don't need looser constraints for pod templates, so it's convenient to apply both validations
|
||||
// here where we've already converted EphemeralContainerCommon to Container.
|
||||
allErrs = append(allErrs, validateContainerOnlyForPod(c, idxPath)...)
|
||||
@ -3431,7 +3472,7 @@ func validateFieldAllowList(value interface{}, allowedFields map[string]bool, er
|
||||
}
|
||||
|
||||
// validateInitContainers is called by pod spec and template validation to validate the list of init containers
|
||||
func validateInitContainers(containers []core.Container, regularContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], gracePeriod int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy) field.ErrorList {
|
||||
func validateInitContainers(containers []core.Container, regularContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], gracePeriod int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy, hostUsers bool) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
allNames := sets.Set[string]{}
|
||||
@ -3442,7 +3483,7 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
|
||||
idxPath := fldPath.Index(i)
|
||||
|
||||
// Apply the validation common to all container types
|
||||
allErrs = append(allErrs, validateContainerCommon(&ctr, volumes, podClaimNames, idxPath, opts, podRestartPolicy)...)
|
||||
allErrs = append(allErrs, validateContainerCommon(&ctr, volumes, podClaimNames, idxPath, opts, podRestartPolicy, hostUsers)...)
|
||||
|
||||
restartAlways := false
|
||||
// Apply the validation specific to init containers
|
||||
@ -3497,7 +3538,7 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
|
||||
|
||||
// validateContainerCommon applies validation common to all container types. It's called by regular, init, and ephemeral
|
||||
// container list validation to require a properly formatted name, image, etc.
|
||||
func validateContainerCommon(ctr *core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], path *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy) field.ErrorList {
|
||||
func validateContainerCommon(ctr *core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], path *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy, hostUsers bool) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
namePath := path.Child("name")
|
||||
@ -3530,13 +3571,13 @@ func validateContainerCommon(ctr *core.Container, volumes map[string]core.Volume
|
||||
volDevices := GetVolumeDeviceMap(ctr.VolumeDevices)
|
||||
allErrs = append(allErrs, validateContainerPorts(ctr.Ports, path.Child("ports"))...)
|
||||
allErrs = append(allErrs, ValidateEnv(ctr.Env, path.Child("env"), opts)...)
|
||||
allErrs = append(allErrs, ValidateEnvFrom(ctr.EnvFrom, path.Child("envFrom"))...)
|
||||
allErrs = append(allErrs, ValidateEnvFrom(ctr.EnvFrom, path.Child("envFrom"), opts)...)
|
||||
allErrs = append(allErrs, ValidateVolumeMounts(ctr.VolumeMounts, volDevices, volumes, ctr, path.Child("volumeMounts"))...)
|
||||
allErrs = append(allErrs, ValidateVolumeDevices(ctr.VolumeDevices, volMounts, volumes, path.Child("volumeDevices"))...)
|
||||
allErrs = append(allErrs, validatePullPolicy(ctr.ImagePullPolicy, path.Child("imagePullPolicy"))...)
|
||||
allErrs = append(allErrs, ValidateResourceRequirements(&ctr.Resources, podClaimNames, path.Child("resources"), opts)...)
|
||||
allErrs = append(allErrs, validateResizePolicy(ctr.ResizePolicy, path.Child("resizePolicy"), podRestartPolicy)...)
|
||||
allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, path.Child("securityContext"))...)
|
||||
allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, path.Child("securityContext"), hostUsers)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -3569,7 +3610,7 @@ func validateHostUsers(spec *core.PodSpec, fldPath *field.Path) field.ErrorList
|
||||
}
|
||||
|
||||
// validateContainers is called by pod spec and template validation to validate the list of regular containers.
|
||||
func validateContainers(containers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], gracePeriod int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy) field.ErrorList {
|
||||
func validateContainers(containers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], gracePeriod int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy, hostUsers bool) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if len(containers) == 0 {
|
||||
@ -3581,7 +3622,7 @@ func validateContainers(containers []core.Container, volumes map[string]core.Vol
|
||||
path := fldPath.Index(i)
|
||||
|
||||
// Apply validation common to all containers
|
||||
allErrs = append(allErrs, validateContainerCommon(&ctr, volumes, podClaimNames, path, opts, podRestartPolicy)...)
|
||||
allErrs = append(allErrs, validateContainerCommon(&ctr, volumes, podClaimNames, path, opts, podRestartPolicy, hostUsers)...)
|
||||
|
||||
// Container names must be unique within the list of regular containers.
|
||||
// Collisions with init or ephemeral container names will be detected by the init or ephemeral
|
||||
@ -3718,9 +3759,7 @@ func validatePodDNSConfig(dnsConfig *core.PodDNSConfig, dnsPolicy *core.DNSPolic
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("nameservers"), dnsConfig.Nameservers, fmt.Sprintf("must not have more than %v nameservers", MaxDNSNameservers)))
|
||||
}
|
||||
for i, ns := range dnsConfig.Nameservers {
|
||||
if ip := netutils.ParseIPSloppy(ns); ip == nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("nameservers").Index(i), ns, "must be valid IP address"))
|
||||
}
|
||||
allErrs = append(allErrs, validation.IsValidIP(fldPath.Child("nameservers").Index(i), ns)...)
|
||||
}
|
||||
// Validate searches.
|
||||
if len(dnsConfig.Searches) > MaxDNSSearchPaths {
|
||||
@ -3887,12 +3926,10 @@ func validateOnlyDeletedSchedulingGates(newGates, oldGates []core.PodSchedulingG
|
||||
|
||||
func ValidateHostAliases(hostAliases []core.HostAlias, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for _, hostAlias := range hostAliases {
|
||||
if ip := netutils.ParseIPSloppy(hostAlias.IP); ip == nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("ip"), hostAlias.IP, "must be valid IP address"))
|
||||
}
|
||||
for _, hostname := range hostAlias.Hostnames {
|
||||
allErrs = append(allErrs, ValidateDNS1123Subdomain(hostname, fldPath.Child("hostnames"))...)
|
||||
for i, hostAlias := range hostAliases {
|
||||
allErrs = append(allErrs, validation.IsValidIP(fldPath.Index(i).Child("ip"), hostAlias.IP)...)
|
||||
for j, hostname := range hostAlias.Hostnames {
|
||||
allErrs = append(allErrs, ValidateDNS1123Subdomain(hostname, fldPath.Index(i).Child("hostnames").Index(j))...)
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
@ -3976,13 +4013,15 @@ type PodValidationOptions struct {
|
||||
AllowHostIPsField bool
|
||||
// Allow invalid topologySpreadConstraint labelSelector for backward compatibility
|
||||
AllowInvalidTopologySpreadConstraintLabelSelector bool
|
||||
// Allow node selector additions for gated pods.
|
||||
AllowMutableNodeSelectorAndNodeAffinity bool
|
||||
// Allow projected token volumes with non-local paths
|
||||
AllowNonLocalProjectedTokenPath bool
|
||||
// Allow namespaced sysctls in hostNet and hostIPC pods
|
||||
AllowNamespacedSysctlsForHostNetAndHostIPC bool
|
||||
// The top-level resource being validated is a Pod, not just a PodSpec
|
||||
// embedded in some other resource.
|
||||
ResourceIsPod bool
|
||||
// Allow relaxed validation of environment variable names
|
||||
AllowRelaxedEnvironmentVariableValidation bool
|
||||
}
|
||||
|
||||
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
|
||||
@ -4027,9 +4066,7 @@ func validatePodIPs(pod *core.Pod) field.ErrorList {
|
||||
|
||||
// all PodIPs must be valid IPs
|
||||
for i, podIP := range pod.Status.PodIPs {
|
||||
for _, msg := range validation.IsValidIP(podIP.IP) {
|
||||
allErrs = append(allErrs, field.Invalid(podIPsField.Index(i), podIP.IP, msg))
|
||||
}
|
||||
allErrs = append(allErrs, validation.IsValidIP(podIPsField.Index(i), podIP.IP)...)
|
||||
}
|
||||
|
||||
// if we have more than one Pod.PodIP then
|
||||
@ -4081,9 +4118,7 @@ func validateHostIPs(pod *core.Pod) field.ErrorList {
|
||||
|
||||
// all HostPs must be valid IPs
|
||||
for i, hostIP := range pod.Status.HostIPs {
|
||||
for _, msg := range validation.IsValidIP(hostIP.IP) {
|
||||
allErrs = append(allErrs, field.Invalid(hostIPsField.Index(i), hostIP.IP, msg))
|
||||
}
|
||||
allErrs = append(allErrs, validation.IsValidIP(hostIPsField.Index(i), hostIP.IP)...)
|
||||
}
|
||||
|
||||
// if we have more than one Pod.HostIP then
|
||||
@ -4131,13 +4166,17 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi
|
||||
gracePeriod = *spec.TerminationGracePeriodSeconds
|
||||
}
|
||||
|
||||
// The default for hostUsers is true, so a spec with no SecurityContext or no HostUsers field will be true.
|
||||
// If the default ever changes, this condition will need to be changed.
|
||||
hostUsers := spec.SecurityContext == nil || spec.SecurityContext.HostUsers == nil || *spec.SecurityContext.HostUsers
|
||||
|
||||
vols, vErrs := ValidateVolumes(spec.Volumes, podMeta, fldPath.Child("volumes"), opts)
|
||||
allErrs = append(allErrs, vErrs...)
|
||||
podClaimNames := gatherPodResourceClaimNames(spec.ResourceClaims)
|
||||
allErrs = append(allErrs, validatePodResourceClaims(podMeta, spec.ResourceClaims, fldPath.Child("resourceClaims"))...)
|
||||
allErrs = append(allErrs, validateContainers(spec.Containers, vols, podClaimNames, gracePeriod, fldPath.Child("containers"), opts, &spec.RestartPolicy)...)
|
||||
allErrs = append(allErrs, validateInitContainers(spec.InitContainers, spec.Containers, vols, podClaimNames, gracePeriod, fldPath.Child("initContainers"), opts, &spec.RestartPolicy)...)
|
||||
allErrs = append(allErrs, validateEphemeralContainers(spec.EphemeralContainers, spec.Containers, spec.InitContainers, vols, podClaimNames, fldPath.Child("ephemeralContainers"), opts, &spec.RestartPolicy)...)
|
||||
allErrs = append(allErrs, validateContainers(spec.Containers, vols, podClaimNames, gracePeriod, fldPath.Child("containers"), opts, &spec.RestartPolicy, hostUsers)...)
|
||||
allErrs = append(allErrs, validateInitContainers(spec.InitContainers, spec.Containers, vols, podClaimNames, gracePeriod, fldPath.Child("initContainers"), opts, &spec.RestartPolicy, hostUsers)...)
|
||||
allErrs = append(allErrs, validateEphemeralContainers(spec.EphemeralContainers, spec.Containers, spec.InitContainers, vols, podClaimNames, fldPath.Child("ephemeralContainers"), opts, &spec.RestartPolicy, hostUsers)...)
|
||||
allErrs = append(allErrs, validatePodHostNetworkDeps(spec, fldPath, opts)...)
|
||||
allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy, fldPath.Child("restartPolicy"))...)
|
||||
allErrs = append(allErrs, validateDNSPolicy(&spec.DNSPolicy, fldPath.Child("dnsPolicy"))...)
|
||||
@ -4240,6 +4279,9 @@ func validateWindows(spec *core.PodSpec, fldPath *field.Path) field.ErrorList {
|
||||
securityContext := spec.SecurityContext
|
||||
// validate Pod SecurityContext
|
||||
if securityContext != nil {
|
||||
if securityContext.AppArmorProfile != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("securityContext").Child("appArmorProfile"), "cannot be set for a windows pod"))
|
||||
}
|
||||
if securityContext.SELinuxOptions != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("securityContext").Child("seLinuxOptions"), "cannot be set for a windows pod"))
|
||||
}
|
||||
@ -4286,6 +4328,9 @@ func validateWindows(spec *core.PodSpec, fldPath *field.Path) field.ErrorList {
|
||||
// TODO: Think if we need to relax this restriction or some of the restrictions
|
||||
if sc != nil {
|
||||
fldPath := cFldPath.Child("securityContext")
|
||||
if sc.AppArmorProfile != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("appArmorProfile"), "cannot be set for a windows pod"))
|
||||
}
|
||||
if sc.SELinuxOptions != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("seLinuxOptions"), "cannot be set for a windows pod"))
|
||||
}
|
||||
@ -4663,13 +4708,55 @@ func validateSeccompProfileType(fldPath *field.Path, seccompProfileType core.Sec
|
||||
}
|
||||
}
|
||||
|
||||
func ValidateAppArmorProfileField(profile *core.AppArmorProfile, fldPath *field.Path) field.ErrorList {
|
||||
if profile == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
switch profile.Type {
|
||||
case core.AppArmorProfileTypeLocalhost:
|
||||
if profile.LocalhostProfile == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("localhostProfile"), "must be set when AppArmor type is Localhost"))
|
||||
} else {
|
||||
localhostProfile := strings.TrimSpace(*profile.LocalhostProfile)
|
||||
if localhostProfile != *profile.LocalhostProfile {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("localhostProfile"), *profile.LocalhostProfile, "must not be padded with whitespace"))
|
||||
} else if localhostProfile == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("localhostProfile"), "must be set when AppArmor type is Localhost"))
|
||||
}
|
||||
|
||||
const maxLocalhostProfileLength = 4095 // PATH_MAX - 1
|
||||
if len(*profile.LocalhostProfile) > maxLocalhostProfileLength {
|
||||
allErrs = append(allErrs, field.TooLongMaxLength(fldPath.Child("localhostProfile"), *profile.LocalhostProfile, maxLocalhostProfileLength))
|
||||
}
|
||||
}
|
||||
|
||||
case core.AppArmorProfileTypeRuntimeDefault, core.AppArmorProfileTypeUnconfined:
|
||||
if profile.LocalhostProfile != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("localhostProfile"), profile.LocalhostProfile, "can only be set when AppArmor type is Localhost"))
|
||||
}
|
||||
|
||||
case "":
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("type"), "type is required when appArmorProfile is set"))
|
||||
|
||||
default:
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("type"), profile.Type,
|
||||
[]core.AppArmorProfileType{core.AppArmorProfileTypeLocalhost, core.AppArmorProfileTypeRuntimeDefault, core.AppArmorProfileTypeUnconfined}))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
|
||||
}
|
||||
|
||||
func ValidateAppArmorPodAnnotations(annotations map[string]string, spec *core.PodSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for k, p := range annotations {
|
||||
if !strings.HasPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
|
||||
if !strings.HasPrefix(k, v1.DeprecatedAppArmorBetaContainerAnnotationKeyPrefix) {
|
||||
continue
|
||||
}
|
||||
containerName := strings.TrimPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix)
|
||||
containerName := strings.TrimPrefix(k, v1.DeprecatedAppArmorBetaContainerAnnotationKeyPrefix)
|
||||
if !podSpecHasContainer(spec, containerName) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Key(k), containerName, "container not found"))
|
||||
}
|
||||
@ -4683,15 +4770,70 @@ func ValidateAppArmorPodAnnotations(annotations map[string]string, spec *core.Po
|
||||
}
|
||||
|
||||
func ValidateAppArmorProfileFormat(profile string) error {
|
||||
if profile == "" || profile == v1.AppArmorBetaProfileRuntimeDefault || profile == v1.AppArmorBetaProfileNameUnconfined {
|
||||
if profile == "" || profile == v1.DeprecatedAppArmorBetaProfileRuntimeDefault || profile == v1.DeprecatedAppArmorBetaProfileNameUnconfined {
|
||||
return nil
|
||||
}
|
||||
if !strings.HasPrefix(profile, v1.AppArmorBetaProfileNamePrefix) {
|
||||
if !strings.HasPrefix(profile, v1.DeprecatedAppArmorBetaProfileNamePrefix) {
|
||||
return fmt.Errorf("invalid AppArmor profile name: %q", profile)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateAppArmorAnnotationsAndFieldsMatchOnCreate validates that AppArmor fields and annotations are consistent.
|
||||
func validateAppArmorAnnotationsAndFieldsMatchOnCreate(objectMeta metav1.ObjectMeta, podSpec *core.PodSpec, specPath *field.Path) field.ErrorList {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.AppArmorFields) {
|
||||
return nil
|
||||
}
|
||||
if podSpec.OS != nil && podSpec.OS.Name == core.Windows {
|
||||
// Skip consistency check for windows pods.
|
||||
return nil
|
||||
}
|
||||
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
var podProfile *core.AppArmorProfile
|
||||
if podSpec.SecurityContext != nil {
|
||||
podProfile = podSpec.SecurityContext.AppArmorProfile
|
||||
}
|
||||
podshelper.VisitContainersWithPath(podSpec, specPath, func(c *core.Container, cFldPath *field.Path) bool {
|
||||
containerProfile := podProfile
|
||||
if c.SecurityContext != nil && c.SecurityContext.AppArmorProfile != nil {
|
||||
containerProfile = c.SecurityContext.AppArmorProfile
|
||||
}
|
||||
|
||||
if containerProfile == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
key := core.DeprecatedAppArmorAnnotationKeyPrefix + c.Name
|
||||
if annotation, found := objectMeta.Annotations[key]; found {
|
||||
apparmorPath := cFldPath.Child("securityContext").Child("appArmorProfile")
|
||||
|
||||
switch containerProfile.Type {
|
||||
case core.AppArmorProfileTypeUnconfined:
|
||||
if annotation != core.DeprecatedAppArmorAnnotationValueUnconfined {
|
||||
allErrs = append(allErrs, field.Forbidden(apparmorPath.Child("type"), "apparmor type in annotation and field must match"))
|
||||
}
|
||||
|
||||
case core.AppArmorProfileTypeRuntimeDefault:
|
||||
if annotation != core.DeprecatedAppArmorAnnotationValueRuntimeDefault {
|
||||
allErrs = append(allErrs, field.Forbidden(apparmorPath.Child("type"), "apparmor type in annotation and field must match"))
|
||||
}
|
||||
|
||||
case core.AppArmorProfileTypeLocalhost:
|
||||
if !strings.HasPrefix(annotation, core.DeprecatedAppArmorAnnotationValueLocalhostPrefix) {
|
||||
allErrs = append(allErrs, field.Forbidden(apparmorPath.Child("type"), "apparmor type in annotation and field must match"))
|
||||
} else if containerProfile.LocalhostProfile == nil || strings.TrimPrefix(annotation, core.DeprecatedAppArmorAnnotationValueLocalhostPrefix) != *containerProfile.LocalhostProfile {
|
||||
allErrs = append(allErrs, field.Forbidden(apparmorPath.Child("localhostProfile"), "apparmor profile in annotation and field must match"))
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func podSpecHasContainer(spec *core.PodSpec, containerName string) bool {
|
||||
var hasContainer bool
|
||||
podshelper.VisitContainersWithPath(spec, field.NewPath("spec"), func(c *core.Container, _ *field.Path) bool {
|
||||
@ -4805,6 +4947,7 @@ func validatePodSpecSecurityContext(securityContext *core.PodSecurityContext, sp
|
||||
|
||||
allErrs = append(allErrs, validateSeccompProfileField(securityContext.SeccompProfile, fldPath.Child("seccompProfile"))...)
|
||||
allErrs = append(allErrs, validateWindowsSecurityContextOptions(securityContext.WindowsOptions, fldPath.Child("windowsOptions"))...)
|
||||
allErrs = append(allErrs, ValidateAppArmorProfileField(securityContext.AppArmorProfile, fldPath.Child("appArmorProfile"))...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
@ -4845,6 +4988,7 @@ func ValidatePodCreate(pod *core.Pod, opts PodValidationOptions) field.ErrorList
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("nodeName"), "cannot be set until all schedulingGates have been cleared"))
|
||||
}
|
||||
allErrs = append(allErrs, validateSeccompAnnotationsAndFields(pod.ObjectMeta, &pod.Spec, fldPath)...)
|
||||
allErrs = append(allErrs, validateAppArmorAnnotationsAndFieldsMatchOnCreate(pod.ObjectMeta, &pod.Spec, fldPath)...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
@ -5060,7 +5204,7 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel
|
||||
|
||||
// Handle validations specific to gated pods.
|
||||
podIsGated := len(oldPod.Spec.SchedulingGates) > 0
|
||||
if opts.AllowMutableNodeSelectorAndNodeAffinity && podIsGated {
|
||||
if podIsGated {
|
||||
// Additions to spec.nodeSelector are allowed (no deletions or mutations) for gated pods.
|
||||
if !apiequality.Semantic.DeepEqual(mungedPodSpec.NodeSelector, oldPod.Spec.NodeSelector) {
|
||||
allErrs = append(allErrs, validateNodeSelectorMutation(specPath.Child("nodeSelector"), mungedPodSpec.NodeSelector, oldPod.Spec.NodeSelector)...)
|
||||
@ -5439,10 +5583,8 @@ func ValidateService(service *core.Service) field.ErrorList {
|
||||
ipPath := specPath.Child("externalIPs")
|
||||
for i, ip := range service.Spec.ExternalIPs {
|
||||
idxPath := ipPath.Index(i)
|
||||
if msgs := validation.IsValidIP(ip); len(msgs) != 0 {
|
||||
for i := range msgs {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath, ip, msgs[i]))
|
||||
}
|
||||
if errs := validation.IsValidIP(idxPath, ip); len(errs) != 0 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateNonSpecialIP(ip, idxPath)...)
|
||||
}
|
||||
@ -5496,24 +5638,32 @@ func ValidateService(service *core.Service) field.ErrorList {
|
||||
ports[key] = true
|
||||
}
|
||||
|
||||
// Validate SourceRange field and annotation
|
||||
_, ok := service.Annotations[core.AnnotationLoadBalancerSourceRangesKey]
|
||||
if len(service.Spec.LoadBalancerSourceRanges) > 0 || ok {
|
||||
var fieldPath *field.Path
|
||||
var val string
|
||||
if len(service.Spec.LoadBalancerSourceRanges) > 0 {
|
||||
fieldPath = specPath.Child("LoadBalancerSourceRanges")
|
||||
val = fmt.Sprintf("%v", service.Spec.LoadBalancerSourceRanges)
|
||||
} else {
|
||||
fieldPath = field.NewPath("metadata", "annotations").Key(core.AnnotationLoadBalancerSourceRangesKey)
|
||||
val = service.Annotations[core.AnnotationLoadBalancerSourceRangesKey]
|
||||
}
|
||||
// Validate SourceRanges field or annotation.
|
||||
if len(service.Spec.LoadBalancerSourceRanges) > 0 {
|
||||
fieldPath := specPath.Child("LoadBalancerSourceRanges")
|
||||
|
||||
if service.Spec.Type != core.ServiceTypeLoadBalancer {
|
||||
allErrs = append(allErrs, field.Forbidden(fieldPath, "may only be used when `type` is 'LoadBalancer'"))
|
||||
}
|
||||
_, err := apiservice.GetLoadBalancerSourceRanges(service)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fieldPath, val, "must be a list of IP ranges. For example, 10.240.0.0/24,10.250.0.0/24 "))
|
||||
for idx, value := range service.Spec.LoadBalancerSourceRanges {
|
||||
// Note: due to a historical accident around transition from the
|
||||
// annotation value, these values are allowed to be space-padded.
|
||||
value = strings.TrimSpace(value)
|
||||
allErrs = append(allErrs, validation.IsValidCIDR(fieldPath.Index(idx), value)...)
|
||||
}
|
||||
} else if val, annotationSet := service.Annotations[core.AnnotationLoadBalancerSourceRangesKey]; annotationSet {
|
||||
fieldPath := field.NewPath("metadata", "annotations").Key(core.AnnotationLoadBalancerSourceRangesKey)
|
||||
if service.Spec.Type != core.ServiceTypeLoadBalancer {
|
||||
allErrs = append(allErrs, field.Forbidden(fieldPath, "may only be used when `type` is 'LoadBalancer'"))
|
||||
}
|
||||
|
||||
val = strings.TrimSpace(val)
|
||||
if val != "" {
|
||||
cidrs := strings.Split(val, ",")
|
||||
for _, value := range cidrs {
|
||||
value = strings.TrimSpace(value)
|
||||
allErrs = append(allErrs, validation.IsValidCIDR(fieldPath, value)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5534,6 +5684,9 @@ func ValidateService(service *core.Service) field.ErrorList {
|
||||
// internal traffic policy field
|
||||
allErrs = append(allErrs, validateServiceInternalTrafficFieldsValue(service)...)
|
||||
|
||||
// traffic distribution field
|
||||
allErrs = append(allErrs, validateServiceTrafficDistribution(service)...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -5651,6 +5804,22 @@ func validateServiceInternalTrafficFieldsValue(service *core.Service) field.Erro
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateServiceTrafficDistribution validates the values for the
|
||||
// trafficDistribution field.
|
||||
func validateServiceTrafficDistribution(service *core.Service) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if service.Spec.TrafficDistribution == nil {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
if *service.Spec.TrafficDistribution != v1.ServiceTrafficDistributionPreferClose {
|
||||
allErrs = append(allErrs, field.NotSupported(field.NewPath("spec").Child("trafficDistribution"), *service.Spec.TrafficDistribution, []string{v1.ServiceTrafficDistributionPreferClose}))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateServiceCreate validates Services as they are created.
|
||||
func ValidateServiceCreate(service *core.Service) field.ErrorList {
|
||||
return ValidateService(service)
|
||||
@ -5797,6 +5966,7 @@ func ValidatePodTemplateSpec(spec *core.PodTemplateSpec, fldPath *field.Path, op
|
||||
allErrs = append(allErrs, ValidatePodSpecificAnnotations(spec.Annotations, &spec.Spec, fldPath.Child("annotations"), opts)...)
|
||||
allErrs = append(allErrs, ValidatePodSpec(&spec.Spec, nil, fldPath.Child("spec"), opts)...)
|
||||
allErrs = append(allErrs, validateSeccompAnnotationsAndFields(spec.ObjectMeta, &spec.Spec, fldPath.Child("spec"))...)
|
||||
allErrs = append(allErrs, validateAppArmorAnnotationsAndFieldsMatchOnCreate(spec.ObjectMeta, &spec.Spec, fldPath.Child("spec"))...)
|
||||
|
||||
if len(spec.Spec.EphemeralContainers) > 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("spec", "ephemeralContainers"), "ephemeral containers not allowed in pod template"))
|
||||
@ -5916,9 +6086,7 @@ func ValidateNode(node *core.Node) field.ErrorList {
|
||||
|
||||
// all PodCIDRs should be valid ones
|
||||
for idx, value := range node.Spec.PodCIDRs {
|
||||
if _, err := ValidateCIDR(value); err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(podCIDRsField.Index(idx), node.Spec.PodCIDRs, "must be valid CIDR"))
|
||||
}
|
||||
allErrs = append(allErrs, validation.IsValidCIDR(podCIDRsField.Index(idx), value)...)
|
||||
}
|
||||
|
||||
// if more than PodCIDR then
|
||||
@ -6954,9 +7122,7 @@ func validateEndpointSubsets(subsets []core.EndpointSubset, fldPath *field.Path)
|
||||
|
||||
func validateEndpointAddress(address *core.EndpointAddress, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for _, msg := range validation.IsValidIP(address.IP) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("ip"), address.IP, msg))
|
||||
}
|
||||
allErrs = append(allErrs, validation.IsValidIP(fldPath.Child("ip"), address.IP)...)
|
||||
if len(address.Hostname) > 0 {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(address.Hostname, fldPath.Child("hostname"))...)
|
||||
}
|
||||
@ -7022,7 +7188,7 @@ func validateEndpointPort(port *core.EndpointPort, requireName bool, fldPath *fi
|
||||
}
|
||||
|
||||
// ValidateSecurityContext ensures the security context contains valid settings
|
||||
func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path) field.ErrorList {
|
||||
func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path, hostUsers bool) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
// this should only be true for testing since SecurityContext is defaulted by the core
|
||||
if sc == nil {
|
||||
@ -7051,6 +7217,9 @@ func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path) fiel
|
||||
if err := ValidateProcMountType(fldPath.Child("procMount"), *sc.ProcMount); err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
if hostUsers && *sc.ProcMount == core.UnmaskedProcMount {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("procMount"), sc.ProcMount, "`hostUsers` must be false to use `Unmasked`"))
|
||||
}
|
||||
|
||||
}
|
||||
allErrs = append(allErrs, validateSeccompProfileField(sc.SeccompProfile, fldPath.Child("seccompProfile"))...)
|
||||
@ -7069,6 +7238,7 @@ func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path) fiel
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, validateWindowsSecurityContextOptions(sc.WindowsOptions, fldPath.Child("windowsOptions"))...)
|
||||
allErrs = append(allErrs, ValidateAppArmorProfileField(sc.AppArmorProfile, fldPath.Child("appArmorProfile"))...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
@ -7302,9 +7472,7 @@ func ValidateLoadBalancerStatus(status *core.LoadBalancerStatus, fldPath *field.
|
||||
for i, ingress := range status.Ingress {
|
||||
idxPath := ingrPath.Index(i)
|
||||
if len(ingress.IP) > 0 {
|
||||
if isIP := (netutils.ParseIPSloppy(ingress.IP) != nil); !isIP {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("ip"), ingress.IP, "must be a valid IP address"))
|
||||
}
|
||||
allErrs = append(allErrs, validation.IsValidIP(idxPath.Child("ip"), ingress.IP)...)
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.LoadBalancerIPMode) && ingress.IPMode == nil {
|
||||
@ -7350,15 +7518,6 @@ func validateVolumeNodeAffinity(nodeAffinity *core.VolumeNodeAffinity, fldPath *
|
||||
return true, allErrs
|
||||
}
|
||||
|
||||
// ValidateCIDR validates whether a CIDR matches the conventions expected by net.ParseCIDR
|
||||
func ValidateCIDR(cidr string) (*net.IPNet, error) {
|
||||
_, net, err := netutils.ParseCIDRSloppy(cidr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return net, nil
|
||||
}
|
||||
|
||||
func IsDecremented(update, old *int32) bool {
|
||||
if update == nil && old != nil {
|
||||
return true
|
||||
@ -7658,11 +7817,9 @@ func ValidateServiceClusterIPsRelatedFields(service *core.Service) field.ErrorLi
|
||||
}
|
||||
|
||||
// is it valid ip?
|
||||
errorMessages := validation.IsValidIP(clusterIP)
|
||||
errorMessages := validation.IsValidIP(clusterIPsField.Index(i), clusterIP)
|
||||
hasInvalidIPs = (len(errorMessages) != 0) || hasInvalidIPs
|
||||
for _, msg := range errorMessages {
|
||||
allErrs = append(allErrs, field.Invalid(clusterIPsField.Index(i), clusterIP, msg))
|
||||
}
|
||||
allErrs = append(allErrs, errorMessages...)
|
||||
}
|
||||
|
||||
// max two
|
||||
|
115
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
115
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
@ -74,6 +74,27 @@ func (in *Affinity) DeepCopy() *Affinity {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppArmorProfile) DeepCopyInto(out *AppArmorProfile) {
|
||||
*out = *in
|
||||
if in.LocalhostProfile != nil {
|
||||
in, out := &in.LocalhostProfile, &out.LocalhostProfile
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppArmorProfile.
|
||||
func (in *AppArmorProfile) DeepCopy() *AppArmorProfile {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppArmorProfile)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AttachedVolume) DeepCopyInto(out *AttachedVolume) {
|
||||
*out = *in
|
||||
@ -1041,6 +1062,13 @@ func (in *ContainerStatus) DeepCopyInto(out *ContainerStatus) {
|
||||
*out = new(ResourceRequirements)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.VolumeMounts != nil {
|
||||
in, out := &in.VolumeMounts, &out.VolumeMounts
|
||||
*out = make([]VolumeMountStatus, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -2728,24 +2756,43 @@ func (in *NodeProxyOptions) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NodeResources) DeepCopyInto(out *NodeResources) {
|
||||
func (in *NodeRuntimeHandler) DeepCopyInto(out *NodeRuntimeHandler) {
|
||||
*out = *in
|
||||
if in.Capacity != nil {
|
||||
in, out := &in.Capacity, &out.Capacity
|
||||
*out = make(ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
if in.Features != nil {
|
||||
in, out := &in.Features, &out.Features
|
||||
*out = new(NodeRuntimeHandlerFeatures)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResources.
|
||||
func (in *NodeResources) DeepCopy() *NodeResources {
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeRuntimeHandler.
|
||||
func (in *NodeRuntimeHandler) DeepCopy() *NodeRuntimeHandler {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NodeResources)
|
||||
out := new(NodeRuntimeHandler)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NodeRuntimeHandlerFeatures) DeepCopyInto(out *NodeRuntimeHandlerFeatures) {
|
||||
*out = *in
|
||||
if in.RecursiveReadOnlyMounts != nil {
|
||||
in, out := &in.RecursiveReadOnlyMounts, &out.RecursiveReadOnlyMounts
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeRuntimeHandlerFeatures.
|
||||
func (in *NodeRuntimeHandlerFeatures) DeepCopy() *NodeRuntimeHandlerFeatures {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NodeRuntimeHandlerFeatures)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@ -2910,6 +2957,13 @@ func (in *NodeStatus) DeepCopyInto(out *NodeStatus) {
|
||||
*out = new(NodeConfigStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.RuntimeHandlers != nil {
|
||||
in, out := &in.RuntimeHandlers, &out.RuntimeHandlers
|
||||
*out = make([]NodeRuntimeHandler, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -4033,6 +4087,11 @@ func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) {
|
||||
*out = new(SeccompProfile)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.AppArmorProfile != nil {
|
||||
in, out := &in.AppArmorProfile, &out.AppArmorProfile
|
||||
*out = new(AppArmorProfile)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -5401,6 +5460,11 @@ func (in *SecurityContext) DeepCopyInto(out *SecurityContext) {
|
||||
*out = new(SeccompProfile)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.AppArmorProfile != nil {
|
||||
in, out := &in.AppArmorProfile, &out.AppArmorProfile
|
||||
*out = new(AppArmorProfile)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -5700,6 +5764,11 @@ func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) {
|
||||
*out = new(ServiceInternalTrafficPolicy)
|
||||
**out = **in
|
||||
}
|
||||
if in.TrafficDistribution != nil {
|
||||
in, out := &in.TrafficDistribution, &out.TrafficDistribution
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -6058,6 +6127,11 @@ func (in *VolumeDevice) DeepCopy() *VolumeDevice {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeMount) DeepCopyInto(out *VolumeMount) {
|
||||
*out = *in
|
||||
if in.RecursiveReadOnly != nil {
|
||||
in, out := &in.RecursiveReadOnly, &out.RecursiveReadOnly
|
||||
*out = new(RecursiveReadOnlyMode)
|
||||
**out = **in
|
||||
}
|
||||
if in.MountPropagation != nil {
|
||||
in, out := &in.MountPropagation, &out.MountPropagation
|
||||
*out = new(MountPropagationMode)
|
||||
@ -6076,6 +6150,27 @@ func (in *VolumeMount) DeepCopy() *VolumeMount {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeMountStatus) DeepCopyInto(out *VolumeMountStatus) {
|
||||
*out = *in
|
||||
if in.RecursiveReadOnly != nil {
|
||||
in, out := &in.RecursiveReadOnly, &out.RecursiveReadOnly
|
||||
*out = new(RecursiveReadOnlyMode)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeMountStatus.
|
||||
func (in *VolumeMountStatus) DeepCopy() *VolumeMountStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeMountStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeNodeAffinity) DeepCopyInto(out *VolumeNodeAffinity) {
|
||||
*out = *in
|
||||
|
5
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
@ -52,7 +52,6 @@ import (
|
||||
hashutil "k8s.io/kubernetes/pkg/util/hash"
|
||||
taintutils "k8s.io/kubernetes/pkg/util/taints"
|
||||
"k8s.io/utils/clock"
|
||||
"k8s.io/utils/integer"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@ -940,7 +939,7 @@ func podReadyTime(pod *v1.Pod) *metav1.Time {
|
||||
func maxContainerRestarts(pod *v1.Pod) int {
|
||||
maxRestarts := 0
|
||||
for _, c := range pod.Status.ContainerStatuses {
|
||||
maxRestarts = integer.IntMax(maxRestarts, int(c.RestartCount))
|
||||
maxRestarts = max(maxRestarts, int(c.RestartCount))
|
||||
}
|
||||
return maxRestarts
|
||||
}
|
||||
@ -952,7 +951,7 @@ func FilterActivePods(logger klog.Logger, pods []*v1.Pod) []*v1.Pod {
|
||||
if IsPodActive(p) {
|
||||
result = append(result, p)
|
||||
} else {
|
||||
logger.V(4).Info("Ignoring inactive pod", "pod", klog.KObj(p), "phase", p.Status.Phase, "deletionTime", p.DeletionTimestamp)
|
||||
logger.V(4).Info("Ignoring inactive pod", "pod", klog.KObj(p), "phase", p.Status.Phase, "deletionTime", klog.SafePtr(p.DeletionTimestamp))
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
6
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go
generated
vendored
@ -479,12 +479,12 @@ func GetProportion(logger klog.Logger, rs *apps.ReplicaSet, d apps.Deployment, d
|
||||
// Use the minimum between the replica set fraction and the maximum allowed replicas
|
||||
// when scaling up. This way we ensure we will not scale up more than the allowed
|
||||
// replicas we can add.
|
||||
return integer.Int32Min(rsFraction, allowed)
|
||||
return min(rsFraction, allowed)
|
||||
}
|
||||
// Use the maximum between the replica set fraction and the maximum allowed replicas
|
||||
// when scaling down. This way we ensure we will not scale down more than the allowed
|
||||
// replicas we can remove.
|
||||
return integer.Int32Max(rsFraction, allowed)
|
||||
return max(rsFraction, allowed)
|
||||
}
|
||||
|
||||
// getReplicaSetFraction estimates the fraction of replicas a replica set can have in
|
||||
@ -799,7 +799,7 @@ func NewRSNewReplicas(deployment *apps.Deployment, allRSs []*apps.ReplicaSet, ne
|
||||
// Scale up.
|
||||
scaleUpCount := maxTotalPods - currentPodCount
|
||||
// Do not exceed the number of desired replicas.
|
||||
scaleUpCount = int32(integer.IntMin(int(scaleUpCount), int(*(deployment.Spec.Replicas)-*(newRS.Spec.Replicas))))
|
||||
scaleUpCount = min(scaleUpCount, *(deployment.Spec.Replicas)-*(newRS.Spec.Replicas))
|
||||
return *(newRS.Spec.Replicas) + scaleUpCount, nil
|
||||
case apps.RecreateDeploymentStrategyType:
|
||||
return *(deployment.Spec.Replicas), nil
|
||||
|
69
vendor/k8s.io/kubernetes/pkg/features/client_adapter.go
generated
vendored
Normal file
69
vendor/k8s.io/kubernetes/pkg/features/client_adapter.go
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 (
|
||||
"fmt"
|
||||
|
||||
clientfeatures "k8s.io/client-go/features"
|
||||
"k8s.io/component-base/featuregate"
|
||||
)
|
||||
|
||||
// clientAdapter adapts a k8s.io/component-base/featuregate.MutableFeatureGate to client-go's
|
||||
// feature Gate and Registry interfaces. The component-base types Feature, FeatureSpec, and
|
||||
// prerelease, and the component-base prerelease constants, are duplicated by parallel types and
|
||||
// constants in client-go. The parallel types exist to allow the feature gate mechanism to be used
|
||||
// for client-go features without introducing a circular dependency between component-base and
|
||||
// client-go.
|
||||
type clientAdapter struct {
|
||||
mfg featuregate.MutableFeatureGate
|
||||
}
|
||||
|
||||
var _ clientfeatures.Gates = &clientAdapter{}
|
||||
|
||||
func (a *clientAdapter) Enabled(name clientfeatures.Feature) bool {
|
||||
return a.mfg.Enabled(featuregate.Feature(name))
|
||||
}
|
||||
|
||||
var _ clientfeatures.Registry = &clientAdapter{}
|
||||
|
||||
func (a *clientAdapter) Add(in map[clientfeatures.Feature]clientfeatures.FeatureSpec) error {
|
||||
out := map[featuregate.Feature]featuregate.FeatureSpec{}
|
||||
for name, spec := range in {
|
||||
converted := featuregate.FeatureSpec{
|
||||
Default: spec.Default,
|
||||
LockToDefault: spec.LockToDefault,
|
||||
}
|
||||
switch spec.PreRelease {
|
||||
case clientfeatures.Alpha:
|
||||
converted.PreRelease = featuregate.Alpha
|
||||
case clientfeatures.Beta:
|
||||
converted.PreRelease = featuregate.Beta
|
||||
case clientfeatures.GA:
|
||||
converted.PreRelease = featuregate.GA
|
||||
case clientfeatures.Deprecated:
|
||||
converted.PreRelease = featuregate.Deprecated
|
||||
default:
|
||||
// The default case implies programmer error. The same set of prerelease
|
||||
// constants must exist in both component-base and client-go, and each one
|
||||
// must have a case here.
|
||||
panic(fmt.Sprintf("unrecognized prerelease %q of feature %q", spec.PreRelease, name))
|
||||
}
|
||||
out[featuregate.Feature(name)] = converted
|
||||
}
|
||||
return a.mfg.Add(out)
|
||||
}
|
352
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
352
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
@ -21,6 +21,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
clientfeatures "k8s.io/client-go/features"
|
||||
"k8s.io/component-base/featuregate"
|
||||
)
|
||||
|
||||
@ -58,21 +59,18 @@ const (
|
||||
// Enables usage of any object for volume data source in PVCs
|
||||
AnyVolumeDataSource featuregate.Feature = "AnyVolumeDataSource"
|
||||
|
||||
// owner: @nabokihms
|
||||
// alpha: v1.26
|
||||
// beta: v1.27
|
||||
// GA: v1.28
|
||||
//
|
||||
// Enables API to get self subject attributes after authentication.
|
||||
APISelfSubjectReview featuregate.Feature = "APISelfSubjectReview"
|
||||
|
||||
// owner: @tallclair
|
||||
// beta: v1.4
|
||||
AppArmor featuregate.Feature = "AppArmor"
|
||||
|
||||
// owner: @tallclair
|
||||
// beta: v1.30
|
||||
AppArmorFields featuregate.Feature = "AppArmorFields"
|
||||
|
||||
// owner: @danwinship
|
||||
// alpha: v1.27
|
||||
// beta: v1.29
|
||||
// GA: v1.30
|
||||
//
|
||||
// Enables dual-stack --node-ip in kubelet with external cloud providers
|
||||
CloudDualStackNodeIPs featuregate.Feature = "CloudDualStackNodeIPs"
|
||||
@ -137,14 +135,6 @@ const (
|
||||
// Allow the usage of options to fine-tune the cpumanager policies.
|
||||
CPUManagerPolicyOptions featuregate.Feature = "CPUManagerPolicyOptions"
|
||||
|
||||
// owner: @andyzhangx
|
||||
// alpha: v1.15
|
||||
// beta: v1.21
|
||||
// GA: v1.26
|
||||
//
|
||||
// Enables the Azure File in-tree driver to Azure File Driver migration feature.
|
||||
CSIMigrationAzureFile featuregate.Feature = "CSIMigrationAzureFile"
|
||||
|
||||
// owner: @mfordjody
|
||||
// alpha: v1.26
|
||||
//
|
||||
@ -179,14 +169,6 @@ const (
|
||||
// Enables kubelet to detect CSI volume condition and send the event of the abnormal volume to the corresponding pod that is using it.
|
||||
CSIVolumeHealth featuregate.Feature = "CSIVolumeHealth"
|
||||
|
||||
// owner: @seans3
|
||||
// kep: http://kep.k8s.io/4006
|
||||
// alpha: v1.29
|
||||
//
|
||||
// Enables StreamTranslator proxy to handle WebSockets upgrade requests for the
|
||||
// version of the RemoteCommand subprotocol that supports the "close" signal.
|
||||
TranslateStreamCloseWebsocketRequests featuregate.Feature = "TranslateStreamCloseWebsocketRequests"
|
||||
|
||||
// owner: @nckturner
|
||||
// kep: http://kep.k8s.io/2699
|
||||
// alpha: v1.27
|
||||
@ -196,6 +178,7 @@ const (
|
||||
// owner: @adrianreber
|
||||
// kep: https://kep.k8s.io/2008
|
||||
// alpha: v1.25
|
||||
// beta: v1.30
|
||||
//
|
||||
// Enables container Checkpoint support in the kubelet
|
||||
ContainerCheckpoint featuregate.Feature = "ContainerCheckpoint"
|
||||
@ -272,21 +255,11 @@ const (
|
||||
// Lock to default and remove after v1.22 based on user feedback that should be reflected in KEP #1972 update
|
||||
ExecProbeTimeout featuregate.Feature = "ExecProbeTimeout"
|
||||
|
||||
// owner: @gjkim42
|
||||
// kep: https://kep.k8s.io/2595
|
||||
// alpha: v1.22
|
||||
// beta: v1.26
|
||||
// GA: v1.28
|
||||
//
|
||||
// Enables apiserver and kubelet to allow up to 32 DNSSearchPaths and up to 2048 DNSSearchListChars.
|
||||
ExpandedDNSConfig featuregate.Feature = "ExpandedDNSConfig"
|
||||
|
||||
// owner: @pweil-
|
||||
// alpha: v1.5
|
||||
// deprecated: v1.28
|
||||
//
|
||||
// This flag used to be needed for dockershim CRI and currently does nothing.
|
||||
ExperimentalHostUserNamespaceDefaultingGate featuregate.Feature = "ExperimentalHostUserNamespaceDefaulting"
|
||||
// owner: @jpbetz
|
||||
// alpha: v1.30
|
||||
// Resource create requests using generateName are retried automatically by the apiserver
|
||||
// if the generated name conflicts with an existing resource name, up to a maximum number of 7 retries.
|
||||
RetryGenerateName featuregate.Feature = "RetryGenerateName"
|
||||
|
||||
// owner: @bobbypage
|
||||
// alpha: v1.20
|
||||
@ -304,6 +277,7 @@ const (
|
||||
// kep: https://kep.k8s.io/1610
|
||||
// alpha: v1.20
|
||||
// beta: v1.27
|
||||
// GA: v1.30
|
||||
//
|
||||
// Add support for the HPA to scale based on metrics from individual containers
|
||||
// in target pods
|
||||
@ -372,15 +346,6 @@ const (
|
||||
// Disables the vSphere in-tree driver.
|
||||
InTreePluginvSphereUnregister featuregate.Feature = "InTreePluginvSphereUnregister"
|
||||
|
||||
// owner: @danwinship
|
||||
// kep: https://kep.k8s.io/3178
|
||||
// alpha: v1.25
|
||||
// beta: v1.27
|
||||
// stable: v1.28
|
||||
//
|
||||
// Causes kubelet to no longer create legacy IPTables rules
|
||||
IPTablesOwnershipCleanup featuregate.Feature = "IPTablesOwnershipCleanup"
|
||||
|
||||
// owner: @mimowo
|
||||
// kep: https://kep.k8s.io/3850
|
||||
// alpha: v1.28
|
||||
@ -389,6 +354,13 @@ const (
|
||||
// Allows users to specify counting of failed pods per index.
|
||||
JobBackoffLimitPerIndex featuregate.Feature = "JobBackoffLimitPerIndex"
|
||||
|
||||
// owner: @mimowo
|
||||
// kep: https://kep.k8s.io/4368
|
||||
// alpha: v1.30
|
||||
//
|
||||
// Allows to delegate reconciliation of a Job object to an external controller.
|
||||
JobManagedBy featuregate.Feature = "JobManagedBy"
|
||||
|
||||
// owner: @mimowo
|
||||
// kep: https://kep.k8s.io/3329
|
||||
// alpha: v1.25
|
||||
@ -406,6 +378,15 @@ const (
|
||||
// Allow users to specify recreating pods of a job only when
|
||||
// pods have fully terminated.
|
||||
JobPodReplacementPolicy featuregate.Feature = "JobPodReplacementPolicy"
|
||||
|
||||
// owner: @tenzen-y
|
||||
// kep: https://kep.k8s.io/3998
|
||||
// alpha: v1.30
|
||||
//
|
||||
// Allow users to specify when a Job can be declared as succeeded
|
||||
// based on the set of succeeded pods.
|
||||
JobSuccessPolicy featuregate.Feature = "JobSuccessPolicy"
|
||||
|
||||
// owner: @alculquicondor
|
||||
// alpha: v1.23
|
||||
// beta: v1.24
|
||||
@ -432,14 +413,6 @@ const (
|
||||
// All the node components such as CRI need to be running in the same user namespace.
|
||||
KubeletInUserNamespace featuregate.Feature = "KubeletInUserNamespace"
|
||||
|
||||
// owner: @dashpole, @ffromani (only for GA graduation)
|
||||
// alpha: v1.13
|
||||
// beta: v1.15
|
||||
// GA: v1.28
|
||||
//
|
||||
// Enables the kubelet's pod resources grpc endpoint
|
||||
KubeletPodResources featuregate.Feature = "KubeletPodResources"
|
||||
|
||||
// owner: @moshe010
|
||||
// alpha: v1.27
|
||||
//
|
||||
@ -452,13 +425,6 @@ const (
|
||||
// Enable POD resources API with Get method
|
||||
KubeletPodResourcesGet featuregate.Feature = "KubeletPodResourcesGet"
|
||||
|
||||
// owner: @ffromani
|
||||
// alpha: v1.21
|
||||
// beta: v1.23
|
||||
// GA: v1.28
|
||||
// Enable POD resources API to return allocatable resources
|
||||
KubeletPodResourcesGetAllocatable featuregate.Feature = "KubeletPodResourcesGetAllocatable"
|
||||
|
||||
// KubeletSeparateDiskGC enables Kubelet to garbage collection images/containers on different filesystems
|
||||
// owner: @kannon92
|
||||
// kep: https://kep.k8s.io/4191
|
||||
@ -476,23 +442,17 @@ const (
|
||||
// owner: @alexanderConstantinescu
|
||||
// kep: http://kep.k8s.io/3836
|
||||
// alpha: v1.28
|
||||
// beta: v1.30
|
||||
//
|
||||
// Implement connection draining for terminating nodes for
|
||||
// `externalTrafficPolicy: Cluster` services.
|
||||
KubeProxyDrainingTerminatingNodes featuregate.Feature = "KubeProxyDrainingTerminatingNodes"
|
||||
|
||||
// owner: @zshihang
|
||||
// kep: http://kep.k8s.io/2800
|
||||
// alpha: v1.26
|
||||
// beta: v1.27
|
||||
//
|
||||
// Enables tracking of secret-based service account tokens usage.
|
||||
LegacyServiceAccountTokenTracking featuregate.Feature = "LegacyServiceAccountTokenTracking"
|
||||
|
||||
// owner: @yt2985
|
||||
// kep: http://kep.k8s.io/2800
|
||||
// kep: http://kep.k8s.io/2799
|
||||
// alpha: v1.28
|
||||
// beta: v1.29
|
||||
// GA: v1.30
|
||||
//
|
||||
// Enables cleaning up of secret-based service account tokens.
|
||||
LegacyServiceAccountTokenCleanUp featuregate.Feature = "LegacyServiceAccountTokenCleanUp"
|
||||
@ -549,18 +509,11 @@ const (
|
||||
// kep: https://kep.k8s.io/3022
|
||||
// alpha: v1.24
|
||||
// beta: v1.25
|
||||
// GA: v1.30
|
||||
//
|
||||
// Enable MinDomains in Pod Topology Spread.
|
||||
MinDomainsInPodTopologySpread featuregate.Feature = "MinDomainsInPodTopologySpread"
|
||||
|
||||
// owner: @danwinship
|
||||
// kep: http://kep.k8s.io/3453
|
||||
// alpha: v1.26
|
||||
// beta: v1.27
|
||||
//
|
||||
// Enables new performance-improving code in kube-proxy iptables mode
|
||||
MinimizeIPTablesRestore featuregate.Feature = "MinimizeIPTablesRestore"
|
||||
|
||||
// owner: @aojea
|
||||
// kep: https://kep.k8s.io/1880
|
||||
// alpha: v1.27
|
||||
@ -572,6 +525,7 @@ const (
|
||||
// kep: https://kep.k8s.io/3756
|
||||
// alpha: v1.25 (as part of SELinuxMountReadWriteOncePod)
|
||||
// beta: v1.27
|
||||
// GA: v1.30
|
||||
// Robust VolumeManager reconstruction after kubelet restart.
|
||||
NewVolumeManagerReconstruction featuregate.Feature = "NewVolumeManagerReconstruction"
|
||||
|
||||
@ -585,6 +539,7 @@ const (
|
||||
// owner: @aravindhp @LorbusChris
|
||||
// kep: http://kep.k8s.io/2271
|
||||
// alpha: v1.27
|
||||
// beta: v1.30
|
||||
//
|
||||
// Enables querying logs of node services using the /logs endpoint
|
||||
NodeLogQuery featuregate.Feature = "NodeLogQuery"
|
||||
@ -598,11 +553,13 @@ const (
|
||||
// Allow pods to failover to a different node in case of non graceful node shutdown
|
||||
NodeOutOfServiceVolumeDetach featuregate.Feature = "NodeOutOfServiceVolumeDetach"
|
||||
|
||||
// owner: @iholder101
|
||||
// owner: @iholder101 @kannon92
|
||||
// kep: https://kep.k8s.io/2400
|
||||
// alpha: v1.22
|
||||
// beta1: v1.28. For more info, please look at the KEP: https://kep.k8s.io/2400.
|
||||
//
|
||||
// Permits kubelet to run with swap enabled
|
||||
// beta1: v1.28 (default=false)
|
||||
// beta2: v.1.30 (default=true)
|
||||
|
||||
// Permits kubelet to run with swap enabled.
|
||||
NodeSwap featuregate.Feature = "NodeSwap"
|
||||
|
||||
// owner: @mortent, @atiratree, @ravig
|
||||
@ -664,6 +621,7 @@ const (
|
||||
// kep: http://kep.k8s.io/2681
|
||||
// alpha: v1.28
|
||||
// beta: v1.29
|
||||
// GA: v1.30
|
||||
//
|
||||
// Adds pod.status.hostIPs and downward API
|
||||
PodHostIPs featuregate.Feature = "PodHostIPs"
|
||||
@ -671,6 +629,7 @@ const (
|
||||
// owner: @AxeZhan
|
||||
// kep: http://kep.k8s.io/3960
|
||||
// alpha: v1.29
|
||||
// beta: v1.30
|
||||
//
|
||||
// Enables SleepAction in container lifecycle hooks
|
||||
PodLifecycleSleepAction featuregate.Feature = "PodLifecycleSleepAction"
|
||||
@ -679,25 +638,24 @@ const (
|
||||
// kep: https://kep.k8s.io/3521
|
||||
// alpha: v1.26
|
||||
// beta: v1.27
|
||||
// stable: v1.30
|
||||
//
|
||||
// Enable users to specify when a Pod is ready for scheduling.
|
||||
PodSchedulingReadiness featuregate.Feature = "PodSchedulingReadiness"
|
||||
|
||||
// owner: @seans3
|
||||
// kep: http://kep.k8s.io/4006
|
||||
// alpha: v1.30
|
||||
//
|
||||
// Enables PortForward to be proxied with a websocket client
|
||||
PortForwardWebsockets featuregate.Feature = "PortForwardWebsockets"
|
||||
|
||||
// owner: @jessfraz
|
||||
// alpha: v1.12
|
||||
//
|
||||
// Enables control over ProcMountType for containers.
|
||||
ProcMountType featuregate.Feature = "ProcMountType"
|
||||
|
||||
// owner: @andrewsykim
|
||||
// kep: https://kep.k8s.io/1669
|
||||
// alpha: v1.22
|
||||
// beta: v1.26
|
||||
// GA: v1.28
|
||||
//
|
||||
// Enable kube-proxy to handle terminating ednpoints when externalTrafficPolicy=Local
|
||||
ProxyTerminatingEndpoints featuregate.Feature = "ProxyTerminatingEndpoints"
|
||||
|
||||
// owner: @sjenning
|
||||
// alpha: v1.11
|
||||
//
|
||||
@ -721,6 +679,13 @@ const (
|
||||
// Allow users to recover from volume expansion failure
|
||||
RecoverVolumeExpansionFailure featuregate.Feature = "RecoverVolumeExpansionFailure"
|
||||
|
||||
// owner: @HirazawaUi
|
||||
// kep: https://kep.k8s.io/4369
|
||||
// alpha: v1.30
|
||||
//
|
||||
// Allow almost all printable ASCII characters in environment variables
|
||||
RelaxedEnvironmentVariableValidation featuregate.Feature = "RelaxedEnvironmentVariableValidation"
|
||||
|
||||
// owner: @mikedanese
|
||||
// alpha: v1.7
|
||||
// beta: v1.12
|
||||
@ -754,14 +719,6 @@ const (
|
||||
// which benefits to reduce the useless requeueing.
|
||||
SchedulerQueueingHints featuregate.Feature = "SchedulerQueueingHints"
|
||||
|
||||
// owner: @mtardy
|
||||
// alpha: v1.0
|
||||
//
|
||||
// Putting this admission plugin behind a feature gate is part of the
|
||||
// deprecation process. For details about the removal see:
|
||||
// https://github.com/kubernetes/kubernetes/issues/111516
|
||||
SecurityContextDeny featuregate.Feature = "SecurityContextDeny"
|
||||
|
||||
// owner: @atosatto @yuanchen8911
|
||||
// kep: http://kep.k8s.io/3902
|
||||
// beta: v1.29
|
||||
@ -772,6 +729,7 @@ const (
|
||||
// owner: @munnerz
|
||||
// kep: http://kep.k8s.io/4193
|
||||
// alpha: v1.29
|
||||
// beta: v1.30
|
||||
//
|
||||
// Controls whether JTIs (UUIDs) are embedded into generated service account tokens, and whether these JTIs are
|
||||
// recorded into the audit log for future requests made by these tokens.
|
||||
@ -787,6 +745,7 @@ const (
|
||||
// owner: @munnerz
|
||||
// kep: http://kep.k8s.io/4193
|
||||
// alpha: v1.29
|
||||
// beta: v1.30
|
||||
//
|
||||
// Controls whether the apiserver will validate Node claims in service account tokens.
|
||||
ServiceAccountTokenNodeBindingValidation featuregate.Feature = "ServiceAccountTokenNodeBindingValidation"
|
||||
@ -794,6 +753,7 @@ const (
|
||||
// owner: @munnerz
|
||||
// kep: http://kep.k8s.io/4193
|
||||
// alpha: v1.29
|
||||
// beta: v1.30
|
||||
//
|
||||
// Controls whether the apiserver embeds the node name and uid for the associated node when issuing
|
||||
// service account tokens bound to Pod objects.
|
||||
@ -808,9 +768,17 @@ const (
|
||||
// Subdivide the NodePort range for dynamic and static port allocation.
|
||||
ServiceNodePortStaticSubrange featuregate.Feature = "ServiceNodePortStaticSubrange"
|
||||
|
||||
// owner: @gauravkghildiyal @robscott
|
||||
// kep: https://kep.k8s.io/4444
|
||||
// alpha: v1.30
|
||||
//
|
||||
// Enables trafficDistribution field on Services.
|
||||
ServiceTrafficDistribution featuregate.Feature = "ServiceTrafficDistribution"
|
||||
|
||||
// owner: @gjkim42 @SergeyKanzhelev @matthyx @tzneal
|
||||
// kep: http://kep.k8s.io/753
|
||||
// alpha: v1.28
|
||||
// beta: v1.29
|
||||
//
|
||||
// Introduces sidecar containers, a new type of init container that starts
|
||||
// before other containers but remains running for the full duration of the
|
||||
@ -827,6 +795,7 @@ const (
|
||||
// owner: @alexanderConstantinescu
|
||||
// kep: http://kep.k8s.io/3458
|
||||
// beta: v1.27
|
||||
// GA: v1.30
|
||||
//
|
||||
// Enables less load balancer re-configurations by the service controller
|
||||
// (KCCM) as an effect of changing node state.
|
||||
@ -846,6 +815,13 @@ const (
|
||||
// Enables a StatefulSet to start from an arbitrary non zero ordinal
|
||||
StatefulSetStartOrdinal featuregate.Feature = "StatefulSetStartOrdinal"
|
||||
|
||||
// owner: @nilekhc
|
||||
// kep: https://kep.k8s.io/4192
|
||||
// alpha: v1.30
|
||||
|
||||
// Enables support for the StorageVersionMigrator controller.
|
||||
StorageVersionMigrator featuregate.Feature = "StorageVersionMigrator"
|
||||
|
||||
// owner: @robscott
|
||||
// kep: https://kep.k8s.io/2433
|
||||
// alpha: v1.21
|
||||
@ -882,6 +858,14 @@ const (
|
||||
// Allow the usage of options to fine-tune the topology manager policies.
|
||||
TopologyManagerPolicyOptions featuregate.Feature = "TopologyManagerPolicyOptions"
|
||||
|
||||
// owner: @seans3
|
||||
// kep: http://kep.k8s.io/4006
|
||||
// beta: v1.30
|
||||
//
|
||||
// Enables StreamTranslator proxy to handle WebSockets upgrade requests for the
|
||||
// version of the RemoteCommand subprotocol that supports the "close" signal.
|
||||
TranslateStreamCloseWebsocketRequests featuregate.Feature = "TranslateStreamCloseWebsocketRequests"
|
||||
|
||||
// owner: @richabanker
|
||||
// alpha: v1.28
|
||||
//
|
||||
@ -891,6 +875,7 @@ const (
|
||||
// owner: @rata, @giuseppe
|
||||
// kep: https://kep.k8s.io/127
|
||||
// alpha: v1.25
|
||||
// beta: v1.30
|
||||
//
|
||||
// Enables user namespace support for stateless pods.
|
||||
UserNamespacesSupport featuregate.Feature = "UserNamespacesSupport"
|
||||
@ -951,15 +936,17 @@ const (
|
||||
// Enables In-Place Pod Vertical Scaling
|
||||
InPlacePodVerticalScaling featuregate.Feature = "InPlacePodVerticalScaling"
|
||||
|
||||
// owner: @Sh4d1,@RyanAoh
|
||||
// owner: @Sh4d1,@RyanAoh,@rikatz
|
||||
// kep: http://kep.k8s.io/1860
|
||||
// alpha: v1.29
|
||||
// beta: v1.30
|
||||
// LoadBalancerIPMode enables the IPMode field in the LoadBalancerIngress status of a Service
|
||||
LoadBalancerIPMode featuregate.Feature = "LoadBalancerIPMode"
|
||||
|
||||
// owner: @haircommander
|
||||
// kep: http://kep.k8s.io/4210
|
||||
// alpha: v1.29
|
||||
// beta: v1.30
|
||||
// ImageMaximumGCAge enables the Kubelet configuration field of the same name, allowing an admin
|
||||
// to specify the age after which an image will be garbage collected.
|
||||
ImageMaximumGCAge featuregate.Feature = "ImageMaximumGCAge"
|
||||
@ -975,10 +962,39 @@ const (
|
||||
// will not graduate or be enabled by default in future Kubernetes
|
||||
// releases.
|
||||
UserNamespacesPodSecurityStandards featuregate.Feature = "UserNamespacesPodSecurityStandards"
|
||||
|
||||
// owner: @ahutsunshine
|
||||
// beta: v1.30
|
||||
//
|
||||
// Allows namespace indexer for namespace scope resources in apiserver cache to accelerate list operations.
|
||||
StorageNamespaceIndex featuregate.Feature = "StorageNamespaceIndex"
|
||||
|
||||
// owner: @jsafrane
|
||||
// kep: https://kep.k8s.io/1710
|
||||
// alpha: v1.30
|
||||
// Speed up container startup by mounting volumes with the correct SELinux label
|
||||
// instead of changing each file on the volumes recursively.
|
||||
SELinuxMount featuregate.Feature = "SELinuxMount"
|
||||
|
||||
// owner: @AkihiroSuda
|
||||
// kep: https://kep.k8s.io/3857
|
||||
// alpha: v1.30
|
||||
//
|
||||
// Allows recursive read-only mounts.
|
||||
RecursiveReadOnlyMounts featuregate.Feature = "RecursiveReadOnlyMounts"
|
||||
)
|
||||
|
||||
func init() {
|
||||
runtime.Must(utilfeature.DefaultMutableFeatureGate.Add(defaultKubernetesFeatureGates))
|
||||
|
||||
// Register all client-go features with kube's feature gate instance and make all client-go
|
||||
// feature checks use kube's instance. The effect is that for kube binaries, client-go
|
||||
// features are wired to the existing --feature-gates flag just as all other features
|
||||
// are. Further, client-go features automatically support the existing mechanisms for
|
||||
// feature enablement metrics and test overrides.
|
||||
ca := &clientAdapter{utilfeature.DefaultMutableFeatureGate}
|
||||
runtime.Must(clientfeatures.AddFeaturesToExistingFeatureGates(ca))
|
||||
clientfeatures.ReplaceFeatureGates(ca)
|
||||
}
|
||||
|
||||
// defaultKubernetesFeatureGates consists of all known Kubernetes-specific feature keys.
|
||||
@ -994,11 +1010,11 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
AnyVolumeDataSource: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.24
|
||||
|
||||
APISelfSubjectReview: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.28; remove in 1.30
|
||||
|
||||
AppArmor: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
CloudDualStackNodeIPs: {Default: true, PreRelease: featuregate.Beta},
|
||||
AppArmorFields: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
CloudDualStackNodeIPs: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
ClusterTrustBundle: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
@ -1014,8 +1030,6 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
CPUManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
CSIMigrationAzureFile: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
CSIMigrationPortworx: {Default: false, PreRelease: featuregate.Beta}, // Off by default (requires Portworx CSI driver)
|
||||
|
||||
CSIMigrationRBD: {Default: false, PreRelease: featuregate.Deprecated}, // deprecated in 1.28, remove in 1.31
|
||||
@ -1026,13 +1040,11 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
SkipReadOnlyValidationGCE: {Default: true, PreRelease: featuregate.Deprecated}, // remove in 1.31
|
||||
|
||||
TranslateStreamCloseWebsocketRequests: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
CloudControllerManagerWebhook: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ContainerCheckpoint: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ContainerCheckpoint: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
ConsistentHTTPGetHandlers: {Default: true, PreRelease: featuregate.GA},
|
||||
ConsistentHTTPGetHandlers: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
CronJobsScheduledAnnotation: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
@ -1052,18 +1064,18 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
ExecProbeTimeout: {Default: true, PreRelease: featuregate.GA}, // lock to default and remove after v1.22 based on KEP #1972 update
|
||||
|
||||
ExpandedDNSConfig: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: featuregate.Deprecated, LockToDefault: true}, // remove in 1.30
|
||||
RetryGenerateName: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
GracefulNodeShutdown: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
GracefulNodeShutdownBasedOnPodPriority: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
HPAContainerMetrics: {Default: true, PreRelease: featuregate.Beta},
|
||||
HPAContainerMetrics: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
HonorPVReclaimPolicy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ImageMaximumGCAge: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
InTreePluginAWSUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
InTreePluginAzureDiskUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
@ -1080,37 +1092,33 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
InTreePluginvSphereUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
IPTablesOwnershipCleanup: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
JobBackoffLimitPerIndex: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
JobManagedBy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
JobPodFailurePolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
JobPodReplacementPolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
JobSuccessPolicy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
JobReadyPods: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
KubeletCgroupDriverFromCRI: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletInUserNamespace: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletPodResources: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.28, remove in 1.30
|
||||
|
||||
KubeletPodResourcesDynamicResources: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletPodResourcesGet: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletPodResourcesGetAllocatable: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.28, remove in 1.30
|
||||
|
||||
KubeletSeparateDiskGC: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
KubeletTracing: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
KubeProxyDrainingTerminatingNodes: {Default: false, PreRelease: featuregate.Alpha},
|
||||
KubeProxyDrainingTerminatingNodes: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
LegacyServiceAccountTokenTracking: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
LegacyServiceAccountTokenCleanUp: {Default: true, PreRelease: featuregate.Beta},
|
||||
LegacyServiceAccountTokenCleanUp: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.30; remove in 1.32
|
||||
|
||||
LocalStorageCapacityIsolationFSQuotaMonitoring: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
@ -1126,21 +1134,19 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
MemoryQoS: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
MinDomainsInPodTopologySpread: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
MinimizeIPTablesRestore: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
MinDomainsInPodTopologySpread: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
MultiCIDRServiceAllocator: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
NewVolumeManagerReconstruction: {Default: true, PreRelease: featuregate.Beta},
|
||||
NewVolumeManagerReconstruction: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
NFTablesProxyMode: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
NodeLogQuery: {Default: false, PreRelease: featuregate.Alpha},
|
||||
NodeLogQuery: {Default: false, PreRelease: featuregate.Beta},
|
||||
|
||||
NodeOutOfServiceVolumeDetach: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
NodeSwap: {Default: false, PreRelease: featuregate.Beta},
|
||||
NodeSwap: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
PDBUnhealthyPodEvictionPolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
@ -1154,22 +1160,24 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
PodReadyToStartContainersCondition: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
PodHostIPs: {Default: true, PreRelease: featuregate.Beta},
|
||||
PodHostIPs: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
PodLifecycleSleepAction: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PodLifecycleSleepAction: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
PodSchedulingReadiness: {Default: true, PreRelease: featuregate.Beta},
|
||||
PodSchedulingReadiness: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.30; remove in 1.32
|
||||
|
||||
PortForwardWebsockets: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ProcMountType: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ProxyTerminatingEndpoints: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.30
|
||||
|
||||
QOSReserved: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ReadWriteOncePod: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
RecoverVolumeExpansionFailure: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
RelaxedEnvironmentVariableValidation: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
RotateKubeletServerCertificate: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
RuntimeClassInImageCriAPI: {Default: false, PreRelease: featuregate.Alpha},
|
||||
@ -1178,30 +1186,32 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
SchedulerQueueingHints: {Default: false, PreRelease: featuregate.Beta},
|
||||
|
||||
SecurityContextDeny: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
SeparateTaintEvictionController: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
ServiceAccountTokenJTI: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ServiceAccountTokenJTI: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
ServiceAccountTokenPodNodeInfo: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ServiceAccountTokenPodNodeInfo: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
ServiceAccountTokenNodeBinding: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ServiceAccountTokenNodeBindingValidation: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ServiceAccountTokenNodeBindingValidation: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
ServiceNodePortStaticSubrange: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.29; remove in 1.31
|
||||
|
||||
ServiceTrafficDistribution: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
SidecarContainers: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
SizeMemoryBackedVolumes: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
StableLoadBalancerNodeSet: {Default: true, PreRelease: featuregate.Beta},
|
||||
StableLoadBalancerNodeSet: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.30, remove in 1.31
|
||||
|
||||
StatefulSetAutoDeletePVC: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
StatefulSetStartOrdinal: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
StorageVersionMigrator: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
TopologyAwareHints: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
TopologyManagerPolicyAlphaOptions: {Default: false, PreRelease: featuregate.Alpha},
|
||||
@ -1210,13 +1220,15 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
TopologyManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
TranslateStreamCloseWebsocketRequests: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
UnknownVersionInteroperabilityProxy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
VolumeAttributesClass: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
VolumeCapacityPriority: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
UserNamespacesSupport: {Default: false, PreRelease: featuregate.Alpha},
|
||||
UserNamespacesSupport: {Default: false, PreRelease: featuregate.Beta},
|
||||
|
||||
WinDSR: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
@ -1232,18 +1244,18 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
PodIndexLabel: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
LoadBalancerIPMode: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ImageMaximumGCAge: {Default: false, PreRelease: featuregate.Alpha},
|
||||
LoadBalancerIPMode: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
UserNamespacesPodSecurityStandards: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
SELinuxMount: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
||||
genericfeatures.AdmissionWebhookMatchConditions: {Default: true, PreRelease: featuregate.Beta},
|
||||
genericfeatures.AdmissionWebhookMatchConditions: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
|
||||
genericfeatures.AggregatedDiscoveryEndpoint: {Default: true, PreRelease: featuregate.Beta},
|
||||
genericfeatures.AggregatedDiscoveryEndpoint: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||
|
||||
genericfeatures.APIListChunking: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
@ -1251,36 +1263,68 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
genericfeatures.APIResponseCompression: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.APIServerIdentity: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.APIServerTracing: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.APIServingWithRoutine: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.ConsistentListFromCache: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
genericfeatures.CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
genericfeatures.EfficientWatchResumption: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
|
||||
genericfeatures.KMSv1: {Default: false, PreRelease: featuregate.Deprecated},
|
||||
|
||||
genericfeatures.KMSv2: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
genericfeatures.KMSv2KDF: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
genericfeatures.ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
genericfeatures.MutatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
genericfeatures.OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.RemainingItemCount: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
|
||||
genericfeatures.SeparateCacheWatchRPC: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.ServerSideApply: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
|
||||
|
||||
genericfeatures.StructuredAuthorizationConfiguration: {Default: false, PreRelease: featuregate.Alpha},
|
||||
genericfeatures.StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
genericfeatures.StorageVersionHash: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.StructuredAuthenticationConfiguration: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.StructuredAuthorizationConfiguration: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.UnauthenticatedHTTP2DOSMitigation: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.ZeroLimitedNominalConcurrencyShares: {Default: false, PreRelease: featuregate.Beta},
|
||||
genericfeatures.ValidatingAdmissionPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
genericfeatures.WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
|
||||
genericfeatures.WatchFromStorageWithoutResourceVersion: {Default: false, PreRelease: featuregate.Beta},
|
||||
|
||||
genericfeatures.WatchList: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
genericfeatures.ZeroLimitedNominalConcurrencyShares: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
||||
apiextensionsfeatures.CRDValidationRatcheting: {Default: false, PreRelease: featuregate.Alpha},
|
||||
apiextensionsfeatures.CRDValidationRatcheting: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
apiextensionsfeatures.CustomResourceFieldSelectors: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
// features that enable backwards compatibility but are scheduled to be removed
|
||||
// ...
|
||||
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
StorageNamespaceIndex: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
RecursiveReadOnlyMounts: {Default: false, PreRelease: featuregate.Alpha},
|
||||
}
|
||||
|
27
vendor/k8s.io/kubernetes/pkg/util/filesystem/util.go
generated
vendored
Normal file
27
vendor/k8s.io/kubernetes/pkg/util/filesystem/util.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
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)
|
||||
}
|
6
vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go
generated
vendored
@ -22,6 +22,7 @@ package filesystem
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// IsUnixDomainSocket returns whether a given file is a AF_UNIX socket file
|
||||
@ -35,3 +36,8 @@ func IsUnixDomainSocket(filePath string) (bool, error) {
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// IsAbs is same as filepath.IsAbs on Unix.
|
||||
func IsAbs(path string) bool {
|
||||
return filepath.IsAbs(path)
|
||||
}
|
||||
|
12
vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go
generated
vendored
@ -23,6 +23,8 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
@ -85,3 +87,13 @@ func IsUnixDomainSocket(filePath string) (bool, error) {
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// 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, `/`)
|
||||
}
|
||||
|
127
vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go
generated
vendored
127
vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go
generated
vendored
@ -17,6 +17,10 @@ limitations under the License.
|
||||
package filesystem
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
@ -87,3 +91,126 @@ func (w *fsnotifyWatcher) Run() {
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
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/plugins.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
@ -1064,7 +1064,7 @@ func NewPersistentVolumeRecyclerPodTemplate() *v1.Pod {
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "pv-recycler",
|
||||
Image: "registry.k8s.io/build-image/debian-base:bookworm-v1.0.1",
|
||||
Image: "registry.k8s.io/build-image/debian-base:bookworm-v1.0.2",
|
||||
Command: []string{"/bin/sh"},
|
||||
Args: []string{"-c", "test -e /scrub && find /scrub -mindepth 1 -delete && test -z \"$(ls -A /scrub)\" || exit 1"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
|
106
vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go
generated
vendored
106
vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go
generated
vendored
@ -101,9 +101,9 @@ const (
|
||||
// portion of the payload was deleted and is still present on disk.
|
||||
//
|
||||
// 4. The data in the current timestamped directory is compared to the projected
|
||||
// data to determine if an update is required.
|
||||
// data to determine if an update to data directory is required.
|
||||
//
|
||||
// 5. A new timestamped dir is created.
|
||||
// 5. A new timestamped dir is created if an update is required.
|
||||
//
|
||||
// 6. The payload is written to the new timestamped directory.
|
||||
//
|
||||
@ -159,6 +159,7 @@ func (w *AtomicWriter) Write(payload map[string]FileProjection, setPerms func(su
|
||||
oldTsPath := filepath.Join(w.targetDir, oldTsDir)
|
||||
|
||||
var pathsToRemove sets.String
|
||||
shouldWrite := true
|
||||
// if there was no old version, there's nothing to remove
|
||||
if len(oldTsDir) != 0 {
|
||||
// (3)
|
||||
@ -173,57 +174,74 @@ func (w *AtomicWriter) Write(payload map[string]FileProjection, setPerms func(su
|
||||
klog.Errorf("%s: error determining whether payload should be written to disk: %v", w.logContext, err)
|
||||
return err
|
||||
} else if !should && len(pathsToRemove) == 0 {
|
||||
klog.V(4).Infof("%s: no update required for target directory %v", w.logContext, w.targetDir)
|
||||
return nil
|
||||
klog.V(4).Infof("%s: write not required for data directory %v", w.logContext, oldTsDir)
|
||||
// data directory is already up to date, but we need to make sure that
|
||||
// the user-visible symlinks are created.
|
||||
// See https://github.com/kubernetes/kubernetes/issues/121472 for more details.
|
||||
// Reset oldTsDir to empty string to avoid removing the data directory.
|
||||
shouldWrite = false
|
||||
oldTsDir = ""
|
||||
} else {
|
||||
klog.V(4).Infof("%s: write required for target directory %v", w.logContext, w.targetDir)
|
||||
}
|
||||
}
|
||||
|
||||
// (5)
|
||||
tsDir, err := w.newTimestampDir()
|
||||
if err != nil {
|
||||
klog.V(4).Infof("%s: error creating new ts data directory: %v", w.logContext, err)
|
||||
return err
|
||||
}
|
||||
tsDirName := filepath.Base(tsDir)
|
||||
|
||||
// (6)
|
||||
if err = w.writePayloadToDir(cleanPayload, tsDir); err != nil {
|
||||
klog.Errorf("%s: error writing payload to ts data directory %s: %v", w.logContext, tsDir, err)
|
||||
return err
|
||||
}
|
||||
klog.V(4).Infof("%s: performed write of new data to ts data directory: %s", w.logContext, tsDir)
|
||||
|
||||
// (7)
|
||||
if setPerms != nil {
|
||||
if err := setPerms(tsDirName); err != nil {
|
||||
klog.Errorf("%s: error applying ownership settings: %v", w.logContext, err)
|
||||
if shouldWrite {
|
||||
// (5)
|
||||
tsDir, err := w.newTimestampDir()
|
||||
if err != nil {
|
||||
klog.V(4).Infof("%s: error creating new ts data directory: %v", w.logContext, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
tsDirName := filepath.Base(tsDir)
|
||||
|
||||
// (8)
|
||||
newDataDirPath := filepath.Join(w.targetDir, newDataDirName)
|
||||
if err = os.Symlink(tsDirName, newDataDirPath); err != nil {
|
||||
os.RemoveAll(tsDir)
|
||||
klog.Errorf("%s: error creating symbolic link for atomic update: %v", w.logContext, err)
|
||||
return err
|
||||
}
|
||||
// (6)
|
||||
if err = w.writePayloadToDir(cleanPayload, tsDir); err != nil {
|
||||
klog.Errorf("%s: error writing payload to ts data directory %s: %v", w.logContext, tsDir, err)
|
||||
return err
|
||||
}
|
||||
klog.V(4).Infof("%s: performed write of new data to ts data directory: %s", w.logContext, tsDir)
|
||||
|
||||
// (9)
|
||||
if runtime.GOOS == "windows" {
|
||||
os.Remove(dataDirPath)
|
||||
err = os.Symlink(tsDirName, dataDirPath)
|
||||
os.Remove(newDataDirPath)
|
||||
} else {
|
||||
err = os.Rename(newDataDirPath, dataDirPath)
|
||||
}
|
||||
if err != nil {
|
||||
os.Remove(newDataDirPath)
|
||||
os.RemoveAll(tsDir)
|
||||
klog.Errorf("%s: error renaming symbolic link for data directory %s: %v", w.logContext, newDataDirPath, err)
|
||||
return err
|
||||
// (7)
|
||||
if setPerms != nil {
|
||||
if err := setPerms(tsDirName); err != nil {
|
||||
klog.Errorf("%s: error applying ownership settings: %v", w.logContext, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// (8)
|
||||
newDataDirPath := filepath.Join(w.targetDir, newDataDirName)
|
||||
if err = os.Symlink(tsDirName, newDataDirPath); err != nil {
|
||||
if err := os.RemoveAll(tsDir); err != nil {
|
||||
klog.Errorf("%s: error removing new ts directory %s: %v", w.logContext, tsDir, err)
|
||||
}
|
||||
klog.Errorf("%s: error creating symbolic link for atomic update: %v", w.logContext, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// (9)
|
||||
if runtime.GOOS == "windows" {
|
||||
if err := os.Remove(dataDirPath); err != nil {
|
||||
klog.Errorf("%s: error removing data dir directory %s: %v", w.logContext, dataDirPath, err)
|
||||
}
|
||||
err = os.Symlink(tsDirName, dataDirPath)
|
||||
if err := os.Remove(newDataDirPath); err != nil {
|
||||
klog.Errorf("%s: error removing new data dir directory %s: %v", w.logContext, newDataDirPath, err)
|
||||
}
|
||||
} else {
|
||||
err = os.Rename(newDataDirPath, dataDirPath)
|
||||
}
|
||||
if err != nil {
|
||||
if err := os.Remove(newDataDirPath); err != nil && err != os.ErrNotExist {
|
||||
klog.Errorf("%s: error removing new data dir directory %s: %v", w.logContext, newDataDirPath, err)
|
||||
}
|
||||
if err := os.RemoveAll(tsDir); err != nil {
|
||||
klog.Errorf("%s: error removing new ts directory %s: %v", w.logContext, tsDir, err)
|
||||
}
|
||||
klog.Errorf("%s: error renaming symbolic link for data directory %s: %v", w.logContext, newDataDirPath, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// (10)
|
||||
|
7
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil.go
generated
vendored
7
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil.go
generated
vendored
@ -41,6 +41,10 @@ const (
|
||||
FileTypeUnknown FileType = ""
|
||||
)
|
||||
|
||||
var (
|
||||
errUnknownFileType = fmt.Errorf("only recognise file, directory, socket, block device and character device")
|
||||
)
|
||||
|
||||
// HostUtils defines the set of methods for interacting with paths on a host.
|
||||
type HostUtils interface {
|
||||
// DeviceOpened determines if the device (e.g. /dev/sdc) is in use elsewhere
|
||||
@ -50,6 +54,7 @@ type HostUtils interface {
|
||||
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.
|
||||
@ -108,5 +113,5 @@ func getFileType(pathname string) (FileType, error) {
|
||||
return FileTypeBlockDev, nil
|
||||
}
|
||||
|
||||
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
|
||||
return pathType, errUnknownFileType
|
||||
}
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux.go
generated
vendored
@ -109,7 +109,7 @@ func (hu *HostUtil) GetDeviceNameFromMount(mounter mount.Interface, mountPath, p
|
||||
return getDeviceNameFromMount(mounter, mountPath, pluginMountDir)
|
||||
}
|
||||
|
||||
// getDeviceNameFromMountLinux find the device name from /proc/mounts in which
|
||||
// getDeviceNameFromMount find the device name from /proc/self/mountinfo in which
|
||||
// the mount path reference should match the given plugin mount directory. In case no mount path reference
|
||||
// matches, returns the volume name taken from its given mountPath
|
||||
func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) {
|
||||
|
5
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go
generated
vendored
@ -23,7 +23,6 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
@ -72,7 +71,7 @@ func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir s
|
||||
}
|
||||
}
|
||||
|
||||
return path.Base(mountPath), nil
|
||||
return filepath.Base(mountPath), nil
|
||||
}
|
||||
|
||||
// DeviceOpened determines if the device is in use elsewhere
|
||||
@ -106,7 +105,7 @@ func (hu *(HostUtil)) GetFileType(pathname string) (FileType, error) {
|
||||
|
||||
// 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 isSystemCannotAccessErr(err) {
|
||||
if err == errUnknownFileType || isSystemCannotAccessErr(err) {
|
||||
if isSocket, errSocket := filesystem.IsUnixDomainSocket(pathname); errSocket == nil && isSocket {
|
||||
return FileTypeSocket, nil
|
||||
}
|
||||
|
4
vendor/k8s.io/kubernetes/pkg/volume/util/selinux.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/volume/util/selinux.go
generated
vendored
@ -177,6 +177,10 @@ func VolumeSupportsSELinuxMount(volumeSpec *volume.Spec) bool {
|
||||
if len(volumeSpec.PersistentVolume.Spec.AccessModes) != 1 {
|
||||
return false
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMount) {
|
||||
return true
|
||||
}
|
||||
// Only SELinuxMountReadWriteOncePod feature enabled
|
||||
if !v1helper.ContainsAccessMode(volumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) {
|
||||
return false
|
||||
}
|
||||
|
Reference in New Issue
Block a user