- Shipped
- September 23, 2026 at 2:02 AM UTC
- Author
- Kamo
- Commit
- 53d1b49
A member's own Linux computer, running as a KubeVirt VM in its organization's namespace and opened from the browser. Separate from desktop/ in every way that matters: that is one shared machine for platform admins, deliberately on the pod network so it can reach the database, NATS and MinIO. These are tenant machines whose defining property is the opposite. Three facts shaped this, and each contradicts the obvious reading: - Pausing a VM frees nothing. KubeVirt's docs: pausing "freezes the process without releasing CPU resources, but memory remains allocated". So sleeping is suspend-to-DISK — the guest writes its memory into its own swap and powers off, the launcher pod terminates, and the memory request goes back to the scheduler. That needs runStrategy RerunOnFailure, documented to let a guest shut itself down without being relaunched; under Always the sleep would be undone in seconds. - Headroom is bounded by scheduler REQUESTS, not physical RAM. A launcher pod that does not fit sits Pending forever, which looks exactly like a computer that never appears and logs nothing. So a wake is refused before it is attempted, and the refusal names the number. - Cilium reserved identities cannot be matched by a CIDR rule. **************** records that from an outage, where toEntities [host, remote-node] had to be added to ALLOW the node. Here the same fact is the defence inverted: no rule names them, and default-deny.yaml egressDenies them so no later edit can open them — a Cilium deny beats every allow, from any file. Isolation is asserted rather than reviewed. canary/verify-isolation.sh runs a pod carrying the same kamo.io/hc-org label a launcher pod carries, so it gets the same identity and the same policy, and probes both directions: the nodes, kube-apiserver, YugabyteDB, NATS, MinIO, kube-dns, the metadata address and another org's computers must all be unreachable; the internet and same-org computers must work. It also reports, without asserting, whether the upstream router hairpins — api.kamocrm.com resolves to 47.181.8.84 while Traefik's LoadBalancer IP is k1m1's own 192.168.4.22, so the agent's heartbeat is best-effort by construction and nothing depends on it. White-labeling needs no distro rebuild, which was checked surface by surface first. Every visible Xubuntu identity is config or a removable package. strip-distro-identity.sh removes them and pins them so apt cannot restore them — a shadowed file comes back on the next upgrade and the failure is a tenant seeing somebody else's logo weeks later. The golden image ships with no logo and no colours at all; the agent paints them per org from Behavior & Labeling, honouring the rule that a tenant never sees KamoCRM's images. The agent is stdlib-only and cannot call out, because the network policy means there is nobody to call. Config is pushed in, the sleep decision is local so it survives a Kamo outage, and hibernation readiness is verified (swap size, resume= AND resume_offset=, disk in /sys/power/state) before the idle timer is armed — a misconfigured hibernate does not raise, it boots clean and loses the session. 26 tests cover that arithmetic plus the branding input validation. **************** is applied by hand (ddl-auto is none and InitializerService is not deployed) and has been, against the live database as the owner. It needed a grant the existing recipe does not mention: a NEW schema has no ACL, so the global default privileges that cover tables left kamo_app with "permission denied for schema hosted_computer" on the first insert. Verified after. Every manifest validated with kubectl apply --dry-run=server.
