'\" t .\" Automatically generated by Pandoc 3.1.8 .\" .TH "mkosi" "1" "" "" "" .SH NAME mkosi \[em] Build Bespoke OS Images .SH SYNOPSIS \f[CR]mkosi [options\&...] summary\f[R] .PP \f[CR]mkosi [options\&...] build [command line\&...]\f[R] .PP \f[CR]mkosi [options\&...] shell [command line\&...]\f[R] .PP \f[CR]mkosi [options\&...] boot [nspawn settings\&...]\f[R] .PP \f[CR]mkosi [options\&...] qemu [qemu parameters\&...]\f[R] .PP \f[CR]mkosi [options\&...] vmspawn [vmspawn settings\&...]\f[R] .PP \f[CR]mkosi [options\&...] ssh [command line\&...]\f[R] .PP \f[CR]mkosi [options\&...] journalctl [command line\&...]\f[R] .PP \f[CR]mkosi [options\&...] coredumpctl [command line\&...]\f[R] .PP \f[CR]mkosi [options\&...] clean\f[R] .PP \f[CR]mkosi [options\&...] serve\f[R] .PP \f[CR]mkosi [options\&...] burn \f[R] .PP \f[CR]mkosi [options\&...] bump\f[R] .PP \f[CR]mkosi [options\&...] genkey\f[R] .PP \f[CR]mkosi [options\&...] documentation\f[R] .PP \f[CR]mkosi [options\&...] help\f[R] .SH DESCRIPTION \f[CR]mkosi\f[R] is a tool for easily building customized OS images. It\[cq]s a fancy wrapper around \f[CR]dnf --installroot\f[R], \f[CR]apt\f[R], \f[CR]pacman\f[R] and \f[CR]zypper\f[R] that may generate disk images with a number of bells and whistles. .SS Command Line Verbs The following command line verbs are known: .TP \f[CR]summary\f[R] Outputs a human-readable summary of all options used for building an image. This will parse the command line and \f[CR]mkosi.conf\f[R] file as it would do on \f[CR]build\f[R], but only output what it is configured for and not actually build anything. .TP \f[CR]build\f[R] This builds the image based on the settings passed in on the command line or read from configuration files. This command is the default if no verb is explicitly specified. If any command line arguments are specified, these are passed directly to the build script if one is defined. .TP \f[CR]shell\f[R] This builds the image if it is not built yet, and then invokes \f[CR]systemd-nspawn\f[R] to acquire an interactive shell prompt in it. An optional command line may be specified after the \f[CR]shell\f[R] verb, to be invoked in place of the shell in the container. Use \f[CR]-f\f[R] in order to rebuild the image unconditionally before acquiring the shell, see below. This command must be executed as \f[CR]root\f[R]. .TP \f[CR]boot\f[R] Similar to \f[CR]shell\f[R], but boots the image using \f[CR]systemd-nspawn\f[R]. An optional command line may be specified after the \f[CR]boot\f[R] verb, which can contain extra nspawn options as well as arguments which are passed as the \f[I]kernel command line\f[R] to the init system in the image. .TP \f[CR]qemu\f[R] Similar to \f[CR]boot\f[R], but uses \f[CR]qemu\f[R] to boot up the image, i.e.\ instead of container virtualization virtual machine virtualization is used. This verb is only supported for disk images that contain a boot loader and cpio images in which a kernel was installed. For cpio images a kernel can also be provided by passing the \f[CR]-kernel\f[R] qemu argument to the \f[CR]qemu\f[R] verb. Any arguments specified after the \f[CR]qemu\f[R] verb are appended to the \f[CR]qemu\f[R] invocation. .TP \f[CR]vmspawn\f[R] Similar to \f[CR]boot\f[R], but uses \f[CR]systemd-vmspawn\f[R] to boot up the image, i.e. instead of container virtualization virtual machine virtualization is used. This verb is only supported for disk and directory type images. Any arguments specified after the \f[CR]vmspawn\f[R] verb are appended to the \f[CR]systemd-vmspawn\f[R] invocation. .TP \f[CR]ssh\f[R] When the image is built with the \f[CR]Ssh=yes\f[R] option, this command connects to a booted virtual machine (\f[CR]qemu\f[R]) via SSH. Make sure to run \f[CR]mkosi ssh\f[R] with the same config as \f[CR]mkosi build\f[R] so that it has the necessary information available to connect to the running virtual machine via SSH. Specifically, the SSH private key from the \f[CR]SshKey=\f[R] setting is used to connect to the virtual machine. Use \f[CR]mkosi genkey\f[R] to automatically generate a key and certificate that will be picked up by mkosi. Any arguments passed after the \f[CR]ssh\f[R] verb are passed as arguments to the \f[CR]ssh\f[R] invocation. To connect to a container, use \f[CR]machinectl login\f[R] or \f[CR]machinectl shell\f[R]. .TP \f[CR]journalctl\f[R] Uses \f[CR]journalctl\f[R] to inspect the journal inside the image. Any arguments specified after the \f[CR]journalctl\f[R] verb are appended to the \f[CR]journalctl\f[R] invocation. .TP \f[CR]coredumpctl\f[R] Uses \f[CR]coredumpctl\f[R] to look for coredumps inside the image. Any arguments specified after the \f[CR]coredumpctl\f[R] verb are appended to the \f[CR]coredumpctl\f[R] invocation. .TP \f[CR]clean\f[R] Remove build artifacts generated on a previous build. If combined with \f[CR]-f\f[R], also removes incremental build cache images. If \f[CR]-f\f[R] is specified twice, also removes any package cache. .TP \f[CR]serve\f[R] This builds the image if it is not built yet, and then serves the output directory (i.e.\ usually \f[CR]mkosi.output/\f[R], see below) via a small embedded HTTP server, listening on port 8081. Combine with \f[CR]-f\f[R] in order to rebuild the image unconditionally before serving it. This command is useful for testing network based acquisition of OS images, for example via \f[CR]machinectl pull-raw \&...\f[R] and \f[CR]machinectl pull-tar \&...\f[R]. .TP \f[CR]burn \f[R] This builds the image if it is not built yet, and then writes it to the specified block device. The partition contents are written as-is, but the GPT partition table is corrected to match sector and disk size of the specified medium. .TP \f[CR]bump\f[R] Bumps the image version from \f[CR]mkosi.version\f[R] and writes the resulting version string to \f[CR]mkosi.version\f[R]. This is useful for implementing a simple versioning scheme: each time this verb is called the version is bumped in preparation for the subsequent build. Note that \f[CR]--auto-bump\f[R]/\f[CR]-B\f[R] may be used to automatically bump the version after each successful build. .TP \f[CR]genkey\f[R] Generate a pair of SecureBoot keys for usage with the \f[CR]SecureBootKey=\f[R]/\f[CR]--secure-boot-key=\f[R] and \f[CR]SecureBootCertificate=\f[R]/\f[CR]--secure-boot-certificate=\f[R] options. .TP \f[CR]documentation\f[R] Show mkosi\[cq]s documentation. By default this verb will try several ways to output the documentation, but a specific option can be chosen with the \f[CR]--doc-format\f[R] option. Distro packagers are encouraged to add a file \f[CR]mkosi.1\f[R] into the \f[CR]mkosi/resources\f[R] directory of the Python package, if it is missing, as well as to install it in the appropriate search path for man pages. The man page can be generated from the markdown file \f[CR]mkosi/resources/mkosi.md\f[R] e.g via \f[CR]pandoc -t man -s -o mkosi.1 mkosi.md\f[R]. .TP \f[CR]help\f[R] This verb is equivalent to the \f[CR]--help\f[R] switch documented below: it shows a brief usage explanation. .SS Commandline-only Options Those settings cannot be configured in the configuration files. .TP \f[CR]--force\f[R], \f[CR]-f\f[R] Replace the output file if it already exists, when building an image. By default when building an image and an output artifact already exists \f[CR]mkosi\f[R] will refuse operation. Specify this option once to delete all build artifacts from a previous run before re-building the image. If incremental builds are enabled, specifying this option twice will ensure the intermediary cache files are removed, too, before the re-build is initiated. If a package cache is used (also see the \f[B]Files\f[R] section below), specifying this option thrice will ensure the package cache is removed too, before the re-build is initiated. For the \f[CR]clean\f[R] operation this option has a slightly different effect: by default the verb will only remove build artifacts from a previous run, when specified once the incremental cache files are deleted too, and when specified twice the package cache is also removed. .TP \f[CR]--directory=\f[R], \f[CR]-C\f[R] Takes a path to a directory. \f[CR]mkosi\f[R] switches to this directory before doing anything. Note that the various configuration files are searched for in this directory, hence using this option is an effective way to build a project located in a specific directory. .TP \f[CR]--debug=\f[R] Enable additional debugging output. .TP \f[CR]--debug-shell\f[R] When executing a command in the image fails, mkosi will start an interactive shell in the image allowing further debugging. .TP \f[CR]--debug-workspace=\f[R] When an error occurs, the workspace directory will not be deleted. .TP \f[CR]--version\f[R] Show package version. .TP \f[CR]--help\f[R], \f[CR]-h\f[R] Show brief usage information. .TP \f[CR]--genkey-common-name=\f[R] Common name to be used when generating keys via mkosi\[cq]s \f[CR]genkey\f[R] command. Defaults to \f[CR]mkosi of %u\f[R], where \f[CR]%u\f[R] expands to the username of the user invoking mkosi. .TP \f[CR]--genkey-valid-days=\f[R] Number of days that the keys should remain valid when generating keys via mkosi\[cq]s \f[CR]genkey\f[R] command. Defaults to two years (730 days). .TP \f[CR]--auto-bump=\f[R], \f[CR]-B\f[R] If specified, after each successful build the the version is bumped in a fashion equivalent to the \f[CR]bump\f[R] verb, in preparation for the next build. This is useful for simple, linear version management: each build in a series will have a version number one higher then the previous one. .TP \f[CR]--doc-format\f[R] The format to show the documentation in. Supports the values \f[CR]markdown\f[R], \f[CR]man\f[R], \f[CR]pandoc\f[R], \f[CR]system\f[R] and \f[CR]auto\f[R]. In the case of \f[CR]markdown\f[R] the documentation is shown in the original Markdown format. \f[CR]man\f[R] shows the documentation in man page format, if it is available. \f[CR]pandoc\f[R] will generate the man page format on the fly, if \f[CR]pandoc\f[R] is available. \f[CR]system\f[R] will show the system-wide man page for mkosi, which may or may not correspond to the version you are using, depending on how you installed mkosi. \f[CR]auto\f[R], which is the default, will try all methods in the order \f[CR]man\f[R], \f[CR]pandoc\f[R], \f[CR]markdown\f[R], \f[CR]system\f[R]. .TP \f[CR]--json\f[R] Show the summary output as JSON-SEQ. .SS Supported output formats The following output formats are supported: .IP \[bu] 2 Raw \f[I]GPT\f[R] disk image, created using systemd-repart (\f[I]disk\f[R]) .IP \[bu] 2 Plain directory, containing the OS tree (\f[I]directory\f[R]) .IP \[bu] 2 Tar archive (\f[I]tar\f[R]) .IP \[bu] 2 CPIO archive (\f[I]cpio\f[R]) .PP The output format may also be set to \f[I]none\f[R] to have mkosi produce no image at all. This can be useful if you only want to use the image to produce another output in the build scripts (e.g.\ build an rpm). .PP When a \f[I]GPT\f[R] disk image is created, repart partition definition files may be placed in \f[CR]mkosi.repart/\f[R] to configure the generated disk image. .PP It is highly recommended to run \f[CR]mkosi\f[R] on a file system that supports reflinks such as XFS and btrfs and to keep all related directories on the same file system. This allows mkosi to create images very quickly by using reflinks to perform copying via copy-on-write operations. .SS Configuration Settings The following settings can be set through configuration files (the syntax with \f[CR]SomeSetting=value\f[R]) and on the command line (the syntax with \f[CR]--some-setting=value\f[R]). For some command line parameters, a single-letter shortcut is also allowed. In the configuration files, the setting must be in the appropriate section, so the settings are grouped by section below. .PP Configuration is parsed in the following order: .IP \[bu] 2 The command line arguments are parsed .IP \[bu] 2 \f[CR]mkosi.local.conf\f[R] is parsed if it exists. This file should be in the gitignore (or equivalent) and is intended for local configuration. .IP \[bu] 2 Any default paths (depending on the option) are configured if the corresponding path exists. .IP \[bu] 2 \f[CR]mkosi.conf\f[R] is parsed if it exists in the directory configured with \f[CR]--directory=\f[R] or the current working directory if \f[CR]--directory=\f[R] is not used. .IP \[bu] 2 \f[CR]mkosi.conf.d/\f[R] is parsed in the same directory if it exists. Each directory and each file with the \f[CR].conf\f[R] extension in \f[CR]mkosi.conf.d/\f[R] is parsed. Any directory in \f[CR]mkosi.conf.d\f[R] is parsed as if it were a regular top level directory. .PP Note that if the same setting is configured twice, the later assignment overrides the earlier assignment unless the setting is a list based setting. Also note that before v16, we used to do the opposite, where the earlier assignment would be used instead of later assignments. .PP Settings that take a list of values are merged by appending the new values to the previously configured values. Assigning the empty string to such a setting removes all previously assigned values, and overrides any configured default values as well. .PP If a setting\[cq]s name in the configuration file is prefixed with \f[CR]\[at]\f[R], it configures the default value used for that setting if no explicit default value is set. This can be used to set custom default values in configuration files that can still be overridden by specifying the setting explicitly via the CLI. .PP To conditionally include configuration files, the \f[CR][Match]\f[R] section can be used. A \f[CR][Match]\f[R] section consists of invididual conditions. Conditions can use a pipe symbol (\f[CR]|\f[R]) after the equals sign (\f[CR]\&...=|\&...\f[R]), which causes the condition to become a triggering condition. The config file will be included if the logical AND of all non-triggering conditions and the logical OR of all triggering conditions is satisfied. To negate the result of a condition, prefix the argument with an exclamation mark. If an argument is prefixed with the pipe symbol and an exclamation mark, the pipe symbol must be passed first, and the exclamation second. .PP Note that \f[CR][Match]\f[R] conditions compare against the current values of specific settings, and do not take into account changes made to the setting in configuration files that have not been parsed yet. Also note that matching against a setting and then changing its value afterwards in a different config file may lead to unexpected results. .PP The \f[CR][Match]\f[R] section of a \f[CR]mkosi.conf\f[R] file in a directory applies to the entire directory. If the conditions are not satisfied, the entire directory is skipped. The \f[CR][Match]\f[R] sections of files in \f[CR]mkosi.conf.d/\f[R] and \f[CR]mkosi.local.conf\f[R] only apply to the file itself. .PP If there are multiple \f[CR][Match]\f[R] sections in the same configuration file, each of them has to be satisfied in order for the configuration file to be included. Specifically, triggering conditions only apply to the current \f[CR][Match]\f[R] section and are reset between multiple \f[CR][Match]\f[R] sections. As an example, the following will only match if the output format is one of \f[CR]disk\f[R] or \f[CR]directory\f[R] and the architecture is one of \f[CR]x86-64\f[R] or \f[CR]arm64\f[R]: .IP .EX [Match] Format=|disk Format=|directory [Match] Architecture=|x86-64 Architecture=|arm64 .EE .PP The \f[CR][TriggerMatch]\f[R] section can be used to indicate triggering match sections. These are identical to triggering conditions except they apply to the entire match section instead of just a single condition. As an example, the following will match if the distribution is \f[CR]debian\f[R] and the release is \f[CR]bookworm\f[R] or if the distribution is \f[CR]ubuntu\f[R] and the release is \f[CR]focal\f[R]. .IP .EX [TriggerMatch] Distribution=debian Release=bookworm [TriggerMatch] Distribution=ubuntu Release=focal .EE .PP The semantics of conditions in \f[CR][TriggerMatch]\f[R] sections is the same as in \f[CR][Match]\f[R], i.e.\ all normal conditions are joined by a logical AND and all triggering conditions are joined by a logical OR. When mixing \f[CR][Match]\f[R] and \f[CR][TriggerMatch]\f[R] sections, a match is achieved when all \f[CR][Match]\f[R] sections match and at least one \f[CR][TriggerMatch]\f[R] section matches. No match sections are valued as true. Logically this means: .IP .EX (⋀ᵢ Matchᵢ) ∧ (⋁ᵢ TriggerMatchᵢ) .EE .PP Command line options that take no argument are shown without \f[CR]=\f[R] in their long version. In the config files, they should be specified with a boolean argument: either \f[CR]1\f[R], \f[CR]yes\f[R], or \f[CR]true\f[R] to enable, or \f[CR]0\f[R], \f[CR]no\f[R], \f[CR]false\f[R] to disable. .SS [Match] Section. .TP \f[CR]Profile=\f[R] Matches against the configured profile. .TP \f[CR]Distribution=\f[R] Matches against the configured distribution. .TP \f[CR]Release=\f[R] Matches against the configured distribution release. If this condition is used and no distribution has been explicitly configured yet, the host distribution and release are used. .TP \f[CR]Architecture=\f[R] Matches against the configured architecture. If this condition is used and no architecture has been explicitly configured yet, the host architecture is used. .TP \f[CR]PathExists=\f[R] This condition is satisfied if the given path exists. Relative paths are interpreted relative to the parent directory of the config file that the condition is read from. .TP \f[CR]ImageId=\f[R] Matches against the configured image ID, supporting globs. If this condition is used and no image ID has been explicitly configured yet, this condition fails. .TP \f[CR]ImageVersion=\f[R] Matches against the configured image version. Image versions can be prepended by the operators \f[CR]==\f[R], \f[CR]!=\f[R], \f[CR]>=\f[R], \f[CR]<=\f[R], \f[CR]<\f[R], \f[CR]>\f[R] for rich version comparisons according to the UAPI group version format specification. If no operator is prepended, the equality operator is assumed by default. If this condition is used and no image version has been explicitly configured yet, this condition fails. .TP \f[CR]Bootable=\f[R] Matches against the configured value for the \f[CR]Bootable=\f[R] feature. Takes a boolean value or \f[CR]auto\f[R]. .TP \f[CR]Format=\f[R] Matches against the configured value for the \f[CR]Format=\f[R] option. Takes an output format (see the \f[CR]Format=\f[R] option). .TP \f[CR]SystemdVersion=\f[R] Matches against the systemd version on the host (as reported by \f[CR]systemctl --version\f[R]). Values can be prepended by the operators \f[CR]==\f[R], \f[CR]!=\f[R], \f[CR]>=\f[R], \f[CR]<=\f[R], \f[CR]<\f[R], \f[CR]>\f[R] for rich version comparisons according to the UAPI group version format specification. If no operator is prepended, the equality operator is assumed by default. .TP \f[CR]BuildSources=\f[R] Takes a build source target path (see \f[CR]BuildSources=\f[R]). This match is satisfied if any of the configured build sources uses this target path. For example, if we have a \f[CR]mkosi.conf\f[R] file containing: .IP .EX [Content] BuildSources=../abc/qed:kernel .EE .PP and a drop-in containing: .IP .EX [Match] BuildSources=kernel .EE .TP The drop-in will be included. Any absolute paths passed to this setting are interpreted relative to the current working directory. .TP \f[CR]HostArchitecture=\f[R] Matches against the host\[cq]s native architecture. See the \f[CR]Architecture=\f[R] setting for a list of possible values. .PP .TS tab(@); lw(20.7n) lw(6.9n) lw(17.7n) lw(24.6n). T{ Matcher T}@T{ Globs T}@T{ Rich Comparisons T}@T{ Default T} _ T{ \f[CR]Profile=\f[R] T}@T{ no T}@T{ no T}@T{ match fails T} T{ \f[CR]Distribution=\f[R] T}@T{ no T}@T{ no T}@T{ match host distribution T} T{ \f[CR]Release=\f[R] T}@T{ no T}@T{ no T}@T{ match host release T} T{ \f[CR]Architecture=\f[R] T}@T{ no T}@T{ no T}@T{ match host architecture T} T{ \f[CR]PathExists=\f[R] T}@T{ no T}@T{ no T}@T{ n/a T} T{ \f[CR]ImageId=\f[R] T}@T{ yes T}@T{ no T}@T{ match fails T} T{ \f[CR]ImageVersion=\f[R] T}@T{ no T}@T{ yes T}@T{ match fails T} T{ \f[CR]Bootable=\f[R] T}@T{ no T}@T{ no T}@T{ match auto feature T} T{ \f[CR]Format=\f[R] T}@T{ no T}@T{ no T}@T{ match default format T} T{ \f[CR]SystemdVersion=\f[R] T}@T{ no T}@T{ yes T}@T{ n/a T} T{ \f[CR]BuildSources=\f[R] T}@T{ no T}@T{ no T}@T{ match fails T} T{ \f[CR]HostArchitecture=\f[R] T}@T{ no T}@T{ no T}@T{ n/a T} .TE .SS [Config] Section .TP \f[CR]Profile=\f[R], \f[CR]--profile=\f[R] Select the given profile. A profile is a configuration file or directory in the \f[CR]mkosi.profiles/\f[R] directory. When selected, this configuration file or directory is included after parsing the \f[CR]mkosi.conf\f[R] file, but before any \f[CR]mkosi.conf.d/*.conf\f[R] drop in configuration. .TP \f[CR]Include=\f[R], \f[CR]--include=\f[R] Include extra configuration from the given file or directory. The extra configuration is included immediately after parsing the setting, except when a default is set using \f[CR]\[at]Include=\f[R], in which case the configuration is included after parsing all the other configuration files. Note that each path containing extra configuration is only parsed once, even if included more than once with \f[CR]Include=\f[R]. The builtin configs for the mkosi default initrd and default tools tree can be included by including the literal value \f[CR]mkosi-initrd\f[R] and \f[CR]mkosi-tools\f[R] respectively. Note: Include names starting with either of the literals \f[CR]mkosi-\f[R] or \f[CR]contrib-\f[R] are reserved for use by mkosi itself. .TP \f[CR]InitrdInclude=\f[R], \f[CR]--initrd-include=\f[R] Same as \f[CR]Include=\f[R], but the extra configuration files or directories are included when building the default initrd. .TP \f[CR]Images=\f[R], \f[CR]--image=\f[R] If specified, only build the given image. Can be specified multiple times to build multiple images. All the given images and their dependencies are built. If not specified, all images are built. See the \f[B]Building multiple images\f[R] section for more information. Note that this section only takes effect when specified in the global configuration files. It has no effect if specified as an image specific setting. .TP \f[CR]Dependencies=\f[R], \f[CR]--dependency=\f[R] The images that this image depends on specified as a comma-separated list. All images configured in this option will be built before this image and will be pulled in as dependencies of this image when \f[CR]Images=\f[R] is used. .TP \f[CR]MinimumVersion=\f[R], \f[CR]--minimum-version=\f[R] The minimum mkosi version required to build this configuration. If specified multiple times, the highest specified version is used. .SS [Distribution] Section .TP \f[CR]Distribution=\f[R], \f[CR]--distribution=\f[R], \f[CR]-d\f[R] The distribution to install in the image. Takes one of the following arguments: \f[CR]fedora\f[R], \f[CR]debian\f[R], \f[CR]ubuntu\f[R], \f[CR]arch\f[R], \f[CR]opensuse\f[R], \f[CR]mageia\f[R], \f[CR]centos\f[R], \f[CR]rhel\f[R], \f[CR]rhel-ubi\f[R], \f[CR]openmandriva\f[R], \f[CR]rocky\f[R], \f[CR]alma\f[R], \f[CR]custom\f[R]. If not specified, defaults to the distribution of the host or \f[CR]custom\f[R] if the distribution of the host is not a supported distribution. .TP \f[CR]Release=\f[R], \f[CR]--release=\f[R], \f[CR]-r\f[R] The release of the distribution to install in the image. The precise syntax of the argument this takes depends on the distribution used, and is either a numeric string (in case of Fedora Linux, CentOS, \&..., e.g.\ \f[CR]29\f[R]), or a distribution version name (in case of Debian, Ubuntu, \&..., e.g.\ \f[CR]artful\f[R]). Defaults to a recent version of the chosen distribution, or the version of the distribution running on the host if it matches the configured distribution. .TP \f[CR]Architecture=\f[R], \f[CR]--architecture=\f[R] The architecture to build the image for. The architectures that are actually supported depends on the distribution used and whether a bootable image is requested or not. When building for a foreign architecture, you\[cq]ll also need to install and register a user mode emulator for that architecture. One of the following architectures can be specified per image built: \f[CR]alpha\f[R], \f[CR]arc\f[R], \f[CR]arm\f[R], \f[CR]arm64\f[R], \f[CR]ia64\f[R], \f[CR]loongarch64\f[R], \f[CR]mips64-le\f[R], \f[CR]mips-le\f[R], \f[CR]parisc\f[R], \f[CR]ppc\f[R], \f[CR]ppc64\f[R], \f[CR]ppc64-le\f[R], \f[CR]riscv32\f[R], \f[CR]riscv64\f[R], \f[CR]s390\f[R], \f[CR]s390x\f[R], \f[CR]tilegx\f[R], \f[CR]x86\f[R], \f[CR]x86-64\f[R]. .TP \f[CR]Mirror=\f[R], \f[CR]--mirror=\f[R], \f[CR]-m\f[R] The mirror to use for downloading the distribution packages. Expects a mirror URL as argument. If not provided, the default mirror for the distribution is used. The default mirrors for each distribution are as follows (unless specified, the same mirror is used for all architectures): .PP .TS tab(@); lw(13.5n) lw(29.5n) lw(27.0n). T{ T}@T{ x86-64 T}@T{ aarch64 T} _ T{ \f[CR]debian\f[R] T}@T{ http://deb.debian.org/debian T}@T{ T} T{ \f[CR]arch\f[R] T}@T{ https://geo.mirror.pkgbuild.com T}@T{ http://mirror.archlinuxarm.org T} T{ \f[CR]opensuse\f[R] T}@T{ http://download.opensuse.org T}@T{ T} T{ \f[CR]ubuntu\f[R] T}@T{ http://archive.ubuntu.com T}@T{ http://ports.ubuntu.com T} T{ \f[CR]centos\f[R] T}@T{ https://mirrors.centos.org T}@T{ T} T{ \f[CR]rocky\f[R] T}@T{ https://mirrors.rockylinux.org T}@T{ T} T{ \f[CR]alma\f[R] T}@T{ https://mirrors.almalinux.org T}@T{ T} T{ \f[CR]fedora\f[R] T}@T{ https://mirrors.fedoraproject.org T}@T{ T} T{ \f[CR]rhel-ubi\f[R] T}@T{ https://cdn-ubi.redhat.com T}@T{ T} T{ \f[CR]mageia\f[R] T}@T{ https://www.mageia.org T}@T{ T} T{ \f[CR]openmandriva\f[R] T}@T{ http://mirrors.openmandriva.org T}@T{ T} .TE .TP \f[CR]LocalMirror=\f[R], \f[CR]--local-mirror=\f[R] The mirror will be used as a local, plain and direct mirror instead of using it as a prefix for the full set of repositories normally supported by distributions. Useful for fully offline builds with a single repository. Supported on deb/rpm/arch based distributions. Overrides \f[CR]--mirror=\f[R] but only for the local mkosi build, it will not be configured inside the final image, \f[CR]--mirror=\f[R] (or the default repository) will be configured inside the final image instead. .TP \f[CR]RepositoryKeyCheck=\f[R], \f[CR]--repository-key-check=\f[R] Controls signature/key checks when using repositories, enabled by default. Useful to disable checks when combined with \f[CR]--local-mirror=\f[R] and using only a repository from a local filesystem. Not used for DNF-based distros yet. .TP \f[CR]Repositories=\f[R], \f[CR]--repositories=\f[R] Enable package repositories that are disabled by default. This can be used to enable the EPEL repos for CentOS or different components of the Debian/Ubuntu repositories. .TP \f[CR]CacheOnly=\f[R], \f[CR]--cache-only=\f[R] Takes one of \f[CR]none\f[R], \f[CR]metadata\f[R] or \f[CR]always\f[R]. If \f[CR]always\f[R], the package manager is instructed not to contact the network. This provides a minimal level of reproducibility, as long as the package cache is already fully populated. If set to \f[CR]metadata\f[R], the package manager can still download packages, but we won\[cq]t sync the repository metadata. If set to \f[CR]none\f[R], the repository metadata is synced and packages can be downloaded during the build. .TP \f[CR]PackageManagerTrees=\f[R], \f[CR]--package-manager-tree=\f[R] This option mirrors the above \f[CR]SkeletonTrees=\f[R] option and defaults to the same value if not configured otherwise, but installs the files to a subdirectory of the workspace directory instead of the OS tree. This subdirectory of the workspace is used to configure the package manager. \f[CR]mkosi\f[R] will look for the package manager configuration and related files in the configured package manager trees. Unless specified otherwise, it will use the configuration files from their canonical locations in \f[CR]/usr\f[R] or \f[CR]/etc\f[R] in the package manager trees. For example, it will look for \f[CR]etc/dnf/dnf.conf\f[R] in the package manager trees if \f[CR]dnf\f[R] is used to install packages. \f[CR]SkeletonTrees=\f[R] and \f[CR]PackageManagerTrees=\f[R] fulfill similar roles. Use \f[CR]SkeletonTrees=\f[R] if you want the files to be present in the final image. Use \f[CR]PackageManagerTrees=\f[R] if you don\[cq]t want the files to be present in the final image, e.g.\ when building an initrd or if you want to refer to paths outside of the image in your repository configuration. .SS [Output] Section .TP \f[CR]Format=\f[R], \f[CR]--format=\f[R], \f[CR]-t\f[R] The image format type to generate. One of \f[CR]directory\f[R] (for generating an OS image directly in a local directory), \f[CR]tar\f[R] (similar, but a tarball of the OS image is generated), \f[CR]cpio\f[R] (similar, but a cpio archive is generated), \f[CR]disk\f[R] (a block device OS image with a GPT partition table), \f[CR]uki\f[R] (a unified kernel image with the OS image in the \f[CR].initrd\f[R] PE section), \f[CR]esp\f[R] (\f[CR]uki\f[R] but wrapped in a disk image with only an ESP partition), \f[CR]sysext\f[R], \f[CR]confext\f[R], \f[CR]portable\f[R] or \f[CR]none\f[R] (the OS image is solely intended as a build image to produce another artifact). If the \f[CR]disk\f[R] output format is used, the disk image is generated using \f[CR]systemd-repart\f[R]. The repart partition definition files to use can be configured using the \f[CR]RepartDirectories=\f[R] setting or via \f[CR]mkosi.repart/\f[R]. When verity partitions are configured using systemd-repart\[cq]s \f[CR]Verity=\f[R] setting, mkosi will automatically parse the verity hash partition\[cq]s roothash from systemd-repart\[cq]s JSON output and include it in the kernel command line of every unified kernel image built by mkosi. .TP \f[CR]ManifestFormat=\f[R], \f[CR]--manifest-format=\f[R] The manifest format type or types to generate. A comma-delimited list consisting of \f[CR]json\f[R] (the standard JSON output format that describes the packages installed), \f[CR]changelog\f[R] (a human-readable text format designed for diffing). By default no manifest is generated. .TP \f[CR]Output=\f[R], \f[CR]--output=\f[R], \f[CR]-o\f[R] Name to use for the generated output image file or directory. All outputs will be prefixed with the given name. Defaults to \f[CR]image\f[R] or, if \f[CR]ImageId=\f[R] is specified, it is used as the default output name, optionally suffixed with the version set with \f[CR]ImageVersion=\f[R]. Note that this option does not allow configuring the output directory, use \f[CR]OutputDirectory=\f[R] for that. Note that this only specifies the output prefix, depending on the specific output format, compression and image version used, the full output name might be \f[CR]image_7.8.raw.xz\f[R]. .TP \f[CR]CompressOutput=\f[R], \f[CR]--compress-output=\f[R] Configure compression for the resulting image or archive. The argument can be either a boolean or a compression algorithm (\f[CR]xz\f[R], \f[CR]zstd\f[R]). \f[CR]zstd\f[R] compression is used by default, except CentOS and derivatives up to version 8, which default to \f[CR]xz\f[R]. Note that when applied to block device image types, compression means the image cannot be started directly but needs to be decompressed first. This also means that the \f[CR]shell\f[R], \f[CR]boot\f[R], \f[CR]qemu\f[R] verbs are not available when this option is used. Implied for \f[CR]tar\f[R], \f[CR]cpio\f[R], \f[CR]uki\f[R], and \f[CR]esp\f[R]. .TP \f[CR]CompressLevel=\f[R], \f[CR]--compress-level=\f[R] Configure the compression level to use. Takes an integer. The possible values depend on the compression being used. .TP \f[CR]OutputDirectory=\f[R], \f[CR]--output-dir=\f[R], \f[CR]-O\f[R] Path to a directory where to place all generated artifacts. If this is not specified and the directory \f[CR]mkosi.output/\f[R] exists in the local directory, it is automatically used for this purpose. .TP \f[CR]WorkspaceDirectory=\f[R], \f[CR]--workspace-dir=\f[R] Path to a directory where to store data required temporarily while building the image. This directory should have enough space to store the full OS image, though in most modes the actually used disk space is smaller. If not specified, a subdirectory of \f[CR]$XDG_CACHE_HOME\f[R] (if set), \f[CR]$HOME/.cache\f[R] (if set) or \f[CR]/var/tmp\f[R] is used. The data in this directory is removed automatically after each build. It\[cq]s safe to manually remove the contents of this directory should an \f[CR]mkosi\f[R] invocation be aborted abnormally (for example, due to reboot/power failure). .TP \f[CR]CacheDirectory=\f[R], \f[CR]--cache-dir=\f[R] Takes a path to a directory to use as the incremental cache directory for the incremental images produced when the \f[CR]Incremental=\f[R] option is enabled. If this option is not used, but a \f[CR]mkosi.cache/\f[R] directory is found in the local directory it is automatically used for this purpose. .TP \f[CR]PackageCacheDirectory=\f[R], \f[CR]--package-cache-dir\f[R] Takes a path to a directory to use as the package cache directory for the distribution package manager used. If unset, a suitable directory in the user\[cq]s home directory or system is used. .TP \f[CR]BuildDirectory=\f[R], \f[CR]--build-dir=\f[R] Takes a path to a directory to use as the build directory for build systems that support out-of-tree builds (such as Meson). The directory used this way is shared between repeated builds, and allows the build system to reuse artifacts (such as object files, executable, \&...) generated on previous invocations. The build scripts can find the path to this directory in the \f[CR]$BUILDDIR\f[R] environment variable. This directory is mounted into the image\[cq]s root directory when \f[CR]mkosi-chroot\f[R] is invoked during execution of the build scripts. If this option is not specified, but a directory \f[CR]mkosi.builddir/\f[R] exists in the local directory it is automatically used for this purpose (also see the \f[B]Files\f[R] section below). .TP \f[CR]ImageVersion=\f[R], \f[CR]--image-version=\f[R] Configure the image version. This accepts any string, but it is recommended to specify a series of dot separated components. The version may also be configured in a file \f[CR]mkosi.version\f[R] in which case it may be conveniently managed via the \f[CR]bump\f[R] verb or the \f[CR]--auto-bump\f[R] option. When specified the image version is included in the default output file name, i.e.\ instead of \f[CR]image.raw\f[R] the default will be \f[CR]image_0.1.raw\f[R] for version \f[CR]0.1\f[R] of the image, and similar. The version is also passed via the \f[CR]$IMAGE_VERSION\f[R] to any build scripts invoked (which may be useful to patch it into \f[CR]/etc/os-release\f[R] or similar, in particular the \f[CR]IMAGE_VERSION=\f[R] field of it). .TP \f[CR]ImageId=\f[R], \f[CR]--image-id=\f[R] Configure the image identifier. This accepts a freeform string that shall be used to identify the image with. If set the default output file will be named after it (possibly suffixed with the version). The identifier is also passed via the \f[CR]$IMAGE_ID\f[R] to any build scripts invoked. The image ID is automatically added to \f[CR]/usr/lib/os-release\f[R]. .TP \f[CR]SplitArtifacts=\f[R], \f[CR]--split-artifacts\f[R] If specified and building a disk image, pass \f[CR]--split=yes\f[R] to systemd-repart to have it write out split partition files for each configured partition. Read the man (https://www.freedesktop.org/software/systemd/man/systemd-repart.html#--split=BOOL) page for more information. This is useful in A/B update scenarios where an existing disk image shall be augmented with a new version of a root or \f[CR]/usr\f[R] partition along with its Verity partition and unified kernel. .TP \f[CR]RepartDirectories=\f[R], \f[CR]--repart-dir=\f[R] Paths to directories containing systemd-repart partition definition files that are used when mkosi invokes systemd-repart when building a disk image. If \f[CR]mkosi.repart/\f[R] exists in the local directory, it will be used for this purpose as well. Note that mkosi invokes repart with \f[CR]--root=\f[R] set to the root of the image root, so any \f[CR]CopyFiles=\f[R] source paths in partition definition files will be relative to the image root directory. .TP \f[CR]SectorSize=\f[R], \f[CR]--sector-size=\f[R] Override the default sector size that systemd-repart uses when building a disk image. .TP \f[CR]RepartOffline=\f[R], \f[CR]--repart-offline=\f[R] Specifies whether to build disk images using loopback devices. Enabled by default. When enabled, \f[CR]systemd-repart\f[R] will not use loopback devices to build disk images. When disabled, \f[CR]systemd-repart\f[R] will always use loopback devices to build disk images. Note that when using \f[CR]RepartOffline=no\f[R] mkosi cannot run unprivileged and the image build has to be done as the root user outside of any containers and with loopback devices available on the host system. There are currently two known scenarios where \f[CR]RepartOffline=no\f[R] has to be used. The first is when using \f[CR]Subvolumes=\f[R] in a repart partition definition file, as subvolumes cannot be created without using loopback devices. The second is when creating a system with SELinux and an XFS root partition. Because \f[CR]mkfs.xfs\f[R] does not support populating an XFS filesystem with extended attributes, loopback devices have to be used to ensure the SELinux extended attributes end up in the generated XFS filesystem. .TP \f[CR]Overlay=\f[R], \f[CR]--overlay\f[R] When used together with \f[CR]BaseTrees=\f[R], the output will consist only out of changes to the specified base trees. Each base tree is attached as a lower layer in an overlayfs structure, and the output becomes the upper layer, initially empty. Thus files that are not modified compared to the base trees will not be present in the final output. This option may be used to create systemd \f[I]system extensions\f[R] or \f[I]portable services\f[R] (https://uapi-group.org/specifications/specs/extension_image). .TP \f[CR]UseSubvolumes=\f[R], \f[CR]--use-subvolumes=\f[R] Takes a boolean or \f[CR]auto\f[R]. Enables or disables use of btrfs subvolumes for directory tree outputs. If enabled, mkosi will create the root directory as a btrfs subvolume and use btrfs subvolume snapshots where possible to copy base or cached trees which is much faster than doing a recursive copy. If explicitly enabled and \f[CR]btrfs\f[R] is not installed or subvolumes cannot be created, an error is raised. If \f[CR]auto\f[R], missing \f[CR]btrfs\f[R] or failures to create subvolumes are ignored. .TP \f[CR]Seed=\f[R], \f[CR]--seed=\f[R] Takes a UUID as argument or the special value \f[CR]random\f[R]. Overrides the seed that \f[CR]systemd-repart(8)\f[R] (https://www.freedesktop.org/software/systemd/man/systemd-repart.service.html) uses when building a disk image. This is useful to achieve reproducible builds, where deterministic UUIDs and other partition metadata should be derived on each build. .TP \f[CR]SourceDateEpoch=\f[R], \f[CR]--source-date-epoch=\f[R] Takes a timestamp as argument. Resets file modification times of all files to this timestamp. The variable is also propagated to systemd-repart and scripts executed by mkosi. If not set explicitly, \f[CR]SOURCE_DATE_EPOCH\f[R] from \f[CR]--environment\f[R] and from the host environment are tried in that order. This is useful to make builds reproducible. See SOURCE_DATE_EPOCH (https://reproducible-builds.org/specs/source-date-epoch/) for more information. .SS [Content] Section .TP \f[CR]Packages=\f[R], \f[CR]--package=\f[R], \f[CR]-p\f[R] Install the specified distribution packages (i.e.\ RPM, DEB, \&...) in the image. Takes a comma separated list of package specifications. This option may be used multiple times in which case the specified package lists are combined. Use \f[CR]BuildPackages=\f[R] to specify packages that shall only be installed in an overlay that is mounted when the prepare scripts are executed with the \f[CR]build\f[R] argument and when the build scripts are executed. The types and syntax of \f[I]package specifications\f[R] that are allowed depend on the package installer (e.g.\ \f[CR]dnf\f[R] for \f[CR]rpm\f[R]-based distros or \f[CR]apt\f[R] for \f[CR]deb\f[R]-based distros), but may include package names, package names with version and/or architecture, package name globs, paths to packages in the file system, package groups, and virtual provides, including file paths. Example: when using a distro that uses \f[CR]dnf\f[R], the following configuration would install the \f[CR]meson\f[R] package (in the latest version), the 32-bit version of the \f[CR]libfdisk-devel\f[R] package, all available packages that start with the \f[CR]git-\f[R] prefix, a \f[CR]systemd\f[R] rpm from the local file system, one of the packages that provides \f[CR]/usr/bin/ld\f[R], the packages in the \f[I]Development Tools\f[R] group, and the package that contains the \f[CR]mypy\f[R] python module. .IP .EX Packages=meson libfdisk-devel.i686 git-* prebuilt/rpms/systemd-249-rc1.local.rpm /usr/bin/ld \[at]development-tools python3dist(mypy) .EE .PP : Note that since mkosi runs in a sandbox with most of the host files unavailable, any local packages have to be mounted into the sandbox explicitly using \f[CR]BuildSources=\f[R]. For example, let\[cq]s say we have a local package located at \f[CR]../my-packages/abc.rpm\f[R] relative to the mkosi working directory, then we\[cq]d be able to install it as follows: .IP .EX BuildSources=../my-packages:my-packages-in-sandbox Packages=my-packages-in-sandbox/abc.rpm .EE .TP \f[CR]BuildPackages=\f[R], \f[CR]--build-package=\f[R] Similar to \f[CR]Packages=\f[R], but configures packages to install only in an overlay that is made available on top of the image to the prepare scripts when executed with the \f[CR]build\f[R] argument and the build scripts. This option should be used to list packages containing header files, compilers, build systems, linkers and other build tools the \f[CR]mkosi.build\f[R] scripts require to operate. Note that packages listed here will be absent in the final image. .TP \f[CR]PackageDirectories=\f[R], \f[CR]--package-directory=\f[R] Specify directories containing extra packages to be made available during the build. \f[CR]mkosi\f[R] will create a local repository containing all packages in these directories and make it available when installing packages or running scripts. Note that this local repository is also made available when running scripts. Build scripts can add more packages to the local repository by placing the built packages in \f[CR]$PACKAGEDIR\f[R]. .TP \f[CR]WithRecommends=\f[R], \f[CR]--with-recommends=\f[R] Configures whether to install recommended or weak dependencies, depending on how they are named by the used package manager, or not. By default, recommended packages are not installed. This is only used for package managers that support the concept, which are currently apt, dnf and zypper. .TP \f[CR]WithDocs=\f[R], \f[CR]--with-docs\f[R] Include documentation in the image. Enabled by default. When disabled, if the underlying distribution package manager supports it documentation is not included in the image. The \f[CR]$WITH_DOCS\f[R] environment variable passed to the \f[CR]mkosi.build\f[R] scripts is set to \f[CR]0\f[R] or \f[CR]1\f[R] depending on whether this option is enabled or disabled. .TP \f[CR]BaseTrees=\f[R], \f[CR]--base-tree=\f[R] Takes a comma separated list of paths to use as base trees. When used, these base trees are each copied into the OS tree and form the base distribution instead of installing the distribution from scratch. Only extra packages are installed on top of the ones already installed in the base trees. Note that for this to work properly, the base image still needs to contain the package manager metadata by setting \f[CR]CleanPackageMetadata=no\f[R] (see \f[CR]CleanPackageMetadata=\f[R]). Instead of a directory, a tar file or a disk image may be provided. In this case it is unpacked into the OS tree. This mode of operation allows setting permissions and file ownership explicitly, in particular for projects stored in a version control system such as \f[CR]git\f[R] which retain full file ownership and access mode metadata for committed files. .TP \f[CR]SkeletonTrees=\f[R], \f[CR]--skeleton-tree=\f[R] Takes a comma separated list of colon separated path pairs. The first path of each pair refers to a directory to copy into the OS tree before invoking the package manager. The second path of each pair refers to the target directory inside the image. If the second path is not provided, the directory is copied on top of the root directory of the image. The second path is always interpreted as an absolute path. Use this to insert files and directories into the OS tree before the package manager installs any packages. If the \f[CR]mkosi.skeleton/\f[R] directory is found in the local directory it is also used for this purpose with the root directory as target (also see the \f[B]Files\f[R] section below). Note that skeleton trees are cached and any changes to skeleton trees after a cached image has been built (when using \f[CR]Incremental=\f[R]) are only applied when the cached image is rebuilt (by using \f[CR]-ff\f[R] or running \f[CR]mkosi -f clean\f[R]). As with the base tree logic above, instead of a directory, a tar file may be provided too. \f[CR]mkosi.skeleton.tar\f[R] will be automatically used if found in the local directory. .TP \f[CR]ExtraTrees=\f[R], \f[CR]--extra-tree=\f[R] Takes a comma separated list of colon separated path pairs. The first path of each pair refers to a directory to copy from the host into the image. The second path of each pair refers to the target directory inside the image. If the second path is not provided, the directory is copied on top of the root directory of the image. The second path is always interpreted as an absolute path. Use this to override any default configuration files shipped with the distribution. If the \f[CR]mkosi.extra/\f[R] directory is found in the local directory it is also used for this purpose with the root directory as target. (also see the \f[B]Files\f[R] section below). As with the base tree logic above, instead of a directory, a tar file may be provided too. \f[CR]mkosi.extra.tar\f[R] will be automatically used if found in the local directory. .TP \f[CR]RemovePackages=\f[R], \f[CR]--remove-package=\f[R] Takes a comma-separated list of package specifications for removal, in the same format as \f[CR]Packages=\f[R]. The removal will be performed as one of the last steps. This step is skipped if \f[CR]CleanPackageMetadata=no\f[R] is used. .TP \f[CR]RemoveFiles=\f[R], \f[CR]--remove-files=\f[R] Takes a comma-separated list of globs. Files in the image matching the globs will be purged at the end. .TP \f[CR]CleanPackageMetadata=\f[R], \f[CR]--clean-package-metadata=\f[R] Enable/disable removal of package manager databases and repository metadata at the end of installation. Can be specified as \f[CR]true\f[R], \f[CR]false\f[R], or \f[CR]auto\f[R] (the default). With \f[CR]auto\f[R], package manager databases and repository metadata will be removed if the respective package manager executable is \f[I]not\f[R] present at the end of the installation. .TP \f[CR]SyncScripts=\f[R], \f[CR]--sync-script=\f[R] Takes a comma-separated list of paths to executables that are used as the sync scripts for this image. See the \f[B]Scripts\f[R] section for more information. .TP \f[CR]PrepareScripts=\f[R], \f[CR]--prepare-script=\f[R] Takes a comma-separated list of paths to executables that are used as the prepare scripts for this image. See the \f[B]Scripts\f[R] section for more information. .TP \f[CR]BuildScripts=\f[R], \f[CR]--build-script=\f[R] Takes a comma-separated list of paths to executables that are used as the build scripts for this image. See the \f[B]Scripts\f[R] section for more information. .TP \f[CR]PostInstallationScripts=\f[R], \f[CR]--postinst-script=\f[R] Takes a comma-separated list of paths to executables that are used as the post-installation scripts for this image. See the \f[B]Scripts\f[R] section for more information. .TP \f[CR]FinalizeScripts=\f[R], \f[CR]--finalize-script=\f[R] Takes a comma-separated list of paths to executables that are used as the finalize scripts for this image. See the \f[B]Scripts\f[R] section for more information. .TP \f[CR]BuildSources=\f[R], \f[CR]--build-sources=\f[R] Takes a comma separated list of colon separated path pairs. The first path of each pair refers to a directory to mount from the host. The second path of each pair refers to the directory where the source directory should be mounted when running scripts. Every target path is prefixed with \f[CR]/work/src\f[R] and all build sources are sorted lexicographically by their target before mounting, so that top level paths are mounted first. If not configured explicitly, the current working directory is mounted to \f[CR]/work/src\f[R]. .TP \f[CR]BuildSourcesEphemeral=\f[R], \f[CR]--build-sources-ephemeral=\f[R] Takes a boolean. Disabled by default. Configures whether changes to source directories (The working directory and configured using \f[CR]BuildSources=\f[R]) are persisted. If enabled, all source directories will be reset to their original state after scripts (except sync scripts) finish executing. .TP \f[CR]Environment=\f[R], \f[CR]--environment=\f[R] Adds variables to the environment that package managers and the prepare/build/postinstall/finalize scripts are executed with. Takes a space-separated list of variable assignments or just variable names. In the latter case, the values of those variables will be passed through from the environment in which \f[CR]mkosi\f[R] was invoked. This option may be specified more than once, in which case all listed variables will be set. If the same variable is set twice, the later setting overrides the earlier one. .TP \f[CR]EnvironmentFiles=\f[R], \f[CR]--env-file=\f[R] Takes a comma-separated list of paths to files that contain environment variable definitions to be added to the scripting environment. Uses \f[CR]mkosi.env\f[R] if it is found in the local directory. The variables are first read from \f[CR]mkosi.env\f[R] if it exists, then from the given list of files and then from the \f[CR]Environment=\f[R] settings. .TP \f[CR]WithTests=\f[R], \f[CR]--without-tests\f[R], \f[CR]-T\f[R] If set to false (or when the command-line option is used), the \f[CR]$WITH_TESTS\f[R] environment variable is set to \f[CR]0\f[R] when the \f[CR]mkosi.build\f[R] scripts are invoked. This is supposed to be used by the build scripts to bypass any unit or integration tests that are normally run during the source build process. Note that this option has no effect unless the \f[CR]mkosi.build\f[R] build scripts honor it. .TP \f[CR]WithNetwork=\f[R], \f[CR]--with-network=\f[R] When true, enables network connectivity while the build scripts \f[CR]mkosi.build\f[R] are invoked. By default, the build scripts run with networking turned off. The \f[CR]$WITH_NETWORK\f[R] environment variable is passed to the \f[CR]mkosi.build\f[R] build scripts indicating whether the build is done with or without network. .TP \f[CR]Bootable=\f[R], \f[CR]--bootable=\f[R] Takes a boolean or \f[CR]auto\f[R]. Enables or disables generation of a bootable image. If enabled, mkosi will install an EFI bootloader, and add an ESP partition when the disk image output is used. If the selected EFI bootloader (See \f[CR]Bootloader=\f[R]) is not installed or no kernel images can be found, the build will fail. \f[CR]auto\f[R] behaves as if the option was enabled, but the build won\[cq]t fail if either no kernel images or the selected EFI bootloader can\[cq]t be found. If disabled, no bootloader will be installed even if found inside the image, no unified kernel images will be generated and no ESP partition will be added to the image if the disk output format is used. .TP \f[CR]Bootloader=\f[R], \f[CR]--bootloader=\f[R] Takes one of \f[CR]none\f[R], \f[CR]systemd-boot\f[R], \f[CR]uki\f[R] or \f[CR]grub\f[R]. Defaults to \f[CR]systemd-boot\f[R]. If set to \f[CR]none\f[R], no EFI bootloader will be installed into the image. If set to \f[CR]systemd-boot\f[R], systemd-boot will be installed and for each installed kernel, a UKI will be generated and stored in \f[CR]EFI/Linux\f[R] in the ESP. If set to \f[CR]uki\f[R], a single UKI will be generated for the latest installed kernel (the one with the highest version) which is installed to \f[CR]EFI/BOOT/BOOTX64.EFI\f[R] in the ESP. If set to \f[CR]grub\f[R], for each installed kernel, a UKI will be generated and stored in \f[CR]EFI/Linux\f[R] in the ESP. For each generated UKI, a menu entry is appended to the grub configuration in \f[CR]grub/grub.cfg\f[R] in the ESP which chainloads into the UKI. A shim grub.cfg is also written to \f[CR]EFI//grub.cfg\f[R] in the ESP which loads \f[CR]grub/grub.cfg\f[R] in the ESP for compatibility with signed versions of grub which load the grub configuration from this location. Note that we do not yet install grub to the ESP when \f[CR]Bootloader=\f[R] is set to \f[CR]grub\f[R]. This has to be done manually in a postinst or finalize script. The grub EFI binary should be installed to \f[CR]/efi/EFI/BOOT/BOOTX64.EFI\f[R] (or similar depending on the architecture) and should be configured to load its configuration from \f[CR]EFI//grub.cfg\f[R] in the ESP. Signed versions of grub shipped by distributions will load their configuration from this location by default. .TP \f[CR]BiosBootloader=\f[R], \f[CR]--bios-bootloader=\f[R] Takes one of \f[CR]none\f[R] or \f[CR]grub\f[R]. Defaults to \f[CR]none\f[R]. If set to \f[CR]none\f[R], no BIOS bootloader will be installed. If set to \f[CR]grub\f[R], grub is installed as the BIOS boot loader if a bootable image is requested with the \f[CR]Bootable=\f[R] option. If no repart partition definition files are configured, mkosi will add a grub BIOS boot partition and an EFI system partition to the default partition definition files. Note that this option is not mutually exclusive with \f[CR]Bootloader=\f[R]. It is possible to have an image that is both bootable on UEFI and BIOS by configuring both \f[CR]Bootloader=\f[R] and \f[CR]BiosBootloader=\f[R]. The grub BIOS boot partition should have UUID \f[CR]21686148-6449-6e6f-744e-656564454649\f[R] and should be at least 1MB. Even if no EFI bootloader is installed, we still need an ESP for BIOS boot as that\[cq]s where we store the kernel, initrd and grub modules. .TP \f[CR]ShimBootloader=\f[R], \f[CR]--shim-bootloader=\f[R] Takes one of \f[CR]none\f[R], \f[CR]unsigned\f[R], or \f[CR]signed\f[R]. Defaults to \f[CR]none\f[R]. If set to \f[CR]none\f[R], shim and MokManager will not be installed to the ESP. If set to \f[CR]unsigned\f[R], mkosi will search for unsigned shim and MokManager EFI binaries and install them. If \f[CR]SecureBoot=\f[R] is enabled, mkosi will sign the unsigned EFI binaries before installing thel. If set to \f[CR]signed\f[R], mkosi will search for signed EFI binaries and install those. Even if \f[CR]SecureBoot=\f[R] is enabled, mkosi won\[cq]t sign these binaries again. Note that this option only takes effect when an image that is bootable on UEFI firmware is requested using other options (\f[CR]Bootable=\f[R], \f[CR]Bootloader=\f[R]). Note that when this option is enabled, mkosi will only install already signed bootloader binaries, kernel image files and unified kernel images as self-signed binaries would not be accepted by the signed version of shim. .TP \f[CR]UnifiedKernelImages=\f[R], \f[CR]--unified-kernel-images=\f[R] Specifies whether to use unified kernel images or not when \f[CR]Bootloader=\f[R] is set to \f[CR]systemd-boot\f[R] or \f[CR]grub\f[R]. Takes a boolean value or \f[CR]auto\f[R]. Defaults to \f[CR]auto\f[R]. If enabled, unified kernel images are always used and the build will fail if any components required to build unified kernel images are missing. If set to \f[CR]auto\f[R], unified kernel images will be used if all necessary components are available. Otherwise Type 1 entries as defined by the Boot Loader Specification will be used instead. If disabled, Type 1 entries will always be used. .TP \f[CR]Initrds=\f[R], \f[CR]--initrd\f[R] Use user-provided initrd(s). Takes a comma separated list of paths to initrd files. This option may be used multiple times in which case the initrd lists are combined. If no initrds are specified and a bootable image is requested, mkosi will automatically build a default initrd. .TP \f[CR]InitrdPackages=\f[R], \f[CR]--initrd-package=\f[R] Extra packages to install into the default initrd. Takes a comma separated list of package specifications. This option may be used multiple times in which case the specified package lists are combined. .TP \f[CR]MicrocodeHost=\f[R], \f[CR]--microcode-host=\f[R] When set to true only include microcode for the host\[cq]s CPU in the image. .TP \f[CR]KernelCommandLine=\f[R], \f[CR]--kernel-command-line=\f[R] Use the specified kernel command line when building images. Defaults to \f[CR]console=ttyS0\f[R]. For \f[CR]arm\f[R], \f[CR]s390\f[R] and \f[CR]ppc\f[R], \f[CR]ttyS0\f[R] is replaced with \f[CR]ttyAMA0\f[R], \f[CR]ttysclp0\f[R] or \f[CR]hvc0\f[R], respectively. .TP \f[CR]KernelModulesInclude=\f[R], \f[CR]--kernel-modules-include=\f[R] Takes a list of regex patterns that specify kernel modules to include in the image. Patterns should be relative to the \f[CR]/usr/lib/modules//kernel\f[R] directory. mkosi checks for a match anywhere in the module path (e.g.\ \f[CR]i915\f[R] will match against \f[CR]drivers/gpu/drm/i915.ko\f[R]). All modules that match any of the specified patterns are included in the image. All module and firmware dependencies of the matched modules are included in the image as well. This setting takes priority over \f[CR]KernelModulesExclude=\f[R] and only makes sense when used in combination with it because all kernel modules are included in the image by default. .TP \f[CR]KernelModulesExclude=\f[R], \f[CR]--kernel-modules-exclude=\f[R] Takes a list of regex patterns that specify modules to exclude from the image. Behaves the same as \f[CR]KernelModulesInclude=\f[R] except that all modules that match any of the specified patterns are excluded from the image. .TP \f[CR]KernelModulesIncludeHost=\f[R], \f[CR]--kernel-modules-include-host=\f[R] Takes a boolean. Specifies whether to include the currently loaded modules on the host system in the image. This setting takes priority over \f[CR]KernelModulesExclude=\f[R] and only makes sense when used in combination with it because all kernel modules are included in the image by default. .TP \f[CR]KernelModulesInitrd=\f[R], \f[CR]--kernel-modules-initrd=\f[R] Enable/Disable generation of the kernel modules initrd when building a bootable image. Enabled by default. If enabled, when building a bootable image, for each kernel that we assemble a unified kernel image for we generate an extra initrd containing only the kernel modules for that kernel version and append it to the prebuilt initrd. This allows generating kernel independent initrds which are augmented with the necessary kernel modules when the UKI is assembled. .TP \f[CR]KernelModulesInitrdInclude=\f[R], \f[CR]--kernel-modules-initrd-include=\f[R] Like \f[CR]KernelModulesInclude=\f[R], but applies to the kernel modules included in the kernel modules initrd. .TP \f[CR]KernelModulesInitrdExclude=\f[R], \f[CR]--kernel-modules-initrd-exclude=\f[R] Like \f[CR]KernelModulesExclude=\f[R], but applies to the kernel modules included in the kernel modules initrd. .TP \f[CR]KernelModulesInitrdIncludeHost=\f[R], \f[CR]--kernel-modules-initrd-include-host=\f[R] Like \f[CR]KernelModulesIncludeHost=\f[R], but applies to the kernel modules included in the kernel modules initrd. .TP \f[CR]Locale=\f[R], \f[CR]--locale=\f[R], \f[CR]LocaleMessages=\f[R], \f[CR]--locale-messages=\f[R], \f[CR]Keymap=\f[R], \f[CR]--keymap=\f[R], \f[CR]Timezone=\f[R], \f[CR]--timezone=\f[R], \f[CR]Hostname=\f[R], \f[CR]--hostname=\f[R], \f[CR]RootShell=\f[R], \f[CR]--root-shell=\f[R] The settings \f[CR]Locale=\f[R], \f[CR]--locale=\f[R], \f[CR]LocaleMessages=\f[R], \f[CR]--locale-messages=\f[R], \f[CR]Keymap=\f[R], \f[CR]--keymap=\f[R], \f[CR]Timezone=\f[R], \f[CR]--timezone=\f[R], \f[CR]Hostname=\f[R], \f[CR]--hostname=\f[R], \f[CR]RootShell=\f[R], \f[CR]--root-shell=\f[R] correspond to the identically named systemd-firstboot options. See the systemd firstboot manpage (https://www.freedesktop.org/software/systemd/man/systemd-firstboot.html) for more information. Additionally, where applicable, the corresponding systemd credentials for these settings are written to \f[CR]/usr/lib/credstore\f[R], so that they apply even if only \f[CR]/usr\f[R] is shipped in the image. .TP \f[CR]RootPassword=\f[R], \f[CR]--root-password=\f[R], Set the system root password. If this option is not used, but a \f[CR]mkosi.rootpw\f[R] file is found in the local directory, the password is automatically read from it. If the password starts with \f[CR]hashed:\f[R], it is treated as an already hashed root password. The root password is also stored in \f[CR]/usr/lib/credstore\f[R] under the appropriate systemd credential so that it applies even if only \f[CR]/usr\f[R] is shipped in the image. To create an unlocked account without any password use \f[CR]hashed:\f[R] without a hash. .TP \f[CR]Autologin=\f[R], \f[CR]--autologin\f[R] Enable autologin for the \f[CR]root\f[R] user on \f[CR]/dev/pts/0\f[R] (nspawn), \f[CR]/dev/tty1\f[R] and \f[CR]/dev/ttyS0\f[R]. .TP \f[CR]MakeInitrd=\f[R], \f[CR]--make-initrd\f[R] Add \f[CR]/etc/initrd-release\f[R] and \f[CR]/init\f[R] to the image so that it can be used as an initramfs. .TP \f[CR]Ssh=\f[R], \f[CR]--ssh\f[R] If specified, an sshd socket unit and matching service are installed in the final image that expose SSH over VSock. When building with this option and running the image using \f[CR]mkosi qemu\f[R], the \f[CR]mkosi ssh\f[R] command can be used to connect to the container/VM via SSH. Note that you still have to make sure openssh is installed in the image to make this option behave correctly. Run \f[CR]mkosi genkey\f[R] to automatically generate an X509 certificate and private key to be used by mkosi to enable SSH access to any virtual machines via \f[CR]mkosi ssh\f[R]. To access images booted using \f[CR]mkosi boot\f[R], use \f[CR]machinectl\f[R]. .TP \f[CR]SELinuxRelabel=\f[R], \f[CR]--selinux-relabel=\f[R] Specifies whether to relabel files to match the image\[cq]s SELinux policy. Takes a boolean value or \f[CR]auto\f[R]. Defaults to \f[CR]auto\f[R]. If disabled, files will not relabeled. If enabled, an SELinux policy has to be installed in the image and \f[CR]setfiles\f[R] has to be available to relabel files. If any errors occur during \f[CR]setfiles\f[R], the build will fail. If set to \f[CR]auto\f[R], files will be relabeled if an SELinux policy is installed in the image and if \f[CR]setfiles\f[R] is available. Any errors occurred during \f[CR]setfiles\f[R] will be ignored. Note that when running unprivileged, \f[CR]setfiles\f[R] will fail to set any labels that are not in the host\[cq]s SELinux policy. To ensure \f[CR]setfiles\f[R] succeeds without errors, make sure to run mkosi as root or build from a host system with the same SELinux policy as the image you\[cq]re building. .SS [Validation] Section .TP \f[CR]SecureBoot=\f[R], \f[CR]--secure-boot\f[R] Sign systemd-boot (if it is not signed yet) and any generated unified kernel images for UEFI SecureBoot. .TP \f[CR]SecureBootAutoEnroll=\f[R], \f[CR]--secure-boot-auto-enroll=\f[R] Set up automatic enrollment of the secure boot keys in virtual machines as documented in the systemd-boot man page (https://www.freedesktop.org/software/systemd/man/systemd-boot.html) if \f[CR]SecureBoot=\f[R] is used. Note that systemd-boot will only do automatic secure boot key enrollment in virtual machines starting from systemd v253. To do auto enrollment on systemd v252 or on bare metal machines, write a systemd-boot configuration file to \f[CR]/efi/loader/loader.conf\f[R] using an extra tree with \f[CR]secure-boot-enroll force\f[R] or \f[CR]secure-boot-enroll manual\f[R] in it. Auto enrollment is not supported on systemd versions older than v252. Defaults to \f[CR]yes\f[R]. .TP \f[CR]SecureBootKey=\f[R], \f[CR]--secure-boot-key=\f[R] Path to the PEM file containing the secret key for signing the UEFI kernel image if \f[CR]SecureBoot=\f[R] is used and PCR signatures when \f[CR]SignExpectedPcr=\f[R] is also used. When \f[CR]SecureBootKeySource=\f[R] is specified, the input type depends on the source. .TP \f[CR]SecureBootKeySource=\f[R], \f[CR]--secure-boot-key-source=\f[R] Source of \f[CR]SecureBootKey=\f[R], to support OpenSSL engines. E.g.: \f[CR]--secure-boot-key-source=engine:pkcs11\f[R] .TP \f[CR]SecureBootCertificate=\f[R], \f[CR]--secure-boot-certificate=\f[R] Path to the X.509 file containing the certificate for the signed UEFI kernel image, if \f[CR]SecureBoot=\f[R] is used. .TP \f[CR]SecureBootSignTool=\f[R], \f[CR]--secure-boot-sign-tool\f[R] Tool to use to sign secure boot PE binaries. Takes one of \f[CR]sbsign\f[R], \f[CR]pesign\f[R] or \f[CR]auto\f[R]. Defaults to \f[CR]auto\f[R]. If set to \f[CR]auto\f[R], either sbsign or pesign are used if available, with sbsign being preferred if both are installed. .TP \f[CR]VerityKey=\f[R], \f[CR]--verity-key=\f[R] Path to the PEM file containing the secret key for signing the verity signature, if a verity signature partition is added with systemd-repart. When \f[CR]VerityKeySource=\f[R] is specified, the input type depends on the source. .TP \f[CR]VerityKeySource=\f[R], \f[CR]--verity-key-source=\f[R] Source of \f[CR]VerityKey=\f[R], to support OpenSSL engines. E.g.: \f[CR]--verity-key-source=engine:pkcs11\f[R] .TP \f[CR]VerityCertificate=\f[R], \f[CR]--verity-certificate=\f[R] Path to the X.509 file containing the certificate for signing the verity signature, if a verity signature partition is added with systemd-repart. .TP \f[CR]SignExpectedPcr=\f[R], \f[CR]--sign-expected-pcr\f[R] Measure the components of the unified kernel image (UKI) using \f[CR]systemd-measure\f[R] and embed the PCR signature into the unified kernel image. This option takes a boolean value or the special value \f[CR]auto\f[R], which is the default, which is equal to a true value if the \f[CR]systemd-measure\f[R] binary is in \f[CR]PATH\f[R]. Depends on \f[CR]SecureBoot=\f[R] being enabled and key from \f[CR]SecureBootKey=\f[R]. .TP \f[CR]Passphrase=\f[R], \f[CR]--passphrase\f[R] Specify the path to a file containing the passphrase to use for LUKS encryption. It should contain the passphrase literally, and not end in a newline character (i.e.\ in the same format as cryptsetup and \f[CR]/etc/crypttab\f[R] expect the passphrase files). The file must have an access mode of 0600 or less. .TP \f[CR]Checksum=\f[R], \f[CR]--checksum\f[R] Generate a \f[CR]SHA256SUMS\f[R] file of all generated artifacts after the build is complete. .TP \f[CR]Sign=\f[R], \f[CR]--sign\f[R] Sign the generated \f[CR]SHA256SUMS\f[R] using \f[CR]gpg\f[R] after completion. .TP \f[CR]Key=\f[R], \f[CR]--key=\f[R] Select the \f[CR]gpg\f[R] key to use for signing \f[CR]SHA256SUMS\f[R]. This key must be already present in the \f[CR]gpg\f[R] keyring. .SS [Host] Section .TP \f[CR]Incremental=\f[R], \f[CR]--incremental=\f[R], \f[CR]-i\f[R] Enable incremental build mode. In this mode, a copy of the OS image is created immediately after all OS packages are installed and the prepare scripts have executed but before the \f[CR]mkosi.build\f[R] scripts are invoked (or anything that happens after it). On subsequent invocations of \f[CR]mkosi\f[R] with the \f[CR]-i\f[R] switch this cached image may be used to skip the OS package installation, thus drastically speeding up repetitive build times. Note that while there is some rudimentary cache invalidation, it is definitely not perfect. In order to force rebuilding of the cached image, combine \f[CR]-i\f[R] with \f[CR]-ff\f[R] to ensure the cached image is first removed and then re-created. .TP \f[CR]NSpawnSettings=\f[R], \f[CR]--settings=\f[R] Specifies a \f[CR].nspawn\f[R] settings file for \f[CR]systemd-nspawn\f[R] to use in the \f[CR]boot\f[R] and \f[CR]shell\f[R] verbs, and to place next to the generated image file. This is useful to configure the \f[CR]systemd-nspawn\f[R] environment when the image is run. If this setting is not used but an \f[CR]mkosi.nspawn\f[R] file found in the local directory it is automatically used for this purpose. .TP \f[CR]ExtraSearchPaths=\f[R], \f[CR]--extra-search-path=\f[R] List of colon-separated paths to look for tools in, before using the regular \f[CR]$PATH\f[R] search path. .TP \f[CR]QemuGui=\f[R], \f[CR]--qemu-gui=\f[R] If enabled, qemu is executed with its graphical interface instead of with a serial console. .TP \f[CR]QemuSmp=\f[R], \f[CR]--qemu-smp=\f[R] When used with the \f[CR]qemu\f[R] verb, this options sets \f[CR]qemu\f[R]\[cq]s \f[CR]-smp\f[R] argument which controls the number of guest\[cq]s CPUs. Defaults to \f[CR]2\f[R]. .TP \f[CR]QemuMem=\f[R], \f[CR]--qemu-mem=\f[R] When used with the \f[CR]qemu\f[R] verb, this options sets \f[CR]qemu\f[R]\[cq]s \f[CR]-m\f[R] argument which controls the amount of guest\[cq]s RAM. Defaults to \f[CR]2G\f[R]. .TP \f[CR]QemuKvm=\f[R], \f[CR]--qemu-kvm=\f[R] When used with the \f[CR]qemu\f[R] verb, this option specifies whether QEMU should use KVM acceleration. Takes a boolean value or \f[CR]auto\f[R]. Defaults to \f[CR]auto\f[R]. .TP \f[CR]QemuVsock=\f[R], \f[CR]--qemu-vsock=\f[R] When used with the \f[CR]qemu\f[R] verb, this option specifies whether QEMU should be configured with a vsock. Takes a boolean value or \f[CR]auto\f[R]. Defaults to \f[CR]auto\f[R]. .TP \f[CR]QemuVsockConnectionId=\f[R], \f[CR]--qemu-vsock-cid=\f[R] When used with the \f[CR]qemu\f[R] verb, this option specifies the vsock connection ID to use. Takes a number in the interval \f[CR][3, 0xFFFFFFFF)\f[R] or \f[CR]hash\f[R] or \f[CR]auto\f[R]. Defaults to \f[CR]hash\f[R]. When set to \f[CR]hash\f[R], the connection ID will be derived from the full path to the image. When set to \f[CR]auto\f[R], \f[CR]mkosi\f[R] will try to find a free connection ID automatically. Otherwise, the provided number will be used as is. Note that when set to \f[CR]auto\f[R], \f[CR]mkosi ssh\f[R] cannot be used as we cannot figure out which free connection ID we found when booting the image earlier. .TP \f[CR]QemuSwtpm=\f[R], \f[CR]--qemu-swtpm=\f[R] When used with the \f[CR]qemu\f[R] verb, this option specifies whether to start an instance of swtpm to be used as a TPM with qemu. This requires swtpm to be installed on the host. Takes a boolean value or \f[CR]auto\f[R]. Defaults to \f[CR]auto\f[R]. .TP \f[CR]QemuCdrom=\f[R], \f[CR]--qemu-cdrom=\f[R] When used with the \f[CR]qemu\f[R] verb, this option specifies whether to attach the image to the virtual machine as a CD-ROM device. Takes a boolean. Defaults to \f[CR]no\f[R]. .TP \f[CR]QemuFirmware=\f[R], \f[CR]--qemu-firmware=\f[R] When used with the \f[CR]qemu\f[R] verb, this option specifies which firmware to use. Takes one of \f[CR]uefi\f[R], \f[CR]uefi-secure-boot\f[R], \f[CR]bios\f[R], \f[CR]linux\f[R], or \f[CR]auto\f[R]. Defaults to \f[CR]auto\f[R]. When set to \f[CR]uefi\f[R], the OVMF firmware without secure boot support is used. When set to \f[CR]uefi-secure-boot\f[R], the OVMF firmware with secure boot support is used. When set to \f[CR]bios\f[R], the default SeaBIOS firmware is used. When set to \f[CR]linux\f[R], direct kernel boot is used. See the \f[CR]QemuKernel=\f[R] option for more details on which kernel image is used with direct kernel boot. When set to \f[CR]auto\f[R], \f[CR]uefi-secure-boot\f[R] is used if possible and \f[CR]linux\f[R] otherwise. .TP \f[CR]QemuFirmwareVariables=\f[R], \f[CR]--qemu-firmware-variables=\f[R] When used with the \f[CR]qemu\f[R] verb, this option specifies the path to the the firmware variables file to use. Currently, this option is only taken into account when the \f[CR]uefi\f[R] or \f[CR]uefi-secure-boot\f[R] firmware is used. If not specified, mkosi will search for the default variables file and use that instead. When set to \f[CR]microsoft\f[R], a firmware variables file with the Microsoft secure boot certificates already enrolled will be used. When set to \f[CR]custom\f[R], the secure boot certificate from \f[CR]SecureBootCertificate=\f[R] will be enrolled into the default firmware variables file. \f[CR]virt-fw-vars\f[R] from the virt-firmware (https://gitlab.com/kraxel/virt-firmware) project can be used to customize OVMF variable files. .TP \f[CR]QemuKernel=\f[R], \f[CR]--qemu-kernel=\f[R] Set the kernel image to use for qemu direct kernel boot. If not specified, mkosi will use the kernel provided via the command line (\f[CR]-kernel\f[R] option) or latest the kernel that was installed into the image (or fail if no kernel was installed into the image). Note that when the \f[CR]cpio\f[R] output format is used, direct kernel boot is used regardless of the configured firmware. Depending on the configured firmware, qemu might boot the kernel itself or using the configured firmware. .TP \f[CR]QemuDrives=\f[R], \f[CR]--qemu-drive=\f[R] Add a qemu drive. Takes a colon-delimited string of format \f[CR]:[:[:]]\f[R]. \f[CR]id\f[R] specifies the qemu id we assign to the drive. This can be used as the \f[CR]drive=\f[R] property in various qemu devices. \f[CR]size\f[R] specifies the size of the drive. This takes a size in bytes. Additionally, the suffixes \f[CR]K\f[R], \f[CR]M\f[R] and \f[CR]G\f[R] can be used to specify a size in kilobytes, megabytes and gigabytes respectively. \f[CR]directory\f[R] optionally specifies the directory in which to create the file backing the drive. \f[CR]options\f[R] optionally specifies extra comma-delimited properties which are passed verbatim to qemu\[cq]s \f[CR]-drive\f[R] option. Example usage: .IP .EX [Host] QemuDrives=btrfs:10G ext4:20G QemuArgs=-device nvme,serial=btrfs,drive=btrfs -device nvme,serial=ext4,drive=ext4 .EE .TP \f[CR]QemuArgs=\f[R] Space-delimited list of additional arguments to pass when invoking qemu. .TP \f[CR]Ephemeral=\f[R], \f[CR]--ephemeral\f[R] When used with the \f[CR]shell\f[R], \f[CR]boot\f[R], or \f[CR]qemu\f[R] verbs, this option runs the specified verb on a temporary snapshot of the output image that is removed immediately when the container terminates. Taking the temporary snapshot is more efficient on file systems that support reflinks natively (btrfs or xfs) than on more traditional file systems that do not (ext4). .TP \f[CR]Credentials=\f[R], \f[CR]--credential=\f[R] Set credentials to be passed to systemd-nspawn or qemu respectively when \f[CR]mkosi shell/boot\f[R] or \f[CR]mkosi qemu\f[R] are used. This option takes a space separated list of key=value assignments. .TP \f[CR]KernelCommandLineExtra=\f[R], \f[CR]--kernel-command-line-extra=\f[R] Set extra kernel command line entries that are appended to the kernel command line at runtime when booting the image. When booting in a container, these are passed as extra arguments to systemd. When booting in a VM, these are appended to the kernel command line via the SMBIOS io.systemd.stub.kernel-cmdline-extra OEM string. This will only be picked up by systemd-boot/systemd-stub versions newer than or equal to v254. .TP \f[CR]Acl=\f[R], \f[CR]--acl=\f[R] If specified, ACLs will be set on any generated root filesystem directories that allow the user running mkosi to remove them without needing privileges. .TP \f[CR]ToolsTree=\f[R], \f[CR]--tools-tree=\f[R] If specified, programs executed by mkosi to build and boot an image are looked up inside the given tree instead of in the host system. Use this option to make image builds more reproducible by always using the same versions of programs to build the final image instead of whatever version is installed on the host system. If this option is not used, but the \f[CR]mkosi.tools/\f[R] directory is found in the local directory it is automatically used for this purpose with the root directory as target. Note that when looking up binaries in \f[CR]--tools-tree=\f[R], only \f[CR]/usr/bin\f[R] and \f[CR]/usr/sbin\f[R] are considered. Specifically, paths specified by \f[CR]--extra-search-path=\f[R] are ignored when looking up binaries in the given tools tree. If set to \f[CR]default\f[R], mkosi will automatically add an extra tools tree image and use it as the tools tree. The following table shows for which distributions default tools tree packages are defined and which packages are included in those default tools trees: .PP .TS tab(@); lw(24.0n) lw(7.7n) lw(7.7n) lw(7.7n) lw(7.7n) lw(5.8n) lw(9.6n). T{ T}@T{ Fedora T}@T{ CentOS T}@T{ Debian T}@T{ Ubuntu T}@T{ Arch T}@T{ openSUSE T} _ T{ \f[CR]acl\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]apt\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ T} T{ \f[CR]archlinux-keyring\f[R] T}@T{ X T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ T} T{ \f[CR]attr\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]bash\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]btrfs-progs\f[R] T}@T{ X T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]bubblewrap\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]ca-certificates\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]coreutils\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]cpio\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]curl\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]debian-keyring\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ T} T{ \f[CR]diffutils\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]distribution-gpg-keys\f[R] T}@T{ X T}@T{ X T}@T{ T}@T{ T}@T{ T}@T{ X T} T{ \f[CR]dnf\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]dnf-plugins-core\f[R] T}@T{ X T}@T{ X T}@T{ T}@T{ T}@T{ T}@T{ X T} T{ \f[CR]dnf5\f[R] T}@T{ X T}@T{ T}@T{ T}@T{ T}@T{ T}@T{ T} T{ \f[CR]dnf5-plugins\f[R] T}@T{ X T}@T{ T}@T{ T}@T{ T}@T{ T}@T{ T} T{ \f[CR]dosfstools\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]e2fsprogs\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]edk2-ovmf\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]erofs-utils\f[R] T}@T{ X T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]findutils\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]git\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]grep\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]jq\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]kmod\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]less\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]mtools\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]nano\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]openssh\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]openssl\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]sed\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]pacman\f[R] T}@T{ X T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ T} T{ \f[CR]pesign\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]policycoreutils\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ T}@T{ X T} T{ \f[CR]qemu\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]sbsigntools\f[R] T}@T{ X T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]socat\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]squashfs-tools\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]strace\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]swtpm\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]systemd\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]ukify\f[R] T}@T{ X T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]tar\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]ubuntu-keyring\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ T} T{ \f[CR]util-linux\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]virtiofsd\f[R] T}@T{ X T}@T{ X T}@T{ T}@T{ T}@T{ X T}@T{ X T} T{ \f[CR]virt-firmware\f[R] T}@T{ X T}@T{ X T}@T{ T}@T{ T}@T{ X T}@T{ T} T{ \f[CR]xfsprogs\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]xz\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]zstd\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]zypper\f[R] T}@T{ X T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ T} .TE .TP \f[CR]ToolsTreeDistribution=\f[R], \f[CR]--tools-tree-distribution=\f[R] Set the distribution to use for the default tools tree. By default, the same distribution as the image that\[cq]s being built is used, except for CentOS and Ubuntu images, in which case Fedora and Debian are used respectively. .TP \f[CR]ToolsTreeRelease=\f[R], \f[CR]--tools-tree-release=\f[R] Set the distribution release to use for the default tools tree. By default, the hardcoded default release in mkosi for the distribution is used. .TP \f[CR]ToolsTreeMirror=\f[R], \f[CR]--tools-tree-mirror=\f[R] Set the mirror to use for the default tools tree. By default, the default mirror for the tools tree distribution is used. .TP \f[CR]ToolsTreeRepositories=\f[R], \f[CR]--tools-tree-repository\f[R] Same as \f[CR]Repositories=\f[R] but for the default tools tree. .TP \f[CR]ToolsTreePackageManagerTrees=\f[R], \f[CR]--tools-tree-package-manager-tree=\f[R] Same as \f[CR]PackageManagerTrees=\f[R] but for the default tools tree. .TP \f[CR]ToolsTreePackages=\f[R], \f[CR]--tools-tree-packages=\f[R] Extra packages to install into the default tools tree. Takes a comma separated list of package specifications. This option may be used multiple times in which case the specified package lists are combined. .TP \f[CR]RuntimeTrees=\f[R], \f[CR]--runtime-tree=\f[R] Takes a colon separated pair of paths. The first path refers to a directory to mount into any machine (container or VM) started by mkosi. The second path refers to the target directory inside the machine. If the second path is not provided, the directory is mounted below \f[CR]/root/src\f[R] in the machine. If the second path is relative, it is interpreted relative to \f[CR]/root/src\f[R] in the machine. For each mounted directory, the uid and gid of the user running mkosi are mapped to the root user in the machine. This means that all the files and directories will appear as if they\[cq]re owned by root in the machine, and all new files and directories created by root in the machine in these directories will be owned by the user running mkosi on the host. Note that when using \f[CR]mkosi qemu\f[R] with this feature systemd v254 or newer has to be installed in the image. .TP \f[CR]RuntimeSize=\f[R], \f[CR]--runtime-size=\f[R] If specified, disk images are grown to the specified size before they\[cq]re booted with systemd-nspawn or qemu. Takes a size in bytes. Additionally, the suffixes \f[CR]K\f[R], \f[CR]M\f[R] and \f[CR]G\f[R] can be used to specify a size in kilobytes, megabytes and gigabytes respectively. .TP \f[CR]RuntimeScratch=\f[R]: \f[CR]--runtime-scratch=\f[R] Takes a boolean value or \f[CR]auto\f[R]. Specifies whether to mount extra scratch space to \f[CR]/var/tmp\f[R]. If enabled, practically unlimited scratch space is made available under \f[CR]/var/tmp\f[R] when booting the image with \f[CR]mkosi qemu\f[R], \f[CR]mkosi boot\f[R] or \f[CR]mkosi shell\f[R]. Note that using this feature with \f[CR]mkosi qemu\f[R] requires systemd v254 or newer in the guest. .TP \f[CR]RuntimeNetwork=\f[R]: \f[CR]--runtime-network=\f[R] Takes one of \f[CR]user\f[R], \f[CR]interface\f[R] or \f[CR]none\f[R]. Defaults to \f[CR]user\f[R]. Specifies the networking to set up when booting the image. \f[CR]user\f[R] sets up usermode networking. \f[CR]interface\f[R] sets up a virtual network connection between the host and the image. This translates to a veth interface for \f[CR]mkosi shell\f[R] and \f[CR]mkosi boot\f[R] and a tap interface for \f[CR]mkosi qemu\f[R] and \f[CR]mkosi vmspawn\f[R]. Note that when using \f[CR]interface\f[R], mkosi does not automatically configure the host interface. It is expected that a recent version of \f[CR]systemd-networkd\f[R] is running on the host which will automatically configure the host interface of the link. .TP \f[CR]SshKey=\f[R], \f[CR]--ssh-key=\f[R] Path to the X509 private key in PEM format to use to connect to a virtual machine started with \f[CR]mkosi qemu\f[R] and built with the \f[CR]Ssh=\f[R] option enabled via the \f[CR]mkosi ssh\f[R] command. If not configured and \f[CR]mkosi.key\f[R] exists in the working directory, it will automatically be used for this purpose. Run \f[CR]mkosi genkey\f[R] to automatically generate a key in \f[CR]mkosi.key\f[R]. .TP \f[CR]SshCertificate=\f[R], \f[CR]--ssh-certificate=\f[R] Path to the X509 certificate in PEM format to provision as the SSH public key in virtual machines started with \f[CR]mkosi qemu\f[R]. If not configured and \f[CR]mkosi.crt\f[R] exists in the working directory, it will automatically be used for this purpose. Run \f[CR]mkosi genkey\f[R] to automatically generate a certificate in \f[CR]mkosi.crt\f[R]. .SS Specifiers The current value of various settings can be accessed when parsing configuration files by using specifiers. To write a literal \f[CR]%\f[R] character in a configuration file without treating it as a specifier, use \f[CR]%%\f[R]. The following specifiers are understood: .PP .TS tab(@); l l. T{ Setting T}@T{ Specifier T} _ T{ \f[CR]Distribution=\f[R] T}@T{ \f[CR]%d\f[R] T} T{ \f[CR]Release=\f[R] T}@T{ \f[CR]%r\f[R] T} T{ \f[CR]Architecture=\f[R] T}@T{ \f[CR]%a\f[R] T} T{ \f[CR]Format=\f[R] T}@T{ \f[CR]%t\f[R] T} T{ \f[CR]Output=\f[R] T}@T{ \f[CR]%o\f[R] T} T{ \f[CR]OutputDirectory=\f[R] T}@T{ \f[CR]%O\f[R] T} T{ \f[CR]ImageId=\f[R] T}@T{ \f[CR]%i\f[R] T} T{ \f[CR]ImageVersion=\f[R] T}@T{ \f[CR]%v\f[R] T} .TE .SS Supported distributions Images may be created containing installations of the following distributions: .IP \[bu] 2 \f[I]Fedora Linux\f[R] .IP \[bu] 2 \f[I]Debian\f[R] .IP \[bu] 2 \f[I]Ubuntu\f[R] .IP \[bu] 2 \f[I]Arch Linux\f[R] .IP \[bu] 2 \f[I]openSUSE\f[R] .IP \[bu] 2 \f[I]Mageia\f[R] .IP \[bu] 2 \f[I]CentOS\f[R] .IP \[bu] 2 \f[I]RHEL\f[R] .IP \[bu] 2 \f[I]RHEL UBI\f[R] .IP \[bu] 2 \f[I]OpenMandriva\f[R] .IP \[bu] 2 \f[I]Rocky Linux\f[R] .IP \[bu] 2 \f[I]Alma Linux\f[R] .IP \[bu] 2 \f[I]None\f[R] (\f[B]Requires the user to provide a pre-built rootfs\f[R]) .PP In theory, any distribution may be used on the host for building images containing any other distribution, as long as the necessary tools are available. Specifically, any distribution that packages \f[CR]apt\f[R] may be used to build \f[I]Debian\f[R] or \f[I]Ubuntu\f[R] images. Any distribution that packages \f[CR]dnf\f[R] may be used to build images for any of the rpm-based distributions. Any distro that packages \f[CR]pacman\f[R] may be used to build \f[I]Arch Linux\f[R] images. Any distribution that packages \f[CR]zypper\f[R] may be used to build \f[I]openSUSE\f[R] images. Other distributions and build automation tools for embedded Linux systems such as Buildroot, OpenEmbedded and Yocto Project may be used by selecting the \f[CR]custom\f[R] distribution, and populating the rootfs via a combination of base trees, skeleton trees, and prepare scripts. .PP Currently, \f[I]Fedora Linux\f[R] packages all relevant tools as of Fedora 28. .PP Note that when not using a custom mirror, \f[CR]RHEL\f[R] images can only be built from a host system with a \f[CR]RHEL\f[R] subscription (established using e.g.\ \f[CR]subscription-manager\f[R]). .SH Execution Flow Execution flow for \f[CR]mkosi build\f[R]. Default values/calls are shown in parentheses. When building with \f[CR]--incremental\f[R] mkosi creates a cache of the distribution installation if not already existing and replaces the distribution installation in consecutive runs with data from the cached one. .IP "1." 3 Parse CLI options .IP "2." 3 Parse configuration files .IP "3." 3 If we\[cq]re not running as root, unshare the user namespace and map the subuid range configured in \f[CR]/etc/subuid\f[R] and \f[CR]/etc/subgid\f[R] into it. .IP "4." 3 Unshare the mount namespace .IP "5." 3 Remount the following directories read-only if they exist: .RS 4 .IP \[bu] 2 \f[CR]/usr\f[R] .IP \[bu] 2 \f[CR]/etc\f[R] .IP \[bu] 2 \f[CR]/opt\f[R] .IP \[bu] 2 \f[CR]/srv\f[R] .IP \[bu] 2 \f[CR]/boot\f[R] .IP \[bu] 2 \f[CR]/efi\f[R] .IP \[bu] 2 \f[CR]/media\f[R] .IP \[bu] 2 \f[CR]/mnt\f[R] .RE .PP Then, for each image, we execute the following steps: .IP " 1." 4 Copy package manager trees into the workspace .IP " 2." 4 Sync the package manager repository metadata .IP " 3." 4 Copy base trees (\f[CR]--base-tree=\f[R]) into the image .IP " 4." 4 Reuse a cached image if one is available .IP " 5." 4 Copy a snapshot of the package manager repository metadata into the image .IP " 6." 4 Copy skeleton trees (\f[CR]mkosi.skeleton\f[R]) into image .IP " 7." 4 Install distribution and packages into image .IP " 8." 4 Run prepare scripts on image with the \f[CR]final\f[R] argument (\f[CR]mkosi.prepare\f[R]) .IP " 9." 4 Install build packages in overlay if any build scripts are configured .IP "10." 4 Run prepare scripts on overlay with the \f[CR]build\f[R] argument if any build scripts are configured (\f[CR]mkosi.prepare\f[R]) .IP "11." 4 Cache the image if configured (\f[CR]--incremental\f[R]) .IP "12." 4 Run build scripts on image + overlay if any build scripts are configured (\f[CR]mkosi.build\f[R]) .IP "13." 4 Finalize the build if the output format \f[CR]none\f[R] is configured .IP "14." 4 Copy the build scripts outputs into the image .IP "15." 4 Copy the extra trees into the image (\f[CR]mkosi.extra\f[R]) .IP "16." 4 Run post-install scripts (\f[CR]mkosi.postinst\f[R]) .IP "17." 4 Write config files required for \f[CR]Ssh=\f[R], \f[CR]Autologin=\f[R] and \f[CR]MakeInitrd=\f[R] .IP "18." 4 Install systemd-boot and configure secure boot if configured (\f[CR]--secure-boot\f[R]) .IP "19." 4 Run \f[CR]systemd-sysusers\f[R] .IP "20." 4 Run \f[CR]systemd-tmpfiles\f[R] .IP "21." 4 Run \f[CR]systemctl preset-all\f[R] .IP "22." 4 Run \f[CR]depmod\f[R] .IP "23." 4 Run \f[CR]systemd-firstboot\f[R] .IP "24." 4 Run \f[CR]systemd-hwdb\f[R] .IP "25." 4 Remove packages and files (\f[CR]RemovePackages=\f[R], \f[CR]RemoveFiles=\f[R]) .IP "26." 4 Run SELinux relabel is a SELinux policy is installed .IP "27." 4 Run finalize scripts (\f[CR]mkosi.finalize\f[R]) .IP "28." 4 Generate unified kernel image if configured to do so .IP "29." 4 Generate final output format .SH Scripts To allow for image customization that cannot be implemented using mkosi\[cq]s builtin features, mkosi supports running scripts at various points during the image build process that can customize the image as needed. Scripts are executed on the host system as root (either real root or root within the user namespace that mkosi created when running unprivileged) with a customized environment to simplify modifying the image. For each script, the configured build sources (\f[CR]BuildSources=\f[R]) are mounted into the current working directory before running the script in the current working directory. \f[CR]$SRCDIR\f[R] is set to point to the current working directory. The following scripts are supported: .IP \[bu] 2 If \f[B]\f[CB]mkosi.sync\f[B]\f[R] (\f[CR]SyncScripts=\f[R]) exists, it is executed before the image is built. This script may be used to update various sources that are used to build the image. One use case is to run \f[CR]git pull\f[R] on various source repositories before building the image. Specifically, the \f[CR]BuildSourcesEphemeral=\f[R] setting does not apply to sync scripts, which means sync scripts can be used to update build sources even if \f[CR]BuildSourcesEphemeral=\f[R] is enabled. .IP \[bu] 2 If \f[B]\f[CB]mkosi.prepare\f[B]\f[R] (\f[CR]PrepareScripts=\f[R]) exists, it is first called with the \f[CR]final\f[R] argument, right after the software packages are installed. It is called a second time with the \f[CR]build\f[R] command line parameter, right after the build packages are installed and the build overlay mounted on top of the image\[cq]s root directory . This script has network access and may be used to install packages from other sources than the distro\[cq]s package manager (e.g.\ \f[CR]pip\f[R], \f[CR]npm\f[R], \&...), after all software packages are installed but before the image is cached (if incremental mode is enabled). In contrast to a general purpose installation, it is safe to install packages to the system (\f[CR]pip install\f[R], \f[CR]npm install -g\f[R]) instead of in \f[CR]$SRCDIR\f[R] itself because the build image is only used for a single project and can easily be thrown away and rebuilt so there\[cq]s no risk of conflicting dependencies and no risk of polluting the host system. .IP \[bu] 2 If \f[B]\f[CB]mkosi.build\f[B]\f[R] (\f[CR]BuildScripts=\f[R]) exists, it is executed with the build overlay mounted on top of the image\[cq]s root directory. When running the build script, \f[CR]$DESTDIR\f[R] points to a directory where the script should place any files generated it would like to end up in the image. Note that \f[CR]make\f[R]/\f[CR]automake\f[R]/\f[CR]meson\f[R] based build systems generally honor \f[CR]$DESTDIR\f[R], thus making it very natural to build \f[I]source\f[R] trees from the build script. After running the build script, the contents of \f[CR]$DESTDIR\f[R] are copied into the image. .IP \[bu] 2 If \f[B]\f[CB]mkosi.postinst\f[B]\f[R] (\f[CR]PostInstallationScripts=\f[R]) exists, it is executed after the (optional) build tree and extra trees have been installed. This script may be used to alter the images without any restrictions, after all software packages and built sources have been installed. .IP \[bu] 2 If \f[B]\f[CB]mkosi.finalize\f[B]\f[R] (\f[CR]FinalizeScripts=\f[R]) exists, it is executed as the last step of preparing an image. .PP If a script uses the \f[CR].chroot\f[R] extension, mkosi will chroot into the image using \f[CR]mkosi-chroot\f[R] (see below) before executing the script. For example, if \f[CR]mkosi.postinst.chroot\f[R] exists, mkosi will chroot into the image and execute it as the post-installation script. .PP Scripts executed by mkosi receive the following environment variables: .IP \[bu] 2 \f[CR]$ARCHITECTURE\f[R] contains the architecture from the \f[CR]Architecture=\f[R] setting. If \f[CR]Architecture=\f[R] is not set, it will contain the native architecture of the host machine. See the documentation of \f[CR]Architecture=\f[R] for possible values for this variable. .IP \[bu] 2 \f[CR]$DISTRIBUTION\f[R] contains the distribution from the \f[CR]Distribution=\f[R] setting. .IP \[bu] 2 \f[CR]$RELEASE\f[R] contains the release from the \f[CR]Release=\f[R] setting. .IP \[bu] 2 \f[CR]$PROFILE\f[R] contains the profile from the \f[CR]Profile=\f[R] setting. .IP \[bu] 2 \f[CR]$CACHED=\f[R] is set to \f[CR]1\f[R] if a cached image is available, \f[CR]0\f[R] otherwise. .IP \[bu] 2 \f[CR]$CHROOT_SCRIPT\f[R] contains the path to the running script relative to the image root directory. The primary usecase for this variable is in combination with the \f[CR]mkosi-chroot\f[R] script. See the description of \f[CR]mkosi-chroot\f[R] below for more information. .IP \[bu] 2 \f[CR]$SRCDIR\f[R] contains the path to the directory mkosi was invoked from, with any configured build sources mounted on top. \f[CR]$CHROOT_SRCDIR\f[R] contains the value that \f[CR]$SRCDIR\f[R] will have after invoking \f[CR]mkosi-chroot\f[R]. .IP \[bu] 2 \f[CR]$BUILDDIR\f[R] is only defined if \f[CR]mkosi.builddir\f[R] exists and points to the build directory to use. This is useful for all build systems that support out-of-tree builds to reuse already built artifacts from previous runs. \f[CR]$CHROOT_BUILDDIR\f[R] contains the value that \f[CR]$BUILDDIR\f[R] will have after invoking \f[CR]mkosi-chroot\f[R]. .IP \[bu] 2 \f[CR]$DESTDIR\f[R] is a directory into which any installed software generated by a build script may be placed. This variable is only set when executing a build script. \f[CR]$CHROOT_DESTDIR\f[R] contains the value that \f[CR]$DESTDIR\f[R] will have after invoking \f[CR]mkosi-chroot\f[R]. .IP \[bu] 2 \f[CR]$OUTPUTDIR\f[R] points to the staging directory used to store build artifacts generated during the build. \f[CR]$CHROOT_OUTPUTDIR\f[R] contains the value that \f[CR]$OUTPUTDIR\f[R] will have after invoking \f[CR]mkosi-chroot\f[R]. .IP \[bu] 2 \f[CR]$PACKAGEDIR\f[R] points to the directory containing the local package repository. Build scripts can add more packages to the local repository by writing the packages to \f[CR]$PACKAGEDIR\f[R]. .IP \[bu] 2 \f[CR]$BUILDROOT\f[R] is the root directory of the image being built, optionally with the build overlay mounted on top depending on the script that\[cq]s being executed. .IP \[bu] 2 \f[CR]$WITH_DOCS\f[R] is either \f[CR]0\f[R] or \f[CR]1\f[R] depending on whether a build without or with installed documentation was requested (\f[CR]WithDocs=yes\f[R]). A build script should suppress installation of any package documentation to \f[CR]$DESTDIR\f[R] in case \f[CR]$WITH_DOCS\f[R] is set to \f[CR]0\f[R]. .IP \[bu] 2 \f[CR]$WITH_TESTS\f[R] is either \f[CR]0\f[R] or \f[CR]1\f[R] depending on whether a build without or with running the test suite was requested (\f[CR]WithTests=no\f[R]). A build script should avoid running any unit or integration tests in case \f[CR]$WITH_TESTS\f[R] is \f[CR]0\f[R]. .IP \[bu] 2 \f[CR]$WITH_NETWORK\f[R] is either \f[CR]0\f[R] or \f[CR]1\f[R] depending on whether a build without or with networking is being executed (\f[CR]WithNetwork=no\f[R]). A build script should avoid any network communication in case \f[CR]$WITH_NETWORK\f[R] is \f[CR]0\f[R]. .IP \[bu] 2 \f[CR]$SOURCE_DATE_EPOCH\f[R] is defined if requested (\f[CR]SourceDateEpoch=TIMESTAMP\f[R], \f[CR]Environment=SOURCE_DATE_EPOCH=TIMESTAMP\f[R] or the host environment variable \f[CR]$SOURCE_DATE_EPOCH\f[R]). This is useful to make builds reproducible. See SOURCE_DATE_EPOCH (https://reproducible-builds.org/specs/source-date-epoch/) for more information. .IP \[bu] 2 \f[CR]$MKOSI_UID\f[R] and \f[CR]$MKOSI_GID\f[R] are the respectively the uid, gid of the user that invoked mkosi, potentially translated to a uid in the user namespace that mkosi is running in. These can be used in combination with \f[CR]setpriv\f[R] to run commands as the user that invoked mkosi (e.g. \f[CR]setpriv --reuid=$MKOSI_UID --regid=$MKOSI_GID --clear-groups \f[R]) .IP \[bu] 2 \f[CR]$MKOSI_CONFIG\f[R] is a file containing a json summary of the settings of the current image. This file can be parsed inside scripts to gain access to all settings for the current image. .PP Consult this table for which script receives which environment variables: .PP .TS tab(@); lw(14.3n) lw(9.5n) lw(11.6n) lw(10.2n) lw(12.2n) lw(12.2n). T{ Variable T}@T{ \f[CR]mkosi.sync\f[R] T}@T{ \f[CR]mkosi.prepare\f[R] T}@T{ \f[CR]mkosi.build\f[R] T}@T{ \f[CR]mkosi.postinst\f[R] T}@T{ \f[CR]mkosi.finalize\f[R] T} _ T{ \f[CR]ARCHITECTURE\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]DISTRIBUTION\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]RELEASE\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]PROFILE\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]CACHED\f[R] T}@T{ X T}@T{ T}@T{ T}@T{ T}@T{ T} T{ \f[CR]CHROOT_SCRIPT\f[R] T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]SRCDIR\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]CHROOT_SRCDIR\f[R] T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]BUILDDIR\f[R] T}@T{ T}@T{ T}@T{ X T}@T{ T}@T{ T} T{ \f[CR]CHROOT_BUILDDIR\f[R] T}@T{ T}@T{ T}@T{ X T}@T{ T}@T{ T} T{ \f[CR]DESTDIR\f[R] T}@T{ T}@T{ T}@T{ X T}@T{ T}@T{ T} T{ \f[CR]CHROOT_DESTDIR\f[R] T}@T{ T}@T{ T}@T{ X T}@T{ T}@T{ T} T{ \f[CR]OUTPUTDIR\f[R] T}@T{ T}@T{ T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]CHROOT_OUTPUTDIR\f[R] T}@T{ T}@T{ T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]BUILDROOT\f[R] T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]WITH_DOCS\f[R] T}@T{ T}@T{ X T}@T{ X T}@T{ T}@T{ T} T{ \f[CR]WITH_TESTS\f[R] T}@T{ T}@T{ X T}@T{ X T}@T{ T}@T{ T} T{ \f[CR]WITH_NETWORK\f[R] T}@T{ T}@T{ X T}@T{ X T}@T{ T}@T{ T} T{ \f[CR]SOURCE_DATE_EPOCH\f[R] T}@T{ T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]MKOSI_UID\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]MKOSI_GID\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} T{ \f[CR]MKOSI_CONFIG\f[R] T}@T{ X T}@T{ X T}@T{ X T}@T{ X T}@T{ X T} .TE .PP Additionally, when a script is executed, a few scripts are made available via \f[CR]$PATH\f[R] to simplify common usecases. .IP \[bu] 2 \f[CR]mkosi-chroot\f[R]: This script will chroot into the image and execute the given command. On top of chrooting into the image, it will also mount various files and directories (\f[CR]$SRCDIR\f[R], \f[CR]$DESTDIR\f[R], \f[CR]$BUILDDIR\f[R], \f[CR]$OUTPUTDIR\f[R], \f[CR]$CHROOT_SCRIPT\f[R]) into the image and modify the corresponding environment variables to point to the locations inside the image. It will also mount APIVFS filesystems (\f[CR]/proc\f[R], \f[CR]/dev\f[R], \&...) to make sure scripts and tools executed inside the chroot work properly. It also propagates \f[CR]/etc/resolv.conf\f[R] from the host into the chroot if requested so that DNS resolution works inside the chroot. After the mkosi-chroot command exits, various mount points are cleaned up. .RS 2 .PP For example, to invoke \f[CR]ls\f[R] inside of the image, use the following .IP .EX mkosi-chroot ls ... .EE .PP To execute the entire script inside the image, add a \[lq].chroot\[rq] suffix to the name (\f[CR]mkosi.build.chroot\f[R] instead of \f[CR]mkosi.build\f[R], etc.). .RE .IP \[bu] 2 For all of the supported package managers except portage (\f[CR]dnf\f[R], \f[CR]rpm\f[R], \f[CR]apt\f[R], \f[CR]pacman\f[R], \f[CR]zypper\f[R]), scripts of the same name are put into \f[CR]$PATH\f[R] that make sure these commands operate on the image\[cq]s root directory with the configuration supplied by the user instead of on the host system. This means that from a script, you can do e.g.\ \f[CR]dnf install vim\f[R] to install vim into the image. .RS 2 .PP Additionally, \f[CR]mkosi-install\f[R], \f[CR]mkosi-reinstall\f[R], \f[CR]mkosi-upgrade\f[R] and \f[CR]mkosi-remove\f[R] will invoke the corresponding operation of the package manager being used to built the image. .RE .IP \[bu] 2 \f[CR]mkosi-as-caller\f[R]: This script uses \f[CR]setpriv\f[R] to switch from the user \f[CR]root\f[R] in the user namespace used for various build steps back to the original user that called mkosi. This is useful when we want to invoke build steps which will write to \f[CR]$BUILDDIR\f[R] and we want to have the files owned by the calling user. .RS 2 .PP For example, a complete \f[CR]mkosi.build\f[R] script might be the following: .IP .EX set -ex mkosi-as-caller meson setup \[dq]$BUILDDIR/build\[dq] \[dq]$SRCDIR\[dq] mkosi-as-caller meson compile -C \[dq]$BUILDDIR/build\[dq] meson install -C \[dq]$BUILDDIR/build\[dq] --no-rebuild .EE .RE .IP \[bu] 2 \f[CR]git\f[R] is automatically invoked with \f[CR]safe.directory=*\f[R] to avoid permissions errors when running as the root user in a user namespace. .IP \[bu] 2 \f[CR]useradd\f[R] and \f[CR]groupadd\f[R] are automatically invoked with \f[CR]--root=$BUILDROOT\f[R] when executed outside of the image. .PP When scripts are executed, any directories that are still writable are also made read-only (\f[CR]/home\f[R], \f[CR]/var\f[R], \f[CR]/root\f[R], \&...) and only the minimal set of directories that need to be writable remain writable. This is to ensure that scripts can\[cq]t mess with the host system when mkosi is running as root. .PP Note that when executing scripts, all source directories are made ephemeral which means all changes made to source directories while running scripts are thrown away after the scripts finish executing. Use the output, build or cache directories if you need to persist data between builds. .SH Files To make it easy to build images for development versions of your projects, mkosi can read configuration data from the local directory, under the assumption that it is invoked from a \f[I]source\f[R] tree. Specifically, the following files are used if they exist in the local directory: .IP \[bu] 2 The \f[B]\f[CB]mkosi.skeleton/\f[B]\f[R] directory or \f[B]\f[CB]mkosi.skeleton.tar\f[B]\f[R] archive may be used to insert files into the image. The files are copied \f[I]before\f[R] the distribution packages are installed into the image. This allows creation of files that need to be provided early, for example to configure the package manager or set systemd presets. .RS 2 .PP When using the directory, file ownership is not preserved: all files copied will be owned by root. To preserve ownership, use a tar archive. .RE .IP \[bu] 2 The \f[B]\f[CB]mkosi.extra/\f[B]\f[R] directory or \f[B]\f[CB]mkosi.extra.tar\f[B]\f[R] archive may be used to insert additional files into the image, on top of what the distribution includes in its packages. They are similar to \f[CR]mkosi.skeleton/\f[R] and \f[CR]mkosi.skeleton.tar\f[R], but the files are copied into the directory tree of the image \f[I]after\f[R] the OS was installed. .RS 2 .PP When using the directory, file ownership is not preserved: all files copied will be owned by root. To preserve ownership, use a tar archive. .RE .IP \[bu] 2 The \f[B]\f[CB]mkosi.nspawn\f[B]\f[R] nspawn settings file will be copied into the same place as the output image file, if it exists. This is useful since nspawn looks for settings files next to image files it boots, for additional container runtime settings. .IP \[bu] 2 The \f[B]\f[CB]mkosi.cache/\f[B]\f[R] directory, if it exists, is automatically used as package download cache, in order to speed repeated runs of the tool. .IP \[bu] 2 The \f[B]\f[CB]mkosi.builddir/\f[B]\f[R] directory, if it exists, is automatically used as out-of-tree build directory, if the build commands in the \f[CR]mkosi.build\f[R] scripts support it. Specifically, this directory will be mounted into the build container, and the \f[CR]$BUILDDIR\f[R] environment variable will be set to it when the build scripts are invoked. A build script may then use this directory as build directory, for automake-style or ninja-style out-of-tree builds. This speeds up builds considerably, in particular when \f[CR]mkosi\f[R] is used in incremental mode (\f[CR]-i\f[R]): not only the image and build overlay, but also the build tree is reused between subsequent invocations. Note that if this directory does not exist the \f[CR]$BUILDDIR\f[R] environment variable is not set, and it is up to the build scripts to decide whether to do in in-tree or an out-of-tree build, and which build directory to use. .IP \[bu] 2 The \f[B]\f[CB]mkosi.rootpw\f[B]\f[R] file can be used to provide the password for the root user of the image. If the password is prefixed with \f[CR]hashed:\f[R] it is treated as an already hashed root password. The password may optionally be followed by a newline character which is implicitly removed. The file must have an access mode of 0600 or less. If this file does not exist, the distribution\[cq]s default root password is set (which usually means access to the root user is blocked). .IP \[bu] 2 The \f[B]\f[CB]mkosi.passphrase\f[B]\f[R] file provides the passphrase to use when LUKS encryption is selected. It should contain the passphrase literally, and not end in a newline character (i.e.\ in the same format as cryptsetup and \f[CR]/etc/crypttab\f[R] expect the passphrase files). The file must have an access mode of 0600 or less. .IP \[bu] 2 The \f[B]\f[CB]mkosi.crt\f[B]\f[R] and \f[B]\f[CB]mkosi.key\f[B]\f[R] files contain an X.509 certificate and PEM private key to use when signing is required (UEFI SecureBoot, verity, \&...). .IP \[bu] 2 The \f[B]\f[CB]mkosi.output/\f[B]\f[R] directory is used to store all build artifacts. .IP \[bu] 2 The \f[B]\f[CB]mkosi.credentials/\f[B]\f[R] directory is used as a source of extra credentials similar to the \f[CR]Credentials=\f[R] option. For each file in the directory, the filename will be used as the credential name and the file contents become the credential value, or, if the file is executable, mkosi will execute the file and the command\[cq]s output to stdout will be used as the credential value. Output to stderr will be ignored. Credentials configured with \f[CR]Credentials=\f[R] take precedence over files in \f[CR]mkosi.credentials\f[R]. .IP \[bu] 2 The \f[B]\f[CB]mkosi.repart/\f[B]\f[R] directory is used as the source for systemd-repart partition definition files which are passed to systemd-repart when building a disk image. If it does not exist and the \f[CR]RepartDirectories=\f[R] setting is not configured, mkosi will default to the following partition definition files: .RS 2 .PP \f[CR]00-esp.conf\f[R] (if we\[cq]re building a bootable image): .IP .EX [Partition] Type=esp Format=vfat CopyFiles=/boot:/ CopyFiles=/efi:/ SizeMinBytes=512M SizeMaxBytes=512M .EE .PP \f[CR]05-bios.conf\f[R] (if we\[cq]re building a BIOS bootable image): .IP .EX [Partition] # UUID of the grub BIOS boot partition which grubs needs on GPT to # embed itself into. Type=21686148-6449-6e6f-744e-656564454649 SizeMinBytes=1M SizeMaxBytes=1M .EE .PP \f[CR]10-root.conf\f[R]: .IP .EX [Partition] Type=root Format= CopyFiles=/ Minimize=guess .EE .PP Note that if either \f[CR]mkosi.repart/\f[R] is found or \f[CR]RepartDirectories=\f[R] is used, we will not use any of the default partition definitions. .RE .PP All these files are optional. .PP Note that the location of all these files may also be configured during invocation via command line switches, and as settings in \f[CR]mkosi.conf\f[R], in case the default settings are not acceptable for a project. .SH CACHING \f[CR]mkosi\f[R] supports three different caches for speeding up repetitive re-building of images. Specifically: .IP "1." 3 The package cache of the distribution package manager may be cached between builds. This is configured with the \f[CR]--cache-dir=\f[R] option or the \f[CR]mkosi.cache/\f[R] directory. This form of caching relies on the distribution\[cq]s package manager, and caches distribution packages (RPM, DEB, \&...) after they are downloaded, but before they are unpacked. .IP "2." 3 If the incremental build mode is enabled with \f[CR]--incremental\f[R], cached copies of the final image and build overlay are made immediately before the build sources are copied in (for the build overlay) or the artifacts generated by \f[CR]mkosi.build\f[R] are copied in (in case of the final image). This form of caching allows bypassing the time-consuming package unpacking step of the distribution package managers, but is only effective if the list of packages to use remains stable, but the build sources and its scripts change regularly. Note that this cache requires manual flushing: whenever the package list is modified the cached images need to be explicitly removed before the next re-build, using the \f[CR]-f\f[R] switch. .IP "3." 3 Finally, between multiple builds the build artifact directory may be shared, using the \f[CR]mkosi.builddir/\f[R] directory. This directory allows build systems such as Meson to reuse already compiled sources from a previous built, thus speeding up the build process of a \f[CR]mkosi.build\f[R] build script. .PP The package cache and incremental mode are unconditionally useful. The final cache only apply to uses of \f[CR]mkosi\f[R] with a source tree and build script. When all three are enabled together turn-around times for complete image builds are minimal, as only changed source files need to be recompiled. .SH Building multiple images If the \f[CR]mkosi.images/\f[R] directory exists, mkosi will load individual image configurations from it and build each of them. Image configurations can be either directories containing mkosi configuration files or regular files with the \f[CR].conf\f[R] extension. .PP When image configurations are found in \f[CR]mkosi.images/\f[R], mkosi will build the configured images and all of their dependencies (or all of them if no images were explicitly configured using \f[CR]Images=\f[R]). To add dependencies between images, the \f[CR]Dependencies=\f[R] setting can be used. .PP When images are defined, mkosi will first read the global configuration (configuration outside of the \f[CR]mkosi.images/\f[R] directory), followed by the image specific configuration. This means that global configuration takes precedence over image specific configuration. .PP Images can refer to outputs of images they depend on. Specifically, for the following options, mkosi will only check whether the inputs exist just before building the image: .IP \[bu] 2 \f[CR]BaseTrees=\f[R] .IP \[bu] 2 \f[CR]PackageManagerTrees=\f[R] .IP \[bu] 2 \f[CR]SkeletonTrees=\f[R] .IP \[bu] 2 \f[CR]ExtraTrees=\f[R] .IP \[bu] 2 \f[CR]ToolsTree=\f[R] .IP \[bu] 2 \f[CR]Initrds=\f[R] .PP To refer to outputs of a image\[cq]s dependencies, simply configure any of these options with a relative path to the output to use in the output directory of the dependency. Or use the \f[CR]%O\f[R] specifier to refer to the output directory. .PP A good example on how to build multiple images can be found in the systemd (https://github.com/systemd/systemd/tree/main/mkosi.images) repository. .SH ENVIRONMENT VARIABLES .IP \[bu] 2 \f[CR]$MKOSI_LESS\f[R] overrides options for \f[CR]less\f[R] when it is invoked by \f[CR]mkosi\f[R] to page output. .IP \[bu] 2 \f[CR]$MKOSI_DNF\f[R] can be used to override the executable used as \f[CR]dnf\f[R]. This is particularly useful to select between \f[CR]dnf\f[R] and \f[CR]dnf5\f[R]. .SH EXAMPLES Create and run a raw \f[I]GPT\f[R] image with \f[I]ext4\f[R], as \f[CR]image.raw\f[R]: .IP .EX # mkosi -p systemd --incremental boot .EE .PP Create and run a bootable \f[I]GPT\f[R] image, as \f[CR]foobar.raw\f[R]: .IP .EX $ mkosi -d fedora -p kernel-core -p systemd -p systemd-boot -p udev -o foobar.raw # mkosi --output foobar.raw boot $ mkosi --output foobar.raw qemu .EE .PP Create and run a \f[I]Fedora Linux\f[R] image in a plain directory: .IP .EX # mkosi --distribution fedora --format directory boot .EE .PP Create a compressed image \f[CR]image.raw.xz\f[R] with \f[I]SSH\f[R] installed and add a checksum file: .IP .EX $ mkosi --distribution fedora --format disk --checksum --compress-output --package=openssh-clients .EE .PP Inside the source directory of an \f[CR]automake\f[R]-based project, configure \f[I]mkosi\f[R] so that simply invoking \f[CR]mkosi\f[R] without any parameters builds an OS image containing a built version of the project in its current state: .IP .EX $ cat >mkosi.conf <mkosi.build <