netboot: enable netboot image workflow and automate target configuration - #10195
netboot: enable netboot image workflow and automate target configuration#10195deece wants to merge 3 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a NETBOOT build path that prepares NFS-root filesystems, creates compressed and TFTP artifacts, generates deployment documentation and a bootloader image, sources the new helpers, warns about deprecated NFS rootfs types, and provides a TTY-safe ChangesNetboot generation
Non-interactive progress handling
Estimated code review effort: 4 (Complex) | ~45 minutes Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant build_rootfs_and_image
participant create_netboot_tarballs_and_images
participant target_rootfs
participant FINALDEST
build_rootfs_and_image->>create_netboot_tarballs_and_images: select netboot generation
create_netboot_tarballs_and_images->>target_rootfs: provision rootfs and configure overlayroot
create_netboot_tarballs_and_images->>FINALDEST: create archives and stage TFTP files
create_netboot_tarballs_and_images->>FINALDEST: write deployment guide and bootloader image
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 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 `@lib/functions/image/rootfs-to-image.sh`:
- Around line 235-245: Propagate the resolved NETBOOT_TFTP_SERVER value into
tftp_server_ip after the TFTP server prompt/defaulting logic, and ensure the
same assignment is applied in the corresponding boot.scr generation paths
referenced by the comment. Preserve the existing NFS fallback behavior only when
no TFTP server is configured.
- Around line 492-505: Register a cleanup handler immediately after `loop_dev`
is assigned in the loop-device setup flow, before formatting or mounting. Have
it conditionally unmount and remove `temp_mount` and detach `loop_dev`,
explicitly tolerating cleanup-command failures under `set -e`; disarm the
handler after successful cleanup so later execution does not trigger it again.
- Around line 318-322: Update the fstab adjustment block in rootfs-to-image.sh
to comment every block-backed mount entry, including UUID/PARTUUID/LABEL
sources, all /dev/* sources, and indented entries. Preserve network and
pseudo-filesystem entries by limiting the match to block-device source forms.
- Around line 328-334: Update the deployment-guide generation associated with
the rootfs/boot archive instructions to install both `${version}-rootfs.${ext}`
and `${version}-boot.${ext}` before bind-mounting `${NETBOOT_NFS_PATH}/boot`
over TFTP. Generate extraction commands using the appropriate gzip or zstd
decompressor, and apply the same change to all corresponding guide sections.
- Around line 401-405: Update the `/etc/exports` entry in the rootfs-to-image
export setup to replace the unrestricted `*` client with the configured network,
or preferably the specific target address, while preserving the existing NFS
options and `no_root_squash` behavior.
- Around line 586-599: Update the U-Boot handling around
image_artifacts_debs_reversioned and write_uboot_to_loop_image so the upstream
artifact map is authoritative: remove the broad DEB_STORAGE fallback search, and
when the "uboot" entry is missing or unusable, emit an error and terminate with
failure instead of publishing the image. Preserve writing the mapped U-Boot
package when the entry is present.
- Around line 291-294: Update the sed expression assigning latest_installed_ver
in the latest_file block to use proper extended-regex alternation for the
vmlinuz and Image prefixes, removing either prefix from the extracted kernel
version instead of retaining it.
🪄 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: 1609498c-6cca-48cf-9180-4cbbb4534002
📒 Files selected for processing (3)
config/kernel/linux-sunxi64-current.configlib/functions/image/rootfs-to-image.shlib/functions/main/rootfs-image.sh
|
Good one. I was thinking on this too ... currently we use full images for initial deployment. A bit of a waste. https://github.com/armbian/infra/tree/main/nfs-image-prep (WIP, not in production as there is some problem with using overlaysfs - rootfs images are shared by more then one device) |
There was a problem hiding this comment.
Interesting effort, but again, seems to me u-boot already provides much of this. Ref exporting, I thought that the nfs root stuff did that already?
Also create_netboot_tarballs_and_images is way too long for rootfs-to-image.sh, refactor it a bit, and use a separate rootfs-to-netboot.sh or such (and tools...gen-library.sh; or, better yet, make core extensible)
Interesting, I was thinking of how a production OverlayFS would work to allow a shared readonly root - similar to OpenWRT, stock image is RO, config, home, etc goes onto a writable mount. The RO fs itself could be layered, a generic layer for nooarch packages, an arch layer that contains shared architecture files (most packages), and a board layer for the board specific things (like kernel packages). That would cut down storage requirements a bit, but does add complexity. The benefits are that it would enable further work to create a more secure Armbian where most things are readonly. The alternative would be to throw it all on a deduping filesystem on the server like ZFS (which is where I serve my test from), which removes the storage costs, but still incurs the packaging & extraction overheads. |
Hmm, you're right, I didn't think to check for PXE - it looks like u-boot implements enough of PXE to get going, so I'll look into reworking this so that the local u-boot uses PXE, then drop any unnecessary infrastructure. |
16c6641 to
3bf5b40
Compare
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 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 `@config/templates/netboot.md.template`:
- Around line 60-72: Update the netboot deployment instructions around the TFTP
copy and bind-mount example so generated pxelinux.cfg/default remains accessible
after mounting ${NETBOOT_NFS_PATH}/boot. Place the PXE configuration within the
bound boot tree or mount that tree beneath a separate TFTP subdirectory, and
ensure the documented copy path and fstab entry are consistent.
In `@lib/functions/image/rootfs-to-netboot.sh`:
- Around line 185-192: The kernel-copy fallback must require exactly one
matching kernel image before publishing it. Update the fallback in the “Copy
kernel image” block to collect candidates matching vmlinuz* or Image, fail the
build when none or multiple candidates are found, and copy the sole candidate to
netboot_dir/Image.
- Around line 224-232: Update the PXE entry generated in the rootfs-to-netboot
flow to use the board’s established console configuration instead of hardcoded
console=ttyS0,115200 and earlycon=uart,mmio32,0x05000000 arguments. Reuse the
existing board-configured console argument symbol or generation mechanism, while
preserving the remaining kernel, initrd, FDT, and NFS options.
- Around line 201-203: The netboot-specific boot script is not staged for
pure-PXE clients. In lib/functions/image/rootfs-to-netboot.sh lines 201-203,
generate or copy the netboot-specific boot.scr into ${netboot_dir}; in
config/templates/netboot.md.template lines 15-18, update the pure-PXE deployment
instructions to install that script, or switch them to native U-Boot PXE
loading.
- Around line 170-176: Update both archive pipelines in the rootfs packaging
flow to explicitly propagate tar failures when pipefail is disabled, covering
the root filesystem archive and the boot/kernel archive. Ensure a failed tar
causes the script to stop or return failure rather than allowing the
compressor’s successful exit status to publish an incomplete archive.
- Around line 133-150: Update the initramfs rebuild and uInitrd generation flow
around update-initramfs and mkimage so failures that prevent producing the
required uInitrd are propagated instead of ignored. Ensure the PXE-referenced
${SDCARD}/boot/uInitrd is successfully regenerated from the newest initrd.img,
and fail the function or script when either required generation step fails.
In `@lib/functions/logging/runners.sh`:
- Around line 14-44: Update the pv wrapper to use command pv whenever stderr is
a TTY, regardless of stdin or stdout. Replace regex-based option parsing with
explicit case handling for supported value-taking flags, treat -C/--no-control
as argument-free, safely handle missing option values without failing under set
-e, and stop parsing options after -- while preserving remaining operands as
files.
🪄 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: 8105c867-58f1-4be9-9405-fc8e688e74e2
📒 Files selected for processing (6)
config/templates/netboot.md.templatelib/functions/image/rootfs-to-image.shlib/functions/image/rootfs-to-netboot.shlib/functions/logging/runners.shlib/functions/main/rootfs-image.shlib/library-functions.sh
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/functions/main/rootfs-image.sh
c354b0c to
7c94564
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@lib/functions/image/rootfs-to-netboot.sh`:
- Around line 291-310: The PXE configuration generation must not select an
arbitrary or empty DTB. Update the DTB resolution and `fdt` emission around
`dtb_rel_path` and the `Generating PXE configuration` heredoc to require the
board-configured `BOOT_FDT_FILE` for FDT-based targets, failing or handling the
missing file explicitly, while omitting the `fdt` directive only for
architectures that do not require one; remove the `find | head` fallback.
- Around line 12-24: Update the NETBOOT_TFTP_SERVER and NETBOOT_NFS_SERVER
handling in rootfs-to-netboot.sh to require valid numeric IPv4 addresses,
including when values are supplied non-interactively or NFS defaults from TFTP.
Revise the TFTP prompt to request an IP address and validate each server value
before generating U-Boot serverip and nfsroot settings, rejecting invalid or
hostname values.
🪄 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: b77b8dd7-cdb0-417e-8048-6272fb176b09
📒 Files selected for processing (7)
config/templates/netboot.md.templatelib/functions/configuration/main-config.shlib/functions/image/rootfs-to-image.shlib/functions/image/rootfs-to-netboot.shlib/functions/logging/runners.shlib/functions/main/rootfs-image.shlib/library-functions.sh
🚧 Files skipped from review as they are similar to previous changes (4)
- lib/functions/image/rootfs-to-image.sh
- lib/functions/main/rootfs-image.sh
- lib/functions/logging/runners.sh
- config/templates/netboot.md.template
| local dtb_rel_path="" | ||
| if [[ -n "${BOOT_FDT_FILE}" && -f "${netboot_dir}/${BOOT_FDT_FILE}" ]]; then | ||
| dtb_rel_path="${BOOT_FDT_FILE}" | ||
| elif [[ -n "${BOOT_FDT_FILE}" && -f "${netboot_dir}/$(basename "${BOOT_FDT_FILE}")" ]]; then | ||
| dtb_rel_path="$(basename "${BOOT_FDT_FILE}")" | ||
| else | ||
| local dtb_file | ||
| dtb_file=$(find "${netboot_dir}" -name "*.dtb" -type f | head -n 1) | ||
| if [[ -n "${dtb_file}" ]]; then | ||
| dtb_rel_path=$(realpath --relative-to="${netboot_dir}" "${dtb_file}") | ||
| fi | ||
| fi | ||
|
|
||
| display_alert "Generating PXE configuration" "${pxe_dir}/default" "info" | ||
| cat <<EOF > "${pxe_dir}/default" | ||
| default armbian | ||
| label armbian | ||
| kernel Image | ||
| initrd uInitrd | ||
| fdt ${dtb_rel_path} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Do not publish an arbitrary or empty DTB path.
When the configured DTB is unavailable, find | head silently chooses an arbitrary DTB—or emits fdt when none exists. Require the board-configured DTB for FDT-based targets; only omit the directive on architectures that do not need one.
🤖 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 `@lib/functions/image/rootfs-to-netboot.sh` around lines 291 - 310, The PXE
configuration generation must not select an arbitrary or empty DTB. Update the
DTB resolution and `fdt` emission around `dtb_rel_path` and the `Generating PXE
configuration` heredoc to require the board-configured `BOOT_FDT_FILE` for
FDT-based targets, failing or handling the missing file explicitly, while
omitting the `fdt` directive only for architectures that do not require one;
remove the `find | head` fallback.
|
Latest version integrates the core ideas from @igorpecovnik's scripts - use an initrd to avoid changing kernel config, allows for readonly nfsroot with tmpfs overlay, as well as @rpardini's insight to utilise u-boot's built-in PXE functionality. |
b385c03 to
ff80f51
Compare
- Implement a wrapper function for the `pv` (Pipe Viewer) command in lib/functions/logging/runners.sh. - Check if stderr is connected to a TTY (`[[ -t 2 ]]`). - If in an interactive TTY, delegate execution to the system `pv` command. - If running in a non-interactive/redirected environment (such as Docker, background tasks, or CI pipelines), bypass the progress viewer to prevent hangs and terminal size query deadlocks by falling back to standard `cat` streaming. - Safely parse command arguments to extract the list of target filenames using a robust case statement. Why this is needed: During automated builds (e.g. Docker runs, background daemon loggers, or CI runners), there is no interactive tty. The standard `pv` utility attempts to perform ioctl/tty size calls and wait on output channels. If these streams are redirected or run without an active controller terminal, `pv` can hang indefinitely or stall build execution. Wrapping it ensures the pipe continues to flow cleanly as a simple stdin-to-stdout stream. Signed-off-by: Alastair D'Silva <alastair@d-silva.org> Assisted-by: Antigravity <antigravity@google.com>
… target config - Modify lib/functions/main/rootfs-image.sh to run create_netboot_tarballs_and_images when NETBOOT=yes, bypassing the standard partition and SD image creation steps. - Implement create_netboot_tarballs_and_images in lib/functions/image/rootfs-to-image.sh, and refactor it into smaller modular helper functions in lib/functions/image/rootfs-to-netboot.sh. - Automatically verify and install initramfs-tools in target chroot, compile, and package the target initramfs (uInitrd) to support network boot. - Parse or prompt for TFTP, NFS, target subnet, router/gateway IP, and netmask options, defaulting to generic fallback addresses (192.168.1.1, 192.168.1.0, 255.255.255.0). - Package the staging rootfs and boot directories into compressed tarballs. - Create a minimal 32MB bootloader loop image containing U-Boot and a U-Boot boot script. - Pivot to U-Boot's native PXE network booting flow (pxe get && pxe boot) for both the SD bootloader and diskless boots. - Generate a standard plain-text PXE configuration file (pxelinux.cfg/default) containing kernel, DTB, and command-line parameters, allowing users to modify boot arguments without recompiling boot.scr. - Support pure diskless PXE booting (zero SD card) if U-Boot is pre-installed in SPI flash, or boot via the minimal SD card image. - Support read-only NFS rootfs sharing using OverlayFS with `overlayroot=tmpfs` kernel parameter loaded via the custom initramfs hook. - Add target fstab cleanup to automatically comment out block devices (like / and /usr) during image build to prevent systemd from hanging on read-only NFS mounts. - Deprecate legacy ROOTFS_TYPE=nfs / nfs-root options. Add deprecation warnings to lib/functions/configuration/main-config.sh recommending users shift to the modern, complete NETBOOT=yes implementation. - Update netboot.md guide explaining target deployment and config requirements, documenting standard/diskless PXE options, and detail advanced user configurations (locale, root password, timezone, SSH key injection). Example Build Command: ./compile.sh BOARD=mellowflyc5 BRANCH=current RELEASE=bookworm BUILD_MINIMAL=yes NETBOOT=yes Output Artifacts (in output/images/): - Armbian-unofficial_26.08.0-trunk_Mellowflyc5_bookworm_current_6.18.38_minimal-rootfs.tar.zst (compressed NFS root filesystem) - Armbian-unofficial_26.08.0-trunk_Mellowflyc5_bookworm_current_6.18.38_minimal-boot.tar.zst (compressed boot/kernel directory) - Armbian-unofficial_26.08.0-trunk_Mellowflyc5_bookworm_current_6.18.38_minimal-bootloader.img (minimal 32MB U-Boot bootloader image) - Armbian-unofficial_26.08.0-trunk_Mellowflyc5_bookworm_current_6.18.38_minimal-netboot/ (directory containing kernel Image, dtb/, boot.scr, uInitrd, pxelinux.cfg/default, and netboot.md) Signed-off-by: Alastair D'Silva <alastair@d-silva.org> Assisted-by: Antigravity <antigravity@google.com>
- Add deprecation warnings to do_main_configuration in lib/functions/configuration/main-config.sh when ROOTFS_TYPE is set to nfs or nfs-root. - Recommend users transition to the modern, complete NETBOOT=yes implementation instead. Signed-off-by: Alastair D'Silva <alastair@d-silva.org> Assisted-by: Antigravity <antigravity@google.com>
|
Nice work. I do still think that this is waaay too big for core and would better serve us in an extension. (I also disagree with that |
|
I would reframe it as a reimplementation of ROOTFS=nfs - it aims to do the same goals, but with minimal local storage (only u-boot where needed), vs the existing implementation that requires a local kernel. This aligns it closer to how PCs network boot, and simplifies automated testing in a lab environment, as local storage only needs to be updated for u-boot changes, rather than kernel changes. I'm sure we could probably even chain-load u-boot, so local storage won't need updating in an automated test scenario. RE pv: this is used in a few places throughout the build, and the problem can be triggered just by trying to launch through an IDE without an associated terminal. |
This PR enables support for building netboot (network boot) targets directly from the Armbian Build Framework when
NETBOOT=yesis passed.The main intent is to facilitate developing new platforms, and testing in a lab environment.
Net booting will need to be enabled in u-boot on a per-platform basis.
For platforms without native network/PXE in firmware, we build a minimal stub image that can be flashed to SD/emmc, only containing U-boot, which then chains on to fetch and execute the kernel from the network, and mounts root via NFS.
Description of Changes
=y) kernel support forCONFIG_NFS_FS,CONFIG_NFS_V2/V3/V4, andCONFIG_ROOT_NFSin current sunxi64 kernel configs, allowing the kernel to boot and mount NFS shares out-of-the-box.create_netboot_tarballs_and_imagesstage whenNETBOOT=yes.boot.scrfrom aboot.cmdtemplate, using template placeholders (@BOARD@,@NETBOOT_NFS_SERVER@, and@NETBOOT_NFS_PATH@) that are substituted at build-time. This keeps personal hostnames, local IPs, and specific board names completely out of the git repository.boot.scrto flash onto target SD cards./dev/mmcblk*mounts) in target/etc/fstabto prevent systemd from hanging during netboot.netboot.mddeployment guide tailored to the user's configured settings, detailing NFS exports, TFTP copy steps, OpenWrt/Dnsmasq DHCP setups, and ISC DHCP setups.Tested Setup
This configuration has been successfully tested on:
Example Build Command
Output Artifacts (in
output/images/):Armbian_24.8.0-trunk_Mellowflyc5_bookworm_current_6.18.38-rootfs.tar.zst(NFS RootFS)Armbian_24.8.0-trunk_Mellowflyc5_bookworm_current_6.18.38-boot.tar.zst(Kernel/Boot Archive)Armbian_24.8.0-trunk_Mellowflyc5_bookworm_current_6.18.38-netboot/(Directory with Raw Boot files,boot.scr, andnetboot.md)Armbian_24.8.0-trunk_Mellowflyc5_bootloader.img(Minimal 32MB bootloader image)Summary by CodeRabbit
overlayroot=tmpfs.ROOTFS_TYPEvaluesnfs/nfs-rootin favor of usingNETBOOT=yesfor PXE network booting.