Configuration
Katsu images are defined using "Manifests".
A manifest is a modular YAML file that defines the content inside the image, and scripts to run when the image is built.
A manifest is made up of a number of sections, each of which is optional. However, though some sections should only be defined by a manifest that will be used as an entrypoint so the image can be functional.
Sections
builder
The builder
section defines the builder module that will be used to build the image. Currently this supports dnf
and bootc
The bootc builder is only supported in Katsu 0.10.0 and later. The DNF builder is the default and is used if this section is not defined.
builder: dnf # or bootc
distro
This section defines the product name of the image. It is used for ISO images to name the boot entry.
distro: Fedora 39
scripts
This section defines the scripts that will be run before and after the image is built.
They have two sub-sections, pre
and post
, which define the scripts to run before and after the image is built.
Both of these has the same format described below.
The contents in the subsections are defined as arrays.
scripts:
pre:
- inline: |
#!/bin/bash
echo "Hello World"
id: hello-world
name: Hello World
- file: ./hello-world.sh
id: hello-world-file
scripts.*.[].inline
A string containing the script to run, can be replaced with file
(optional)
scripts.*.[].file
A path to a file containing the script to run, can be replaced with inline
(optional)
scripts.*.[].id
A unique identifier for the script, used for dependency trees, similar to how Ansible works (optional)
scripts.*.[].needs
A list of script IDs that must be run before this script (optional)
scripts.*.[].name
A name for the script, used for logging (optional)
scripts.*.[].chroot
Whether to run the script in a sandboxed chroot environment (optional)
By default, this value will be assumed true. If set to false, the script will be run in the host environment.
The $CHROOT
environment variable will be exported for use in the script.
Files should be placed in the same directory as the manifest file that loads it.
So if the manifest that loads hello-world-file
is in modules/hello.yaml
, the file should be in modules/hello-world.sh
The best practice is to create a separate folder for each module, and place the required files in that folder.
bootc
This section configures how Katsu will build the image based on bootc.
bootc:
image: ghcr.io/you/your-image:latest
derivation: /path/to/Containerfile
context: . # OCI build context for copying files from outside the container (optional)
embed_image: true # This is set to true by default, injects the original image into the final image's Podman storage
bootc (opens in a new tab) is an image-based paradigm for transactional OS updates, based on OCI (opens in a new tab) images.
You can build an entire OS image and pack them into a Docker/OCI image, which can then be deployed into a bootable image, and updated the same way you
would pull a Docker image.
The bootc
section is used to configure how Katsu will build the image based on bootc.
bootc.image
The base image tag to use for this build. This image must be a bootc-compatible image.
bootc.derivation
The path to the Containerfile
that will be used to build a special derivation made just for this build,
Relative to the current working directory.
Katsu calls podman build
with the extra build argument DERIVE_FROM
with the value of the base image (bootc.image
), this can be used to dynamically
specify the base image in the Containerfile
.
An example Containerfile to be consumed by Katsu bootc mode would look like this:
ARG DERIVE_FROM
FROM $DERIVE_FROM
# Touch grass
RUN touch /grass
# You can do whatever you want here, as you would a normal Docker layer image
# This will be the final image Katsu will export as the root filesystem
This image will be tagged with the name of the base image, with the :katsu_deriv
tag instead of whatever tag the base image has.
This is done to prevent the image from being overwritten by the base image, and to allow Podman to cache this build for later use.
bootc.context
The OCI build context for copying files from outside the container. This is the same as the --context
(or the standard positional) argument to podman build
.
This is useful for copying files from the host into the container, such as scripts or files that are needed for the build.
bootc.embed_image
Whether to embed the original image into the final image's Podman storage. This is set to true
by default.
This is useful for creating self-installing images, as the original image will be embedded into the final image's Podman storage.
The image that will be embedded is the one specified in bootc.image
, and will be used as the base image for the final image, not the one specified in bootc.derivation
.
bootc Notes
To create self-installer images, you may need to deal with some quirks of the bootc runtime.
- You may require fuse-overlayfs (opens in a new tab) to be installed on the final image, as Podman and most other container runtimes cannot nest kernel-based overlayfs mounts, requiring FUSE to be used for nested overlayfs.
- You may need to symlink
/var/tmp
to/tmp
in the final image, as bootc uses/var/tmp
for its temporary files, This is a bootc implementation detail, and is not a Katsu issue.
dnf
This section configures the DNF package manager.
dnf:
releasever: 39
repodir: /etc/yum.repos.d
options:
- --setopt=install_weak_deps=False
- --nogpgcheck
exclude:
- foo
- bar
packages:
- baz
arch_packages:
x86_64:
- baz-x86_64
aarch64:
- baz-aarch64
dnf.releasever
The release version DNF should pull repos from, replaces DNF's $releasever
variable.
dnf.repodir
The directory to load repositories from.
dnf.options
A list of additional arguments to pass to DNF.
dnf.exclude
A list of packages to exclude from the image.
dnf.packages
A list of packages to install in the image.
This can also be any DNF spec string that DNF understands, such as @core
or foo.x86_64
dnf.arch_packages
A map of packages to install for each architecture. The key is the architecture, and the value is a list of packages to install.
dnf.arch_exclude
A map of packages to exclude from the image per each architecture. The key is the architecture, and the value is a list of packages to exclude from the image.
disk
This section configures the disk layout (GPT only)
disk:
size: 8GiB
partitions:
- label: EFI
size: 512MiB
filesystem: efi
mountpoint: /boot/efi
- label: boot
size: 1GiB
filesystem: ext4
mountpoint: /boot
- label: root
filesystem: ext4
mountpoint: /
disk.size
The total size of the disk image, defined by bytesize (opens in a new tab)
disk.partitions
A list of partitions to create on the disk.
disk.partitions.[].label
The label of the partition
disk.partitions.[].size
The size of the partition, defined by bytesize (opens in a new tab)
disk.partitions.[].filesystem
The filesystem to format the partition with mkfs
disk.partitions.[].mountpoint
The mountpoint to mount the partition at relative to the root of the image.
The order of the partitions is important, as they are created in the order they are defined, however, mountpoints will be sorted
by nesting level, so /
will be mounted first, then /boot
, then /boot/efi
. This is done using a topological sort algorithm.
If the mountpoint depths are the same, they will be sorted alphabetically.
import.[]
File paths to other manifests to import and merge into the current manifest during runtime. Must be relative to the current manifest.
Not all attributes get merged when importing another manfiest. The following attributes are not merged:
bootloader
iso
disk
dnf
with the exception ofdnf.packages
dnf.arch_packages
dnf.arch_exclude
dnf.options
dnf.exclude
dnf.repodir
import:
- ./modules/hello.yaml
users.[]
A list of users to create in the image.
users.[].name
The username of the user
users.[].password
The password of the user, must be hashed using crypt(3)
users.[].uid
The UID of the user
users.[].gid
The GID of the user
users.[].groups.[]
A list of groups to add the user to
users.[].shell
The shell of the user
users.[].ssh_keys.[]
A list of SSH keys to add to the user's authorized_keys
file
users.[].create_home
Whether to create the user's home directory
Must be a boolean, defaults to true
Example Manifest
# Example manifest for a Katsu build
builder: dnf
distro: Katsu Ultramarine
import:
- modules/base.yaml
scripts:
post:
- id: grub-install
name: Install GRUB
file: modules/scripts/grub-install.sh
disk:
size: 8GiB
partitions:
- label: EFI
size: 512MiB
filesystem: efi
mountpoint: /boot/efi
- label: boot
size: 1GiB
filesystem: ext4
mountpoint: /boot
- label: root
# size: 2.5MiB
filesystem: ext4
mountpoint: /
dnf:
releasever: 39
repodir: repodir/
options:
- --setopt=cachedir=/var/cache/dnf
- --nogpgcheck
- --setopt=keepcache=True
exclude:
- fedora-release*
- generic-release*
packages:
- filesystem
- setup
- lvm2
- btrfs-progs
- kernel
- glibc
- glibc-common
- dnf
- "@core"
- NetworkManager
- fedora-repos
arch_packages:
aarch64:
- grub2-efi-aa64
- grub2-efi-aa64-modules
- grub2-efi-aa64-cdboot
- shim-aa64
- shim-unsigned-aarch64
- bcm283x-firmware
- bcm283x-overlays
- "@arm-tools"
x86_64:
- grub2-efi-x64
- grub2-efi-x64-modules
- grub2-efi-x64-cdboot
- grub2-pc
- grub2-pc-modules
- shim-x64
- shim-unsigned-x64