mirror of https://github.com/k3s-io/k3s
validate container state transitions
parent
2aeace402a
commit
7b6aa09046
|
@ -3322,6 +3322,31 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod) field.ErrorList {
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidateContainerStateTransition test to if any illegal container state transitions are being attempted
|
||||||
|
func ValidateContainerStateTransition(newStatuses, oldStatuses []core.ContainerStatus, fldpath *field.Path, restartPolicy core.RestartPolicy) field.ErrorList {
|
||||||
|
allErrs := field.ErrorList{}
|
||||||
|
// If we should always restart, containers are allowed to leave the terminated state
|
||||||
|
if restartPolicy == core.RestartPolicyAlways {
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
for i, oldStatus := range oldStatuses {
|
||||||
|
// Skip any container that is not terminated
|
||||||
|
if oldStatus.State.Terminated == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Skip any container that failed but is allowed to restart
|
||||||
|
if oldStatus.State.Terminated.ExitCode != 0 && restartPolicy == core.RestartPolicyOnFailure {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, newStatus := range newStatuses {
|
||||||
|
if oldStatus.Name == newStatus.Name && newStatus.State.Terminated == nil {
|
||||||
|
allErrs = append(allErrs, field.Forbidden(fldpath.Index(i).Child("state"), "may not be transitioned to non-terminated state"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
|
||||||
// ValidatePodStatusUpdate tests to see if the update is legal for an end user to make. newPod is updated with fields
|
// ValidatePodStatusUpdate tests to see if the update is legal for an end user to make. newPod is updated with fields
|
||||||
// that cannot be changed.
|
// that cannot be changed.
|
||||||
func ValidatePodStatusUpdate(newPod, oldPod *core.Pod) field.ErrorList {
|
func ValidatePodStatusUpdate(newPod, oldPod *core.Pod) field.ErrorList {
|
||||||
|
@ -3329,10 +3354,16 @@ func ValidatePodStatusUpdate(newPod, oldPod *core.Pod) field.ErrorList {
|
||||||
allErrs := ValidateObjectMetaUpdate(&newPod.ObjectMeta, &oldPod.ObjectMeta, fldPath)
|
allErrs := ValidateObjectMetaUpdate(&newPod.ObjectMeta, &oldPod.ObjectMeta, fldPath)
|
||||||
allErrs = append(allErrs, ValidatePodSpecificAnnotationUpdates(newPod, oldPod, fldPath.Child("annotations"))...)
|
allErrs = append(allErrs, ValidatePodSpecificAnnotationUpdates(newPod, oldPod, fldPath.Child("annotations"))...)
|
||||||
|
|
||||||
|
fldPath = field.NewPath("status")
|
||||||
if newPod.Spec.NodeName != oldPod.Spec.NodeName {
|
if newPod.Spec.NodeName != oldPod.Spec.NodeName {
|
||||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("status", "nodeName"), "may not be changed directly"))
|
allErrs = append(allErrs, field.Forbidden(fldPath.Child("nodeName"), "may not be changed directly"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If pod should not restart, make sure the status update does not transition
|
||||||
|
// any terminated containers to a non-terminated state.
|
||||||
|
allErrs = append(allErrs, ValidateContainerStateTransition(newPod.Status.ContainerStatuses, oldPod.Status.ContainerStatuses, fldPath.Child("containerStatuses"), oldPod.Spec.RestartPolicy)...)
|
||||||
|
allErrs = append(allErrs, ValidateContainerStateTransition(newPod.Status.InitContainerStatuses, oldPod.Status.InitContainerStatuses, fldPath.Child("initContainerStatuses"), oldPod.Spec.RestartPolicy)...)
|
||||||
|
|
||||||
// For status update we ignore changes to pod spec.
|
// For status update we ignore changes to pod spec.
|
||||||
newPod.Spec = oldPod.Spec
|
newPod.Spec = oldPod.Spec
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue