apis/v1 holds the typed Go definitions for the cocoonset.cocoonstack.io/v1
API group and the CRD YAML generated from them, under apis/v1/crds/.
Import path: github.com/cocoonstack/cocoon-common/apis/v1.
| Kind | Short names | Purpose |
|---|---|---|
CocoonSet |
cs, cocoonsets |
Declarative agent cluster: one main agent, agent.replicas sub-agents, and any number of toolbox VMs |
CocoonHibernation |
ch, cocoonhibernations |
Per-pod hibernate / wake request |
Both carry a status subresource and a Ready condition built by
k8s.NewReadyCondition.
| Field | Default | Notes |
|---|---|---|
suspend |
false |
Suspends the whole set |
snapshotPolicy |
always |
always / main-only / never |
hibernatePolicy |
retain |
retain keeps the scheduling seat while suspended; release frees it once the hibernate snapshot is registry-verified |
nodePool |
default |
Selected via the cocoonstack.io/pool node label |
snapshotCompatibilityClass |
unset | Certified guest-visible CPU ABI; rendered as a hard node selector |
nodeName |
unset | Pins the set to one node (cross-node migrate); empty leaves placement to the scheduler |
agent |
required | AgentSpec — image, replicas, mode, plus the shared VMOptions |
toolboxes |
unset | []ToolboxSpec — named auxiliary VMs |
VMOptions is inlined into both AgentSpec and ToolboxSpec: os,
backend, connType, network, forcePull, noDirectIO, probePort,
storage, resources.
Toolbox names contain 1–63 characters and match
^[a-z0-9]([-a-z0-9]*[a-z0-9])?$. The webhook additionally rejects duplicate
or purely numeric names. Static toolboxes require staticIP and staticVMID
at admission and are unmanaged; image is required for run/clone toolboxes.
Spec enum types are strings with a +kubebuilder:validation:Enum marker and
an IsValid() predicate. Types with defaults also provide Default() to
resolve the empty string; a non-empty value is returned unchanged, so this
method does not replace validation.
| Type | Values | Default() |
|---|---|---|
AgentMode |
clone, run |
clone |
ToolboxMode |
run, clone, static |
run |
OSType |
linux, windows, android, macos |
linux |
SnapshotPolicy |
always, main-only, never |
always |
HibernatePolicy |
retain, release |
retain |
Backend |
cloud-hypervisor, firecracker |
cloud-hypervisor |
ConnType |
ssh, rdp, vnc, adb |
none — empty infers it from the VNC port, then the OS |
HibernationDesire |
Hibernate, Wake |
none |
CocoonSetPhase and CocoonHibernationPhase are status-only enums with no
IsValid() — the controller is their only writer.
For managed VMs, Backend: firecracker requires mode: run, boots a kernel
directly, and accepts only OCI VM images. The webhook rejects clone mode,
cloudimg URLs, and Windows guests. Static toolboxes skip backend/image checks
because vk-cocoon does not create their VMs.
Two rules ship in the generated CocoonSet CRD, so they hold for any client that never touches the Go types:
- message: hibernatePolicy=release requires agent.replicas=0 and no toolboxes
rule: '!has(self.hibernatePolicy) || self.hibernatePolicy != ''release''
|| ((!has(self.agent.replicas) || self.agent.replicas == 0)
&& (!has(self.toolboxes) || size(self.toolboxes) == 0))'
- message: snapshotCompatibilityClass is immutable once set
rule: '!has(oldSelf.snapshotCompatibilityClass)
|| (has(self.snapshotCompatibilityClass)
&& self.snapshotCompatibilityClass == oldSelf.snapshotCompatibilityClass)'
Seat release is restricted to a main-only set until sub-agent and toolbox restore intent is defined. The compatibility class is immutable because changing it would invalidate every memory snapshot the set has already published.
CocoonHibernation adds one: spec.podRef is immutable.
zz_generated.deepcopy.go and apis/v1/crds/*.yaml are generated by
controller-gen, pinned through hack/tools.go so no separate binary
download is needed:
make generate # deepcopy methods
make manifests # CRD YAML
Run both after any change to apis/v1/*_types.go and commit the result. The
lint workflow re-runs them and fails on a dirty tree, so a forgotten
regeneration is caught in CI rather than in a downstream repo.
Field godoc becomes the CRD description and is what kubectl explain
prints — it is API documentation, not a code comment, and removing it changes
the generated YAML.
Consumers pin a release or commit in go.mod; changing cocoon-common alone
does not update their binaries. A consumer must update its dependency to
include a fix before rebuilding with it. A workspace can resolve a newer
sibling checkout without changing that pin.
cocoon-operator also copies the CRD YAML into its kustomize tree with
make import-crds. This reads the resolved module directory, so use
GOWORK=off make import-crds to copy from the committed dependency version.
Commit the copied config/crd/bases/*.yaml along with the dependency update;
a Go module update alone does not update the manifests deployed to a cluster.