# bootc Technical Installation Guide ## Overview This document provides a comprehensive technical explanation of how bootc installs container images as bootable operating systems. bootc bridges the gap between OCI/Docker container images and bootable host systems by providing installation mechanisms that create traditional Linux boot environments from container images. ## Architecture Overview bootc operates in two distinct modes: 1. **Container Mode**: When run inside a container (during build), behaves like any other container 2. **Host Mode**: When installed to a physical/virtual machine, becomes the bootable OS The installation process transforms a container image into a bootable system with: - Bootloader configuration - Kernel and initramfs setup - Root filesystem deployment - OSTree repository initialization ## Installation Commands ### Primary Installation Commands 1. **`bootc install to-disk`** - Direct installation to a block device 2. **`bootc install to-filesystem`** - Installation to an existing mounted filesystem 3. **`bootc install to-existing-root`** - Convert existing Linux system to bootc 4. **`bootc install finalize`** - Post-installation finalization ### Command Structure ```bash bootc install [COMMAND] [OPTIONS] [TARGET] ``` ## Technical Installation Process ### Phase 1: Preparation and Validation #### 1.1 Container Environment Detection ```rust // From install.rs:519-538 pub(crate) fn from_container( root: &Dir, container_info: &ContainerExecutionInfo, ) -> Result { if !container_info.engine.starts_with("podman") { anyhow::bail!("Currently this command only supports being executed via podman"); } // ... validation logic } ``` **External Commands Required:** - `podman` - Container runtime (required) - `ostree` - OSTree repository management - `bootupd` - Bootloader management #### 1.2 Privilege and Namespace Validation ```rust // From install.rs:1061-1082 fn require_host_pidns() -> Result<()> { if rustix::process::getpid().is_init() { anyhow::bail!("This command must be run with the podman --pid=host flag") } Ok(()) } ``` **Required Container Flags:** - `--privileged` - Full host access - `--pid=host` - Host process namespace - `--security-opt label=type:unconfined_t` - SELinux bypass #### 1.3 SELinux State Management ```rust // From install.rs:1001-1029 pub(crate) fn reexecute_self_for_selinux_if_needed( srcdata: &SourceInfo, override_disable_selinux: bool, ) -> Result { // SELinux policy detection and re-execution logic } ``` ### Phase 2: Filesystem Setup #### 2.1 OSTree Repository Initialization ```rust // From install.rs:591-694 async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result<(Storage, bool)> { let has_ostree = rootfs_dir.try_exists("ostree/repo")?; if !has_ostree { Task::new("Initializing ostree layout", "ostree") .args(["admin", "init-fs", "--modern", "."]) .cwd(rootfs_dir)? .run()?; } // ... repository configuration } ``` **External Commands:** - `ostree admin init-fs --modern` - Initialize OSTree filesystem - `ostree config set` - Configure repository settings #### 2.2 Container Image Deployment ```rust // From install.rs:718-892 async fn install_container( state: &State, root_setup: &RootSetup, sysroot: &ostree::Sysroot, has_ostree: bool, ) -> Result<(ostree::Deployment, InstallAleph)> { // Pull container image into OSTree repository let pulled_image = match prepare_for_pull(repo, &spec_imgref, Some(&state.target_imgref)).await? { PreparedPullResult::AlreadyPresent(existing) => existing, PreparedPullResult::Ready(image_meta) => { check_disk_space(root_setup.physical_root.as_fd(), &image_meta, &spec_imgref)?; pull_from_prepared(&spec_imgref, false, ProgressWriter::default(), *image_meta).await? } }; // ... deployment logic } ``` ### Phase 3: Bootloader Installation #### 3.1 Bootupd Integration ```rust // From install.rs:1337-1343 crate::bootloader::install_via_bootupd( &rootfs.device_info, &rootfs.physical_root_path, &state.config_opts, &deployment_path.as_str(), )?; ``` **External Commands:** - `bootupctl install` - Install bootloader - `bootupctl generate` - Generate bootloader configuration #### 3.2 Architecture-Specific Bootloaders - **x86_64/aarch64**: GRUB2 via bootupd - **s390x**: zipl (IBM Z) - **Other**: Platform-specific implementations ### Phase 4: Kernel and Initramfs Setup #### 4.1 Kernel Argument Processing ```rust // From install.rs:773-825 let kargsd = crate::bootc_kargs::get_kargs_from_ostree_root( &sysroot.repo(), merged_ostree_root.downcast_ref().unwrap(), std::env::consts::ARCH, )?; ``` **Kernel Arguments Sources (in order):** 1. Root filesystem kargs 2. Install configuration kargs 3. Container image kargs.d files 4. CLI-specified kargs #### 4.2 Initramfs Integration - Kernel location: `/usr/lib/modules/$kver/vmlinuz` - Initramfs location: `/usr/lib/modules/$kver/initramfs.img` - Generated by dracut during container build ### Phase 5: Filesystem Finalization #### 5.1 Filesystem Optimization ```rust // From install.rs:1033-1058 pub(crate) fn finalize_filesystem( fsname: &str, root: &Dir, path: impl AsRef, ) -> Result<()> { // fstrim - optimize filesystem Task::new(format!("Trimming {fsname}"), "fstrim") .args(["--quiet-unsupported", "-v", path.as_str()]) .cwd(root)? .run()?; // Remount read-only Task::new(format!("Finalizing filesystem {fsname}"), "mount") .cwd(root)? .args(["-o", "remount,ro", path.as_str()]) .run()?; // Freeze/thaw for journal flush for a in ["-f", "-u"] { Command::new("fsfreeze") .cwd_dir(root.try_clone()?) .args([a, path.as_str()]) .run_capture_stderr()?; } } ``` **External Commands:** - `fstrim` - Trim filesystem for optimization - `mount -o remount,ro` - Remount read-only - `fsfreeze` - Freeze/thaw for journal flush ## Installation Modes ### 1. to-disk Installation **Process Flow:** 1. Create filesystem on target device 2. Mount target device 3. Deploy container image to mounted filesystem 4. Install bootloader 5. Unmount and finalize **External Commands:** ```bash mkfs.$filesystem_type /dev/target mount /dev/target /mnt bootc install to-filesystem --karg=root=UUID= /mnt umount /mnt ``` ### 2. to-filesystem Installation **Process Flow:** 1. Validate target filesystem 2. Initialize OSTree repository 3. Deploy container image 4. Configure bootloader 5. Finalize filesystem **Use Cases:** - Integration with external installers (Anaconda) - Custom partitioning schemes - Cloud image generation ### 3. to-existing-root Installation **Process Flow:** 1. Mount host root filesystem 2. Clean boot directories 3. Deploy alongside existing system 4. Configure bootloader 5. Set up cleanup service **Special Considerations:** - Preserves existing data in `/sysroot` - Requires `--acknowledge-destructive` flag - Sets up cleanup service for first boot ## External Dependencies ### Required System Commands | Command | Purpose | Package | |---------|---------|---------| | `ostree` | OSTree repository management | ostree | | `bootupd` | Bootloader management | bootupd | | `podman` | Container runtime | podman | | `fstrim` | Filesystem optimization | util-linux | | `mount` | Filesystem mounting | util-linux | | `umount` | Filesystem unmounting | util-linux | | `fsfreeze` | Filesystem freeze/thaw | util-linux | ### Optional Commands | Command | Purpose | Package | |---------|---------|---------| | `cryptsetup` | LUKS encryption | cryptsetup | | `grub2-mkconfig` | GRUB configuration | grub2-tools | | `dracut` | Initramfs generation | dracut | ## Configuration Files ### 1. Install Configuration Location: `/usr/lib/bootc/install/*.toml` ```toml [install.filesystem.root] type = "xfs" [install.filesystem.boot] type = "ext4" ``` ### 2. Kernel Arguments Location: `/usr/lib/bootc/kargs.d/*.toml` ```toml [kargs] append = ["console=ttyS0", "quiet"] prepend = ["rd.luks.uuid=12345678-1234-1234-1234-123456789abc"] ``` ### 3. OSTree Configuration Location: `ostree/repo/config` ```ini [core] repo_version=1 mode=bare [sysroot] bootloader=none bootprefix=true readonly=true ``` ## Security Considerations ### 1. SELinux Integration - Automatic policy detection - Re-execution for proper labeling - Target system SELinux configuration ### 2. Container Security - Requires privileged container execution - Host mount namespace access - Device access for installation ### 3. Filesystem Security - Atomic operations where possible - Proper file permissions - SELinux labeling ## Error Handling and Recovery ### 1. Disk Space Validation ```rust // From install.rs:696-715 fn check_disk_space( repo_fd: impl AsFd, image_meta: &PreparedImportMeta, imgref: &ImageReference, ) -> Result<()> { let stat = rustix::fs::fstatvfs(repo_fd)?; let bytes_avail: u64 = stat.f_bsize * stat.f_bavail; if image_meta.bytes_to_fetch > bytes_avail { anyhow::bail!( "Insufficient free space for {image} (available: {bytes_avail} required: {bytes_to_fetch})", // ... error details ); } } ``` ### 2. Rollback Capability - OSTree provides atomic rollback - Bootloader configuration backup - Deployment state tracking ### 3. Validation Steps - Container image integrity - Filesystem compatibility - Bootloader support - Kernel compatibility ## Performance Considerations ### 1. Parallel Operations - Container image pulling - Filesystem operations - Bootloader installation ### 2. Disk I/O Optimization - OSTree repository configuration - Filesystem trimming - Write optimization ### 3. Memory Usage - Container image caching - OSTree repository management - Temporary file handling ## Debugging and Troubleshooting ### 1. Logging - Structured logging with tracing - Journal integration - Progress reporting ### 2. Common Issues - Insufficient disk space - SELinux policy conflicts - Bootloader installation failures - Container image access issues ### 3. Debug Commands ```bash # Check OSTree repository ostree admin status # Verify bootloader bootupctl status # Check container image podman images # Validate filesystem lsblk -f ``` ## Future Enhancements ### 1. Planned Features - Dynamic ConfigMap injection - Enhanced rollback mechanisms - Multi-architecture support - Cloud integration improvements ### 2. API Evolution - Stable CLI interface - REST API for management - Configuration management - Monitoring integration --- This technical guide provides the foundation for understanding bootc's installation process. The system is designed to be robust, secure, and maintainable while providing the flexibility needed for various deployment scenarios.