Chapter 5. Customizing disk images of RHEL image mode with advanced partitioning There are 2 options to customize advanced partitions: Disk customizations Filesystem customizations However, the two customizations are incompatible with each other. You cannot use both customizations in the same blueprint. 5.1. Understanding partitions The following are the general principles about partitions: The full disk image size is always larger than the size of the sum of the partitions, due to requirements for headers and metadata. Consequently, all sizes are treated as minimum requirements, whether for specific filesystems, partitions, logical volumes, or the image itself. When the partition is automatically added, the partition that contains the root filesystem is always the last in the partition table layout. This is valid for a plain formatted partition, an LVM Volume Group, or a Btrfs partition. For disk customizations, the order that you defined is respected. For the raw partitioning, that is, with no LVM, the partition containing the root filesystem is grown to fill any leftover space on the partition table. Logical Volumes are not grown to fill the space in the Volume Group because they are simple to grow on a live system. Some directories have hard-coded minimum sizes which cannot be overridden. These are 1 GiB for / and 2 GiB for /usr . As a result, if /usr is not on a separate partition, the root filesystem size is at least 3 GiB. 5.2. The disk customizations option The disk customizations option provides a more powerful interface to control the whole partitioning layout of the image. Allowed mountpoints When using bootc-image-builder , only the following directories allow customization: The / (root) directory. Custom directories under /var , but not /var itself. Not allowed mountpoints Under /var , the following mount points do not allow customization: /var/home /var/lock /var/mail /var/mnt /var/roothome /var/run /var/srv /var/usrlocal 5.3. Describing disk customizations in a blueprint When using the Disk customizations, you can describe the partition table almost entirely by using a blueprint. The customizations have the following structure: Partitions : The top level is a list of partitions. type : Each partition has a type, which can be either plain or lvm . If the type is not set, it defaults to plain . The remaining required and optional properties of the partition depend on the type. plain : A plain partition is a partition with a filesystem. It supports the following properties: fs_type : The filesystem type, which should be one of xfs , ext4 , vfat , or swap . Setting it to swap will create a swap partition. The mountpoint for a swap partition must be empty. minsize : The minimum size of the partition, as an integer (in bytes) or a string with a data unit (for example 3 GiB). The final size of the partition in the image might be larger for specific mountpoints. See Understanding partitions section. mountpoint The mountpoint for the filesystem. For swap partitions, this must be empty. label : The label for the filesystem (optional). lvm : An lvm partition is a partition with an LVM volume group. Only single Persistent Volumes volume groups are supported. It supports the following properties: name : The name of the volume group (optional; if unset, a name will be generated automatically). minsize : The minimum size of the volume group, as an integer (in bytes) or a string with a data unit (for example 3 GiB). The final size of the partition and volume group in the image might be larger if the value is smaller than the sum of logical volumes it contains. logical_volumes : One or more logical volumes for the volume group. Each volume group supports the following properties: name : The name of the logical volume (optional; if unset, a name will be generated automatically based on the mountpoint). minsize : The minimum size of the logical volume, as an integer (in bytes) or a string with a data unit (for example 3 GiB). The final size of the logical volume in the image might be larger for specific mountpoints. See the General principles chapter for more details). label : The label for the filesystem (optional). fs_type : The filesystem type, which should be one of xfs , ext4 , vfat , or swap . Setting it to swap will create a swap logical volume. The mountpoint for a swap logical volume must be empty. mountpoint : The mountpoint for the logical volume's filesystem. For swap logical volumes, this must be empty. Order : The order of each element in a list is respected when creating the partition table. The partitions are created in the order they are defined, regardless of their type. Incomplete partition tables : Incomplete partitioning descriptions are valid. Partitions, LVM logical volumes, are added automatically to create a valid partition table. The following rules are applied: A root filesystem is added if one is not defined. This is identified by the mountpoint / . If an LVM volume group is defined, the root filesystem is created as a logical volume, otherwise it will be created as a plain partition with a filesystem. The type of the filesystem, for plain and LVM, depends on the distribution (xfs for RHEL and CentOS, ext4 for Fedora). See Understanding partitions section for information about the sizing and order of the root partition. A boot partition is created if needed and if one is not defined. This is identified by the mountpoint /boot . A boot partition is needed when the root partition (mountpoint / ) is on an LVM logical volume. It is created as the first partition after the ESP (see item). An EFI system partition (ESP) is created if needed. This is identified by the mountpoint /boot/efi . An ESP is needed when the image is configured to boot with UEFI. This is defined by the image definition and depends on the image type, the distribution, and the architecture. The type of the filesystem is always vfat . By default, the ESP is 200 MiB and is the first partition after the BIOS boot (see item). A 1 MiB unformatted BIOS boot partition is created at the start of the partition table if the image is configured to boot with BIOS. This is defined by the image definition and depends on the image type, the distribution, and the architecture. Both a BIOS boot partition and an ESP are created for images that are configured for hybrid boot. Combining partition types : You can define multiple partitions. The following combination of partition types are valid: plain and lvm : Plain partitions can be created alongside an LVM volume group. However, only one LVM volume group can be defined. Examples: Blueprint to define two partitions The following blueprint defines two partitions. The first is a 50 GiB partition with an ext4 filesystem that will be mounted at /data . The second is an LVM volume group with three logical volumes, one for root / , one for home directories /home , and a swap space in that order. The LVM volume group will have 15 GiB of non-allocated space. 5.4. The filesystem customization option The filesystem customization option provides the final partition table of an image that you built with image builder, and it is determined by a combination of the following factors: The base partition table for a given image type. The relevant blueprint customizations: Partitioning mode. Filesystem customizations. The image size parameter of the build request: On the command line, this is the --size option of the composer-cli compose start command. The following describes how these factors affect the final layout of the partition table. Modifying partition tables You can modify the partition table by taking the following aspects in consideration: Partitioning modes The partitioning mode controls how the partition table is modified from the image type's default layout. The raw partition type does not convert any partition to LVM. The lvm partition type always converts the partition that contains the / root mountpoint to an LVM Volume Group and creates a root Logical Volume. Except from /boot , any extra mountpoint is added to the Volume Group as new Logical Volumes. The auto-lvm mode is the default mode and converts a raw partition table to an LVM-based one if and only if new mountpoints are defined in the filesystems customization. See the Mountpoints entry for more details. Mountpoints You can define new filesystems and minimum partition sizes by using the filesystems customization in the blueprint. By default, if new mountpoints are created, a partition table is automatically converted to LVM. See the Partitioning modes entry for more details. Image size The minimum size of the partition table is the size of the disk image. The final size of the image will either be the value of the size parameter or the sum of all partitions and their associated metadata, depending on which one is the larger. 5.5. Creating images with specific sizes To create a disk image of a very specific size, you must ensure that the following requirements are met: You must specify the exact [Image size] in the build request. The mountpoints that you define as customizations must specify sizes that are smaller than the total size in sum. This is required, because the partition table, partitions, and other entities often require extra space for metadata and headers, so the space required to fit all the mountpoints is always larger than the sum of the size of the partitions. However, the exact size of the extra space that is required varies based on many factors, such as image type, for example. The following are overall steps to create a disk image of a very specific size in the TOML file: Set the [Image size] parameter to the size that you want. Add any extra mountpoints with their required minimum sizes. Ensure that the sum of the sizes is smaller than the image size by at least 3.01 GiB if there is no /usr mountpoint, or at least 1.01 GiB if there is. The extra 0.01 MiB is more than enough for the headers and metadata for which extra space might be reserved. Do not specify a size for the / mountpoint. With this, you create a disk with a partition table of the desired size with each partition sized to fit the desired mountpoints. The root partition, root LVM Logical Volume, will be at least 3 GiB, or 1 GiB if /usr is specified. See Understanding partitions for more details. If the partition table does not have any LVM Volume Groups (VG), the root partition will be grown to fill the remaining space. If the partition table contains an LVM Volume Group (VG), the VG will have unallocated extents that can be used to grow any of the Logical Volumes. 5.6. Building disk images of image-mode RHEL with advanced partitioning Create image mode disk images with advanced partitioning by using bootc-image-builder . The image mode disk images that you create of image mode RHEL with custom mount points, include custom mount options, LVM-based partitions and LVM-based SWAP. With that you can, for example, change the size of the / and the /boot directories by using a config.toml file. When installing the RHEL image mode on bare-metal machines, you can benefit from all partitioning features available on Anaconda. Prerequisites You have Podman installed on your host machine. You have virt-install installed on your host machine. You have root access to run the bootc-image-builder tool, and run the containers in --privileged mode, to build the images. Procedure Create a config.toml to configure custom mount options, for example: Run bootc-image-builder , passing the config.toml as an argument. Note If you do not have the container storage mount and --local image options, your image must be public. You can find your image with the customized advanced partitioning in the output folder. steps Deploy the disk image with advanced partitioning layout. See Deploying your customized images. Additional resources link: Creating an LVM2 logical volume for swap

Commands:
[[customizations.disk.partitions]] type = "plain" label = "data" mountpoint = "/data" fs_type = "ext4" minsize = "50 GiB" [[customizations.disk.partitions]] type = "lvm" name = "mainvg" minsize = "20 GiB" [[customizations.disk.partitions.logical_volumes]] name = "rootlv" mountpoint = "/" label = "root" fs_type = "ext4" minsize = "2 GiB" [[customizations.disk.partitions.logical_volumes]] name = "homelv" mountpoint = "/home" label = "home" fs_type = "ext4" minsize = "2 GiB" [[customizations.disk.partitions.logical_volumes]] name = "swaplv" fs_type = "swap" minsize = "1 GiB"
name = "lvm" description = "A base system with custom LVM partitioning" [customizations.disk] [[customizations.disk.partitions]] mountpoint = "/var/data" minsize = "1 GiB" label = "data" fs_type = "ext4" [[customizations.disk.partitions]] mountpoint = "/" minsize = "2 GiB" label = "root" fs_type = "ext4"
sudo podman run --rm -it --privileged --pull=newer --security-opt label=type:unconfined_t -v ./config.toml:/config.toml -v ./output:/output registry.redhat.io/rhel9/bootc-image-builder:latest --type <image_type> --config config.toml quay.io/ <namespace> / <image> : <tag>