Expand description
§Writing a container to a block device in a bootable way
This module implements the core installation logic for bootc, enabling a container image to be written to storage in a bootable form. It bridges the gap between OCI container images and traditional bootable Linux systems.
§Overview
The installation process transforms a container image into a bootable system by:
-
Preparing the environment: Validating we’re running in a privileged container, handling SELinux re-execution if needed, and loading configuration.
-
Setting up storage: Either creating partitions (
to-disk) or using externally-prepared filesystems (to-filesystem). -
Deploying the image: Pulling the container image into an ostree repository and creating a deployment, or setting up a composefs-based root.
-
Installing the bootloader: Using bootupd, systemd-boot, or zipl depending on architecture and configuration.
-
Finalizing: Trimming the filesystem, flushing writes, and freezing/thawing the journal.
§Installation Modes
§bootc install to-disk
Creates a complete bootable system on a block device. This is the simplest path and handles partitioning automatically using the Discoverable Partitions Specification (DPS). The partition layout includes:
- ESP (EFI System Partition): Required for UEFI boot
- BIOS boot partition: For legacy boot on x86_64
- Boot partition: Optional, used when LUKS encryption is enabled
- Root partition: Uses architecture-specific DPS type GUIDs for auto-discovery
§bootc install to-filesystem
Installs to a pre-mounted filesystem, allowing external tools to handle complex
storage layouts (RAID, LVM, custom LUKS configurations). The caller is responsible
for creating and mounting the filesystem, then providing appropriate --karg
options or mount specifications.
§bootc install to-existing-root
“Alongside” installation mode that converts an existing Linux system. The boot
partition is wiped and replaced, but the root filesystem content is preserved
until reboot. Post-reboot, the old system is accessible at /sysroot for
data migration.
§bootc install reset
Creates a new stateroot within an existing bootc system, effectively providing a factory-reset capability without touching other stateroots.
§Storage Backends
§OSTree Backend (Default)
Uses ostree-ext to convert container layers into an ostree repository. The
deployment is created via ostree admin deploy, and bootloader entries are
managed via BLS (Boot Loader Specification) files.
§Composefs Backend (Experimental)
Alternative backend using composefs overlayfs for the root filesystem. Provides stronger integrity guarantees via fs-verity and supports UKI (Unified Kernel Images) for measured boot scenarios.
§Discoverable Partitions Specification (DPS)
As of bootc 1.11, partitions are created with DPS type GUIDs from the UAPI Group specification. This enables:
- Auto-discovery: systemd-gpt-auto-generator can mount partitions without explicit configuration
- Architecture awareness: Root partition types are architecture-specific, preventing cross-architecture boot issues
- Future extensibility: Enables systemd-repart for declarative partition management
See crate::discoverable_partition_specification for the partition type GUIDs.
§Installation Flow
The high-level flow is:
- CLI entry →
install_to_disk,install_to_filesystem, orinstall_to_existing_root - Preparation →
prepare_installvalidates environment, handles SELinux, loads config - Storage setup → (to-disk only)
baseline::install_create_rootfspartitions and formats - Deployment →
install_to_filesystem_implbranches to OSTree or Composefs backend - Bootloader →
crate::bootloader::install_via_bootupdor architecture-specific installer - Finalization →
finalize_filesystemtrims, flushes, and freezes the filesystem
For a visual diagram of this flow, see the bootc documentation.
§Key Types
-
State: Immutable global state for the installation, including source image info, SELinux state, configuration, and composefs options. -
RootSetup: Represents the prepared root filesystem, including mount paths, device information, boot partition specs, and kernel arguments. -
SourceInfo: Information about the source container image, including the ostree-container reference and whether SELinux labels are present. -
SELinuxFinalState: Tracks SELinux handling during installation (enabled, disabled, host-disabled, or force-disabled).
§Configuration
Installation is configured via TOML files loaded from multiple paths in systemd-style priority order:
/usr/lib/bootc/install/*.toml- Distribution/image defaults/etc/bootc/install/*.toml- Local overrides
Files are merged alphanumerically, with higher-numbered files taking precedence.
See config::InstallConfiguration for the schema.
Key configurable options include:
- Root filesystem type (xfs, ext4, btrfs)
- Allowed block setups (direct, tpm2-luks)
- Default kernel arguments
- Architecture-specific overrides
§Submodules
baseline: The “baseline” installer for simple partitioning (to-disk)config: TOML configuration parsing and mergingcompletion: Post-installation hooks for external installers (Anaconda)osconfig: SSH key injection and OS configurationaleph: Installation provenance tracking (.bootc-aleph.json)osbuild: Helper APIs for bootc-image-builder integration
Modules§
- aleph 🔒
- baseline 🔒
- The baseline installer
- completion 🔒
- This module handles finishing/completion after an ostree-based install from e.g. Anaconda.
- config 🔒
- Configuration for
bootc install - osbuild 🔒
- Helper APIs for interacting with bootc-image-builder
- osconfig 🔒
Structs§
- Install
Composefs 🔒Opts - Install
Config 🔒Opts - Install
Print 🔒Configuration Opts - Install
Reset 🔒Opts - Install
Source 🔒Opts - Install
Target 🔒Filesystem Opts - Options for installing to a filesystem
- Install
Target 🔒Opts - Install
ToDisk 🔒Opts - Install
ToExisting 🔒Root Opts - Install
ToFilesystem 🔒Opts - Mount
Spec 🔒 - A mount specification is a subset of a line in
/etc/fstab. - Post
Fetch 🔒State - Root
Mount 🔒Info - Root
Setup 🔒 - Source
Info 🔒 - Global state captured from the container.
- State 🔒
Enums§
Constants§
- ALONGSIDE_
ROOT_ 🔒MOUNT - The default path for the host rootfs
- ARCH_
USES_ 🔒EFI - BOOT 🔒
- The toplevel boot directory
- DEFAULT_
REPO_ 🔒CONFIG - DESTRUCTIVE_
CLEANUP 🔒 - Global flag to signal the booted system was provisioned via an alongside bootc install
- EFIVARFS 🔒
- The mount path for uefi
- EFI_
LOADER_ 🔒INFO - LOST_
AND_ 🔒FOUND - This is an ext4 special directory we need to ignore.
- OSTREE_
COMPOSEFS_ 🔒SUPER - The filename of the composefs EROFS superblock; TODO move this into ostree
- RUN_
BOOTC 🔒 - Directory for transient runtime state
- RW_KARG 🔒
- Kernel argument used to specify we want the rootfs mounted read-write by default
- SELINUXFS 🔒
- The mount path for selinux
Functions§
- check_
disk_ 🔒space - clean_
boot_ 🔒directories - exec_
in_ 🔒host_ mountns - finalize_
filesystem 🔒 - Trim, flush outstanding writes, and freeze/thaw the target mounted filesystem; these steps prepare the filesystem for its first booted use.
- find_
root_ 🔒args_ to_ inherit - Discover how to mount the root filesystem, using existing kernel arguments and information about the root mount.
- initialize_
ostree_ 🔒root - install_
container 🔒 - install_
finalize 🔒 - Implementation of
bootc install finalize. - install_
reset 🔒 - install_
to_ 🔒disk - Implementation of the
bootc install to-diskCLI command. - install_
to_ 🔒existing_ root - install_
to_ 🔒filesystem - Implementation of the
bootc install to-filesystemCLI command. - install_
to_ 🔒filesystem_ impl - install_
with_ 🔒sysroot - Given a baseline root filesystem with an ostree sysroot initialized:
- installation_
complete 🔒 - ostree_
install 🔒 - prepare_
install 🔒 - Preparation for an install; validates and prepares some (thereafter immutable) global state.
- print_
configuration 🔒 - read_
boot_ 🔒fstab_ entry - Read the /boot entry from /etc/fstab, if it exists
- reexecute_
self_ 🔒for_ selinux_ if_ needed - If we detect that the target ostree commit has SELinux labels, and we aren’t passed an override to disable it, then ensure the running process is labeled with install_t so it can write arbitrary labels.
- remove_
all_ 🔒except_ loader_ dirs - remove_
all_ 🔒in_ dir_ no_ xdev - Remove all entries in a directory, but do not traverse across distinct devices. If mount_err is true, then an error is returned if a mount point is found; otherwise it is silently ignored.
- require_
boot_ 🔒uuid - require_
dir_ 🔒contains_ only_ mounts - Require that a directory contains only mount points recursively. Returns Ok(()) if all entries in the directory tree are either:
- require_
empty_ 🔒rootdir - require_
host_ 🔒pidns - A heuristic check that we were invoked with –pid=host
- require_
host_ 🔒userns - Verify that we can access /proc/1, which will catch rootless podman (with –pid=host) for example.
- run_
in_ 🔒host_ mountns - Run a command in the host mount namespace
- setup_
sys_ 🔒mount - By default, podman/docker etc. when passed
--privilegedmount/sysas read-only, but non-recursively. We selectively grab sub-filesystems that we need. - setup_
tmp_ 🔒mount - Ensure that /tmp is a tmpfs because in some cases we might perform operations which expect it (as it is on a proper host system). Ideally we have people run this container via podman run –read-only-tmpfs actually.
- verify_
target_ 🔒fetch - Verify that we can load the manifest of the target image
- warn_
on_ 🔒host_ root