| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Shared Go packages for cocoonstack services.
This repository keeps cross-project contracts in one place instead of re-exporting them from cocoon-operator. cocoon-operator, cocoon-webhook, vk-cocoon, and cocoon-net all consume the same package set directly.
go get github.com/cocoonstack/cocoon-common@latestgit clone https://github.com/cocoonstack/cocoon-common.git
cd cocoon-common
make buildTyped Go definitions for the cocoonset.cocoonstack.io/v1 API group, plus the generated CRD YAML manifests under apis/v1/crds/. The package ships:
Two CEL rules ship inside the generated CocoonSet CRD, so they hold even for a client that never touches these Go types: hibernatePolicy: release requires a main-only set (agent.replicas=0, no toolboxes), and snapshotCompatibilityClass is immutable once set — a snapshot class change would invalidate every memory snapshot the set has already published.
Downstream operators import these via go list -m and copy the CRD YAML into their own kustomize tree (see make import-crds in cocoon-operator). Regenerate via make generate manifests after any type change.
Use meta for:
All identifiers live under three cocoonstack.io prefixes:
| Prefix | Used for | Examples |
|---|---|---|
| cocoonset.cocoonstack.io/ | CocoonSet CRD group, Pod selector labels, and CocoonSet-level fields the operator mirrors onto a managed Pod | cocoonset.cocoonstack.io/v1, name, role, slot, mode, image, os, storage, snapshot-policy, network, managed, force-pull, generation, hibernated-on-node |
| vm.cocoonstack.io/ | VM-instance metadata — observed runtime state plus per-VM spec the operator hands to vk-cocoon | id, name, ip, vnc-port, hibernate, restore-from-hibernate, keep-snapshot-on-delete, fork-from, clone-from-dir, conn-type, backend, no-direct-io, probe-port, lifecycle-state, lifecycle-observed-generation, lifecycle-state-message |
| cocoonstack.io/ | Node labels vk-cocoon stamps on its virtual node and the operator selects on | pool, snapshot-cpu-class |
For typed annotation access, prefer the meta.VMSpec / meta.VMRuntime / meta.HibernateState wrappers over raw map manipulation:
// Managed=true: vk-cocoon owns lifecycle; false: adopt pre-assigned VM.
spec := meta.VMSpec{
VMName: "vk-prod-demo-0",
Image: "ghcr.io/cocoonstack/cocoon/ubuntu:24.04",
Mode: string(v1.AgentModeRun),
OS: string(v1.OSLinux),
Backend: string(v1.BackendFirecracker),
SnapshotPolicy: string(v1.SnapshotPolicyAlways),
Managed: true,
ForcePull: true, // bypass image cache
ProbePort: "22", // TCP readiness probe on port 22
}
spec.Apply(pod)
// vk-cocoon side: write runtime state back to the pod.
runtime := meta.VMRuntime{VMID: vmID, IP: ip}
runtime.Apply(pod)
// hibernate / wake
meta.HibernateState(true).Apply(pod)Two snapshot tag constants anchor the cross-component contract:
meta.ShouldSnapshotVM(spec, role) is the single shared decoder for the SnapshotPolicy / role decision. vk-cocoon consults it on the producer side (should I push this VM?) and cocoon-operator on the GC side (should I delete this tag?) so the two cannot drift — under main-only both sides agree only the main agent is touched. The role comes from the pod's CocoonSet ownership (meta.RoleForPod), never from a VM-name suffix.
meta.LabelSnapshotCompatibilityClass (cocoonstack.io/snapshot-cpu-class) closes the same loop for placement: CocoonSetSpec.SnapshotCompatibilityClass names a certified guest-visible CPU ABI, cocoon-operator renders it as a hard node selector on every managed pod, and vk-cocoon publishes the label on nodes configured with that class and refuses any classified pod it cannot serve. It is independent from LabelNodePool, so several workload pools can share one snapshot class.
meta.AnnotationKeepSnapshotOnDelete marks a pod delete as a scheduling-seat release rather than a teardown: vk-cocoon keeps the node-local snapshot as the warm-wake cache instead of dropping it with the VM. It is best-effort by contract — a lost flag costs the wake a registry pull, never correctness.
meta.LifecycleStatus is the typed contract for the lifecycle-state annotation triple vk-cocoon writes (state, observed-generation, message):
status := meta.LifecycleStatus{
State: meta.LifecycleStateReady,
ObservedGeneration: meta.ReadCocoonSetGeneration(pod),
}
// In-memory: mutate the pod we already hold.
status.Apply(pod)
// Wire: status.Annotations() returns the annotation key/value map
// (nil values delete the key); wrap with k8s.AnnotationsMergePatch
// for an apiserver merge-patch body.
patch, _ := k8s.AnnotationsMergePatch(status.Annotations())cocoon-operator stamps the owning CocoonSet's metadata.generation onto the pod via meta.StampCocoonSetGeneration so vk-cocoon can echo it back as lifecycle-observed-generation. Counter-based completion lets clients tell "the operation I asked for finished" from "an older completion is still being reported", without depending on wall-clock skew.
Use k8s.LoadConfig() to resolve cluster configuration from:
Other helpers in this package:
Shared admission-webhook scaffolding. Example:
import commonadmission "github.com/cocoonstack/cocoon-common/k8s/admission"
mux.HandleFunc("/mutate", func(w http.ResponseWriter, r *http.Request) {
commonadmission.Serve(w, r, 0 /* default max body */, func(ctx context.Context, rev *admissionv1.AdmissionReview) *admissionv1.AdmissionResponse {
// ... your handler logic ...
return commonadmission.Allow()
})
})The registry side of the platform: cocoon VM snapshots and cloud images travel between nodes as OCI artifacts, and every component that touches them shares this code so producer and consumer cannot drift on the wire format.
httpx.Run(ctx, shutdownTimeout, specs...) starts one or more servers built by httpx.NewServer (which applies DefaultReadHeaderTimeout) and shuts them all down together when the context fires or any one of them fails. Both plain and TLS servers register through HTTPServerSpec / HTTPSServerSpec.
Use log.Setup(ctx, envVar) error to initialize the shared logger from an environment variable, defaulting to info. Returns an error if the level value is invalid.
make build # build all packages
make test # run tests with coverage
make lint # run golangci-lint on linux + darwin
make fmt # format code
make generate # regenerate deepcopy methods for api types
make manifests # regenerate CRD YAML manifests for api types
make all # full pipeline: deps + generate + manifests + fmt + lint + test + build
make help # show all targetsAfter any change to apis/v1/*_types.go, run make generate manifests and commit the regenerated zz_generated.deepcopy.go and apis/v1/crds/*.yaml. CI rejects PRs that forget this step.
| Project | Role |
|---|---|
| cocoon-operator | CocoonSet and Hibernation controllers |
| cocoon-webhook | Admission webhook for sticky scheduling |
| vk-cocoon | Virtual kubelet provider |
| cocoon-net | Per-host VM networking |
| Back | FazBrowse Home | New Git URL |