docs(platforms): supported-host matrix and air-gapped install runbook#927
Conversation
Two self-host gaps left the journey with dead ends. There was no single page saying which machines can be KVM workers versus control-plane only, so the requirement was discoverable only by hitting mitos doctor on a rejected node. And the offline story was sold (for example in the E2B migration doc) with no runbook behind it. Add docs/platforms/supported-hosts.md: a host-support matrix that ties each requirement to the mitos doctor check that gates it, splits control-plane from KVM-worker requirements, and is explicit about bare metal (supported), nested-virt cloud instances (supported if doctor passes), plain cloud VMs and rescue kernels (not supported as workers). Add docs/platforms/air-gapped.md: an offline runbook that stages the three things an install needs inside the boundary (the container images under ghcr.io/mitos-run, the OCI Helm chart, and the per-node guest kernel plus Firecracker binary), installs against them via image.registry and global.imageTag, and notes that the runtime dials no third-party SaaS. Cross-link both from prerequisites.md so neither is a dead end. Closes #777 Closes #788 Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
📝 WalkthroughWalkthroughAdds platform documentation for supported host requirements, ChangesPlatform documentation
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/platforms/air-gapped.md`:
- Around line 86-91: Update the mitos doctor documentation to accurately
describe its offline behavior: when kubeconfig is available, checks may contact
the Kubernetes cluster API; without it, cluster checks report errors while node
checks still run. Clarify that pre-install execution can exit non-zero because
cluster checks are unavailable, and remove the claim that every check reads only
the local host.
- Around line 74-78: Update the Helm installation flow in the air-gapped
platform instructions to create and label the mitos namespace with
pod-security.kubernetes.io/enforce=privileged before running helm install.
Remove reliance on --create-namespace so the installation uses the pre-labeled
namespace while preserving the existing chart, version, registry, and image tag
options.
- Around line 3-9: Revise the introductory scope in the air-gapped runbook to
guarantee only absence of third-party SaaS connectivity for the specified
release/version boundary. Remove or qualify claims that the product is fully
offline or not degraded, and explicitly distinguish this guarantee from required
internal registry, Kubernetes, and in-cluster network traffic.
In `@docs/platforms/supported-hosts.md`:
- Around line 49-50: Update the definition of “Supported” in the platform
documentation to state that any conformant Kubernetes node can host the control
plane, while preserving the distinction that supported hosts can be KVM workers
and unsupported hosts cannot.
- Around line 9-12: Update the supported KVM worker rule in the documentation to
define support as having no required check with FAIL status rather than
requiring every signal to pass. Clarify that WARN results, including unavailable
userfaultfd or failed data-directory probing, indicate degraded or unverifiable
capability and do not make the machine unsupported, while retaining the non-zero
FAIL and remediation behavior.
- Around line 33-42: Update the supported-hosts requirements matrix to
accurately distinguish rows backed by named mitos doctor checks from
prerequisite-only requirements: use kernel-module-nf_tables for nf_tables, and
either separate the real-filesystem prerequisite row or revise the matrix
introduction so it no longer implies every row has a doctor check.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 91d7a82a-c347-47df-b5de-af10d8cafab4
📒 Files selected for processing (3)
docs/platforms/air-gapped.mddocs/platforms/prerequisites.mddocs/platforms/supported-hosts.md
| mitos self-hosts fully offline. Nothing in the runtime dials a third-party SaaS: | ||
| billing, self-serve signup, and abuse checks are hosted-only surfaces that are | ||
| capability-gated off by default, so an air-gapped install is a clean, complete | ||
| product, not a degraded one. What an offline install needs is exactly three | ||
| things staged inside the boundary: the container images, the Helm chart, and the | ||
| per-node microVM assets (guest kernel and Firecracker). This runbook stages each | ||
| one and installs against them. |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the target doc and nearby references
git ls-files docs/platforms/air-gapped.md
wc -l docs/platforms/air-gapped.md
cat -n docs/platforms/air-gapped.md | sed -n '1,140p'
printf '\n--- related references ---\n'
rg -n "fully offline|air-gapped|third-party SaaS|billing|self-serve signup|abuse checks|Helm chart|Firecracker|guest kernel|runtime dials" docs . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'Repository: mitos-run/mitos
Length of output: 50372
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- docs/platforms/air-gapped.md ---\n'
cat -n docs/platforms/air-gapped.md | sed -n '1,120p'
printf '\n--- precise references ---\n'
rg -n -m 40 "fully offline|third-party SaaS|hosted-only surfaces|capability-gated off by default|clean, complete product|degraded one|exactly three things|internal Kubernetes|cluster-network" docs internalRepository: mitos-run/mitos
Length of output: 244
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf -- '--- docs/platforms/air-gapped.md ---\n'
cat -n docs/platforms/air-gapped.md | sed -n '1,140p'
printf -- '\n--- precise references ---\n'
rg -n -m 40 "fully offline|third-party SaaS|hosted-only surfaces|capability-gated off by default|clean, complete product|degraded one|exactly three things|internal Kubernetes|cluster-network" docs internalRepository: mitos-run/mitos
Length of output: 6850
Scope the offline guarantee to external connectivity. “Fully offline” and “not a degraded product” are broader than the contract here; keep this tied to the release/version boundary and separate “no third-party SaaS calls” from the internal registry and in-cluster Kubernetes/network traffic this install still depends on.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/platforms/air-gapped.md` around lines 3 - 9, Revise the introductory
scope in the air-gapped runbook to guarantee only absence of third-party SaaS
connectivity for the specified release/version boundary. Remove or qualify
claims that the product is fully offline or not degraded, and explicitly
distinguish this guarantee from required internal registry, Kubernetes, and
in-cluster network traffic.
| helm install mitos oci://registry.internal/mitos/charts/mitos \ | ||
| --version X.Y.Z -n mitos --create-namespace \ | ||
| --set image.registry=registry.internal/mitos \ | ||
| --set global.imageTag=vX.Y.Z | ||
| ``` |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Label the namespace before installing.
prerequisites.md states that the install namespace must be labeled pod-security.kubernetes.io/enforce=privileged and that Helm cannot create this label. Using --create-namespace here creates an unlabeled namespace, so PSA-enabled clusters can reject the workloads.
Proposed command flow
-helm install mitos oci://registry.internal/mitos/charts/mitos \
- --version X.Y.Z -n mitos --create-namespace \
+kubectl create namespace mitos
+kubectl label namespace mitos \
+ pod-security.kubernetes.io/enforce=privileged --overwrite
+helm install mitos oci://registry.internal/mitos/charts/mitos \
+ --version X.Y.Z -n mitos \📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| helm install mitos oci://registry.internal/mitos/charts/mitos \ | |
| --version X.Y.Z -n mitos --create-namespace \ | |
| --set image.registry=registry.internal/mitos \ | |
| --set global.imageTag=vX.Y.Z | |
| ``` | |
| kubectl create namespace mitos | |
| kubectl label namespace mitos \ | |
| pod-security.kubernetes.io/enforce=privileged --overwrite | |
| helm install mitos oci://registry.internal/mitos/charts/mitos \ | |
| --version X.Y.Z -n mitos \ | |
| --set image.registry=registry.internal/mitos \ | |
| --set global.imageTag=vX.Y.Z |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/platforms/air-gapped.md` around lines 74 - 78, Update the Helm
installation flow in the air-gapped platform instructions to create and label
the mitos namespace with pod-security.kubernetes.io/enforce=privileged before
running helm install. Remove reliance on --create-namespace so the installation
uses the pre-labeled namespace while preserving the existing chart, version,
registry, and image tag options.
| `mitos doctor` is offline-safe: every check reads the local host, none dial out. | ||
| Run it on each KVM worker before and after install: | ||
|
|
||
| ```bash | ||
| mitos doctor | ||
| ``` |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Clarify mitos doctor’s offline behavior.
cmd/mitos/main.go attaches a Kubernetes client when kubeconfig is available, so doctor can contact the cluster API. Without kubeconfig, cluster checks report errors while node checks still run. Do not say every check reads only the local host; explain that pre-install execution may exit non-zero because cluster checks are unavailable.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/platforms/air-gapped.md` around lines 86 - 91, Update the mitos doctor
documentation to accurately describe its offline behavior: when kubeconfig is
available, checks may contact the Kubernetes cluster API; without it, cluster
checks report errors while node checks still run. Clarify that pre-install
execution can exit non-zero because cluster checks are unavailable, and remove
the claim that every check reads only the local host.
| The rule is simple and mechanical: a machine is a supported **KVM worker** if it | ||
| passes `mitos doctor`. That command is the per-requirement hard gate; it exits | ||
| non-zero and prints an actionable remediation for every requirement it finds | ||
| unmet, so you never have to guess why a node was rejected. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Separate FAIL gates from WARN-only checks.
internal/agentcli/doctor.go returns WARN when userfaultfd is unavailable and when data-directory probing fails, so not every unmet signal is a hard, non-zero gate. Document support as “no required check is FAIL”; describe WARN as degraded or unverifiable capability.
Also applies to: 44-45
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/platforms/supported-hosts.md` around lines 9 - 12, Update the supported
KVM worker rule in the documentation to define support as having no required
check with FAIL status rather than requiring every signal to pass. Clarify that
WARN results, including unavailable userfaultfd or failed data-directory
probing, indicate degraded or unverifiable capability and do not make the
machine unsupported, while retaining the non-zero FAIL and remediation behavior.
| | Requirement | `mitos doctor` check | Needed for | | ||
| | --- | --- | --- | | ||
| | `/dev/kvm` present and usable | `kvm-device` | booting every microVM | | ||
| | `kvm_intel` / `kvm_amd` loaded | `kernel-module-*` | KVM acceleration | | ||
| | `vhost_vsock` module | `kernel-module-vhost_vsock` | guest agent exec/files/env over vsock | | ||
| | `tun` module | `kernel-module-tun` | per-sandbox tap networking | | ||
| | `nf_tables` support | (see prerequisites) | husk egress isolation and kube-proxy | | ||
| | containerd on a real filesystem | (see prerequisites) | the overlay snapshotter cannot stack on overlay/tmpfs | | ||
| | adequate free space on `--data-dir` | `data-dir-space` | template rootfs images, snapshots, jailer chroots | | ||
| | `CONFIG_USERFAULTFD=y` (perf path) | `userfaultfd` | hugepage-backed restore and snapshot-resume prefetch | |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- supported-hosts.md (relevant slice) ---'
nl -ba docs/platforms/supported-hosts.md | sed -n '20,70p'
echo
echo '--- doctor-check references ---'
rg -n "kvm-device|kernel-module-|vhost_vsock|tun|nf_tables|data-dir-space|userfaultfd|prerequisites|containerd on a real filesystem" docs src . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' || trueRepository: mitos-run/mitos
Length of output: 237
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- supported-hosts.md (relevant slice) ---'
sed -n '20,70p' docs/platforms/supported-hosts.md | cat -n
echo
echo '--- search for check names and prerequisite wording ---'
rg -n "kvm-device|kernel-module-|vhost_vsock|kernel-module-vhost_vsock|kernel-module-tun|nf_tables|data-dir-space|userfaultfd|real filesystem|overlay snapshotter|prerequisite" docs . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' || trueRepository: mitos-run/mitos
Length of output: 50372
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- docs/cli.md around doctor checks ---'
sed -n '200,235p' docs/cli.md | cat -n
echo
echo '--- docs/platforms/prerequisites.md relevant rows ---'
sed -n '12,45p' docs/platforms/prerequisites.md | cat -n
echo
echo '--- docs/platforms/host-prerequisites.md relevant rows ---'
sed -n '12,40p' docs/platforms/host-prerequisites.md | cat -nRepository: mitos-run/mitos
Length of output: 6988
Align the matrix with mitos doctor
nf_tableshas an actual doctor check (kernel-module-nf_tables); the real-filesystem requirement is prerequisite-only and doesn’t map to a doctor check name.- Either split prerequisite-only rows out, or change the intro so it doesn’t claim every row names a
mitos doctorcheck.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/platforms/supported-hosts.md` around lines 33 - 42, Update the
supported-hosts requirements matrix to accurately distinguish rows backed by
named mitos doctor checks from prerequisite-only requirements: use
kernel-module-nf_tables for nf_tables, and either separate the real-filesystem
prerequisite row or revise the matrix introduction so it no longer implies every
row has a doctor check.
| "Supported" below means "can be a KVM worker". Anything can host the control | ||
| plane. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Do not claim that “anything” can host the control plane.
The prerequisite documentation limits this to conformant Kubernetes nodes. Replace this with “any conformant Kubernetes node” and preserve the supported/unsupported distinction.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/platforms/supported-hosts.md` around lines 49 - 50, Update the
definition of “Supported” in the platform documentation to state that any
conformant Kubernetes node can host the control plane, while preserving the
distinction that supported hosts can be KVM workers and unsupported hosts
cannot.
Thinking Path
Linked Issues or Issue Description
Closes #777. Closes #788.
What Changed
Verification
Risks
Low risk. Documentation only. The pages describe existing, shipped behavior (the chart levers and doctor checks already exist); they add no claims that are not reproducible from the chart and the doctor command.
Model Used
Claude Opus 4.8 (claude-opus-4-8), 1M context, extended thinking.
Summary by CodeRabbit