deb-bootupd/README.md
robojerk 6afdfbc6c4
All checks were successful
Build deb-bootupd Artifacts / build (push) Successful in 9m3s
Update Cargo.lock and README.md with latest dependencies and documentation
2025-08-12 16:18:59 -07:00

29 KiB

deb-bootc-image-builder

Debian adaptation of the bootc-image-builder project for creating bootable Debian-based immutable system images.

Summary

deb-bootc-image-builder is a container-based tool that converts Debian-based container images into bootable disk images (ISO, raw disk images, QCOW2, etc.). It addresses the need for creating immutable Debian systems using the bootc standard, making it possible to build and distribute Debian-based immutable distributions like particle-os.

This fork specifically adapts the original Red Hat/Fedora-centric bootc-image-builder for Debian-based systems, handling Debian package conventions, bootloader configurations, and system integration.

Key Features

  • Container-Based Tool: Runs as a container image, no local compilation required
  • Multiple Output Formats: Generates ISO, raw disk images, QCOW2, and other formats
  • Debian Integration: Native support for Debian package systems and conventions
  • Bootc Standard: Full compatibility with the bootc specification for immutable systems
  • Cross-Architecture Support: x86_64, aarch64, riscv64, powerpc64
  • Bootloader Support: GRUB, shim, systemd-boot detection and configuration
  • OSTree Integration: Seamless integration with Debian OSTree deployments

Architecture

Core Components

  • Container Runtime: Runs as a privileged container with access to host storage
  • Image Processing: Extracts and processes Debian-based container images
  • Bootloader Management: Installs and configures GRUB, shim, and systemd-boot
  • Disk Image Creation: Generates various bootable disk image formats
  • Debian Integration: Handles Debian package conventions and system structure

Container Architecture

  • Input: Debian-based container images (OCI format)
  • Processing: Container filesystem extraction and bootloader installation
  • Output: Bootable disk images (ISO, raw, QCOW2, etc.)
  • Runtime: Privileged container with host storage access

Design Philosophy

  • Container-First: Designed to run as a container tool, not a local binary
  • Debian-Native: Optimized for Debian package systems and conventions
  • Immutable-Focused: Built for creating immutable Debian system images
  • CI/CD Ready: Designed for automated image building pipelines

Usage

How bootc-image-builder Works

bootc-image-builder is a container image tool, not a locally compiled executable. It's distributed as a container image that you run with podman/docker to convert your Debian-based container images into bootable disk images.

The Process Flow

  1. Your CI/CD builds your Debian container image
  2. Your CI/CD runs bootc-image-builder as a container to convert your image
  3. bootc-image-builder produces artifacts (ISO, raw disk images, QCOW2, etc.)

Basic Usage

# Run bootc-image-builder against your Debian container image
podman run --rm --privileged \
  -v $PWD/output:/output \
  -v /var/lib/containers/storage:/var/lib/containers/storage \
  your-registry.com/deb-bootc-image-builder:latest \
  --type iso \
  --type raw \
  --output /output \
  your-registry.com/your-debian-image:latest

Output Artifacts

bootc-image-builder creates files like:

output/
├── your-image.iso          # Bootable installer ISO
├── your-image.raw          # Raw disk image  
├── your-image.qcow2        # VM image
└── build-logs/             # Build information

Workflow Integration

This section provides comprehensive workflow examples for integrating deb-bootc-image-builder into your CI/CD pipelines. Each workflow demonstrates the complete process from building your Debian container image to generating distributable bootable artifacts.

GitHub Actions Workflow

GitHub Actions - Complete Workflow
name: Build Debian Bootc Image

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
  release:
    types: [ published ]

env:
  REGISTRY: ghcr.io/${{ github.repository_owner }}
  IMAGE_NAME: particle-os
  BOOTC_BUILDER: your-registry.com/deb-bootc-image-builder:latest

jobs:
  build-container:
    runs-on: ubuntu-latest
    outputs:
      image-tag: ${{ steps.meta.outputs.tags }}
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Log in to Container Registry
      uses: docker/login-action@v3
      with:
        registry: ghcr.io
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=semver,pattern={{version}}
          type=semver,pattern={{major}}.{{minor}}
          type=sha,prefix={{branch}}-
    
    - name: Build and push container image
      uses: docker/build-push-action@v5
      with:
        context: .
        file: ./Containerfile.debian-bootc
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

  generate-bootable-images:
    needs: build-container
    runs-on: ubuntu-latest
    strategy:
      matrix:
        image-type: [iso, raw, qcow2]
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Podman
      uses: redhat-actions/setup-podman@v1
    
    - name: Pull bootc-image-builder
      run: |
        podman pull ${{ env.BOOTC_BUILDER }}
    
    - name: Generate ${{ matrix.image-type }} image
      run: |
        mkdir -p output
        podman run --rm --privileged \
          -v $PWD/output:/output \
          -v /var/lib/containers/storage:/var/lib/containers/storage \
          ${{ env.BOOTC_BUILDER }} \
          --type ${{ matrix.image-type }} \
          --output /output \
          ${{ needs.build-container.outputs.image-tag }}
    
    - name: Upload ${{ matrix.image-type }} artifact
      uses: actions/upload-artifact@v4
      with:
        name: particle-os-${{ matrix.image-type }}
        path: output/
        retention-days: 30

  publish-release:
    needs: [build-container, generate-bootable-images]
    if: github.event_name == 'release'
    runs-on: ubuntu-latest
    steps:
    - name: Download all artifacts
      uses: actions/download-artifact@v4
      with:
        path: artifacts/
    
    - name: Create release assets
      run: |
        mkdir -p release-assets
        find artifacts/ -name "*.iso" -exec cp {} release-assets/ \;
        find artifacts/ -name "*.raw" -exec cp {} release-assets/ \;
        find artifacts/ -name "*.qcow2" -exec cp {} release-assets/ \;
    
    - name: Upload to GitHub Release
      uses: softprops/action-gh-release@v1
      with:
        files: release-assets/*
        tag_name: ${{ github.event.release.tag_name }}
        name: ${{ github.event.release.name }}
        body: ${{ github.event.release.body }}

Key Features:

  • Multi-architecture support with Docker Buildx
  • Caching for faster builds
  • Matrix strategy for multiple image types
  • Automatic releases on tag creation
  • Artifact retention and management

GitLab CI Workflow

GitLab CI - Complete Workflow
stages:
  - build-container
  - generate-bootable-images
  - test-images
  - publish-artifacts
  - deploy

variables:
  REGISTRY: $CI_REGISTRY
  IMAGE_NAME: particle-os
  BOOTC_BUILDER: your-registry.com/deb-bootc-image-builder:latest
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"

build-container:
  stage: build-container
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  variables:
    DOCKER_HOST: tcp://docker:2376
    DOCKER_TLS_VERIFY: 1
    DOCKER_CERT_PATH: "$CI_PROJECT_DIR/.certs"
  before_script:
    - mkdir -p .certs
    - echo "$DOCKER_CA_CERT" > .certs/ca.pem
    - echo "$DOCKER_CERT" > .certs/cert.pem
    - echo "$DOCKER_KEY" > .certs/key.pem
    - chmod 600 .certs/*
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -f Containerfile.debian-bootc -t $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA .
    - docker build -f Containerfile.debian-bootc -t $REGISTRY/$IMAGE_NAME:latest .
    - docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA
    - docker push $REGISTRY/$IMAGE_NAME:latest
  only:
    - main
    - develop
    - merge_requests

generate-bootable-images:
  stage: generate-bootable-images
  image: registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-latest
  variables:
    GIT_STRATEGY: none
  before_script:
    - apk add --no-cache podman
    - mkdir -p output
  script:
    - podman pull $BOOTC_BUILDER
    - |
      podman run --rm --privileged \
        -v $PWD/output:/output \
        -v /var/lib/containers/storage:/var/lib/containers/storage \
        $BOOTC_BUILDER \
        --type iso,raw,qcow2 \
        --output /output \
        $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA
  artifacts:
    paths:
      - output/
    expire_in: 1 week
  only:
    - main
    - develop
  tags:
    - privileged

test-images:
  stage: test-images
  image: registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-latest
  variables:
    GIT_STRATEGY: none
  before_script:
    - apk add --no-cache qemu-system-x86
  script:
    - echo "Testing generated images..."
    - ls -la output/
    - |
      for img in output/*.qcow2; do
        echo "Testing $img..."
        timeout 30s qemu-system-x86_64 \
          -m 512M \
          -nographic \
          -drive file="$img",format=qcow2 \
          -boot d \
          -no-reboot \
          -no-shutdown || echo "QEMU test completed"
      done
  dependencies:
    - generate-bootable-images
  artifacts:
    reports:
      junit: test-results.xml
    paths:
      - output/
    expire_in: 1 week
  only:
    - main
    - develop

publish-artifacts:
  stage: publish-artifacts
  image: alpine:latest
  variables:
    GIT_STRATEGY: none
  before_script:
    - apk add --no-cache rsync openssh-client
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - |
      rsync -av --progress output/ \
        $ARTIFACT_USER@$ARTIFACT_SERVER:/var/www/releases/particle-os/$CI_COMMIT_REF_NAME/
    - |
      echo "Published artifacts to $ARTIFACT_SERVER"
      echo "Available at: https://$ARTIFACT_SERVER/releases/particle-os/$CI_COMMIT_REF_NAME/"
  dependencies:
    - test-images
  only:
    - main
    - develop
  environment:
    name: production
    url: https://$ARTIFACT_SERVER/releases/particle-os/

deploy:
  stage: deploy
  image: alpine:latest
  variables:
    GIT_STRATEGY: none
  before_script:
    - apk add --no-cache curl
  script:
    - |
      if [ "$CI_COMMIT_REF_NAME" = "main" ]; then
        echo "Deploying to production..."
        curl -X POST "$DEPLOY_WEBHOOK_URL" \
          -H "Content-Type: application/json" \
          -d "{\"ref\":\"$CI_COMMIT_REF_NAME\",\"sha\":\"$CI_COMMIT_SHA\"}"
        echo "Deployment triggered"
      else
        echo "Skipping deployment for branch: $CI_COMMIT_REF_NAME"
      fi
  dependencies:
    - publish-artifacts
  only:
    - main
  environment:
    name: production
    url: https://your-production-url.com

Key Features:

  • Docker-in-Docker for container builds
  • Podman integration for bootc-image-builder
  • QEMU testing of generated images
  • SSH-based artifact publishing
  • Environment-specific deployments
  • Comprehensive artifact management

Forgejo Actions Workflow

Forgejo Actions - Complete Workflow
name: Build Debian Bootc Image

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
  release:
    types: [ published ]

env:
  REGISTRY: forgejo.raines.xyz
  IMAGE_NAME: particle-os
  BOOTC_BUILDER: your-registry.com/deb-bootc-image-builder:latest

jobs:
  build-container:
    runs-on: ubuntu-latest
    outputs:
      image-tag: ${{ steps.meta.outputs.tags }}
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Log in to Forgejo Container Registry
      uses: docker/login-action@v3
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ secrets.FORGEJO_USERNAME }}
        password: ${{ secrets.FORGEJO_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=semver,pattern={{version}}
          type=semver,pattern={{major}}.{{minor}}
          type=sha,prefix={{branch}}-
    
    - name: Build and push container image
      uses: docker/build-push-action@v5
      with:
        context: .
        file: ./Containerfile.debian-bootc
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

  generate-bootable-images:
    needs: build-container
    runs-on: ubuntu-latest
    strategy:
      matrix:
        image-type: [iso, raw, qcow2]
        architecture: [amd64, arm64]
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Podman
      uses: redhat-actions/setup-podman@v1
    
    - name: Pull bootc-image-builder
      run: |
        podman pull ${{ env.BOOTC_BUILDER }}
    
    - name: Generate ${{ matrix.image-type }} for ${{ matrix.architecture }}
      run: |
        mkdir -p output/${{ matrix.architecture }}
        podman run --rm --privileged \
          -v $PWD/output/${{ matrix.architecture }}:/output \
          -v /var/lib/containers/storage:/var/lib/containers/storage \
          ${{ env.BOOTC_BUILDER }} \
          --type ${{ matrix.image-type }} \
          --target-arch ${{ matrix.architecture }} \
          --output /output \
          ${{ needs.build-container.outputs.image-tag }}
    
    - name: Upload ${{ matrix.architecture }} ${{ matrix.image-type }} artifact
      uses: actions/upload-artifact@v4
      with:
        name: particle-os-${{ matrix.architecture }}-${{ matrix.image-type }}
        path: output/${{ matrix.architecture }}/
        retention-days: 30

  test-images:
    needs: [build-container, generate-bootable-images]
    runs-on: ubuntu-latest
    strategy:
      matrix:
        architecture: [amd64, arm64]
    steps:
    - name: Download artifacts
      uses: actions/download-artifact@v4
      with:
        pattern: particle-os-${{ matrix.architecture }}-*
        merge-multiple: true
        path: test-artifacts/
    
    - name: Set up QEMU for ${{ matrix.architecture }}
      if: matrix.architecture != 'amd64'
      uses: docker/setup-qemu-action@v3
      with:
        platforms: ${{ matrix.architecture }}
    
    - name: Test ${{ matrix.architecture }} images
      run: |
        echo "Testing ${{ matrix.architecture }} images..."
        ls -la test-artifacts/
        
        # Test QCOW2 images if available
        for img in test-artifacts/*.qcow2; do
          if [ -f "$img" ]; then
            echo "Testing $img..."
            # Basic file validation
            qemu-img info "$img"
            # Check file integrity
            qemu-img check "$img" || echo "Image validation completed"
          fi
        done

  publish-release:
    needs: [build-container, generate-bootable-images, test-images]
    if: github.event_name == 'release'
    runs-on: ubuntu-latest
    steps:
    - name: Download all artifacts
      uses: actions/download-artifact@v4
      with:
        path: release-artifacts/
    
    - name: Create release assets
      run: |
        mkdir -p release-assets
        find release-artifacts/ -name "*.iso" -exec cp {} release-assets/ \;
        find release-artifacts/ -name "*.raw" -exec cp {} release-assets/ \;
        find release-artifacts/ -name "*.qcow2" -exec cp {} release-assets/ \;
        
        # Create checksums
        cd release-assets
        for file in *; do
          sha256sum "$file" > "$file.sha256"
        done
        
        # Create manifest
        echo "# Particle-OS Release Assets" > manifest.md
        echo "Release: ${{ github.event.release.tag_name }}" >> manifest.md
        echo "Date: $(date -u)" >> manifest.md
        echo "" >> manifest.md
        echo "## Available Images" >> manifest.md
        for file in *.iso *.raw *.qcow2; do
          if [ -f "$file" ]; then
            echo "- $file" >> manifest.md
          fi
        done
    
    - name: Upload to Forgejo Release
      uses: softprops/action-gh-release@v1
      with:
        files: release-assets/*
        tag_name: ${{ github.event.release.tag_name }}
        name: ${{ github.event.release.name }}
        body: ${{ github.event.release.body }}
        draft: false
        prerelease: false

Key Features:

  • Multi-architecture support (amd64, arm64)
  • Forgejo-specific registry integration
  • QEMU emulation for cross-architecture testing
  • Comprehensive artifact management
  • Checksum generation for security
  • Release manifest creation

Workflow Best Practices

Best Practices & Tips

Container Image Requirements

# Your Containerfile MUST include these labels
LABEL com.debian.bootc="true"
LABEL ostree.bootable="true"

# Optional but recommended
LABEL org.opencontainers.image.title="Your OS Name"
LABEL org.opencontainers.image.description="Description"
LABEL org.opencontainers.image.vendor="Your Organization"

Environment Variables

# Required for all workflows
REGISTRY=your-registry.com
IMAGE_NAME=your-os-name
BOOTC_BUILDER=your-registry.com/deb-bootc-image-builder:latest

# Optional but useful
ARTIFACT_SERVER=your-artifact-server.com
DEPLOY_WEBHOOK_URL=https://your-deploy-service.com/webhook

Security Considerations

  • Use secrets for registry credentials
  • Implement artifact signing for production releases
  • Scan images for vulnerabilities before publishing
  • Use minimal base images to reduce attack surface

Performance Optimization

  • Enable caching for faster builds
  • Use multi-stage builds to reduce image size
  • Parallel execution for independent jobs
  • Artifact retention policies to manage storage

Monitoring & Debugging

  • Add health checks to your container images
  • Implement logging for troubleshooting
  • Use job dependencies to ensure proper execution order
  • Add timeout limits to prevent hanging builds

Installation

Prerequisites

For Container Usage:

  • Linux system with podman or docker
  • Container runtime (podman, docker, or containerd)
  • Privileged access for disk image creation
  • Storage space for output artifacts

For Building the Container Image:

  • Linux system with podman or docker
  • Build tools and dependencies
  • Access to Debian package repositories
# Pull the pre-built container image
podman pull your-registry.com/deb-bootc-image-builder:latest

# Or build from source
git clone https://git.raines.xyz/robojerk/deb-bootc-image-builder.git
cd deb-bootc-image-builder
podman build -t deb-bootc-image-builder:latest .

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:

  1. Add ACCESS_TOKEN secret to repository settings
  2. Token needs repo and write:packages permissions
  3. 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

  1. Package System: Replaced RPM with DPKG/APT integration
  2. OS Detection: Enhanced for Debian family distributions
  3. Path Conventions: Adapted for Debian filesystem standards
  4. 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

  1. Permission Denied: Ensure you're running with root privileges
  2. EFI Not Detected: Verify efibootmgr is installed and EFI is enabled
  3. OSTree Integration: Check that OSTree is properly configured
  4. 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

  1. Core Functionality: Ensure basic bootloader management works on Debian
  2. OSTree Integration: Optimize for Debian OSTree deployments
  3. Testing: Comprehensive test coverage for Debian environments
  4. 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

Debian-Specific Features

Package System Integration

  • DPKG/APT Support: Native integration with Debian package management
  • Debian Conventions: Follows Debian filesystem and package standards
  • Package Queries: Uses dpkg -S and dpkg -s for metadata discovery
  • Version Handling: Supports Debian package versioning conventions

Bootloader Configuration

  • GRUB Integration: Debian-specific GRUB configuration and installation
  • EFI Support: UEFI bootloader management with Debian conventions
  • Kernel Detection: Handles Debian kernel naming patterns
  • Initramfs Support: Integration with Debian initramfs tools

OSTree Integration

  • Debian OSTree: Support for Debian-based immutable systems
  • Deployment Management: Works with OSTree deployment structures
  • State Persistence: Maintains configuration across deployments
  • Rollback Support: Leverages OSTree's built-in rollback capabilities

Roadmap

  • Initial Debian Adaptation: Basic DPKG integration
  • Container Tool Structure: Proper container-based architecture
  • Debian Package Support: DPKG/APT integration
  • 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 creating bootable Debian-based immutable system images using the bootc standard and ublue-os tools.

Test workflow trigger - Sun Aug 10 08:53:24 AM PDT 2025