mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
rebase: update kubernetes and libraries to v1.22.0 version
Kubernetes v1.22 version has been released and this update ceph csi dependencies to use the same version. Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
committed by
mergify[bot]
parent
e077c1fdf5
commit
aa698bc3e1
17
vendor/k8s.io/kubernetes/pkg/apis/apps/OWNERS
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/apis/apps/OWNERS
generated
vendored
@ -1,19 +1,8 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
# approval on api packages bubbles to api-approvers
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- deads2k
|
||||
- caesarxuchao
|
||||
- pmorie
|
||||
- sttts
|
||||
- saad-ali
|
||||
- ncdc
|
||||
- dims
|
||||
- errordeveloper
|
||||
- mml
|
||||
- m1093782566
|
||||
- kevin-wangzefeng
|
||||
- sig-apps-api-reviewers
|
||||
- sig-apps-api-approvers
|
||||
labels:
|
||||
- sig/apps
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/apis/apps/types.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/apis/apps/types.go
generated
vendored
@ -157,6 +157,13 @@ type StatefulSetSpec struct {
|
||||
// consists of all revisions not represented by a currently applied
|
||||
// StatefulSetSpec version. The default value is 10.
|
||||
RevisionHistoryLimit *int32
|
||||
|
||||
// Minimum number of seconds for which a newly created pod should be ready
|
||||
// without any of its container crashing for it to be considered available.
|
||||
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
||||
// This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.
|
||||
// +optional
|
||||
MinReadySeconds int32
|
||||
}
|
||||
|
||||
// StatefulSetStatus represents the current state of a StatefulSet.
|
||||
@ -196,6 +203,12 @@ type StatefulSetStatus struct {
|
||||
|
||||
// Represents the latest available observations of a statefulset's current state.
|
||||
Conditions []StatefulSetCondition
|
||||
|
||||
// Total number of available pods (ready for at least minReadySeconds) targeted by this statefulset.
|
||||
// This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.
|
||||
// Remove omitempty when graduating to beta
|
||||
// +optional
|
||||
AvailableReplicas int32
|
||||
}
|
||||
|
||||
// StatefulSetConditionType describes the condition types of StatefulSets.
|
||||
@ -532,7 +545,7 @@ type RollingUpdateDaemonSet struct {
|
||||
// The maximum number of DaemonSet pods that can be unavailable during the
|
||||
// update. Value can be an absolute number (ex: 5) or a percentage of total
|
||||
// number of DaemonSet pods at the start of the update (ex: 10%). Absolute
|
||||
// number is calculated from percentage by rounding down to a minimum of one.
|
||||
// number is calculated from percentage by rounding up.
|
||||
// This cannot be 0 if MaxSurge is 0
|
||||
// Default value is 1.
|
||||
// Example: when this is set to 30%, at most 30% of the total number of nodes
|
||||
@ -564,7 +577,7 @@ type RollingUpdateDaemonSet struct {
|
||||
// daemonset on any given node can double if the readiness check fails, and
|
||||
// so resource intensive daemonsets should take into account that they may
|
||||
// cause evictions during disruption.
|
||||
// This is an alpha field and requires enabling DaemonSetUpdateSurge feature gate.
|
||||
// This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate.
|
||||
// +optional
|
||||
MaxSurge intstr.IntOrString
|
||||
}
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/OWNERS
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/OWNERS
generated
vendored
@ -7,10 +7,8 @@ reviewers:
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- caesarxuchao
|
||||
- erictune
|
||||
- sttts
|
||||
- ncdc
|
||||
- piosz
|
||||
- dims
|
||||
- errordeveloper
|
||||
- mml
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/apis/batch/OWNERS
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/apis/batch/OWNERS
generated
vendored
@ -1,19 +1,8 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
# approval on api packages bubbles to api-approvers
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- caesarxuchao
|
||||
- erictune
|
||||
- sttts
|
||||
- saad-ali
|
||||
- ncdc
|
||||
- soltysh
|
||||
- dims
|
||||
- errordeveloper
|
||||
- mml
|
||||
- sig-apps-api-reviewers
|
||||
- sig-apps-api-approvers
|
||||
labels:
|
||||
- sig/apps
|
||||
|
55
vendor/k8s.io/kubernetes/pkg/apis/batch/types.go
generated
vendored
55
vendor/k8s.io/kubernetes/pkg/apis/batch/types.go
generated
vendored
@ -18,9 +18,18 @@ package batch
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
// JobTrackingFinalizer is a finalizer for Job's pods. It prevents them from
|
||||
// being deleted before being accounted in the Job status.
|
||||
// The apiserver and job controller use this string as a Job annotation, to
|
||||
// mark Jobs that are being tracked using pod finalizers. Two releases after
|
||||
// the JobTrackingWithFinalizers graduates to GA, JobTrackingFinalizer will
|
||||
// no longer be used as a Job annotation.
|
||||
const JobTrackingFinalizer = "batch.kubernetes.io/job-tracking"
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Job represents the configuration of a single job.
|
||||
@ -183,9 +192,11 @@ type JobSpec struct {
|
||||
// for each index.
|
||||
// When value is `Indexed`, .spec.completions must be specified and
|
||||
// `.spec.parallelism` must be less than or equal to 10^5.
|
||||
// In addition, The Pod name takes the form
|
||||
// `$(job-name)-$(index)-$(random-string)`,
|
||||
// the Pod hostname takes the form `$(job-name)-$(index)`.
|
||||
//
|
||||
// This field is alpha-level and is only honored by servers that enable the
|
||||
// IndexedJob feature gate. More completion modes can be added in the future.
|
||||
// This field is beta-level. More completion modes can be added in the future.
|
||||
// If the Job controller observes a mode that it doesn't recognize, the
|
||||
// controller skips updates for the Job.
|
||||
// +optional
|
||||
@ -197,9 +208,11 @@ type JobSpec struct {
|
||||
// false to true), the Job controller will delete all active Pods associated
|
||||
// with this Job. Users must design their workload to gracefully handle this.
|
||||
// Suspending a Job will reset the StartTime field of the Job, effectively
|
||||
// resetting the ActiveDeadlineSeconds timer too. This is an alpha field and
|
||||
// requires the SuspendJob feature gate to be enabled; otherwise this field
|
||||
// may not be set to true. Defaults to false.
|
||||
// resetting the ActiveDeadlineSeconds timer too. Defaults to false.
|
||||
//
|
||||
// This field is beta-level, gated by SuspendJob feature flag (enabled by
|
||||
// default).
|
||||
//
|
||||
// +optional
|
||||
Suspend *bool
|
||||
}
|
||||
@ -251,6 +264,38 @@ type JobStatus struct {
|
||||
// represented as "1,3-5,7".
|
||||
// +optional
|
||||
CompletedIndexes string
|
||||
|
||||
// UncountedTerminatedPods holds the UIDs of Pods that have terminated but
|
||||
// the job controller hasn't yet accounted for in the status counters.
|
||||
//
|
||||
// The job controller creates pods with a finalizer. When a pod terminates
|
||||
// (succeeded or failed), the controller does three steps to account for it
|
||||
// in the job status:
|
||||
// (1) Add the pod UID to the corresponding array in this field.
|
||||
// (2) Remove the pod finalizer.
|
||||
// (3) Remove the pod UID from the array while increasing the corresponding
|
||||
// counter.
|
||||
//
|
||||
// This field is alpha-level. The job controller only makes use of this field
|
||||
// when the feature gate PodTrackingWithFinalizers is enabled.
|
||||
// Old jobs might not be tracked using this field, in which case the field
|
||||
// remains null.
|
||||
// +optional
|
||||
UncountedTerminatedPods *UncountedTerminatedPods
|
||||
}
|
||||
|
||||
// UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't
|
||||
// been accounted in Job status counters.
|
||||
type UncountedTerminatedPods struct {
|
||||
// Succeeded holds UIDs of succeeded Pods.
|
||||
// +listType=set
|
||||
// +optional
|
||||
Succeeded []types.UID
|
||||
|
||||
// Failed holds UIDs of failed Pods.
|
||||
// +listType=set
|
||||
// +optional
|
||||
Failed []types.UID
|
||||
}
|
||||
|
||||
// JobConditionType is a valid value for JobCondition.Type
|
||||
|
32
vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
32
vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
@ -23,6 +23,7 @@ package batch
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
core "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
@ -312,6 +313,11 @@ func (in *JobStatus) DeepCopyInto(out *JobStatus) {
|
||||
in, out := &in.CompletionTime, &out.CompletionTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.UncountedTerminatedPods != nil {
|
||||
in, out := &in.UncountedTerminatedPods, &out.UncountedTerminatedPods
|
||||
*out = new(UncountedTerminatedPods)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -369,3 +375,29 @@ func (in *JobTemplateSpec) DeepCopy() *JobTemplateSpec {
|
||||
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
|
||||
if in.Succeeded != nil {
|
||||
in, out := &in.Succeeded, &out.Succeeded
|
||||
*out = make([]types.UID, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Failed != nil {
|
||||
in, out := &in.Failed, &out.Failed
|
||||
*out = make([]types.UID, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UncountedTerminatedPods.
|
||||
func (in *UncountedTerminatedPods) DeepCopy() *UncountedTerminatedPods {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UncountedTerminatedPods)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
36
vendor/k8s.io/kubernetes/pkg/apis/core/OWNERS
generated
vendored
36
vendor/k8s.io/kubernetes/pkg/apis/core/OWNERS
generated
vendored
@ -1,40 +1,4 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- thockin
|
||||
- liggitt
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- yujuhong
|
||||
- brendandburns
|
||||
- derekwaynecarr
|
||||
- caesarxuchao
|
||||
- vishh
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- erictune
|
||||
- davidopp
|
||||
- pmorie
|
||||
- sttts
|
||||
- dchen1107
|
||||
- saad-ali
|
||||
- luxas
|
||||
- janetkuo
|
||||
- justinsb
|
||||
- pwittrock
|
||||
- ncdc
|
||||
- tallclair
|
||||
- yifan-gu
|
||||
- mwielgus
|
||||
- soltysh
|
||||
- piosz
|
||||
- jsafrane
|
||||
labels:
|
||||
- sig/apps
|
||||
|
5
vendor/k8s.io/kubernetes/pkg/apis/core/annotation_key_constants.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/apis/core/annotation_key_constants.go
generated
vendored
@ -23,9 +23,6 @@ const (
|
||||
// webhook backend fails.
|
||||
ImagePolicyFailedOpenKey string = "alpha.image-policy.k8s.io/failed-open"
|
||||
|
||||
// PodPresetOptOutAnnotationKey represents the annotation key for a pod to exempt itself from pod preset manipulation
|
||||
PodPresetOptOutAnnotationKey string = "podpreset.admission.kubernetes.io/exclude"
|
||||
|
||||
// MirrorPodAnnotationKey represents the annotation key set by kubelets when creating mirror pods
|
||||
MirrorPodAnnotationKey string = "kubernetes.io/config.mirror"
|
||||
|
||||
@ -122,7 +119,7 @@ const (
|
||||
// pod deletion order.
|
||||
// The implicit deletion cost for pods that don't set the annotation is 0, negative values are permitted.
|
||||
//
|
||||
// This annotation is alpha-level and is only honored when PodDeletionCost feature is enabled.
|
||||
// This annotation is beta-level and is only honored when PodDeletionCost feature is enabled.
|
||||
PodDeletionCost = "controller.kubernetes.io/pod-deletion-cost"
|
||||
|
||||
// AnnotationTopologyAwareHints can be used to enable or disable Topology
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go
generated
vendored
@ -303,19 +303,22 @@ func IsStandardFinalizerName(str string) bool {
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns a string representation of an array of access modes.
|
||||
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
||||
// modes, when present, are always in the same order: RWO,ROX,RWX,RWOP.
|
||||
func GetAccessModesAsString(modes []core.PersistentVolumeAccessMode) string {
|
||||
modes = removeDuplicateAccessModes(modes)
|
||||
modesStr := []string{}
|
||||
if containsAccessMode(modes, core.ReadWriteOnce) {
|
||||
if ContainsAccessMode(modes, core.ReadWriteOnce) {
|
||||
modesStr = append(modesStr, "RWO")
|
||||
}
|
||||
if containsAccessMode(modes, core.ReadOnlyMany) {
|
||||
if ContainsAccessMode(modes, core.ReadOnlyMany) {
|
||||
modesStr = append(modesStr, "ROX")
|
||||
}
|
||||
if containsAccessMode(modes, core.ReadWriteMany) {
|
||||
if ContainsAccessMode(modes, core.ReadWriteMany) {
|
||||
modesStr = append(modesStr, "RWX")
|
||||
}
|
||||
if ContainsAccessMode(modes, core.ReadWriteOncePod) {
|
||||
modesStr = append(modesStr, "RWOP")
|
||||
}
|
||||
return strings.Join(modesStr, ",")
|
||||
}
|
||||
|
||||
@ -332,6 +335,8 @@ func GetAccessModesFromString(modes string) []core.PersistentVolumeAccessMode {
|
||||
accessModes = append(accessModes, core.ReadOnlyMany)
|
||||
case s == "RWX":
|
||||
accessModes = append(accessModes, core.ReadWriteMany)
|
||||
case s == "RWOP":
|
||||
accessModes = append(accessModes, core.ReadWriteOncePod)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
@ -341,14 +346,14 @@ func GetAccessModesFromString(modes string) []core.PersistentVolumeAccessMode {
|
||||
func removeDuplicateAccessModes(modes []core.PersistentVolumeAccessMode) []core.PersistentVolumeAccessMode {
|
||||
accessModes := []core.PersistentVolumeAccessMode{}
|
||||
for _, m := range modes {
|
||||
if !containsAccessMode(accessModes, m) {
|
||||
if !ContainsAccessMode(accessModes, m) {
|
||||
accessModes = append(accessModes, m)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
func containsAccessMode(modes []core.PersistentVolumeAccessMode, mode core.PersistentVolumeAccessMode) bool {
|
||||
func ContainsAccessMode(modes []core.PersistentVolumeAccessMode, mode core.PersistentVolumeAccessMode) bool {
|
||||
for _, m := range modes {
|
||||
if m == mode {
|
||||
return true
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/core/register.go
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/register.go
generated
vendored
@ -96,7 +96,6 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
&RangeAllocation{},
|
||||
&ConfigMap{},
|
||||
&ConfigMapList{},
|
||||
&EphemeralContainers{},
|
||||
)
|
||||
|
||||
return nil
|
||||
|
184
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
184
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
@ -450,13 +450,31 @@ type PersistentVolumeClaimSpec struct {
|
||||
// This field can be used to specify either:
|
||||
// * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
|
||||
// * An existing PVC (PersistentVolumeClaim)
|
||||
// * An existing custom resource that implements data population (Alpha)
|
||||
// In order to use custom resource types that implement data population,
|
||||
// the AnyVolumeDataSource feature gate must be enabled.
|
||||
// If the provisioner or an external controller can support the specified data source,
|
||||
// it will create a new volume based on the contents of the specified data source.
|
||||
// If the AnyVolumeDataSource feature gate is enabled, this field will always have
|
||||
// the same contents as the DataSourceRef field.
|
||||
// +optional
|
||||
DataSource *TypedLocalObjectReference
|
||||
// Specifies the object from which to populate the volume with data, if a non-empty
|
||||
// volume is desired. This may be any local object from a non-empty API group (non
|
||||
// core object) or a PersistentVolumeClaim object.
|
||||
// When this field is specified, volume binding will only succeed if the type of
|
||||
// the specified object matches some installed volume populator or dynamic
|
||||
// provisioner.
|
||||
// This field will replace the functionality of the DataSource field and as such
|
||||
// if both fields are non-empty, they must have the same value. For backwards
|
||||
// compatibility, both fields (DataSource and DataSourceRef) will be set to the same
|
||||
// value automatically if one of them is empty and the other is non-empty.
|
||||
// There are two important differences between DataSource and DataSourceRef:
|
||||
// * While DataSource only allows two specific types of objects, DataSourceRef
|
||||
// allows any non-core object, as well as PersistentVolumeClaim objects.
|
||||
// * While DataSource ignores disallowed values (dropping them), DataSourceRef
|
||||
// preserves all values, and generates an error if a disallowed value is
|
||||
// specified.
|
||||
// (Alpha) Using this field requires the AnyVolumeDataSource feature gate to be enabled.
|
||||
// +optional
|
||||
DataSourceRef *TypedLocalObjectReference
|
||||
}
|
||||
|
||||
// PersistentVolumeClaimConditionType defines the condition of PV claim.
|
||||
@ -511,6 +529,9 @@ const (
|
||||
ReadOnlyMany PersistentVolumeAccessMode = "ReadOnlyMany"
|
||||
// can be mounted in read/write mode to many hosts
|
||||
ReadWriteMany PersistentVolumeAccessMode = "ReadWriteMany"
|
||||
// can be mounted read/write mode to exactly 1 pod
|
||||
// cannot be used in combination with other access modes
|
||||
ReadWriteOncePod PersistentVolumeAccessMode = "ReadWriteOncePod"
|
||||
)
|
||||
|
||||
// PersistentVolumePhase defines the phase in which a PV is
|
||||
@ -1826,12 +1847,13 @@ type EnvVar struct {
|
||||
Name string
|
||||
// Optional: no more than one of the following may be specified.
|
||||
// Optional: Defaults to ""; variable references $(VAR_NAME) are expanded
|
||||
// using the previous defined environment variables in the container and
|
||||
// using the previously defined environment variables in the container and
|
||||
// any service environment variables. If a variable cannot be resolved,
|
||||
// the reference in the input string will be unchanged. The $(VAR_NAME)
|
||||
// syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped
|
||||
// references will never be expanded, regardless of whether the variable
|
||||
// exists or not.
|
||||
// the reference in the input string will be unchanged. Double $$ are
|
||||
// reduced to a single $, which allows for escaping the $(VAR_NAME)
|
||||
// syntax: i.e. "$$(VAR_NAME)" will produce the string literal
|
||||
// "$(VAR_NAME)". Escaped references will never be expanded,
|
||||
// regardless of whether the variable exists or not.
|
||||
// +optional
|
||||
Value string
|
||||
// Optional: Specifies a source the value of this var should come from.
|
||||
@ -2028,7 +2050,7 @@ type Probe struct {
|
||||
// value overrides the value provided by the pod spec.
|
||||
// Value must be non-negative integer. The value zero indicates stop immediately via
|
||||
// the kill signal (no opportunity to shut down).
|
||||
// This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
// This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
// +optional
|
||||
TerminationGracePeriodSeconds *int64
|
||||
}
|
||||
@ -2102,16 +2124,18 @@ type Container struct {
|
||||
Image string
|
||||
// Optional: The docker image's entrypoint is used if this is not provided; cannot be updated.
|
||||
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
|
||||
// cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax
|
||||
// can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
|
||||
// regardless of whether the variable exists or not.
|
||||
// cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced
|
||||
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
|
||||
// produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless
|
||||
// of whether the variable exists or not.
|
||||
// +optional
|
||||
Command []string
|
||||
// Optional: The docker image's cmd is used if this is not provided; cannot be updated.
|
||||
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
|
||||
// cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax
|
||||
// can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
|
||||
// regardless of whether the variable exists or not.
|
||||
// cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced
|
||||
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
|
||||
// produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless
|
||||
// of whether the variable exists or not.
|
||||
// +optional
|
||||
Args []string
|
||||
// Optional: Defaults to Docker's default.
|
||||
@ -2304,6 +2328,7 @@ const (
|
||||
PodFailed PodPhase = "Failed"
|
||||
// PodUnknown means that for some reason the state of the pod could not be obtained, typically due
|
||||
// to an error in communicating with the host of the pod.
|
||||
// Deprecated in v1.21: It isn't being set since 2015 (74da3b14b0c0f658b3bb8d2def5094686d0e9095)
|
||||
PodUnknown PodPhase = "Unknown"
|
||||
)
|
||||
|
||||
@ -2579,7 +2604,7 @@ type PodAffinityTerm struct {
|
||||
// and the ones listed in the namespaces field.
|
||||
// null selector and null or empty namespaces list means "this pod's namespace".
|
||||
// An empty selector ({}) matches all namespaces.
|
||||
// This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
// This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
// +optional
|
||||
NamespaceSelector *metav1.LabelSelector
|
||||
}
|
||||
@ -2832,14 +2857,14 @@ type PodSpec struct {
|
||||
// If specified, all readiness gates will be evaluated for pod readiness.
|
||||
// A pod is ready when all its containers are ready AND
|
||||
// all conditions specified in the readiness gates have status equal to "True"
|
||||
// More info: https://git.k8s.io/enhancements/keps/sig-network/0007-pod-ready%2B%2B.md
|
||||
// More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates
|
||||
// +optional
|
||||
ReadinessGates []PodReadinessGate
|
||||
// RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used
|
||||
// to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run.
|
||||
// If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an
|
||||
// empty definition that uses the default runtime handler.
|
||||
// More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class/README.md
|
||||
// More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class
|
||||
// +optional
|
||||
RuntimeClassName *string
|
||||
// Overhead represents the resource overhead associated with running a pod for a given RuntimeClass.
|
||||
@ -2848,8 +2873,8 @@ type PodSpec struct {
|
||||
// The RuntimeClass admission controller will reject Pod create requests which have the overhead already
|
||||
// set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value
|
||||
// defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero.
|
||||
// More info: https://git.k8s.io/enhancements/keps/sig-node/20190226-pod-overhead.md
|
||||
// This field is alpha-level as of Kubernetes v1.16, and is only honored by servers that enable the PodOverhead feature.
|
||||
// More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead
|
||||
// This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.
|
||||
// +optional
|
||||
Overhead ResourceList
|
||||
// EnableServiceLinks indicates whether information about services should be injected into pod's
|
||||
@ -3078,16 +3103,18 @@ type EphemeralContainerCommon struct {
|
||||
Image string
|
||||
// Optional: The docker image's entrypoint is used if this is not provided; cannot be updated.
|
||||
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
|
||||
// cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax
|
||||
// can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
|
||||
// regardless of whether the variable exists or not.
|
||||
// cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced
|
||||
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
|
||||
// produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless
|
||||
// of whether the variable exists or not.
|
||||
// +optional
|
||||
Command []string
|
||||
// Optional: The docker image's cmd is used if this is not provided; cannot be updated.
|
||||
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
|
||||
// cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax
|
||||
// can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
|
||||
// regardless of whether the variable exists or not.
|
||||
// cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced
|
||||
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
|
||||
// produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless
|
||||
// of whether the variable exists or not.
|
||||
// +optional
|
||||
Args []string
|
||||
// Optional: Defaults to Docker's default.
|
||||
@ -3134,7 +3161,8 @@ type EphemeralContainerCommon struct {
|
||||
TerminationMessagePolicy TerminationMessagePolicy
|
||||
// Required: Policy for pulling images for this container
|
||||
ImagePullPolicy PullPolicy
|
||||
// SecurityContext is not allowed for ephemeral containers.
|
||||
// Optional: SecurityContext defines the security options the ephemeral container should be run with.
|
||||
// If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.
|
||||
// +optional
|
||||
SecurityContext *SecurityContext
|
||||
|
||||
@ -3554,11 +3582,6 @@ type LoadBalancerIngress struct {
|
||||
Ports []PortStatus
|
||||
}
|
||||
|
||||
const (
|
||||
// MaxServiceTopologyKeys is the largest number of topology keys allowed on a service
|
||||
MaxServiceTopologyKeys = 16
|
||||
)
|
||||
|
||||
// IPFamily represents the IP Family (IPv4 or IPv6). This type is used
|
||||
// to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies).
|
||||
type IPFamily string
|
||||
@ -3726,29 +3749,14 @@ type ServiceSpec struct {
|
||||
// +optional
|
||||
PublishNotReadyAddresses bool
|
||||
|
||||
// topologyKeys is a preference-order list of topology keys which
|
||||
// implementations of services should use to preferentially sort endpoints
|
||||
// when accessing this Service, it can not be used at the same time as
|
||||
// externalTrafficPolicy=Local.
|
||||
// Topology keys must be valid label keys and at most 16 keys may be specified.
|
||||
// Endpoints are chosen based on the first topology key with available backends.
|
||||
// If this field is specified and all entries have no backends that match
|
||||
// the topology of the client, the service has no backends for that client
|
||||
// and connections should fail.
|
||||
// The special value "*" may be used to mean "any topology". This catch-all
|
||||
// value, if used, only makes sense as the last value in the list.
|
||||
// If this is not specified or empty, no topology constraints will be applied.
|
||||
// This field is alpha-level and is only honored by servers that enable the ServiceTopology feature.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
TopologyKeys []string
|
||||
|
||||
// allocateLoadBalancerNodePorts defines if NodePorts will be automatically
|
||||
// allocated for services with type LoadBalancer. Default is "true". It may be
|
||||
// set to "false" if the cluster load-balancer does not rely on NodePorts.
|
||||
// allocateLoadBalancerNodePorts may only be set for services with type LoadBalancer
|
||||
// and will be cleared if the type is changed to any other type.
|
||||
// This field is alpha-level and is only honored by servers that enable the ServiceLBNodePortControl feature.
|
||||
// allocated for services with type LoadBalancer. Default is "true". It
|
||||
// may be set to "false" if the cluster load-balancer does not rely on
|
||||
// NodePorts. If the caller requests specific NodePorts (by specifying a
|
||||
// value), those requests will be respected, regardless of this field.
|
||||
// This field may only be set for services with type LoadBalancer and will
|
||||
// be cleared if the type is changed to any other type.
|
||||
// This field is beta-level and is only honored by servers that enable the ServiceLBNodePortControl feature.
|
||||
// +optional
|
||||
AllocateLoadBalancerNodePorts *bool
|
||||
|
||||
@ -4200,6 +4208,7 @@ type PodSignature struct {
|
||||
// ContainerImage describe a container image
|
||||
type ContainerImage struct {
|
||||
// Names by which this image is known.
|
||||
// +optional
|
||||
Names []string
|
||||
// The size of the image in bytes.
|
||||
// +optional
|
||||
@ -4255,11 +4264,44 @@ type NodeAddressType string
|
||||
|
||||
// These are valid values of node address type
|
||||
const (
|
||||
NodeHostName NodeAddressType = "Hostname"
|
||||
NodeExternalIP NodeAddressType = "ExternalIP"
|
||||
NodeInternalIP NodeAddressType = "InternalIP"
|
||||
NodeExternalDNS NodeAddressType = "ExternalDNS"
|
||||
// NodeHostName identifies a name of the node. Although every node can be assumed
|
||||
// to have a NodeAddress of this type, its exact syntax and semantics are not
|
||||
// defined, and are not consistent between different clusters.
|
||||
NodeHostName NodeAddressType = "Hostname"
|
||||
|
||||
// NodeInternalIP identifies an IP address which is assigned to one of the node's
|
||||
// network interfaces. Every node should have at least one address of this type.
|
||||
//
|
||||
// An internal IP is normally expected to be reachable from every other node, but
|
||||
// may not be visible to hosts outside the cluster. By default it is assumed that
|
||||
// kube-apiserver can reach node internal IPs, though it is possible to configure
|
||||
// clusters where this is not the case.
|
||||
//
|
||||
// NodeInternalIP is the default type of node IP, and does not necessarily imply
|
||||
// that the IP is ONLY reachable internally. If a node has multiple internal IPs,
|
||||
// no specific semantics are assigned to the additional IPs.
|
||||
NodeInternalIP NodeAddressType = "InternalIP"
|
||||
|
||||
// NodeExternalIP identifies an IP address which is, in some way, intended to be
|
||||
// more usable from outside the cluster then an internal IP, though no specific
|
||||
// semantics are defined. It may be a globally routable IP, though it is not
|
||||
// required to be.
|
||||
//
|
||||
// External IPs may be assigned directly to an interface on the node, like a
|
||||
// NodeInternalIP, or alternatively, packets sent to the external IP may be NAT'ed
|
||||
// to an internal node IP rather than being delivered directly (making the IP less
|
||||
// efficient for node-to-node traffic than a NodeInternalIP).
|
||||
NodeExternalIP NodeAddressType = "ExternalIP"
|
||||
|
||||
// NodeInternalDNS identifies a DNS name which resolves to an IP address which has
|
||||
// the characteristics of a NodeInternalIP. The IP it resolves to may or may not
|
||||
// be a listed NodeInternalIP address.
|
||||
NodeInternalDNS NodeAddressType = "InternalDNS"
|
||||
|
||||
// NodeExternalDNS identifies a DNS name which resolves to an IP address which has
|
||||
// the characteristics of a NodeExternalIP. The IP it resolves to may or may not
|
||||
// be a listed NodeExternalIP address.
|
||||
NodeExternalDNS NodeAddressType = "ExternalDNS"
|
||||
)
|
||||
|
||||
// NodeAddress represents node's address
|
||||
@ -4439,20 +4481,6 @@ type Binding struct {
|
||||
Target ObjectReference
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// EphemeralContainers is a list of ephemeral containers used with the Pod ephemeralcontainers subresource.
|
||||
type EphemeralContainers struct {
|
||||
metav1.TypeMeta
|
||||
// +optional
|
||||
metav1.ObjectMeta
|
||||
|
||||
// A list of ephemeral containers associated with this pod. New ephemeral containers
|
||||
// may be appended to this list, but existing ephemeral containers may not be removed
|
||||
// or modified.
|
||||
EphemeralContainers []EphemeralContainer
|
||||
}
|
||||
|
||||
// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
|
||||
type Preconditions struct {
|
||||
// Specifies the target UID.
|
||||
@ -4900,7 +4928,7 @@ const (
|
||||
// Match all pod objects that have priority class mentioned
|
||||
ResourceQuotaScopePriorityClass ResourceQuotaScope = "PriorityClass"
|
||||
// Match all pod objects that have cross-namespace pod (anti)affinity mentioned
|
||||
// This is an alpha feature enabled by the PodAffinityNamespaceSelector feature flag.
|
||||
// This is a beta feature enabled by the PodAffinityNamespaceSelector feature flag.
|
||||
ResourceQuotaScopeCrossNamespacePodAffinity ResourceQuotaScope = "CrossNamespacePodAffinity"
|
||||
)
|
||||
|
||||
@ -5364,6 +5392,16 @@ type WindowsSecurityContextOptions struct {
|
||||
// PodSecurityContext, the value specified in SecurityContext takes precedence.
|
||||
// +optional
|
||||
RunAsUserName *string
|
||||
|
||||
// HostProcess determines if a container should be run as a 'Host Process' container.
|
||||
// This field is alpha-level and will only be honored by components that enable the
|
||||
// WindowsHostProcessContainers feature flag. Setting this field without the feature
|
||||
// flag will result in errors when validating the Pod. All of a Pod's containers must
|
||||
// have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
|
||||
// containers and non-HostProcess containers). In addition, if HostProcess is true
|
||||
// then HostNetwork must also be set to true.
|
||||
// +optional
|
||||
HostProcess *bool
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/OWNERS
generated
vendored
@ -13,7 +13,6 @@ reviewers:
|
||||
- vishh
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- erictune
|
||||
- davidopp
|
||||
- pmorie
|
||||
- sttts
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go
generated
vendored
@ -170,19 +170,22 @@ func ingressEqual(lhs, rhs *v1.LoadBalancerIngress) bool {
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns a string representation of an array of access modes.
|
||||
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
||||
// modes, when present, are always in the same order: RWO,ROX,RWX,RWOP.
|
||||
func GetAccessModesAsString(modes []v1.PersistentVolumeAccessMode) string {
|
||||
modes = removeDuplicateAccessModes(modes)
|
||||
modesStr := []string{}
|
||||
if containsAccessMode(modes, v1.ReadWriteOnce) {
|
||||
if ContainsAccessMode(modes, v1.ReadWriteOnce) {
|
||||
modesStr = append(modesStr, "RWO")
|
||||
}
|
||||
if containsAccessMode(modes, v1.ReadOnlyMany) {
|
||||
if ContainsAccessMode(modes, v1.ReadOnlyMany) {
|
||||
modesStr = append(modesStr, "ROX")
|
||||
}
|
||||
if containsAccessMode(modes, v1.ReadWriteMany) {
|
||||
if ContainsAccessMode(modes, v1.ReadWriteMany) {
|
||||
modesStr = append(modesStr, "RWX")
|
||||
}
|
||||
if ContainsAccessMode(modes, v1.ReadWriteOncePod) {
|
||||
modesStr = append(modesStr, "RWOP")
|
||||
}
|
||||
return strings.Join(modesStr, ",")
|
||||
}
|
||||
|
||||
@ -199,6 +202,8 @@ func GetAccessModesFromString(modes string) []v1.PersistentVolumeAccessMode {
|
||||
accessModes = append(accessModes, v1.ReadOnlyMany)
|
||||
case s == "RWX":
|
||||
accessModes = append(accessModes, v1.ReadWriteMany)
|
||||
case s == "RWOP":
|
||||
accessModes = append(accessModes, v1.ReadWriteOncePod)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
@ -208,14 +213,14 @@ func GetAccessModesFromString(modes string) []v1.PersistentVolumeAccessMode {
|
||||
func removeDuplicateAccessModes(modes []v1.PersistentVolumeAccessMode) []v1.PersistentVolumeAccessMode {
|
||||
accessModes := []v1.PersistentVolumeAccessMode{}
|
||||
for _, m := range modes {
|
||||
if !containsAccessMode(accessModes, m) {
|
||||
if !ContainsAccessMode(accessModes, m) {
|
||||
accessModes = append(accessModes, m)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
func containsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
|
||||
func ContainsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
|
||||
for _, m := range modes {
|
||||
if m == mode {
|
||||
return true
|
||||
|
38
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
38
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
@ -531,16 +531,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.EphemeralContainers)(nil), (*core.EphemeralContainers)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_EphemeralContainers_To_core_EphemeralContainers(a.(*v1.EphemeralContainers), b.(*core.EphemeralContainers), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*core.EphemeralContainers)(nil), (*v1.EphemeralContainers)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_core_EphemeralContainers_To_v1_EphemeralContainers(a.(*core.EphemeralContainers), b.(*v1.EphemeralContainers), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.EphemeralVolumeSource)(nil), (*core.EphemeralVolumeSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_EphemeralVolumeSource_To_core_EphemeralVolumeSource(a.(*v1.EphemeralVolumeSource), b.(*core.EphemeralVolumeSource), scope)
|
||||
}); err != nil {
|
||||
@ -3522,28 +3512,6 @@ func Convert_core_EphemeralContainerCommon_To_v1_EphemeralContainerCommon(in *co
|
||||
return autoConvert_core_EphemeralContainerCommon_To_v1_EphemeralContainerCommon(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_EphemeralContainers_To_core_EphemeralContainers(in *v1.EphemeralContainers, out *core.EphemeralContainers, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.EphemeralContainers = *(*[]core.EphemeralContainer)(unsafe.Pointer(&in.EphemeralContainers))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_EphemeralContainers_To_core_EphemeralContainers is an autogenerated conversion function.
|
||||
func Convert_v1_EphemeralContainers_To_core_EphemeralContainers(in *v1.EphemeralContainers, out *core.EphemeralContainers, s conversion.Scope) error {
|
||||
return autoConvert_v1_EphemeralContainers_To_core_EphemeralContainers(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_EphemeralContainers_To_v1_EphemeralContainers(in *core.EphemeralContainers, out *v1.EphemeralContainers, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.EphemeralContainers = *(*[]v1.EphemeralContainer)(unsafe.Pointer(&in.EphemeralContainers))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_core_EphemeralContainers_To_v1_EphemeralContainers is an autogenerated conversion function.
|
||||
func Convert_core_EphemeralContainers_To_v1_EphemeralContainers(in *core.EphemeralContainers, out *v1.EphemeralContainers, s conversion.Scope) error {
|
||||
return autoConvert_core_EphemeralContainers_To_v1_EphemeralContainers(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_EphemeralVolumeSource_To_core_EphemeralVolumeSource(in *v1.EphemeralVolumeSource, out *core.EphemeralVolumeSource, s conversion.Scope) error {
|
||||
out.VolumeClaimTemplate = (*core.PersistentVolumeClaimTemplate)(unsafe.Pointer(in.VolumeClaimTemplate))
|
||||
return nil
|
||||
@ -5149,6 +5117,7 @@ func autoConvert_v1_PersistentVolumeClaimSpec_To_core_PersistentVolumeClaimSpec(
|
||||
out.StorageClassName = (*string)(unsafe.Pointer(in.StorageClassName))
|
||||
out.VolumeMode = (*core.PersistentVolumeMode)(unsafe.Pointer(in.VolumeMode))
|
||||
out.DataSource = (*core.TypedLocalObjectReference)(unsafe.Pointer(in.DataSource))
|
||||
out.DataSourceRef = (*core.TypedLocalObjectReference)(unsafe.Pointer(in.DataSourceRef))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -5167,6 +5136,7 @@ func autoConvert_core_PersistentVolumeClaimSpec_To_v1_PersistentVolumeClaimSpec(
|
||||
out.StorageClassName = (*string)(unsafe.Pointer(in.StorageClassName))
|
||||
out.VolumeMode = (*v1.PersistentVolumeMode)(unsafe.Pointer(in.VolumeMode))
|
||||
out.DataSource = (*v1.TypedLocalObjectReference)(unsafe.Pointer(in.DataSource))
|
||||
out.DataSourceRef = (*v1.TypedLocalObjectReference)(unsafe.Pointer(in.DataSourceRef))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -7631,7 +7601,6 @@ func autoConvert_v1_ServiceSpec_To_core_ServiceSpec(in *v1.ServiceSpec, out *cor
|
||||
out.HealthCheckNodePort = in.HealthCheckNodePort
|
||||
out.PublishNotReadyAddresses = in.PublishNotReadyAddresses
|
||||
out.SessionAffinityConfig = (*core.SessionAffinityConfig)(unsafe.Pointer(in.SessionAffinityConfig))
|
||||
out.TopologyKeys = *(*[]string)(unsafe.Pointer(&in.TopologyKeys))
|
||||
out.IPFamilies = *(*[]core.IPFamily)(unsafe.Pointer(&in.IPFamilies))
|
||||
out.IPFamilyPolicy = (*core.IPFamilyPolicyType)(unsafe.Pointer(in.IPFamilyPolicy))
|
||||
out.AllocateLoadBalancerNodePorts = (*bool)(unsafe.Pointer(in.AllocateLoadBalancerNodePorts))
|
||||
@ -7662,7 +7631,6 @@ func autoConvert_core_ServiceSpec_To_v1_ServiceSpec(in *core.ServiceSpec, out *v
|
||||
out.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyType(in.ExternalTrafficPolicy)
|
||||
out.HealthCheckNodePort = in.HealthCheckNodePort
|
||||
out.PublishNotReadyAddresses = in.PublishNotReadyAddresses
|
||||
out.TopologyKeys = *(*[]string)(unsafe.Pointer(&in.TopologyKeys))
|
||||
out.AllocateLoadBalancerNodePorts = (*bool)(unsafe.Pointer(in.AllocateLoadBalancerNodePorts))
|
||||
out.LoadBalancerClass = (*string)(unsafe.Pointer(in.LoadBalancerClass))
|
||||
out.InternalTrafficPolicy = (*v1.ServiceInternalTrafficPolicyType)(unsafe.Pointer(in.InternalTrafficPolicy))
|
||||
@ -8244,6 +8212,7 @@ func autoConvert_v1_WindowsSecurityContextOptions_To_core_WindowsSecurityContext
|
||||
out.GMSACredentialSpecName = (*string)(unsafe.Pointer(in.GMSACredentialSpecName))
|
||||
out.GMSACredentialSpec = (*string)(unsafe.Pointer(in.GMSACredentialSpec))
|
||||
out.RunAsUserName = (*string)(unsafe.Pointer(in.RunAsUserName))
|
||||
out.HostProcess = (*bool)(unsafe.Pointer(in.HostProcess))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -8256,6 +8225,7 @@ func autoConvert_core_WindowsSecurityContextOptions_To_v1_WindowsSecurityContext
|
||||
out.GMSACredentialSpecName = (*string)(unsafe.Pointer(in.GMSACredentialSpecName))
|
||||
out.GMSACredentialSpec = (*string)(unsafe.Pointer(in.GMSACredentialSpec))
|
||||
out.RunAsUserName = (*string)(unsafe.Pointer(in.RunAsUserName))
|
||||
out.HostProcess = (*bool)(unsafe.Pointer(in.HostProcess))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
54
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.defaults.go
generated
vendored
54
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.defaults.go
generated
vendored
@ -33,7 +33,6 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&v1.ConfigMapList{}, func(obj interface{}) { SetObjectDefaults_ConfigMapList(obj.(*v1.ConfigMapList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.Endpoints{}, func(obj interface{}) { SetObjectDefaults_Endpoints(obj.(*v1.Endpoints)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.EndpointsList{}, func(obj interface{}) { SetObjectDefaults_EndpointsList(obj.(*v1.EndpointsList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.EphemeralContainers{}, func(obj interface{}) { SetObjectDefaults_EphemeralContainers(obj.(*v1.EphemeralContainers)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.LimitRange{}, func(obj interface{}) { SetObjectDefaults_LimitRange(obj.(*v1.LimitRange)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.LimitRangeList{}, func(obj interface{}) { SetObjectDefaults_LimitRangeList(obj.(*v1.LimitRangeList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.Namespace{}, func(obj interface{}) { SetObjectDefaults_Namespace(obj.(*v1.Namespace)) })
|
||||
@ -85,59 +84,6 @@ func SetObjectDefaults_EndpointsList(in *v1.EndpointsList) {
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_EphemeralContainers(in *v1.EphemeralContainers) {
|
||||
for i := range in.EphemeralContainers {
|
||||
a := &in.EphemeralContainers[i]
|
||||
SetDefaults_EphemeralContainer(a)
|
||||
for j := range a.EphemeralContainerCommon.Ports {
|
||||
b := &a.EphemeralContainerCommon.Ports[j]
|
||||
if b.Protocol == "" {
|
||||
b.Protocol = "TCP"
|
||||
}
|
||||
}
|
||||
for j := range a.EphemeralContainerCommon.Env {
|
||||
b := &a.EphemeralContainerCommon.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDefaults_ResourceList(&a.EphemeralContainerCommon.Resources.Limits)
|
||||
SetDefaults_ResourceList(&a.EphemeralContainerCommon.Resources.Requests)
|
||||
if a.EphemeralContainerCommon.LivenessProbe != nil {
|
||||
SetDefaults_Probe(a.EphemeralContainerCommon.LivenessProbe)
|
||||
if a.EphemeralContainerCommon.LivenessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.EphemeralContainerCommon.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.EphemeralContainerCommon.ReadinessProbe != nil {
|
||||
SetDefaults_Probe(a.EphemeralContainerCommon.ReadinessProbe)
|
||||
if a.EphemeralContainerCommon.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.EphemeralContainerCommon.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.EphemeralContainerCommon.StartupProbe != nil {
|
||||
SetDefaults_Probe(a.EphemeralContainerCommon.StartupProbe)
|
||||
if a.EphemeralContainerCommon.StartupProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.EphemeralContainerCommon.StartupProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.EphemeralContainerCommon.Lifecycle != nil {
|
||||
if a.EphemeralContainerCommon.Lifecycle.PostStart != nil {
|
||||
if a.EphemeralContainerCommon.Lifecycle.PostStart.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.EphemeralContainerCommon.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.EphemeralContainerCommon.Lifecycle.PreStop != nil {
|
||||
if a.EphemeralContainerCommon.Lifecycle.PreStop.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.EphemeralContainerCommon.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_LimitRange(in *v1.LimitRange) {
|
||||
for i := range in.Spec.Limits {
|
||||
a := &in.Spec.Limits[i]
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/core/validation/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/validation/OWNERS
generated
vendored
@ -13,7 +13,6 @@ reviewers:
|
||||
- vishh
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- erictune
|
||||
- davidopp
|
||||
- pmorie
|
||||
- sttts
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/apis/core/validation/events.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/core/validation/events.go
generated
vendored
@ -109,7 +109,7 @@ func validateV1EventSeries(event *core.Event) field.ErrorList {
|
||||
zeroTime := time.Time{}
|
||||
if event.Series != nil {
|
||||
if event.Series.Count < 2 {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("series.count"), "", fmt.Sprintf("should be at least 2")))
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("series.count"), "", "should be at least 2"))
|
||||
}
|
||||
if event.Series.LastObservedTime.Time == zeroTime {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("series.lastObservedTime"), ""))
|
||||
|
386
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
386
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
@ -35,7 +35,6 @@ import (
|
||||
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||
v1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
@ -49,7 +48,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
podshelper "k8s.io/kubernetes/pkg/apis/core/pods"
|
||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||
"k8s.io/kubernetes/pkg/capabilities"
|
||||
"k8s.io/kubernetes/pkg/cluster/ports"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
@ -86,6 +84,7 @@ var allowedEphemeralContainerFields = map[string]bool{
|
||||
"TerminationMessagePath": true,
|
||||
"TerminationMessagePolicy": true,
|
||||
"ImagePullPolicy": true,
|
||||
"SecurityContext": true,
|
||||
"Stdin": true,
|
||||
"StdinOnce": true,
|
||||
"TTY": true,
|
||||
@ -283,7 +282,7 @@ var ValidateClusterName = apimachineryvalidation.ValidateClusterName
|
||||
// (where it should be) and this file.
|
||||
var ValidateClassName = apimachineryvalidation.NameIsDNSSubdomain
|
||||
|
||||
// ValidatePiorityClassName can be used to check whether the given priority
|
||||
// ValidatePriorityClassName can be used to check whether the given priority
|
||||
// class name is valid.
|
||||
var ValidatePriorityClassName = apimachineryvalidation.NameIsDNSSubdomain
|
||||
|
||||
@ -1217,8 +1216,8 @@ func validateMountPropagation(mountPropagation *core.MountPropagationMode, conta
|
||||
}
|
||||
|
||||
if container == nil {
|
||||
// The container is not available yet, e.g. during validation of
|
||||
// PodPreset. Stop validation now, Pod validation will refuse final
|
||||
// The container is not available yet.
|
||||
// Stop validation now, Pod validation will refuse final
|
||||
// Pods with Bidirectional propagation in non-privileged containers.
|
||||
return allErrs
|
||||
}
|
||||
@ -1609,22 +1608,23 @@ func validateEphemeralVolumeSource(ephemeral *core.EphemeralVolumeSource, fldPat
|
||||
if ephemeral.VolumeClaimTemplate == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("volumeClaimTemplate"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimTemplate(ephemeral.VolumeClaimTemplate, fldPath.Child("volumeClaimTemplate"))...)
|
||||
opts := ValidationOptionsForPersistentVolumeClaimTemplate(ephemeral.VolumeClaimTemplate, nil)
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimTemplate(ephemeral.VolumeClaimTemplate, fldPath.Child("volumeClaimTemplate"), opts)...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeClaimTemplate verifies that the embedded object meta and spec are valid.
|
||||
// Checking of the object data is very minimal because only labels and annotations are used.
|
||||
func ValidatePersistentVolumeClaimTemplate(claimTemplate *core.PersistentVolumeClaimTemplate, fldPath *field.Path) field.ErrorList {
|
||||
func ValidatePersistentVolumeClaimTemplate(claimTemplate *core.PersistentVolumeClaimTemplate, fldPath *field.Path, opts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||
allErrs := validatePersistentVolumeClaimTemplateObjectMeta(&claimTemplate.ObjectMeta, fldPath.Child("metadata"))
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&claimTemplate.Spec, fldPath.Child("spec"))...)
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&claimTemplate.Spec, fldPath.Child("spec"), opts)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validatePersistentVolumeClaimTemplateObjectMeta(objMeta *metav1.ObjectMeta, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := apimachineryvalidation.ValidateAnnotations(objMeta.Annotations, fldPath.Child("annotations"))
|
||||
allErrs = append(allErrs, v1validation.ValidateLabels(objMeta.Labels, fldPath.Child("labels"))...)
|
||||
allErrs = append(allErrs, unversionedvalidation.ValidateLabels(objMeta.Labels, fldPath.Child("labels"))...)
|
||||
// All other fields are not supported and thus must not be set
|
||||
// to avoid confusion. We could reject individual fields,
|
||||
// but then adding a new one to ObjectMeta wouldn't be checked
|
||||
@ -1639,6 +1639,12 @@ var allowedPVCTemplateObjectMetaFields = map[string]bool{
|
||||
"Labels": true,
|
||||
}
|
||||
|
||||
// PersistentVolumeSpecValidationOptions contains the different settings for PeristentVolume validation
|
||||
type PersistentVolumeSpecValidationOptions struct {
|
||||
// Allow spec to contain the "ReadWiteOncePod" access mode
|
||||
AllowReadWriteOncePod bool
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeName checks that a name is appropriate for a
|
||||
// PersistentVolumeName object.
|
||||
var ValidatePersistentVolumeName = apimachineryvalidation.NameIsDNSSubdomain
|
||||
@ -1649,7 +1655,22 @@ var supportedReclaimPolicy = sets.NewString(string(core.PersistentVolumeReclaimD
|
||||
|
||||
var supportedVolumeModes = sets.NewString(string(core.PersistentVolumeBlock), string(core.PersistentVolumeFilesystem))
|
||||
|
||||
func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName string, validateInlinePersistentVolumeSpec bool, fldPath *field.Path) field.ErrorList {
|
||||
func ValidationOptionsForPersistentVolume(pv, oldPv *core.PersistentVolume) PersistentVolumeSpecValidationOptions {
|
||||
opts := PersistentVolumeSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
}
|
||||
if oldPv == nil {
|
||||
// If there's no old PV, use the options based solely on feature enablement
|
||||
return opts
|
||||
}
|
||||
if helper.ContainsAccessMode(oldPv.Spec.AccessModes, core.ReadWriteOncePod) {
|
||||
// If the old object allowed "ReadWriteOncePod", continue to allow it in the new object
|
||||
opts.AllowReadWriteOncePod = true
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName string, validateInlinePersistentVolumeSpec bool, fldPath *field.Path, opts PersistentVolumeSpecValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if validateInlinePersistentVolumeSpec {
|
||||
@ -1667,10 +1688,26 @@ func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName stri
|
||||
if len(pvSpec.AccessModes) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("accessModes"), ""))
|
||||
}
|
||||
|
||||
expandedSupportedAccessModes := sets.StringKeySet(supportedAccessModes)
|
||||
if opts.AllowReadWriteOncePod {
|
||||
expandedSupportedAccessModes.Insert(string(core.ReadWriteOncePod))
|
||||
}
|
||||
|
||||
foundReadWriteOncePod, foundNonReadWriteOncePod := false, false
|
||||
for _, mode := range pvSpec.AccessModes {
|
||||
if !supportedAccessModes.Has(string(mode)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, supportedAccessModes.List()))
|
||||
if !expandedSupportedAccessModes.Has(string(mode)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, expandedSupportedAccessModes.List()))
|
||||
}
|
||||
|
||||
if mode == core.ReadWriteOncePod {
|
||||
foundReadWriteOncePod = true
|
||||
} else if supportedAccessModes.Has(string(mode)) {
|
||||
foundNonReadWriteOncePod = true
|
||||
}
|
||||
}
|
||||
if foundReadWriteOncePod && foundNonReadWriteOncePod {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("accessModes"), "may not use ReadWriteOncePod with other access modes"))
|
||||
}
|
||||
|
||||
if !validateInlinePersistentVolumeSpec {
|
||||
@ -1923,17 +1960,17 @@ func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName stri
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidatePersistentVolume(pv *core.PersistentVolume) field.ErrorList {
|
||||
func ValidatePersistentVolume(pv *core.PersistentVolume, opts PersistentVolumeSpecValidationOptions) field.ErrorList {
|
||||
metaPath := field.NewPath("metadata")
|
||||
allErrs := ValidateObjectMeta(&pv.ObjectMeta, false, ValidatePersistentVolumeName, metaPath)
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeSpec(&pv.Spec, pv.ObjectMeta.Name, false, field.NewPath("spec"))...)
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeSpec(&pv.Spec, pv.ObjectMeta.Name, false, field.NewPath("spec"), opts)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeUpdate tests to see if the update is legal for an end user to make.
|
||||
// newPv is updated with fields that cannot be changed.
|
||||
func ValidatePersistentVolumeUpdate(newPv, oldPv *core.PersistentVolume) field.ErrorList {
|
||||
allErrs := ValidatePersistentVolume(newPv)
|
||||
func ValidatePersistentVolumeUpdate(newPv, oldPv *core.PersistentVolume, opts PersistentVolumeSpecValidationOptions) field.ErrorList {
|
||||
allErrs := ValidatePersistentVolume(newPv, opts)
|
||||
|
||||
// if oldPV does not have ControllerExpandSecretRef then allow it to be set
|
||||
if (oldPv.Spec.CSI != nil && oldPv.Spec.CSI.ControllerExpandSecretRef == nil) &&
|
||||
@ -1966,15 +2003,72 @@ func ValidatePersistentVolumeStatusUpdate(newPv, oldPv *core.PersistentVolume) f
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// PersistentVolumeClaimSpecValidationOptions contains the different settings for PersistentVolumeClaim validation
|
||||
type PersistentVolumeClaimSpecValidationOptions struct {
|
||||
// Allow spec to contain the "ReadWiteOncePod" access mode
|
||||
AllowReadWriteOncePod bool
|
||||
}
|
||||
|
||||
func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolumeClaim) PersistentVolumeClaimSpecValidationOptions {
|
||||
opts := PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
}
|
||||
if oldPvc == nil {
|
||||
// If there's no old PVC, use the options based solely on feature enablement
|
||||
return opts
|
||||
}
|
||||
if helper.ContainsAccessMode(oldPvc.Spec.AccessModes, core.ReadWriteOncePod) {
|
||||
// If the old object allowed "ReadWriteOncePod", continue to allow it in the new object
|
||||
opts.AllowReadWriteOncePod = true
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func ValidationOptionsForPersistentVolumeClaimTemplate(claimTemplate, oldClaimTemplate *core.PersistentVolumeClaimTemplate) PersistentVolumeClaimSpecValidationOptions {
|
||||
opts := PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
}
|
||||
if oldClaimTemplate == nil {
|
||||
// If there's no old PVC template, use the options based solely on feature enablement
|
||||
return opts
|
||||
}
|
||||
if helper.ContainsAccessMode(oldClaimTemplate.Spec.AccessModes, core.ReadWriteOncePod) {
|
||||
// If the old object allowed "ReadWriteOncePod", continue to allow it in the new object
|
||||
opts.AllowReadWriteOncePod = true
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeClaim validates a PersistentVolumeClaim
|
||||
func ValidatePersistentVolumeClaim(pvc *core.PersistentVolumeClaim) field.ErrorList {
|
||||
func ValidatePersistentVolumeClaim(pvc *core.PersistentVolumeClaim, opts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||
allErrs := ValidateObjectMeta(&pvc.ObjectMeta, true, ValidatePersistentVolumeName, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&pvc.Spec, field.NewPath("spec"))...)
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&pvc.Spec, field.NewPath("spec"), opts)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateDataSource validates a DataSource/DataSourceRef in a PersistentVolumeClaimSpec
|
||||
func validateDataSource(dataSource *core.TypedLocalObjectReference, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if len(dataSource.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
|
||||
}
|
||||
if len(dataSource.Kind) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("kind"), ""))
|
||||
}
|
||||
apiGroup := ""
|
||||
if dataSource.APIGroup != nil {
|
||||
apiGroup = *dataSource.APIGroup
|
||||
}
|
||||
if len(apiGroup) == 0 && dataSource.Kind != "PersistentVolumeClaim" {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, dataSource.Kind, ""))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeClaimSpec validates a PersistentVolumeClaimSpec
|
||||
func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fldPath *field.Path) field.ErrorList {
|
||||
func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fldPath *field.Path, opts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(spec.AccessModes) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("accessModes"), "at least 1 access mode is required"))
|
||||
@ -1982,11 +2076,28 @@ func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fld
|
||||
if spec.Selector != nil {
|
||||
allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...)
|
||||
}
|
||||
|
||||
expandedSupportedAccessModes := sets.StringKeySet(supportedAccessModes)
|
||||
if opts.AllowReadWriteOncePod {
|
||||
expandedSupportedAccessModes.Insert(string(core.ReadWriteOncePod))
|
||||
}
|
||||
|
||||
foundReadWriteOncePod, foundNonReadWriteOncePod := false, false
|
||||
for _, mode := range spec.AccessModes {
|
||||
if mode != core.ReadWriteOnce && mode != core.ReadOnlyMany && mode != core.ReadWriteMany {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, supportedAccessModes.List()))
|
||||
if !expandedSupportedAccessModes.Has(string(mode)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, expandedSupportedAccessModes.List()))
|
||||
}
|
||||
|
||||
if mode == core.ReadWriteOncePod {
|
||||
foundReadWriteOncePod = true
|
||||
} else if supportedAccessModes.Has(string(mode)) {
|
||||
foundNonReadWriteOncePod = true
|
||||
}
|
||||
}
|
||||
if foundReadWriteOncePod && foundNonReadWriteOncePod {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("accessModes"), "may not use ReadWriteOncePod with other access modes"))
|
||||
}
|
||||
|
||||
storageValue, ok := spec.Resources.Requests[core.ResourceStorage]
|
||||
if !ok {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("resources").Key(string(core.ResourceStorage)), ""))
|
||||
@ -2006,18 +2117,15 @@ func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fld
|
||||
}
|
||||
|
||||
if spec.DataSource != nil {
|
||||
if len(spec.DataSource.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("dataSource", "name"), ""))
|
||||
}
|
||||
if len(spec.DataSource.Kind) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("dataSource", "kind"), ""))
|
||||
}
|
||||
apiGroup := ""
|
||||
if spec.DataSource.APIGroup != nil {
|
||||
apiGroup = *spec.DataSource.APIGroup
|
||||
}
|
||||
if len(apiGroup) == 0 && spec.DataSource.Kind != "PersistentVolumeClaim" {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("dataSource"), spec.DataSource.Kind, ""))
|
||||
allErrs = append(allErrs, validateDataSource(spec.DataSource, fldPath.Child("dataSource"))...)
|
||||
}
|
||||
if spec.DataSourceRef != nil {
|
||||
allErrs = append(allErrs, validateDataSource(spec.DataSourceRef, fldPath.Child("dataSourceRef"))...)
|
||||
}
|
||||
if spec.DataSource != nil && spec.DataSourceRef != nil {
|
||||
if !apiequality.Semantic.DeepEqual(spec.DataSource, spec.DataSourceRef) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, fldPath.Child("dataSource"),
|
||||
"must match dataSourceRef"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -2025,9 +2133,9 @@ func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fld
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeClaimUpdate validates an update to a PersistentVolumeClaim
|
||||
func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeClaim) field.ErrorList {
|
||||
func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeClaim, opts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||
allErrs := ValidateObjectMetaUpdate(&newPvc.ObjectMeta, &oldPvc.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeClaim(newPvc)...)
|
||||
allErrs = append(allErrs, ValidatePersistentVolumeClaim(newPvc, opts)...)
|
||||
newPvcClone := newPvc.DeepCopy()
|
||||
oldPvcClone := oldPvc.DeepCopy()
|
||||
|
||||
@ -2547,6 +2655,9 @@ func validateProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList {
|
||||
allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.PeriodSeconds), fldPath.Child("periodSeconds"))...)
|
||||
allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.SuccessThreshold), fldPath.Child("successThreshold"))...)
|
||||
allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.FailureThreshold), fldPath.Child("failureThreshold"))...)
|
||||
if probe.TerminationGracePeriodSeconds != nil && *probe.TerminationGracePeriodSeconds <= 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("terminationGracePeriodSeconds"), *probe.TerminationGracePeriodSeconds, "must be greater than 0"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -2962,10 +3073,14 @@ const (
|
||||
// restrictions in Linux libc name resolution handling.
|
||||
// Max number of DNS name servers.
|
||||
MaxDNSNameservers = 3
|
||||
// Max number of domains in search path.
|
||||
MaxDNSSearchPaths = 6
|
||||
// Max number of characters in search path.
|
||||
MaxDNSSearchListChars = 256
|
||||
// Expanded max number of domains in the search path list.
|
||||
MaxDNSSearchPathsExpanded = 32
|
||||
// Expanded max number of characters in the search path.
|
||||
MaxDNSSearchListCharsExpanded = 2048
|
||||
// Max number of domains in the search path list.
|
||||
MaxDNSSearchPathsLegacy = 6
|
||||
// Max number of characters in the search path list.
|
||||
MaxDNSSearchListCharsLegacy = 256
|
||||
)
|
||||
|
||||
func validateReadinessGates(readinessGates []core.PodReadinessGate, fldPath *field.Path) field.ErrorList {
|
||||
@ -2978,7 +3093,7 @@ func validateReadinessGates(readinessGates []core.PodReadinessGate, fldPath *fie
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validatePodDNSConfig(dnsConfig *core.PodDNSConfig, dnsPolicy *core.DNSPolicy, fldPath *field.Path) field.ErrorList {
|
||||
func validatePodDNSConfig(dnsConfig *core.PodDNSConfig, dnsPolicy *core.DNSPolicy, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// Validate DNSNone case. Must provide at least one DNS name server.
|
||||
@ -3002,12 +3117,16 @@ func validatePodDNSConfig(dnsConfig *core.PodDNSConfig, dnsPolicy *core.DNSPolic
|
||||
}
|
||||
}
|
||||
// Validate searches.
|
||||
if len(dnsConfig.Searches) > MaxDNSSearchPaths {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("searches"), dnsConfig.Searches, fmt.Sprintf("must not have more than %v search paths", MaxDNSSearchPaths)))
|
||||
maxDNSSearchPaths, maxDNSSearchListChars := MaxDNSSearchPathsLegacy, MaxDNSSearchListCharsLegacy
|
||||
if opts.AllowExpandedDNSConfig {
|
||||
maxDNSSearchPaths, maxDNSSearchListChars = MaxDNSSearchPathsExpanded, MaxDNSSearchListCharsExpanded
|
||||
}
|
||||
if len(dnsConfig.Searches) > maxDNSSearchPaths {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("searches"), dnsConfig.Searches, fmt.Sprintf("must not have more than %v search paths", maxDNSSearchPaths)))
|
||||
}
|
||||
// Include the space between search paths.
|
||||
if len(strings.Join(dnsConfig.Searches, " ")) > MaxDNSSearchListChars {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("searches"), dnsConfig.Searches, "must not have more than 256 characters (including spaces) in the search list"))
|
||||
if len(strings.Join(dnsConfig.Searches, " ")) > maxDNSSearchListChars {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("searches"), dnsConfig.Searches, fmt.Sprintf("must not have more than %v characters (including spaces) in the search list", maxDNSSearchListChars)))
|
||||
}
|
||||
for i, search := range dnsConfig.Searches {
|
||||
// it is fine to have a trailing dot
|
||||
@ -3197,31 +3316,16 @@ func validateContainersOnlyForPod(containers []core.Container, fldPath *field.Pa
|
||||
|
||||
// PodValidationOptions contains the different settings for pod validation
|
||||
type PodValidationOptions struct {
|
||||
// Allow pod spec to have more than one huge page resource (with different sizes)
|
||||
AllowMultipleHugePageResources bool
|
||||
// Allow pod spec to use hugepages in downward API
|
||||
AllowDownwardAPIHugePages bool
|
||||
// Allow invalid pod-deletion-cost annotation value for backward compatibility.
|
||||
AllowInvalidPodDeletionCost bool
|
||||
// Allow pod spec to use non-integer multiple of huge page unit size
|
||||
AllowIndivisibleHugePagesValues bool
|
||||
}
|
||||
|
||||
// ValidatePodSingleHugePageResources checks if there are multiple huge
|
||||
// pages resources in the pod object.
|
||||
func ValidatePodSingleHugePageResources(pod *core.Pod, specPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
resourceSet := helper.ToPodResourcesSet(&pod.Spec)
|
||||
hugePageResources := sets.NewString()
|
||||
for resourceStr := range resourceSet {
|
||||
if v1helper.IsHugePageResourceName(v1.ResourceName(resourceStr)) {
|
||||
hugePageResources.Insert(resourceStr)
|
||||
}
|
||||
}
|
||||
if len(hugePageResources) > 1 {
|
||||
allErrs = append(allErrs, field.Invalid(specPath, hugePageResources.List(), "must use a single hugepage size in a pod spec"))
|
||||
}
|
||||
return allErrs
|
||||
// Allow hostProcess field to be set in windows security context
|
||||
AllowWindowsHostProcessField bool
|
||||
// Allow more DNSSearchPaths and longer DNSSearchListChars
|
||||
AllowExpandedDNSConfig bool
|
||||
}
|
||||
|
||||
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
|
||||
@ -3253,10 +3357,6 @@ func validatePodMetadataAndSpec(pod *core.Pod, opts PodValidationOptions) field.
|
||||
allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.Containers, specPath.Child("containers"))...)
|
||||
allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.InitContainers, specPath.Child("initContainers"))...)
|
||||
|
||||
if !opts.AllowMultipleHugePageResources {
|
||||
allErrs = append(allErrs, ValidatePodSingleHugePageResources(pod, specPath)...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@ -3325,9 +3425,10 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi
|
||||
allErrs = append(allErrs, ValidatePodSecurityContext(spec.SecurityContext, spec, fldPath, fldPath.Child("securityContext"))...)
|
||||
allErrs = append(allErrs, validateImagePullSecrets(spec.ImagePullSecrets, fldPath.Child("imagePullSecrets"))...)
|
||||
allErrs = append(allErrs, validateAffinity(spec.Affinity, fldPath.Child("affinity"))...)
|
||||
allErrs = append(allErrs, validatePodDNSConfig(spec.DNSConfig, &spec.DNSPolicy, fldPath.Child("dnsConfig"))...)
|
||||
allErrs = append(allErrs, validatePodDNSConfig(spec.DNSConfig, &spec.DNSPolicy, fldPath.Child("dnsConfig"), opts)...)
|
||||
allErrs = append(allErrs, validateReadinessGates(spec.ReadinessGates, fldPath.Child("readinessGates"))...)
|
||||
allErrs = append(allErrs, validateTopologySpreadConstraints(spec.TopologySpreadConstraints, fldPath.Child("topologySpreadConstraints"))...)
|
||||
allErrs = append(allErrs, validateWindowsHostProcessPod(spec, fldPath, opts)...)
|
||||
if len(spec.ServiceAccountName) > 0 {
|
||||
for _, msg := range ValidateServiceAccountName(spec.ServiceAccountName, false) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("serviceAccountName"), spec.ServiceAccountName, msg))
|
||||
@ -3953,14 +4054,11 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel
|
||||
allErrs = append(allErrs, ValidatePodSpecificAnnotationUpdates(newPod, oldPod, fldPath.Child("annotations"), opts)...)
|
||||
specPath := field.NewPath("spec")
|
||||
|
||||
if !opts.AllowMultipleHugePageResources {
|
||||
allErrs = append(allErrs, ValidatePodSingleHugePageResources(newPod, specPath)...)
|
||||
}
|
||||
|
||||
// validate updateable fields:
|
||||
// 1. spec.containers[*].image
|
||||
// 2. spec.initContainers[*].image
|
||||
// 3. spec.activeDeadlineSeconds
|
||||
// 4. spec.terminationGracePeriodSeconds
|
||||
|
||||
containerErrs, stop := ValidateContainerUpdates(newPod.Spec.Containers, oldPod.Spec.Containers, specPath.Child("containers"))
|
||||
allErrs = append(allErrs, containerErrs...)
|
||||
@ -4027,11 +4125,17 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel
|
||||
// tolerations are checked before the deep copy, so munge those too
|
||||
mungedPodSpec.Tolerations = oldPod.Spec.Tolerations // +k8s:verify-mutation:reason=clone
|
||||
|
||||
// Relax validation of immutable fields to allow it to be set to 1 if it was previously negative.
|
||||
if oldPod.Spec.TerminationGracePeriodSeconds != nil && *oldPod.Spec.TerminationGracePeriodSeconds < 0 &&
|
||||
mungedPodSpec.TerminationGracePeriodSeconds != nil && *mungedPodSpec.TerminationGracePeriodSeconds == 1 {
|
||||
mungedPodSpec.TerminationGracePeriodSeconds = oldPod.Spec.TerminationGracePeriodSeconds // +k8s:verify-mutation:reason=clone
|
||||
}
|
||||
|
||||
if !apiequality.Semantic.DeepEqual(mungedPodSpec, oldPod.Spec) {
|
||||
// This diff isn't perfect, but it's a helluva lot better an "I'm not going to tell you what the difference is".
|
||||
//TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff
|
||||
specDiff := diff.ObjectDiff(mungedPodSpec, oldPod.Spec)
|
||||
allErrs = append(allErrs, field.Forbidden(specPath, fmt.Sprintf("pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds` or `spec.tolerations` (only additions to existing tolerations)\n%v", specDiff)))
|
||||
allErrs = append(allErrs, field.Forbidden(specPath, fmt.Sprintf("pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds`, `spec.tolerations` (only additions to existing tolerations) or `spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)\n%v", specDiff)))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
@ -4086,11 +4190,7 @@ func ValidatePodStatusUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions
|
||||
allErrs = append(allErrs, ValidateContainerStateTransition(newPod.Status.InitContainerStatuses, oldPod.Status.InitContainerStatuses, fldPath.Child("initContainerStatuses"), oldPod.Spec.RestartPolicy)...)
|
||||
|
||||
if newIPErrs := validatePodIPs(newPod); len(newIPErrs) > 0 {
|
||||
// Tolerate IP errors if IP errors already existed in the old pod. See http://issue.k8s.io/90625
|
||||
// TODO(liggitt): Drop the check of oldPod in 1.20
|
||||
if oldIPErrs := validatePodIPs(oldPod); len(oldIPErrs) == 0 {
|
||||
allErrs = append(allErrs, newIPErrs...)
|
||||
}
|
||||
allErrs = append(allErrs, newIPErrs...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
@ -4319,35 +4419,6 @@ func ValidateService(service *core.Service) field.ErrorList {
|
||||
ports[key] = true
|
||||
}
|
||||
|
||||
// Validate TopologyKeys
|
||||
if len(service.Spec.TopologyKeys) > 0 {
|
||||
topoPath := specPath.Child("topologyKeys")
|
||||
// topologyKeys is mutually exclusive with 'externalTrafficPolicy=Local'
|
||||
if service.Spec.ExternalTrafficPolicy == core.ServiceExternalTrafficPolicyTypeLocal {
|
||||
allErrs = append(allErrs, field.Forbidden(topoPath, "may not be specified when `externalTrafficPolicy=Local`"))
|
||||
}
|
||||
if len(service.Spec.TopologyKeys) > core.MaxServiceTopologyKeys {
|
||||
allErrs = append(allErrs, field.TooMany(topoPath, len(service.Spec.TopologyKeys), core.MaxServiceTopologyKeys))
|
||||
}
|
||||
topoKeys := sets.NewString()
|
||||
for i, key := range service.Spec.TopologyKeys {
|
||||
keyPath := topoPath.Index(i)
|
||||
if topoKeys.Has(key) {
|
||||
allErrs = append(allErrs, field.Duplicate(keyPath, key))
|
||||
}
|
||||
topoKeys.Insert(key)
|
||||
// "Any" must be the last value specified
|
||||
if key == v1.TopologyKeyAny && i != len(service.Spec.TopologyKeys)-1 {
|
||||
allErrs = append(allErrs, field.Invalid(keyPath, key, `"*" must be the last value specified`))
|
||||
}
|
||||
if key != v1.TopologyKeyAny {
|
||||
for _, msg := range validation.IsQualifiedName(key) {
|
||||
allErrs = append(allErrs, field.Invalid(keyPath, service.Spec.TopologyKeys, msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate SourceRange field and annotation
|
||||
_, ok := service.Annotations[core.AnnotationLoadBalancerSourceRangesKey]
|
||||
if len(service.Spec.LoadBalancerSourceRanges) > 0 || ok {
|
||||
@ -5408,7 +5479,7 @@ func ValidateResourceRequirements(requirements *core.ResourceRequirements, fldPa
|
||||
|
||||
}
|
||||
if !limContainsCPUOrMemory && !reqContainsCPUOrMemory && (reqContainsHugePages || limContainsHugePages) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath, fmt.Sprintf("HugePages require cpu or memory")))
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath, "HugePages require cpu or memory"))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
@ -5775,16 +5846,16 @@ func ValidateNonSpecialIP(ipAddress string, fldPath *field.Path) field.ErrorList
|
||||
return allErrs
|
||||
}
|
||||
if ip.IsUnspecified() {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, "may not be unspecified (0.0.0.0)"))
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, fmt.Sprintf("may not be unspecified (%v)", ipAddress)))
|
||||
}
|
||||
if ip.IsLoopback() {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, "may not be in the loopback range (127.0.0.0/8)"))
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, "may not be in the loopback range (127.0.0.0/8, ::1/128)"))
|
||||
}
|
||||
if ip.IsLinkLocalUnicast() {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, "may not be in the link-local range (169.254.0.0/16)"))
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, "may not be in the link-local range (169.254.0.0/16, fe80::/10)"))
|
||||
}
|
||||
if ip.IsLinkLocalMulticast() {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, "may not be in the link-local multicast range (224.0.0.0/24)"))
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, "may not be in the link-local multicast range (224.0.0.0/24, ff02::/10)"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
@ -5927,10 +5998,10 @@ func validateWindowsSecurityContextOptions(windowsOptions *core.WindowsSecurityC
|
||||
if l := len(*windowsOptions.RunAsUserName); l == 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fieldPath.Child("runAsUserName"), windowsOptions.RunAsUserName, "runAsUserName cannot be an empty string"))
|
||||
} else if ctrlRegex.MatchString(*windowsOptions.RunAsUserName) {
|
||||
errMsg := fmt.Sprintf("runAsUserName cannot contain control characters")
|
||||
errMsg := "runAsUserName cannot contain control characters"
|
||||
allErrs = append(allErrs, field.Invalid(fieldPath.Child("runAsUserName"), windowsOptions.RunAsUserName, errMsg))
|
||||
} else if parts := strings.Split(*windowsOptions.RunAsUserName, "\\"); len(parts) > 2 {
|
||||
errMsg := fmt.Sprintf("runAsUserName cannot contain more than one backslash")
|
||||
errMsg := "runAsUserName cannot contain more than one backslash"
|
||||
allErrs = append(allErrs, field.Invalid(fieldPath.Child("runAsUserName"), windowsOptions.RunAsUserName, errMsg))
|
||||
} else {
|
||||
var (
|
||||
@ -5957,7 +6028,7 @@ func validateWindowsSecurityContextOptions(windowsOptions *core.WindowsSecurityC
|
||||
}
|
||||
|
||||
if l := len(user); l == 0 {
|
||||
errMsg := fmt.Sprintf("runAsUserName's User cannot be empty")
|
||||
errMsg := "runAsUserName's User cannot be empty"
|
||||
allErrs = append(allErrs, field.Invalid(fieldPath.Child("runAsUserName"), windowsOptions.RunAsUserName, errMsg))
|
||||
} else if l > maxRunAsUserNameUserLength {
|
||||
errMsg := fmt.Sprintf("runAsUserName's User length must not be longer than %d characters", maxRunAsUserNameUserLength)
|
||||
@ -5979,6 +6050,91 @@ func validateWindowsSecurityContextOptions(windowsOptions *core.WindowsSecurityC
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateWindowsHostProcessPod(podSpec *core.PodSpec, fieldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// Keep track of container and hostProcess container count for validate
|
||||
containerCount := 0
|
||||
hostProcessContainerCount := 0
|
||||
|
||||
var podHostProcess *bool
|
||||
if podSpec.SecurityContext != nil && podSpec.SecurityContext.WindowsOptions != nil {
|
||||
podHostProcess = podSpec.SecurityContext.WindowsOptions.HostProcess
|
||||
}
|
||||
|
||||
if !opts.AllowWindowsHostProcessField && podHostProcess != nil {
|
||||
// Do not allow pods to persist data that sets hostProcess (true or false)
|
||||
errMsg := "not allowed when feature gate 'WindowsHostProcessContainers' is not enabled"
|
||||
allErrs = append(allErrs, field.Forbidden(fieldPath.Child("securityContext", "windowsOptions", "hostProcess"), errMsg))
|
||||
return allErrs
|
||||
}
|
||||
|
||||
hostNetwork := false
|
||||
if podSpec.SecurityContext != nil {
|
||||
hostNetwork = podSpec.SecurityContext.HostNetwork
|
||||
}
|
||||
|
||||
podshelper.VisitContainersWithPath(podSpec, fieldPath, func(c *core.Container, cFieldPath *field.Path) bool {
|
||||
containerCount++
|
||||
|
||||
var containerHostProcess *bool = nil
|
||||
if c.SecurityContext != nil && c.SecurityContext.WindowsOptions != nil {
|
||||
containerHostProcess = c.SecurityContext.WindowsOptions.HostProcess
|
||||
}
|
||||
|
||||
if !opts.AllowWindowsHostProcessField && containerHostProcess != nil {
|
||||
// Do not allow pods to persist data that sets hostProcess (true or false)
|
||||
errMsg := "not allowed when feature gate 'WindowsHostProcessContainers' is not enabled"
|
||||
allErrs = append(allErrs, field.Forbidden(cFieldPath.Child("securityContext", "windowsOptions", "hostProcess"), errMsg))
|
||||
}
|
||||
|
||||
if podHostProcess != nil && containerHostProcess != nil && *podHostProcess != *containerHostProcess {
|
||||
errMsg := fmt.Sprintf("pod hostProcess value must be identical if both are specified, was %v", *podHostProcess)
|
||||
allErrs = append(allErrs, field.Invalid(cFieldPath.Child("securityContext", "windowsOptions", "hostProcess"), *containerHostProcess, errMsg))
|
||||
}
|
||||
|
||||
switch {
|
||||
case containerHostProcess != nil && *containerHostProcess:
|
||||
// Container explitly sets hostProcess=true
|
||||
hostProcessContainerCount++
|
||||
case containerHostProcess == nil && podHostProcess != nil && *podHostProcess:
|
||||
// Container inherits hostProcess=true from pod settings
|
||||
hostProcessContainerCount++
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
if hostProcessContainerCount > 0 {
|
||||
// Fail Pod validation if feature is not enabled (unless podspec already exists and contains HostProcess fields) instead of dropping fields based on PRR reivew.
|
||||
if !opts.AllowWindowsHostProcessField {
|
||||
errMsg := "pod must not contain Windows hostProcess containers when feature gate 'WindowsHostProcessContainers' is not enabled"
|
||||
allErrs = append(allErrs, field.Forbidden(fieldPath, errMsg))
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// At present, if a Windows Pods contains any HostProcess containers than all containers must be
|
||||
// HostProcess containers (explicitly set or inherited).
|
||||
if hostProcessContainerCount != containerCount {
|
||||
errMsg := "If pod contains any hostProcess containers then all containers must be HostProcess containers"
|
||||
allErrs = append(allErrs, field.Invalid(fieldPath, "", errMsg))
|
||||
}
|
||||
|
||||
// At present Windows Pods which contain HostProcess containers must also set HostNetwork.
|
||||
if hostNetwork != true {
|
||||
errMsg := "hostNetwork must be true if pod contains any hostProcess containers"
|
||||
allErrs = append(allErrs, field.Invalid(fieldPath.Child("hostNetwork"), hostNetwork, errMsg))
|
||||
}
|
||||
|
||||
if !capabilities.Get().AllowPrivileged {
|
||||
errMsg := "hostProcess containers are disallowed by cluster policy"
|
||||
allErrs = append(allErrs, field.Forbidden(fieldPath, errMsg))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidatePodLogOptions(opts *core.PodLogOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if opts.TailLines != nil && *opts.TailLines < 0 {
|
||||
|
48
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
48
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
@ -1400,39 +1400,6 @@ func (in *EphemeralContainerCommon) DeepCopy() *EphemeralContainerCommon {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *EphemeralContainers) DeepCopyInto(out *EphemeralContainers) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
if in.EphemeralContainers != nil {
|
||||
in, out := &in.EphemeralContainers, &out.EphemeralContainers
|
||||
*out = make([]EphemeralContainer, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EphemeralContainers.
|
||||
func (in *EphemeralContainers) DeepCopy() *EphemeralContainers {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EphemeralContainers)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *EphemeralContainers) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *EphemeralVolumeSource) DeepCopyInto(out *EphemeralVolumeSource) {
|
||||
*out = *in
|
||||
@ -2969,6 +2936,11 @@ func (in *PersistentVolumeClaimSpec) DeepCopyInto(out *PersistentVolumeClaimSpec
|
||||
*out = new(TypedLocalObjectReference)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.DataSourceRef != nil {
|
||||
in, out := &in.DataSourceRef, &out.DataSourceRef
|
||||
*out = new(TypedLocalObjectReference)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -5325,11 +5297,6 @@ func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.TopologyKeys != nil {
|
||||
in, out := &in.TopologyKeys, &out.TopologyKeys
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.AllocateLoadBalancerNodePorts != nil {
|
||||
in, out := &in.AllocateLoadBalancerNodePorts, &out.AllocateLoadBalancerNodePorts
|
||||
*out = new(bool)
|
||||
@ -5928,6 +5895,11 @@ func (in *WindowsSecurityContextOptions) DeepCopyInto(out *WindowsSecurityContex
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.HostProcess != nil {
|
||||
in, out := &in.HostProcess, &out.HostProcess
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/apis/extensions/OWNERS
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/extensions/OWNERS
generated
vendored
@ -11,7 +11,6 @@ reviewers:
|
||||
- caesarxuchao
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- erictune
|
||||
- pmorie
|
||||
- sttts
|
||||
- saad-ali
|
||||
@ -25,7 +24,6 @@ reviewers:
|
||||
- dims
|
||||
- errordeveloper
|
||||
- rootfs
|
||||
- mml
|
||||
- resouer
|
||||
- therc
|
||||
- pweil-
|
||||
|
8
vendor/k8s.io/kubernetes/pkg/apis/networking/types.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/apis/networking/types.go
generated
vendored
@ -149,8 +149,8 @@ type NetworkPolicyPort struct {
|
||||
// should be allowed by the policy. This field cannot be defined if the port field
|
||||
// is not defined or if the port field is defined as a named (string) port.
|
||||
// The endPort must be equal or greater than port.
|
||||
// This feature is in Alpha state and should be enabled using the Feature Gate
|
||||
// "NetworkPolicyEndPort".
|
||||
// This feature is in Beta state and is enabled by default.
|
||||
// It can be disabled using the Feature Gate "NetworkPolicyEndPort".
|
||||
// +optional
|
||||
EndPort *int32
|
||||
}
|
||||
@ -492,8 +492,8 @@ const (
|
||||
type HTTPIngressPath struct {
|
||||
// Path is matched against the path of an incoming request. Currently it can
|
||||
// contain characters disallowed from the conventional "path" part of a URL
|
||||
// as defined by RFC 3986. Paths must begin with a '/'. When unspecified,
|
||||
// all paths from incoming requests are matched.
|
||||
// as defined by RFC 3986. Paths must begin with a '/' and must be present
|
||||
// when using PathType with value "Exact" or "Prefix".
|
||||
// +optional
|
||||
Path string
|
||||
|
||||
|
1
vendor/k8s.io/kubernetes/pkg/apis/policy/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/policy/OWNERS
generated
vendored
@ -2,6 +2,7 @@
|
||||
|
||||
# approval on api packages bubbles to api-approvers
|
||||
reviewers:
|
||||
- sig-apps-api-reviewers
|
||||
- sig-apps-api-approvers
|
||||
- sig-auth-policy-approvers
|
||||
- sig-auth-policy-reviewers
|
||||
|
4
vendor/k8s.io/kubernetes/pkg/cluster/ports/ports.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/cluster/ports/ports.go
generated
vendored
@ -25,10 +25,6 @@ const (
|
||||
// KubeletPort is the default port for the kubelet server on each host machine.
|
||||
// May be overridden by a flag at startup.
|
||||
KubeletPort = 10250
|
||||
// InsecureKubeControllerManagerPort is the default port for the controller manager status server.
|
||||
// May be overridden by a flag at startup.
|
||||
// Deprecated: use the secure KubeControllerManagerPort instead.
|
||||
InsecureKubeControllerManagerPort = 10252
|
||||
// KubeletReadOnlyPort exposes basic read-only services from the kubelet.
|
||||
// May be overridden by a flag at startup.
|
||||
// This is necessary for heapster to collect monitoring stats from the kubelet
|
||||
|
32
vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go
generated
vendored
32
vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go
generated
vendored
@ -124,6 +124,7 @@ type PodControllerRefManager struct {
|
||||
BaseControllerRefManager
|
||||
controllerKind schema.GroupVersionKind
|
||||
podControl PodControlInterface
|
||||
finalizers []string
|
||||
}
|
||||
|
||||
// NewPodControllerRefManager returns a PodControllerRefManager that exposes
|
||||
@ -143,6 +144,7 @@ func NewPodControllerRefManager(
|
||||
selector labels.Selector,
|
||||
controllerKind schema.GroupVersionKind,
|
||||
canAdopt func() error,
|
||||
finalizers ...string,
|
||||
) *PodControllerRefManager {
|
||||
return &PodControllerRefManager{
|
||||
BaseControllerRefManager: BaseControllerRefManager{
|
||||
@ -152,6 +154,7 @@ func NewPodControllerRefManager(
|
||||
},
|
||||
controllerKind: controllerKind,
|
||||
podControl: podControl,
|
||||
finalizers: finalizers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,7 +219,7 @@ func (m *PodControllerRefManager) AdoptPod(pod *v1.Pod) error {
|
||||
// Note that ValidateOwnerReferences() will reject this patch if another
|
||||
// OwnerReference exists with controller=true.
|
||||
|
||||
patchBytes, err := ownerRefControllerPatch(m.Controller, m.controllerKind, pod.UID)
|
||||
patchBytes, err := ownerRefControllerPatch(m.Controller, m.controllerKind, pod.UID, m.finalizers...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -228,7 +231,7 @@ func (m *PodControllerRefManager) AdoptPod(pod *v1.Pod) error {
|
||||
func (m *PodControllerRefManager) ReleasePod(pod *v1.Pod) error {
|
||||
klog.V(2).Infof("patching pod %s_%s to remove its controllerRef to %s/%s:%s",
|
||||
pod.Namespace, pod.Name, m.controllerKind.GroupVersion(), m.controllerKind.Kind, m.Controller.GetName())
|
||||
patchBytes, err := deleteOwnerRefStrategicMergePatch(pod.UID, m.Controller.GetUID())
|
||||
patchBytes, err := deleteOwnerRefStrategicMergePatch(pod.UID, m.Controller.GetUID(), m.finalizers...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -518,19 +521,22 @@ type objectForDeleteOwnerRefStrategicMergePatch struct {
|
||||
}
|
||||
|
||||
type objectMetaForMergePatch struct {
|
||||
UID types.UID `json:"uid"`
|
||||
OwnerReferences []map[string]string `json:"ownerReferences"`
|
||||
UID types.UID `json:"uid"`
|
||||
OwnerReferences []map[string]string `json:"ownerReferences"`
|
||||
DeleteFinalizers []string `json:"$deleteFromPrimitiveList/finalizers,omitempty"`
|
||||
}
|
||||
|
||||
func deleteOwnerRefStrategicMergePatch(dependentUID types.UID, ownerUIDs ...types.UID) ([]byte, error) {
|
||||
var pieces []map[string]string
|
||||
for _, ownerUID := range ownerUIDs {
|
||||
pieces = append(pieces, map[string]string{"$patch": "delete", "uid": string(ownerUID)})
|
||||
}
|
||||
func deleteOwnerRefStrategicMergePatch(dependentUID types.UID, ownerUID types.UID, finalizers ...string) ([]byte, error) {
|
||||
patch := objectForDeleteOwnerRefStrategicMergePatch{
|
||||
Metadata: objectMetaForMergePatch{
|
||||
UID: dependentUID,
|
||||
OwnerReferences: pieces,
|
||||
UID: dependentUID,
|
||||
OwnerReferences: []map[string]string{
|
||||
{
|
||||
"$patch": "delete",
|
||||
"uid": string(ownerUID),
|
||||
},
|
||||
},
|
||||
DeleteFinalizers: finalizers,
|
||||
},
|
||||
}
|
||||
patchBytes, err := json.Marshal(&patch)
|
||||
@ -547,9 +553,10 @@ type objectForAddOwnerRefPatch struct {
|
||||
type objectMetaForPatch struct {
|
||||
OwnerReferences []metav1.OwnerReference `json:"ownerReferences"`
|
||||
UID types.UID `json:"uid"`
|
||||
Finalizers []string `json:"finalizers,omitempty"`
|
||||
}
|
||||
|
||||
func ownerRefControllerPatch(controller metav1.Object, controllerKind schema.GroupVersionKind, uid types.UID) ([]byte, error) {
|
||||
func ownerRefControllerPatch(controller metav1.Object, controllerKind schema.GroupVersionKind, uid types.UID, finalizers ...string) ([]byte, error) {
|
||||
blockOwnerDeletion := true
|
||||
isController := true
|
||||
addControllerPatch := objectForAddOwnerRefPatch{
|
||||
@ -565,6 +572,7 @@ func ownerRefControllerPatch(controller metav1.Object, controllerKind schema.Gro
|
||||
BlockOwnerDeletion: &blockOwnerDeletion,
|
||||
},
|
||||
},
|
||||
Finalizers: finalizers,
|
||||
},
|
||||
}
|
||||
patchBytes, err := json.Marshal(&addControllerPatch)
|
||||
|
58
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
58
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
@ -445,13 +445,10 @@ func (r RealControllerRevisionControl) PatchControllerRevision(namespace, name s
|
||||
// PodControlInterface is an interface that knows how to add or delete pods
|
||||
// created as an interface to allow testing.
|
||||
type PodControlInterface interface {
|
||||
// CreatePods creates new pods according to the spec.
|
||||
CreatePods(namespace string, template *v1.PodTemplateSpec, object runtime.Object) error
|
||||
// CreatePodsOnNode creates a new pod according to the spec on the specified node,
|
||||
// and sets the ControllerRef.
|
||||
CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error
|
||||
// CreatePodsWithControllerRef creates new pods according to the spec, and sets object as the pod's controller.
|
||||
CreatePodsWithControllerRef(namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error
|
||||
// CreatePods creates new pods according to the spec, and sets object as the pod's controller.
|
||||
CreatePods(namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error
|
||||
// CreatePodsWithGenerateName creates new pods according to the spec, sets object as the pod's controller and sets pod's generateName.
|
||||
CreatePodsWithGenerateName(namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference, generateName string) error
|
||||
// DeletePod deletes the pod identified by podID.
|
||||
DeletePod(namespace string, podID string, object runtime.Object) error
|
||||
// PatchPod patches the pod.
|
||||
@ -516,22 +513,22 @@ func validateControllerRef(controllerRef *metav1.OwnerReference) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r RealPodControl) CreatePods(namespace string, template *v1.PodTemplateSpec, object runtime.Object) error {
|
||||
return r.createPods("", namespace, template, object, nil)
|
||||
func (r RealPodControl) CreatePods(namespace string, template *v1.PodTemplateSpec, controllerObject runtime.Object, controllerRef *metav1.OwnerReference) error {
|
||||
return r.CreatePodsWithGenerateName(namespace, template, controllerObject, controllerRef, "")
|
||||
}
|
||||
|
||||
func (r RealPodControl) CreatePodsWithControllerRef(namespace string, template *v1.PodTemplateSpec, controllerObject runtime.Object, controllerRef *metav1.OwnerReference) error {
|
||||
func (r RealPodControl) CreatePodsWithGenerateName(namespace string, template *v1.PodTemplateSpec, controllerObject runtime.Object, controllerRef *metav1.OwnerReference, generateName string) error {
|
||||
if err := validateControllerRef(controllerRef); err != nil {
|
||||
return err
|
||||
}
|
||||
return r.createPods("", namespace, template, controllerObject, controllerRef)
|
||||
}
|
||||
|
||||
func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
|
||||
if err := validateControllerRef(controllerRef); err != nil {
|
||||
pod, err := GetPodFromTemplate(template, controllerObject, controllerRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.createPods(nodeName, namespace, template, object, controllerRef)
|
||||
if len(generateName) > 0 {
|
||||
pod.ObjectMeta.GenerateName = generateName
|
||||
}
|
||||
return r.createPods(namespace, pod, controllerObject)
|
||||
}
|
||||
|
||||
func (r RealPodControl) PatchPod(namespace, name string, data []byte) error {
|
||||
@ -564,14 +561,7 @@ func GetPodFromTemplate(template *v1.PodTemplateSpec, parentObject runtime.Objec
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
func (r RealPodControl) createPods(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
|
||||
pod, err := GetPodFromTemplate(template, object, controllerRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(nodeName) != 0 {
|
||||
pod.Spec.NodeName = nodeName
|
||||
}
|
||||
func (r RealPodControl) createPods(namespace string, pod *v1.Pod, object runtime.Object) error {
|
||||
if len(labels.Set(pod.Labels)) == 0 {
|
||||
return fmt.Errorf("unable to create pods, no labels")
|
||||
}
|
||||
@ -636,21 +626,7 @@ func (f *FakePodControl) PatchPod(namespace, name string, data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePods(namespace string, spec *v1.PodTemplateSpec, object runtime.Object) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.CreateCallCount++
|
||||
if f.CreateLimit != 0 && f.CreateCallCount > f.CreateLimit {
|
||||
return fmt.Errorf("not creating pod, limit %d already reached (create call %d)", f.CreateLimit, f.CreateCallCount)
|
||||
}
|
||||
f.Templates = append(f.Templates, *spec)
|
||||
if f.Err != nil {
|
||||
return f.Err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
|
||||
func (f *FakePodControl) CreatePods(namespace string, spec *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.CreateCallCount++
|
||||
@ -665,14 +641,14 @@ func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *v1.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
|
||||
func (f *FakePodControl) CreatePodsWithGenerateName(namespace string, spec *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference, generateNamePrefix string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.CreateCallCount++
|
||||
if f.CreateLimit != 0 && f.CreateCallCount > f.CreateLimit {
|
||||
return fmt.Errorf("not creating pod, limit %d already reached (create call %d)", f.CreateLimit, f.CreateCallCount)
|
||||
}
|
||||
f.Templates = append(f.Templates, *template)
|
||||
f.Templates = append(f.Templates, *spec)
|
||||
f.ControllerRefs = append(f.ControllerRefs, *controllerRef)
|
||||
if f.Err != nil {
|
||||
return f.Err
|
||||
|
343
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
343
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
@ -27,6 +27,7 @@ const (
|
||||
// Every feature gate should add method here following this template:
|
||||
//
|
||||
// // owner: @username
|
||||
// // kep: http://kep.k8s.io/NNN
|
||||
// // alpha: v1.X
|
||||
// MyFeature featuregate.Feature = "MyFeature"
|
||||
|
||||
@ -37,6 +38,7 @@ const (
|
||||
// owner: @mtaufen
|
||||
// alpha: v1.4
|
||||
// beta: v1.11
|
||||
// deprecated: 1.22
|
||||
DynamicKubeletConfig featuregate.Feature = "DynamicKubeletConfig"
|
||||
|
||||
// owner: @pweil-
|
||||
@ -124,7 +126,8 @@ const (
|
||||
TopologyManager featuregate.Feature = "TopologyManager"
|
||||
|
||||
// owner: @cynepco3hahue(alukiano) @cezaryzukowski @k-wiatrzyk
|
||||
// alpha:: v1.20
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
|
||||
// Allows setting memory affinity for a container based on NUMA topology
|
||||
MemoryManager featuregate.Feature = "MemoryManager"
|
||||
@ -137,31 +140,6 @@ const (
|
||||
// Enable pods to set sysctls on a pod
|
||||
Sysctls featuregate.Feature = "Sysctls"
|
||||
|
||||
// owner @smarterclayton
|
||||
// alpha: v1.16
|
||||
// beta: v1.19
|
||||
// ga: v1.21
|
||||
//
|
||||
// Enable legacy behavior to vary cluster functionality on the node-role.kubernetes.io labels. On by default (legacy), will be turned off in 1.18.
|
||||
// Lock to false in v1.21 and remove in v1.22.
|
||||
LegacyNodeRoleBehavior featuregate.Feature = "LegacyNodeRoleBehavior"
|
||||
|
||||
// owner @brendandburns
|
||||
// alpha: v1.9
|
||||
// beta: v1.19
|
||||
// ga: v1.21
|
||||
//
|
||||
// Enable nodes to exclude themselves from service load balancers
|
||||
ServiceNodeExclusion featuregate.Feature = "ServiceNodeExclusion"
|
||||
|
||||
// owner @smarterclayton
|
||||
// alpha: v1.16
|
||||
// beta: v1.19
|
||||
// ga: v1.21
|
||||
//
|
||||
// Enable nodes to exclude themselves from network disruption checks
|
||||
NodeDisruptionExclusion featuregate.Feature = "NodeDisruptionExclusion"
|
||||
|
||||
// owner: @pospispa
|
||||
// GA: v1.11
|
||||
//
|
||||
@ -179,6 +157,7 @@ const (
|
||||
// owner: @mikedanese
|
||||
// alpha: v1.13
|
||||
// beta: v1.21
|
||||
// ga: v1.22
|
||||
//
|
||||
// Migrate ServiceAccount volumes to use a projected volume consisting of a
|
||||
// ServiceAccountTokenVolumeProjection. This feature adds new required flags
|
||||
@ -196,20 +175,6 @@ const (
|
||||
// intended to be used for service account token verification.
|
||||
ServiceAccountIssuerDiscovery featuregate.Feature = "ServiceAccountIssuerDiscovery"
|
||||
|
||||
// owner: @Random-Liu
|
||||
// beta: v1.11
|
||||
// ga: v1.21
|
||||
//
|
||||
// Enable container log rotation for cri container runtime
|
||||
CRIContainerLogRotation featuregate.Feature = "CRIContainerLogRotation"
|
||||
|
||||
// owner: @krmayankk
|
||||
// beta: v1.14
|
||||
// ga: v1.21
|
||||
//
|
||||
// Enables control over the primary group ID of containers' init processes.
|
||||
RunAsGroup featuregate.Feature = "RunAsGroup"
|
||||
|
||||
// owner: @saad-ali
|
||||
// ga: v1.10
|
||||
//
|
||||
@ -217,14 +182,6 @@ const (
|
||||
// Do not remove this feature gate even though it's GA
|
||||
VolumeSubpath featuregate.Feature = "VolumeSubpath"
|
||||
|
||||
// owner: @ravig
|
||||
// alpha: v1.11
|
||||
//
|
||||
// Include volume count on node to be considered for balanced resource allocation while scheduling.
|
||||
// A node which has closer cpu,memory utilization and volume count is favoured by scheduler
|
||||
// while making decisions.
|
||||
BalanceAttachedNodeVolumes featuregate.Feature = "BalanceAttachedNodeVolumes"
|
||||
|
||||
// owner: @pohly
|
||||
// alpha: v1.14
|
||||
// beta: v1.16
|
||||
@ -255,6 +212,7 @@ const (
|
||||
|
||||
// owner: @chendave
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// PreferNominatedNode tells scheduler whether the nominated node will be checked first before looping
|
||||
// all the rest of nodes in the cluster.
|
||||
@ -280,28 +238,14 @@ const (
|
||||
// (Kube) Node Lifecycle Controller uses these heartbeats as a node health signal.
|
||||
NodeLease featuregate.Feature = "NodeLease"
|
||||
|
||||
// owner: @janosi
|
||||
// alpha: v1.12
|
||||
// beta: v1.19
|
||||
// GA: v1.20
|
||||
//
|
||||
// Enables SCTP as new protocol for Service ports, NetworkPolicy, and ContainerPort in Pod/Containers definition
|
||||
SCTPSupport featuregate.Feature = "SCTPSupport"
|
||||
|
||||
// owner: @rikatz
|
||||
// kep: http://kep.k8s.io/2079
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Enables the endPort field in NetworkPolicy to enable a Port Range behavior in Network Policies.
|
||||
NetworkPolicyEndPort featuregate.Feature = "NetworkPolicyEndPort"
|
||||
|
||||
// owner: @xing-yang
|
||||
// alpha: v1.12
|
||||
// beta: v1.17
|
||||
// GA: v1.20
|
||||
//
|
||||
// Enable volume snapshot data source support.
|
||||
VolumeSnapshotDataSource featuregate.Feature = "VolumeSnapshotDataSource"
|
||||
|
||||
// owner: @jessfraz
|
||||
// alpha: v1.12
|
||||
//
|
||||
@ -316,10 +260,20 @@ const (
|
||||
|
||||
// owner: @alculquicondor
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Allows Job controller to manage Pod completions per completion index.
|
||||
IndexedJob featuregate.Feature = "IndexedJob"
|
||||
|
||||
// owner: @alculquicondor
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Track Job completion without relying on Pod remaining in the cluster
|
||||
// indefinitely. Pod finalizers, in addition to a field in the Job status
|
||||
// allow the Job controller to keep track of Pods that it didn't account for
|
||||
// yet.
|
||||
JobTrackingWithFinalizers featuregate.Feature = "JobTrackingWithFinalizers"
|
||||
|
||||
// owner: @dashpole
|
||||
// alpha: v1.13
|
||||
// beta: v1.15
|
||||
@ -392,13 +346,6 @@ const (
|
||||
// Enables the vSphere in-tree driver to vSphere CSI Driver migration feature.
|
||||
CSIMigrationvSphere featuregate.Feature = "CSIMigrationvSphere"
|
||||
|
||||
// owner: @divyenpatel
|
||||
// beta: v1.19 (requires: vSphere vCenter/ESXi Version: 7.0u1, HW Version: VM version 15)
|
||||
//
|
||||
// Disables the vSphere in-tree driver.
|
||||
// Expects vSphere CSI Driver to be installed and configured on all nodes.
|
||||
CSIMigrationvSphereComplete featuregate.Feature = "CSIMigrationvSphereComplete"
|
||||
|
||||
// owner: @divyenpatel
|
||||
// alpha: v1.21
|
||||
//
|
||||
@ -432,6 +379,13 @@ const (
|
||||
// a volume in a Pod.
|
||||
ConfigurableFSGroupPolicy featuregate.Feature = "ConfigurableFSGroupPolicy"
|
||||
|
||||
// owner: @gnufied, @verult
|
||||
// alpha: v1.22
|
||||
// If supported by the CSI driver, delegates the role of applying FSGroup to
|
||||
// the driver by passing FSGroup through the NodeStageVolume and
|
||||
// NodePublishVolume calls.
|
||||
DelegateFSGroupToCSIDriver featuregate.Feature = "DelegateFSGroupToCSIDriver"
|
||||
|
||||
// owner: @RobertKrawitz, @derekwaynecarr
|
||||
// beta: v1.15
|
||||
// GA: v1.20
|
||||
@ -461,6 +415,7 @@ const (
|
||||
PodOverhead featuregate.Feature = "PodOverhead"
|
||||
|
||||
// owner: @khenidak
|
||||
// kep: http://kep.k8s.io/563
|
||||
// alpha: v1.15
|
||||
// beta: v1.21
|
||||
//
|
||||
@ -468,6 +423,7 @@ const (
|
||||
IPv6DualStack featuregate.Feature = "IPv6DualStack"
|
||||
|
||||
// owner: @robscott @freehan
|
||||
// kep: http://kep.k8s.io/752
|
||||
// alpha: v1.16
|
||||
// beta: v1.18
|
||||
// ga: v1.21
|
||||
@ -476,15 +432,19 @@ const (
|
||||
EndpointSlice featuregate.Feature = "EndpointSlice"
|
||||
|
||||
// owner: @robscott @freehan
|
||||
// kep: http://kep.k8s.io/752
|
||||
// alpha: v1.18
|
||||
// beta: v1.19
|
||||
// ga: v1.22
|
||||
//
|
||||
// Enable Endpoint Slice consumption by kube-proxy for improved scalability.
|
||||
EndpointSliceProxying featuregate.Feature = "EndpointSliceProxying"
|
||||
|
||||
// owner: @robscott @kumarvin123
|
||||
// kep: http://kep.k8s.io/752
|
||||
// alpha: v1.19
|
||||
// beta: v1.21
|
||||
// ga: v1.22
|
||||
//
|
||||
// Enable Endpoint Slice consumption by kube-proxy in Windows for improved scalability.
|
||||
WindowsEndpointSliceProxying featuregate.Feature = "WindowsEndpointSliceProxying"
|
||||
@ -514,33 +474,18 @@ const (
|
||||
// owner: @alaypatel07, @soltysh
|
||||
// alpha: v1.20
|
||||
// beta: v1.21
|
||||
// GA: v1.22
|
||||
//
|
||||
// CronJobControllerV2 controls whether the controller manager starts old cronjob
|
||||
// controller or new one which is implemented with informers and delaying queue
|
||||
//
|
||||
// This feature is deprecated, and will be removed in v1.22.
|
||||
CronJobControllerV2 featuregate.Feature = "CronJobControllerV2"
|
||||
|
||||
// owner: @smarterclayton
|
||||
// alpha: v1.21
|
||||
//
|
||||
// beta: v1.22
|
||||
// DaemonSets allow workloads to maintain availability during update per node
|
||||
DaemonSetUpdateSurge featuregate.Feature = "DaemonSetUpdateSurge"
|
||||
|
||||
// owner: @m1093782566
|
||||
// alpha: v1.17
|
||||
//
|
||||
// Enables topology aware service routing
|
||||
ServiceTopology featuregate.Feature = "ServiceTopology"
|
||||
|
||||
// owner: @robscott
|
||||
// alpha: v1.18
|
||||
// beta: v1.19
|
||||
// ga: v1.20
|
||||
//
|
||||
// Enables AppProtocol field for Services and Endpoints.
|
||||
ServiceAppProtocol featuregate.Feature = "ServiceAppProtocol"
|
||||
|
||||
// owner: @wojtek-t
|
||||
// alpha: v1.18
|
||||
// beta: v1.19
|
||||
@ -552,6 +497,7 @@ const (
|
||||
// owner: @bart0sh
|
||||
// alpha: v1.18
|
||||
// beta: v1.19
|
||||
// GA: 1.22
|
||||
//
|
||||
// Enables usage of HugePages-<size> in a volume medium,
|
||||
// e.g. emptyDir:
|
||||
@ -565,13 +511,6 @@ const (
|
||||
// Enables usage of hugepages-<size> in downward API.
|
||||
DownwardAPIHugePages featuregate.Feature = "DownwardAPIHugePages"
|
||||
|
||||
// owner: @freehan
|
||||
// GA: v1.18
|
||||
//
|
||||
// Enable ExternalTrafficPolicy for Service ExternalIPs.
|
||||
// This is for bug fix #69811
|
||||
ExternalPolicyForExternalIP featuregate.Feature = "ExternalPolicyForExternalIP"
|
||||
|
||||
// owner: @bswartz
|
||||
// alpha: v1.18
|
||||
//
|
||||
@ -579,8 +518,10 @@ const (
|
||||
AnyVolumeDataSource featuregate.Feature = "AnyVolumeDataSource"
|
||||
|
||||
// owner: @javidiaz
|
||||
// kep: http://kep.k8s.io/1797
|
||||
// alpha: v1.19
|
||||
// beta: v1.20
|
||||
// GA: v1.22
|
||||
//
|
||||
// Allow setting the Fully Qualified Domain Name (FQDN) in the hostname of a Pod. If a Pod does not
|
||||
// have FQDN, this feature has no effect.
|
||||
@ -613,22 +554,23 @@ const (
|
||||
// in target pods
|
||||
HPAContainerMetrics featuregate.Feature = "HPAContainerMetrics"
|
||||
|
||||
// owner: @zshihang
|
||||
// alpha: v1.13
|
||||
// beta: v1.20
|
||||
// ga: v1.21
|
||||
//
|
||||
// Allows kube-controller-manager to publish kube-root-ca.crt configmap to
|
||||
// every namespace. This feature is a prerequisite of BoundServiceAccountTokenVolume.
|
||||
RootCAConfigMap featuregate.Feature = "RootCAConfigMap"
|
||||
|
||||
// owner: @andrewsykim
|
||||
// kep: http://kep.k8s.io/1672
|
||||
// alpha: v1.20
|
||||
// beta: v1.22
|
||||
//
|
||||
// Enable Terminating condition in Endpoint Slices.
|
||||
EndpointSliceTerminatingCondition featuregate.Feature = "EndpointSliceTerminatingCondition"
|
||||
|
||||
// owner: @andrewsykim
|
||||
// kep: http://kep.k8s.io/1669
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Enable kube-proxy to handle terminating ednpoints when externalTrafficPolicy=Local
|
||||
ProxyTerminatingEndpoints featuregate.Feature = "ProxyTerminatingEndpoints"
|
||||
|
||||
// owner: @robscott
|
||||
// kep: http://kep.k8s.io/752
|
||||
// alpha: v1.20
|
||||
//
|
||||
// Enable NodeName field on Endpoint Slices.
|
||||
@ -636,6 +578,7 @@ const (
|
||||
|
||||
// owner: @derekwaynecarr
|
||||
// alpha: v1.20
|
||||
// beta: v1.22
|
||||
//
|
||||
// Enables kubelet support to size memory backed volumes
|
||||
SizeMemoryBackedVolumes featuregate.Feature = "SizeMemoryBackedVolumes"
|
||||
@ -654,9 +597,16 @@ const (
|
||||
// Enable kubelet exec plugins for image pull credentials.
|
||||
KubeletCredentialProviders featuregate.Feature = "KubeletCredentialProviders"
|
||||
|
||||
// owner: @andrewsykim
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Disable any functionality in kube-apiserver, kube-controller-manager and kubelet related to the `--cloud-provider` component flag.
|
||||
DisableCloudProviders featuregate.Feature = "DisableCloudProviders"
|
||||
|
||||
// owner: @zshihang
|
||||
// alpha: v1.20
|
||||
// beta: v1.21
|
||||
// ga: v1.22
|
||||
//
|
||||
// Enable kubelet to pass pod's service account token to NodePublishVolume
|
||||
// call of CSI driver which is mounting volumes for that pod.
|
||||
@ -669,12 +619,15 @@ const (
|
||||
GracefulNodeShutdown featuregate.Feature = "GracefulNodeShutdown"
|
||||
|
||||
// owner: @andrewsykim @uablrek
|
||||
// kep: http://kep.k8s.io/1864
|
||||
// alpha: v1.20
|
||||
// beta: v1.22
|
||||
//
|
||||
// Allows control if NodePorts shall be created for services with "type: LoadBalancer" by defining the spec.AllocateLoadBalancerNodePorts field (bool)
|
||||
ServiceLBNodePortControl featuregate.Feature = "ServiceLBNodePortControl"
|
||||
|
||||
// owner: @janosi
|
||||
// kep: http://kep.k8s.io/1435
|
||||
// alpha: v1.20
|
||||
//
|
||||
// Enables the usage of different protocols in the same Service with type=LoadBalancer
|
||||
@ -686,11 +639,13 @@ const (
|
||||
|
||||
// owner: @ahg-g
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Enables controlling pod ranking on replicaset scale-down.
|
||||
PodDeletionCost featuregate.Feature = "PodDeletionCost"
|
||||
|
||||
// owner: @robscott
|
||||
// kep: http://kep.k8s.io/2433
|
||||
// alpha: v1.21
|
||||
//
|
||||
// Enables topology aware hints for EndpointSlices
|
||||
@ -702,31 +657,44 @@ const (
|
||||
// Allows user to override pod-level terminationGracePeriod for probes
|
||||
ProbeTerminationGracePeriod featuregate.Feature = "ProbeTerminationGracePeriod"
|
||||
|
||||
// owner: @ehashman
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Permits kubelet to run with swap enabled
|
||||
NodeSwap featuregate.Feature = "NodeSwap"
|
||||
|
||||
// owner: @ahg-g
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Allow specifying NamespaceSelector in PodAffinityTerm.
|
||||
PodAffinityNamespaceSelector featuregate.Feature = "PodAffinityNamespaceSelector"
|
||||
|
||||
// owner: @andrewsykim @xudongliuharold
|
||||
// owner: @andrewsykim @XudongLiuHarold
|
||||
// kep: http://kep.k8s.io/1959
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Enable support multiple Service "type: LoadBalancer" implementations in a cluster by specifying LoadBalancerClass
|
||||
ServiceLoadBalancerClass featuregate.Feature = "ServiceLoadBalancerClass"
|
||||
|
||||
// owner: @damemi
|
||||
// aplpha: v1.21
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Enables scaling down replicas via logarithmic comparison of creation/ready timestamps
|
||||
LogarithmicScaleDown featuregate.Feature = "LogarithmicScaleDown"
|
||||
|
||||
// owner: @hbagdi
|
||||
// kep: http://kep.k8s.io/2365
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Enable Scope and Namespace fields on IngressClassParametersReference.
|
||||
IngressClassNamespacedParams featuregate.Feature = "IngressClassNamespacedParams"
|
||||
|
||||
// owner: @maplain @andrewsykim
|
||||
// kep: http://kep.k8s.io/2086
|
||||
// alpha: v1.21
|
||||
//
|
||||
// Enables node-local routing for Service internal traffic
|
||||
@ -734,6 +702,7 @@ const (
|
||||
|
||||
// owner: @adtac
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Allows jobs to be created in the suspended state.
|
||||
SuspendJob featuregate.Feature = "SuspendJob"
|
||||
@ -745,7 +714,9 @@ const (
|
||||
KubeletPodResourcesGetAllocatable featuregate.Feature = "KubeletPodResourcesGetAllocatable"
|
||||
|
||||
// owner: @jayunit100 @abhiraut @rikatz
|
||||
// kep: http://kep.k8s.io/2161
|
||||
// beta: v1.21
|
||||
// ga: v1.22
|
||||
//
|
||||
// Labels all namespaces with a default label "kubernetes.io/metadata.name: <namespaceName>"
|
||||
NamespaceDefaultLabelName featuregate.Feature = "NamespaceDefaultLabelName"
|
||||
@ -755,6 +726,77 @@ 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: @marosset
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Enables support for 'HostProcess' containers on Windows nodes.
|
||||
WindowsHostProcessContainers featuregate.Feature = "WindowsHostProcessContainers"
|
||||
|
||||
// owner: @ravig
|
||||
// alpha: v1.22
|
||||
//
|
||||
// StatefulSetMinReadySeconds allows minReadySeconds to be respected by StatefulSet controller
|
||||
StatefulSetMinReadySeconds featuregate.Feature = "StatefulSetMinReadySeconds"
|
||||
|
||||
// owner: @gjkim42
|
||||
// kep: http://kep.k8s.io/2595
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Enables apiserver and kubelet to allow up to 32 DNSSearchPaths and up to 2048 DNSSearchListChars.
|
||||
ExpandedDNSConfig featuregate.Feature = "ExpandedDNSConfig"
|
||||
|
||||
// owner: @saschagrunert
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Enables the use of `RuntimeDefault` as the default seccomp profile for all workloads.
|
||||
SeccompDefault featuregate.Feature = "SeccompDefault"
|
||||
|
||||
// owner: @liggitt, @tallclair, sig-auth
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Enables the PodSecurity admission plugin
|
||||
PodSecurity featuregate.Feature = "PodSecurity"
|
||||
|
||||
// owner: @chrishenzie
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Enables usage of the ReadWriteOncePod PersistentVolume access mode.
|
||||
ReadWriteOncePod featuregate.Feature = "ReadWriteOncePod"
|
||||
|
||||
// owner: @enj
|
||||
// beta: v1.22
|
||||
//
|
||||
// Allows clients to request a duration for certificates issued via the Kubernetes CSR API.
|
||||
CSRDuration featuregate.Feature = "CSRDuration"
|
||||
|
||||
// owner: @AkihiroSuda
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Enables support for running kubelet in a user namespace.
|
||||
// The user namespace has to be created before running kubelet.
|
||||
// All the node components such as CRI need to be running in the same user namespace.
|
||||
KubeletInUserNamespace featuregate.Feature = "KubeletInUserNamespace"
|
||||
|
||||
// owner: @xiaoxubeii
|
||||
// kep: http://kep.k8s.io/2570
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Enables kubelet to support memory QoS with cgroups v2.
|
||||
MemoryQoS featuregate.Feature = "MemoryQoS"
|
||||
|
||||
// owner: @fromanirh
|
||||
// alpha: v1.22
|
||||
//
|
||||
// Allow fine-tuning of cpumanager policies
|
||||
CPUManagerPolicyOptions featuregate.Feature = "CPUManagerPolicyOptions"
|
||||
|
||||
// owner: @jiahuif
|
||||
// alpha: v1.21
|
||||
// beta: v1.22
|
||||
//
|
||||
// Enables Leader Migration for kube-controller-manager and cloud-controller-manager
|
||||
ControllerManagerLeaderMigration featuregate.Feature = "ControllerManagerLeaderMigration"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -766,7 +808,7 @@ func init() {
|
||||
// available throughout Kubernetes binaries.
|
||||
var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
|
||||
AppArmor: {Default: true, PreRelease: featuregate.Beta},
|
||||
DynamicKubeletConfig: {Default: true, PreRelease: featuregate.Beta},
|
||||
DynamicKubeletConfig: {Default: false, PreRelease: featuregate.Deprecated}, // feature gate is deprecated in 1.22, remove no early than 1.23
|
||||
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: featuregate.Beta},
|
||||
DevicePlugins: {Default: true, PreRelease: featuregate.Beta},
|
||||
RotateKubeletServerCertificate: {Default: true, PreRelease: featuregate.Beta},
|
||||
@ -778,17 +820,14 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
ExpandInUsePersistentVolumes: {Default: true, PreRelease: featuregate.Beta},
|
||||
ExpandCSIVolumes: {Default: true, PreRelease: featuregate.Beta},
|
||||
CPUManager: {Default: true, PreRelease: featuregate.Beta},
|
||||
MemoryManager: {Default: false, PreRelease: featuregate.Alpha},
|
||||
MemoryManager: {Default: true, PreRelease: featuregate.Beta},
|
||||
CPUCFSQuotaPeriod: {Default: false, PreRelease: featuregate.Alpha},
|
||||
TopologyManager: {Default: true, PreRelease: featuregate.Beta},
|
||||
ServiceNodeExclusion: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
NodeDisruptionExclusion: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
StorageObjectInUseProtection: {Default: true, PreRelease: featuregate.GA},
|
||||
SupportPodPidsLimit: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
SupportNodePidsLimit: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
BoundServiceAccountTokenVolume: {Default: true, PreRelease: featuregate.Beta},
|
||||
BoundServiceAccountTokenVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
ServiceAccountIssuerDiscovery: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
CRIContainerLogRotation: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
CSIMigration: {Default: true, PreRelease: featuregate.Beta},
|
||||
CSIMigrationGCE: {Default: false, PreRelease: featuregate.Beta}, // Off by default (requires GCE PD CSI Driver)
|
||||
InTreePluginGCEUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
@ -799,91 +838,97 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
CSIMigrationAzureFile: {Default: false, PreRelease: featuregate.Beta}, // Off by default (requires Azure File CSI driver)
|
||||
InTreePluginAzureFileUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
CSIMigrationvSphere: {Default: false, PreRelease: featuregate.Beta}, // Off by default (requires vSphere CSI driver)
|
||||
CSIMigrationvSphereComplete: {Default: false, PreRelease: featuregate.Beta}, // remove in 1.22
|
||||
InTreePluginvSphereUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
CSIMigrationOpenStack: {Default: true, PreRelease: featuregate.Beta},
|
||||
InTreePluginOpenStackUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||
VolumeSubpath: {Default: true, PreRelease: featuregate.GA},
|
||||
ConfigurableFSGroupPolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||
BalanceAttachedNodeVolumes: {Default: false, PreRelease: featuregate.Alpha},
|
||||
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
|
||||
CSIStorageCapacity: {Default: true, PreRelease: featuregate.Beta},
|
||||
CSIServiceAccountToken: {Default: true, PreRelease: featuregate.Beta},
|
||||
CSIServiceAccountToken: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
GenericEphemeralVolume: {Default: true, PreRelease: featuregate.Beta},
|
||||
CSIVolumeFSGroupPolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||
RuntimeClass: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
NodeLease: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
SCTPSupport: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
NetworkPolicyEndPort: {Default: false, PreRelease: featuregate.Alpha},
|
||||
VolumeSnapshotDataSource: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.21
|
||||
NetworkPolicyEndPort: {Default: true, PreRelease: featuregate.Beta},
|
||||
ProcMountType: {Default: false, PreRelease: featuregate.Alpha},
|
||||
TTLAfterFinished: {Default: true, PreRelease: featuregate.Beta},
|
||||
IndexedJob: {Default: false, PreRelease: featuregate.Alpha},
|
||||
IndexedJob: {Default: true, PreRelease: featuregate.Beta},
|
||||
JobTrackingWithFinalizers: {Default: false, PreRelease: featuregate.Alpha},
|
||||
KubeletPodResources: {Default: true, PreRelease: featuregate.Beta},
|
||||
LocalStorageCapacityIsolationFSQuotaMonitoring: {Default: false, PreRelease: featuregate.Alpha},
|
||||
NonPreemptingPriority: {Default: true, PreRelease: featuregate.Beta},
|
||||
PodOverhead: {Default: true, PreRelease: featuregate.Beta},
|
||||
IPv6DualStack: {Default: true, PreRelease: featuregate.Beta},
|
||||
EndpointSlice: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
||||
EndpointSliceProxying: {Default: true, PreRelease: featuregate.Beta},
|
||||
EndpointSliceTerminatingCondition: {Default: false, PreRelease: featuregate.Alpha},
|
||||
EndpointSliceProxying: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
||||
EndpointSliceTerminatingCondition: {Default: true, PreRelease: featuregate.Beta},
|
||||
ProxyTerminatingEndpoints: {Default: false, PreRelease: featuregate.Alpha},
|
||||
EndpointSliceNodeName: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, //remove in 1.25
|
||||
WindowsEndpointSliceProxying: {Default: true, PreRelease: featuregate.Beta},
|
||||
WindowsEndpointSliceProxying: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
||||
StartupProbe: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
AllowInsecureBackendProxy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
PodDisruptionBudget: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
||||
CronJobControllerV2: {Default: true, PreRelease: featuregate.Beta},
|
||||
DaemonSetUpdateSurge: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ServiceTopology: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ServiceAppProtocol: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||
CronJobControllerV2: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
DaemonSetUpdateSurge: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.22
|
||||
ImmutableEphemeralVolumes: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
|
||||
HugePageStorageMediumSize: {Default: true, PreRelease: featuregate.Beta},
|
||||
HugePageStorageMediumSize: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||
DownwardAPIHugePages: {Default: false, PreRelease: featuregate.Beta}, // on by default in 1.22
|
||||
ExternalPolicyForExternalIP: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
AnyVolumeDataSource: {Default: false, PreRelease: featuregate.Alpha},
|
||||
DefaultPodTopologySpread: {Default: true, PreRelease: featuregate.Beta},
|
||||
SetHostnameAsFQDN: {Default: true, PreRelease: featuregate.Beta},
|
||||
SetHostnameAsFQDN: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, //remove in 1.24
|
||||
WinOverlay: {Default: true, PreRelease: featuregate.Beta},
|
||||
WinDSR: {Default: false, PreRelease: featuregate.Alpha},
|
||||
DisableAcceleratorUsageMetrics: {Default: true, PreRelease: featuregate.Beta},
|
||||
HPAContainerMetrics: {Default: false, PreRelease: featuregate.Alpha},
|
||||
RootCAConfigMap: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
SizeMemoryBackedVolumes: {Default: false, PreRelease: featuregate.Alpha},
|
||||
SizeMemoryBackedVolumes: {Default: true, PreRelease: featuregate.Beta},
|
||||
ExecProbeTimeout: {Default: true, PreRelease: featuregate.GA}, // lock to default and remove after v1.22 based on KEP #1972 update
|
||||
KubeletCredentialProviders: {Default: false, PreRelease: featuregate.Alpha},
|
||||
GracefulNodeShutdown: {Default: true, PreRelease: featuregate.Beta},
|
||||
ServiceLBNodePortControl: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ServiceLBNodePortControl: {Default: true, PreRelease: featuregate.Beta},
|
||||
MixedProtocolLBService: {Default: false, PreRelease: featuregate.Alpha},
|
||||
VolumeCapacityPriority: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PreferNominatedNode: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ProbeTerminationGracePeriod: {Default: false, PreRelease: featuregate.Alpha},
|
||||
RunAsGroup: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
PodDeletionCost: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PreferNominatedNode: {Default: true, PreRelease: featuregate.Beta},
|
||||
ProbeTerminationGracePeriod: {Default: false, PreRelease: featuregate.Beta}, // Default to false in beta 1.22, set to true in 1.24
|
||||
NodeSwap: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PodDeletionCost: {Default: true, PreRelease: featuregate.Beta},
|
||||
TopologyAwareHints: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PodAffinityNamespaceSelector: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ServiceLoadBalancerClass: {Default: false, PreRelease: featuregate.Alpha},
|
||||
LogarithmicScaleDown: {Default: false, PreRelease: featuregate.Alpha},
|
||||
IngressClassNamespacedParams: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ServiceInternalTrafficPolicy: {Default: false, PreRelease: featuregate.Alpha},
|
||||
SuspendJob: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PodAffinityNamespaceSelector: {Default: true, PreRelease: featuregate.Beta},
|
||||
ServiceLoadBalancerClass: {Default: true, PreRelease: featuregate.Beta},
|
||||
IngressClassNamespacedParams: {Default: true, PreRelease: featuregate.Beta},
|
||||
ServiceInternalTrafficPolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||
LogarithmicScaleDown: {Default: true, PreRelease: featuregate.Beta},
|
||||
SuspendJob: {Default: true, PreRelease: featuregate.Beta},
|
||||
KubeletPodResourcesGetAllocatable: {Default: false, PreRelease: featuregate.Alpha},
|
||||
NamespaceDefaultLabelName: {Default: true, PreRelease: featuregate.Beta}, // graduate to GA and lock to default in 1.22, remove in 1.24
|
||||
NamespaceDefaultLabelName: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
|
||||
CSIVolumeHealth: {Default: false, PreRelease: featuregate.Alpha},
|
||||
WindowsHostProcessContainers: {Default: false, PreRelease: featuregate.Alpha},
|
||||
DisableCloudProviders: {Default: false, PreRelease: featuregate.Alpha},
|
||||
StatefulSetMinReadySeconds: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ExpandedDNSConfig: {Default: false, PreRelease: featuregate.Alpha},
|
||||
SeccompDefault: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PodSecurity: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ReadWriteOncePod: {Default: false, PreRelease: featuregate.Alpha},
|
||||
CSRDuration: {Default: true, PreRelease: featuregate.Beta},
|
||||
DelegateFSGroupToCSIDriver: {Default: false, PreRelease: featuregate.Alpha},
|
||||
KubeletInUserNamespace: {Default: false, PreRelease: featuregate.Alpha},
|
||||
MemoryQoS: {Default: false, PreRelease: featuregate.Alpha},
|
||||
CPUManagerPolicyOptions: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ControllerManagerLeaderMigration: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
genericfeatures.StreamingProxyRedirects: {Default: true, PreRelease: featuregate.Deprecated},
|
||||
genericfeatures.ValidateProxyRedirects: {Default: true, PreRelease: featuregate.Beta},
|
||||
genericfeatures.StreamingProxyRedirects: {Default: false, PreRelease: featuregate.Deprecated}, // remove in 1.24
|
||||
genericfeatures.ValidateProxyRedirects: {Default: true, PreRelease: featuregate.Deprecated},
|
||||
genericfeatures.AdvancedAuditing: {Default: true, PreRelease: featuregate.GA},
|
||||
genericfeatures.APIResponseCompression: {Default: true, PreRelease: featuregate.Beta},
|
||||
genericfeatures.APIListChunking: {Default: true, PreRelease: featuregate.Beta},
|
||||
genericfeatures.DryRun: {Default: true, PreRelease: featuregate.GA},
|
||||
genericfeatures.ServerSideApply: {Default: true, PreRelease: featuregate.Beta},
|
||||
genericfeatures.ServerSideApply: {Default: true, PreRelease: featuregate.GA},
|
||||
genericfeatures.APIPriorityAndFairness: {Default: true, PreRelease: featuregate.Beta},
|
||||
genericfeatures.WarningHeaders: {Default: true, PreRelease: featuregate.Beta},
|
||||
genericfeatures.WarningHeaders: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
|
||||
|
||||
// features that enable backwards compatibility but are scheduled to be removed
|
||||
// ...
|
||||
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
|
||||
LegacyNodeRoleBehavior: {Default: false, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
|
||||
}
|
||||
|
28
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go
generated
vendored
28
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go
generated
vendored
@ -221,6 +221,10 @@ type KubeletConfiguration struct {
|
||||
// CPUManagerPolicy is the name of the policy to use.
|
||||
// Requires the CPUManager feature gate to be enabled.
|
||||
CPUManagerPolicy string
|
||||
// CPUManagerPolicyOptions is a set of key=value which allows to set extra options
|
||||
// to fine tune the behaviour of the cpu manager policies.
|
||||
// Requires both the "CPUManager" and "CPUManagerPolicyOptions" feature gates to be enabled.
|
||||
CPUManagerPolicyOptions map[string]string
|
||||
// CPU Manager reconciliation period.
|
||||
// Requires the CPUManager feature gate to be enabled.
|
||||
CPUManagerReconcilePeriod metav1.Duration
|
||||
@ -326,6 +330,10 @@ type KubeletConfiguration struct {
|
||||
FeatureGates map[string]bool
|
||||
// Tells the Kubelet to fail to start if swap is enabled on the node.
|
||||
FailSwapOn bool
|
||||
// memorySwap configures swap memory available to container workloads.
|
||||
// +featureGate=NodeSwap
|
||||
// +optional
|
||||
MemorySwap MemorySwapConfiguration
|
||||
// A quantity defines the maximum size of the container log file before it is rotated. For example: "5Mi" or "256Ki".
|
||||
ContainerLogMaxSize string
|
||||
// Maximum number of container log files that can be present for a container.
|
||||
@ -407,6 +415,17 @@ type KubeletConfiguration struct {
|
||||
EnableProfilingHandler bool
|
||||
// EnableDebugFlagsHandler enables/debug/flags/v handler.
|
||||
EnableDebugFlagsHandler bool
|
||||
// SeccompDefault enables the use of `RuntimeDefault` as the default seccomp profile for all workloads.
|
||||
SeccompDefault bool
|
||||
// MemoryThrottlingFactor specifies the factor multiplied by the memory limit or node allocatable memory
|
||||
// when setting the cgroupv2 memory.high value to enforce MemoryQoS.
|
||||
// Decreasing this factor will set lower high limit for container cgroups and put heavier reclaim pressure
|
||||
// while increasing will put less reclaim pressure.
|
||||
// See http://kep.k8s.io/2570 for more details.
|
||||
// Default: 0.8
|
||||
// +featureGate=MemoryQoS
|
||||
// +optional
|
||||
MemoryThrottlingFactor *float64
|
||||
}
|
||||
|
||||
// KubeletAuthorizationMode denotes the authorization mode for the kubelet
|
||||
@ -566,3 +585,12 @@ type MemoryReservation struct {
|
||||
NumaNode int32
|
||||
Limits v1.ResourceList
|
||||
}
|
||||
|
||||
type MemorySwapConfiguration struct {
|
||||
// swapBehavior configures swap memory available to container workloads. May be one of
|
||||
// "", "LimitedSwap": workload combined memory and swap usage cannot exceed pod memory limit
|
||||
// "UnlimitedSwap": workloads can use unlimited swap, up to the allocatable limit.
|
||||
// +featureGate=NodeSwap
|
||||
// +optional
|
||||
SwapBehavior string
|
||||
}
|
||||
|
29
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
vendored
29
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
vendored
@ -201,6 +201,13 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
||||
out.NodeStatusReportFrequency = in.NodeStatusReportFrequency
|
||||
out.ImageMinimumGCAge = in.ImageMinimumGCAge
|
||||
out.VolumeStatsAggPeriod = in.VolumeStatsAggPeriod
|
||||
if in.CPUManagerPolicyOptions != nil {
|
||||
in, out := &in.CPUManagerPolicyOptions, &out.CPUManagerPolicyOptions
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.CPUManagerReconcilePeriod = in.CPUManagerReconcilePeriod
|
||||
if in.QOSReserved != nil {
|
||||
in, out := &in.QOSReserved, &out.QOSReserved
|
||||
@ -247,6 +254,7 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.MemorySwap = in.MemorySwap
|
||||
if in.AllowedUnsafeSysctls != nil {
|
||||
in, out := &in.AllowedUnsafeSysctls, &out.AllowedUnsafeSysctls
|
||||
*out = make([]string, len(*in))
|
||||
@ -281,6 +289,11 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.MemoryThrottlingFactor != nil {
|
||||
in, out := &in.MemoryThrottlingFactor, &out.MemoryThrottlingFactor
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -376,6 +389,22 @@ func (in *MemoryReservation) DeepCopy() *MemoryReservation {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MemorySwapConfiguration) DeepCopyInto(out *MemorySwapConfiguration) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemorySwapConfiguration.
|
||||
func (in *MemorySwapConfiguration) DeepCopy() *MemorySwapConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MemorySwapConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SerializedNodeConfigSource) DeepCopyInto(out *SerializedNodeConfigSource) {
|
||||
*out = *in
|
||||
|
6
vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go
generated
vendored
@ -38,3 +38,9 @@ const (
|
||||
KubeReservedEnforcementKey = "kube-reserved"
|
||||
NodeAllocatableNoneKey = "none"
|
||||
)
|
||||
|
||||
// SwapBehavior types
|
||||
const (
|
||||
LimitedSwap = "LimitedSwap"
|
||||
UnlimitedSwap = "UnlimitedSwap"
|
||||
)
|
||||
|
9
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go
generated
vendored
@ -120,8 +120,8 @@ const (
|
||||
SyncPodUpdate
|
||||
// SyncPodCreate is when the pod is created from source
|
||||
SyncPodCreate
|
||||
// SyncPodKill is when the pod is killed based on a trigger internal to the kubelet for eviction.
|
||||
// If a SyncPodKill request is made to pod workers, the request is never dropped, and will always be processed.
|
||||
// SyncPodKill is when the pod should have no running containers. A pod stopped in this way could be
|
||||
// restarted in the future due config changes.
|
||||
SyncPodKill
|
||||
)
|
||||
|
||||
@ -184,3 +184,8 @@ func Preemptable(preemptor, preemptee *v1.Pod) bool {
|
||||
func IsCriticalPodBasedOnPriority(priority int32) bool {
|
||||
return priority >= scheduling.SystemCriticalPriority
|
||||
}
|
||||
|
||||
// IsNodeCriticalPod checks if the given pod is a system-node-critical
|
||||
func IsNodeCriticalPod(pod *v1.Pod) bool {
|
||||
return IsCriticalPod(pod) && (pod.Spec.PriorityClassName == scheduling.SystemNodeCritical)
|
||||
}
|
||||
|
14
vendor/k8s.io/kubernetes/pkg/proxy/util/network.go
generated
vendored
14
vendor/k8s.io/kubernetes/pkg/proxy/util/network.go
generated
vendored
@ -24,22 +24,16 @@ import (
|
||||
// code will forward to net library functions, and unit tests will override the methods
|
||||
// for testing purposes.
|
||||
type NetworkInterfacer interface {
|
||||
Addrs(intf *net.Interface) ([]net.Addr, error)
|
||||
Interfaces() ([]net.Interface, error)
|
||||
InterfaceAddrs() ([]net.Addr, error)
|
||||
}
|
||||
|
||||
// RealNetwork implements the NetworkInterfacer interface for production code, just
|
||||
// wrapping the underlying net library function calls.
|
||||
type RealNetwork struct{}
|
||||
|
||||
// Addrs wraps net.Interface.Addrs(), it's a part of NetworkInterfacer interface.
|
||||
func (RealNetwork) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||
return intf.Addrs()
|
||||
}
|
||||
|
||||
// Interfaces wraps net.Interfaces(), it's a part of NetworkInterfacer interface.
|
||||
func (RealNetwork) Interfaces() ([]net.Interface, error) {
|
||||
return net.Interfaces()
|
||||
// InterfaceAddrs wraps net.InterfaceAddrs(), it's a part of NetworkInterfacer interface.
|
||||
func (RealNetwork) InterfaceAddrs() ([]net.Addr, error) {
|
||||
return net.InterfaceAddrs()
|
||||
}
|
||||
|
||||
var _ NetworkInterfacer = &RealNetwork{}
|
||||
|
59
vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go
generated
vendored
59
vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go
generated
vendored
@ -29,7 +29,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilrand "k8s.io/apimachinery/pkg/util/rand"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/tools/events"
|
||||
helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||
utilsysctl "k8s.io/kubernetes/pkg/util/sysctl"
|
||||
utilnet "k8s.io/utils/net"
|
||||
@ -162,7 +162,7 @@ func GetLocalAddrs() ([]net.IP, error) {
|
||||
func GetLocalAddrSet() utilnet.IPSet {
|
||||
localAddrs, err := GetLocalAddrs()
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to get local addresses assuming no local IPs", err)
|
||||
klog.ErrorS(err, "Failed to get local addresses assuming no local IPs")
|
||||
} else if len(localAddrs) == 0 {
|
||||
klog.InfoS("No local addresses were found")
|
||||
}
|
||||
@ -209,9 +209,9 @@ func GetNodeAddresses(cidrs []string, nw NetworkInterfacer) (sets.String, error)
|
||||
}
|
||||
}
|
||||
|
||||
itfs, err := nw.Interfaces()
|
||||
addrs, err := nw.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listing all interfaces from host, error: %v", err)
|
||||
return nil, fmt.Errorf("error listing all interfaceAddrs from host, error: %v", err)
|
||||
}
|
||||
|
||||
// Second round of iteration to parse IPs based on cidr.
|
||||
@ -221,29 +221,24 @@ func GetNodeAddresses(cidrs []string, nw NetworkInterfacer) (sets.String, error)
|
||||
}
|
||||
|
||||
_, ipNet, _ := net.ParseCIDR(cidr)
|
||||
for _, itf := range itfs {
|
||||
addrs, err := nw.Addrs(&itf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting address from interface %s, error: %v", itf.Name, err)
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
// nw.InterfaceAddrs may return net.IPAddr or net.IPNet on windows, and it will return net.IPNet on linux.
|
||||
switch v := addr.(type) {
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if addr == nil {
|
||||
continue
|
||||
if ipNet.Contains(ip) {
|
||||
if utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv6ZeroCIDR) {
|
||||
uniqueAddressList.Insert(ip.String())
|
||||
}
|
||||
|
||||
ip, _, err := net.ParseCIDR(addr.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing CIDR for interface %s, error: %v", itf.Name, err)
|
||||
}
|
||||
|
||||
if ipNet.Contains(ip) {
|
||||
if utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv6ZeroCIDR) {
|
||||
uniqueAddressList.Insert(ip.String())
|
||||
}
|
||||
if !utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv4ZeroCIDR) {
|
||||
uniqueAddressList.Insert(ip.String())
|
||||
}
|
||||
if !utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv4ZeroCIDR) {
|
||||
uniqueAddressList.Insert(ip.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -257,7 +252,7 @@ func GetNodeAddresses(cidrs []string, nw NetworkInterfacer) (sets.String, error)
|
||||
}
|
||||
|
||||
// LogAndEmitIncorrectIPVersionEvent logs and emits incorrect IP version event.
|
||||
func LogAndEmitIncorrectIPVersionEvent(recorder record.EventRecorder, fieldName, fieldValue, svcNamespace, svcName string, svcUID types.UID) {
|
||||
func LogAndEmitIncorrectIPVersionEvent(recorder events.EventRecorder, fieldName, fieldValue, svcNamespace, svcName string, svcUID types.UID) {
|
||||
errMsg := fmt.Sprintf("%s in %s has incorrect IP version", fieldValue, fieldName)
|
||||
klog.Errorf("%s (service %s/%s).", errMsg, svcNamespace, svcName)
|
||||
if recorder != nil {
|
||||
@ -267,7 +262,7 @@ func LogAndEmitIncorrectIPVersionEvent(recorder record.EventRecorder, fieldName,
|
||||
Name: svcName,
|
||||
Namespace: svcNamespace,
|
||||
UID: svcUID,
|
||||
}, v1.EventTypeWarning, "KubeProxyIncorrectIPVersion", errMsg)
|
||||
}, nil, v1.EventTypeWarning, "KubeProxyIncorrectIPVersion", "GatherEndpoints", errMsg)
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,6 +472,18 @@ func WriteLine(buf *bytes.Buffer, words ...string) {
|
||||
}
|
||||
}
|
||||
|
||||
// WriteRuleLine prepends the strings "-A" and chainName to the buffer and calls
|
||||
// WriteLine to join all the words into the buffer and terminate with newline.
|
||||
func WriteRuleLine(buf *bytes.Buffer, chainName string, words ...string) {
|
||||
if len(words) == 0 {
|
||||
return
|
||||
}
|
||||
buf.WriteString("-A ")
|
||||
buf.WriteString(chainName)
|
||||
buf.WriteByte(' ')
|
||||
WriteLine(buf, words...)
|
||||
}
|
||||
|
||||
// WriteBytesLine write bytes to buffer, terminate with newline
|
||||
func WriteBytesLine(buf *bytes.Buffer, bytes []byte) {
|
||||
buf.Write(bytes)
|
||||
|
18
vendor/k8s.io/kubernetes/pkg/security/apparmor/validate.go
generated
vendored
18
vendor/k8s.io/kubernetes/pkg/security/apparmor/validate.go
generated
vendored
@ -20,11 +20,11 @@ import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
@ -107,7 +107,7 @@ func validateHost(runtime string) error {
|
||||
}
|
||||
|
||||
// Check kernel support.
|
||||
if !IsAppArmorEnabled() {
|
||||
if !apparmor.IsEnabled() {
|
||||
return errors.New("AppArmor is not enabled on the host")
|
||||
}
|
||||
|
||||
@ -212,17 +212,3 @@ func getAppArmorFS() (string, error) {
|
||||
|
||||
return "", errors.New("securityfs not found")
|
||||
}
|
||||
|
||||
// IsAppArmorEnabled returns true if apparmor is enabled for the host.
|
||||
// This function is forked from
|
||||
// https://github.com/opencontainers/runc/blob/1a81e9ab1f138c091fe5c86d0883f87716088527/libcontainer/apparmor/apparmor.go
|
||||
// to avoid the libapparmor dependency.
|
||||
func IsAppArmorEnabled() bool {
|
||||
if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" {
|
||||
if _, err = os.Stat("/sbin/apparmor_parser"); err == nil {
|
||||
buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
|
||||
return err == nil && len(buf) > 1 && buf[0] == 'Y'
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
87
vendor/k8s.io/kubernetes/pkg/volume/metrics_block.go
generated
vendored
Normal file
87
vendor/k8s.io/kubernetes/pkg/volume/metrics_block.go
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright 2021 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 volume
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var _ MetricsProvider = &metricsBlock{}
|
||||
|
||||
// metricsBlock represents a MetricsProvider that detects the size of the
|
||||
// BlockMode Volume.
|
||||
type metricsBlock struct {
|
||||
// the device node where the volume is attached to.
|
||||
device string
|
||||
}
|
||||
|
||||
// NewMetricsStatfs creates a new metricsBlock with the device node of the
|
||||
// Volume.
|
||||
func NewMetricsBlock(device string) MetricsProvider {
|
||||
return &metricsBlock{device}
|
||||
}
|
||||
|
||||
// See MetricsProvider.GetMetrics
|
||||
// GetMetrics detects the size of the BlockMode volume for the device node
|
||||
// where the Volume is attached.
|
||||
//
|
||||
// Note that only the capacity of the device can be detected with standard
|
||||
// tools. Storage systems may have more information that they can provide by
|
||||
// going through specialized APIs.
|
||||
func (mb *metricsBlock) GetMetrics() (*Metrics, error) {
|
||||
// TODO: Windows does not yet support VolumeMode=Block
|
||||
if runtime.GOOS == "windows" {
|
||||
return nil, NewNotImplementedError("Windows does not support Block volumes")
|
||||
}
|
||||
|
||||
metrics := &Metrics{Time: metav1.Now()}
|
||||
if mb.device == "" {
|
||||
return metrics, NewNoPathDefinedError()
|
||||
}
|
||||
|
||||
err := mb.getBlockInfo(metrics)
|
||||
if err != nil {
|
||||
return metrics, err
|
||||
}
|
||||
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
// getBlockInfo fetches metrics.Capacity by opening the device and seeking to
|
||||
// the end.
|
||||
func (mb *metricsBlock) getBlockInfo(metrics *Metrics) error {
|
||||
dev, err := os.Open(mb.device)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to open device %q: %w", mb.device, err)
|
||||
}
|
||||
defer dev.Close()
|
||||
|
||||
end, err := dev.Seek(0, io.SeekEnd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to detect size of %q: %w", mb.device, err)
|
||||
}
|
||||
|
||||
metrics.Capacity = resource.NewQuantity(end, resource.BinarySI)
|
||||
|
||||
return nil
|
||||
}
|
26
vendor/k8s.io/kubernetes/pkg/volume/metrics_du.go
generated
vendored
26
vendor/k8s.io/kubernetes/pkg/volume/metrics_du.go
generated
vendored
@ -46,12 +46,7 @@ func (md *metricsDu) GetMetrics() (*Metrics, error) {
|
||||
return metrics, NewNoPathDefinedError()
|
||||
}
|
||||
|
||||
err := md.runDiskUsage(metrics)
|
||||
if err != nil {
|
||||
return metrics, err
|
||||
}
|
||||
|
||||
err = md.runFind(metrics)
|
||||
err := md.getDiskUsage(metrics)
|
||||
if err != nil {
|
||||
return metrics, err
|
||||
}
|
||||
@ -64,23 +59,14 @@ func (md *metricsDu) GetMetrics() (*Metrics, error) {
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
// runDiskUsage gets disk usage of md.path and writes the results to metrics.Used
|
||||
func (md *metricsDu) runDiskUsage(metrics *Metrics) error {
|
||||
used, err := fs.DiskUsage(md.path)
|
||||
// getDiskUsage writes metrics.Used and metric.InodesUsed from fs.DiskUsage
|
||||
func (md *metricsDu) getDiskUsage(metrics *Metrics) error {
|
||||
usage, err := fs.DiskUsage(md.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metrics.Used = used
|
||||
return nil
|
||||
}
|
||||
|
||||
// runFind executes the "find" command and writes the results to metrics.InodesUsed
|
||||
func (md *metricsDu) runFind(metrics *Metrics) error {
|
||||
inodesUsed, err := fs.Find(md.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metrics.InodesUsed = resource.NewQuantity(inodesUsed, resource.BinarySI)
|
||||
metrics.Used = resource.NewQuantity(usage.Bytes, resource.BinarySI)
|
||||
metrics.InodesUsed = resource.NewQuantity(usage.Inodes, resource.BinarySI)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
8
vendor/k8s.io/kubernetes/pkg/volume/metrics_errors.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/volume/metrics_errors.go
generated
vendored
@ -35,6 +35,14 @@ func NewNotSupportedError() *MetricsError {
|
||||
}
|
||||
}
|
||||
|
||||
// NewNotImplementedError creates a new MetricsError with code NotSupported.
|
||||
func NewNotImplementedError(reason string) *MetricsError {
|
||||
return &MetricsError{
|
||||
Code: ErrCodeNotSupported,
|
||||
Msg: fmt.Sprintf("metrics support is not implemented: %s", reason),
|
||||
}
|
||||
}
|
||||
|
||||
// NewNotSupportedErrorWithDriverName creates a new MetricsError with code NotSupported.
|
||||
// driver name is added to the error message.
|
||||
func NewNotSupportedErrorWithDriverName(name string) *MetricsError {
|
||||
|
5
vendor/k8s.io/kubernetes/pkg/volume/metrics_nil.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/volume/metrics_nil.go
generated
vendored
@ -23,6 +23,11 @@ var _ MetricsProvider = &MetricsNil{}
|
||||
// metrics.
|
||||
type MetricsNil struct{}
|
||||
|
||||
// SupportsMetrics returns false for the MetricsNil type.
|
||||
func (*MetricsNil) SupportsMetrics() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetMetrics returns an empty Metrics and an error.
|
||||
// See MetricsProvider.GetMetrics
|
||||
func (*MetricsNil) GetMetrics() (*Metrics, error) {
|
||||
|
36
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
36
vendor/k8s.io/kubernetes/pkg/volume/plugins.go
generated
vendored
@ -71,8 +71,10 @@ const (
|
||||
|
||||
var (
|
||||
deprecatedVolumeProviders = map[string]string{
|
||||
"kubernetes.io/cinder": "The Cinder volume provider is deprecated and will be removed in a future release",
|
||||
"kubernetes.io/scaleio": "The ScaleIO volume provider is deprecated and will be removed in a future release",
|
||||
"kubernetes.io/cinder": "The Cinder volume provider is deprecated and will be removed in a future release",
|
||||
"kubernetes.io/storageos": "The StorageOS volume provider is deprecated and will be removed in a future release",
|
||||
"kubernetes.io/quobyte": "The Quobyte volume provider is deprecated and will be removed in a future release",
|
||||
"kubernetes.io/flocker": "The Flocker volume provider is deprecated and will be removed in a future release",
|
||||
}
|
||||
)
|
||||
|
||||
@ -606,7 +608,7 @@ func (pm *VolumePluginMgr) InitPlugins(plugins []VolumePlugin, prober DynamicPlu
|
||||
}
|
||||
if err := pm.prober.Init(); err != nil {
|
||||
// Prober init failure should not affect the initialization of other plugins.
|
||||
klog.Errorf("Error initializing dynamic plugin prober: %s", err)
|
||||
klog.ErrorS(err, "Error initializing dynamic plugin prober")
|
||||
pm.prober = &dummyPluginProber{}
|
||||
}
|
||||
|
||||
@ -631,12 +633,12 @@ func (pm *VolumePluginMgr) InitPlugins(plugins []VolumePlugin, prober DynamicPlu
|
||||
}
|
||||
err := plugin.Init(host)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to load volume plugin %s, error: %s", name, err.Error())
|
||||
klog.ErrorS(err, "Failed to load volume plugin", "pluginName", name)
|
||||
allErrs = append(allErrs, err)
|
||||
continue
|
||||
}
|
||||
pm.plugins[name] = plugin
|
||||
klog.V(1).Infof("Loaded volume plugin %q", name)
|
||||
klog.V(1).InfoS("Loaded volume plugin", "pluginName", name)
|
||||
}
|
||||
return utilerrors.NewAggregate(allErrs)
|
||||
}
|
||||
@ -649,10 +651,10 @@ func (pm *VolumePluginMgr) initProbedPlugin(probedPlugin VolumePlugin) error {
|
||||
|
||||
err := probedPlugin.Init(pm.Host)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to load volume plugin %s, error: %s", name, err.Error())
|
||||
return fmt.Errorf("failed to load volume plugin %s, error: %s", name, err.Error())
|
||||
}
|
||||
|
||||
klog.V(1).Infof("Loaded volume plugin %q", name)
|
||||
klog.V(1).InfoS("Loaded volume plugin", "pluginName", name)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -664,7 +666,7 @@ func (pm *VolumePluginMgr) FindPluginBySpec(spec *Spec) (VolumePlugin, error) {
|
||||
defer pm.mutex.RUnlock()
|
||||
|
||||
if spec == nil {
|
||||
return nil, fmt.Errorf("Could not find plugin because volume spec is nil")
|
||||
return nil, fmt.Errorf("could not find plugin because volume spec is nil")
|
||||
}
|
||||
|
||||
matches := []VolumePlugin{}
|
||||
@ -745,15 +747,15 @@ func (pm *VolumePluginMgr) logDeprecation(plugin string) {
|
||||
func (pm *VolumePluginMgr) refreshProbedPlugins() {
|
||||
events, err := pm.prober.Probe()
|
||||
if err != nil {
|
||||
klog.Errorf("Error dynamically probing plugins: %s", err)
|
||||
klog.ErrorS(err, "Error dynamically probing plugins")
|
||||
return // Use cached plugins upon failure.
|
||||
}
|
||||
|
||||
for _, event := range events {
|
||||
if event.Op == ProbeAddOrUpdate {
|
||||
if err := pm.initProbedPlugin(event.Plugin); err != nil {
|
||||
klog.Errorf("Error initializing dynamically probed plugin %s; error: %s",
|
||||
event.Plugin.GetPluginName(), err)
|
||||
klog.ErrorS(err, "Error initializing dynamically probed plugin",
|
||||
"pluginName", event.Plugin.GetPluginName())
|
||||
continue
|
||||
}
|
||||
pm.probedPlugins[event.Plugin.GetPluginName()] = event.Plugin
|
||||
@ -761,8 +763,8 @@ func (pm *VolumePluginMgr) refreshProbedPlugins() {
|
||||
// Plugin is not available on ProbeRemove event, only PluginName
|
||||
delete(pm.probedPlugins, event.PluginName)
|
||||
} else {
|
||||
klog.Errorf("Unknown Operation on PluginName: %s.",
|
||||
event.Plugin.GetPluginName())
|
||||
klog.ErrorS(nil, "Unknown Operation on PluginName.",
|
||||
"pluginName", event.Plugin.GetPluginName())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -787,7 +789,7 @@ func (pm *VolumePluginMgr) ListVolumePluginWithLimits() []VolumePluginWithAttach
|
||||
func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *Spec) (PersistentVolumePlugin, error) {
|
||||
volumePlugin, err := pm.FindPluginBySpec(spec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not find volume plugin for spec: %#v", spec)
|
||||
return nil, fmt.Errorf("could not find volume plugin for spec: %#v", spec)
|
||||
}
|
||||
if persistentVolumePlugin, ok := volumePlugin.(PersistentVolumePlugin); ok {
|
||||
return persistentVolumePlugin, nil
|
||||
@ -800,7 +802,7 @@ func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *Spec) (PersistentVol
|
||||
func (pm *VolumePluginMgr) FindVolumePluginWithLimitsBySpec(spec *Spec) (VolumePluginWithAttachLimits, error) {
|
||||
volumePlugin, err := pm.FindPluginBySpec(spec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not find volume plugin for spec : %#v", spec)
|
||||
return nil, fmt.Errorf("could not find volume plugin for spec : %#v", spec)
|
||||
}
|
||||
|
||||
if limitedPlugin, ok := volumePlugin.(VolumePluginWithAttachLimits); ok {
|
||||
@ -956,10 +958,10 @@ func (pm *VolumePluginMgr) FindExpandablePluginBySpec(spec *Spec) (ExpandableVol
|
||||
if spec.IsKubeletExpandable() {
|
||||
// for kubelet expandable volumes, return a noop plugin that
|
||||
// returns success for expand on the controller
|
||||
klog.V(4).Infof("FindExpandablePluginBySpec(%s) -> returning noopExpandableVolumePluginInstance", spec.Name())
|
||||
klog.V(4).InfoS("FindExpandablePluginBySpec -> returning noopExpandableVolumePluginInstance", "specName", spec.Name())
|
||||
return &noopExpandableVolumePluginInstance{spec}, nil
|
||||
}
|
||||
klog.V(4).Infof("FindExpandablePluginBySpec(%s) -> err:%v", spec.Name(), err)
|
||||
klog.V(4).InfoS("FindExpandablePluginBySpec -> err", "specName", spec.Name(), "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
134
vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs.go
generated
vendored
134
vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs.go
generated
vendored
@ -19,17 +19,21 @@ limitations under the License.
|
||||
package fs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/volume/util/fsquota"
|
||||
)
|
||||
|
||||
type UsageInfo struct {
|
||||
Bytes int64
|
||||
Inodes int64
|
||||
}
|
||||
|
||||
// Info linux returns (available bytes, byte capacity, byte usage, total inodes, inodes free, inode usage, error)
|
||||
// for the filesystem that path resides upon.
|
||||
func Info(path string) (int64, int64, int64, int64, int64, int64, error) {
|
||||
@ -55,63 +59,83 @@ func Info(path string) (int64, int64, int64, int64, int64, int64, error) {
|
||||
return available, capacity, usage, inodes, inodesFree, inodesUsed, nil
|
||||
}
|
||||
|
||||
// DiskUsage gets disk usage of specified path.
|
||||
func DiskUsage(path string) (*resource.Quantity, error) {
|
||||
// First check whether the quota system knows about this directory
|
||||
// A nil quantity with no error means that the path does not support quotas
|
||||
// and we should use other mechanisms.
|
||||
data, err := fsquota.GetConsumption(path)
|
||||
if data != nil {
|
||||
return data, nil
|
||||
} else if err != nil {
|
||||
return nil, fmt.Errorf("unable to retrieve disk consumption via quota for %s: %v", path, err)
|
||||
}
|
||||
// Uses the same niceness level as cadvisor.fs does when running du
|
||||
// Uses -B 1 to always scale to a blocksize of 1 byte
|
||||
out, err := exec.Command("nice", "-n", "19", "du", "-x", "-s", "-B", "1", path).CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed command 'du' ($ nice -n 19 du -x -s -B 1) on path %s with error %v", path, err)
|
||||
}
|
||||
used, err := resource.ParseQuantity(strings.Fields(string(out))[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
|
||||
}
|
||||
used.Format = resource.BinarySI
|
||||
return &used, nil
|
||||
}
|
||||
// DiskUsage calculates the number of inodes and disk usage for a given directory
|
||||
func DiskUsage(path string) (UsageInfo, error) {
|
||||
var usage UsageInfo
|
||||
|
||||
// Find uses the equivalent of the command `find <path> -dev -printf '.' | wc -c` to count files and directories.
|
||||
// While this is not an exact measure of inodes used, it is a very good approximation.
|
||||
func Find(path string) (int64, error) {
|
||||
if path == "" {
|
||||
return 0, fmt.Errorf("invalid directory")
|
||||
return usage, fmt.Errorf("invalid directory")
|
||||
}
|
||||
|
||||
// First check whether the quota system knows about this directory
|
||||
// A nil quantity with no error means that the path does not support quotas
|
||||
// and we should use other mechanisms.
|
||||
inodes, err := fsquota.GetInodes(path)
|
||||
// A nil quantity or error means that the path does not support quotas
|
||||
// or xfs_quota tool is missing and we should use other mechanisms.
|
||||
consumption, _ := fsquota.GetConsumption(path)
|
||||
if consumption != nil {
|
||||
usage.Bytes = consumption.Value()
|
||||
}
|
||||
|
||||
inodes, _ := fsquota.GetInodes(path)
|
||||
if inodes != nil {
|
||||
return inodes.Value(), nil
|
||||
} else if err != nil {
|
||||
return 0, fmt.Errorf("unable to retrieve inode consumption via quota for %s: %v", path, err)
|
||||
usage.Inodes = inodes.Value()
|
||||
}
|
||||
var counter byteCounter
|
||||
var stderr bytes.Buffer
|
||||
findCmd := exec.Command("find", path, "-xdev", "-printf", ".")
|
||||
findCmd.Stdout, findCmd.Stderr = &counter, &stderr
|
||||
if err := findCmd.Start(); err != nil {
|
||||
return 0, fmt.Errorf("failed to exec cmd %v - %v; stderr: %v", findCmd.Args, err, stderr.String())
|
||||
}
|
||||
if err := findCmd.Wait(); err != nil {
|
||||
return 0, fmt.Errorf("cmd %v failed. stderr: %s; err: %v", findCmd.Args, stderr.String(), err)
|
||||
}
|
||||
return counter.bytesWritten, nil
|
||||
}
|
||||
|
||||
// Simple io.Writer implementation that counts how many bytes were written.
|
||||
type byteCounter struct{ bytesWritten int64 }
|
||||
if inodes != nil && consumption != nil {
|
||||
return usage, nil
|
||||
}
|
||||
|
||||
func (b *byteCounter) Write(p []byte) (int, error) {
|
||||
b.bytesWritten += int64(len(p))
|
||||
return len(p), nil
|
||||
topLevelStat := &unix.Stat_t{}
|
||||
err := unix.Stat(path, topLevelStat)
|
||||
if err != nil {
|
||||
return usage, err
|
||||
}
|
||||
|
||||
// dedupedInode stores inodes that could be duplicates (nlink > 1)
|
||||
dedupedInodes := make(map[uint64]struct{})
|
||||
|
||||
err = filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||
// ignore files that have been deleted after directory was read
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to count inodes for %s: %s", path, err)
|
||||
}
|
||||
|
||||
// according to the docs, Sys can be nil
|
||||
if info.Sys() == nil {
|
||||
return fmt.Errorf("fileinfo Sys is nil")
|
||||
}
|
||||
|
||||
s, ok := info.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported fileinfo; could not convert to stat_t")
|
||||
}
|
||||
|
||||
if s.Dev != topLevelStat.Dev {
|
||||
// don't descend into directories on other devices
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
// Dedupe hardlinks
|
||||
if s.Nlink > 1 {
|
||||
if _, ok := dedupedInodes[s.Ino]; !ok {
|
||||
dedupedInodes[s.Ino] = struct{}{}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if consumption == nil {
|
||||
usage.Bytes += int64(s.Blocks) * int64(512) // blocksize in bytes
|
||||
}
|
||||
|
||||
if inodes == nil {
|
||||
usage.Inodes++
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return usage, err
|
||||
}
|
||||
|
17
vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_unsupported.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_unsupported.go
generated
vendored
@ -20,21 +20,20 @@ package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
type UsageInfo struct {
|
||||
Bytes int64
|
||||
Inodes int64
|
||||
}
|
||||
|
||||
// Info unsupported returns 0 values for available and capacity and an error.
|
||||
func Info(path string) (int64, int64, int64, int64, int64, int64, error) {
|
||||
return 0, 0, 0, 0, 0, 0, fmt.Errorf("fsinfo not supported for this build")
|
||||
}
|
||||
|
||||
// DiskUsage gets disk usage of specified path.
|
||||
func DiskUsage(path string) (*resource.Quantity, error) {
|
||||
return nil, fmt.Errorf("du not supported for this build")
|
||||
}
|
||||
|
||||
// Find will always return zero since is on unsupported platform.
|
||||
func Find(path string) (int64, error) {
|
||||
return 0, fmt.Errorf("find not supported for this build")
|
||||
func DiskUsage(path string) (UsageInfo, error) {
|
||||
var usage UsageInfo
|
||||
return usage, fmt.Errorf("directory disk usage not supported for this build.")
|
||||
}
|
||||
|
30
vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go
generated
vendored
30
vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go
generated
vendored
@ -26,8 +26,6 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -35,6 +33,11 @@ var (
|
||||
procGetDiskFreeSpaceEx = modkernel32.NewProc("GetDiskFreeSpaceExW")
|
||||
)
|
||||
|
||||
type UsageInfo struct {
|
||||
Bytes int64
|
||||
Inodes int64
|
||||
}
|
||||
|
||||
// Info returns (available bytes, byte capacity, byte usage, total inodes, inodes free, inode usage, error)
|
||||
// for the filesystem that path resides upon.
|
||||
func Info(path string) (int64, int64, int64, int64, int64, int64, error) {
|
||||
@ -64,28 +67,15 @@ func Info(path string) (int64, int64, int64, int64, int64, int64, error) {
|
||||
}
|
||||
|
||||
// DiskUsage gets disk usage of specified path.
|
||||
func DiskUsage(path string) (*resource.Quantity, error) {
|
||||
func DiskUsage(path string) (UsageInfo, error) {
|
||||
var usage UsageInfo
|
||||
info, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return usage, err
|
||||
}
|
||||
|
||||
usage, err := diskUsage(path, info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
used, err := resource.ParseQuantity(fmt.Sprintf("%d", usage))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse fs usage %d due to %v", usage, err)
|
||||
}
|
||||
used.Format = resource.BinarySI
|
||||
return &used, nil
|
||||
}
|
||||
|
||||
// Find will always return zero since inodes is not supported on Windows.
|
||||
func Find(path string) (int64, error) {
|
||||
return 0, nil
|
||||
usage.Bytes, err = diskUsage(path, info)
|
||||
return usage, err
|
||||
}
|
||||
|
||||
func diskUsage(currPath string, info os.FileInfo) (int64, error) {
|
||||
|
5
vendor/k8s.io/kubernetes/pkg/volume/util/types/types.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/volume/util/types/types.go
generated
vendored
@ -148,10 +148,7 @@ func IsOperationFinishedError(err error) bool {
|
||||
// on PVC and actual filesystem on disk did not match
|
||||
func IsFilesystemMismatchError(err error) bool {
|
||||
mountError := mount.MountError{}
|
||||
if errors.As(err, &mountError) && mountError.Type == mount.FilesystemMismatch {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return errors.As(err, &mountError) && mountError.Type == mount.FilesystemMismatch
|
||||
}
|
||||
|
||||
// IsUncertainProgressError checks if given error is of type that indicates
|
||||
|
15
vendor/k8s.io/kubernetes/pkg/volume/volume.go
generated
vendored
15
vendor/k8s.io/kubernetes/pkg/volume/volume.go
generated
vendored
@ -48,6 +48,14 @@ type BlockVolume interface {
|
||||
// and name of a symbolic link associated to a block device.
|
||||
// ex. pods/{podUid}/{DefaultKubeletVolumeDevicesDirName}/{escapeQualifiedPluginName}/, {volumeName}
|
||||
GetPodDeviceMapPath() (string, string)
|
||||
|
||||
// SupportsMetrics should return true if the MetricsProvider is
|
||||
// initialized
|
||||
SupportsMetrics() bool
|
||||
|
||||
// MetricsProvider embeds methods for exposing metrics (e.g.
|
||||
// used, available space).
|
||||
MetricsProvider
|
||||
}
|
||||
|
||||
// MetricsProvider exposes metrics (e.g. used,available space) related to a
|
||||
@ -263,6 +271,11 @@ type Attacher interface {
|
||||
WaitForAttach(spec *Spec, devicePath string, pod *v1.Pod, timeout time.Duration) (string, error)
|
||||
}
|
||||
|
||||
// DeviceMounterArgs provides auxiliary, optional arguments to DeviceMounter.
|
||||
type DeviceMounterArgs struct {
|
||||
FsGroup *int64
|
||||
}
|
||||
|
||||
// DeviceMounter can mount a block volume to a global path.
|
||||
type DeviceMounter interface {
|
||||
// GetDeviceMountPath returns a path where the device should
|
||||
@ -277,7 +290,7 @@ type DeviceMounter interface {
|
||||
// - TransientOperationFailure
|
||||
// - UncertainProgressError
|
||||
// - Error of any other type should be considered a final error
|
||||
MountDevice(spec *Spec, devicePath string, deviceMountPath string) error
|
||||
MountDevice(spec *Spec, devicePath string, deviceMountPath string, deviceMounterArgs DeviceMounterArgs) error
|
||||
}
|
||||
|
||||
type BulkVolumeVerifier interface {
|
||||
|
16
vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go
generated
vendored
16
vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go
generated
vendored
@ -66,7 +66,7 @@ func SetVolumeOwnership(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1
|
||||
}
|
||||
|
||||
if skipPermissionChange(mounter, fsGroup, fsGroupChangePolicy) {
|
||||
klog.V(3).Infof("skipping permission and ownership change for volume %s", mounter.GetPath())
|
||||
klog.V(3).InfoS("Skipping permission and ownership change for volume", "path", mounter.GetPath())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ func legacyOwnershipChange(mounter Mounter, fsGroup *int64) error {
|
||||
func changeFilePermission(filename string, fsGroup *int64, readonly bool, info os.FileInfo) error {
|
||||
err := os.Lchown(filename, -1, int(*fsGroup))
|
||||
if err != nil {
|
||||
klog.Errorf("Lchown failed on %v: %v", filename, err)
|
||||
klog.ErrorS(err, "Lchown failed", "path", filename)
|
||||
}
|
||||
|
||||
// chmod passes through to the underlying file for symlinks.
|
||||
@ -122,7 +122,7 @@ func changeFilePermission(filename string, fsGroup *int64, readonly bool, info o
|
||||
|
||||
err = os.Chmod(filename, info.Mode()|mask)
|
||||
if err != nil {
|
||||
klog.Errorf("Chmod failed on %v: %v", filename, err)
|
||||
klog.ErrorS(err, "Chown failed", "path", filename)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -132,7 +132,7 @@ func skipPermissionChange(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *
|
||||
dir := mounter.GetPath()
|
||||
|
||||
if fsGroupChangePolicy == nil || *fsGroupChangePolicy != v1.FSGroupChangeOnRootMismatch {
|
||||
klog.V(4).Infof("perform recursive ownership change for %s", dir)
|
||||
klog.V(4).InfoS("Perform recursive ownership change for directory", "path", dir)
|
||||
return false
|
||||
}
|
||||
return !requiresPermissionChange(mounter.GetPath(), fsGroup, mounter.GetAttributes().ReadOnly)
|
||||
@ -141,17 +141,17 @@ func skipPermissionChange(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *
|
||||
func requiresPermissionChange(rootDir string, fsGroup *int64, readonly bool) bool {
|
||||
fsInfo, err := os.Stat(rootDir)
|
||||
if err != nil {
|
||||
klog.Errorf("performing recursive ownership change on %s because reading permissions of root volume failed: %v", rootDir, err)
|
||||
klog.ErrorS(err, "Performing recursive ownership change on rootDir because reading permissions of root volume failed", "path", rootDir)
|
||||
return true
|
||||
}
|
||||
stat, ok := fsInfo.Sys().(*syscall.Stat_t)
|
||||
if !ok || stat == nil {
|
||||
klog.Errorf("performing recursive ownership change on %s because reading permissions of root volume failed", rootDir)
|
||||
klog.ErrorS(nil, "Performing recursive ownership change on rootDir because reading permissions of root volume failed", "path", rootDir)
|
||||
return true
|
||||
}
|
||||
|
||||
if int(stat.Gid) != int(*fsGroup) {
|
||||
klog.V(4).Infof("expected group ownership of volume %s did not match with: %d", rootDir, stat.Gid)
|
||||
klog.V(4).InfoS("Expected group ownership of volume did not match with Gid", "path", rootDir, "GID", stat.Gid)
|
||||
return true
|
||||
}
|
||||
unixPerms := rwMask
|
||||
@ -175,7 +175,7 @@ func requiresPermissionChange(rootDir string, fsGroup *int64, readonly bool) boo
|
||||
// unixPerms: 770, filePerms: 750 : 770&750 = 750 (perms on directory is NOT a superset)
|
||||
// We also need to check if setgid bits are set in permissions of the directory.
|
||||
if (unixPerms&filePerm != unixPerms) || (fsInfo.Mode()&os.ModeSetgid == 0) {
|
||||
klog.V(4).Infof("performing recursive ownership change on %s because of mismatching mode", rootDir)
|
||||
klog.V(4).InfoS("Performing recursive ownership change on rootDir because of mismatching mode", "path", rootDir)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
6
vendor/k8s.io/kubernetes/test/e2e/framework/auth/helpers.go
generated
vendored
6
vendor/k8s.io/kubernetes/test/e2e/framework/auth/helpers.go
generated
vendored
@ -18,10 +18,10 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
authorizationv1 "k8s.io/api/authorization/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -99,7 +99,7 @@ func BindClusterRole(c bindingsGetter, clusterRole, ns string, subjects ...rbacv
|
||||
}, metav1.CreateOptions{})
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "binding clusterrole/%s for %q for %v", clusterRole, ns, subjects)
|
||||
return fmt.Errorf("binding clusterrole/%s for %q for %v: %w", clusterRole, ns, subjects, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -136,7 +136,7 @@ func bindInNamespace(c bindingsGetter, roleType, role, ns string, subjects ...rb
|
||||
}, metav1.CreateOptions{})
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "binding %s/%s into %q for %v", roleType, role, ns, subjects)
|
||||
return fmt.Errorf("binding %s/%s into %q for %v: %w", roleType, role, ns, subjects, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/framework/cleanup.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/framework/cleanup.go
generated
vendored
@ -17,6 +17,9 @@ limitations under the License.
|
||||
package framework
|
||||
|
||||
import (
|
||||
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@ -70,6 +73,7 @@ func RunCleanupActions() {
|
||||
}()
|
||||
// Run unlocked.
|
||||
for _, fn := range list {
|
||||
e2elog.Logf("Running Cleanup Action: %v", runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name())
|
||||
fn()
|
||||
}
|
||||
}
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/framework/framework.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/framework/framework.go
generated
vendored
@ -296,7 +296,7 @@ func (f *Framework) BeforeEach() {
|
||||
|
||||
gatherMetricsAfterTest := TestContext.GatherMetricsAfterTest == "true" || TestContext.GatherMetricsAfterTest == "master"
|
||||
if gatherMetricsAfterTest && TestContext.IncludeClusterAutoscalerMetrics {
|
||||
grabber, err := e2emetrics.NewMetricsGrabber(f.ClientSet, f.KubemarkExternalClusterClientSet, !ProviderIs("kubemark"), false, false, false, TestContext.IncludeClusterAutoscalerMetrics)
|
||||
grabber, err := e2emetrics.NewMetricsGrabber(f.ClientSet, f.KubemarkExternalClusterClientSet, f.ClientConfig(), !ProviderIs("kubemark"), false, false, false, TestContext.IncludeClusterAutoscalerMetrics, false)
|
||||
if err != nil {
|
||||
Logf("Failed to create MetricsGrabber (skipping ClusterAutoscaler metrics gathering before test): %v", err)
|
||||
} else {
|
||||
@ -449,7 +449,7 @@ func (f *Framework) AfterEach() {
|
||||
ginkgo.By("Gathering metrics")
|
||||
// Grab apiserver, scheduler, controller-manager metrics and (optionally) nodes' kubelet metrics.
|
||||
grabMetricsFromKubelets := TestContext.GatherMetricsAfterTest != "master" && !ProviderIs("kubemark")
|
||||
grabber, err := e2emetrics.NewMetricsGrabber(f.ClientSet, f.KubemarkExternalClusterClientSet, grabMetricsFromKubelets, true, true, true, TestContext.IncludeClusterAutoscalerMetrics)
|
||||
grabber, err := e2emetrics.NewMetricsGrabber(f.ClientSet, f.KubemarkExternalClusterClientSet, f.ClientConfig(), grabMetricsFromKubelets, true, true, true, TestContext.IncludeClusterAutoscalerMetrics, false)
|
||||
if err != nil {
|
||||
Logf("Failed to create MetricsGrabber (skipping metrics gathering): %v", err)
|
||||
} else {
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go
generated
vendored
@ -142,6 +142,10 @@ func (tk *TestKubeconfig) WriteFileViaContainer(podName, containerName string, p
|
||||
}
|
||||
}
|
||||
command := fmt.Sprintf("echo '%s' > '%s'; sync", contents, path)
|
||||
// TODO(mauriciopoppe): remove this statement once we add `sync` to the test image, ref #101172
|
||||
if e2epod.NodeOSDistroIs("windows") {
|
||||
command = fmt.Sprintf("echo '%s' > '%s';", contents, path)
|
||||
}
|
||||
stdout, stderr, err := tk.kubectlExecWithRetry(tk.Namespace, podName, containerName, "--", "/bin/sh", "-c", command)
|
||||
if err != nil {
|
||||
e2elog.Logf("error running kubectl exec to write file: %v\nstdout=%v\nstderr=%v)", err, string(stdout), string(stderr))
|
||||
|
2
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/kubelet_metrics.go
generated
vendored
2
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/kubelet_metrics.go
generated
vendored
@ -139,7 +139,7 @@ func getKubeletMetricsFromNode(c clientset.Interface, nodeName string) (KubeletM
|
||||
if c == nil {
|
||||
return GrabKubeletMetricsWithoutProxy(nodeName, "/metrics")
|
||||
}
|
||||
grabber, err := NewMetricsGrabber(c, nil, true, false, false, false, false)
|
||||
grabber, err := NewMetricsGrabber(c, nil, nil, true, false, false, false, false, false)
|
||||
if err != nil {
|
||||
return KubeletMetrics{}, err
|
||||
}
|
||||
|
292
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/metrics_grabber.go
generated
vendored
292
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/metrics_grabber.go
generated
vendored
@ -18,62 +18,89 @@ package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||
)
|
||||
|
||||
const (
|
||||
// insecureSchedulerPort is the default port for the scheduler status server.
|
||||
// May be overridden by a flag at startup.
|
||||
// Deprecated: use the secure KubeSchedulerPort instead.
|
||||
insecureSchedulerPort = 10251
|
||||
// insecureKubeControllerManagerPort is the default port for the controller manager status server.
|
||||
// May be overridden by a flag at startup.
|
||||
// Deprecated: use the secure KubeControllerManagerPort instead.
|
||||
insecureKubeControllerManagerPort = 10252
|
||||
// kubeSchedulerPort is the default port for the scheduler status server.
|
||||
kubeSchedulerPort = 10259
|
||||
// kubeControllerManagerPort is the default port for the controller manager status server.
|
||||
kubeControllerManagerPort = 10257
|
||||
// snapshotControllerPort is the port for the snapshot controller
|
||||
snapshotControllerPort = 9102
|
||||
)
|
||||
|
||||
// MetricsGrabbingDisabledError is an error that is wrapped by the
|
||||
// different MetricsGrabber.Wrap functions when metrics grabbing is
|
||||
// not supported. Tests that check metrics data should then skip
|
||||
// the check.
|
||||
var MetricsGrabbingDisabledError = errors.New("metrics grabbing disabled")
|
||||
|
||||
// Collection is metrics collection of components
|
||||
type Collection struct {
|
||||
APIServerMetrics APIServerMetrics
|
||||
ControllerManagerMetrics ControllerManagerMetrics
|
||||
KubeletMetrics map[string]KubeletMetrics
|
||||
SchedulerMetrics SchedulerMetrics
|
||||
ClusterAutoscalerMetrics ClusterAutoscalerMetrics
|
||||
APIServerMetrics APIServerMetrics
|
||||
ControllerManagerMetrics ControllerManagerMetrics
|
||||
SnapshotControllerMetrics SnapshotControllerMetrics
|
||||
KubeletMetrics map[string]KubeletMetrics
|
||||
SchedulerMetrics SchedulerMetrics
|
||||
ClusterAutoscalerMetrics ClusterAutoscalerMetrics
|
||||
}
|
||||
|
||||
// Grabber provides functions which grab metrics from components
|
||||
type Grabber struct {
|
||||
client clientset.Interface
|
||||
externalClient clientset.Interface
|
||||
grabFromAPIServer bool
|
||||
grabFromControllerManager bool
|
||||
grabFromKubelets bool
|
||||
grabFromScheduler bool
|
||||
grabFromClusterAutoscaler bool
|
||||
kubeScheduler string
|
||||
kubeControllerManager string
|
||||
waitForControllerManagerReadyOnce sync.Once
|
||||
client clientset.Interface
|
||||
externalClient clientset.Interface
|
||||
config *rest.Config
|
||||
grabFromAPIServer bool
|
||||
grabFromControllerManager bool
|
||||
grabFromKubelets bool
|
||||
grabFromScheduler bool
|
||||
grabFromClusterAutoscaler bool
|
||||
grabFromSnapshotController bool
|
||||
kubeScheduler string
|
||||
waitForSchedulerReadyOnce sync.Once
|
||||
kubeControllerManager string
|
||||
waitForControllerManagerReadyOnce sync.Once
|
||||
snapshotController string
|
||||
waitForSnapshotControllerReadyOnce sync.Once
|
||||
}
|
||||
|
||||
// NewMetricsGrabber returns new metrics which are initialized.
|
||||
func NewMetricsGrabber(c clientset.Interface, ec clientset.Interface, kubelets bool, scheduler bool, controllers bool, apiServer bool, clusterAutoscaler bool) (*Grabber, error) {
|
||||
// NewMetricsGrabber prepares for grabbing metrics data from several different
|
||||
// components. It should be called when those components are running because
|
||||
// it needs to communicate with them to determine for which components
|
||||
// metrics data can be retrieved.
|
||||
//
|
||||
// Collecting metrics data is an optional debug feature. Not all clusters will
|
||||
// support it. If disabled for a component, the corresponding Grab function
|
||||
// will immediately return an error derived from MetricsGrabbingDisabledError.
|
||||
func NewMetricsGrabber(c clientset.Interface, ec clientset.Interface, config *rest.Config, kubelets bool, scheduler bool, controllers bool, apiServer bool, clusterAutoscaler bool, snapshotController bool) (*Grabber, error) {
|
||||
|
||||
kubeScheduler := ""
|
||||
kubeControllerManager := ""
|
||||
snapshotControllerManager := ""
|
||||
|
||||
regKubeScheduler := regexp.MustCompile("kube-scheduler-.*")
|
||||
regKubeControllerManager := regexp.MustCompile("kube-controller-manager-.*")
|
||||
regSnapshotController := regexp.MustCompile("volume-snapshot-controller.*")
|
||||
|
||||
if (scheduler || controllers) && config == nil {
|
||||
return nil, errors.New("a rest config is required for grabbing kube-controller and kube-controller-manager metrics")
|
||||
}
|
||||
|
||||
podList, err := c.CoreV1().Pods(metav1.NamespaceSystem).List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
@ -89,35 +116,55 @@ func NewMetricsGrabber(c clientset.Interface, ec clientset.Interface, kubelets b
|
||||
if regKubeControllerManager.MatchString(pod.Name) {
|
||||
kubeControllerManager = pod.Name
|
||||
}
|
||||
if kubeScheduler != "" && kubeControllerManager != "" {
|
||||
if regSnapshotController.MatchString(pod.Name) {
|
||||
snapshotControllerManager = pod.Name
|
||||
}
|
||||
if kubeScheduler != "" && kubeControllerManager != "" && snapshotControllerManager != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
if kubeScheduler == "" {
|
||||
scheduler = false
|
||||
klog.Warningf("Can't find kube-scheduler pod. Grabbing metrics from kube-scheduler is disabled.")
|
||||
}
|
||||
if kubeControllerManager == "" {
|
||||
controllers = false
|
||||
klog.Warningf("Can't find kube-controller-manager pod. Grabbing metrics from kube-controller-manager is disabled.")
|
||||
}
|
||||
if ec == nil {
|
||||
if clusterAutoscaler && ec == nil {
|
||||
klog.Warningf("Did not receive an external client interface. Grabbing metrics from ClusterAutoscaler is disabled.")
|
||||
}
|
||||
|
||||
return &Grabber{
|
||||
client: c,
|
||||
externalClient: ec,
|
||||
grabFromAPIServer: apiServer,
|
||||
grabFromControllerManager: controllers,
|
||||
grabFromKubelets: kubelets,
|
||||
grabFromScheduler: scheduler,
|
||||
grabFromClusterAutoscaler: clusterAutoscaler,
|
||||
kubeScheduler: kubeScheduler,
|
||||
kubeControllerManager: kubeControllerManager,
|
||||
client: c,
|
||||
externalClient: ec,
|
||||
config: config,
|
||||
grabFromAPIServer: apiServer,
|
||||
grabFromControllerManager: checkPodDebugHandlers(c, controllers, "kube-controller-manager", kubeControllerManager),
|
||||
grabFromKubelets: kubelets,
|
||||
grabFromScheduler: checkPodDebugHandlers(c, scheduler, "kube-scheduler", kubeScheduler),
|
||||
grabFromClusterAutoscaler: clusterAutoscaler,
|
||||
grabFromSnapshotController: checkPodDebugHandlers(c, snapshotController, "snapshot-controller", snapshotControllerManager),
|
||||
kubeScheduler: kubeScheduler,
|
||||
kubeControllerManager: kubeControllerManager,
|
||||
snapshotController: snapshotControllerManager,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func checkPodDebugHandlers(c clientset.Interface, requested bool, component, podName string) bool {
|
||||
if !requested {
|
||||
return false
|
||||
}
|
||||
if podName == "" {
|
||||
klog.Warningf("Can't find %s pod. Grabbing metrics from %s is disabled.", component, component)
|
||||
return false
|
||||
}
|
||||
|
||||
// The debug handlers on the host where the pod runs might be disabled.
|
||||
// We can check that indirectly by trying to retrieve log output.
|
||||
limit := int64(1)
|
||||
if _, err := c.CoreV1().Pods(metav1.NamespaceSystem).GetLogs(podName, &v1.PodLogOptions{LimitBytes: &limit}).DoRaw(context.TODO()); err != nil {
|
||||
klog.Warningf("Can't retrieve log output of %s (%q). Debug handlers might be disabled in kubelet. Grabbing metrics from %s is disabled.",
|
||||
podName, err, component)
|
||||
return false
|
||||
}
|
||||
|
||||
// Metrics gathering enabled.
|
||||
return true
|
||||
}
|
||||
|
||||
// HasControlPlanePods returns true if metrics grabber was able to find control-plane pods
|
||||
func (g *Grabber) HasControlPlanePods() bool {
|
||||
return g.kubeScheduler != "" && g.kubeControllerManager != ""
|
||||
@ -149,20 +196,38 @@ func (g *Grabber) grabFromKubeletInternal(nodeName string, kubeletPort int) (Kub
|
||||
|
||||
// GrabFromScheduler returns metrics from scheduler
|
||||
func (g *Grabber) GrabFromScheduler() (SchedulerMetrics, error) {
|
||||
if g.kubeScheduler == "" {
|
||||
return SchedulerMetrics{}, fmt.Errorf("kube-scheduler pod is not registered. Skipping Scheduler's metrics gathering")
|
||||
if !g.grabFromScheduler {
|
||||
return SchedulerMetrics{}, fmt.Errorf("kube-scheduler: %w", MetricsGrabbingDisabledError)
|
||||
}
|
||||
output, err := g.getMetricsFromPod(g.client, g.kubeScheduler, metav1.NamespaceSystem, insecureSchedulerPort)
|
||||
|
||||
var err error
|
||||
|
||||
g.waitForSchedulerReadyOnce.Do(func() {
|
||||
if readyErr := e2epod.WaitForPodsReady(g.client, metav1.NamespaceSystem, g.kubeScheduler, 0); readyErr != nil {
|
||||
err = fmt.Errorf("error waiting for kube-scheduler pod to be ready: %w", readyErr)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return SchedulerMetrics{}, err
|
||||
}
|
||||
|
||||
var lastMetricsFetchErr error
|
||||
var output string
|
||||
if metricsWaitErr := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
||||
output, lastMetricsFetchErr = g.getSecureMetricsFromPod(g.kubeScheduler, metav1.NamespaceSystem, kubeSchedulerPort)
|
||||
return lastMetricsFetchErr == nil, nil
|
||||
}); metricsWaitErr != nil {
|
||||
err := fmt.Errorf("error waiting for kube-scheduler pod to expose metrics: %v; %v", metricsWaitErr, lastMetricsFetchErr)
|
||||
return SchedulerMetrics{}, err
|
||||
}
|
||||
|
||||
return parseSchedulerMetrics(output)
|
||||
}
|
||||
|
||||
// GrabFromClusterAutoscaler returns metrics from cluster autoscaler
|
||||
func (g *Grabber) GrabFromClusterAutoscaler() (ClusterAutoscalerMetrics, error) {
|
||||
if !g.HasControlPlanePods() && g.externalClient == nil {
|
||||
return ClusterAutoscalerMetrics{}, fmt.Errorf("Did not find control-plane pods. Skipping ClusterAutoscaler's metrics gathering")
|
||||
return ClusterAutoscalerMetrics{}, fmt.Errorf("ClusterAutoscaler: %w", MetricsGrabbingDisabledError)
|
||||
}
|
||||
var client clientset.Interface
|
||||
var namespace string
|
||||
@ -182,38 +247,73 @@ func (g *Grabber) GrabFromClusterAutoscaler() (ClusterAutoscalerMetrics, error)
|
||||
|
||||
// GrabFromControllerManager returns metrics from controller manager
|
||||
func (g *Grabber) GrabFromControllerManager() (ControllerManagerMetrics, error) {
|
||||
if g.kubeControllerManager == "" {
|
||||
return ControllerManagerMetrics{}, fmt.Errorf("kube-controller-manager pod is not registered. Skipping ControllerManager's metrics gathering")
|
||||
if !g.grabFromControllerManager {
|
||||
return ControllerManagerMetrics{}, fmt.Errorf("kube-controller-manager: %w", MetricsGrabbingDisabledError)
|
||||
}
|
||||
|
||||
var err error
|
||||
podName := g.kubeControllerManager
|
||||
g.waitForControllerManagerReadyOnce.Do(func() {
|
||||
if readyErr := e2epod.WaitForPodsReady(g.client, metav1.NamespaceSystem, podName, 0); readyErr != nil {
|
||||
err = fmt.Errorf("error waiting for controller manager pod to be ready: %w", readyErr)
|
||||
return
|
||||
}
|
||||
|
||||
var lastMetricsFetchErr error
|
||||
if metricsWaitErr := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
||||
_, lastMetricsFetchErr = g.getMetricsFromPod(g.client, podName, metav1.NamespaceSystem, insecureKubeControllerManagerPort)
|
||||
return lastMetricsFetchErr == nil, nil
|
||||
}); metricsWaitErr != nil {
|
||||
err = fmt.Errorf("error waiting for controller manager pod to expose metrics: %v; %v", metricsWaitErr, lastMetricsFetchErr)
|
||||
return
|
||||
g.waitForControllerManagerReadyOnce.Do(func() {
|
||||
if readyErr := e2epod.WaitForPodsReady(g.client, metav1.NamespaceSystem, g.kubeControllerManager, 0); readyErr != nil {
|
||||
err = fmt.Errorf("error waiting for kube-controller-manager pod to be ready: %w", readyErr)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return ControllerManagerMetrics{}, err
|
||||
}
|
||||
|
||||
output, err := g.getMetricsFromPod(g.client, podName, metav1.NamespaceSystem, insecureKubeControllerManagerPort)
|
||||
if err != nil {
|
||||
var output string
|
||||
var lastMetricsFetchErr error
|
||||
if metricsWaitErr := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
||||
output, lastMetricsFetchErr = g.getSecureMetricsFromPod(g.kubeControllerManager, metav1.NamespaceSystem, kubeControllerManagerPort)
|
||||
return lastMetricsFetchErr == nil, nil
|
||||
}); metricsWaitErr != nil {
|
||||
err := fmt.Errorf("error waiting for kube-controller-manager to expose metrics: %v; %v", metricsWaitErr, lastMetricsFetchErr)
|
||||
return ControllerManagerMetrics{}, err
|
||||
}
|
||||
|
||||
return parseControllerManagerMetrics(output)
|
||||
}
|
||||
|
||||
// GrabFromSnapshotController returns metrics from controller manager
|
||||
func (g *Grabber) GrabFromSnapshotController(podName string, port int) (SnapshotControllerMetrics, error) {
|
||||
if !g.grabFromSnapshotController {
|
||||
return SnapshotControllerMetrics{}, fmt.Errorf("volume-snapshot-controller: %w", MetricsGrabbingDisabledError)
|
||||
}
|
||||
|
||||
// Use overrides if provided via test config flags.
|
||||
// Otherwise, use the default volume-snapshot-controller pod name and port.
|
||||
if podName == "" {
|
||||
podName = g.snapshotController
|
||||
}
|
||||
if port == 0 {
|
||||
port = snapshotControllerPort
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
g.waitForSnapshotControllerReadyOnce.Do(func() {
|
||||
if readyErr := e2epod.WaitForPodsReady(g.client, metav1.NamespaceSystem, podName, 0); readyErr != nil {
|
||||
err = fmt.Errorf("error waiting for volume-snapshot-controller pod to be ready: %w", readyErr)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return SnapshotControllerMetrics{}, err
|
||||
}
|
||||
|
||||
var output string
|
||||
var lastMetricsFetchErr error
|
||||
if metricsWaitErr := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
||||
output, lastMetricsFetchErr = g.getMetricsFromPod(g.client, podName, metav1.NamespaceSystem, port)
|
||||
return lastMetricsFetchErr == nil, nil
|
||||
}); metricsWaitErr != nil {
|
||||
err = fmt.Errorf("error waiting for volume-snapshot-controller pod to expose metrics: %v; %v", metricsWaitErr, lastMetricsFetchErr)
|
||||
return SnapshotControllerMetrics{}, err
|
||||
}
|
||||
|
||||
return parseSnapshotControllerMetrics(output)
|
||||
}
|
||||
|
||||
// GrabFromAPIServer returns metrics from API server
|
||||
func (g *Grabber) GrabFromAPIServer() (APIServerMetrics, error) {
|
||||
output, err := g.getMetricsFromAPIServer()
|
||||
@ -251,6 +351,14 @@ func (g *Grabber) Grab() (Collection, error) {
|
||||
result.ControllerManagerMetrics = metrics
|
||||
}
|
||||
}
|
||||
if g.grabFromSnapshotController {
|
||||
metrics, err := g.GrabFromSnapshotController(g.snapshotController, snapshotControllerPort)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
} else {
|
||||
result.SnapshotControllerMetrics = metrics
|
||||
}
|
||||
}
|
||||
if g.grabFromClusterAutoscaler {
|
||||
metrics, err := g.GrabFromClusterAutoscaler()
|
||||
if err != nil {
|
||||
@ -281,12 +389,13 @@ func (g *Grabber) Grab() (Collection, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getMetricsFromPod retrieves metrics data from an insecure port.
|
||||
func (g *Grabber) getMetricsFromPod(client clientset.Interface, podName string, namespace string, port int) (string, error) {
|
||||
rawOutput, err := client.CoreV1().RESTClient().Get().
|
||||
Namespace(namespace).
|
||||
Resource("pods").
|
||||
SubResource("proxy").
|
||||
Name(fmt.Sprintf("%v:%v", podName, port)).
|
||||
Name(fmt.Sprintf("%s:%d", podName, port)).
|
||||
Suffix("metrics").
|
||||
Do(context.TODO()).Raw()
|
||||
if err != nil {
|
||||
@ -294,3 +403,50 @@ func (g *Grabber) getMetricsFromPod(client clientset.Interface, podName string,
|
||||
}
|
||||
return string(rawOutput), nil
|
||||
}
|
||||
|
||||
// getSecureMetricsFromPod retrieves metrics from a pod that uses TLS
|
||||
// and checks client credentials. Conceptually this function is
|
||||
// similar to "kubectl port-forward" + "kubectl get --raw
|
||||
// https://localhost:<port>/metrics". It uses the same credentials
|
||||
// as kubelet.
|
||||
func (g *Grabber) getSecureMetricsFromPod(podName string, namespace string, port int) (string, error) {
|
||||
dialer := e2epod.NewDialer(g.client, g.config)
|
||||
metricConfig := rest.CopyConfig(g.config)
|
||||
addr := e2epod.Addr{
|
||||
Namespace: namespace,
|
||||
PodName: podName,
|
||||
Port: port,
|
||||
}
|
||||
metricConfig.Dial = func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
return dialer.DialContainerPort(ctx, addr)
|
||||
}
|
||||
// This should make it possible verify the server, but while it
|
||||
// got past the server name check, certificate validation
|
||||
// still failed.
|
||||
metricConfig.Host = addr.String()
|
||||
metricConfig.ServerName = "localhost"
|
||||
// Verifying the pod certificate with the same root CA
|
||||
// as for the API server led to an error about "unknown root
|
||||
// certificate". Disabling certificate checking on the client
|
||||
// side gets around that and should be good enough for
|
||||
// E2E testing.
|
||||
metricConfig.Insecure = true
|
||||
metricConfig.CAFile = ""
|
||||
metricConfig.CAData = nil
|
||||
|
||||
// clientset.NewForConfig is used because
|
||||
// metricClient.RESTClient() is directly usable, in contrast
|
||||
// to the client constructed by rest.RESTClientFor().
|
||||
metricClient, err := clientset.NewForConfig(metricConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
rawOutput, err := metricClient.RESTClient().Get().
|
||||
AbsPath("metrics").
|
||||
Do(context.TODO()).Raw()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(rawOutput), nil
|
||||
}
|
||||
|
40
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/snapshot_controller_metrics.go
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/test/e2e/framework/metrics/snapshot_controller_metrics.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2021 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 metrics
|
||||
|
||||
import "k8s.io/component-base/metrics/testutil"
|
||||
|
||||
// SnapshotControllerMetrics is metrics for controller manager
|
||||
type SnapshotControllerMetrics testutil.Metrics
|
||||
|
||||
// Equal returns true if all metrics are the same as the arguments.
|
||||
func (m *SnapshotControllerMetrics) Equal(o SnapshotControllerMetrics) bool {
|
||||
return (*testutil.Metrics)(m).Equal(testutil.Metrics(o))
|
||||
}
|
||||
|
||||
func newSnapshotControllerMetrics() SnapshotControllerMetrics {
|
||||
result := testutil.NewMetrics()
|
||||
return SnapshotControllerMetrics(result)
|
||||
}
|
||||
|
||||
func parseSnapshotControllerMetrics(data string) (SnapshotControllerMetrics, error) {
|
||||
result := newSnapshotControllerMetrics()
|
||||
if err := testutil.ParseMetrics(data, (*testutil.Metrics)(&result)); err != nil {
|
||||
return SnapshotControllerMetrics{}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
25
vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go
generated
vendored
25
vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go
generated
vendored
@ -561,6 +561,31 @@ func GetClusterZones(c clientset.Interface) (sets.String, error) {
|
||||
return zones, nil
|
||||
}
|
||||
|
||||
// GetSchedulableClusterZones returns the values of zone label collected from all nodes which are schedulable.
|
||||
func GetSchedulableClusterZones(c clientset.Interface) (sets.String, error) {
|
||||
nodes, err := c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting nodes while attempting to list cluster zones: %v", err)
|
||||
}
|
||||
|
||||
// collect values of zone label from all nodes
|
||||
zones := sets.NewString()
|
||||
for _, node := range nodes.Items {
|
||||
// We should have at least 1 node in the zone which is schedulable.
|
||||
if !IsNodeSchedulable(&node) {
|
||||
continue
|
||||
}
|
||||
if zone, found := node.Labels[v1.LabelFailureDomainBetaZone]; found {
|
||||
zones.Insert(zone)
|
||||
}
|
||||
|
||||
if zone, found := node.Labels[v1.LabelTopologyZone]; found {
|
||||
zones.Insert(zone)
|
||||
}
|
||||
}
|
||||
return zones, nil
|
||||
}
|
||||
|
||||
// CreatePodsPerNodeForSimpleApp creates pods w/ labels. Useful for tests which make a bunch of pods w/o any networking.
|
||||
func CreatePodsPerNodeForSimpleApp(c clientset.Interface, namespace, appName string, podSpec func(n v1.Node) v1.PodSpec, maxCount int) map[string]string {
|
||||
nodes, err := GetBoundedReadySchedulableNodes(c, maxCount)
|
||||
|
6
vendor/k8s.io/kubernetes/test/e2e/framework/node/wait.go
generated
vendored
6
vendor/k8s.io/kubernetes/test/e2e/framework/node/wait.go
generated
vendored
@ -214,8 +214,12 @@ func CheckReadyForTests(c clientset.Interface, nonblockingTaints string, allowed
|
||||
}
|
||||
allNodes, err := c.CoreV1().Nodes().List(context.TODO(), opts)
|
||||
if err != nil {
|
||||
var terminalListNodesErr error
|
||||
e2elog.Logf("Unexpected error listing nodes: %v", err)
|
||||
return false, err
|
||||
if attempt >= 3 {
|
||||
terminalListNodesErr = err
|
||||
}
|
||||
return false, terminalListNodesErr
|
||||
}
|
||||
for _, node := range allNodes.Items {
|
||||
if !readyForTests(&node, nonblockingTaints) {
|
||||
|
2
vendor/k8s.io/kubernetes/test/e2e/framework/nodes_util.go
generated
vendored
2
vendor/k8s.io/kubernetes/test/e2e/framework/nodes_util.go
generated
vendored
@ -34,7 +34,7 @@ import (
|
||||
e2essh "k8s.io/kubernetes/test/e2e/framework/ssh"
|
||||
)
|
||||
|
||||
const etcdImage = "3.4.13-0"
|
||||
const etcdImage = "3.5.0-0"
|
||||
|
||||
// EtcdUpgrade upgrades etcd on GCE.
|
||||
func EtcdUpgrade(targetStorage, targetVersion string) error {
|
||||
|
43
vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go
generated
vendored
43
vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go
generated
vendored
@ -19,7 +19,6 @@ package pod
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@ -154,15 +153,7 @@ func MakePod(ns string, nodeSelector map[string]string, pvclaims []*v1.Persisten
|
||||
RestartPolicy: v1.RestartPolicyOnFailure,
|
||||
},
|
||||
}
|
||||
var volumeMounts = make([]v1.VolumeMount, len(pvclaims))
|
||||
var volumes = make([]v1.Volume, len(pvclaims))
|
||||
for index, pvclaim := range pvclaims {
|
||||
volumename := fmt.Sprintf("volume%v", index+1)
|
||||
volumeMounts[index] = v1.VolumeMount{Name: volumename, MountPath: "/mnt/" + volumename}
|
||||
volumes[index] = v1.Volume{Name: volumename, VolumeSource: v1.VolumeSource{PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ClaimName: pvclaim.Name, ReadOnly: false}}}
|
||||
}
|
||||
podSpec.Spec.Containers[0].VolumeMounts = volumeMounts
|
||||
podSpec.Spec.Volumes = volumes
|
||||
setVolumes(&podSpec.Spec, pvclaims, nil /*inline volume sources*/, false /*PVCs readonly*/)
|
||||
if nodeSelector != nil {
|
||||
podSpec.Spec.NodeSelector = nodeSelector
|
||||
}
|
||||
@ -175,11 +166,12 @@ func MakeSecPod(podConfig *Config) (*v1.Pod, error) {
|
||||
if podConfig.NS == "" {
|
||||
return nil, fmt.Errorf("Cannot create pod with empty namespace")
|
||||
}
|
||||
if len(podConfig.Command) == 0 {
|
||||
if len(podConfig.Command) == 0 && !NodeOSDistroIs("windows") {
|
||||
podConfig.Command = "trap exit TERM; while true; do sleep 1; done"
|
||||
}
|
||||
|
||||
podName := "pod-" + string(uuid.NewUUID())
|
||||
if podConfig.FsGroup == nil && runtime.GOOS != "windows" {
|
||||
if podConfig.FsGroup == nil && !NodeOSDistroIs("windows") {
|
||||
podConfig.FsGroup = func(i int64) *int64 {
|
||||
return &i
|
||||
}(1000)
|
||||
@ -223,33 +215,42 @@ func MakePodSpec(podConfig *Config) *v1.PodSpec {
|
||||
podSpec.SecurityContext.FSGroupChangePolicy = podConfig.PodFSGroupChangePolicy
|
||||
}
|
||||
|
||||
setVolumes(podSpec, podConfig.PVCs, podConfig.InlineVolumeSources, podConfig.PVCsReadOnly)
|
||||
SetNodeSelection(podSpec, podConfig.NodeSelection)
|
||||
return podSpec
|
||||
}
|
||||
|
||||
func setVolumes(podSpec *v1.PodSpec, pvcs []*v1.PersistentVolumeClaim, inlineVolumeSources []*v1.VolumeSource, pvcsReadOnly bool) {
|
||||
var volumeMounts = make([]v1.VolumeMount, 0)
|
||||
var volumeDevices = make([]v1.VolumeDevice, 0)
|
||||
var volumes = make([]v1.Volume, len(podConfig.PVCs)+len(podConfig.InlineVolumeSources))
|
||||
var volumes = make([]v1.Volume, len(pvcs)+len(inlineVolumeSources))
|
||||
volumeIndex := 0
|
||||
for _, pvclaim := range podConfig.PVCs {
|
||||
for _, pvclaim := range pvcs {
|
||||
volumename := fmt.Sprintf("volume%v", volumeIndex+1)
|
||||
if pvclaim.Spec.VolumeMode != nil && *pvclaim.Spec.VolumeMode == v1.PersistentVolumeBlock {
|
||||
volumeDevices = append(volumeDevices, v1.VolumeDevice{Name: volumename, DevicePath: "/mnt/" + volumename})
|
||||
} else {
|
||||
volumeMounts = append(volumeMounts, v1.VolumeMount{Name: volumename, MountPath: "/mnt/" + volumename})
|
||||
}
|
||||
|
||||
volumes[volumeIndex] = v1.Volume{Name: volumename, VolumeSource: v1.VolumeSource{PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ClaimName: pvclaim.Name, ReadOnly: podConfig.PVCsReadOnly}}}
|
||||
volumes[volumeIndex] = v1.Volume{
|
||||
Name: volumename,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: pvclaim.Name,
|
||||
ReadOnly: pvcsReadOnly,
|
||||
},
|
||||
},
|
||||
}
|
||||
volumeIndex++
|
||||
}
|
||||
for _, src := range podConfig.InlineVolumeSources {
|
||||
for _, src := range inlineVolumeSources {
|
||||
volumename := fmt.Sprintf("volume%v", volumeIndex+1)
|
||||
// In-line volumes can be only filesystem, not block.
|
||||
volumeMounts = append(volumeMounts, v1.VolumeMount{Name: volumename, MountPath: "/mnt/" + volumename})
|
||||
volumes[volumeIndex] = v1.Volume{Name: volumename, VolumeSource: *src}
|
||||
volumeIndex++
|
||||
}
|
||||
|
||||
podSpec.Containers[0].VolumeMounts = volumeMounts
|
||||
podSpec.Containers[0].VolumeDevices = volumeDevices
|
||||
podSpec.Volumes = volumes
|
||||
|
||||
SetNodeSelection(podSpec, podConfig.NodeSelection)
|
||||
return podSpec
|
||||
}
|
||||
|
215
vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go
generated
vendored
Normal file
215
vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go
generated
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package pod
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/httpstream"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/portforward"
|
||||
"k8s.io/client-go/transport/spdy"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// NewTransport creates a transport which uses the port forward dialer.
|
||||
// URLs must use <namespace>.<pod>:<port> as host.
|
||||
func NewTransport(client kubernetes.Interface, restConfig *rest.Config) *http.Transport {
|
||||
return &http.Transport{
|
||||
DialContext: func(ctx context.Context, _, addr string) (net.Conn, error) {
|
||||
dialer := NewDialer(client, restConfig)
|
||||
a, err := ParseAddr(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dialer.DialContainerPort(ctx, *a)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewDialer creates a dialer that supports connecting to container ports.
|
||||
func NewDialer(client kubernetes.Interface, restConfig *rest.Config) *Dialer {
|
||||
return &Dialer{
|
||||
client: client,
|
||||
restConfig: restConfig,
|
||||
}
|
||||
}
|
||||
|
||||
// Dialer holds the relevant parameters that are independent of a particular connection.
|
||||
type Dialer struct {
|
||||
client kubernetes.Interface
|
||||
restConfig *rest.Config
|
||||
}
|
||||
|
||||
// DialContainerPort connects to a certain container port in a pod.
|
||||
func (d *Dialer) DialContainerPort(ctx context.Context, addr Addr) (conn net.Conn, finalErr error) {
|
||||
restClient := d.client.CoreV1().RESTClient()
|
||||
restConfig := d.restConfig
|
||||
if restConfig.GroupVersion == nil {
|
||||
restConfig.GroupVersion = &schema.GroupVersion{}
|
||||
}
|
||||
if restConfig.NegotiatedSerializer == nil {
|
||||
restConfig.NegotiatedSerializer = scheme.Codecs
|
||||
}
|
||||
|
||||
// The setup code around the actual portforward is from
|
||||
// https://github.com/kubernetes/kubernetes/blob/c652ffbe4a29143623a1aaec39f745575f7e43ad/staging/src/k8s.io/kubectl/pkg/cmd/portforward/portforward.go
|
||||
req := restClient.Post().
|
||||
Resource("pods").
|
||||
Namespace(addr.Namespace).
|
||||
Name(addr.PodName).
|
||||
SubResource("portforward")
|
||||
transport, upgrader, err := spdy.RoundTripperFor(restConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create round tripper: %v", err)
|
||||
}
|
||||
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", req.URL())
|
||||
|
||||
streamConn, _, err := dialer.Dial(portforward.PortForwardProtocolV1Name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("dialer failed: %v", err)
|
||||
}
|
||||
requestID := "1"
|
||||
defer func() {
|
||||
if finalErr != nil {
|
||||
streamConn.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
// create error stream
|
||||
headers := http.Header{}
|
||||
headers.Set(v1.StreamType, v1.StreamTypeError)
|
||||
headers.Set(v1.PortHeader, fmt.Sprintf("%d", addr.Port))
|
||||
headers.Set(v1.PortForwardRequestIDHeader, requestID)
|
||||
|
||||
// We're not writing to this stream, just reading an error message from it.
|
||||
// This happens asynchronously.
|
||||
errorStream, err := streamConn.CreateStream(headers)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating error stream: %v", err)
|
||||
}
|
||||
errorStream.Close()
|
||||
go func() {
|
||||
message, err := ioutil.ReadAll(errorStream)
|
||||
switch {
|
||||
case err != nil:
|
||||
klog.ErrorS(err, "error reading from error stream")
|
||||
case len(message) > 0:
|
||||
klog.ErrorS(errors.New(string(message)), "an error occurred connecting to the remote port")
|
||||
}
|
||||
}()
|
||||
|
||||
// create data stream
|
||||
headers.Set(v1.StreamType, v1.StreamTypeData)
|
||||
dataStream, err := streamConn.CreateStream(headers)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating data stream: %v", err)
|
||||
}
|
||||
|
||||
return &stream{
|
||||
Stream: dataStream,
|
||||
streamConn: streamConn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Addr contains all relevant parameters for a certain port in a pod.
|
||||
// The container should be running before connections are attempted,
|
||||
// otherwise the connection will fail.
|
||||
type Addr struct {
|
||||
Namespace, PodName string
|
||||
Port int
|
||||
}
|
||||
|
||||
var _ net.Addr = Addr{}
|
||||
|
||||
func (a Addr) Network() string {
|
||||
return "port-forwarding"
|
||||
}
|
||||
|
||||
func (a Addr) String() string {
|
||||
return fmt.Sprintf("%s.%s:%d", a.Namespace, a.PodName, a.Port)
|
||||
}
|
||||
|
||||
// ParseAddr expects a <namespace>.<pod>:<port number> as produced
|
||||
// by Addr.String.
|
||||
func ParseAddr(addr string) (*Addr, error) {
|
||||
parts := addrRegex.FindStringSubmatch(addr)
|
||||
if parts == nil {
|
||||
return nil, fmt.Errorf("%q: must match the format <namespace>.<pod>:<port number>", addr)
|
||||
}
|
||||
port, _ := strconv.Atoi(parts[3])
|
||||
return &Addr{
|
||||
Namespace: parts[1],
|
||||
PodName: parts[2],
|
||||
Port: port,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var addrRegex = regexp.MustCompile(`^([^\.]+)\.([^:]+):(\d+)$`)
|
||||
|
||||
type stream struct {
|
||||
addr Addr
|
||||
httpstream.Stream
|
||||
streamConn httpstream.Connection
|
||||
}
|
||||
|
||||
var _ net.Conn = &stream{}
|
||||
|
||||
func (s *stream) Close() error {
|
||||
s.Stream.Close()
|
||||
s.streamConn.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stream) LocalAddr() net.Addr {
|
||||
return LocalAddr{}
|
||||
}
|
||||
|
||||
func (s *stream) RemoteAddr() net.Addr {
|
||||
return s.addr
|
||||
}
|
||||
|
||||
func (s *stream) SetDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stream) SetReadDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stream) SetWriteDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type LocalAddr struct{}
|
||||
|
||||
var _ net.Addr = LocalAddr{}
|
||||
|
||||
func (l LocalAddr) Network() string { return "port-forwarding" }
|
||||
func (l LocalAddr) String() string { return "apiserver" }
|
2
vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go
generated
vendored
2
vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go
generated
vendored
@ -25,7 +25,6 @@ import (
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/gomega"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@ -34,6 +33,7 @@ import (
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubectl/pkg/util/podutils"
|
||||
|
||||
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
||||
testutils "k8s.io/kubernetes/test/utils"
|
||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go
generated
vendored
@ -37,14 +37,9 @@ func NodeOSDistroIs(distro string) bool {
|
||||
}
|
||||
|
||||
// GenerateScriptCmd generates the corresponding command lines to execute a command.
|
||||
// Depending on the Node OS is Windows or linux, the command will use powershell or /bin/sh
|
||||
func GenerateScriptCmd(command string) []string {
|
||||
var commands []string
|
||||
if !NodeOSDistroIs("windows") {
|
||||
commands = []string{"/bin/sh", "-c", command}
|
||||
} else {
|
||||
commands = []string{"powershell", "/c", command}
|
||||
}
|
||||
commands = []string{"/bin/sh", "-c", command}
|
||||
return commands
|
||||
}
|
||||
|
||||
|
15
vendor/k8s.io/kubernetes/test/e2e/framework/pod/wait.go
generated
vendored
15
vendor/k8s.io/kubernetes/test/e2e/framework/pod/wait.go
generated
vendored
@ -435,6 +435,21 @@ func PodsResponding(c clientset.Interface, ns, name string, wantName bool, pods
|
||||
return wait.PollImmediate(poll, podRespondingTimeout, NewProxyResponseChecker(c, ns, label, name, wantName, pods).CheckAllResponses)
|
||||
}
|
||||
|
||||
// WaitForNumberOfPods waits up to timeout to ensure there are exact
|
||||
// `num` pods in namespace `ns`.
|
||||
// It returns the matching Pods or a timeout error.
|
||||
func WaitForNumberOfPods(c clientset.Interface, ns string, num int, timeout time.Duration) (pods *v1.PodList, err error) {
|
||||
err = wait.PollImmediate(poll, timeout, func() (bool, error) {
|
||||
pods, err = c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{})
|
||||
// ignore intermittent network error
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
return len(pods.Items) == num, nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// WaitForPodsWithLabelScheduled waits for all matching pods to become scheduled and at least one
|
||||
// matching pod exists. Return the list of matching pods.
|
||||
func WaitForPodsWithLabelScheduled(c clientset.Interface, ns string, label labels.Selector) (pods *v1.PodList, err error) {
|
||||
|
2
vendor/k8s.io/kubernetes/test/e2e/framework/pods.go
generated
vendored
2
vendor/k8s.io/kubernetes/test/e2e/framework/pods.go
generated
vendored
@ -181,7 +181,7 @@ func (c *PodClient) mungeSpec(pod *v1.Pod) {
|
||||
c := &pod.Spec.Containers[i]
|
||||
if c.ImagePullPolicy == v1.PullAlways {
|
||||
// If the image pull policy is PullAlways, the image doesn't need to be in
|
||||
// the white list or pre-pulled, because the image is expected to be pulled
|
||||
// the allow list or pre-pulled, because the image is expected to be pulled
|
||||
// in the test anyway.
|
||||
continue
|
||||
}
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/framework/ports.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/framework/ports.go
generated
vendored
@ -22,10 +22,6 @@ const (
|
||||
// KubeletPort is the default port for the kubelet server on each host machine.
|
||||
// May be overridden by a flag at startup.
|
||||
KubeletPort = 10250
|
||||
// InsecureKubeControllerManagerPort is the default port for the controller manager status server.
|
||||
// May be overridden by a flag at startup.
|
||||
// Deprecated: use the secure KubeControllerManagerPort instead.
|
||||
InsecureKubeControllerManagerPort = 10252
|
||||
// KubeControllerManagerPort is the default port for the controller manager status server.
|
||||
// May be overridden by a flag at startup.
|
||||
KubeControllerManagerPort = 10257
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/framework/provider.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/framework/provider.go
generated
vendored
@ -21,8 +21,6 @@ import (
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
)
|
||||
@ -78,7 +76,7 @@ func SetupProviderConfig(providerName string) (ProviderInterface, error) {
|
||||
defer mutex.Unlock()
|
||||
factory, ok := providers[providerName]
|
||||
if !ok {
|
||||
return nil, errors.Wrapf(os.ErrNotExist, "The provider %s is unknown.", providerName)
|
||||
return nil, fmt.Errorf("The provider %s is unknown: %w", providerName, os.ErrNotExist)
|
||||
}
|
||||
provider, err := factory()
|
||||
|
||||
|
8
vendor/k8s.io/kubernetes/test/e2e/framework/psp.go
generated
vendored
8
vendor/k8s.io/kubernetes/test/e2e/framework/psp.go
generated
vendored
@ -177,7 +177,13 @@ func CreatePrivilegedPSPBinding(kubeClient clientset.Interface, namespace string
|
||||
Kind: rbacv1.ServiceAccountKind,
|
||||
Namespace: namespace,
|
||||
Name: "default",
|
||||
})
|
||||
},
|
||||
rbacv1.Subject{
|
||||
Kind: rbacv1.GroupKind,
|
||||
APIGroup: rbacv1.GroupName,
|
||||
Name: "system:serviceaccounts:" + namespace,
|
||||
},
|
||||
)
|
||||
ExpectNoError(err)
|
||||
ExpectNoError(e2eauth.WaitForNamedAuthorizationUpdate(kubeClient.AuthorizationV1(),
|
||||
serviceaccount.MakeUsername(namespace, "default"), namespace, "use", podSecurityPolicyPrivileged,
|
||||
|
7
vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go
generated
vendored
7
vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go
generated
vendored
@ -49,6 +49,7 @@ var localStorageCapacityIsolation featuregate.Feature = "LocalStorageCapacityIso
|
||||
var (
|
||||
downwardAPIHugePages featuregate.Feature = "DownwardAPIHugePages"
|
||||
execProbeTimeout featuregate.Feature = "ExecProbeTimeout"
|
||||
csiMigration featuregate.Feature = "CSIMigration"
|
||||
)
|
||||
|
||||
func skipInternalf(caller int, format string, args ...interface{}) {
|
||||
@ -154,6 +155,12 @@ func SkipUnlessExecProbeTimeoutEnabled() {
|
||||
}
|
||||
}
|
||||
|
||||
func SkipIfCSIMigrationEnabled() {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(csiMigration) {
|
||||
skipInternalf(1, "Only supported when %v feature is disabled", csiMigration)
|
||||
}
|
||||
}
|
||||
|
||||
// SkipIfMissingResource skips if the gvr resource is missing.
|
||||
func SkipIfMissingResource(dynamicClient dynamic.Interface, gvr schema.GroupVersionResource, namespace string) {
|
||||
resourceClient := dynamicClient.Resource(gvr).Namespace(namespace)
|
||||
|
44
vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go
generated
vendored
44
vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/gomega"
|
||||
@ -48,6 +49,9 @@ const (
|
||||
// singleCallTimeout is how long to try single API calls (like 'get' or 'list'). Used to prevent
|
||||
// transient failures from failing tests.
|
||||
singleCallTimeout = 5 * time.Minute
|
||||
|
||||
// sshBastionEnvKey is the environment variable key for running SSH commands via bastion.
|
||||
sshBastionEnvKey = "KUBE_SSH_BASTION"
|
||||
)
|
||||
|
||||
// GetSigner returns an ssh.Signer for the provider ("gce", etc.) that can be
|
||||
@ -133,13 +137,45 @@ func NodeSSHHosts(c clientset.Interface) ([]string, error) {
|
||||
len(hosts), len(nodelist.Items), nodelist)
|
||||
}
|
||||
|
||||
sshHosts := make([]string, 0, len(hosts))
|
||||
for _, h := range hosts {
|
||||
sshHosts = append(sshHosts, net.JoinHostPort(h, SSHPort))
|
||||
lenHosts := len(hosts)
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(lenHosts)
|
||||
sshHosts := make([]string, 0, lenHosts)
|
||||
var sshHostsLock sync.Mutex
|
||||
|
||||
for _, host := range hosts {
|
||||
go func(host string) {
|
||||
defer wg.Done()
|
||||
if canConnect(host) {
|
||||
e2elog.Logf("Assuming SSH on host %s", host)
|
||||
sshHostsLock.Lock()
|
||||
sshHosts = append(sshHosts, net.JoinHostPort(host, SSHPort))
|
||||
sshHostsLock.Unlock()
|
||||
} else {
|
||||
e2elog.Logf("Skipping host %s because it does not run anything on port %s", host, SSHPort)
|
||||
}
|
||||
}(host)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
return sshHosts, nil
|
||||
}
|
||||
|
||||
// canConnect returns true if a network connection is possible to the SSHPort.
|
||||
func canConnect(host string) bool {
|
||||
if _, ok := os.LookupEnv(sshBastionEnvKey); ok {
|
||||
return true
|
||||
}
|
||||
hostPort := net.JoinHostPort(host, SSHPort)
|
||||
conn, err := net.DialTimeout("tcp", hostPort, 3*time.Second)
|
||||
if err != nil {
|
||||
e2elog.Logf("cannot dial %s: %v", hostPort, err)
|
||||
return false
|
||||
}
|
||||
conn.Close()
|
||||
return true
|
||||
}
|
||||
|
||||
// Result holds the execution result of SSH command
|
||||
type Result struct {
|
||||
User string
|
||||
@ -176,7 +212,7 @@ func SSH(cmd, host, provider string) (Result, error) {
|
||||
result.User = os.Getenv("USER")
|
||||
}
|
||||
|
||||
if bastion := os.Getenv("KUBE_SSH_BASTION"); len(bastion) > 0 {
|
||||
if bastion := os.Getenv(sshBastionEnvKey); len(bastion) > 0 {
|
||||
stdout, stderr, code, err := runSSHCommandViaBastion(cmd, result.User, bastion, host, signer)
|
||||
result.Stdout = stdout
|
||||
result.Stderr = stderr
|
||||
|
15
vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go
generated
vendored
15
vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go
generated
vendored
@ -19,6 +19,7 @@ package framework
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -29,7 +30,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/config"
|
||||
"github.com/pkg/errors"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
@ -182,6 +182,12 @@ type TestContextType struct {
|
||||
|
||||
// DockerConfigFile is a file that contains credentials which can be used to pull images from certain private registries, needed for a test.
|
||||
DockerConfigFile string
|
||||
|
||||
// SnapshotControllerPodName is the name used for identifying the snapshot controller pod.
|
||||
SnapshotControllerPodName string
|
||||
|
||||
// SnapshotControllerHTTPPort the port used for communicating with the snapshot controller HTTP endpoint.
|
||||
SnapshotControllerHTTPPort int
|
||||
}
|
||||
|
||||
// NodeKillerConfig describes configuration of NodeKiller -- a utility to
|
||||
@ -223,6 +229,8 @@ type NodeTestContextType struct {
|
||||
// the node e2e test. If empty, the default one (system.DefaultSpec) is
|
||||
// used. The system specs are in test/e2e_node/system/specs/.
|
||||
SystemSpecName string
|
||||
// RestartKubelet restarts Kubelet unit when the process is killed.
|
||||
RestartKubelet bool
|
||||
// ExtraEnvs is a map of environment names to values.
|
||||
ExtraEnvs map[string]string
|
||||
}
|
||||
@ -315,6 +323,9 @@ func RegisterCommonFlags(flags *flag.FlagSet) {
|
||||
flags.StringVar(&TestContext.ProgressReportURL, "progress-report-url", "", "The URL to POST progress updates to as the suite runs to assist in aiding integrations. If empty, no messages sent.")
|
||||
flags.StringVar(&TestContext.SpecSummaryOutput, "spec-dump", "", "The file to dump all ginkgo.SpecSummary to after tests run. If empty, no objects are saved/printed.")
|
||||
flags.StringVar(&TestContext.DockerConfigFile, "docker-config-file", "", "A file that contains credentials which can be used to pull images from certain private registries, needed for a test.")
|
||||
|
||||
flags.StringVar(&TestContext.SnapshotControllerPodName, "snapshot-controller-pod-name", "", "The pod name to use for identifying the snapshot controller in the kube-system namespace.")
|
||||
flags.IntVar(&TestContext.SnapshotControllerHTTPPort, "snapshot-controller-http-port", 0, "The port to use for snapshot controller HTTP communication.")
|
||||
}
|
||||
|
||||
// RegisterClusterFlags registers flags specific to the cluster e2e test suite.
|
||||
@ -473,7 +484,7 @@ func AfterReadingAllFlags(t *TestContextType) {
|
||||
var err error
|
||||
TestContext.CloudConfig.Provider, err = SetupProviderConfig(TestContext.Provider)
|
||||
if err != nil {
|
||||
if os.IsNotExist(errors.Cause(err)) {
|
||||
if os.IsNotExist(errors.Unwrap(err)) {
|
||||
// Provide a more helpful error message when the provider is unknown.
|
||||
var providers []string
|
||||
for _, name := range GetProviders() {
|
||||
|
1
vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/testdata/a/foo.txt
generated
vendored
Normal file
1
vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/testdata/a/foo.txt
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
Hello World
|
56
vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/testfiles.go
generated
vendored
56
vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/testfiles.go
generated
vendored
@ -25,13 +25,14 @@ limitations under the License.
|
||||
package testfiles
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -147,32 +148,47 @@ func (r RootFileSource) DescribeFiles() string {
|
||||
return description
|
||||
}
|
||||
|
||||
// BindataFileSource handles files stored in a package generated with bindata.
|
||||
type BindataFileSource struct {
|
||||
Asset func(string) ([]byte, error)
|
||||
AssetNames func() []string
|
||||
// EmbeddedFileSource handles files stored in a package generated with bindata.
|
||||
type EmbeddedFileSource struct {
|
||||
EmbeddedFS embed.FS
|
||||
Root string
|
||||
fileList []string
|
||||
}
|
||||
|
||||
// ReadTestFile looks for an asset with the given path.
|
||||
func (b BindataFileSource) ReadTestFile(filePath string) ([]byte, error) {
|
||||
fileBytes, err := b.Asset(filePath)
|
||||
// ReadTestFile looks for an embedded file with the given path.
|
||||
func (e EmbeddedFileSource) ReadTestFile(filepath string) ([]byte, error) {
|
||||
relativePath := strings.TrimPrefix(filepath, fmt.Sprintf("%s/", e.Root))
|
||||
|
||||
b, err := e.EmbeddedFS.ReadFile(relativePath)
|
||||
if err != nil {
|
||||
// It would be nice to have a better way to detect
|
||||
// "not found" errors :-/
|
||||
if strings.HasSuffix(err.Error(), "not found") {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return fileBytes, nil
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// DescribeFiles explains about gobindata and then lists all available files.
|
||||
func (b BindataFileSource) DescribeFiles() string {
|
||||
// DescribeFiles explains that it is looking inside an embedded filesystem
|
||||
func (e EmbeddedFileSource) DescribeFiles() string {
|
||||
var lines []string
|
||||
lines = append(lines, "The following files are built into the test executable via gobindata. For questions on maintaining gobindata, contact the sig-testing group.")
|
||||
assets := b.AssetNames()
|
||||
sort.Strings(assets)
|
||||
lines = append(lines, assets...)
|
||||
description := strings.Join(lines, "\n ")
|
||||
return description
|
||||
lines = append(lines, "The following files are embedded into the test executable:")
|
||||
|
||||
if len(e.fileList) == 0 {
|
||||
e.populateFileList()
|
||||
}
|
||||
lines = append(lines, e.fileList...)
|
||||
|
||||
return strings.Join(lines, "\n\t")
|
||||
}
|
||||
|
||||
func (e *EmbeddedFileSource) populateFileList() {
|
||||
fs.WalkDir(e.EmbeddedFS, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if !d.IsDir() {
|
||||
e.fileList = append(e.fileList, filepath.Join(e.Root, path))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
57
vendor/k8s.io/kubernetes/test/e2e/framework/timeouts.go
generated
vendored
57
vendor/k8s.io/kubernetes/test/e2e/framework/timeouts.go
generated
vendored
@ -20,19 +20,20 @@ import "time"
|
||||
|
||||
const (
|
||||
// Default timeouts to be used in TimeoutContext
|
||||
podStartTimeout = 5 * time.Minute
|
||||
podStartShortTimeout = 2 * time.Minute
|
||||
podStartSlowTimeout = 15 * time.Minute
|
||||
podDeleteTimeout = 5 * time.Minute
|
||||
claimProvisionTimeout = 5 * time.Minute
|
||||
claimProvisionShortTimeout = 1 * time.Minute
|
||||
claimBoundTimeout = 3 * time.Minute
|
||||
pvReclaimTimeout = 3 * time.Minute
|
||||
pvBoundTimeout = 3 * time.Minute
|
||||
pvDeleteTimeout = 3 * time.Minute
|
||||
pvDeleteSlowTimeout = 20 * time.Minute
|
||||
snapshotCreateTimeout = 5 * time.Minute
|
||||
snapshotDeleteTimeout = 5 * time.Minute
|
||||
podStartTimeout = 5 * time.Minute
|
||||
podStartShortTimeout = 2 * time.Minute
|
||||
podStartSlowTimeout = 15 * time.Minute
|
||||
podDeleteTimeout = 5 * time.Minute
|
||||
claimProvisionTimeout = 5 * time.Minute
|
||||
claimProvisionShortTimeout = 1 * time.Minute
|
||||
claimBoundTimeout = 3 * time.Minute
|
||||
pvReclaimTimeout = 3 * time.Minute
|
||||
pvBoundTimeout = 3 * time.Minute
|
||||
pvDeleteTimeout = 3 * time.Minute
|
||||
pvDeleteSlowTimeout = 20 * time.Minute
|
||||
snapshotCreateTimeout = 5 * time.Minute
|
||||
snapshotDeleteTimeout = 5 * time.Minute
|
||||
snapshotControllerMetricsTimeout = 5 * time.Minute
|
||||
)
|
||||
|
||||
// TimeoutContext contains timeout settings for several actions.
|
||||
@ -77,23 +78,27 @@ type TimeoutContext struct {
|
||||
|
||||
// SnapshotDelete is how long for snapshot to delete snapshotContent.
|
||||
SnapshotDelete time.Duration
|
||||
|
||||
// SnapshotControllerMetrics is how long to wait for snapshot controller metrics.
|
||||
SnapshotControllerMetrics time.Duration
|
||||
}
|
||||
|
||||
// NewTimeoutContextWithDefaults returns a TimeoutContext with default values.
|
||||
func NewTimeoutContextWithDefaults() *TimeoutContext {
|
||||
return &TimeoutContext{
|
||||
PodStart: podStartTimeout,
|
||||
PodStartShort: podStartShortTimeout,
|
||||
PodStartSlow: podStartSlowTimeout,
|
||||
PodDelete: podDeleteTimeout,
|
||||
ClaimProvision: claimProvisionTimeout,
|
||||
ClaimProvisionShort: claimProvisionShortTimeout,
|
||||
ClaimBound: claimBoundTimeout,
|
||||
PVReclaim: pvReclaimTimeout,
|
||||
PVBound: pvBoundTimeout,
|
||||
PVDelete: pvDeleteTimeout,
|
||||
PVDeleteSlow: pvDeleteSlowTimeout,
|
||||
SnapshotCreate: snapshotCreateTimeout,
|
||||
SnapshotDelete: snapshotDeleteTimeout,
|
||||
PodStart: podStartTimeout,
|
||||
PodStartShort: podStartShortTimeout,
|
||||
PodStartSlow: podStartSlowTimeout,
|
||||
PodDelete: podDeleteTimeout,
|
||||
ClaimProvision: claimProvisionTimeout,
|
||||
ClaimProvisionShort: claimProvisionShortTimeout,
|
||||
ClaimBound: claimBoundTimeout,
|
||||
PVReclaim: pvReclaimTimeout,
|
||||
PVBound: pvBoundTimeout,
|
||||
PVDelete: pvDeleteTimeout,
|
||||
PVDeleteSlow: pvDeleteSlowTimeout,
|
||||
SnapshotCreate: snapshotCreateTimeout,
|
||||
SnapshotDelete: snapshotDeleteTimeout,
|
||||
SnapshotControllerMetrics: snapshotControllerMetricsTimeout,
|
||||
}
|
||||
}
|
||||
|
13
vendor/k8s.io/kubernetes/test/e2e/framework/volume/OWNERS
generated
vendored
13
vendor/k8s.io/kubernetes/test/e2e/framework/volume/OWNERS
generated
vendored
@ -1,20 +1,11 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- saad-ali
|
||||
- sig-storage-approvers
|
||||
- rootfs
|
||||
- gnufied
|
||||
- jingxu97
|
||||
- jsafrane
|
||||
- msau42
|
||||
reviewers:
|
||||
- saad-ali
|
||||
- rootfs
|
||||
- gnufied
|
||||
- jingxu97
|
||||
- jsafrane
|
||||
- msau42
|
||||
- sig-storage-reviewers
|
||||
- jeffvance
|
||||
- copejon
|
||||
- verult
|
||||
- davidz627
|
||||
|
32
vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go
generated
vendored
32
vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go
generated
vendored
@ -368,11 +368,7 @@ func runVolumeTesterPod(client clientset.Interface, timeouts *framework.TimeoutC
|
||||
var gracePeriod int64 = 1
|
||||
var command string
|
||||
|
||||
if !framework.NodeOSDistroIs("windows") {
|
||||
command = "while true ; do sleep 2; done "
|
||||
} else {
|
||||
command = "while(1) {sleep 2}"
|
||||
}
|
||||
command = "while true ; do sleep 2; done "
|
||||
seLinuxOptions := &v1.SELinuxOptions{Level: "s0:c0,c1"}
|
||||
clientPod := &v1.Pod{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
@ -572,47 +568,30 @@ func InjectContent(f *framework.Framework, config TestConfig, fsGroup *int64, fs
|
||||
// generateWriteCmd is used by generateWriteBlockCmd and generateWriteFileCmd
|
||||
func generateWriteCmd(content, path string) []string {
|
||||
var commands []string
|
||||
if !framework.NodeOSDistroIs("windows") {
|
||||
commands = []string{"/bin/sh", "-c", "echo '" + content + "' > " + path}
|
||||
} else {
|
||||
commands = []string{"powershell", "/c", "echo '" + content + "' > " + path}
|
||||
}
|
||||
commands = []string{"/bin/sh", "-c", "echo '" + content + "' > " + path}
|
||||
return commands
|
||||
}
|
||||
|
||||
// generateReadBlockCmd generates the corresponding command lines to read from a block device with the given file path.
|
||||
// Depending on the Node OS is Windows or linux, the command will use powershell or /bin/sh
|
||||
func generateReadBlockCmd(fullPath string, numberOfCharacters int) []string {
|
||||
var commands []string
|
||||
if !framework.NodeOSDistroIs("windows") {
|
||||
commands = []string{"head", "-c", strconv.Itoa(numberOfCharacters), fullPath}
|
||||
} else {
|
||||
// TODO: is there a way on windows to get the first X bytes from a device?
|
||||
commands = []string{"powershell", "/c", "type " + fullPath}
|
||||
}
|
||||
commands = []string{"head", "-c", strconv.Itoa(numberOfCharacters), fullPath}
|
||||
return commands
|
||||
}
|
||||
|
||||
// generateWriteBlockCmd generates the corresponding command lines to write to a block device the given content.
|
||||
// Depending on the Node OS is Windows or linux, the command will use powershell or /bin/sh
|
||||
func generateWriteBlockCmd(content, fullPath string) []string {
|
||||
return generateWriteCmd(content, fullPath)
|
||||
}
|
||||
|
||||
// GenerateReadFileCmd generates the corresponding command lines to read from a file with the given file path.
|
||||
// Depending on the Node OS is Windows or linux, the command will use powershell or /bin/sh
|
||||
func GenerateReadFileCmd(fullPath string) []string {
|
||||
var commands []string
|
||||
if !framework.NodeOSDistroIs("windows") {
|
||||
commands = []string{"cat", fullPath}
|
||||
} else {
|
||||
commands = []string{"powershell", "/c", "type " + fullPath}
|
||||
}
|
||||
commands = []string{"cat", fullPath}
|
||||
return commands
|
||||
}
|
||||
|
||||
// generateWriteFileCmd generates the corresponding command lines to write a file with the given content and file path.
|
||||
// Depending on the Node OS is Windows or linux, the command will use powershell or /bin/sh
|
||||
func generateWriteFileCmd(content, fullPath string) []string {
|
||||
return generateWriteCmd(content, fullPath)
|
||||
}
|
||||
@ -638,9 +617,6 @@ func CheckVolumeModeOfPath(f *framework.Framework, pod *v1.Pod, volMode v1.Persi
|
||||
// TODO: put this under e2epod once https://github.com/kubernetes/kubernetes/issues/81245
|
||||
// is resolved. Otherwise there will be dependency issue.
|
||||
func PodExec(f *framework.Framework, pod *v1.Pod, shExec string) (string, string, error) {
|
||||
if framework.NodeOSDistroIs("windows") {
|
||||
return f.ExecCommandInContainerWithFullOutput(pod.Name, pod.Spec.Containers[0].Name, "powershell", "/c", shExec)
|
||||
}
|
||||
return f.ExecCommandInContainerWithFullOutput(pod.Name, pod.Spec.Containers[0].Name, "/bin/sh", "-c", shExec)
|
||||
}
|
||||
|
||||
|
88
vendor/k8s.io/kubernetes/test/e2e/storage/podlogs/podlogs.go
generated
vendored
88
vendor/k8s.io/kubernetes/test/e2e/storage/podlogs/podlogs.go
generated
vendored
@ -33,8 +33,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -57,11 +56,18 @@ type LogOutput struct {
|
||||
// Matches harmless errors from pkg/kubelet/kubelet_pods.go.
|
||||
var expectedErrors = regexp.MustCompile(`container .* in pod .* is (terminated|waiting to start|not available)|the server could not find the requested resource`)
|
||||
|
||||
// CopyAllLogs follows the logs of all containers in all pods,
|
||||
// CopyPodLogs is basically CopyPodLogs for all current or future pods in the given namespace ns
|
||||
func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogOutput) error {
|
||||
return CopyPodLogs(ctx, cs, ns, "", to)
|
||||
}
|
||||
|
||||
// CopyPodLogs follows the logs of all containers in pod with the given podName,
|
||||
// including those that get created in the future, and writes each log
|
||||
// line as configured in the output options. It does that until the
|
||||
// context is done or until an error occurs.
|
||||
//
|
||||
// If podName is empty, it will follow all pods in the given namespace ns.
|
||||
//
|
||||
// Beware that there is currently no way to force log collection
|
||||
// before removing pods, which means that there is a known race
|
||||
// between "stop pod" and "collecting log entries". The alternative
|
||||
@ -79,10 +85,17 @@ var expectedErrors = regexp.MustCompile(`container .* in pod .* is (terminated|w
|
||||
// But it turned out to be rather confusing, so now a heuristic is used: if
|
||||
// log output of a container was already captured, then capturing does not
|
||||
// resume if the pod is marked for deletion.
|
||||
func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogOutput) error {
|
||||
watcher, err := cs.CoreV1().Pods(ns).Watch(context.TODO(), meta.ListOptions{})
|
||||
func CopyPodLogs(ctx context.Context, cs clientset.Interface, ns, podName string, to LogOutput) error {
|
||||
options := meta.ListOptions{}
|
||||
if podName != "" {
|
||||
options = meta.ListOptions{
|
||||
FieldSelector: fmt.Sprintf("metadata.name=%s", podName),
|
||||
}
|
||||
}
|
||||
watcher, err := cs.CoreV1().Pods(ns).Watch(context.TODO(), options)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot create Pod event watcher")
|
||||
return fmt.Errorf("cannot create Pod event watcher: %w", err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
@ -96,7 +109,7 @@ func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogO
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
pods, err := cs.CoreV1().Pods(ns).List(context.TODO(), meta.ListOptions{})
|
||||
pods, err := cs.CoreV1().Pods(ns).List(context.TODO(), options)
|
||||
if err != nil {
|
||||
if to.StatusWriter != nil {
|
||||
fmt.Fprintf(to.StatusWriter, "ERROR: get pod list in %s: %s\n", ns, err)
|
||||
@ -252,18 +265,42 @@ func logsForPod(ctx context.Context, cs clientset.Interface, ns, pod string, opt
|
||||
}
|
||||
|
||||
// WatchPods prints pod status events for a certain namespace or all namespaces
|
||||
// when namespace name is empty.
|
||||
func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Writer) error {
|
||||
watcher, err := cs.CoreV1().Pods(ns).Watch(context.TODO(), meta.ListOptions{})
|
||||
// when namespace name is empty. The closer can be nil if the caller doesn't want
|
||||
// the file to be closed when watching stops.
|
||||
func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Writer, toCloser io.Closer) (finalErr error) {
|
||||
defer func() {
|
||||
if finalErr != nil && toCloser != nil {
|
||||
toCloser.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
pods, err := cs.CoreV1().Pods(ns).Watch(context.Background(), meta.ListOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot create Pod event watcher")
|
||||
return fmt.Errorf("cannot create Pod watcher: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if finalErr != nil {
|
||||
pods.Stop()
|
||||
}
|
||||
}()
|
||||
|
||||
events, err := cs.CoreV1().Events(ns).Watch(context.Background(), meta.ListOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot create Event watcher: %w", err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer watcher.Stop()
|
||||
defer func() {
|
||||
pods.Stop()
|
||||
events.Stop()
|
||||
if toCloser != nil {
|
||||
toCloser.Close()
|
||||
}
|
||||
}()
|
||||
timeFormat := "15:04:05.000"
|
||||
for {
|
||||
select {
|
||||
case e := <-watcher.ResultChan():
|
||||
case e := <-pods.ResultChan():
|
||||
if e.Object == nil {
|
||||
continue
|
||||
}
|
||||
@ -274,7 +311,8 @@ func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Wri
|
||||
}
|
||||
buffer := new(bytes.Buffer)
|
||||
fmt.Fprintf(buffer,
|
||||
"pod event: %s: %s/%s %s: %s %s\n",
|
||||
"%s pod: %s: %s/%s %s: %s %s\n",
|
||||
time.Now().Format(timeFormat),
|
||||
e.Type,
|
||||
pod.Namespace,
|
||||
pod.Name,
|
||||
@ -300,7 +338,29 @@ func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Wri
|
||||
fmt.Fprintf(buffer, "\n")
|
||||
}
|
||||
to.Write(buffer.Bytes())
|
||||
case e := <-events.ResultChan():
|
||||
if e.Object == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
event, ok := e.Object.(*v1.Event)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
to.Write([]byte(fmt.Sprintf("%s event: %s/%s %s: %s %s: %s (%v - %v)\n",
|
||||
time.Now().Format(timeFormat),
|
||||
event.InvolvedObject.APIVersion,
|
||||
event.InvolvedObject.Kind,
|
||||
event.InvolvedObject.Name,
|
||||
event.Source.Component,
|
||||
event.Type,
|
||||
event.Message,
|
||||
event.FirstTimestamp,
|
||||
event.LastTimestamp,
|
||||
)))
|
||||
case <-ctx.Done():
|
||||
to.Write([]byte(fmt.Sprintf("%s ==== stopping pod watch ====\n",
|
||||
time.Now().Format(timeFormat))))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
49
vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go
generated
vendored
49
vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go
generated
vendored
@ -20,10 +20,9 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
@ -58,17 +57,17 @@ func LoadFromManifests(files ...string) ([]interface{}, error) {
|
||||
// Ignore any additional fields for now, just determine what we have.
|
||||
var what What
|
||||
if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), data, &what); err != nil {
|
||||
return errors.Wrap(err, "decode TypeMeta")
|
||||
return fmt.Errorf("decode TypeMeta: %w", err)
|
||||
}
|
||||
|
||||
factory := factories[what]
|
||||
if factory == nil {
|
||||
return errors.Errorf("item of type %+v not supported", what)
|
||||
return fmt.Errorf("item of type %+v not supported", what)
|
||||
}
|
||||
|
||||
object := factory.New()
|
||||
if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), data, object); err != nil {
|
||||
return errors.Wrapf(err, "decode %+v", what)
|
||||
return fmt.Errorf("decode %+v: %w", what, err)
|
||||
}
|
||||
items = append(items, object)
|
||||
return nil
|
||||
@ -96,7 +95,7 @@ func visitManifests(cb func([]byte) error, files ...string) error {
|
||||
|
||||
for _, item := range items {
|
||||
if err := cb(item); err != nil {
|
||||
return errors.Wrap(err, fileName)
|
||||
return fmt.Errorf("%s: %w", fileName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,13 +172,13 @@ func CreateItems(f *framework.Framework, ns *v1.Namespace, items ...interface{})
|
||||
if err == nil {
|
||||
done = true
|
||||
break
|
||||
} else if errors.Cause(err) != errorItemNotSupported {
|
||||
} else if !errors.Is(err, errorItemNotSupported) {
|
||||
result = err
|
||||
break
|
||||
}
|
||||
}
|
||||
if result == nil && !done {
|
||||
result = errors.Errorf("item of type %T not supported", item)
|
||||
result = fmt.Errorf("item of type %T not supported", item)
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -198,7 +197,7 @@ func CreateItems(f *framework.Framework, ns *v1.Namespace, items ...interface{})
|
||||
func CreateFromManifests(f *framework.Framework, driverNamespace *v1.Namespace, patch func(item interface{}) error, files ...string) (func(), error) {
|
||||
items, err := LoadFromManifests(files...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "CreateFromManifests")
|
||||
return nil, fmt.Errorf("CreateFromManifests: %w", err)
|
||||
}
|
||||
if err := PatchItems(f, driverNamespace, items...); err != nil {
|
||||
return nil, err
|
||||
@ -337,21 +336,21 @@ func patchItemRecursively(f *framework.Framework, driverNamespace *v1.Namespace,
|
||||
PatchName(f, &item.Name)
|
||||
for i := range item.Subjects {
|
||||
if err := patchItemRecursively(f, driverNamespace, &item.Subjects[i]); err != nil {
|
||||
return errors.Wrapf(err, "%T", f)
|
||||
return fmt.Errorf("%T: %w", f, err)
|
||||
}
|
||||
}
|
||||
if err := patchItemRecursively(f, driverNamespace, &item.RoleRef); err != nil {
|
||||
return errors.Wrapf(err, "%T", f)
|
||||
return fmt.Errorf("%T: %w", f, err)
|
||||
}
|
||||
case *rbacv1.RoleBinding:
|
||||
PatchNamespace(f, driverNamespace, &item.Namespace)
|
||||
for i := range item.Subjects {
|
||||
if err := patchItemRecursively(f, driverNamespace, &item.Subjects[i]); err != nil {
|
||||
return errors.Wrapf(err, "%T", f)
|
||||
return fmt.Errorf("%T: %w", f, err)
|
||||
}
|
||||
}
|
||||
if err := patchItemRecursively(f, driverNamespace, &item.RoleRef); err != nil {
|
||||
return errors.Wrapf(err, "%T", f)
|
||||
return fmt.Errorf("%T: %w", f, err)
|
||||
}
|
||||
case *v1.Service:
|
||||
PatchNamespace(f, driverNamespace, &item.ObjectMeta.Namespace)
|
||||
@ -372,7 +371,7 @@ func patchItemRecursively(f *framework.Framework, driverNamespace *v1.Namespace,
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return errors.Errorf("missing support for patching item of type %T", item)
|
||||
return fmt.Errorf("missing support for patching item of type %T", item)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -395,7 +394,7 @@ func (*serviceAccountFactory) Create(f *framework.Framework, ns *v1.Namespace, i
|
||||
}
|
||||
client := f.ClientSet.CoreV1().ServiceAccounts(ns.Name)
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create ServiceAccount")
|
||||
return nil, fmt.Errorf("create ServiceAccount: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -417,7 +416,7 @@ func (*clusterRoleFactory) Create(f *framework.Framework, ns *v1.Namespace, i in
|
||||
framework.Logf("Define cluster role %v", item.GetName())
|
||||
client := f.ClientSet.RbacV1().ClusterRoles()
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create ClusterRole")
|
||||
return nil, fmt.Errorf("create ClusterRole: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -438,7 +437,7 @@ func (*clusterRoleBindingFactory) Create(f *framework.Framework, ns *v1.Namespac
|
||||
|
||||
client := f.ClientSet.RbacV1().ClusterRoleBindings()
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create ClusterRoleBinding")
|
||||
return nil, fmt.Errorf("create ClusterRoleBinding: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -459,7 +458,7 @@ func (*roleFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface
|
||||
|
||||
client := f.ClientSet.RbacV1().Roles(ns.Name)
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create Role")
|
||||
return nil, fmt.Errorf("create Role: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -480,7 +479,7 @@ func (*roleBindingFactory) Create(f *framework.Framework, ns *v1.Namespace, i in
|
||||
|
||||
client := f.ClientSet.RbacV1().RoleBindings(ns.Name)
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create RoleBinding")
|
||||
return nil, fmt.Errorf("create RoleBinding: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -501,7 +500,7 @@ func (*serviceFactory) Create(f *framework.Framework, ns *v1.Namespace, i interf
|
||||
|
||||
client := f.ClientSet.CoreV1().Services(ns.Name)
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create Service")
|
||||
return nil, fmt.Errorf("create Service: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -522,7 +521,7 @@ func (*statefulSetFactory) Create(f *framework.Framework, ns *v1.Namespace, i in
|
||||
|
||||
client := f.ClientSet.AppsV1().StatefulSets(ns.Name)
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create StatefulSet")
|
||||
return nil, fmt.Errorf("create StatefulSet: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -543,7 +542,7 @@ func (*daemonSetFactory) Create(f *framework.Framework, ns *v1.Namespace, i inte
|
||||
|
||||
client := f.ClientSet.AppsV1().DaemonSets(ns.Name)
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create DaemonSet")
|
||||
return nil, fmt.Errorf("create DaemonSet: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -564,7 +563,7 @@ func (*storageClassFactory) Create(f *framework.Framework, ns *v1.Namespace, i i
|
||||
|
||||
client := f.ClientSet.StorageV1().StorageClasses()
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create StorageClass")
|
||||
return nil, fmt.Errorf("create StorageClass: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -585,7 +584,7 @@ func (*csiDriverFactory) Create(f *framework.Framework, ns *v1.Namespace, i inte
|
||||
|
||||
client := f.ClientSet.StorageV1().CSIDrivers()
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create CSIDriver")
|
||||
return nil, fmt.Errorf("create CSIDriver: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
@ -606,7 +605,7 @@ func (*secretFactory) Create(f *framework.Framework, ns *v1.Namespace, i interfa
|
||||
|
||||
client := f.ClientSet.CoreV1().Secrets(ns.Name)
|
||||
if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
|
||||
return nil, errors.Wrap(err, "create Secret")
|
||||
return nil, fmt.Errorf("create Secret: %w", err)
|
||||
}
|
||||
return func() error {
|
||||
return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{})
|
||||
|
26
vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go
generated
vendored
26
vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go
generated
vendored
@ -19,6 +19,9 @@ package utils
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@ -46,6 +49,8 @@ func StartPodLogs(f *framework.Framework, driverNamespace *v1.Namespace) func()
|
||||
|
||||
ns := driverNamespace.Name
|
||||
|
||||
podEventLog := ginkgo.GinkgoWriter
|
||||
var podEventLogCloser io.Closer
|
||||
to := podlogs.LogOutput{
|
||||
StatusWriter: ginkgo.GinkgoWriter,
|
||||
}
|
||||
@ -69,17 +74,22 @@ func StartPodLogs(f *framework.Framework, driverNamespace *v1.Namespace) func()
|
||||
// keeps each directory name smaller (the full test
|
||||
// name at one point exceeded 256 characters, which was
|
||||
// too much for some filesystems).
|
||||
to.LogPathPrefix = framework.TestContext.ReportDir + "/" +
|
||||
strings.Join(components, "/") + "/"
|
||||
logDir := framework.TestContext.ReportDir + "/" + strings.Join(components, "/")
|
||||
to.LogPathPrefix = logDir + "/"
|
||||
|
||||
err := os.MkdirAll(logDir, 0755)
|
||||
framework.ExpectNoError(err, "create pod log directory")
|
||||
f, err := os.Create(path.Join(logDir, "pod-event.log"))
|
||||
framework.ExpectNoError(err, "create pod events log file")
|
||||
podEventLog = f
|
||||
podEventLogCloser = f
|
||||
}
|
||||
podlogs.CopyAllLogs(ctx, cs, ns, to)
|
||||
|
||||
// pod events are something that the framework already collects itself
|
||||
// after a failed test. Logging them live is only useful for interactive
|
||||
// debugging, not when we collect reports.
|
||||
if framework.TestContext.ReportDir == "" {
|
||||
podlogs.WatchPods(ctx, cs, ns, ginkgo.GinkgoWriter)
|
||||
}
|
||||
// The framework doesn't know about the driver pods because of
|
||||
// the separate namespace. Therefore we always capture the
|
||||
// events ourselves.
|
||||
podlogs.WatchPods(ctx, cs, ns, podEventLog, podEventLogCloser)
|
||||
|
||||
return cancel
|
||||
}
|
||||
|
4
vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot.go
generated
vendored
@ -130,7 +130,6 @@ func GenerateSnapshotClassSpec(
|
||||
snapshotter string,
|
||||
parameters map[string]string,
|
||||
ns string,
|
||||
suffix string,
|
||||
) *unstructured.Unstructured {
|
||||
snapshotClass := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
@ -138,8 +137,7 @@ func GenerateSnapshotClassSpec(
|
||||
"apiVersion": SnapshotAPIVersion,
|
||||
"metadata": map[string]interface{}{
|
||||
// Name must be unique, so let's base it on namespace name and use GenerateName
|
||||
// TODO(#96234): Remove unnecessary suffix.
|
||||
"name": names.SimpleNameGenerator.GenerateName(ns + "-" + suffix),
|
||||
"name": names.SimpleNameGenerator.GenerateName(ns),
|
||||
},
|
||||
"driver": snapshotter,
|
||||
"parameters": parameters,
|
||||
|
11
vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go
generated
vendored
11
vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
||||
"math"
|
||||
"math/rand"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -571,6 +572,16 @@ func CheckWriteToPath(f *framework.Framework, pod *v1.Pod, volMode v1.Persistent
|
||||
e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("echo %s | base64 -d | dd of=%s %s bs=%d count=1", encoded, pathForVolMode, oflag, len))
|
||||
}
|
||||
|
||||
// GetSectorSize returns the sector size of the device.
|
||||
func GetSectorSize(f *framework.Framework, pod *v1.Pod, device string) int {
|
||||
stdout, _, err := e2evolume.PodExec(f, pod, fmt.Sprintf("blockdev --getss %s", device))
|
||||
framework.ExpectNoError(err, "Failed to get sector size of %s", device)
|
||||
ss, err := strconv.Atoi(stdout)
|
||||
framework.ExpectNoError(err, "Sector size returned by blockdev command isn't integer value.")
|
||||
|
||||
return ss
|
||||
}
|
||||
|
||||
// findMountPoints returns all mount points on given node under specified directory.
|
||||
func findMountPoints(hostExec HostExec, node *v1.Node, dir string) []string {
|
||||
result, err := hostExec.IssueCommandWithResult(fmt.Sprintf(`find %s -type d -exec mountpoint {} \; | grep 'is a mountpoint$' || true`, dir), node)
|
||||
|
52
vendor/k8s.io/kubernetes/test/utils/create_resources.go
generated
vendored
52
vendor/k8s.io/kubernetes/test/utils/create_resources.go
generated
vendored
@ -55,182 +55,182 @@ func RetryWithExponentialBackOff(fn wait.ConditionFunc) error {
|
||||
|
||||
func CreatePodWithRetries(c clientset.Interface, namespace string, obj *v1.Pod) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().Pods(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v ", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateRCWithRetries(c clientset.Interface, namespace string, obj *v1.ReplicationController) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().ReplicationControllers(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateReplicaSetWithRetries(c clientset.Interface, namespace string, obj *apps.ReplicaSet) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.AppsV1().ReplicaSets(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateDeploymentWithRetries(c clientset.Interface, namespace string, obj *apps.Deployment) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.AppsV1().Deployments(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateDaemonSetWithRetries(c clientset.Interface, namespace string, obj *apps.DaemonSet) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.AppsV1().DaemonSets(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateJobWithRetries(c clientset.Interface, namespace string, obj *batch.Job) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.BatchV1().Jobs(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateSecretWithRetries(c clientset.Interface, namespace string, obj *v1.Secret) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().Secrets(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateConfigMapWithRetries(c clientset.Interface, namespace string, obj *v1.ConfigMap) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().ConfigMaps(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateServiceWithRetries(c clientset.Interface, namespace string, obj *v1.Service) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().Services(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateStorageClassWithRetries(c clientset.Interface, obj *storage.StorageClass) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.StorageV1().StorageClasses().Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreateResourceQuotaWithRetries(c clientset.Interface, namespace string, obj *v1.ResourceQuota) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().ResourceQuotas(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreatePersistentVolumeWithRetries(c clientset.Interface, obj *v1.PersistentVolume) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().PersistentVolumes().Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func CreatePersistentVolumeClaimWithRetries(c clientset.Interface, namespace string, obj *v1.PersistentVolumeClaim) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().PersistentVolumeClaims(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
if err == nil || apierrors.IsAlreadyExists(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
4
vendor/k8s.io/kubernetes/test/utils/delete_resources.go
generated
vendored
4
vendor/k8s.io/kubernetes/test/utils/delete_resources.go
generated
vendored
@ -53,7 +53,7 @@ func deleteResource(c clientset.Interface, kind schema.GroupKind, namespace, nam
|
||||
case api.Kind("Service"):
|
||||
return c.CoreV1().Services(namespace).Delete(context.TODO(), name, options)
|
||||
default:
|
||||
return fmt.Errorf("Unsupported kind when deleting: %v", kind)
|
||||
return fmt.Errorf("unsupported kind when deleting: %v", kind)
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ func DeleteResourceWithRetries(c clientset.Interface, kind schema.GroupKind, nam
|
||||
if err == nil || apierrors.IsNotFound(err) {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to delete object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to delete object with non-retriable error: %v", err)
|
||||
}
|
||||
return RetryWithExponentialBackOff(deleteFunc)
|
||||
}
|
||||
|
3
vendor/k8s.io/kubernetes/test/utils/deployment.go
generated
vendored
3
vendor/k8s.io/kubernetes/test/utils/deployment.go
generated
vendored
@ -22,7 +22,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
apps "k8s.io/api/apps/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
@ -201,7 +200,7 @@ func WaitForDeploymentRevisionAndImage(c clientset.Interface, ns, deploymentName
|
||||
}
|
||||
if err != nil {
|
||||
if deployment == nil {
|
||||
return errors.Wrapf(err, "error creating new replica set for deployment %q ", deploymentName)
|
||||
return fmt.Errorf("error creating new replica set for deployment %q: %w", deploymentName, err)
|
||||
}
|
||||
deploymentImage := ""
|
||||
if len(deployment.Spec.Template.Spec.Containers) > 0 {
|
||||
|
221
vendor/k8s.io/kubernetes/test/utils/image/manifest.go
generated
vendored
221
vendor/k8s.io/kubernetes/test/utils/image/manifest.go
generated
vendored
@ -25,23 +25,25 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// RegistryList holds public and private image registries
|
||||
type RegistryList struct {
|
||||
GcAuthenticatedRegistry string `yaml:"gcAuthenticatedRegistry"`
|
||||
E2eRegistry string `yaml:"e2eRegistry"`
|
||||
PromoterE2eRegistry string `yaml:"promoterE2eRegistry"`
|
||||
BuildImageRegistry string `yaml:"buildImageRegistry"`
|
||||
InvalidRegistry string `yaml:"invalidRegistry"`
|
||||
GcEtcdRegistry string `yaml:"gcEtcdRegistry"`
|
||||
GcRegistry string `yaml:"gcRegistry"`
|
||||
SigStorageRegistry string `yaml:"sigStorageRegistry"`
|
||||
GcrReleaseRegistry string `yaml:"gcrReleaseRegistry"`
|
||||
PrivateRegistry string `yaml:"privateRegistry"`
|
||||
SampleRegistry string `yaml:"sampleRegistry"`
|
||||
MicrosoftRegistry string `yaml:"microsoftRegistry"`
|
||||
GcAuthenticatedRegistry string `yaml:"gcAuthenticatedRegistry"`
|
||||
E2eRegistry string `yaml:"e2eRegistry"`
|
||||
PromoterE2eRegistry string `yaml:"promoterE2eRegistry"`
|
||||
BuildImageRegistry string `yaml:"buildImageRegistry"`
|
||||
InvalidRegistry string `yaml:"invalidRegistry"`
|
||||
GcEtcdRegistry string `yaml:"gcEtcdRegistry"`
|
||||
GcRegistry string `yaml:"gcRegistry"`
|
||||
SigStorageRegistry string `yaml:"sigStorageRegistry"`
|
||||
GcrReleaseRegistry string `yaml:"gcrReleaseRegistry"`
|
||||
PrivateRegistry string `yaml:"privateRegistry"`
|
||||
SampleRegistry string `yaml:"sampleRegistry"`
|
||||
MicrosoftRegistry string `yaml:"microsoftRegistry"`
|
||||
DockerLibraryRegistry string `yaml:"dockerLibraryRegistry"`
|
||||
CloudProviderGcpRegistry string `yaml:"cloudProviderGcpRegistry"`
|
||||
}
|
||||
|
||||
// Config holds an images registry, name, and version
|
||||
@ -67,20 +69,8 @@ func (i *Config) SetVersion(version string) {
|
||||
}
|
||||
|
||||
func initReg() RegistryList {
|
||||
registry := RegistryList{
|
||||
GcAuthenticatedRegistry: "gcr.io/authenticated-image-pulling",
|
||||
E2eRegistry: "gcr.io/kubernetes-e2e-test-images",
|
||||
PromoterE2eRegistry: "k8s.gcr.io/e2e-test-images",
|
||||
BuildImageRegistry: "k8s.gcr.io/build-image",
|
||||
InvalidRegistry: "invalid.com/invalid",
|
||||
GcEtcdRegistry: "k8s.gcr.io",
|
||||
GcRegistry: "k8s.gcr.io",
|
||||
SigStorageRegistry: "k8s.gcr.io/sig-storage",
|
||||
PrivateRegistry: "gcr.io/k8s-authenticated-test",
|
||||
SampleRegistry: "gcr.io/google-samples",
|
||||
GcrReleaseRegistry: "gcr.io/gke-release",
|
||||
MicrosoftRegistry: "mcr.microsoft.com",
|
||||
}
|
||||
registry := initRegistry
|
||||
|
||||
repoList := os.Getenv("KUBE_TEST_REPO_LIST")
|
||||
if repoList == "" {
|
||||
return registry
|
||||
@ -99,26 +89,27 @@ func initReg() RegistryList {
|
||||
}
|
||||
|
||||
var (
|
||||
initRegistry = RegistryList{
|
||||
GcAuthenticatedRegistry: "gcr.io/authenticated-image-pulling",
|
||||
E2eRegistry: "gcr.io/kubernetes-e2e-test-images",
|
||||
PromoterE2eRegistry: "k8s.gcr.io/e2e-test-images",
|
||||
BuildImageRegistry: "k8s.gcr.io/build-image",
|
||||
InvalidRegistry: "invalid.com/invalid",
|
||||
GcEtcdRegistry: "k8s.gcr.io",
|
||||
GcRegistry: "k8s.gcr.io",
|
||||
SigStorageRegistry: "k8s.gcr.io/sig-storage",
|
||||
PrivateRegistry: "gcr.io/k8s-authenticated-test",
|
||||
SampleRegistry: "gcr.io/google-samples",
|
||||
GcrReleaseRegistry: "gcr.io/gke-release",
|
||||
MicrosoftRegistry: "mcr.microsoft.com",
|
||||
DockerLibraryRegistry: "docker.io/library",
|
||||
CloudProviderGcpRegistry: "k8s.gcr.io/cloud-provider-gcp",
|
||||
}
|
||||
|
||||
registry = initReg()
|
||||
|
||||
// PrivateRegistry is an image repository that requires authentication
|
||||
PrivateRegistry = registry.PrivateRegistry
|
||||
|
||||
// Preconfigured image configs
|
||||
dockerLibraryRegistry = "docker.io/library"
|
||||
e2eRegistry = registry.E2eRegistry
|
||||
promoterE2eRegistry = registry.PromoterE2eRegistry
|
||||
buildImageRegistry = registry.BuildImageRegistry
|
||||
gcAuthenticatedRegistry = registry.GcAuthenticatedRegistry
|
||||
gcEtcdRegistry = registry.GcEtcdRegistry
|
||||
gcRegistry = registry.GcRegistry
|
||||
sigStorageRegistry = registry.SigStorageRegistry
|
||||
gcrReleaseRegistry = registry.GcrReleaseRegistry
|
||||
invalidRegistry = registry.InvalidRegistry
|
||||
sampleRegistry = registry.SampleRegistry
|
||||
microsoftRegistry = registry.MicrosoftRegistry
|
||||
|
||||
imageConfigs, originalImageConfigs = initImageConfigs()
|
||||
imageConfigs, originalImageConfigs = initImageConfigs(registry)
|
||||
)
|
||||
|
||||
const (
|
||||
@ -211,51 +202,51 @@ const (
|
||||
WindowsServer
|
||||
)
|
||||
|
||||
func initImageConfigs() (map[int]Config, map[int]Config) {
|
||||
func initImageConfigs(list RegistryList) (map[int]Config, map[int]Config) {
|
||||
configs := map[int]Config{}
|
||||
configs[Agnhost] = Config{promoterE2eRegistry, "agnhost", "2.32"}
|
||||
configs[AgnhostPrivate] = Config{PrivateRegistry, "agnhost", "2.6"}
|
||||
configs[AuthenticatedAlpine] = Config{gcAuthenticatedRegistry, "alpine", "3.7"}
|
||||
configs[AuthenticatedWindowsNanoServer] = Config{gcAuthenticatedRegistry, "windows-nanoserver", "v1"}
|
||||
configs[APIServer] = Config{promoterE2eRegistry, "sample-apiserver", "1.17.4"}
|
||||
configs[AppArmorLoader] = Config{promoterE2eRegistry, "apparmor-loader", "1.3"}
|
||||
configs[BusyBox] = Config{promoterE2eRegistry, "busybox", "1.29-1"}
|
||||
configs[CheckMetadataConcealment] = Config{promoterE2eRegistry, "metadata-concealment", "1.6"}
|
||||
configs[CudaVectorAdd] = Config{e2eRegistry, "cuda-vector-add", "1.0"}
|
||||
configs[CudaVectorAdd2] = Config{promoterE2eRegistry, "cuda-vector-add", "2.2"}
|
||||
configs[DebianIptables] = Config{buildImageRegistry, "debian-iptables", "buster-v1.6.2"}
|
||||
configs[EchoServer] = Config{promoterE2eRegistry, "echoserver", "2.3"}
|
||||
configs[Etcd] = Config{gcEtcdRegistry, "etcd", "3.4.13-0"}
|
||||
configs[GlusterDynamicProvisioner] = Config{promoterE2eRegistry, "glusterdynamic-provisioner", "v1.0"}
|
||||
configs[Httpd] = Config{promoterE2eRegistry, "httpd", "2.4.38-1"}
|
||||
configs[HttpdNew] = Config{promoterE2eRegistry, "httpd", "2.4.39-1"}
|
||||
configs[InvalidRegistryImage] = Config{invalidRegistry, "alpine", "3.1"}
|
||||
configs[IpcUtils] = Config{promoterE2eRegistry, "ipc-utils", "1.2"}
|
||||
configs[JessieDnsutils] = Config{promoterE2eRegistry, "jessie-dnsutils", "1.4"}
|
||||
configs[Kitten] = Config{promoterE2eRegistry, "kitten", "1.4"}
|
||||
configs[Nautilus] = Config{promoterE2eRegistry, "nautilus", "1.4"}
|
||||
configs[NFSProvisioner] = Config{sigStorageRegistry, "nfs-provisioner", "v2.2.2"}
|
||||
configs[Nginx] = Config{promoterE2eRegistry, "nginx", "1.14-1"}
|
||||
configs[NginxNew] = Config{promoterE2eRegistry, "nginx", "1.15-1"}
|
||||
configs[NodePerfNpbEp] = Config{promoterE2eRegistry, "node-perf/npb-ep", "1.1"}
|
||||
configs[NodePerfNpbIs] = Config{promoterE2eRegistry, "node-perf/npb-is", "1.1"}
|
||||
configs[NodePerfTfWideDeep] = Config{promoterE2eRegistry, "node-perf/tf-wide-deep", "1.1"}
|
||||
configs[Nonewprivs] = Config{promoterE2eRegistry, "nonewprivs", "1.3"}
|
||||
configs[NonRoot] = Config{promoterE2eRegistry, "nonroot", "1.1"}
|
||||
configs[Agnhost] = Config{list.PromoterE2eRegistry, "agnhost", "2.32"}
|
||||
configs[AgnhostPrivate] = Config{list.PrivateRegistry, "agnhost", "2.6"}
|
||||
configs[AuthenticatedAlpine] = Config{list.GcAuthenticatedRegistry, "alpine", "3.7"}
|
||||
configs[AuthenticatedWindowsNanoServer] = Config{list.GcAuthenticatedRegistry, "windows-nanoserver", "v1"}
|
||||
configs[APIServer] = Config{list.PromoterE2eRegistry, "sample-apiserver", "1.17.4"}
|
||||
configs[AppArmorLoader] = Config{list.PromoterE2eRegistry, "apparmor-loader", "1.3"}
|
||||
configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.29-1"}
|
||||
configs[CheckMetadataConcealment] = Config{list.PromoterE2eRegistry, "metadata-concealment", "1.6"}
|
||||
configs[CudaVectorAdd] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "1.0"}
|
||||
configs[CudaVectorAdd2] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "2.2"}
|
||||
configs[DebianIptables] = Config{list.BuildImageRegistry, "debian-iptables", "buster-v1.6.5"}
|
||||
configs[EchoServer] = Config{list.PromoterE2eRegistry, "echoserver", "2.3"}
|
||||
configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.4.13-0"}
|
||||
configs[GlusterDynamicProvisioner] = Config{list.PromoterE2eRegistry, "glusterdynamic-provisioner", "v1.0"}
|
||||
configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-1"}
|
||||
configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-1"}
|
||||
configs[InvalidRegistryImage] = Config{list.InvalidRegistry, "alpine", "3.1"}
|
||||
configs[IpcUtils] = Config{list.PromoterE2eRegistry, "ipc-utils", "1.2"}
|
||||
configs[JessieDnsutils] = Config{list.PromoterE2eRegistry, "jessie-dnsutils", "1.4"}
|
||||
configs[Kitten] = Config{list.PromoterE2eRegistry, "kitten", "1.4"}
|
||||
configs[Nautilus] = Config{list.PromoterE2eRegistry, "nautilus", "1.4"}
|
||||
configs[NFSProvisioner] = Config{list.SigStorageRegistry, "nfs-provisioner", "v2.2.2"}
|
||||
configs[Nginx] = Config{list.PromoterE2eRegistry, "nginx", "1.14-1"}
|
||||
configs[NginxNew] = Config{list.PromoterE2eRegistry, "nginx", "1.15-1"}
|
||||
configs[NodePerfNpbEp] = Config{list.PromoterE2eRegistry, "node-perf/npb-ep", "1.1"}
|
||||
configs[NodePerfNpbIs] = Config{list.PromoterE2eRegistry, "node-perf/npb-is", "1.1"}
|
||||
configs[NodePerfTfWideDeep] = Config{list.PromoterE2eRegistry, "node-perf/tf-wide-deep", "1.1"}
|
||||
configs[Nonewprivs] = Config{list.PromoterE2eRegistry, "nonewprivs", "1.3"}
|
||||
configs[NonRoot] = Config{list.PromoterE2eRegistry, "nonroot", "1.1"}
|
||||
// Pause - when these values are updated, also update cmd/kubelet/app/options/container_runtime.go
|
||||
configs[Pause] = Config{gcRegistry, "pause", "3.4.1"}
|
||||
configs[Perl] = Config{promoterE2eRegistry, "perl", "5.26"}
|
||||
configs[PrometheusDummyExporter] = Config{gcRegistry, "prometheus-dummy-exporter", "v0.1.0"}
|
||||
configs[PrometheusToSd] = Config{gcRegistry, "prometheus-to-sd", "v0.5.0"}
|
||||
configs[Redis] = Config{promoterE2eRegistry, "redis", "5.0.5-alpine"}
|
||||
configs[RegressionIssue74839] = Config{promoterE2eRegistry, "regression-issue-74839", "1.2"}
|
||||
configs[ResourceConsumer] = Config{promoterE2eRegistry, "resource-consumer", "1.9"}
|
||||
configs[SdDummyExporter] = Config{gcRegistry, "sd-dummy-exporter", "v0.2.0"}
|
||||
configs[VolumeNFSServer] = Config{promoterE2eRegistry, "volume/nfs", "1.2"}
|
||||
configs[VolumeISCSIServer] = Config{promoterE2eRegistry, "volume/iscsi", "2.2"}
|
||||
configs[VolumeGlusterServer] = Config{promoterE2eRegistry, "volume/gluster", "1.2"}
|
||||
configs[VolumeRBDServer] = Config{promoterE2eRegistry, "volume/rbd", "1.0.3"}
|
||||
configs[WindowsServer] = Config{microsoftRegistry, "windows", "1809"}
|
||||
configs[Pause] = Config{list.GcRegistry, "pause", "3.5"}
|
||||
configs[Perl] = Config{list.PromoterE2eRegistry, "perl", "5.26"}
|
||||
configs[PrometheusDummyExporter] = Config{list.GcRegistry, "prometheus-dummy-exporter", "v0.1.0"}
|
||||
configs[PrometheusToSd] = Config{list.GcRegistry, "prometheus-to-sd", "v0.5.0"}
|
||||
configs[Redis] = Config{list.PromoterE2eRegistry, "redis", "5.0.5-alpine"}
|
||||
configs[RegressionIssue74839] = Config{list.PromoterE2eRegistry, "regression-issue-74839", "1.2"}
|
||||
configs[ResourceConsumer] = Config{list.PromoterE2eRegistry, "resource-consumer", "1.9"}
|
||||
configs[SdDummyExporter] = Config{list.GcRegistry, "sd-dummy-exporter", "v0.2.0"}
|
||||
configs[VolumeNFSServer] = Config{list.PromoterE2eRegistry, "volume/nfs", "1.2"}
|
||||
configs[VolumeISCSIServer] = Config{list.PromoterE2eRegistry, "volume/iscsi", "2.2"}
|
||||
configs[VolumeGlusterServer] = Config{list.PromoterE2eRegistry, "volume/gluster", "1.2"}
|
||||
configs[VolumeRBDServer] = Config{list.PromoterE2eRegistry, "volume/rbd", "1.0.3"}
|
||||
configs[WindowsServer] = Config{list.MicrosoftRegistry, "windows", "1809"}
|
||||
|
||||
// if requested, map all the SHAs into a known format based on the input
|
||||
originalImageConfigs := configs
|
||||
@ -306,7 +297,7 @@ func getRepositoryMappedConfig(index int, config Config, repo string) Config {
|
||||
|
||||
h := sha256.New()
|
||||
h.Write([]byte(pullSpec))
|
||||
hash := base64.RawURLEncoding.EncodeToString(h.Sum(nil)[:16])
|
||||
hash := base64.RawURLEncoding.EncodeToString(h.Sum(nil))[:16]
|
||||
|
||||
shortName := reCharSafe.ReplaceAllLiteralString(pullSpec, "-")
|
||||
shortName = reDashes.ReplaceAllLiteralString(shortName, "-")
|
||||
@ -358,8 +349,15 @@ func GetPauseImageName() string {
|
||||
return GetE2EImage(Pause)
|
||||
}
|
||||
|
||||
// ReplaceRegistryInImageURL replaces the registry in the image URL with a custom one
|
||||
// ReplaceRegistryInImageURL replaces the registry in the image URL with a custom one based
|
||||
// on the configured registries.
|
||||
func ReplaceRegistryInImageURL(imageURL string) (string, error) {
|
||||
return replaceRegistryInImageURLWithList(imageURL, registry)
|
||||
}
|
||||
|
||||
// replaceRegistryInImageURLWithList replaces the registry in the image URL with a custom one based
|
||||
// on the given registry list.
|
||||
func replaceRegistryInImageURLWithList(imageURL string, reg RegistryList) (string, error) {
|
||||
parts := strings.Split(imageURL, "/")
|
||||
countParts := len(parts)
|
||||
registryAndUser := strings.Join(parts[:countParts-1], "/")
|
||||
@ -373,6 +371,9 @@ func ReplaceRegistryInImageURL(imageURL string) (string, error) {
|
||||
}
|
||||
}
|
||||
last := strings.SplitN(parts[countParts-1], ":", 2)
|
||||
if len(last) == 1 {
|
||||
return "", fmt.Errorf("image %q is required to be in an image:tag format", imageURL)
|
||||
}
|
||||
config := getRepositoryMappedConfig(index, Config{
|
||||
registry: parts[0],
|
||||
name: strings.Join([]string{strings.Join(parts[1:countParts-1], "/"), last[0]}, "/"),
|
||||
@ -382,25 +383,37 @@ func ReplaceRegistryInImageURL(imageURL string) (string, error) {
|
||||
}
|
||||
|
||||
switch registryAndUser {
|
||||
case "gcr.io/kubernetes-e2e-test-images":
|
||||
registryAndUser = e2eRegistry
|
||||
case "k8s.gcr.io":
|
||||
registryAndUser = gcRegistry
|
||||
case "k8s.gcr.io/sig-storage":
|
||||
registryAndUser = sigStorageRegistry
|
||||
case "gcr.io/k8s-authenticated-test":
|
||||
registryAndUser = PrivateRegistry
|
||||
case "gcr.io/google-samples":
|
||||
registryAndUser = sampleRegistry
|
||||
case "gcr.io/gke-release":
|
||||
registryAndUser = gcrReleaseRegistry
|
||||
case "docker.io/library":
|
||||
registryAndUser = dockerLibraryRegistry
|
||||
case initRegistry.E2eRegistry:
|
||||
registryAndUser = reg.E2eRegistry
|
||||
case initRegistry.GcRegistry:
|
||||
registryAndUser = reg.GcRegistry
|
||||
case initRegistry.SigStorageRegistry:
|
||||
registryAndUser = reg.SigStorageRegistry
|
||||
case initRegistry.PrivateRegistry:
|
||||
registryAndUser = reg.PrivateRegistry
|
||||
case initRegistry.SampleRegistry:
|
||||
registryAndUser = reg.SampleRegistry
|
||||
case initRegistry.GcrReleaseRegistry:
|
||||
registryAndUser = reg.GcrReleaseRegistry
|
||||
case initRegistry.InvalidRegistry:
|
||||
registryAndUser = reg.InvalidRegistry
|
||||
case initRegistry.MicrosoftRegistry:
|
||||
registryAndUser = reg.MicrosoftRegistry
|
||||
case initRegistry.PromoterE2eRegistry:
|
||||
registryAndUser = reg.PromoterE2eRegistry
|
||||
case initRegistry.BuildImageRegistry:
|
||||
registryAndUser = reg.BuildImageRegistry
|
||||
case initRegistry.GcAuthenticatedRegistry:
|
||||
registryAndUser = reg.GcAuthenticatedRegistry
|
||||
case initRegistry.DockerLibraryRegistry:
|
||||
registryAndUser = reg.DockerLibraryRegistry
|
||||
case initRegistry.CloudProviderGcpRegistry:
|
||||
registryAndUser = reg.CloudProviderGcpRegistry
|
||||
default:
|
||||
if countParts == 1 {
|
||||
// We assume we found an image from docker hub library
|
||||
// e.g. openjdk -> docker.io/library/openjdk
|
||||
registryAndUser = dockerLibraryRegistry
|
||||
registryAndUser = reg.DockerLibraryRegistry
|
||||
break
|
||||
}
|
||||
|
||||
|
7
vendor/k8s.io/kubernetes/test/utils/pki_helpers.go
generated
vendored
7
vendor/k8s.io/kubernetes/test/utils/pki_helpers.go
generated
vendored
@ -23,12 +23,11 @@ import (
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
)
|
||||
|
||||
@ -59,10 +58,10 @@ func NewSignedCert(cfg *certutil.Config, key crypto.Signer, caCert *x509.Certifi
|
||||
return nil, err
|
||||
}
|
||||
if len(cfg.CommonName) == 0 {
|
||||
return nil, errors.New("must specify a CommonName")
|
||||
return nil, fmt.Errorf("must specify a CommonName")
|
||||
}
|
||||
if len(cfg.Usages) == 0 {
|
||||
return nil, errors.New("must specify at least one ExtKeyUsage")
|
||||
return nil, fmt.Errorf("must specify at least one ExtKeyUsage")
|
||||
}
|
||||
|
||||
certTmpl := x509.Certificate{
|
||||
|
57
vendor/k8s.io/kubernetes/test/utils/runners.go
generated
vendored
57
vendor/k8s.io/kubernetes/test/utils/runners.go
generated
vendored
@ -80,7 +80,7 @@ func WaitUntilPodIsScheduled(c clientset.Interface, name, namespace string, time
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("Timed out after %v when waiting for pod %v/%v to start.", timeout, namespace, name)
|
||||
return nil, fmt.Errorf("timed out after %v when waiting for pod %v/%v to start", timeout, namespace, name)
|
||||
}
|
||||
|
||||
func RunPodAndGetNodeName(c clientset.Interface, pod *v1.Pod, timeout time.Duration) (string, error) {
|
||||
@ -357,7 +357,7 @@ func (config *DeploymentConfig) create() error {
|
||||
config.applyTo(&deployment.Spec.Template)
|
||||
|
||||
if err := CreateDeploymentWithRetries(config.Client, config.Namespace, deployment); err != nil {
|
||||
return fmt.Errorf("Error creating deployment: %v", err)
|
||||
return fmt.Errorf("error creating deployment: %v", err)
|
||||
}
|
||||
config.RCConfigLog("Created deployment with name: %v, namespace: %v, replica count: %v", deployment.Name, config.Namespace, removePtr(deployment.Spec.Replicas))
|
||||
return nil
|
||||
@ -435,7 +435,7 @@ func (config *ReplicaSetConfig) create() error {
|
||||
config.applyTo(&rs.Spec.Template)
|
||||
|
||||
if err := CreateReplicaSetWithRetries(config.Client, config.Namespace, rs); err != nil {
|
||||
return fmt.Errorf("Error creating replica set: %v", err)
|
||||
return fmt.Errorf("error creating replica set: %v", err)
|
||||
}
|
||||
config.RCConfigLog("Created replica set with name: %v, namespace: %v, replica count: %v", rs.Name, config.Namespace, removePtr(rs.Spec.Replicas))
|
||||
return nil
|
||||
@ -509,7 +509,7 @@ func (config *JobConfig) create() error {
|
||||
config.applyTo(&job.Spec.Template)
|
||||
|
||||
if err := CreateJobWithRetries(config.Client, config.Namespace, job); err != nil {
|
||||
return fmt.Errorf("Error creating job: %v", err)
|
||||
return fmt.Errorf("error creating job: %v", err)
|
||||
}
|
||||
config.RCConfigLog("Created job with name: %v, namespace: %v, parallelism/completions: %v", job.Name, config.Namespace, job.Spec.Parallelism)
|
||||
return nil
|
||||
@ -628,7 +628,7 @@ func (config *RCConfig) create() error {
|
||||
config.applyTo(rc.Spec.Template)
|
||||
|
||||
if err := CreateRCWithRetries(config.Client, config.Namespace, rc); err != nil {
|
||||
return fmt.Errorf("Error creating replication controller: %v", err)
|
||||
return fmt.Errorf("error creating replication controller: %v", err)
|
||||
}
|
||||
config.RCConfigLog("Created replication controller with name: %v, namespace: %v, replica count: %v", rc.Name, config.Namespace, removePtr(rc.Spec.Replicas))
|
||||
return nil
|
||||
@ -850,7 +850,7 @@ func (config *RCConfig) start() error {
|
||||
} else {
|
||||
config.RCConfigLog("Can't list pod debug info: %v", err)
|
||||
}
|
||||
return fmt.Errorf("Only %d pods started out of %d", oldRunning, config.Replicas)
|
||||
return fmt.Errorf("only %d pods started out of %d", oldRunning, config.Replicas)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -880,7 +880,7 @@ func StartPods(c clientset.Interface, replicas int, namespace string, podNamePre
|
||||
label := labels.SelectorFromSet(labels.Set(map[string]string{"startPodsID": startPodsID}))
|
||||
err := WaitForPodsWithLabelRunning(c, namespace, label)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %d pods to be running - probably a timeout: %v", replicas, err)
|
||||
return fmt.Errorf("error waiting for %d pods to be running - probably a timeout: %v", replicas, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -920,7 +920,7 @@ func WaitForEnoughPodsWithLabelRunning(c clientset.Interface, ns string, label l
|
||||
break
|
||||
}
|
||||
if !running {
|
||||
return fmt.Errorf("Timeout while waiting for pods with labels %q to be running", label.String())
|
||||
return fmt.Errorf("timeout while waiting for pods with labels %q to be running", label.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -1194,12 +1194,12 @@ func DoPrepareNode(client clientset.Interface, node *v1.Node, strategy PrepareNo
|
||||
break
|
||||
}
|
||||
if !apierrors.IsConflict(err) {
|
||||
return fmt.Errorf("Error while applying patch %v to Node %v: %v", string(patch), node.Name, err)
|
||||
return fmt.Errorf("error while applying patch %v to Node %v: %v", string(patch), node.Name, err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("Too many conflicts when applying patch %v to Node %v: %s", string(patch), node.Name, err)
|
||||
return fmt.Errorf("too many conflicts when applying patch %v to Node %v: %s", string(patch), node.Name, err)
|
||||
}
|
||||
|
||||
for attempt := 0; attempt < retries; attempt++ {
|
||||
@ -1207,12 +1207,12 @@ func DoPrepareNode(client clientset.Interface, node *v1.Node, strategy PrepareNo
|
||||
break
|
||||
}
|
||||
if !apierrors.IsConflict(err) {
|
||||
return fmt.Errorf("Error while preparing objects for node %s: %s", node.Name, err)
|
||||
return fmt.Errorf("error while preparing objects for node %s: %s", node.Name, err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("Too many conflicts when creating objects for node %s: %s", node.Name, err)
|
||||
return fmt.Errorf("too many conflicts when creating objects for node %s: %s", node.Name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -1220,9 +1220,10 @@ func DoPrepareNode(client clientset.Interface, node *v1.Node, strategy PrepareNo
|
||||
func DoCleanupNode(client clientset.Interface, nodeName string, strategy PrepareNodeStrategy) error {
|
||||
var err error
|
||||
for attempt := 0; attempt < retries; attempt++ {
|
||||
node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
|
||||
var node *v1.Node
|
||||
node, err = client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Skipping cleanup of Node: failed to get Node %v: %v", nodeName, err)
|
||||
return fmt.Errorf("skipping cleanup of Node: failed to get Node %v: %v", nodeName, err)
|
||||
}
|
||||
updatedNode := strategy.CleanupNode(node)
|
||||
if apiequality.Semantic.DeepEqual(node, updatedNode) {
|
||||
@ -1232,12 +1233,12 @@ func DoCleanupNode(client clientset.Interface, nodeName string, strategy Prepare
|
||||
break
|
||||
}
|
||||
if !apierrors.IsConflict(err) {
|
||||
return fmt.Errorf("Error when updating Node %v: %v", nodeName, err)
|
||||
return fmt.Errorf("error when updating Node %v: %v", nodeName, err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("Too many conflicts when trying to cleanup Node %v: %s", nodeName, err)
|
||||
return fmt.Errorf("too many conflicts when trying to cleanup Node %v: %s", nodeName, err)
|
||||
}
|
||||
|
||||
for attempt := 0; attempt < retries; attempt++ {
|
||||
@ -1246,12 +1247,12 @@ func DoCleanupNode(client clientset.Interface, nodeName string, strategy Prepare
|
||||
break
|
||||
}
|
||||
if !apierrors.IsConflict(err) {
|
||||
return fmt.Errorf("Error when cleaning up Node %v objects: %v", nodeName, err)
|
||||
return fmt.Errorf("error when cleaning up Node %v objects: %v", nodeName, err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("Too many conflicts when trying to cleanup Node %v objects: %s", nodeName, err)
|
||||
return fmt.Errorf("too many conflicts when trying to cleanup Node %v objects: %s", nodeName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -1303,7 +1304,7 @@ func MakePodSpec() v1.PodSpec {
|
||||
return v1.PodSpec{
|
||||
Containers: []v1.Container{{
|
||||
Name: "pause",
|
||||
Image: "k8s.gcr.io/pause:3.4.1",
|
||||
Image: "k8s.gcr.io/pause:3.5",
|
||||
Ports: []v1.ContainerPort{{ContainerPort: 80}},
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
@ -1321,7 +1322,7 @@ func MakePodSpec() v1.PodSpec {
|
||||
|
||||
func makeCreatePod(client clientset.Interface, namespace string, podTemplate *v1.Pod) error {
|
||||
if err := CreatePodWithRetries(client, namespace, podTemplate); err != nil {
|
||||
return fmt.Errorf("Error creating pod: %v", err)
|
||||
return fmt.Errorf("error creating pod: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -1450,7 +1451,7 @@ func createController(client clientset.Interface, controllerName, namespace stri
|
||||
},
|
||||
}
|
||||
if err := CreateRCWithRetries(client, namespace, rc); err != nil {
|
||||
return fmt.Errorf("Error creating replication controller: %v", err)
|
||||
return fmt.Errorf("error creating replication controller: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -1557,7 +1558,7 @@ func (config *SecretConfig) Run() error {
|
||||
}
|
||||
|
||||
if err := CreateSecretWithRetries(config.Client, config.Namespace, secret); err != nil {
|
||||
return fmt.Errorf("Error creating secret: %v", err)
|
||||
return fmt.Errorf("error creating secret: %v", err)
|
||||
}
|
||||
config.LogFunc("Created secret %v/%v", config.Namespace, config.Name)
|
||||
return nil
|
||||
@ -1565,7 +1566,7 @@ func (config *SecretConfig) Run() error {
|
||||
|
||||
func (config *SecretConfig) Stop() error {
|
||||
if err := DeleteResourceWithRetries(config.Client, api.Kind("Secret"), config.Namespace, config.Name, metav1.DeleteOptions{}); err != nil {
|
||||
return fmt.Errorf("Error deleting secret: %v", err)
|
||||
return fmt.Errorf("error deleting secret: %v", err)
|
||||
}
|
||||
config.LogFunc("Deleted secret %v/%v", config.Namespace, config.Name)
|
||||
return nil
|
||||
@ -1615,7 +1616,7 @@ func (config *ConfigMapConfig) Run() error {
|
||||
}
|
||||
|
||||
if err := CreateConfigMapWithRetries(config.Client, config.Namespace, configMap); err != nil {
|
||||
return fmt.Errorf("Error creating configmap: %v", err)
|
||||
return fmt.Errorf("error creating configmap: %v", err)
|
||||
}
|
||||
config.LogFunc("Created configmap %v/%v", config.Namespace, config.Name)
|
||||
return nil
|
||||
@ -1623,7 +1624,7 @@ func (config *ConfigMapConfig) Run() error {
|
||||
|
||||
func (config *ConfigMapConfig) Stop() error {
|
||||
if err := DeleteResourceWithRetries(config.Client, api.Kind("ConfigMap"), config.Namespace, config.Name, metav1.DeleteOptions{}); err != nil {
|
||||
return fmt.Errorf("Error deleting configmap: %v", err)
|
||||
return fmt.Errorf("error deleting configmap: %v", err)
|
||||
}
|
||||
config.LogFunc("Deleted configmap %v/%v", config.Namespace, config.Name)
|
||||
return nil
|
||||
@ -1725,7 +1726,7 @@ type DaemonConfig struct {
|
||||
|
||||
func (config *DaemonConfig) Run() error {
|
||||
if config.Image == "" {
|
||||
config.Image = "k8s.gcr.io/pause:3.4.1"
|
||||
config.Image = "k8s.gcr.io/pause:3.5"
|
||||
}
|
||||
nameLabel := map[string]string{
|
||||
"name": config.Name + "-daemon",
|
||||
@ -1752,7 +1753,7 @@ func (config *DaemonConfig) Run() error {
|
||||
}
|
||||
|
||||
if err := CreateDaemonSetWithRetries(config.Client, config.Namespace, daemon); err != nil {
|
||||
return fmt.Errorf("Error creating daemonset: %v", err)
|
||||
return fmt.Errorf("error creating daemonset: %v", err)
|
||||
}
|
||||
|
||||
var nodes *v1.NodeList
|
||||
@ -1763,7 +1764,7 @@ func (config *DaemonConfig) Run() error {
|
||||
if err == nil {
|
||||
break
|
||||
} else if i+1 == retries {
|
||||
return fmt.Errorf("Error listing Nodes while waiting for DaemonSet %v: %v", config.Name, err)
|
||||
return fmt.Errorf("error listing Nodes while waiting for DaemonSet %v: %v", config.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
2
vendor/k8s.io/kubernetes/test/utils/update_resources.go
generated
vendored
2
vendor/k8s.io/kubernetes/test/utils/update_resources.go
generated
vendored
@ -55,7 +55,7 @@ func ScaleResourceWithRetries(scalesGetter scaleclient.ScalesGetter, namespace,
|
||||
err = scale.WaitForScaleHasDesiredReplicas(scalesGetter, gvr.GroupResource(), name, namespace, size, waitForReplicas)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error while scaling %s to %d replicas: %v", name, size, err)
|
||||
return fmt.Errorf("error while scaling %s to %d replicas: %v", name, size, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user