- Fix Cargo.lock version 4 compatibility by using nightly Rust toolchain - Replace actions/checkout with manual git clone to avoid Node.js dependency - Update simple-build.yml to use Ubuntu container and manual checkout - Add Cargo.lock regeneration logic for version compatibility - Ensure both workflows can handle modern Rust lock file versions |
||
|---|---|---|
| .cargo | ||
| .forgejo/workflows | ||
| .github | ||
| ci | ||
| contrib/packaging | ||
| debian | ||
| doc | ||
| scripts | ||
| src | ||
| systemd | ||
| tests | ||
| xtask | ||
| .cci.jenkinsfile | ||
| .dockerignore | ||
| .gitignore | ||
| bootupd.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| COPYRIGHT | ||
| deb-bootupd.md | ||
| Dockerfile | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
deb-bootupd
A Debian-compatible fork of bootupd for immutable Debian systems.
Project Overview
deb-bootupd is a sophisticated, production-ready Rust-based CLI tool that provides cross-distribution, OS update system agnostic bootloader management capabilities. It addresses a critical gap in Linux system management by handling bootloader updates consistently across different distributions and update mechanisms.
This fork specifically adapts the original Red Hat/Fedora-centric bootupd for Debian-based immutable systems using OSTree and bootc, making it possible to create immutable Debian distributions like particle-os.
Key Features
- Single Binary, Multicall Architecture: The same executable serves as both
bootupdandbootupctl - Component-Based Design: Pluggable architecture supporting EFI, BIOS, and other bootloader types
- OSTree Integration: Full support for Debian OSTree immutable systems
- Debian Package System: Native DPKG/APT integration instead of RPM
- Cross-Architecture Support: x86_64, aarch64, riscv64, powerpc64
- Bootloader Support: GRUB, shim, systemd-boot detection
- State Persistence: Robust state management across OSTree deployments
Architecture
Core Components
- EFI Component: UEFI bootloader management with automatic ESP detection
- BIOS Component: Traditional BIOS/MBR bootloader support
- OSTree Integration: Seamless integration with Debian OSTree deployments
- Package System: DPKG-based package metadata discovery
- State Management: Persistent state tracking in
/boot/bootupd-state.json
Binary Architecture
bootupd: The main binary that performs bootloader updates (NOT a daemon)bootupctl: A symlink to the mainbootupdbinary (multicall binary pattern)- Relationship: Both are the same binary, with
bootupctlbeing a symlink. The binary detects which name it was called as and behaves accordingly.
Design Philosophy
- No Daemon: Despite the 'd' suffix, it's "bootloader-upDater" not "bootloader-updater-Daemon"
- systemd Integration: Uses
systemd-runfor robust locking and sandboxing - Safety First: Comprehensive error handling and rollback capabilities
- Distribution Agnostic: Core architecture works across different Linux distributions
Installation
Installation Methods
1. Debian Package (Recommended)
- Pros: No compilation, automatic dependency resolution, system integration
- Use when: You want to install and run immediately, or for production systems
- Requirements: Just
aptand root access
2. Pre-built .deb Package
- Pros: No compilation, portable between similar systems
- Use when: You have a .deb file but no repository access
- Requirements:
dpkgand root access
3. Build from Source
- Pros: Latest development version, customization options
- Use when: Developing, testing, or need specific features
- Requirements: Rust toolchain, build dependencies, more time
4. Build Your Own .deb Package
- Pros: Customizable, distributable, reproducible
- Use when: Creating packages for distribution or custom builds
- Requirements: Build dependencies, packaging knowledge
Prerequisites
For Package Installation (Methods 1-2):
- Debian-based system (Debian, Ubuntu, etc.)
aptpackage manager- Root access for installation
For Source Building (Methods 3-4):
- Debian-based system (Debian, Ubuntu, etc.)
- Rust toolchain (rustc, cargo)
- Build dependencies (see below)
Required Runtime Packages (installed automatically with .deb):
efibootmgr(for EFI systems)grub-common(for GRUB support)mount/umount(standard Linux tools)
Debian Package (Recommended - No Compilation Required)
# Install from Debian repository (when available)
sudo apt update
sudo apt install deb-bootupd
# Or install from a pre-built .deb package
sudo dpkg -i deb-bootupd_*.deb
# If dependencies are missing, install them
sudo apt install -f
Building from Source
# Clone the repository
git clone https://git.raines.xyz/robojerk/deb-bootupd.git
cd deb-bootupd
# Build the project
cargo build --release
# Install (requires root)
sudo cargo install --path .
Running as Rust Script (Development)
# Clone the repository
git clone https://git.raimes.xyz/robojerk/deb-bootupd.git
cd deb-bootupd
# Run directly without installing (development mode)
cargo run -- status # Run bootupctl status
cargo run -- update # Run bootupctl update
cargo run -- adopt-and-update # Run bootupctl adopt-and-update
# Run with specific binary name (multicall binary)
cargo run --bin bootupd -- status # Run as bootupd binary
cargo run --bin bootupctl -- status # Run as bootupctl binary
# Run with debug output
RUST_LOG=debug cargo run -- status
# Run with custom log level
RUST_LOG=info cargo run -- status
# Run specific tests
cargo test # Run all tests
cargo test --package deb-bootupd # Run package tests
cargo test --test integration # Run integration tests
# Development workflow
cargo check # Check compilation without building
cargo clippy # Run linter
cargo fmt --check # Check code formatting
cargo fmt # Auto-format code
How the Multicall Binary Works
deb-bootupd uses a multicall binary pattern - a single Rust executable that behaves differently based on how it's called:
# When called as 'bootupd' (main binary)
cargo run --bin bootupd -- install --src-root /src --dest-root /dest
# When called as 'bootupctl' (CLI interface)
cargo run --bin bootupctl -- status
cargo run --bin bootupctl -- update
# The binary detects argv[0] and switches behavior accordingly
Benefits for Development:
- Single codebase: All functionality in one Rust project
- Easy testing: Test both modes from one source
- Consistent behavior: Same binary, different interfaces
- Simplified deployment: One executable to install
Building Your Own Debian Package
# Install build dependencies
sudo apt install build-essential dh-cargo rustc cargo pkg-config libssl-dev libsystemd-dev
# Build Debian package
dpkg-buildpackage -b
# Install the resulting package
sudo dpkg -i ../deb-bootupd_*.deb
Quick Start
Install and Run (No Compilation)
# 1. Install the package (when available in repositories)
sudo apt update && sudo apt install deb-bootupd
# 2. Check if it's working
bootupctl status
# 3. You're ready to use deb-bootupd!
Automated Builds with Forgejo Actions
This repository includes Forgejo Actions workflows for automated building and artifact management:
.forgejo/workflows/build-artifacts.yml- Full build pipeline with Forgejo Package Registry upload.forgejo/workflows/simple-build.yml- Simple build with artifact upload
Setup Requirements:
- Add
ACCESS_TOKENsecret to repository settings - Token needs
repoandwrite:packagespermissions - Workflows trigger on push/PR to main/master branches
What Gets Built:
- Rust binaries (release mode)
- Source code artifacts
- Debian packaging files
- Systemd service files
Usage
Basic Commands
# Check system status
bootupctl status
# Update all bootloader components
bootupctl update
# Adopt existing bootloaders and update them
bootupctl adopt-and-update
# Validate system state
bootupctl validate
Advanced Operations
# Generate update metadata (for image builders)
bootupd generate-update-metadata
# Install bootloader components
bootupd install --src-root /path/to/source --dest-root /path/to/destination
OSTree Integration
deb-bootupd is specifically designed for Debian OSTree immutable systems:
- Image-based Updates: Updates come from new bootc images, not traditional package repositories
- Deployment Coordination: Works seamlessly with OSTree deployment system
- State Persistence: Bootloader state survives across OSTree deployments
- Rollback Support: Leverages OSTree's built-in rollback capabilities
Particle-OS Integration
This fork is specifically designed to work with particle-os, a Debian-based immutable distribution:
- Hybrid Approach: Debian packages within immutable OSTree structure
- Bootc Integration: Full integration with bootc image builder
- Debian Conventions: Follows Debian filesystem and package conventions
Configuration
State File Location
- State File:
/boot/bootupd-state.json - Lock File:
/run/bootupd-lock - Updates Directory:
/usr/lib/bootupd/updates
Component Configuration
Components are automatically detected and configured based on your system:
- EFI Systems: Automatic ESP detection and UEFI boot entry management
- BIOS Systems: Direct MBR manipulation for traditional bootloaders
- Hybrid Systems: Support for both EFI and BIOS configurations
Development
Project Structure
deb-bootupd/
├── src/ # Source code
│ ├── efi.rs # EFI component implementation
│ ├── bios.rs # BIOS component implementation
│ ├── ostreeutil.rs # OSTree integration
│ ├── packagesystem.rs # DPKG package system integration
│ └── ...
├── systemd/ # Systemd service files
├── tests/ # Test suite
├── Cargo.toml # Rust dependencies
└── debian/ # Debian packaging files
Key Adaptations from Upstream
- Package System: Replaced RPM with DPKG/APT integration
- OS Detection: Enhanced for Debian family distributions
- Path Conventions: Adapted for Debian filesystem standards
- OSTree Integration: Optimized for Debian OSTree deployments
Building and Testing
# Run tests
cargo test
# Run with specific features
cargo test --features integration
# Check code quality
cargo clippy
cargo fmt
Troubleshooting
Common Issues
- Permission Denied: Ensure you're running with root privileges
- EFI Not Detected: Verify
efibootmgris installed and EFI is enabled - OSTree Integration: Check that OSTree is properly configured
- Package Queries: Ensure DPKG database is accessible
Debug Mode
# Enable debug logging
RUST_LOG=debug bootupctl status
# Check system state
cat /boot/bootupd-state.json
Contributing
We welcome contributions! This project is a proof-of-concept for immutable Debian systems.
Development Priorities
- Core Functionality: Ensure basic bootloader management works on Debian
- OSTree Integration: Optimize for Debian OSTree deployments
- Testing: Comprehensive test coverage for Debian environments
- Documentation: Clear guides for users and developers
License
This project is licensed under the same terms as the original bootupd project. See the LICENSE file for details.
Acknowledgments
- Original bootupd: CoreOS bootupd - The excellent foundation this project builds upon
- ublue-os: For pioneering immutable Debian distributions
- Debian Community: For the robust package system and distribution standards
Roadmap
- Initial Debian Adaptation: Basic DPKG integration
- OSTree Support: Integration with Debian OSTree systems
- Enhanced Testing: Comprehensive test suite for Debian environments
- Production Readiness: Full validation and stability testing
- Community Adoption: Integration with particle-os and other Debian immutable distributions
Support
- Issues: Report bugs and feature requests via GitLab issues
- Discussions: Join the conversation in GitLab discussions
- Documentation: Check this README and inline code documentation
Note: This is a proof-of-concept project. While it's designed to be production-ready, it's primarily intended to demonstrate the feasibility of immutable Debian systems using ublue-os tools.