Skip to content

feat(meta): add lifecycle-state annotation contract#1

Merged
CMGS merged 5 commits into
mainfrom
feat/lifecycle-state-annotation
May 10, 2026
Merged

feat(meta): add lifecycle-state annotation contract#1
CMGS merged 5 commits into
mainfrom
feat/lifecycle-state-annotation

Conversation

@tonicmuroq
Copy link
Copy Markdown
Contributor

@tonicmuroq tonicmuroq commented May 10, 2026

Summary

  • Adds the typed contract for vk-cocoon's vm.cocoonstack.io/lifecycle-state annotation triple (state, observed-generation, message) — LifecycleStatus.Apply / PatchPayload / Snapshot keep the in-memory pod, the apiserver patch body, and the drift-comparison key in sync.
  • Adds the cocoonset.cocoonstack.io/generation bridge that cocoon-operator stamps onto every owned pod so vk-cocoon can read it back as lifecycle-observed-generation. Counter-based completion signal — K8s API conventions explicitly recommend against wallclock-based markers (k/k#29229, k/k#119514 are the canonical case studies).
  • Adds PatchCocoonSetGeneration helper, structurally identical to existing PatchHibernateState.

Why

vk-cocoon today has no way to publish "operation X actually finished" externally. cocoonset.status.phase=Suspended is set eagerly when Epoch.HasManifest returns true — which fires on stale tags from a previous hibernate, so a hibernate2-then-wake cycle on a recently-hibernated VM short-circuits and serializes against the still-running first snapshot push. This contract gives the writer (vk-cocoon) and the reader (clients via Pod annotation) a stable counter-based completion API that does not depend on wall clocks.

Full design in cocoonstack/cocoon-specs#feat/lifecycle-state-annotation (design/lifecycle-state-contract.md).

Test plan

  • go test -race ./... passes
  • make lint clean on both GOOS=linux and GOOS=darwin
  • Downstream PRs (vk-cocoon writer + cocoon-operator bridge) bump to a pseudo-version pointing at the merged commit before they merge

Adds the typed contract for vk-cocoon's lifecycle-state annotation triple
plus the cocoonset-generation bridge cocoon-operator stamps onto pods so
vk-cocoon can write it back as observed-generation. Counter-based, not
clock-based, per K8s API conventions.

- LifecycleState / LifecycleStatus with Apply / PatchPayload / Snapshot
- AnnotationLifecycleState{,ObservedGeneration,Message}
- AnnotationCocoonSetGeneration + StampCocoonSetGeneration
- PatchCocoonSetGeneration helper, mirror of PatchHibernateState
- Apply now consumes PatchPayload directly so the in-memory and patch
  paths cannot drift; eliminates the need for a mirror-invariant test.
- Group IsTerminal with LifecycleState; drop the state list from its
  godoc (would rot when terminal states change).
- Extract readInt64Annotation to dedupe the two int64 annotation parsers.
- Cover Apply, PatchPayload, Snapshot, ReadLifecycleStatus, and
  StampCocoonSetGeneration (previously had only IsTerminal and Read*State
  coverage).
- Lists LifecycleStatus alongside the other typed annotation contracts.
- Adds generation / lifecycle-* keys to the identifier-namespace tables.
- Explains the counter-based completion design so consumers know which
  helpers cooperate (StampCocoonSetGeneration on the operator side,
  ReadCocoonSetGeneration + LifecycleStatus on the vk-cocoon side).
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a typed, shared contract for a Pod lifecycle-state annotation triple (state / observed-generation / message) and introduces a CocoonSet generation “bridge” annotation plus a helper for stamping it onto Pods, so downstream components can reliably publish/observe completion using a counter rather than wall-clock markers.

Changes:

  • Define LifecycleState/LifecycleStatus helpers for writing, reading, patch-payload generation, and drift snapshots of lifecycle annotations.
  • Add cocoonset.cocoonstack.io/generation annotation key and helpers to read/stamp it.
  • Add k8s.PatchCocoonSetGeneration helper + tests mirroring the existing hibernate patch helper.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
meta/meta.go Adds new annotation key constants for lifecycle state and CocoonSet generation.
meta/lifecycle.go Implements the lifecycle-state typed contract, read/write helpers, and int64 parsing utilities.
meta/lifecycle_test.go Adds unit tests for lifecycle helpers and snapshot stability.
k8s/utils.go Adds PatchCocoonSetGeneration helper for patching the generation annotation.
k8s/utils_test.go Adds tests for PatchCocoonSetGeneration and fixes minor formatting in existing tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread meta/lifecycle_test.go Outdated
Comment thread k8s/utils.go
Mirror PatchHibernateState by routing the short-circuit through
ReadCocoonSetGeneration, which tolerates a nil pod. Also normalizes the
comparison to the parsed int64 so a malformed annotation does not force
a redundant patch when the desired generation matches the parsed value.

Names the IsTerminal subtests explicitly so the empty-state case shows
up readably instead of as the synthesized #00.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread README.md Outdated
Comment thread meta/lifecycle.go Outdated
The method returns the annotation key/value map (with nil meaning
delete), not a complete apiserver patch body — callers still need to
wrap it via k8s.AnnotationsMergePatch (or embed under .metadata.annotations).
The previous name and godoc invited the misuse of feeding the bare
return value to a Patch call.

README example now shows the wrap-with-AnnotationsMergePatch link
explicitly.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

@CMGS CMGS merged commit 9af4381 into main May 10, 2026
6 checks passed
@tonicmuroq tonicmuroq deleted the feat/lifecycle-state-annotation branch May 10, 2026 05:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants