POC: split rootfs into bootstrap + pkgs images - #6062
Draft
eriknordmark wants to merge 56 commits into
Draft
Conversation
Add dedicated bootstrap/pkgs LinuxKit templates, glue them into the build graph, and expose make targets for producing each squashfs so the new architecture can be built independently of the legacy rootfs. Signed-off-by: Nikolay Martyanov <nikolay@zededa.com>
Wire the split rootfs into developer workflows by adding live/run targets, and documenting the new entry points in the help output. Signed-off-by: Nikolay Martyanov <nikolay@zededa.com>
Introduce the external-services loader that discovers pkgs.img, mounts it, and starts services through containerd, and register the agent inside the boot sequence. Signed-off-by: Nikolay Martyanov <nikolay@zededa.com>
Add SPLIT-ROOTFS.md outlining the motivation, build pipeline, and Pillar integration for the bootstrap/pkgs experiment. Signed-off-by: Nikolay Martyanov <nikolay@zededa.com>
- Makefile: installer-split target, eve-hv-supported metadata injection - installer.yml.in: include rootfs-ext.img in installer - pkg/installer/install: read HV from CONFIG, copy ext to persist - pkg/grub: read eve-hv-type from CONFIG, write /run/eve-hv-type - storage-init: select ext4/ZFS based on CONFIG eve-hv-type - onboot.sh: propagate CONFIG eve-hv-type to runtime - extsloader: skip kube service when HV != k - rootfs_core/ext/universal.yml.in: split rootfs templates - docs/SPLIT-ROOTFS-DESIGN.md: v1.6 with POC implementation status Signed-off-by: Nikolay Martyanov <ohmspectator@gmail.com>
- gate zedkube startup in device-steps by eve-hv-type (/run/eve-hv-type, fallback /etc/eve-hv-type). - subscribe to ENClusterAppStatus in zedmanager only for kube HV. - update rootfs_ext service template to match the split/universal service set for this WIP. Signed-off-by: Nikolay Martyanov <ohmspectator@gmail.com>
Exclude /persist/pkgs and /persist/eve-services from volumemgr large-file scan to avoid oversized DiskMetric payloads in split rootfs runs. Also tighten FindLargeFiles exclude matching to directory boundaries and add a regression test. Signed-off-by: Nikolay Martyanov <ohmspectator@gmail.com>
Switch kube-only behavior from build-time assumptions to runtime checks for pillar-k running on non-k hypervisor types. - gate PVC disk metrics and PVC format bootstrap scan by runtime HV type - add shared kube runtime guard and apply it across exported kubeapi functions in //go:build k files - add runtime fail-fast checks in zedkube and kubevirt hypervisor exported entry points - reject kubevirt hypervisor selection when runtime HV type is not k - make CSI handler constructor safely fall back when kube runtime is disabled - keep node-drain behavior runtime-aware (NOTSUPPORTED on non-k) - handle DeleteNAD call-site errors explicitly This keeps split/universal images runtime-driven instead of relying on compile-time -k behavior. Signed-off-by: Nikolay Martyanov <ohmspectator@gmail.com>
Split-rootfs OTA update mechanism:
- Makefile: eve-split target rewritten to avoid recursive make (fixes
dirty-timestamp and monolithic rootfs rebuild issues). Uses cp instead
of symlinks so Docker COPY gets real files, not dangling symlinks.
- Dockerfile.in: conditional #SPLIT_ROOTFS_LABEL# for Extension disk label
- baseosmgr/worker.go: WriteExtensionToPersist after WriteToPartition
- baseosmgr/handleextension.go: CAS helper for Extension extraction
- cas/extension.go: FindAdditionalDiskBlob for OCI manifest walking
- extsloader: CAS self-heal via Puller.Pull with FilesTarget{Disks},
pubsub ProcessChange for BaseOsStatus/ContentTreeStatus subscriptions
- types/locationconsts.go: shared Extension A/B path constants
- Roadmap doc updated with HV-agnostic Core limitation note
Eden test infrastructure:
- tests/eden/run.sh: split-rootfs test entry (test #8)
- tests/eden/prepare-split-rootfs-test.sh: build/push/setup/test script
Tested: monolith(15.11.0) -> split OTA, CAS self-heal extracts Extension,
dm-verity mount, debug/SSH container starts from Extension.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- types/extsloadertypes.go: new ExtsloaderStatus type with State enum (Starting/Ready/Failed), published via pubsub by extsloader - extsloader: publish ExtsloaderStatus via pubsub instead of only writing /run/extsloader-state.json (kept as debug aid, marked for removal) - nodeagent: subscribe to ExtsloaderStatus from extsloader, check Extension ready state before marking update TestComplete in testing window (handletimers.go:checkExtsloaderReady). If /etc/ext-verity-roothash exists but Extension not ready, testing window keeps waiting → eventual reboot → automatic rollback - base/logobjecttypes.go: register ExtsloaderStatusLogType Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- pkg/pillar/Dockerfile: add cryptsetup package (provides veritysetup) to the runtime PKGS. Required for dm-verity verification of Extension. - extsloader: remove legacy read-only loop mount fallback. dm-verity is now mandatory for Extension mounting. If veritysetup is missing or roothash not found, mount fails → extsloader reports failed → nodeagent testing window holds → rollback. - Remove "no-verity" PCR12 measurement path since verity is always used. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- tests/eden/prepare-broken-split-image.sh: builds a split-rootfs EVE image with corrupted ext-verity-roothash for rollback testing - tools/make-ext-verity.sh: dm-verity hash tree generation for Extension Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sitions Add CleanupUnusedExtension() to baseosmgr/handleextension.go. Called when a partition transitions to "unused" state: - After successful update (handleZbootTestComplete): other slot's ext cleaned - After uninstall (doBaseOsUninstall): other partition marked unused, ext cleaned - After failed version check (doBaseOsActivate): partition marked unused, ext cleaned This prevents stale Extension images from accumulating on /persist. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… extraction rewrite - Add HV=uni build variant and eve-uni Make target for universal images - GRUB: add set_uni_boot with HV selection menu, EFI variable persistence, and cross-partition HV discovery for OTA from monolithic images - Installer: resolve universal HV from GRUB cmdline, write to CONFIG - onboot.sh: multi-source HV resolution (CONFIG > cmdline > /run > rootfs) with "uni" safety guard; device-steps.sh writes EFI var for next boot - baseosmgr: accept -uni- OTA updates on both kvm and k devices - Extension extraction: rewrite FindAdditionalDiskBlob → HasExtensionDisk + ExtractExtensionDisk using registry.Puller (handles Docker labels correctly) - vaultmgr: replace file-polling extsloader wait with pubsub subscription - zedagent: gate attestation on extsloader terminal state (PCR12 stability) - nodeagent: add diagnostic logging for vault/config timer states - manage-device-identity.sh: auto-detect swtpm in dist/<arch>/current/swtpm - extsloader: improved logging for extension search and CAS self-heal - types/memory.go: add ReadCgroupMemoryLimit/WriteCgroupMemoryLimit helpers - Eden tests: fix HV-dependent paths, improve cleanup between runs - Update bpftrace/recovertpm image hashes, update roadmap docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Default EVE_HV to uni (not kvm) in prepare scripts so rootfs identifies as universal image matching test expectations - Add TEST_ONLY env var for running individual tests with full Eden redeploy (clean disk, volumes, TPM state) - Clear stale Adam PCR enforcement before each test run - Remove Docker volumes during redeploy to prevent stale registrations - Wait for split v1 activation via eden.lim.test before running test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Five bugs found and fixed in the HV-type resolution chain for universal images built with HV=uni: 1. runme.sh: prepare_for_hv() bailed on "uni" — Docker image extraction (`docker run lfedge/eve installer_raw`) failed. Fix: accept "uni" with k-sized media (uni carries pre-compressed kube payloads that don't shrink further in the outer squashfs). 2. installer/install: cmdline check for resolved HV missed "xen" — selecting Xen from GRUB menu silently fell back to KVM. Fix: add `elif cmdline eve_hv_type=xen`. 3. rootfs.cfg: GRUB menu had no Xen entry. Fix: add Xen menuentry that restores the Xen boot chain (multiboot2/xen.gz on x86, xen_hypervisor/xen.efi on arm64) undoing set_kvm_boot overrides. 4. storage-init.sh: no guard against "uni" leaking to runtime. Fix: explicit fallback to kvm with warning log. 5. make-raw: read /root/etc/eve-hv-type which is "uni" in rootfs, so Kubevirt installs got wrong partition sizes (512MB rootfs instead of 4GB, 36MB EFI instead of 2GB). Fix: accept EVE_HV env var from installer, which passes the resolved eve_flavor. Additionally, split the _eve_uni variable into two explicit signals: - _eve_installer: "we are booting from installer media" (set only by grub_installer.cfg) - _eve_uni: "show the HV selection menu" (set by set_uni_boot based on context) This makes the installer-vs-OTA distinction explicit instead of relying on _eve_uni as a heuristic proxy. During installer boot, set_uni_boot always shows the menu with detected HV as default entry. During OTA boot, it resolves silently from the other partition. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Auto-generated by ./tools/update-component-sha.sh --pkg ./pkg/alpine after the preceding pkg/alpine Dockerfile fix produced a new clean content hash 32c9b42 (no dirty suffix). Covers 40 pkg/*/Dockerfile, build-tools/ver-update/Makefile, and eve-tools/bpftrace-compiler/root/Dockerfile. Excludes conf/server, which has an unrelated pre-existing WIP modification.
…plit Split rootfs is always universal — make all split-related targets automatically delegate to HV=uni so callers don't need to remember. Affected targets: eve-split, installer-split, split_rootfs, core_rootfs, ext_rootfs, live-split, live-split-k, run-split. eve-uni is now a simple alias for eve-split. Also add run-installer-split target for QEMU testing of the split installer (boots installer-split.raw, installs to target.img). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Test the full USB installer flow for split-rootfs universal images: 1. Builds installer-split.raw (auto HV=uni) 2. Optionally injects pre-defined HV into CONFIG (simulates ZFlash) 3. Configures Eden with custom-installer.path 4. QEMU boots installer, installs to target disk, reboots 5. Verifies: CONFIG HV, Extension mounted, dm-verity, PCR12, EFI var Usage: ./tests/eden/test-split-installer.sh # default KVM (60s timeout) INSTALL_HV=k ./tests/eden/test-split-installer.sh # pre-parametrized Kubevirt INSTALL_HV=xen ./tests/eden/test-split-installer.sh # pre-parametrized Xen Covers test cases I1-I3 from the installer test plan: I1: Fresh install KVM (GRUB timeout default) I2: Fresh install Kubevirt (partition sizing, ZFS) I3: Fresh install Xen (boot chain) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
installer-split.raw lives at dist/<arch>/<ver>/installer-split.raw, not inside the installer/ subdirectory. Also handle the case where HV=uni delegation creates a different dist dir than current points to. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Symlink installer-split.raw to a short path under eden/dist/ before passing to Eden. The EVE dist directory name includes version, commit, kernel tag, and author — far exceeding the 108-byte Unix socket limit. Eden's StartSWTPM places the socket alongside the image file. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GRUB's measurefs generates TPM errors when efi.mod is not found in the installer squashfs. The errors fill the GRUB console and trigger the --MORE-- pager, which blocks unattended boot indefinitely. Disable TPM for installer tests. PCR12 measurement is already covered by the OTA test suite (update_split_pcr_enforcement_rollback). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
rootfs.cfg sets `set pager=1` which pauses output when the console fills up. During installer boot, TPM measurement errors (efi.mod not found in installer squashfs) generate enough output to trigger the --MORE-- prompt, blocking unattended installation. Fix: set pager=0 in grub_installer.cfg. The pager is never useful during installer boot (no one reads paged output on serial console during automated install). Re-enable TPM in the installer test script — PCR12 measurement is part of the verification suite. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Eden's default OVMF download does not include TPM2 drivers. This causes "Unknown TPM error" in GRUB and broken PCR measurements. The EVE-built OVMF at dist/<ver>/installer/firmware/ includes TPM2 support. Configure Eden to use the EVE-built OVMF_CODE.fd + OVMF_VARS.fd via eve.firmware config key. Also keep the grub_installer.cfg pager=0 fix as defense-in-depth — installer boot should never block on paged output regardless of TPM. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The ln -sf rootfs-ext.img command created a self-referencing symlink that overwrote the real rootfs-ext.img file produced by the ext_rootfs build. The subsequent rm -f deleted it entirely. The installer squashfs was missing rootfs-ext.img, causing containerd to fail with "Error creating 001-installer: exit status 1" (bind mount source not found). Fix: don't symlink rootfs-ext.img — it already exists as a real file. Only rootfs.img needs a symlink (to rootfs-core.img, by linuxkit convention). Only clean up the rootfs.img symlink, not rootfs-ext.img. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The installer squashfs does not include xen.gz — it's only in the installed Core rootfs. The Xen menu entry tried to load xen.gz via multiboot2 and failed with "file /boot/xen.gz not found". Fix: use KVM boot chain (direct linux) for the installer, but pass eve_hv_type=xen on cmdline. The installer writes "xen" to CONFIG. The installed system boots with Xen on first real boot from Core rootfs which has xen.gz. This only affects the installer GRUB menu. Normal Xen boot (from installed system) still uses set_xen_boot with the platform Xen defaults. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…binary Add live-split-xen and run-split-xen Make targets for testing the Xen variant without going through the installer. Same pattern as live-split-k: inject eve-hv-type=xen into CONFIG partition. Bump non-k memory settings from 640M to 1024M dom0_mem. The universal pillar binary (~143MB on disk, ~190MB RSS with THP=madvise) plus containerd plus extension services cannot fit in 640MB. This caused the system to thrash on Xen (where dom0_mem is enforced by the hypervisor) and is also used as the cgroup limit on KVM. New values: dom0=1024M/1536M, eve=800M/1200M, ctrd=400M/600M. Previous: dom0=640M/800M, eve=520M/650M, ctrd=320M/400M. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The 640M/800M dom0_mem values are production defaults that customers depend on. Changing them affects cgroup limits for ALL existing KVM deployments. The Xen memory issue with the universal binary needs a different solution (e.g., Xen-specific override or conf/grub.cfg). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On Xen, dom0_mem is enforced by the hypervisor as a physical RAM limit for dom0. The universal pillar binary (~143MB on disk, ~190MB RSS) plus containerd plus extension services cannot fit in the default 640MB. The system thrashes and agents fail to start. KVM is unaffected — dom0_mem is only a cgroup limit there, and Linux has full physical RAM available for paging. Xen memory tier: dom0=1024M/1536M, eve=800M/1200M, ctrd=400M/600M. KVM unchanged: dom0=640M/800M, eve=520M/650M, ctrd=320M/400M. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete the set: run-split (KVM/menu), run-split-k, run-split-xen. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All split run/live targets now explicitly name the HV variant: make live-split-kvm / run-split-kvm # CONFIG=kvm, no menu wait make live-split-k / run-split-k # CONFIG=k make live-split-xen / run-split-xen # CONFIG=xen make live-split # CONFIG=uni (GRUB menu, 60s) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Usage: make run-installer-image INSTALLER_IMAGE=/tmp/usb-test.img Boots any raw installer image in QEMU (e.g. ZFlash-written loop device or custom image). Resets OVMF_VARS and creates fresh target disk. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split the installer test into two reusable pieces:
1. Shell wrapper (test-split-installer.sh):
- Builds installer-split.raw
- Injects HV into CONFIG (simulates ZFlash)
- Configures Eden with custom-installer, TPM, EVE OVMF
- Waits for device to come online
2. Escript (testdata/verify_split_install.txt):
- Parameterized by EXPECTED_HV env var
- Verifies CONFIG, runtime HV, Extension, dm-verity, extsloader,
services, EFI variable, "uni" leak check
- Kubevirt-specific: zedkube, kube service, 2GB EFI partition
Usage:
./tests/eden/test-split-installer.sh # KVM default
INSTALL_HV=k ./tests/eden/test-split-installer.sh # Kubevirt
INSTALL_HV=xen ./tests/eden/test-split-installer.sh # Xen
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The distinct INSTALLER_SPLIT_{TAR,IMG} variables and the temporary
'ln -sf installer-split.img installer.img' hack existed purely to keep
the two build paths distinguishable in the same INSTALLER dir. Nothing
downstream (pkg/installer, runme.sh, OCI layout) referred to the -split
suffix.
Collapse into canonical INSTALLER_{TAR,IMG} and HV-switch the build
recipe: HV=uni uses the core+ext split path; otherwise monolithic.
Add \$(INSTALLER_IMG) to EVE_SPLIT_ARTIFACTS so the eve-split OCI ships
/bits/installer.img natively. Preserves the 'make installer-split'
target name and the 'installer-split.raw' output filename.
Side effect: 'docker run lfedge/eve:<tag>-uni installer_raw > out.raw'
now works for split builds, enabling the standard '-v confdir:/in'
pre-parametrization path (e.g., dropping eve-hv-type into CONFIG).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrite tests/eden/test-split-installer.sh: - Loop over 4 pre-parametrized HV cases (kvm, k, k-zfs, xen) using docker-run installer_raw with a per-case conf dir mounted at /in, writing eve-hv-type into CONFIG via the supported production path - eve.disks=2 for k-zfs so the installer auto-selects ZFS on multi-disk - Optional GRUB-menu case (INCLUDE_MENU_CHECK=1) with empty CONFIG, inverted assertion that the menu IS shown - Post-reboot re-verification per case: ssh reboot, wait for EVE to come back, re-run verify escript (SKIP_REBOOT=1 to opt out) - Session-scoped GRUB-menu log check sliced from last 'swtpm is starting' marker so prior-case entries don't false-positive - Waits for ~/.eden/certs/root-certificate.pem after eden setup and for dist/swtpm/swtpm-sock after eden start, replacing the manual pkill+cert-wipe that raced with eden's own lifecycle The verify escript lives in the eden repo at tests/update_eve_image/testdata/verify_split_install.txt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Update SPLIT-ROOTFS-DESIGN.md to match the implemented design. The Extension is stored on the plaintext PERSIST root (not the vault) and trusted via dm-verity; extsloader runs before vault unlock and vaultmgr/zedagent wait for it so PCR 12 is finalized before seal/unseal. Flip the POC-gap table and Phase 1/2 checklists to the as-built state (erofs, dm-verity, PCR 12 implemented), and correct the boot/update flows and threat model to match. Note the one real remaining gap: the stock kernel still lacks CONFIG_EROFS_FS and CONFIG_DM_VERITY. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The future-work section and the EXTA/EXTB option note called a GRUB-based Extension measurement "stronger" / the "cleanest security model" and treated dm-verity verification as "redundant" once GRUB measures. That overstates it: dm-verity already anchors the Extension to the Core's measured root hash (PCR 13) and verifies every block at runtime, which a one-time GRUB measurement does not. Reframe GRUB measurement consistently as cleaner (firmware-rooted, removes the seal/attest ordering dependency on extsloader) rather than stronger, and note dm-verity remains the runtime integrity mechanism. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cellular connectivity should not hinge on the Extension image having been loaded and dm-verity verified. Moving the wwan service into the bootable Core makes the modem usable as soon as the Core boots, restoring the original split-rootfs design intent and matching how wwan behaves in the monolithic image. The Core has ample room for it: a measured build puts the universal Core at 224 MB and adds ~21 MB for wwan, still ~55 MB under the 300 MB Core partition budget. wwan is removed from the Extension so only one instance manages the modem. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The bootable Core squashfs must fit the legacy 300 MB IMGA/IMGB partition, but the existing size guard compared it against ROOTFS_MAXSIZE_MB, which is 4096 MB for k and universal builds. So a Core that overran the real partition limit would have passed unnoticed, and nothing bounded the combined deliverable. Add a 300 MB cap keyed on the Core image and a 4096 MB cap on the universal/split OCI image (Core plus the disk-0 Extension layer), both overridable for platform variants. The current build is well within both. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Correct the kernel-config prerequisites: DM_VERITY is verified absent from eve-core_defconfig (the device-mapper base is present, but DM_VERITY itself is not enabled), not "likely present", and the EROFS gap is now confirmed at runtime on a booted split image rather than inferred. Record that wwan is implemented in the Core templates with its measured cost, and document that the build now enforces the 300MB Core and 4096MB OCI-image size limits. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the CONFIG_EROFS_FS_ZIP=y prerequisite (required because the Extension is built with mkfs.erofs -zlz4hc,9, so base EROFS_FS cannot mount it), and mark the EROFS/DM_VERITY kernel gap as enabled and verified end-to-end: with the three options set in a custom eve-kernel, a booted split image mounts the dm-verity erofs Extension, onboards, and runs an app instance. The configs are not yet upstreamed, so stock builds still lack them. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a draft Eden test that updates a device originally installed by a pre-10.2.0 EVE (300 MB IMGA/IMGB) to the universal/split image, asserting the legacy partition layout up front and that the uni Core fits and boots in the 300 MB slot after OTA. Document the upstream prerequisite in the roadmap: doBaseOsActivate compared the whole content-tree size (Core plus the disk-0 Extension layer) against the rootfs partition and wrongly rejected split images; lf-edge#6044 removes that pre-check and bounds the bytes actually written instead. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Repoint eve-* base-image FROM hashes that the split-rootfs commits carried from their pre-rebase base to the values the current master tree actually builds, restoring make check-docker-hashes-consistency. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
github-actions
Bot
requested review from
OhmSpectator,
andrewd-zededa,
christoph-zededa,
europaul,
jsfakian,
milan-zededa,
naiming-zededa,
rene,
rucoder,
shjala and
zedi-pramodh
June 19, 2026 07:05
Add a branch-scoped tracker that consolidates the open items for the split-rootfs feature: the two hard blockers for a stock build (kernel EROFS/DM_VERITY config and the OTA partition-size check), the testing gaps (no unit tests, eden scripts not in CI), cleanup loose ends, and the larger productionization work from the roadmap. Also correct stale claims in the design and roadmap docs to match the settled decisions: eve-wwan lives in Core (not the Extension) so cellular-only devices stay manageable if the Extension fails, and the Extension lives on plain PERSIST protected by dm-verity, so the threat model no longer references vault encryption for it. Signed-off-by: eriknordmark <erik@zededa.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: eriknordmark <erik@zededa.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proof of concept: split the monolithic rootfs into bootstrap + pkgs
EVE's rootfs partition has a fixed size cap for backward compatibility, but the
platform keeps growing with new services and firmware. This POC splits the
single rootfs into two squashfs images: a small bootstrap image with
everything needed to boot to a stable, minimal system (kernel, init, firmware,
hypervisor, storage/networking, security hardening, and core orchestration
including pillar), and a separate pkgs image holding non-critical services
(observability and ancillary tooling) that are mounted and started once the
system is up. The device boots only the bootstrap image; the pkgs image is
staged and consumed at runtime, keeping the boot path under the legacy size
limit while leaving room to grow.
A new pillar agent, extsloader, discovers and activates the services carried
by the pkgs image, and rescans on base-OS updates. The branch also adds the
LinuxKit templates and make targets to build/run the two images, an erofs/verity
tooling path, size enforcement for the Core and OCI portions, and Eden test
scripts covering split installer boot (kvm/k/k-zfs/xen) and OTA upgrade from an
old monolithic image.
Design and rationale are documented in
docs/SPLIT-ROOTFS.md,docs/SPLIT-ROOTFS-DESIGN.md, and the implementation roadmap.Status: draft / WIP — opened for visibility and review of the approach. The
series still contains WIP checkpoints and is not yet squashed into logical
units.