Repository navigation
Conversation
… and load an AppArmor profile granting userns buildHosts.cache.create renders the shared RWX build-cache claim (storageClass and size required, kept on uninstall). buildHosts.sandbox.appArmorLoader ships one profile, mw-build-host (unconfined apart from granting userns, since RuntimeDefault denies the mount bwrap needs), and a privileged DaemonSet on the hosts' pools loads it with the runner image's apparmor_parser. The host pods then run under Localhost/mw-build-host, and naming any other profile beside the loader is refused. The runner image gains apparmor (parser >= 4, asserted). Both are opt-in, so every estate renders unchanged. Chart test: the claim, the loader and the pods' profile, plus two refusals; a profile that drops userns turns it red. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The constant loader checksum allows profile-only upgrades to leave stale kernel policy loaded while readiness remains green.
1 open issue
What changed in this PR
This PR adds opt-in infrastructure for standing build hosts: a chart-managed shared cache and an AppArmor loader that enables sandbox user namespaces.
Changes:
- Adds a retained ReadWriteMany cache claim with required storage class and size.
- Adds an AppArmor profile and loader DaemonSet, plus parser support in the runner image.
- Extends chart checks, refusal fixtures, and documentation; live-node compatibility remains unverified.
| File | Description |
|---|---|
src/MeshWeaver.Documentation/Data/Architecture/BuildHosts.md |
Documents cache creation, profile loading, and pending live verification. |
deploy/helm/values.yaml |
Adds opt-in cache and loader settings. |
deploy/helm/templates/build-host/cache-pvc.yaml |
Creates the retained shared cache claim. |
deploy/helm/templates/build-host/apparmor-loader.yaml |
Defines the AppArmor profile and loader DaemonSet. |
deploy/helm/templates/build-host/_build-hosts.tpl |
Validates cache settings and selects the loader’s profile. |
deploy/build-host/Dockerfile |
Installs AppArmor and checks parser version 4. |
deploy/aks/scripts/testdata/values.build-hosts-loader.yaml |
Provides a cache-and-loader fixture. |
deploy/aks/scripts/testdata/values.build-hosts-loader-other-profile.yaml |
Tests refusal of a conflicting profile. |
deploy/aks/scripts/testdata/values.build-hosts-cache-no-class.yaml |
Tests refusal of a missing storage class. |
deploy/aks/scripts/test-build-hosts.sh |
Checks rendered resources, opt-in behavior, and refusals. |
Review effort: Balanced
… not the chart's An operator Job applies the chart and holds no write on DaemonSets, by design. Loading a kernel profile onto a node pool is node-level setup that the estate's CI-runners lane applies, never an instance release. The chart keeps the cache claim; the pods name the profile through the existing sandbox.appArmorProfile Localhost / appArmorLocalhostProfile keys. The loader, its fixture and the runner image's apparmor package are removed, and the chart test now refuses any node-level DaemonSet rendered by the chart. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| profile that grants `userns` to the build container. **Decided (maintainer, 2026-10-25): the | ||
| profile.** The estate's CI-runners lane loads it onto the CI pools and the record names it (§3). Whether a host on the |
|
Closing this one: core's chart is frozen, and chart edits now go to Systemorph/MeshWeaver.Deploy. The content isn't dropped. The |


The maintainer chose two prerequisites for the standing build hosts (2026-10-25): a cache volume the chart creates, and an AppArmor profile rather than the node-wide sysctl. This PR adds the first. The second's loader is node-level setup, so it lands in the estate's CI-runners lane, not here.
buildHosts.cache.createrenders thebuild-cacheRWX claim.storageClassandsizeare required, and the claim is kept on uninstall (helm.sh/resource-policy: keep). It is opt-in, so every estate renders unchanged.operator-rbac.yaml's scope note: platform setup is installed by an approved lane, never by a lifecycle run). The first revision of this PR shipped a loader DaemonSet, and the operator'severy kind the chart renders is writablecheck turned red on it; that revision is removed. The record names the profile through the existingsandbox.appArmorProfile: Localhost/appArmorLocalhostProfile: mw-build-host. The chart test now refuses any node-level DaemonSet rendered by the chart.Tests:
test-build-hosts.sh: the claim's shape and keep policy, nothing rendered withoutcache.create, no DaemonSet, and a refusal forcache.createwithout a class.operator/test/run-tests.sh: green, including the RBAC coverage check.🤖 Generated with Claude Code