Skip to content

feat(extensions): add netboot extension for TFTP+NFS diskless boot#9656

Draft
iav wants to merge 6 commits intoarmbian:mainfrom
iav:enh/netboot-extension
Draft

feat(extensions): add netboot extension for TFTP+NFS diskless boot#9656
iav wants to merge 6 commits intoarmbian:mainfrom
iav:enh/netboot-extension

Conversation

@iav
Copy link
Copy Markdown
Contributor

@iav iav commented Apr 11, 2026

Summary

Adds an opt-in netboot extension that produces a full network-boot payload — kernel, DTB, optional uInitrd, pxelinux.cfg and an NFS-exportable rootfs — from a regular Armbian build. For netboot the only thing that has to live on the device's local storage is U-Boot itself: the kernel and DTB come from TFTP, / is mounted over NFS, nothing else on mmc/eMMC/USB is touched during early boot.

Today ROOTFS_TYPE=nfs alone only gives a hybrid image (kernel+DTB still on SD/eMMC, only / over NFS). This PR keeps that path working and layers a real netboot flow on top via a new ROOTFS_TYPE=nfs-root.

What changes

  • lib/functions/configuration/main-config.sh — new ROOTFS_TYPE=nfs-root case branch, symmetric with the existing fs-f2fs-support / fs-btrfs wiring: the branch auto-enables the netboot extension so ROOTFS_TYPE=nfs-root is the single switch that selects the full netboot flow. check_filesystem_compatibility_on_host is skipped for both nfs and nfs-root — the host-side check is a sanity net for block-device targets and falsely rejects valid NFS configurations.

  • extensions/netboot/netboot.sh — new, directory-based extension. Directory layout (rather than a single extensions/netboot.sh file) exists so the long-form usage guide can live next to the code as README.md; inlining documentation of that size into the script body would be unwieldy. Hooks:

    • extension_prepare_config — validate variables, compute defaults for NETBOOT_TFTP_PREFIX / NETBOOT_NFS_PATH (shared by LINUXFAMILY/BOARD/BRANCH/RELEASE, or per-host when NETBOOT_HOSTNAME is set), normalize NETBOOT_CLIENT_MAC to the 01-<mac> PXELINUX form, fail fast on bad ROOTFS_COMPRESSION/ROOTFS_EXPORT_DIR combinations before debootstrap.
    • custom_kernel_config — enable ROOT_NFS, NFS_FS, NFS_V3, IP_PNP, IP_PNP_DHCP so root=/dev/nfs ip=dhcp works without an initrd.
    • post_customize_image — drop armbian-resize-filesystem.service (meaningless on NFS root) and /root/.not_logged_in_yet (the armbian-firstlogin interactive wizard blocks bring-up when there is no interactive console). armbian-firstrun.service stays — it only regenerates SSH host keys.
    • host_pre_docker_launch — bind-mount ROOTFS_EXPORT_DIR into the build container when it lives outside ${SRC}, so the single-step builder-as-NFS-server workflow works the same inside and outside Docker.
    • pre_umount_final_image — assemble the TFTP tree (Image/zImage, dtb/, uInitrd), write pxelinux.cfg/{default.example | 01-<mac>} with the right FDT/FDTDIR line and an explicit INITRD directive when uInitrd is present (U-Boot's PXE parser only loads an initramfs when the stanza names it), expose a netboot_artifacts_ready hook for userpatches that deploy to a real server.
  • lib/functions/image/rootfs-to-image.sh — two new controls for NFS-rootfs builds (both ROOTFS_TYPE=nfs and nfs-root):

    • ROOTFS_COMPRESSION=gzip|zstd|none (default gzip). gzip.tar.gz, zstd.tar.zst, none → no archive at all. Rejected early if none is set without ROOTFS_EXPORT_DIR. The tar | pv | compressor pipeline now runs in a set -o pipefail subshell so a broken archive step actually fails the build instead of producing a silently truncated file.
    • ROOTFS_EXPORT_DIR=/abs/path — also (or only) rsync the rootfs tree into this directory. Can point anywhere on the build host's filesystem — inside or outside the Armbian tree (the extension bind-mounts external paths into the Docker container automatically). If the path is an NFS mount or any other network filesystem, the build writes directly to the remote server with no intermediate archive. The rsync uses --delete so a re-used export dir stays in sync with the new build instead of accumulating stale files from previous runs. Combined with ROOTFS_COMPRESSION=none this turns deploy-to-NFS-server into a single build step.
    • ROOTFS_ARCHIVE_PATH is exported so downstream hooks (the new netboot_artifacts_ready) can reference the produced archive.
  • lib/functions/image/partitioning.shprepare_partitions skips the root partition entry for nfs-root the same way it does for nfs, and the SD-size sanity check no longer applies to either (there is no image file to size).

  • config/templates/nfs-boot.cmd.template — previously sunxi/arm32-only (zImage + bootz). Made arch-agnostic so the hybrid ROOTFS_TYPE=nfs path builds for arm64 boards too.

  • extensions/netboot/README.md — long-form guide: variable reference, server setup (tftpd-hpa + nfs-kernel-server), DHCP 66/67 config (OpenWRT + others), per-host / per-MAC deployments, firstrun vs firstlogin, end-to-end helios64 example, troubleshooting.

Variables (quick reference)

All optional. ROOTFS_TYPE=nfs-root alone gives you a shared-rootfs build with a pxelinux.cfg/default.example file.

Variable Default Purpose
NETBOOT_SERVER (empty) TFTP/NFS server IP. Empty → nfsroot= keeps ${serverip} literal for U-Boot to fill from DHCP siaddr.
NETBOOT_TFTP_PREFIX armbian/${LINUXFAMILY}/${BOARD}/${BRANCH}-${RELEASE} Path prefix under TFTP root.
NETBOOT_NFS_PATH /srv/netboot/rootfs/shared/... or /srv/netboot/rootfs/hosts/<hostname> Absolute NFS path used in nfsroot=.
NETBOOT_HOSTNAME (empty) Per-host rootfs under hosts/<hostname>/ — each machine owns its own writable copy.
NETBOOT_CLIENT_MAC (empty) When set, PXE config is written as 01-<mac> (per-MAC PXELINUX override). Accepts : or -, normalized to lowercase.
ROOTFS_COMPRESSION gzip gzip / zstd / none.
ROOTFS_EXPORT_DIR (empty) When set, rsync the rootfs tree here in addition to (or instead of) the archive.

Test plan

Validated end-to-end on helios64 (rockchip64, edge/resolute, ttyS2 @ 1500000), Armbian 26.05:

  • Baseline build (ROOTFS_TYPE=nfs-root NETBOOT_SERVER=192.168.1.125, shared NFS path, FDTDIR fallback for boards without BOOT_FDT_FILE, no hardcoded console=). 6:57 min, all artifacts correct.
  • Per-host + per-MAC (NETBOOT_HOSTNAME=helios64-a NETBOOT_CLIENT_MAC=aa:bb:cc:dd:ee:ff). pxelinux.cfg/01-aa-bb-cc-dd-ee-ff contains nfsroot=.../hosts/helios64-a. 7:44 min.
  • ROOTFS_COMPRESSION=zstd — produces .tar.zst, ROOTFS_ARCHIVE_PATH set correctly. 460 MB vs 503 MB gzip.
  • ROOTFS_COMPRESSION=none ROOTFS_EXPORT_DIR=... — single-step tree workflow, 1.5 GB tree in export dir, no archive produced. 5:17 min.
  • ROOTFS_COMPRESSION=none without ROOTFS_EXPORT_DIR — fails fast in extension_prepare_config before debootstrap, not hours later.
  • End-to-end boot test: TFTP tree deployed to tftpd-hpa + NFS rootfs via rsync to nfs-kernel-server. DHCP options 66/67 on OpenWRT. Helios64 cold boot → U-Boot bootflow scan -lb → TFTP → booti → kernel → ip_auto_config → NFS mount → systemd graphical.target → login prompt on ttyS2@1500000. No armbian-firstlogin wizard, no resize2fs errors, armbian-firstrun.service regenerates SSH host keys normally. Verified twice: once with archive workflow + manual unpack, once with tree workflow + rsync deploy.
  • helios4 (mvebu, armhf, U-Boot v2025.10) — second SoC family. PXE netboot: DHCP → TFTP (zImage + DTB) → bootz → kernel → NFS root → systemd → login prompt. No initrd needed (see notes below).
  • Other boards / other SoC families — review welcome, especially from boards with BOOT_FDT_FILE set (the FDTDIR vs FDT code path is exercised by helios64's missing BOOT_FDT_FILE, but a board with it set should also work).

Known issues found during helios4 testing (not blockers for this PR):

  • RD image overlaps OS image on mvebu: ramdisk_addr_r (0x2880000) is only 8 MB above kernel_addr_r (0x2080000), but zImage 6.12 is 8.1 MB → U-Boot refuses to boot with initrd. Workaround: omit INITRD from PXE config — kernel with CONFIG_ROOT_NFS=y mounts NFS root directly without initrd.
  • DNS not working after NFS boot: kernel ip=dhcp writes DNS to /proc/net/pnp but systemd-resolved doesn't read it → "No DNS servers known". Workaround: resolvectl dns <iface> <gateway>. Needs a networkd .network file or oneshot service in post_customize_image (future improvement).

Post-review update: architecture reworked after CodeRabbit #1 — the extension no longer forces ROOTFS_TYPE from inside extension_prepare_config (too late in the config lifecycle); instead a new ROOTFS_TYPE=nfs-root case branch in main-config.sh enables the extension, symmetric with existing filesystem-support extensions. pipefail on the archive pipeline (#4), rsync --delete on the export dir (#5), and an explicit INITRD directive when uInitrd is present (#2) are all in.

Related work

A companion PR to armbian/documentation will add Developer-Guide_Netboot.md with the short overview + variable reference; this extension's README.md is the long-form guide and is linked from that page.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Network boot (NFS/TFTP) support with configurable rootfs compression (gzip/zstd/none), host export options, per-MAC PXE entries, and staged netboot artifacts.
    • ARM64 kernel selection with automatic fallback to 32-bit boot.
    • New ROOTFS_TYPE=nfs-root mode to build/export NFS-root images.
  • Bug Fixes / Reliability

    • More robust early-boot arguments and initrd handling for resilient network boots.
  • Documentation

    • Comprehensive netboot guide covering setup, deployment workflows, and troubleshooting.

@iav iav requested review from a team, EvilOlaf, TRSx80, igorpecovnik and littlecxm as code owners April 11, 2026 23:32
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8a0869a4-1d2e-4f9e-872c-843bb6271a31

📥 Commits

Reviewing files that changed from the base of the PR and between 2393977 and 4ff6016.

📒 Files selected for processing (6)
  • config/templates/nfs-boot.cmd.template
  • extensions/netboot/README.md
  • extensions/netboot/netboot.sh
  • lib/functions/configuration/main-config.sh
  • lib/functions/image/partitioning.sh
  • lib/functions/image/rootfs-to-image.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/functions/configuration/main-config.sh
  • config/templates/nfs-boot.cmd.template

📝 Walkthrough

Walkthrough

Adds a netboot extension to stage TFTP/NFS boot artifacts and support NFS-root images, updates build framework to recognize nfs-root, revises U-Boot boot script for NFS boot flows (arm64/arm kernel selection, distro boot partition loading), and includes comprehensive netboot documentation.

Changes

Cohort / File(s) Summary
U-Boot NFS Boot Configuration
config/templates/nfs-boot.cmd.template
Replaced hardcoded console=/UART options with rootwait earlycon in bootargs; quoted ${nfs_root} check; load DTB/initrd from active distro boot partition (${devtype} ${devnum}:${distro_bootpart}) instead of fixed mmc offsets; simplify initrd failure handling; add arm64 Image/booti path with zImage/bootz fallback.
Netboot Extension docs
extensions/netboot/README.md
Added a long-form guide describing netboot behavior, build-time variables/defaults, artifact staging conventions, hook interface, U-Boot/DHCP/TFTP/NFS constraints, server setup examples, deployment workflows, and troubleshooting.
Netboot Extension implementation
extensions/netboot/netboot.sh
New extension script: default/validation for netboot vars (server, hostname, MAC formatting), kernel config toggles for NFS root, container mount handling, disable resize/skip first-login for nfs-root images, collect kernel/DTB/uInitrd into TFTP tree, generate PXELINUX entries (per-MAC or default), build nfsroot= using ${serverip} when unset, export artifact context and call netboot_artifacts_ready hook.
Rootfs image and export handling
lib/functions/image/rootfs-to-image.sh
Treat nfs-root same as nfs for versioning and control flow; add ROOTFS_COMPRESSION handling (`gzip
Partitioning & build integration
lib/functions/image/partitioning.sh, lib/functions/configuration/main-config.sh
Recognize nfs-root like nfs when skipping root partition allocation and host filesystem compatibility checks; add nfs-root to inline docs and conditional checks.

Sequence Diagram(s)

sequenceDiagram
    participant Builder as Armbian Builder
    participant Ext as Netboot Extension
    participant KernelCfg as Kernel Config
    participant ImgGen as Image Generator
    participant TFTP as TFTP Staging
    participant Hook as netboot_artifacts_ready Hook

    Builder->>Ext: trigger (ROOTFS_TYPE=nfs-root)
    Ext->>Ext: normalize & validate vars (NETBOOT_SERVER, MAC, paths)
    Ext->>KernelCfg: enable NFS client/kernel options
    Ext->>ImgGen: customize image (disable resize, skip firstlogin)
    ImgGen->>ImgGen: build rootfs
    Ext->>ImgGen: handle ROOTFS_COMPRESSION (gzip/zstd/none) / rsync export
    Ext->>TFTP: collect kernel (Image/zImage), DTBs, optional uInitrd
    Ext->>TFTP: generate PXELINUX entries (per-MAC or default)
    Ext->>Hook: invoke netboot_artifacts_ready with artifact context
Loading
sequenceDiagram
    participant DHCP as DHCP Server
    participant Client as Target Device
    participant UBoot as U-Boot
    participant TFTP as TFTP Server
    participant NFS as NFS Server

    Client->>DHCP: request IP + boot options
    DHCP->>Client: reply (serverip, bootfile)
    Client->>UBoot: PXE/disk boot flow
    UBoot->>TFTP: fetch pxelinux.cfg / kernel / dtb / uInitrd
    TFTP->>UBoot: deliver artifacts
    UBoot->>NFS: mount nfsroot (from cmdline)
    NFS->>Client: provide root filesystem
    Client->>Client: boot kernel with NFS root
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 I hopped through configs, scripts, and docs,
Staged kernels, DTBs, and tidy hard‑locks.
With PXE and NFS I danced on air,
Builder prepared, U‑Boot gave a stare.
Netboot now sings — a rabbit’s small cheer!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main addition: a netboot extension for TFTP+NFS diskless boot capability. It is specific, relevant to the primary change, and follows semantic versioning conventions.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added 05 Milestone: Second quarter release size/large PR with 250 lines or more Needs review Seeking for review Hardware Hardware related like kernel, U-Boot, ... Framework Framework components Documentation Documentation changes or additions labels Apr 11, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@extensions/netboot/netboot.sh`:
- Around line 38-42: The function
extension_prepare_config__netboot_force_nfs_rootfs sets ROOTFS_TYPE too late (it
runs during do_extra_configuration) so NFS-specific branches in
do_main_configuration never see it; move the ROOTFS_TYPE assignment earlier by
ensuring extension_prepare_config__netboot_force_nfs_rootfs (or its logic) runs
before do_main_configuration—either call that function in the init/startup hook
that executes prior to main configuration (e.g., extension_init or top-level
script before do_main_configuration) or export/set declare -g ROOTFS_TYPE="nfs"
at script initialization so the global variable is in effect for
do_main_configuration and the NFS setup in
lib/functions/configuration/main-config.sh executes.
- Around line 147-149: The PXE staging copies ${MOUNT}/boot/uInitrd but never
references it in the generated extlinux.cfg, so U-Boot won't load the initramfs;
modify the netboot stanza generation to set an initrd_line variable when the
file exists (mirror how fdt_line is created — e.g. check for
"${MOUNT}/boot/uInitrd", set initrd_line="INITRD ${tftp_prefix_dir}/uInitrd")
and then include ${initrd_line} in the emitted PXE stanza alongside fdt_line so
the INITRD directive is present for U-Boot.

In `@extensions/netboot/README.md`:
- Around line 137-155: The README has multiple unlabeled fenced code blocks
(e.g., the directory tree block showing "/srv/netboot/" and other blocks around
lines 159-164, 171-175, 465-489, 544-547); update each triple-backtick fence to
include an appropriate info string (for example use sh, ini, or text as
appropriate) so markdownlint stops flagging them—locate the fences by searching
for the blocks that display the directory tree and configuration snippets and
add the matching language tag to each opening ``` line.

In `@lib/functions/image/rootfs-to-image.sh`:
- Around line 82-93: The rsync into ROOTFS_EXPORT_DIR can leave stale files
behind when the export tree is reused; update the rsync invocation in
rootfs-to-image.sh (the run_host_command_logged rsync call) to include --delete
(and optionally --delete-excluded) so files removed from the source are removed
from "${ROOTFS_EXPORT_DIR}" as well; add the flag either into $rsync_ea or
directly in the rsync command invocation to ensure exported NFS root mirrors the
built image.
- Around line 69-76: The archive creation pipeline (tar … | pv … |
${archive_filter} > "${ROOTFS_ARCHIVE_PATH}") must be guarded with pipefail so
failures in tar or pv aren't masked by a later stage; wrap that pipeline in a
shell context with set -o pipefail (or enable set -o pipefail locally before
running the pipeline) so a nonzero exit from tar or pv will cause the script to
fail and propagate the error from creating ROOTFS_ARCHIVE_PATH; update the block
around display_alert/ tar / pv / ${archive_filter} to ensure pipefail is active
for that pipeline.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fca3bef5-36a8-4aaa-81dd-645853e7579e

📥 Commits

Reviewing files that changed from the base of the PR and between fdef407 and 2393977.

📒 Files selected for processing (5)
  • config/templates/nfs-boot.cmd.template
  • extensions/netboot/README.md
  • extensions/netboot/netboot.sh
  • lib/functions/configuration/main-config.sh
  • lib/functions/image/rootfs-to-image.sh

@iav iav marked this pull request as draft April 11, 2026 23:50
iav added a commit to iav/armbian that referenced this pull request Apr 12, 2026
`nfs-root` is a new rootfs type distinct from the existing `nfs` hybrid
mode. Selecting it wires the `netboot` extension from the core
`ROOTFS_TYPE` dispatch in `do_main_configuration`, so callers no longer
need a separate `ENABLE_EXTENSIONS=netboot`. The legacy `nfs` branch
(kernel+DTB on local boot partition, `/` over NFS) is untouched — both
paths coexist until the hybrid mode's future is decided.

Core plumbing mirrors the `nfs` branch for all paths where local root
storage would be meaningless: partition layout skip
(`prepare_partitions`), archive/export gate and version suffix
(`rootfs-to-image.sh`), and the host-side filesystem compatibility
check in `main-config.sh`.

Extension hooks now key on `ROOTFS_TYPE=nfs-root` instead of guessing
from `nfs`, removing the `force ROOTFS_TYPE=nfs` shim that ran too
late relative to `do_main_configuration`.

Also folded in from CodeRabbit review on PR armbian#9656:
- pipefail around tar|pv|compressor so truncated archives no longer
  slip through on an intermediate stage failure
- `rsync --delete` on `ROOTFS_EXPORT_DIR` so stale files from a
  previous build don't linger in the NFS export tree
- explicit `INITRD` directive in extlinux when `uInitrd` is staged;
  U-Boot only loads an initramfs when the stanza names it
- README updated to document `ROOTFS_TYPE=nfs-root` as the single
  switch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rpardini
Copy link
Copy Markdown
Member

Very nice. With recent u-boot (2026.04, thanks to Kwiboo), one can enable LWIP networking stack for better TFTP performance (loading kernel and initramfs) -- there's also some TFTP Window Size stuff that can be tuned. U-boot with LWIP + u-boot's wget offers the best performance, but is not integrated in pxe or dhcp boot target AFAIK.

@iav
Copy link
Copy Markdown
Contributor Author

iav commented Apr 12, 2026

Thanks for the pointer! Let's get this merged first — iterating on something that works is the easy part.

@iav iav force-pushed the enh/netboot-extension branch from a76e4b2 to fec99ac Compare April 12, 2026 17:14
@iav iav added the Work in progress Unfinished / work in progress label Apr 12, 2026
@iav iav force-pushed the enh/netboot-extension branch from fec99ac to 14e6f77 Compare April 14, 2026 14:58
iav and others added 2 commits April 14, 2026 19:19
…YPE=nfs

ROOTFS_TYPE=nfs produces a rootfs tarball via `tar cp ... | gzip` in
rootfs-to-image.sh and never mounts NFS on the build host. The NFS
client runs on the target's kernel at boot time, so host-side NFS
filesystem support is irrelevant. Additionally, the check runs inside
the Armbian docker launcher where /lib/modules is empty, causing
`modprobe nfs` to fail even when the host kernel has nfs.ko available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous template was hardcoded for sunxi arm32 — `zImage`/`bootz`,
`console=tty1 console=ttyS0,115200`, `disp.screen0_output_mode=...`,
`ext4load/fatload mmc 0`. It did not work on arm64 boards (e.g.
rockchip64/helios64) and baked in a 115200 baud that breaks non-standard
UART speeds (helios64 runs at 1500000).

Rewrites the U-Boot hush script to:
- Prefer `Image` + `booti` (arm64), fall back to `zImage` + `bootz` (arm32).
- Load via `${devtype} ${devnum}:${distro_bootpart}` from U-Boot's distro
  bootflow scanner instead of hardcoded `mmc 0`.
- Drop the `console=` overrides — let the kernel resolve the console from
  DTB `/chosen/stdout-path`, keeping `earlycon` for early output.
- Drop sunxi-specific `disp.screen0_output_mode` and legacy `.next`/
  `script.bin` probe paths.

For the full TFTP+NFS netboot flow see the new `netboot` extension; this
template remains the hybrid path where the kernel + DTB live on a local
boot partition and only the rootfs is NFS-mounted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@iav iav force-pushed the enh/netboot-extension branch 2 times, most recently from 51c1bdc to 252da73 Compare April 14, 2026 16:30
…TFS_COMPRESSION

Split the rootfs pipeline so it can produce either (or both) of:
  * a tarball — via ROOTFS_COMPRESSION=gzip (default, .tar.gz) / zstd
    (.tar.zst); matches existing behaviour, with zstd now available for
    faster creation and decompression on modern hardware.
  * an exported tree — via ROOTFS_EXPORT_DIR=<abs path>, which rsyncs
    the built rootfs to a host-side directory (e.g. an NFS export)
    without an intermediate archive.

Set ROOTFS_COMPRESSION=none when only the exported tree is wanted;
this skips archive creation entirely. If both ROOTFS_COMPRESSION=none
and -z ROOTFS_EXPORT_DIR are set the run is aborted — otherwise the
rootfs stage would produce nothing.

This is infrastructure; no existing callers need to change. The
netboot extension (added in a following commit) consumes
ROOTFS_EXPORT_DIR to populate the NFS export tree.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@iav iav force-pushed the enh/netboot-extension branch from 252da73 to a10feb4 Compare April 14, 2026 16:53
iav and others added 3 commits April 14, 2026 20:11
Hooks:
- extension_prepare_config: validate variables, compute defaults for
  NETBOOT_TFTP_PREFIX / NETBOOT_NFS_PATH (shared by
  LINUXFAMILY/BOARD/BRANCH/RELEASE, or per-host when NETBOOT_HOSTNAME
  is set), normalize NETBOOT_CLIENT_MAC to PXELINUX 01-<mac> form,
  fail fast on bad ROOTFS_COMPRESSION/ROOTFS_EXPORT_DIR combinations.
- custom_kernel_config: enable ROOT_NFS, NFS_FS, NFS_V3, IP_PNP,
  IP_PNP_DHCP so root=/dev/nfs ip=dhcp works without an initrd.
- post_customize_image: drop armbian-resize-filesystem.service
  (meaningless on NFS root) and /root/.not_logged_in_yet (the
  armbian-firstlogin interactive wizard blocks bring-up when there is
  no interactive console). armbian-firstrun.service stays — it only
  regenerates SSH host keys.
- host_pre_docker_launch: append a bind-mount for ROOTFS_EXPORT_DIR to
  DOCKER_EXTRA_ARGS when the directory lives outside ${SRC}, using the
  hook's documented mechanism.
- pre_umount_final_image: assemble the TFTP tree (Image/zImage, dtb/,
  uInitrd), write pxelinux.cfg/{default.example | 01-<mac>} with the
  right FDT/FDTDIR line and explicit INITRD directive when uInitrd is
  present, expose a netboot_artifacts_ready hook for userpatches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New rootfs type for full network boot: the only thing on the device's
local storage is U-Boot itself. Kernel, DTB, optional uInitrd and PXE
config come from TFTP; rootfs is mounted over NFS.

A new case branch in do_main_configuration auto-enables the netboot
extension, symmetric with existing fs-f2fs-support / fs-btrfs wiring.
The legacy ROOTFS_TYPE=nfs (hybrid: kernel on local storage, only /
over NFS) is untouched — both paths coexist.

- nfs-root case branch in ROOTFS_TYPE dispatch calls
  enable_extension "netboot"
- prepare_partitions skips root partition creation and SD-size sanity
  check
- check_filesystem_compatibility_on_host skipped for nfs-root

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents the netboot extension: artifact server setup (tftpd-hpa +
nfs-kernel-server), TFTP tree layout, DHCP options 66/67 on the
network DHCP server, userpatches.conf knobs, the
netboot_artifacts_ready hook, a full end-to-end helios64 walkthrough,
and a troubleshooting section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@iav iav force-pushed the enh/netboot-extension branch from a10feb4 to 4ff6016 Compare April 14, 2026 17:14
@iav
Copy link
Copy Markdown
Contributor Author

iav commented Apr 14, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

05 Milestone: Second quarter release Documentation Documentation changes or additions Framework Framework components Hardware Hardware related like kernel, U-Boot, ... Needs review Seeking for review size/large PR with 250 lines or more Work in progress Unfinished / work in progress

Development

Successfully merging this pull request may close these issues.

2 participants