Merge pull request #119026 from AxeZhan/sleepAction

Introducing Sleep Action for PreStop Hook
This commit is contained in:
Kubernetes Prow Robot 2023-10-16 21:19:44 +02:00 committed by GitHub
commit f6ba25fdbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
81 changed files with 2331 additions and 994 deletions

View File

@ -7006,6 +7006,10 @@
"$ref": "#/definitions/io.k8s.api.core.v1.HTTPGetAction", "$ref": "#/definitions/io.k8s.api.core.v1.HTTPGetAction",
"description": "HTTPGet specifies the http request to perform." "description": "HTTPGet specifies the http request to perform."
}, },
"sleep": {
"$ref": "#/definitions/io.k8s.api.core.v1.SleepAction",
"description": "Sleep represents the duration that the container should sleep before being terminated."
},
"tcpSocket": { "tcpSocket": {
"$ref": "#/definitions/io.k8s.api.core.v1.TCPSocketAction", "$ref": "#/definitions/io.k8s.api.core.v1.TCPSocketAction",
"description": "Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified." "description": "Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified."
@ -10435,6 +10439,20 @@
}, },
"type": "object" "type": "object"
}, },
"io.k8s.api.core.v1.SleepAction": {
"description": "SleepAction describes a \"sleep\" action.",
"properties": {
"seconds": {
"description": "Seconds is the number of seconds to sleep.",
"format": "int64",
"type": "integer"
}
},
"required": [
"seconds"
],
"type": "object"
},
"io.k8s.api.core.v1.StorageOSPersistentVolumeSource": { "io.k8s.api.core.v1.StorageOSPersistentVolumeSource": {
"description": "Represents a StorageOS persistent volume resource.", "description": "Represents a StorageOS persistent volume resource.",
"properties": { "properties": {

View File

@ -2901,6 +2901,14 @@
], ],
"description": "HTTPGet specifies the http request to perform." "description": "HTTPGet specifies the http request to perform."
}, },
"sleep": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SleepAction"
}
],
"description": "Sleep represents the duration that the container should sleep before being terminated."
},
"tcpSocket": { "tcpSocket": {
"allOf": [ "allOf": [
{ {
@ -7357,6 +7365,21 @@
}, },
"type": "object" "type": "object"
}, },
"io.k8s.api.core.v1.SleepAction": {
"description": "SleepAction describes a \"sleep\" action.",
"properties": {
"seconds": {
"default": 0,
"description": "Seconds is the number of seconds to sleep.",
"format": "int64",
"type": "integer"
}
},
"required": [
"seconds"
],
"type": "object"
},
"io.k8s.api.core.v1.StorageOSPersistentVolumeSource": { "io.k8s.api.core.v1.StorageOSPersistentVolumeSource": {
"description": "Represents a StorageOS persistent volume resource.", "description": "Represents a StorageOS persistent volume resource.",
"properties": { "properties": {

View File

@ -2760,6 +2760,14 @@
], ],
"description": "HTTPGet specifies the http request to perform." "description": "HTTPGet specifies the http request to perform."
}, },
"sleep": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SleepAction"
}
],
"description": "Sleep represents the duration that the container should sleep before being terminated."
},
"tcpSocket": { "tcpSocket": {
"allOf": [ "allOf": [
{ {
@ -4438,6 +4446,21 @@
], ],
"type": "object" "type": "object"
}, },
"io.k8s.api.core.v1.SleepAction": {
"description": "SleepAction describes a \"sleep\" action.",
"properties": {
"seconds": {
"default": 0,
"description": "Seconds is the number of seconds to sleep.",
"format": "int64",
"type": "integer"
}
},
"required": [
"seconds"
],
"type": "object"
},
"io.k8s.api.core.v1.StorageOSVolumeSource": { "io.k8s.api.core.v1.StorageOSVolumeSource": {
"description": "Represents a StorageOS persistent volume resource.", "description": "Represents a StorageOS persistent volume resource.",
"properties": { "properties": {

View File

@ -2073,6 +2073,14 @@
], ],
"description": "HTTPGet specifies the http request to perform." "description": "HTTPGet specifies the http request to perform."
}, },
"sleep": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SleepAction"
}
],
"description": "Sleep represents the duration that the container should sleep before being terminated."
},
"tcpSocket": { "tcpSocket": {
"allOf": [ "allOf": [
{ {
@ -3629,6 +3637,21 @@
], ],
"type": "object" "type": "object"
}, },
"io.k8s.api.core.v1.SleepAction": {
"description": "SleepAction describes a \"sleep\" action.",
"properties": {
"seconds": {
"default": 0,
"description": "Seconds is the number of seconds to sleep.",
"format": "int64",
"type": "integer"
}
},
"required": [
"seconds"
],
"type": "object"
},
"io.k8s.api.core.v1.StorageOSVolumeSource": { "io.k8s.api.core.v1.StorageOSVolumeSource": {
"description": "Represents a StorageOS persistent volume resource.", "description": "Represents a StorageOS persistent volume resource.",
"properties": { "properties": {

View File

@ -558,6 +558,64 @@ func dropDisabledFields(
} }
// For other types of containers, validateContainers will handle them. // For other types of containers, validateContainers will handle them.
} }
if !utilfeature.DefaultFeatureGate.Enabled(features.PodLifecycleSleepAction) && !podLifecycleSleepActionInUse(oldPodSpec) {
for i := range podSpec.Containers {
if podSpec.Containers[i].Lifecycle == nil {
continue
}
if podSpec.Containers[i].Lifecycle.PreStop != nil {
podSpec.Containers[i].Lifecycle.PreStop.Sleep = nil
}
if podSpec.Containers[i].Lifecycle.PostStart != nil {
podSpec.Containers[i].Lifecycle.PostStart.Sleep = nil
}
}
for i := range podSpec.InitContainers {
if podSpec.InitContainers[i].Lifecycle == nil {
continue
}
if podSpec.InitContainers[i].Lifecycle.PreStop != nil {
podSpec.InitContainers[i].Lifecycle.PreStop.Sleep = nil
}
if podSpec.InitContainers[i].Lifecycle.PostStart != nil {
podSpec.InitContainers[i].Lifecycle.PostStart.Sleep = nil
}
}
for i := range podSpec.EphemeralContainers {
if podSpec.EphemeralContainers[i].Lifecycle == nil {
continue
}
if podSpec.EphemeralContainers[i].Lifecycle.PreStop != nil {
podSpec.EphemeralContainers[i].Lifecycle.PreStop.Sleep = nil
}
if podSpec.EphemeralContainers[i].Lifecycle.PostStart != nil {
podSpec.EphemeralContainers[i].Lifecycle.PostStart.Sleep = nil
}
}
}
}
func podLifecycleSleepActionInUse(podSpec *api.PodSpec) bool {
if podSpec == nil {
return false
}
var inUse bool
VisitContainers(podSpec, AllContainers, func(c *api.Container, containerType ContainerType) bool {
if c.Lifecycle == nil {
return true
}
if c.Lifecycle.PreStop != nil && c.Lifecycle.PreStop.Sleep != nil {
inUse = true
return false
}
if c.Lifecycle.PostStart != nil && c.Lifecycle.PostStart.Sleep != nil {
inUse = true
return false
}
return true
})
return inUse
} }
// dropDisabledPodStatusFields removes disabled fields from the pod status // dropDisabledPodStatusFields removes disabled fields from the pod status

View File

@ -2150,6 +2150,12 @@ type ExecAction struct {
Command []string Command []string
} }
// SleepAction describes a "sleep" action.
type SleepAction struct {
// Seconds is the number of seconds to sleep.
Seconds int64
}
// Probe describes a health check to be performed against a container to determine whether it is // Probe describes a health check to be performed against a container to determine whether it is
// alive or ready to receive traffic. // alive or ready to receive traffic.
type Probe struct { type Probe struct {
@ -2432,6 +2438,10 @@ type LifecycleHandler struct {
// lifecycle hooks will fail in runtime when tcp handler is specified. // lifecycle hooks will fail in runtime when tcp handler is specified.
// +optional // +optional
TCPSocket *TCPSocketAction TCPSocket *TCPSocketAction
// Sleep represents the duration that the container should sleep before being terminated.
// +featureGate=PodLifecycleSleepAction
// +optional
Sleep *SleepAction
} }
type GRPCAction struct { type GRPCAction struct {

View File

@ -1937,6 +1937,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*v1.SleepAction)(nil), (*core.SleepAction)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_SleepAction_To_core_SleepAction(a.(*v1.SleepAction), b.(*core.SleepAction), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*core.SleepAction)(nil), (*v1.SleepAction)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_core_SleepAction_To_v1_SleepAction(a.(*core.SleepAction), b.(*v1.SleepAction), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1.StorageOSPersistentVolumeSource)(nil), (*core.StorageOSPersistentVolumeSource)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*v1.StorageOSPersistentVolumeSource)(nil), (*core.StorageOSPersistentVolumeSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_StorageOSPersistentVolumeSource_To_core_StorageOSPersistentVolumeSource(a.(*v1.StorageOSPersistentVolumeSource), b.(*core.StorageOSPersistentVolumeSource), scope) return Convert_v1_StorageOSPersistentVolumeSource_To_core_StorageOSPersistentVolumeSource(a.(*v1.StorageOSPersistentVolumeSource), b.(*core.StorageOSPersistentVolumeSource), scope)
}); err != nil { }); err != nil {
@ -4325,6 +4335,7 @@ func autoConvert_v1_LifecycleHandler_To_core_LifecycleHandler(in *v1.LifecycleHa
out.Exec = (*core.ExecAction)(unsafe.Pointer(in.Exec)) out.Exec = (*core.ExecAction)(unsafe.Pointer(in.Exec))
out.HTTPGet = (*core.HTTPGetAction)(unsafe.Pointer(in.HTTPGet)) out.HTTPGet = (*core.HTTPGetAction)(unsafe.Pointer(in.HTTPGet))
out.TCPSocket = (*core.TCPSocketAction)(unsafe.Pointer(in.TCPSocket)) out.TCPSocket = (*core.TCPSocketAction)(unsafe.Pointer(in.TCPSocket))
out.Sleep = (*core.SleepAction)(unsafe.Pointer(in.Sleep))
return nil return nil
} }
@ -4337,6 +4348,7 @@ func autoConvert_core_LifecycleHandler_To_v1_LifecycleHandler(in *core.Lifecycle
out.Exec = (*v1.ExecAction)(unsafe.Pointer(in.Exec)) out.Exec = (*v1.ExecAction)(unsafe.Pointer(in.Exec))
out.HTTPGet = (*v1.HTTPGetAction)(unsafe.Pointer(in.HTTPGet)) out.HTTPGet = (*v1.HTTPGetAction)(unsafe.Pointer(in.HTTPGet))
out.TCPSocket = (*v1.TCPSocketAction)(unsafe.Pointer(in.TCPSocket)) out.TCPSocket = (*v1.TCPSocketAction)(unsafe.Pointer(in.TCPSocket))
out.Sleep = (*v1.SleepAction)(unsafe.Pointer(in.Sleep))
return nil return nil
} }
@ -8067,6 +8079,26 @@ func Convert_core_SessionAffinityConfig_To_v1_SessionAffinityConfig(in *core.Ses
return autoConvert_core_SessionAffinityConfig_To_v1_SessionAffinityConfig(in, out, s) return autoConvert_core_SessionAffinityConfig_To_v1_SessionAffinityConfig(in, out, s)
} }
func autoConvert_v1_SleepAction_To_core_SleepAction(in *v1.SleepAction, out *core.SleepAction, s conversion.Scope) error {
out.Seconds = in.Seconds
return nil
}
// Convert_v1_SleepAction_To_core_SleepAction is an autogenerated conversion function.
func Convert_v1_SleepAction_To_core_SleepAction(in *v1.SleepAction, out *core.SleepAction, s conversion.Scope) error {
return autoConvert_v1_SleepAction_To_core_SleepAction(in, out, s)
}
func autoConvert_core_SleepAction_To_v1_SleepAction(in *core.SleepAction, out *v1.SleepAction, s conversion.Scope) error {
out.Seconds = in.Seconds
return nil
}
// Convert_core_SleepAction_To_v1_SleepAction is an autogenerated conversion function.
func Convert_core_SleepAction_To_v1_SleepAction(in *core.SleepAction, out *v1.SleepAction, s conversion.Scope) error {
return autoConvert_core_SleepAction_To_v1_SleepAction(in, out, s)
}
func autoConvert_v1_StorageOSPersistentVolumeSource_To_core_StorageOSPersistentVolumeSource(in *v1.StorageOSPersistentVolumeSource, out *core.StorageOSPersistentVolumeSource, s conversion.Scope) error { func autoConvert_v1_StorageOSPersistentVolumeSource_To_core_StorageOSPersistentVolumeSource(in *v1.StorageOSPersistentVolumeSource, out *core.StorageOSPersistentVolumeSource, s conversion.Scope) error {
out.VolumeName = in.VolumeName out.VolumeName = in.VolumeName
out.VolumeNamespace = in.VolumeNamespace out.VolumeNamespace = in.VolumeNamespace

View File

@ -2886,52 +2886,52 @@ func validatePodResourceClaimSource(claimSource core.ClaimSource, fldPath *field
return allErrs return allErrs
} }
func validateLivenessProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList { func validateLivenessProbe(probe *core.Probe, gracePeriod int64, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if probe == nil { if probe == nil {
return allErrs return allErrs
} }
allErrs = append(allErrs, validateProbe(probe, fldPath)...) allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath)...)
if probe.SuccessThreshold != 1 { if probe.SuccessThreshold != 1 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("successThreshold"), probe.SuccessThreshold, "must be 1")) allErrs = append(allErrs, field.Invalid(fldPath.Child("successThreshold"), probe.SuccessThreshold, "must be 1"))
} }
return allErrs return allErrs
} }
func validateReadinessProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList { func validateReadinessProbe(probe *core.Probe, gracePeriod int64, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if probe == nil { if probe == nil {
return allErrs return allErrs
} }
allErrs = append(allErrs, validateProbe(probe, fldPath)...) allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath)...)
if probe.TerminationGracePeriodSeconds != nil { if probe.TerminationGracePeriodSeconds != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("terminationGracePeriodSeconds"), probe.TerminationGracePeriodSeconds, "must not be set for readinessProbes")) allErrs = append(allErrs, field.Invalid(fldPath.Child("terminationGracePeriodSeconds"), probe.TerminationGracePeriodSeconds, "must not be set for readinessProbes"))
} }
return allErrs return allErrs
} }
func validateStartupProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList { func validateStartupProbe(probe *core.Probe, gracePeriod int64, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if probe == nil { if probe == nil {
return allErrs return allErrs
} }
allErrs = append(allErrs, validateProbe(probe, fldPath)...) allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath)...)
if probe.SuccessThreshold != 1 { if probe.SuccessThreshold != 1 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("successThreshold"), probe.SuccessThreshold, "must be 1")) allErrs = append(allErrs, field.Invalid(fldPath.Child("successThreshold"), probe.SuccessThreshold, "must be 1"))
} }
return allErrs return allErrs
} }
func validateProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList { func validateProbe(probe *core.Probe, gracePeriod int64, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if probe == nil { if probe == nil {
return allErrs return allErrs
} }
allErrs = append(allErrs, validateHandler(handlerFromProbe(&probe.ProbeHandler), fldPath)...) allErrs = append(allErrs, validateHandler(handlerFromProbe(&probe.ProbeHandler), gracePeriod, fldPath)...)
allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.InitialDelaySeconds), fldPath.Child("initialDelaySeconds"))...) allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.InitialDelaySeconds), fldPath.Child("initialDelaySeconds"))...)
allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.TimeoutSeconds), fldPath.Child("timeoutSeconds"))...) allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.TimeoutSeconds), fldPath.Child("timeoutSeconds"))...)
@ -2966,6 +2966,7 @@ type commonHandler struct {
HTTPGet *core.HTTPGetAction HTTPGet *core.HTTPGetAction
TCPSocket *core.TCPSocketAction TCPSocket *core.TCPSocketAction
GRPC *core.GRPCAction GRPC *core.GRPCAction
Sleep *core.SleepAction
} }
func handlerFromProbe(ph *core.ProbeHandler) commonHandler { func handlerFromProbe(ph *core.ProbeHandler) commonHandler {
@ -2982,9 +2983,19 @@ func handlerFromLifecycle(lh *core.LifecycleHandler) commonHandler {
Exec: lh.Exec, Exec: lh.Exec,
HTTPGet: lh.HTTPGet, HTTPGet: lh.HTTPGet,
TCPSocket: lh.TCPSocket, TCPSocket: lh.TCPSocket,
Sleep: lh.Sleep,
} }
} }
func validateSleepAction(sleep *core.SleepAction, gracePeriod int64, fldPath *field.Path) field.ErrorList {
allErrors := field.ErrorList{}
if sleep.Seconds <= 0 || sleep.Seconds > gracePeriod {
invalidStr := fmt.Sprintf("must be greater than 0 and less than terminationGracePeriodSeconds (%d)", gracePeriod)
allErrors = append(allErrors, field.Invalid(fldPath, sleep.Seconds, invalidStr))
}
return allErrors
}
func validateClientIPAffinityConfig(config *core.SessionAffinityConfig, fldPath *field.Path) field.ErrorList { func validateClientIPAffinityConfig(config *core.SessionAffinityConfig, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if config == nil { if config == nil {
@ -3093,7 +3104,7 @@ func validateTCPSocketAction(tcp *core.TCPSocketAction, fldPath *field.Path) fie
func validateGRPCAction(grpc *core.GRPCAction, fldPath *field.Path) field.ErrorList { func validateGRPCAction(grpc *core.GRPCAction, fldPath *field.Path) field.ErrorList {
return ValidatePortNumOrName(intstr.FromInt32(grpc.Port), fldPath.Child("port")) return ValidatePortNumOrName(intstr.FromInt32(grpc.Port), fldPath.Child("port"))
} }
func validateHandler(handler commonHandler, fldPath *field.Path) field.ErrorList { func validateHandler(handler commonHandler, gracePeriod int64, fldPath *field.Path) field.ErrorList {
numHandlers := 0 numHandlers := 0
allErrors := field.ErrorList{} allErrors := field.ErrorList{}
if handler.Exec != nil { if handler.Exec != nil {
@ -3128,19 +3139,27 @@ func validateHandler(handler commonHandler, fldPath *field.Path) field.ErrorList
allErrors = append(allErrors, validateGRPCAction(handler.GRPC, fldPath.Child("grpc"))...) allErrors = append(allErrors, validateGRPCAction(handler.GRPC, fldPath.Child("grpc"))...)
} }
} }
if handler.Sleep != nil {
if numHandlers > 0 {
allErrors = append(allErrors, field.Forbidden(fldPath.Child("sleep"), "may not specify more than 1 handler type"))
} else {
numHandlers++
allErrors = append(allErrors, validateSleepAction(handler.Sleep, gracePeriod, fldPath.Child("sleep"))...)
}
}
if numHandlers == 0 { if numHandlers == 0 {
allErrors = append(allErrors, field.Required(fldPath, "must specify a handler type")) allErrors = append(allErrors, field.Required(fldPath, "must specify a handler type"))
} }
return allErrors return allErrors
} }
func validateLifecycle(lifecycle *core.Lifecycle, fldPath *field.Path) field.ErrorList { func validateLifecycle(lifecycle *core.Lifecycle, gracePeriod int64, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if lifecycle.PostStart != nil { if lifecycle.PostStart != nil {
allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PostStart), fldPath.Child("postStart"))...) allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PostStart), gracePeriod, fldPath.Child("postStart"))...)
} }
if lifecycle.PreStop != nil { if lifecycle.PreStop != nil {
allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PreStop), fldPath.Child("preStop"))...) allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PreStop), gracePeriod, fldPath.Child("preStop"))...)
} }
return allErrs return allErrs
} }
@ -3282,7 +3301,7 @@ func validateFieldAllowList(value interface{}, allowedFields map[string]bool, er
} }
// validateInitContainers is called by pod spec and template validation to validate the list of init containers // validateInitContainers is called by pod spec and template validation to validate the list of init containers
func validateInitContainers(containers []core.Container, regularContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.String, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy) field.ErrorList { func validateInitContainers(containers []core.Container, regularContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.String, gracePeriod int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy) field.ErrorList {
var allErrs field.ErrorList var allErrs field.ErrorList
allNames := sets.String{} allNames := sets.String{}
@ -3316,11 +3335,11 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
switch { switch {
case restartAlways: case restartAlways:
if ctr.Lifecycle != nil { if ctr.Lifecycle != nil {
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, idxPath.Child("lifecycle"))...) allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, gracePeriod, idxPath.Child("lifecycle"))...)
} }
allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, idxPath.Child("livenessProbe"))...) allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, gracePeriod, idxPath.Child("livenessProbe"))...)
allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, idxPath.Child("readinessProbe"))...) allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, gracePeriod, idxPath.Child("readinessProbe"))...)
allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, idxPath.Child("startupProbe"))...) allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, gracePeriod, idxPath.Child("startupProbe"))...)
default: default:
// These fields are disallowed for init containers. // These fields are disallowed for init containers.
@ -3420,7 +3439,7 @@ func validateHostUsers(spec *core.PodSpec, fldPath *field.Path) field.ErrorList
} }
// validateContainers is called by pod spec and template validation to validate the list of regular containers. // validateContainers is called by pod spec and template validation to validate the list of regular containers.
func validateContainers(containers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.String, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy) field.ErrorList { func validateContainers(containers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.String, gracePeriod int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if len(containers) == 0 { if len(containers) == 0 {
@ -3448,11 +3467,11 @@ func validateContainers(containers []core.Container, volumes map[string]core.Vol
// Regular init container and ephemeral container validation will return // Regular init container and ephemeral container validation will return
// field.Forbidden() for these paths. // field.Forbidden() for these paths.
if ctr.Lifecycle != nil { if ctr.Lifecycle != nil {
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, path.Child("lifecycle"))...) allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, gracePeriod, path.Child("lifecycle"))...)
} }
allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, path.Child("livenessProbe"))...) allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, gracePeriod, path.Child("livenessProbe"))...)
allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, path.Child("readinessProbe"))...) allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, gracePeriod, path.Child("readinessProbe"))...)
allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, path.Child("startupProbe"))...) allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, gracePeriod, path.Child("startupProbe"))...)
// These fields are disallowed for regular containers // These fields are disallowed for regular containers
if ctr.RestartPolicy != nil { if ctr.RestartPolicy != nil {
@ -3974,12 +3993,18 @@ func validateHostIPs(pod *core.Pod) field.ErrorList {
func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
var gracePeriod int64
if spec.TerminationGracePeriodSeconds != nil {
// this could happen in tests
gracePeriod = *spec.TerminationGracePeriodSeconds
}
vols, vErrs := ValidateVolumes(spec.Volumes, podMeta, fldPath.Child("volumes"), opts) vols, vErrs := ValidateVolumes(spec.Volumes, podMeta, fldPath.Child("volumes"), opts)
allErrs = append(allErrs, vErrs...) allErrs = append(allErrs, vErrs...)
podClaimNames := gatherPodResourceClaimNames(spec.ResourceClaims) podClaimNames := gatherPodResourceClaimNames(spec.ResourceClaims)
allErrs = append(allErrs, validatePodResourceClaims(podMeta, spec.ResourceClaims, fldPath.Child("resourceClaims"))...) allErrs = append(allErrs, validatePodResourceClaims(podMeta, spec.ResourceClaims, fldPath.Child("resourceClaims"))...)
allErrs = append(allErrs, validateContainers(spec.Containers, vols, podClaimNames, fldPath.Child("containers"), opts, &spec.RestartPolicy)...) allErrs = append(allErrs, validateContainers(spec.Containers, vols, podClaimNames, gracePeriod, fldPath.Child("containers"), opts, &spec.RestartPolicy)...)
allErrs = append(allErrs, validateInitContainers(spec.InitContainers, spec.Containers, vols, podClaimNames, fldPath.Child("initContainers"), opts, &spec.RestartPolicy)...) allErrs = append(allErrs, validateInitContainers(spec.InitContainers, spec.Containers, vols, podClaimNames, gracePeriod, fldPath.Child("initContainers"), opts, &spec.RestartPolicy)...)
allErrs = append(allErrs, validateEphemeralContainers(spec.EphemeralContainers, spec.Containers, spec.InitContainers, vols, podClaimNames, fldPath.Child("ephemeralContainers"), opts, &spec.RestartPolicy)...) allErrs = append(allErrs, validateEphemeralContainers(spec.EphemeralContainers, spec.Containers, spec.InitContainers, vols, podClaimNames, fldPath.Child("ephemeralContainers"), opts, &spec.RestartPolicy)...)
allErrs = append(allErrs, validatePodHostNetworkDeps(spec, fldPath, opts)...) allErrs = append(allErrs, validatePodHostNetworkDeps(spec, fldPath, opts)...)
allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy, fldPath.Child("restartPolicy"))...) allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy, fldPath.Child("restartPolicy"))...)

View File

@ -52,6 +52,7 @@ const (
dnsLabelErrMsg = "a lowercase RFC 1123 label must consist of" dnsLabelErrMsg = "a lowercase RFC 1123 label must consist of"
dnsSubdomainLabelErrMsg = "a lowercase RFC 1123 subdomain" dnsSubdomainLabelErrMsg = "a lowercase RFC 1123 subdomain"
envVarNameErrMsg = "a valid environment variable name must consist of" envVarNameErrMsg = "a valid environment variable name must consist of"
defaultGracePeriod = int64(30)
) )
var ( var (
@ -6616,7 +6617,7 @@ func TestValidateProbe(t *testing.T) {
} }
for _, p := range successCases { for _, p := range successCases {
if errs := validateProbe(p, field.NewPath("field")); len(errs) != 0 { if errs := validateProbe(p, defaultGracePeriod, field.NewPath("field")); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
} }
@ -6628,7 +6629,7 @@ func TestValidateProbe(t *testing.T) {
errorCases = append(errorCases, probe) errorCases = append(errorCases, probe)
} }
for _, p := range errorCases { for _, p := range errorCases {
if errs := validateProbe(p, field.NewPath("field")); len(errs) == 0 { if errs := validateProbe(p, defaultGracePeriod, field.NewPath("field")); len(errs) == 0 {
t.Errorf("expected failure for %v", p) t.Errorf("expected failure for %v", p)
} }
} }
@ -6734,7 +6735,7 @@ func Test_validateProbe(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got := validateProbe(tt.args.probe, tt.args.fldPath) got := validateProbe(tt.args.probe, defaultGracePeriod, tt.args.fldPath)
if len(got) != len(tt.want) { if len(got) != len(tt.want) {
t.Errorf("validateProbe() = %v, want %v", got, tt.want) t.Errorf("validateProbe() = %v, want %v", got, tt.want)
return return
@ -6759,7 +6760,7 @@ func TestValidateHandler(t *testing.T) {
{HTTPGet: &core.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []core.HTTPHeader{{Name: "X-Forwarded-For", Value: "1.2.3.4"}, {Name: "X-Forwarded-For", Value: "5.6.7.8"}}}}, {HTTPGet: &core.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []core.HTTPHeader{{Name: "X-Forwarded-For", Value: "1.2.3.4"}, {Name: "X-Forwarded-For", Value: "5.6.7.8"}}}},
} }
for _, h := range successCases { for _, h := range successCases {
if errs := validateHandler(handlerFromProbe(&h), field.NewPath("field")); len(errs) != 0 { if errs := validateHandler(handlerFromProbe(&h), defaultGracePeriod, field.NewPath("field")); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
} }
@ -6774,7 +6775,7 @@ func TestValidateHandler(t *testing.T) {
{HTTPGet: &core.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []core.HTTPHeader{{Name: "X_Forwarded_For", Value: "foo.example.com"}}}}, {HTTPGet: &core.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []core.HTTPHeader{{Name: "X_Forwarded_For", Value: "foo.example.com"}}}},
} }
for _, h := range errorCases { for _, h := range errorCases {
if errs := validateHandler(handlerFromProbe(&h), field.NewPath("field")); len(errs) == 0 { if errs := validateHandler(handlerFromProbe(&h), defaultGracePeriod, field.NewPath("field")); len(errs) == 0 {
t.Errorf("expected failure for %#v", h) t.Errorf("expected failure for %#v", h)
} }
} }
@ -7694,7 +7695,7 @@ func TestValidateContainers(t *testing.T) {
var PodRestartPolicy core.RestartPolicy var PodRestartPolicy core.RestartPolicy
PodRestartPolicy = "Always" PodRestartPolicy = "Always"
if errs := validateContainers(successCase, volumeDevices, nil, field.NewPath("field"), PodValidationOptions{}, &PodRestartPolicy); len(errs) != 0 { if errs := validateContainers(successCase, volumeDevices, nil, defaultGracePeriod, field.NewPath("field"), PodValidationOptions{}, &PodRestartPolicy); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
@ -8308,7 +8309,7 @@ func TestValidateContainers(t *testing.T) {
for _, tc := range errorCases { for _, tc := range errorCases {
t.Run(tc.title+"__@L"+tc.line, func(t *testing.T) { t.Run(tc.title+"__@L"+tc.line, func(t *testing.T) {
errs := validateContainers(tc.containers, volumeDevices, nil, field.NewPath("containers"), PodValidationOptions{}, &PodRestartPolicy) errs := validateContainers(tc.containers, volumeDevices, nil, defaultGracePeriod, field.NewPath("containers"), PodValidationOptions{}, &PodRestartPolicy)
if len(errs) == 0 { if len(errs) == 0 {
t.Fatal("expected error but received none") t.Fatal("expected error but received none")
} }
@ -8398,7 +8399,7 @@ func TestValidateInitContainers(t *testing.T) {
} }
var PodRestartPolicy core.RestartPolicy var PodRestartPolicy core.RestartPolicy
PodRestartPolicy = "Never" PodRestartPolicy = "Never"
if errs := validateInitContainers(successCase, containers, volumeDevices, nil, field.NewPath("field"), PodValidationOptions{}, &PodRestartPolicy); len(errs) != 0 { if errs := validateInitContainers(successCase, containers, volumeDevices, nil, defaultGracePeriod, field.NewPath("field"), PodValidationOptions{}, &PodRestartPolicy); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
@ -8777,7 +8778,7 @@ func TestValidateInitContainers(t *testing.T) {
for _, tc := range errorCases { for _, tc := range errorCases {
t.Run(tc.title+"__@L"+tc.line, func(t *testing.T) { t.Run(tc.title+"__@L"+tc.line, func(t *testing.T) {
errs := validateInitContainers(tc.initContainers, containers, volumeDevices, nil, field.NewPath("initContainers"), PodValidationOptions{}, &PodRestartPolicy) errs := validateInitContainers(tc.initContainers, containers, volumeDevices, nil, defaultGracePeriod, field.NewPath("initContainers"), PodValidationOptions{}, &PodRestartPolicy)
if len(errs) == 0 { if len(errs) == 0 {
t.Fatal("expected error but received none") t.Fatal("expected error but received none")
} }
@ -23702,3 +23703,57 @@ func TestValidateLoadBalancerStatus(t *testing.T) {
}) })
} }
} }
func TestValidateSleepAction(t *testing.T) {
fldPath := field.NewPath("root")
getInvalidStr := func(gracePeriod int64) string {
return fmt.Sprintf("must be greater than 0 and less than terminationGracePeriodSeconds (%d)", gracePeriod)
}
testCases := []struct {
name string
action *core.SleepAction
gracePeriod int64
expectErr field.ErrorList
}{
{
name: "valid setting",
action: &core.SleepAction{
Seconds: 5,
},
gracePeriod: 30,
},
{
name: "negative seconds",
action: &core.SleepAction{
Seconds: -1,
},
gracePeriod: 30,
expectErr: field.ErrorList{field.Invalid(fldPath, -1, getInvalidStr(30))},
},
{
name: "longer than gracePeriod",
action: &core.SleepAction{
Seconds: 5,
},
gracePeriod: 3,
expectErr: field.ErrorList{field.Invalid(fldPath, 5, getInvalidStr(3))},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
errs := validateSleepAction(tc.action, tc.gracePeriod, fldPath)
if len(tc.expectErr) > 0 && len(errs) == 0 {
t.Errorf("Unexpected success")
} else if len(tc.expectErr) == 0 && len(errs) != 0 {
t.Errorf("Unexpected error(s): %v", errs)
} else if len(tc.expectErr) > 0 {
if tc.expectErr[0].Error() != errs[0].Error() {
t.Errorf("Unexpected error(s): %v", errs)
}
}
})
}
}

View File

@ -2045,6 +2045,11 @@ func (in *LifecycleHandler) DeepCopyInto(out *LifecycleHandler) {
*out = new(TCPSocketAction) *out = new(TCPSocketAction)
**out = **in **out = **in
} }
if in.Sleep != nil {
in, out := &in.Sleep, &out.Sleep
*out = new(SleepAction)
**out = **in
}
return return
} }
@ -5671,6 +5676,22 @@ func (in *SessionAffinityConfig) DeepCopy() *SessionAffinityConfig {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SleepAction) DeepCopyInto(out *SleepAction) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SleepAction.
func (in *SleepAction) DeepCopy() *SleepAction {
if in == nil {
return nil
}
out := new(SleepAction)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StorageOSPersistentVolumeSource) DeepCopyInto(out *StorageOSPersistentVolumeSource) { func (in *StorageOSPersistentVolumeSource) DeepCopyInto(out *StorageOSPersistentVolumeSource) {
*out = *in *out = *in

View File

@ -636,6 +636,13 @@ const (
// Adds pod.status.hostIPs and downward API // Adds pod.status.hostIPs and downward API
PodHostIPs featuregate.Feature = "PodHostIPs" PodHostIPs featuregate.Feature = "PodHostIPs"
// owner: @AxeZhan
// kep: http://kep.k8s.io/3960
// alpha: v1.29
//
// Enables SleepAction in container lifecycle hooks
PodLifecycleSleepAction featuregate.Feature = "PodLifecycleSleepAction"
// owner: @Huang-Wei // owner: @Huang-Wei
// kep: https://kep.k8s.io/3521 // kep: https://kep.k8s.io/3521
// alpha: v1.26 // alpha: v1.26
@ -1063,6 +1070,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
PodHostIPs: {Default: false, PreRelease: featuregate.Alpha}, PodHostIPs: {Default: false, PreRelease: featuregate.Alpha},
PodLifecycleSleepAction: {Default: false, PreRelease: featuregate.Alpha},
PodSchedulingReadiness: {Default: true, PreRelease: featuregate.Beta}, PodSchedulingReadiness: {Default: true, PreRelease: featuregate.Beta},
ProbeTerminationGracePeriod: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 ProbeTerminationGracePeriod: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29

View File

@ -552,6 +552,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"k8s.io/api/core/v1.ServiceSpec": schema_k8sio_api_core_v1_ServiceSpec(ref), "k8s.io/api/core/v1.ServiceSpec": schema_k8sio_api_core_v1_ServiceSpec(ref),
"k8s.io/api/core/v1.ServiceStatus": schema_k8sio_api_core_v1_ServiceStatus(ref), "k8s.io/api/core/v1.ServiceStatus": schema_k8sio_api_core_v1_ServiceStatus(ref),
"k8s.io/api/core/v1.SessionAffinityConfig": schema_k8sio_api_core_v1_SessionAffinityConfig(ref), "k8s.io/api/core/v1.SessionAffinityConfig": schema_k8sio_api_core_v1_SessionAffinityConfig(ref),
"k8s.io/api/core/v1.SleepAction": schema_k8sio_api_core_v1_SleepAction(ref),
"k8s.io/api/core/v1.StorageOSPersistentVolumeSource": schema_k8sio_api_core_v1_StorageOSPersistentVolumeSource(ref), "k8s.io/api/core/v1.StorageOSPersistentVolumeSource": schema_k8sio_api_core_v1_StorageOSPersistentVolumeSource(ref),
"k8s.io/api/core/v1.StorageOSVolumeSource": schema_k8sio_api_core_v1_StorageOSVolumeSource(ref), "k8s.io/api/core/v1.StorageOSVolumeSource": schema_k8sio_api_core_v1_StorageOSVolumeSource(ref),
"k8s.io/api/core/v1.Sysctl": schema_k8sio_api_core_v1_Sysctl(ref), "k8s.io/api/core/v1.Sysctl": schema_k8sio_api_core_v1_Sysctl(ref),
@ -21408,11 +21409,17 @@ func schema_k8sio_api_core_v1_LifecycleHandler(ref common.ReferenceCallback) com
Ref: ref("k8s.io/api/core/v1.TCPSocketAction"), Ref: ref("k8s.io/api/core/v1.TCPSocketAction"),
}, },
}, },
"sleep": {
SchemaProps: spec.SchemaProps{
Description: "Sleep represents the duration that the container should sleep before being terminated.",
Ref: ref("k8s.io/api/core/v1.SleepAction"),
},
},
}, },
}, },
}, },
Dependencies: []string{ Dependencies: []string{
"k8s.io/api/core/v1.ExecAction", "k8s.io/api/core/v1.HTTPGetAction", "k8s.io/api/core/v1.TCPSocketAction"}, "k8s.io/api/core/v1.ExecAction", "k8s.io/api/core/v1.HTTPGetAction", "k8s.io/api/core/v1.SleepAction", "k8s.io/api/core/v1.TCPSocketAction"},
} }
} }
@ -28387,6 +28394,28 @@ func schema_k8sio_api_core_v1_SessionAffinityConfig(ref common.ReferenceCallback
} }
} }
func schema_k8sio_api_core_v1_SleepAction(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "SleepAction describes a \"sleep\" action.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"seconds": {
SchemaProps: spec.SchemaProps{
Description: "Seconds is the number of seconds to sleep.",
Default: 0,
Type: []string{"integer"},
Format: "int64",
},
},
},
Required: []string{"seconds"},
},
},
}
}
func schema_k8sio_api_core_v1_StorageOSPersistentVolumeSource(ref common.ReferenceCallback) common.OpenAPIDefinition { func schema_k8sio_api_core_v1_StorageOSPersistentVolumeSource(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{ return common.OpenAPIDefinition{
Schema: spec.Schema{ Schema: spec.Schema{

View File

@ -26,6 +26,7 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"time"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
@ -86,6 +87,14 @@ func (hr *handlerRunner) Run(ctx context.Context, containerID kubecontainer.Cont
klog.V(1).ErrorS(err, "HTTP lifecycle hook for Container in Pod failed", "path", handler.HTTPGet.Path, "containerName", container.Name, "pod", klog.KObj(pod)) klog.V(1).ErrorS(err, "HTTP lifecycle hook for Container in Pod failed", "path", handler.HTTPGet.Path, "containerName", container.Name, "pod", klog.KObj(pod))
} }
return msg, err return msg, err
case handler.Sleep != nil:
err := hr.runSleepHandler(ctx, handler.Sleep.Seconds)
var msg string
if err != nil {
msg = fmt.Sprintf("Sleep lifecycle hook (%d) for Container %q in Pod %q failed - error: %v", handler.Sleep.Seconds, container.Name, format.Pod(pod), err)
klog.V(1).ErrorS(err, "Sleep lifecycle hook for Container in Pod failed", "sleepSeconds", handler.Sleep.Seconds, "containerName", container.Name, "pod", klog.KObj(pod))
}
return msg, err
default: default:
err := fmt.Errorf("invalid handler: %v", handler) err := fmt.Errorf("invalid handler: %v", handler)
msg := fmt.Sprintf("Cannot run handler: %v", err) msg := fmt.Sprintf("Cannot run handler: %v", err)
@ -117,6 +126,20 @@ func resolvePort(portReference intstr.IntOrString, container *v1.Container) (int
return -1, fmt.Errorf("couldn't find port: %v in %v", portReference, container) return -1, fmt.Errorf("couldn't find port: %v in %v", portReference, container)
} }
func (hr *handlerRunner) runSleepHandler(ctx context.Context, seconds int64) error {
if !utilfeature.DefaultFeatureGate.Enabled(features.PodLifecycleSleepAction) {
return nil
}
c := time.After(time.Duration(seconds) * time.Second)
select {
case <-ctx.Done():
// unexpected termination
return fmt.Errorf("container terminated before sleep hook finished")
case <-c:
return nil
}
}
func (hr *handlerRunner) runHTTPHandler(ctx context.Context, pod *v1.Pod, container *v1.Container, handler *v1.LifecycleHandler, eventRecorder record.EventRecorder) error { func (hr *handlerRunner) runHTTPHandler(ctx context.Context, pod *v1.Pod, container *v1.Container, handler *v1.LifecycleHandler, eventRecorder record.EventRecorder) error {
host := handler.HTTPGet.Host host := handler.HTTPGet.Host
podIP := host podIP := host

View File

@ -859,3 +859,59 @@ func TestIsHTTPResponseError(t *testing.T) {
t.Errorf("unexpected http response error: %v", err) t.Errorf("unexpected http response error: %v", err)
} }
} }
func TestRunSleepHandler(t *testing.T) {
handlerRunner := NewHandlerRunner(&fakeHTTP{}, &fakeContainerCommandRunner{}, nil, nil)
containerID := kubecontainer.ContainerID{Type: "test", ID: "abc1234"}
containerName := "containerFoo"
container := v1.Container{
Name: containerName,
Lifecycle: &v1.Lifecycle{
PreStop: &v1.LifecycleHandler{},
},
}
pod := v1.Pod{}
pod.ObjectMeta.Name = "podFoo"
pod.ObjectMeta.Namespace = "nsFoo"
pod.Spec.Containers = []v1.Container{container}
tests := []struct {
name string
sleepSeconds int64
terminationGracePeriodSeconds int64
expectErr bool
expectedErr string
}{
{
name: "valid seconds",
sleepSeconds: 5,
terminationGracePeriodSeconds: 30,
},
{
name: "longer than TerminationGracePeriodSeconds",
sleepSeconds: 3,
terminationGracePeriodSeconds: 2,
expectErr: true,
expectedErr: "container terminated before sleep hook finished",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodLifecycleSleepAction, true)()
pod.Spec.Containers[0].Lifecycle.PreStop.Sleep = &v1.SleepAction{Seconds: tt.sleepSeconds}
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(tt.terminationGracePeriodSeconds)*time.Second)
defer cancel()
_, err := handlerRunner.Run(ctx, containerID, &pod, &container, container.Lifecycle.PreStop)
if !tt.expectErr && err != nil {
t.Errorf("unexpected success")
}
if tt.expectErr && err.Error() != tt.expectedErr {
t.Errorf("%s: expected error want %s, got %s", tt.name, tt.expectedErr, err.Error())
}
})
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2088,6 +2088,11 @@ message LifecycleHandler {
// lifecycle hooks will fail in runtime when tcp handler is specified. // lifecycle hooks will fail in runtime when tcp handler is specified.
// +optional // +optional
optional TCPSocketAction tcpSocket = 3; optional TCPSocketAction tcpSocket = 3;
// Sleep represents the duration that the container should sleep before being terminated.
// +featureGate=PodLifecycleSleepAction
// +optional
optional SleepAction sleep = 4;
} }
// LimitRange sets resource usage limits for each kind of resource in a Namespace. // LimitRange sets resource usage limits for each kind of resource in a Namespace.
@ -5562,6 +5567,12 @@ message SessionAffinityConfig {
optional ClientIPConfig clientIP = 1; optional ClientIPConfig clientIP = 1;
} }
// SleepAction describes a "sleep" action.
message SleepAction {
// Seconds is the number of seconds to sleep.
optional int64 seconds = 1;
}
// Represents a StorageOS persistent volume resource. // Represents a StorageOS persistent volume resource.
message StorageOSPersistentVolumeSource { message StorageOSPersistentVolumeSource {
// volumeName is the human-readable name of the StorageOS volume. Volume // volumeName is the human-readable name of the StorageOS volume. Volume

View File

@ -2272,6 +2272,12 @@ type ExecAction struct {
Command []string `json:"command,omitempty" protobuf:"bytes,1,rep,name=command"` Command []string `json:"command,omitempty" protobuf:"bytes,1,rep,name=command"`
} }
// SleepAction describes a "sleep" action.
type SleepAction struct {
// Seconds is the number of seconds to sleep.
Seconds int64 `json:"seconds" protobuf:"bytes,1,opt,name=seconds"`
}
// Probe describes a health check to be performed against a container to determine whether it is // Probe describes a health check to be performed against a container to determine whether it is
// alive or ready to receive traffic. // alive or ready to receive traffic.
type Probe struct { type Probe struct {
@ -2667,6 +2673,10 @@ type LifecycleHandler struct {
// lifecycle hooks will fail in runtime when tcp handler is specified. // lifecycle hooks will fail in runtime when tcp handler is specified.
// +optional // +optional
TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" protobuf:"bytes,3,opt,name=tcpSocket"` TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" protobuf:"bytes,3,opt,name=tcpSocket"`
// Sleep represents the duration that the container should sleep before being terminated.
// +featureGate=PodLifecycleSleepAction
// +optional
Sleep *SleepAction `json:"sleep,omitempty" protobuf:"bytes,4,opt,name=sleep"`
} }
// Lifecycle describes actions that the management system should take in response to container lifecycle // Lifecycle describes actions that the management system should take in response to container lifecycle

View File

@ -935,6 +935,7 @@ var map_LifecycleHandler = map[string]string{
"exec": "Exec specifies the action to take.", "exec": "Exec specifies the action to take.",
"httpGet": "HTTPGet specifies the http request to perform.", "httpGet": "HTTPGet specifies the http request to perform.",
"tcpSocket": "Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified.", "tcpSocket": "Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified.",
"sleep": "Sleep represents the duration that the container should sleep before being terminated.",
} }
func (LifecycleHandler) SwaggerDoc() map[string]string { func (LifecycleHandler) SwaggerDoc() map[string]string {
@ -2391,6 +2392,15 @@ func (SessionAffinityConfig) SwaggerDoc() map[string]string {
return map_SessionAffinityConfig return map_SessionAffinityConfig
} }
var map_SleepAction = map[string]string{
"": "SleepAction describes a \"sleep\" action.",
"seconds": "Seconds is the number of seconds to sleep.",
}
func (SleepAction) SwaggerDoc() map[string]string {
return map_SleepAction
}
var map_StorageOSPersistentVolumeSource = map[string]string{ var map_StorageOSPersistentVolumeSource = map[string]string{
"": "Represents a StorageOS persistent volume resource.", "": "Represents a StorageOS persistent volume resource.",
"volumeName": "volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.", "volumeName": "volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.",

View File

@ -2045,6 +2045,11 @@ func (in *LifecycleHandler) DeepCopyInto(out *LifecycleHandler) {
*out = new(TCPSocketAction) *out = new(TCPSocketAction)
**out = **in **out = **in
} }
if in.Sleep != nil {
in, out := &in.Sleep, &out.Sleep
*out = new(SleepAction)
**out = **in
}
return return
} }
@ -5686,6 +5691,22 @@ func (in *SessionAffinityConfig) DeepCopy() *SessionAffinityConfig {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SleepAction) DeepCopyInto(out *SleepAction) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SleepAction.
func (in *SleepAction) DeepCopy() *SleepAction {
if in == nil {
return nil
}
out := new(SleepAction)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StorageOSPersistentVolumeSource) DeepCopyInto(out *StorageOSPersistentVolumeSource) { func (in *StorageOSPersistentVolumeSource) DeepCopyInto(out *StorageOSPersistentVolumeSource) {
*out = *in *out = *in

View File

@ -690,6 +690,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -713,6 +716,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -974,6 +980,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -997,6 +1006,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1258,6 +1270,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1281,6 +1296,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -239,6 +239,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -254,6 +256,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -446,6 +450,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -461,6 +467,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -655,6 +663,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -670,6 +680,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -691,6 +691,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -714,6 +717,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -975,6 +981,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -998,6 +1007,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1259,6 +1271,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1282,6 +1297,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -247,6 +247,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -262,6 +264,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -454,6 +458,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -469,6 +475,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -663,6 +671,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -678,6 +688,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -692,6 +692,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -715,6 +718,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -976,6 +982,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -999,6 +1008,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1260,6 +1272,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1283,6 +1298,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -239,6 +239,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -254,6 +256,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -446,6 +450,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -461,6 +467,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -655,6 +663,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -670,6 +680,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -691,6 +691,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -714,6 +717,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -975,6 +981,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -998,6 +1007,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1259,6 +1271,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1282,6 +1297,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -247,6 +247,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -262,6 +264,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -454,6 +458,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -469,6 +475,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -663,6 +671,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -678,6 +688,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -691,6 +691,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -714,6 +717,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -975,6 +981,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -998,6 +1007,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1259,6 +1271,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1282,6 +1297,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -249,6 +249,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -264,6 +266,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -456,6 +460,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -471,6 +477,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -665,6 +673,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -680,6 +690,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -691,6 +691,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -714,6 +717,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -975,6 +981,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -998,6 +1007,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1259,6 +1271,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1282,6 +1297,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -247,6 +247,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -262,6 +264,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -454,6 +458,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -469,6 +475,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -663,6 +671,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -678,6 +688,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -690,6 +690,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -713,6 +716,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -974,6 +980,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -997,6 +1006,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1258,6 +1270,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1281,6 +1296,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -239,6 +239,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -254,6 +256,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -446,6 +450,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -461,6 +467,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -655,6 +663,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -670,6 +680,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -691,6 +691,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -714,6 +717,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -975,6 +981,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -998,6 +1007,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1259,6 +1271,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1282,6 +1297,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -247,6 +247,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -262,6 +264,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -454,6 +458,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -469,6 +475,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -663,6 +671,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -678,6 +688,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -692,6 +692,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -715,6 +718,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -976,6 +982,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -999,6 +1008,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1260,6 +1272,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1283,6 +1298,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -239,6 +239,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -254,6 +256,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -446,6 +450,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -461,6 +467,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -655,6 +663,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -670,6 +680,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -691,6 +691,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -714,6 +717,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -975,6 +981,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -998,6 +1007,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1259,6 +1271,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1282,6 +1297,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -247,6 +247,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -262,6 +264,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -454,6 +458,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -469,6 +475,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -663,6 +671,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -678,6 +688,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -766,6 +766,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -789,6 +792,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1050,6 +1056,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1073,6 +1082,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1334,6 +1346,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1357,6 +1372,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -294,6 +294,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -309,6 +311,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -501,6 +505,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -516,6 +522,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -710,6 +718,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -725,6 +735,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -717,6 +717,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -740,6 +743,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1001,6 +1007,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1024,6 +1033,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1285,6 +1297,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1308,6 +1323,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -258,6 +258,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -273,6 +275,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -465,6 +469,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -480,6 +486,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -674,6 +682,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -689,6 +699,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -766,6 +766,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -789,6 +792,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1050,6 +1056,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1073,6 +1082,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1334,6 +1346,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1357,6 +1372,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -294,6 +294,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -309,6 +311,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -501,6 +505,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -516,6 +522,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -710,6 +718,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -725,6 +735,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -632,6 +632,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -655,6 +658,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -916,6 +922,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -939,6 +948,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1200,6 +1212,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1223,6 +1238,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -195,6 +195,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -210,6 +212,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -402,6 +406,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -417,6 +423,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -611,6 +619,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -626,6 +636,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -675,6 +675,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -698,6 +701,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -959,6 +965,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -982,6 +991,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1243,6 +1255,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1266,6 +1281,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -228,6 +228,8 @@ template:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -243,6 +245,8 @@ template:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -435,6 +439,8 @@ template:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -450,6 +456,8 @@ template:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -644,6 +652,8 @@ template:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -659,6 +669,8 @@ template:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -681,6 +681,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -704,6 +707,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -965,6 +971,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -988,6 +997,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1249,6 +1261,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1272,6 +1287,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -233,6 +233,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -248,6 +250,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -440,6 +444,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -455,6 +461,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -649,6 +657,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -664,6 +674,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -690,6 +690,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -713,6 +716,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -974,6 +980,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -997,6 +1006,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1258,6 +1270,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1281,6 +1296,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -239,6 +239,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -254,6 +256,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -446,6 +450,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -461,6 +467,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -655,6 +663,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -670,6 +680,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -691,6 +691,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -714,6 +717,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -975,6 +981,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -998,6 +1007,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1259,6 +1271,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1282,6 +1297,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -249,6 +249,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -264,6 +266,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -456,6 +460,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -471,6 +477,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -665,6 +673,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -680,6 +690,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -692,6 +692,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -715,6 +718,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -976,6 +982,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -999,6 +1008,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },
@ -1260,6 +1272,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
}, },
"preStop": { "preStop": {
@ -1283,6 +1298,9 @@
"tcpSocket": { "tcpSocket": {
"port": "portValue", "port": "portValue",
"host": "hostValue" "host": "hostValue"
},
"sleep": {
"seconds": 1
} }
} }
}, },

View File

@ -239,6 +239,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -254,6 +256,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -446,6 +450,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -461,6 +467,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -655,6 +663,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue
@ -670,6 +680,8 @@ spec:
path: pathValue path: pathValue
port: portValue port: portValue
scheme: schemeValue scheme: schemeValue
sleep:
seconds: 1
tcpSocket: tcpSocket:
host: hostValue host: hostValue
port: portValue port: portValue

View File

@ -24,6 +24,7 @@ type LifecycleHandlerApplyConfiguration struct {
Exec *ExecActionApplyConfiguration `json:"exec,omitempty"` Exec *ExecActionApplyConfiguration `json:"exec,omitempty"`
HTTPGet *HTTPGetActionApplyConfiguration `json:"httpGet,omitempty"` HTTPGet *HTTPGetActionApplyConfiguration `json:"httpGet,omitempty"`
TCPSocket *TCPSocketActionApplyConfiguration `json:"tcpSocket,omitempty"` TCPSocket *TCPSocketActionApplyConfiguration `json:"tcpSocket,omitempty"`
Sleep *SleepActionApplyConfiguration `json:"sleep,omitempty"`
} }
// LifecycleHandlerApplyConfiguration constructs an declarative configuration of the LifecycleHandler type for use with // LifecycleHandlerApplyConfiguration constructs an declarative configuration of the LifecycleHandler type for use with
@ -55,3 +56,11 @@ func (b *LifecycleHandlerApplyConfiguration) WithTCPSocket(value *TCPSocketActio
b.TCPSocket = value b.TCPSocket = value
return b return b
} }
// WithSleep sets the Sleep field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Sleep field is set to the value of the last call.
func (b *LifecycleHandlerApplyConfiguration) WithSleep(value *SleepActionApplyConfiguration) *LifecycleHandlerApplyConfiguration {
b.Sleep = value
return b
}

View File

@ -0,0 +1,39 @@
/*
Copyright 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.
*/
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v1
// SleepActionApplyConfiguration represents an declarative configuration of the SleepAction type for use
// with apply.
type SleepActionApplyConfiguration struct {
Seconds *int64 `json:"seconds,omitempty"`
}
// SleepActionApplyConfiguration constructs an declarative configuration of the SleepAction type for use with
// apply.
func SleepAction() *SleepActionApplyConfiguration {
return &SleepActionApplyConfiguration{}
}
// WithSeconds sets the Seconds field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Seconds field is set to the value of the last call.
func (b *SleepActionApplyConfiguration) WithSeconds(value int64) *SleepActionApplyConfiguration {
b.Seconds = &value
return b
}

View File

@ -5497,6 +5497,9 @@ var schemaYAML = typed.YAMLObject(`types:
- name: httpGet - name: httpGet
type: type:
namedType: io.k8s.api.core.v1.HTTPGetAction namedType: io.k8s.api.core.v1.HTTPGetAction
- name: sleep
type:
namedType: io.k8s.api.core.v1.SleepAction
- name: tcpSocket - name: tcpSocket
type: type:
namedType: io.k8s.api.core.v1.TCPSocketAction namedType: io.k8s.api.core.v1.TCPSocketAction
@ -7565,6 +7568,13 @@ var schemaYAML = typed.YAMLObject(`types:
- name: clientIP - name: clientIP
type: type:
namedType: io.k8s.api.core.v1.ClientIPConfig namedType: io.k8s.api.core.v1.ClientIPConfig
- name: io.k8s.api.core.v1.SleepAction
map:
fields:
- name: seconds
type:
scalar: numeric
default: 0
- name: io.k8s.api.core.v1.StorageOSPersistentVolumeSource - name: io.k8s.api.core.v1.StorageOSPersistentVolumeSource
map: map:
fields: fields:

View File

@ -911,6 +911,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationscorev1.ServiceStatusApplyConfiguration{} return &applyconfigurationscorev1.ServiceStatusApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("SessionAffinityConfig"): case corev1.SchemeGroupVersion.WithKind("SessionAffinityConfig"):
return &applyconfigurationscorev1.SessionAffinityConfigApplyConfiguration{} return &applyconfigurationscorev1.SessionAffinityConfigApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("SleepAction"):
return &applyconfigurationscorev1.SleepActionApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("StorageOSPersistentVolumeSource"): case corev1.SchemeGroupVersion.WithKind("StorageOSPersistentVolumeSource"):
return &applyconfigurationscorev1.StorageOSPersistentVolumeSourceApplyConfiguration{} return &applyconfigurationscorev1.StorageOSPersistentVolumeSourceApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("StorageOSVolumeSource"): case corev1.SchemeGroupVersion.WithKind("StorageOSVolumeSource"):

View File

@ -544,3 +544,52 @@ func getSidecarPodWithHook(name string, image string, lifecycle *v1.Lifecycle) *
}, },
} }
} }
var _ = SIGDescribe("[Feature:PodLifecycleSleepAction]", func() {
f := framework.NewDefaultFramework("pod-lifecycle-sleep-action")
f.NamespacePodSecurityEnforceLevel = admissionapi.LevelBaseline
var podClient *e2epod.PodClient
ginkgo.Context("when create a pod with lifecycle hook using sleep action", func() {
ginkgo.BeforeEach(func(ctx context.Context) {
podClient = e2epod.NewPodClient(f)
})
ginkgo.It("valid prestop hook using sleep action", func(ctx context.Context) {
lifecycle := &v1.Lifecycle{
PreStop: &v1.LifecycleHandler{
Sleep: &v1.SleepAction{Seconds: 5},
},
}
podWithHook := getPodWithHook("pod-with-prestop-sleep-hook", imageutils.GetPauseImageName(), lifecycle)
ginkgo.By("create the pod with lifecycle hook using sleep action")
podClient.CreateSync(ctx, podWithHook)
ginkgo.By("delete the pod with lifecycle hook using sleep action")
start := time.Now()
podClient.DeleteSync(ctx, podWithHook.Name, metav1.DeleteOptions{}, e2epod.DefaultPodDeletionTimeout)
cost := time.Since(start)
// verify that deletion was delayed by sleep seconds
if cost < time.Second*5 || cost > time.Second*10 {
framework.Failf("unexpected delay duration before killing the pod")
}
})
ginkgo.It("reduce GracePeriodSeconds during runtime", func(ctx context.Context) {
lifecycle := &v1.Lifecycle{
PreStop: &v1.LifecycleHandler{
Sleep: &v1.SleepAction{Seconds: 10},
},
}
podWithHook := getPodWithHook("pod-with-prestop-sleep-hook", imageutils.GetPauseImageName(), lifecycle)
ginkgo.By("create the pod with lifecycle hook using sleep action")
podClient.CreateSync(ctx, podWithHook)
ginkgo.By("delete the pod with lifecycle hook using sleep action")
start := time.Now()
podClient.DeleteSync(ctx, podWithHook.Name, *metav1.NewDeleteOptions(2), e2epod.DefaultPodDeletionTimeout)
cost := time.Since(start)
// verify that deletion was delayed by sleep seconds
if cost <= time.Second || cost >= time.Second*5 {
framework.Failf("unexpected delay duration before killing the pod")
}
})
})
})