Sidecar: API changes

- Add SidecarContaienrs feature gate
- Add ContainerRestartPolicy type
- Add RestartPolicy field to the Container
- Drop RestartPolicy field if the feature is disabled
- Add validation for the SidecarContainers
- Allow restartable init containaers to have a startup probe
This commit is contained in:
Gunju Kim
2023-05-10 01:34:46 +09:00
committed by Sergey Kanzhelev
parent c17601fa18
commit 5d26bcd468
7 changed files with 472 additions and 12 deletions

View File

@@ -2835,6 +2835,23 @@ func validateProbe(probe *core.Probe, fldPath *field.Path) field.ErrorList {
return allErrs
}
func validateInitContainerRestartPolicy(restartPolicy *core.ContainerRestartPolicy, fldPath *field.Path) field.ErrorList {
var allErrors field.ErrorList
if restartPolicy == nil {
return allErrors
}
switch *restartPolicy {
case core.ContainerRestartPolicyAlways:
break
default:
validValues := []string{string(core.ContainerRestartPolicyAlways)}
allErrors = append(allErrors, field.NotSupported(fldPath, *restartPolicy, validValues))
}
return allErrors
}
type commonHandler struct {
Exec *core.ExecAction
HTTPGet *core.HTTPGetAction
@@ -3165,6 +3182,13 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
// Apply the validation common to all container types
allErrs = append(allErrs, validateContainerCommon(&ctr, volumes, podClaimNames, idxPath, opts)...)
restartAlways := false
// Apply the validation specific to init containers
if ctr.RestartPolicy != nil {
allErrs = append(allErrs, validateInitContainerRestartPolicy(ctr.RestartPolicy, idxPath.Child("restartPolicy"))...)
restartAlways = *ctr.RestartPolicy == core.ContainerRestartPolicyAlways
}
// Names must be unique within regular and init containers. Collisions with ephemeral containers
// will be detected by validateEphemeralContainers().
if allNames.Has(ctr.Name) {
@@ -3176,19 +3200,41 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
// Check for port conflicts in init containers individually since init containers run one-by-one.
allErrs = append(allErrs, checkHostPortConflicts([]core.Container{ctr}, fldPath)...)
// These fields are disallowed for init containers.
if ctr.Lifecycle != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("lifecycle"), "may not be set for init containers"))
}
if ctr.LivenessProbe != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("livenessProbe"), "may not be set for init containers"))
}
if ctr.ReadinessProbe != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("readinessProbe"), "may not be set for init containers"))
}
if ctr.StartupProbe != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("startupProbe"), "may not be set for init containers"))
switch {
case restartAlways:
// TODO: Allow restartable init containers to have a lifecycle hook.
if ctr.Lifecycle != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("lifecycle"), "may not be set for init containers"))
}
// TODO: Allow restartable init containers to have a liveness probe.
if ctr.LivenessProbe != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("livenessProbe"), "may not be set for init containers"))
}
// TODO: Allow restartable init containers to have a readiness probe.
if ctr.ReadinessProbe != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("readinessProbe"), "may not be set for init containers"))
}
allErrs = append(allErrs, validateProbe(ctr.StartupProbe, idxPath.Child("startupProbe"))...)
if ctr.StartupProbe != nil && ctr.StartupProbe.SuccessThreshold != 1 {
allErrs = append(allErrs, field.Invalid(idxPath.Child("startupProbe", "successThreshold"), ctr.StartupProbe.SuccessThreshold, "must be 1"))
}
default:
// These fields are disallowed for init containers.
if ctr.Lifecycle != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("lifecycle"), "may not be set for init containers"))
}
if ctr.LivenessProbe != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("livenessProbe"), "may not be set for init containers"))
}
if ctr.ReadinessProbe != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("readinessProbe"), "may not be set for init containers"))
}
if ctr.StartupProbe != nil {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("startupProbe"), "may not be set for init containers"))
}
}
if len(ctr.ResizePolicy) > 0 {
allErrs = append(allErrs, field.Invalid(idxPath.Child("resizePolicy"), ctr.ResizePolicy, "must not be set for init containers"))
}
@@ -3311,6 +3357,11 @@ func validateContainers(containers []core.Container, volumes map[string]core.Vol
if ctr.StartupProbe != nil && ctr.StartupProbe.SuccessThreshold != 1 {
allErrs = append(allErrs, field.Invalid(path.Child("startupProbe", "successThreshold"), ctr.StartupProbe.SuccessThreshold, "must be 1"))
}
// These fields are disallowed for regular containers
if ctr.RestartPolicy != nil {
allErrs = append(allErrs, field.Forbidden(path.Child("restartPolicy"), "may not be set for non-init containers"))
}
}
// Port conflicts are checked across all containers