1"use strict";(self.webpackChunksaurus=self.webpackChunksaurus||[]).push([[11563],{81023:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"developer-guide/projects/image-builder/advanced/bootc/sources-of-configuration","title":"Sources of Configuration","description":"\x3c!--","source":"@site/docs/developer-guide/02-projects/image-builder/20-advanced/20-bootc/05-sources-of-configuration.md","sourceDirName":"developer-guide/02-projects/image-builder/20-advanced/20-bootc","slug":"/developer-guide/projects/image-builder/advanced/bootc/sources-of-configuration","permalink":"/docs/developer-guide/projects/image-builder/advanced/bootc/sources-of-configuration","draft":false,"unlisted":false,"editUrl":"https://github.com/osbuild/image-builder/blob/main/doc/20-advanced/20-bootc/05-sources-of-configuration.md","tags":[],"version":"current","sidebarPosition":5,"frontMatter":{"custom_edit_url":"https://github.com/osbuild/image-builder/blob/main/doc/20-advanced/20-bootc/05-sources-of-configuration.md"},"sidebar":"developer","previous":{"title":"Advanced bootc Topics","permalink":"/docs/developer-guide/projects/image-builder/advanced/bootc/"},"next":{"title":"ISOs","permalink":"/docs/developer-guide/projects/image-builder/advanced/bootc/isos"}}');var s=i(74848),o=i(28453);const a={custom_edit_url:"https://github.com/osbuild/image-builder/blob/main/doc/20-advanced/20-bootc/05-sources-of-configuration.md"},r="Sources of Configuration",l={},d=[{value:"<code>bootc print-config</code>",id:"bootc-print-config",level:2},{value:"Filesystem",id:"filesystem",level:2},{value:"<code>disk.yaml</code>",id:"diskyaml",level:3},{value:"Partitions",id:"partitions",level:4},{value:"Payloads",id:"payloads",level:5},{value:"Filesystem",id:"filesystem-1",level:6},{value:"LVM",id:"lvm",level:6},{value:"btrfs",id:"btrfs",level:6},{value:"LUKS",id:"luks",level:6},{value:"Deployment Variants",id:"deployment-variants",level:3},{value:"<code>iso.yaml</code>",id:"isoyaml",level:3},{value:"<code>extras.yaml</code>",id:"extrasyaml",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"sources-of-configuration",children:"Sources of Configuration"})}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.code,{children:"bootc"}),"-land it is preferred for the source of truth to be the container itself. For ",(0,s.jsx)(n.code,{children:"image-builder"})," that means that certain instructions can be stored inside the container and will be used by ",(0,s.jsx)(n.code,{children:"image-builder"})," when present. We get various bits and bobs from different places . This page describes what we get from where."]}),"\n",(0,s.jsx)(n.h2,{id:"bootc-print-config",children:(0,s.jsx)(n.code,{children:"bootc print-config"})}),"\n",(0,s.jsx)(n.h2,{id:"filesystem",children:"Filesystem"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"image-builder"})," will use several files with different purposes from the container filesystem if they exist. These files are expected to exist in the ",(0,s.jsx)(n.code,{children:"/usr/lib/image-builder/bootc"})," directory."]}),"\n",(0,s.jsxs)(n.p,{children:["For historical reasons ",(0,s.jsx)(n.code,{children:"image-builder"})," will also see if these files exist in the ",(0,s.jsx)(n.code,{children:"/usr/lib/bootc-image-builder"})," directory. The ",(0,s.jsx)(n.code,{children:"/usr/lib/image-builder/bootc"})," directory has preference and any containers using the ",(0,s.jsx)(n.code,{children:"/usr/lib/bootc-image-builder"})," path should be changed to use ",(0,s.jsx)(n.code,{children:"/usr/lib/image-builder/bootc"})," instead."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["The prefix is resolved once, not per file. If the ",(0,s.jsx)(n.code,{children:"/usr/lib/image-builder/bootc"})," directory exists, all files are read from there and the old ",(0,s.jsx)(n.code,{children:"/u
1sr/lib/bootc-image-builder"})," directory is never consulted. There is no per-file fallback between the two prefixes. If you have a mix of files across both directories, move everything to ",(0,s.jsx)(n.code,{children:"/usr/lib/image-builder/bootc"}),"."]})}),"\n",(0,s.jsx)(n.h3,{id:"diskyaml",children:(0,s.jsx)(n.code,{children:"disk.yaml"})}),"\n",(0,s.jsxs)(n.p,{children:["A YAML file containing the partition layout to use when turning the container image into a disk image. The canonical location for this file is ",(0,s.jsx)(n.code,{children:"/usr/lib/image-builder/bootc/disk.yaml"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If present this will replace the base partition tables that ",(0,s.jsx)(n.code,{children:"image-builder"})," uses during build. Blueprint customizations can be applied on top by end-users that want to modify their deployments."]}),"\n",(0,s.jsx)(n.p,{children:"A quick example that sets up a very default partition layout (BIOS boot, ESP, XBOOTLDR, and root partition) before explanation and more complex examples."}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["The BIOS boot partition is currently required by ",(0,s.jsx)(n.code,{children:"bootupd"}),", hence we've included it here in every example. This might change in the future and be dependent on the container itself; see ",(0,s.jsx)(n.a,{href:"https://github.com/coreos/bootupd/issues/1067",children:"this issue"}),"."]})})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'mount_configuration: "units"\npartition_table:\n type: "gpt"\n partitions:\n - size: "1 MiB"\n type: "21686148-6449-6e6F-744e-656564454649"\n bootable: true\n - size: "200 MiB"\n type: "c12a7328-f81f-11d2-ba4b-00a0c93ec93b"\n payload_type: "filesystem"\n payload:\n type: "vfat"\n mountpoint: "/boot/efi"\n label: "ESP"\n fstab_options: "defaults,uid=0,gid=0,umask=077,shortname=winnt"\n fstab_freq: 0\n fstab_passno: 2\n - size: "2 GiB"\n type: "bc13c2ff-59e6-4262-a352-b275fd6f7172"\n payload_type: "filesystem"\n payload:\n type: "ext4"\n label: "boot"\n mountpoint: "/boot"\n fstab_options: "defaults"\n fstab_freq: 0\n fstab_passno: 0\n - size: "4 GiB"\n type: "44479540-f297-41b2-9af7-d131d5f0458a"\n payload_type: "filesystem"\n payload:\n type: "ext4"\n label: "root"\n mountpoint: "/"\n fstab_options: "defaults"\n fstab_freq: 0\n fstab_passno: 0\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["The type UUIDs used in this example come from the ",(0,s.jsx)(n.a,{href:"https://uapi-group.org/specifications/specs/discoverable_partitions_specification/",children:"Discoverable Partitions Specification"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"mount_configuration"})," is an enum and can hold the values ",(0,s.jsx)(n.code,{children:"fstab"}),", ",(0,s.jsx)(n.code,{children:"units"}),", or ",(0,s.jsx)(n.code,{children:"none"}),". It dictates how the mountpoints are configured in the disk image. ",(0,s.jsx)(n.code,{children:"fstab"})," will write an ",(0,s.jsx)(n.code,{children:"/etc/fstab"}),", ",(0,s.jsx)(n.code,{children:"units"})," will write systemd mount unit files, and ",(0,s.jsx)(n.code,{children:"none"})," will do neither; leaving it up to tooling such as ",(0,s.jsx)(n.code,{children:"systemd-gpt-auto-generator"})," to figure out what to mount where."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"partition_table"})," is an object with the following properties:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"type"}),", an ",(0,s.jsx)(n.code,{children:"enum"})," that can be ",(0,s.jsx)(n.code,{children:"gpt"})," or ",(0,s.jsx)(n.code,{children:"dos"})," and sets the partition table format to use."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"partitions"}),", a list of objects each of which represents a partition."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"size"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," string with units to set the overall disk size (e.g. ",(0,s.jsx)(n.code,{children:'"10 GiB"'}),"). If omitted the disk will be sized to fit all partitions."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"policy"}),", an ",(0,s.jsx)(n.em,{children:"optional"}
1)," object containing partition table policy options:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"grow_root_to_fill_disk"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," boolean (defaults to ",(0,s.jsx)(n.code,{children:"true"}),"). When ",(0,s.jsx)(n.code,{children:"true"})," (or omitted), the partition containing the root filesystem (",(0,s.jsx)(n.code,{children:"/"}),") is automatically grown to fill any remaining disk space. Set to ",(0,s.jsx)(n.code,{children:"false"})," to keep the root partition at its specified size, leaving unallocated space on the disk. This is useful when the image is expected to be grown at first boot (e.g. via ",(0,s.jsx)(n.code,{children:"cloud-utils-growpart"}),") or when you want a compact disk image."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Here's an example using ",(0,s.jsx)(n.code,{children:"grow_root_to_fill_disk: false"})," to produce a 10 GiB disk where the root partition stays at 4 GiB, leaving the remaining space unallocated:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'mount_configuration: "units"\npartition_table:\n type: "gpt"\n size: "10 GiB"\n policy:\n grow_root_to_fill_disk: false\n partitions:\n - size: "1 MiB"\n type: "21686148-6449-6e6F-744e-656564454649"\n bootable: true\n - size: "200 MiB"\n type: "c12a7328-f81f-11d2-ba4b-00a0c93ec93b"\n payload_type: "filesystem"\n payload:\n type: "vfat"\n mountpoint: "/boot/efi"\n label: "ESP"\n fstab_options: "defaults,uid=0,gid=0,umask=077,shortname=winnt"\n fstab_freq: 0\n fstab_passno: 2\n - size: "4 GiB"\n type: "0fc63daf-8483-4772-8e79-3d69d8477de4"\n payload_type: "filesystem"\n payload:\n type: "ext4"\n label: "root"\n mountpoint: "/"\n fstab_options: "defaults"\n fstab_freq: 0\n fstab_passno: 0\n'})}),"\n",(0,s.jsx)(n.h4,{id:"partitions",children:"Partitions"}),"\n",(0,s.jsx)(n.p,{children:"Each partition can have the following properties:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"size"}),", a string with units to set the size of the partition."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"type"}),", the partition type GPT UUID ",(0,s.jsx)(n.em,{children:"or"})," DOS ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bootable"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," boolean indicating that this partition is legacy BIOS bootable (GPT) or active (DOS)."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"uuid"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," string containing the partition UUID itself. Should be omitted and will be based on a PRNG, fixing this value can lead to issues trying to mount the same disk multiple times."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"label"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," ",(0,s.jsx)(n.code,{children:"string"})," containing the partition name (",(0,s.jsx)(n.strong,{children:"not"})," the filesystem label) for GPT."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"attrs"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," array of unsigned integers that set partition attribute flags for GPT."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"payload_type"}),", an ",(0,s.jsx)(n.code,{children:"enum"})," that contains one ",(0,s.jsx)(n.code,{children:"filesystem"}),", ",(0,s.jsx)(n.code,{children:"luks"}),", ",(0,s.jsx)(n.code,{children:"lvm"}),", ",(0,s.jsx)(n.code,{children:"btrfs"}),", ",(0,s.jsx)(n.code,{children:"raw"}),". This field dictates what goes into the ",(0,s.jsx)(n.code,{children:"payload"})," object that comes next."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"payload"}),", an object based on the value of ",(0,s.jsx)(n.code,{children:"payload_type"}),". ",(0,s.jsx)(n.code,{children:"payload_type"}),"s and their ",(0,s.jsx)(n.code,{children:"payload"})," contents are explained below."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h5,{id:"payloads",children:"Payloads"}),"\n",(0,s.jsx)(n.h6,{id:"filesystem-1",children:"Filesystem"}),"\n",(0,s.jsxs)(n.p,{children:["For a ",(0,s.jsx)(n.code,{children:"payload_type: filesystem"})," the ",(0,s.jsx)(n.code,{children:"payload"})," has the following properties:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"type"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"mountpoint"}),", a ",(0,s.jsx)(n.code,{children:"string"}
1)," that tells where this partition should be mounted."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"label"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," ",(0,s.jsx)(n.code,{children:"string"})," that contains the filesystem label."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"fstab_options"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"fstab_freq"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"fstab_passno"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"mkfs_options"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," object containing filesystem-specific mkfs options. Currently supported properties:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"verity"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," ",(0,s.jsx)(n.code,{children:"boolean"})," to enable fs-verity (ext4 only)."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"geometry"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," object for drive geometry (vfat only), with the following properties:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"heads"}),", an ",(0,s.jsx)(n.code,{children:"integer"})," setting the number of heads."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"sectors_per_track"}),", an ",(0,s.jsx)(n.code,{children:"integer"})," setting the number of sectors per track."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"agcount"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," ",(0,s.jsx)(n.code,{children:"integer"})," setting the number of allocation groups (xfs only)."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Here's an example defining a few partition with XFS filesystem(s):"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'mount_configuration: "units"\npartition_table:\n type: "gpt"\n partitions:\n - size: "1 MiB"\n type: "21686148-6449-6e6F-744e-656564454649"\n bootable: true\n - size: "200 MiB"\n type: "c12a7328-f81f-11d2-ba4b-00a0c93ec93b"\n payload_type: "filesystem"\n payload:\n type: "vfat"\n mountpoint: "/boot/efi"\n label: "ESP"\n fstab_options: "defaults,uid=0,gid=0,umask=077,shortname=winnt"\n fstab_freq: 0\n fstab_passno: 2\n - size: "2 GiB"\n type: "bc13c2ff-59e6-4262-a352-b275fd6f7172"\n payload_type: "filesystem"\n payload:\n type: "xfs"\n label: "boot"\n mountpoint: "/boot"\n - payload_type: "filesystem"\n payload:\n type: "xfs"\n label: "root"\n mountpoint: "/"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["To pass custom mkfs options, use the ",(0,s.jsx)(n.code,{children:"mkfs_options"})," field. For example, to set the XFS allocation group count:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:' - payload_type: "filesystem"\n payload:\n type: "xfs"\n label: "root"\n mountpoint: "/"\n mkfs_options:\n agcount: 4\n'})}),"\n",(0,s.jsx)(n.p,{children:"Or to set custom drive geometry on a vfat partition:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:' - payload_type: "filesystem"\n payload:\n type: "vfat"\n mountpoint: "/boot/efi"\n label: "ESP"\n mkfs_options:\n geometry:\n heads: 64\n sectors_per_track: 32\n'})}),"\n",(0,s.jsx)(n.h6,{id:"lvm",children:"LVM"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["LVM configurations currently do not work with bootable containers in ",(0,s.jsx)(n.code,{children:"image-builder"}),". See ",(0,s.jsx)(n.a,{href:"https://github.com/osbuild/images/issues/2228",children:"here"}),"."]})})}),"\n",(0,s.jsx)(n.h6,{id:"btrfs",children:"btrfs"}),"\n",(0,s.jsxs)(n.p,{children:["For a ",(0,s.jsx)(n.code,{children:"payload_type: btrfs"})," the ",(0,s.jsx)(n.code,{children:"payload"})," has the following properties:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"subvolumes"}),", a list of objects."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"subvolumes"})," objects have the following properties:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"name"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"mountpoint"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["An example of using the ",(0,s.jsx)(n.code,{children:"btrfs"})," payload:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'mount_configuration: "units"\npartition_table:\n type: "gpt"\n partitions:\n - size: "1 MiB"\n bootable: true\n type: "21686148-6449-6e6F-744e-656564454649"\n - size: "200 MiB"\n type: "c12a7328-f81f-11d2-ba4b-00a0c93ec93b"\n payload_type: "filesystem"\n payload:\n type: "vfat"\n mountpoint: "/boot/efi"\n label: "ESP"\n fstab_options: "defaults,uid=0,gid=0,umask=077,shortname=winnt"\n fstab_freq: 0\n fstab_passno: 2\n - size: "2 GiB"\n type: "bc13c2ff-59e6-4262-a352-b275fd6f7172"\n payload_type: "filesystem"\n payload:\n type: "ext4"\n label: "boot"\n mountpoint: "/boot"\n fstab_options: "defaults"\n fstab_freq: 0\n fstab_passno: 0\n - size: "4 GiB"\n type: "44479540-f297-41b2-9af7-d131d5f0458a"\n payload_type: "btrfs"\n payload:\n subvolumes:\n - name: "root"\n mountpoint: "/"\n - name: "home"\n mountpoint: "/home"\n - name: "var"\n mountpoint: "/var"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["To use ",(0,s.jsx)(n.code,{children:"btrfs"})," your container must set its configured root filesystem to ",(0,s.jsx)(n.code,{children:"btrfs"}),", or it must be passed when ",(0,s.jsx)(n.code,{children:"image-builder"})," is called."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["To use ",(0,s.jsx)(n.code,{children:"btrfs"})," your build host and container kernel must support ",(0,s.jsx)(n.code,{children:"btrfs"}),"."]})}),"\n",(0,s.jsx)(n.h6,{id:"luks",children:"LUKS"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["LUKS configurations currently do not work with bootable containers in ",(0,s.jsx)(n.code,{children:"image-builder"}),". See ",(0,s.jsx)(n.a,{href:"https://github.com/osbuild/images/issues/2228",children:"here"}),"."]})})}),"\n",(0,s.jsx)(n.h3,{id:"deployment-variants",children:"Deployment Variants"}),"\n",(0,s.jsxs)(n.p,{children:["Containers can ship multiple ",(0,s.jsx)(n.code,{children:"disk.yaml"}),", ",(0,s.jsx)(n.code,{children:"iso.yaml"}),", and/or ",(0,s.jsx)(n.code,{children:"extras.yaml"})," configurations as ",(0,s.jsx)(n.em,{children:"deployment variants"}),". Variants allow a single container image to produce different disk layouts depen
1ding on the target environment, for example a ",(0,s.jsx)(n.code,{children:"secure-execution"})," variant with verity partitions for s390x, or ",(0,s.jsx)(n.code,{children:"btrfs"})," vs ",(0,s.jsx)(n.code,{children:"ext4"})," variants for Fedora images."]}),"\n",(0,s.jsxs)(n.p,{children:["Variants are placed in the ",(0,s.jsx)(n.code,{children:"variant.d/"})," subdirectory, with each variant in its own named directory:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"/usr/lib/image-builder/bootc/\n\u251c\u2500\u2500 disk.yaml # default configuration\n\u251c\u2500\u2500 iso.yaml # default ISO configuration\n\u251c\u2500\u2500 extras.yaml # default extras configuration\n\u2514\u2500\u2500 variant.d/\n \u251c\u2500\u2500 btrfs/\n \u2502 \u251c\u2500\u2500 disk.yaml # btrfs partition layout\n \u2502 \u2514\u2500\u2500 extras.yaml # btrfs-specific extras\n \u2514\u2500\u2500 secure-execution/\n \u2514\u2500\u2500 disk.yaml # s390x SE partition layout\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Each variant directory may contain a ",(0,s.jsx)(n.code,{children:"disk.yaml"}),", ",(0,s.jsx)(n.code,{children:"iso.yaml"}),", and/or ",(0,s.jsx)(n.code,{children:"extras.yaml"}),". When a variant is selected at build time with ",(0,s.jsx)(n.code,{children:"--bootc-variant"}),", ",(0,s.jsx)(n.code,{children:"image-builder"})," uses the variant's configuration files. For any file not provided by the variant, ",(0,s.jsx)(n.code,{children:"image-builder"})," falls back to the default configuration."]}),"\n",(0,s.jsx)(n.p,{children:"Users can list available variants and select one at build time:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",children:"$ image-builder bootc variants --ref quay.io/fedora/fedora-bootc:latest\nbtrfs\nplain\n$ sudo image-builder build --bootc-ref quay.io/fedora/fedora-bootc:latest --bootc-variant btrfs qcow2\n# ...\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Container publishers can use ",(0,s.jsx)(n.code,{children:"$TARGETARCH"})," or other Containerfile logic to include different variants for different architectures."]}),"\n",(0,s.jsx)(n.h3,{id:"isoyaml",children:(0,s.jsx)(n.code,{children:"iso.yaml"})}),"\n",(0,s.jsxs)(n.p,{children:["A YAML file containing instructions for constructing an ISO. This YAML file is only used for the ",(0,s.jsx)(n.code,{children:"bootc-generic-iso"})," image type which makes as few assumptions as possible and thus needs extra instructions to tell it what to do. Read ",(0,s.jsxs)(n.a,{href:"/docs/developer-guide/projects/image-builder/advanced/bootc/isos",children:["more about the ",(0,s.jsx)(n.code,{children:"bootc-generic-iso"})]})," to see what you can do with this file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'label: "Fedora-bootc-Installer"\ngrub2:\n entries:\n - name: "Install Fedora (bootc)"\n linux: "/images/pxeboot/vmlinuz inst.stage2=hd:LABEL=Fedora-bootc-Installer console=tty0 inst.text selinux=0"\n initrd: "/images/pxeboot/initrd.img"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"extrasyaml",children:(0,s.jsx)(n.code,{children:"extras.yaml"})}),"\n",(0,s.jsxs)(n.p,{children:['A YAML file that declares additional build artifacts ("extras") that ',(0,s.jsx)(n.code,{children:"image-builder"})," can produce alongside the main disk image. Currently only partition extras are supported, which extract individual partitions from the built disk image as separate files."]}),"\n",(0,s.jsxs)(n.p,{children:["The canonical location for this file is ",(0,s.jsx)(n.code,{children:"/usr/lib/image-builder/bootc/extras.yaml"}),". Like ",(0,s.jsx)(n.code,{children:"disk.yaml"})," and ",(0,s.jsx)(n.code,{children:"iso.yaml"}),", this file supports ",(0,s.jsx)(n.a,{href:"#deployment-variants",children:"deployment variant"})," overrides via ",(0,s.jsx)(n.code,{children:"variant.d/<name>/extras.yaml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"partitions:\n boot:\n mountpoint: /boot\n filename: boot.img\n compression: xz\n data:\n mountpoint: /var/data\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"partitions"})," is a map where each key is the name of the extra and each value is an object with the following properties:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"mountpoint"}),", a ",(0,s.jsx)(n.code,{children:"string"})," identifying which partition to extract from the disk image. This must match a mountpoint defined in the partition table (either from ",(0,s.jsx)(n.code,{children:"disk.yaml"})," or the base partition table). For mountpoints inside container types (Btrfs, LVM, LUKS, etc.) the entire enclosing partition is exported rather than just the individual mountpoint."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"filename"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," ",(0,s.jsx)(n.code,{children:"string"})," to override the output filename. If omitted, the file is named ",(0,s.jsx)(n.code,{children:"<name>.raw"})," (or ",(0,s.jsx)(n.code,{children:"<name>.raw.<ext>"})," when compressed)."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"compression"}),", an ",(0,s.jsx)(n.em,{children:"optional"})," ",(0,s.jsx)(n.code,{children:"string"})," specifying the compression format to apply to the extracted partition (e.g. ",(0,s.jsx)(n.code,{children:"xz"}),", ",(0,s.jsx)(n.code,{children:"zstd"}),")."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Extras defined in this file are visible in ",(0,s.jsx)(n.code,{children:"image-builder bootc inspect"})," output and can be included in a build with ",(0,s.jsx)(n.code,{children:"--with-extra"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"image-builder build --type qcow2 --with-extra partition:boot ...\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>r});var t=i(96540);const s={},o=t.createContext(s);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.