-
Notifications
You must be signed in to change notification settings - Fork 0
Initialize BitBoot multiboot USB system with rd.systemd.pull support #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
|
@copilot This build failed, please review and fix https://github.com/bitbuilder-io/bitboot/actions/runs/19793549828/job/56710662467#step:8:18 and repeat until the build succeeds. |
Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
Fixed in commit 4b38281. The build was failing because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request initializes the BitBoot repository, a multiboot USB system that creates unified kernel images (UKIs) capable of booting raw disk images from HTTP/HTTPS sources using systemd v258's rd.systemd.pull functionality.
Key Changes:
- Complete directory structure and build system implementation (scripts, Makefile, Containerfile, CI/CD workflows)
- Boot profile configurations for multiple distributions using UKI format with embedded command lines
- Custom initramfs modules and hooks for network pull, ZFS support, and systemd-import integration
Reviewed changes
Copilot reviewed 34 out of 34 changed files in this pull request and generated 25 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/fetch-deps.sh | Downloads ZFSBootMenu, netboot.xyz, and Alpine Linux components with retry logic |
| scripts/create-usb.sh | Creates bootable USB image with GPT/ESP layout and installs all UKIs and dependencies |
| scripts/build-uki.sh | Builds unified kernel images for each profile using ukify or objcopy fallback |
| scripts/build-initramfs.sh | Generates custom initramfs with dracut, includes systemd v258+ components |
| initramfs/modules/bitboot-pull.sh | Dracut module for rd.systemd.pull support with network and compression tools |
| initramfs/modules/bitboot-pull-premount.sh | Pre-mount hook ensuring network availability before image pull |
| initramfs/hooks/bitboot-zfs.sh | ZFS support module with kernel modules and userspace tools |
| initramfs/hooks/bitboot-network-pull.sh | Network pull support with systemd-importd integration |
| initramfs/config.yaml | Dracut configuration defining modules, drivers, and binaries for initramfs |
| config/loader/loader.conf | systemd-boot configuration with timeout and console settings |
| config/loader/entries/*.conf | Boot menu entries for all profiles (chainload EFI binaries) |
| config/cmdline.d/profiles/*.conf | Per-profile kernel command lines embedded into respective UKIs |
| config/cmdline.d/base.conf | Common kernel parameters for console and logging |
| config/cmdline.d/network.conf | Network boot prerequisites with DHCP and systemd-networkd |
| Makefile | Build orchestration with targets for deps, initramfs, uki, and usb creation |
| Containerfile | Fedora 41-based build environment with systemd v258+ and required tools |
| README.md | Comprehensive documentation covering features, usage, and customization |
| CLAUDE.md | AI assistant instructions with project context and patterns |
| .github/workflows/build.yml | CI pipeline for building and validating on push/PR |
| .github/workflows/release.yml | Automated release workflow for tagged versions with artifact publishing |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
scripts/build-uki.sh
Outdated
| grep -v '^\s*#' "${cmdline_file}" | grep -v '^\s*$' | tr '\n' ' ' > "${cmdline_temp}" | ||
| echo "" >> "${cmdline_temp}" | ||
|
|
||
| log_info " Cmdline: $(cat ${cmdline_temp})" |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable assignment uses command substitution with cat which is unnecessary. This can be simplified to: log_info " Cmdline: $(tr '\n' ' ' < "${cmdline_temp}")" or even better, just use the original file directly without the extra process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit 3379ff0. Simplified the command substitution from $(cat ${cmdline_temp}) to $(tr '\n' ' ' < "${cmdline_temp}").
| mkdir -p "${initdir}/run/machines" | ||
|
|
||
| # Enable the services | ||
| systemctl -q --root "$initdir" enable systemd-importd.socket 2>/dev/null || true |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The systemctl command uses $initdir without quotes. It should be "${initdir}" for proper quoting to handle paths with spaces or special characters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit 3379ff0. Changed $initdir to "${initdir}" for proper quoting.
initramfs/config.yaml
Outdated
| # This file defines how the custom initramfs is built using dracut | ||
| # | ||
| # The initramfs must contain: | ||
| # - systemd v258+ with rd.systemd.pull support |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment states systemd v258 is required for rd.systemd.pull, but according to the PR description, systemd v258 introduced this feature. The systemd version check should be >= 258, not < 258. The condition on line 124 correctly checks for less than 258 and warns, which is appropriate, but ensure this aligns with actual systemd version support.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit d8bbaec. Clarified the systemd version requirement comment to explicitly state "v258 or higher" and note that rd.systemd.pull was introduced in v258. The version check in build-initramfs.sh (line 124) correctly warns when systemd < 258.
.github/workflows/release.yml
Outdated
| wget https://github.com/\${GITHUB_REPOSITORY}/releases/download/${VERSION}/bitboot-x86_64.img.xz | ||
| # Decompress and write to USB (replace /dev/sdX with your USB device) | ||
| xzcat bitboot-x86_64.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync | ||
| \`\`\` | ||
| ### Verify Downloads | ||
| \`\`\`bash | ||
| sha256sum -c SHA256SUMS | ||
| \`\`\` | ||
| ## System Requirements | ||
| - UEFI-capable system (64-bit x86_64) | ||
| - 512MB+ USB drive | ||
| - Network connection (for rd.systemd.pull profiles) | ||
| - Minimum 4GB RAM recommended for network booting | ||
| ## Documentation | ||
| See the [README](https://github.com/\${GITHUB_REPOSITORY}#readme) for detailed usage instructions. |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable GITHUB_REPOSITORY is used but not defined in the heredoc. GitHub Actions provides this as ${{ github.repository }} but it's being referenced inside the shell script without the Actions syntax. Line 123 and 144 should use ${GITHUB_REPOSITORY} or the Actions variable syntax ${{ github.repository }}.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit 5dc8a7b. Changed the heredoc to use a shell variable REPO that's set from ${{ github.repository }}, so the repository name is properly expanded in the release notes URLs.
| UKI_BUILD_DIR="$(dirname "${UKI_PATH}")" | ||
| if [[ -d "${UKI_BUILD_DIR}/efi" ]]; then | ||
| log_info "Installing BitBoot UKIs..." | ||
| mkdir -p "${MOUNT_POINT}/EFI/bitboot" |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section contains duplicate code - the directory creation for "${MOUNT_POINT}/EFI/bitboot" is repeated on lines 166 and 178. The second occurrence on line 178 is redundant and should be removed.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Daniel Bodnar <1790726+danielbodnar@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Daniel Bodnar <1790726+danielbodnar@users.noreply.github.com>
Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
|
@copilot Please fix that, and also update it to use the edge release: |
…config-lts Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
... Fixed in commit 8817a2f. Changed Alpine Linux from |
|
@copilot Also, let's use fedora 43, not 41 |
…md.pull) Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
Fixed in commit 5325e9c. Updated Fedora from 41 to 43 in:
|
|
@copilot Can we split .github/workflows/build.yml and .github/workflows/release.yml out into multiple, modular files? That way if one distro fails they don |
Co-authored-by: danielbodnar <1790726+danielbodnar@users.noreply.github.com>
Fixed in commit 204c3e1. Split workflows into modular jobs: New structure:
Each distro now builds independently, so one failure won't block others. The final Also replaced Fedora CoreOS with uCore (ublue-os/ucore) - boots CoreOS base image that can be rebased to uCore after boot. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 35 out of 35 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| - name: Build UKI for ${{ inputs.profile }} | ||
| run: | | ||
| ./scripts/build-uki.sh --profile "${{ inputs.profile }}" --output "${BUILD_DIR}/efi/${{ inputs.profile }}.efi" |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The build-uki.sh script's --output parameter expects a directory path (as documented on line 12: 'Output directory (default: ./build)'), but this workflow invocation passes a file path. The script's build_uki() function constructs the output file path as ${BUILD_DIR}/efi/${profile_name}.efi, so passing a file path here will result in an incorrect path like build/efi/profile.efi/efi/profile.efi. Change this to --output \"${BUILD_DIR}\" to pass only the directory.
| ./scripts/build-uki.sh --profile "${{ inputs.profile }}" --output "${BUILD_DIR}/efi/${{ inputs.profile }}.efi" | |
| ./scripts/build-uki.sh --profile "${{ inputs.profile }}" --output "${BUILD_DIR}" |
| ### Build System | ||
| - systemd v258+ (for rd.systemd.pull support) | ||
| - Fedora 41+ or equivalent (recommended) |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation inconsistency: The README states 'Fedora 41+ or equivalent' as a requirement, but the Containerfile uses Fedora 43. Update this to 'Fedora 43+ or equivalent' to match the actual build environment being used.
| - Fedora 41+ or equivalent (recommended) | |
| - Fedora 43+ or equivalent (recommended) |
| # | ||
| # For more info: https://github.com/ublue-os/ucore | ||
|
|
||
| rd.systemd.pull=raw,machine,verify=no,blockdev:rootdisk:https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/43.20250521.3.0/x86_64/fedora-coreos-43.20250521.3.0-metal.x86_64.raw.xz |
Copilot
AI
Nov 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Image integrity verification disabled (verify=no) for rd.systemd.pull. This allows booting a tampered or malicious image if the download is compromised or redirected; use signature verification (e.g., verify=signature) with trusted keys.
Severity: HIGH. Confidence: 9
| rd.systemd.pull=raw,machine,verify=no,blockdev:rootdisk:https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/43.20250521.3.0/x86_64/fedora-coreos-43.20250521.3.0-metal.x86_64.raw.xz | |
| rd.systemd.pull=raw,machine,verify=signature,blockdev:rootdisk:https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/43.20250521.3.0/x86_64/fedora-coreos-43.20250521.3.0-metal.x86_64.raw.xz |
Original prompt
BitBoot Repository Initialization Prompt
Context & Objective
Initialize a new GitHub repository called
bitbootthat builds a multiboot USB system producing a unified kernel image (bitboot.efi). This UKI serves as a meta-bootloader combining ZFSBootMenu, netboot.xyz, and systemd-boot into a single portable EFI binary with the revolutionary capability to pull and boot raw disk images directly from HTTP/HTTPS sources at boot time using systemd v258'srd.systemd.pullfunctionality.The core innovation is leveraging
systemd-import-generatorto dynamically download, decompress, and loopback-mount raw disk images before pivoting root—enabling network-booted ephemeral Linux environments from a single USB drive without pre-downloading ISOs. Boot entries are defined as standard systemd-boot loader entries (/loader/entries/*.conf) where each distro profile specifies its pull URL and root device reference.Technical Architecture
The
bitboot.efiunified kernel image must embed:systemd-importd,systemd-import-generator, andrd.systemd.pullsupport/dev/loop*ZFSBootMenu Integration Benefits
ZFSBootMenu's recovery environment provides critical capabilities for ZFS administration without requiring a separate boot medium:
zpool,zfs,zdb,zstream,zinjectThis means users can boot
bitboot.efi, enter the ZFSBootMenu recovery shell, and perform tasks like:Boot flow: UEFI →
bitboot.efi→ systemd-boot menu → select distro profile →rd.systemd.pulldownloads image → loopback attach → pivot root → boot into downloaded OS.Repository Structure Requirements
Create the following layout:
Distro Profile Entry Format
Each loader entry uses this pattern leveraging
rd.systemd.pull:For proper raw images (not ISOs), the pattern is: