Documentation
¶
Index ¶
- Constants
- Variables
- func GetPodPhaseDuration(pod *corev1.Pod, phase string, now time.Time) (time.Duration, bool, error)
- func GetPodPhaseSince(pod *corev1.Pod, phase string) (time.Time, bool, error)
- func GetSandboxPhase(pod *corev1.Pod) string
- func HasUnexpectedRestart(pod *corev1.Pod) bool
- func IsInplaceUpdateCompleted(ctx context.Context, sandboxPool *agentsv1alpha1.SandboxPool, pod *corev1.Pod, ...) bool
- func MarkUpdateCompleted(ctx context.Context, c client.Client, sandboxPool *agentsv1alpha1.SandboxPool, ...) (*corev1.Pod, error)
- func TriggerUpdateWithOptions(ctx context.Context, c client.Client, pod *corev1.Pod, opts UpdateOptions) (*corev1.Pod, error)
- type InplaceUpdateContainerStatus
- type InplaceUpdateState
- type StableContainerStatus
- type UpdateOptions
Constants ¶
const ( PodAnnotationInPlaceUpdateStateKey = "agentbox.navix.sh/inplace-update-state" InplaceUpdatePhaseStarting = "starting" InplaceUpdatePhaseStopping = "stopping" InplaceUpdatePhaseCompleted = "completed" )
Variables ¶
var ( ErrNoContainers = errors.New("pod has no containers") ErrContainerNotFound = errors.New("container not found in pod") ErrUnexpectedPodPhase = errors.New("pod phase does not match expected value") ErrNoIdlePodsAvailable = errors.New("no idle sandboxes available for creating") ErrTargetImageIsRequired = errors.New("target image is required") )
Functions ¶
func GetPodPhaseDuration ¶
GetPodPhaseDuration returns how long the pod has been in the requested sandbox phase. It uses GetPodPhaseSince and subtracts it from now. When now.IsZero(), time.Now().UTC() is used. The returned bool is false when the pod is not currently in that phase.
func GetPodPhaseSince ¶
GetPodPhaseSince returns the timestamp when the pod entered the requested sandbox phase.
For Starting/Stopping, the timestamp comes from InplaceUpdateState.UpdateTimestamp recorded when the transition was triggered. For Running/Idle, it comes from the completed InplaceUpdateState timestamp refreshed by MarkUpdateCompleted. When the pod has no matching in-place update state (for example, a freshly created idle pod), the method falls back to metadata.creationTimestamp.
The returned bool is false when the pod is not currently in the requested phase. When phase is empty, the pod's current sandbox phase label is used.
func GetSandboxPhase ¶
func HasUnexpectedRestart ¶
HasUnexpectedRestart returns true if any container in the pod has a different containerID than what was recorded in StableContainerStatuses. A containerID change indicates the container was killed and restarted by kubelet (e.g., OOM-kill, crash) while the pod was in Running phase.
Design note: we intentionally do NOT use restartCount as a signal here. kubelet reports containerID, restartCount, and Ready in separate status patches, which means the controller-runtime informer cache can reflect an intermediate state where imageID/Ready are already updated but restartCount has not yet incremented. Using only containerID avoids this race: containerID is assigned atomically when a new container is created, so a change unambiguously indicates a container replacement event. If stable.ContainerID is empty (cache lag prevented snapshotting), we skip the check to avoid a false positive.
func IsInplaceUpdateCompleted ¶
func IsInplaceUpdateCompleted(ctx context.Context, sandboxPool *agentsv1alpha1.SandboxPool, pod *corev1.Pod, resolver imageresolver.DigestResolver) bool
func MarkUpdateCompleted ¶
func MarkUpdateCompleted(ctx context.Context, c client.Client, sandboxPool *agentsv1alpha1.SandboxPool, pod *corev1.Pod, resolver imageresolver.DigestResolver) (*corev1.Pod, error)
MarkUpdateCompleted marks the in-place update as completed for the given pod. It returns the updated pod object as seen by the API server after the update, or nil if no update was performed (e.g., already completed or phase mismatch). Callers should replace their in-memory pod with the returned object to avoid operating on stale informer-cache data within the same reconcile loop.
Types ¶
type InplaceUpdateContainerStatus ¶
type InplaceUpdateContainerStatus struct {
ImageID string `json:"imageID,omitempty"`
// ContainerID is the container ID at the moment the in-place update was
// triggered. It is used as a secondary completion signal: even when the
// target image has the same digest as the previous one (e.g. rolling back
// after a failed pull of a non-existent image), a changed containerID
// proves that the old container was replaced and the new one is running.
ContainerID string `json:"containerID,omitempty"`
}
type InplaceUpdateState ¶
type InplaceUpdateState struct {
Phase string `json:"phase"`
TargetImage string `json:"targetImage,omitempty"`
TargetImages map[string]string `json:"targetImages,omitempty"`
TargetPodPhase string `json:"targetPodPhase,omitempty"`
UpdateTimestamp metav1.Time `json:"updateTimestamp,omitempty"`
LastContainerStatuses map[string]InplaceUpdateContainerStatus `json:"lastContainerStatuses,omitempty"`
// StableContainerStatuses is populated when the update phase transitions to
// Completed and TargetPodPhase==Running. It records containerID+restartCount
// so the controller can detect unexpected restarts while phase=running.
StableContainerStatuses map[string]StableContainerStatus `json:"stableContainerStatuses,omitempty"`
}
InplaceUpdateState is serialized into Pod annotation to track an in-flight update.
func GetInplaceUpdateState ¶
func GetInplaceUpdateState(pod *corev1.Pod) (*InplaceUpdateState, error)
func GetPodInPlaceUpdateState ¶
func GetPodInPlaceUpdateState(pod *corev1.Pod) (*InplaceUpdateState, error)
type StableContainerStatus ¶
type StableContainerStatus struct {
ContainerID string `json:"containerID,omitempty"`
RestartCount int32 `json:"restartCount"`
}
StableContainerStatus records the container state after an in-place update completes. Used by the controller to detect unexpected restarts (e.g., OOM).
type UpdateOptions ¶
type UpdateOptions struct {
ContainerImages map[string]string
Labels map[string]string
Annotations map[string]string
RemoveLabels []string
RemoveAnnotations []string
TargetPodPhase string
// UpdatePodPhase is the intermediate phase label set on the Pod while the
// in-place image update is in progress (before the new image is pulled).
// Use PodPhaseStarting for Idle→Running transitions and PodPhaseStopping
// for Running→Idle transitions. Defaults to PodPhaseStarting when empty.
UpdatePodPhase string
ExpectedCurrentSandboxPhase string
// DisableRetry, when true, causes TriggerUpdateWithOptions to return
// immediately on a conflict error instead of retrying. This is appropriate
// for optimistic operations (e.g. unexpected-restart detection) where
// retrying on stale data could misfire: the caller should skip the pod and
// let the next Reconcile re-observe the true state before acting.
DisableRetry bool
}