% mkosi(1) % The mkosi Authors % 2016- # NAME mkosi — Build Legacy-Free OS Images # SYNOPSIS `mkosi [options…] build` `mkosi [options…] clean` `mkosi [options…] summary` `mkosi [options…] shell [command line…]` `mkosi [options…] boot [command line…]` `mkosi [options…] qemu` # DESCRIPTION `mkosi` is a tool for easily building legacy-free OS images. It's a fancy wrapper around `dnf --installroot`, `debootstrap`, `pacstrap` and `zypper` that may generate disk images with a number of bells and whistles. ## Supported output formats The following output formats are supported: * Raw *GPT* disk image, with ext4 as root (*gpt_ext4*) * Raw *GPT* disk image, with xfs as root (*gpt_xfs*) * Raw *GPT* disk image, with btrfs as root (*gpt_btrfs*) * Raw *GPT* disk image, with squashfs as read-only root (*gpt_squashfs*) * Plain squashfs image, without partition table, as read-only root (*plain_squashfs*) * Plain directory, containing the *OS* tree (*directory*) * btrfs subvolume, with separate subvolumes for `/var`, `/home`, `/srv`, `/var/tmp` (*subvolume*) * Tarball (*tar*) When a *GPT* disk image is created, the following additional options are available: * A swap partition may be added in * The image may be made bootable on *EFI* and *BIOS* systems * Separate partitions for `/srv` and `/home` may be added in * The root, /srv and /home partitions may optionally be encrypted with LUKS. * A dm-verity partition may be added in that adds runtime integrity data for the root partition ## Other features * Optionally, create an *SHA256SUMS* checksum file for the result, possibly even signed via `gpg`. * Optionally, place a specific `.nspawn` settings file along with the result. * Optionally, build a local project's *source* tree in the image and add the result to the generated image (see below). * Optionally, share *RPM*/*DEB* package cache between multiple runs, in order to optimize build speeds. * Optionally, the resulting image may be compressed with *XZ*. * Optionally, the resulting image may be converted into a *QCOW2* file suitable for `qemu` storage. * Optionally, btrfs' read-only flag for the root subvolume may be set. * Optionally, btrfs' compression may be enabled for all created subvolumes. * By default images are created without all files marked as documentation in the packages, on distributions where the package manager supports this. Use the `--with-docs` flag to build an image with docs added. ## Command Line Verbs The following command line verbs are known: `build` : This builds the image, based on the settings passed in on the command line or read from a `mkosi.default` file, see below. This verb is the default if no verb is explicitly specified. This command must be executed as `root`. `clean` : Remove build artifacts generated on a previous build. If combined with `-f`, also removes incremental build cache images. If `-f` is specified twice, also removes any package cache. `summary` : Outputs a human-readable summary of all options used for building an image. This will parse the command line and `mkosi.default` file as it would do on `build`, but only output what it is configured for and not actually build anything.` `shell` : This builds the image if it is not build yet, and then invokes `systemd-nspawn` to acquire an interactive shell prompt in it. If this verb is used an optional command line may be specified which is then invoked in place of the shell in the container. Combine this with `-f` in order to rebuild the image unconditionally before acquiring the shell, see below. This command must be executed as `root`. `boot` : Similar to `shell` but boots the image up using `systemd-nspawn`. If this verb is used an optional command line may be specified which is passed as "kernel command line" to the init system in the image. `qemu` : Similar to `boot` but uses `qemu` to boot up the image, i.e. instead of container virtualization VM virtualization is used. This verb is only supported on images that contain a boot loader, i.e. those built with `--bootable` (see below). This command must be executed as `root` unless the image already exists and `-f` is not specified. `help` : This verb is equivalent to the `--help` switch documented below: it shows a brief usage explanation. ## Command Line Parameters The following command line parameters are understood. Note that many of these parameters can also be set in the `mkosi.default` file, for details see the table below. `--distribution=`, `-d` : The distribution to install in the image. Takes one of the following arguments: `fedora`, `debian`, `ubuntu`, `arch`, `opensuse`, `mageia`, `centos`, `clear`. If not specified, defaults to the distribution of the host. `--release=`, `-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, CentOS, …, e.g. `29`), or a distribution version name (in case of Debian, Ubuntu, …, e.g. `artful`). If neither this option, not `--distribution=` is specified, defaults to the distribution version of the host. If the distribution is specified, defaults to a recent version of it. `--mirror=`, `-m` : The mirror to use for downloading the distribution packages. Expects a mirror URL as argument. `--repositories=` : Additional package repositories to use during installation. Expects one or more URLs as argument, separated by commas. This option may be used multiple times, in which case the list of repositories to use is combined. `--architecture=` : The architecture to build the image for. Note that this currently only works for architectures compatible with the host's architecture. `--format=`, `-t` : The image format type to generate. One of `directory` (for generating OS images inside a local directory), `subvolume` (similar, but as a btrfs subvolume), `tar` (similar, but a tarball of the image is generated), `gpt_ext4` (a block device image with an ext4 file system inside a GPT partition table), `gpt_xfs` (similar, but with an xfs file system), `gpt_btrfs` (similar, but with an btrfs file system), `gpt_squashfs` (similar, but with a squashfs file system), `plain_squashfs` (a plain squashfs file system without a partition table). `--output=`, `-o` : Path for the output image file to generate. Takes a relative or absolute path where the generated image will be placed. If neither this option nor `--output-dir=` is used (see below), the image is generated under the name `image`, but its name suffixed with an appropriate file suffix (e.g. `image.raw.xz` in case `gpt_ext4` is used in combination with `--xz`). `--output-dir=`, `-O` : Path to a directory where to place all generated artifacts (i.e. the `SHA256SUMS` file and similar). If this is not specified and a directory `mkosi.output/` exists in the local directory it is automatically used for this purpose. If this is not specified and such a directory does not exist, all output artifacts are placed adjacent to the output image file. `--force`, `-f` : Replace the output file if it already exists, when building an image. By default when building an image and an output artifact already exists `mkosi` will refuse operation. Specify `-f` to delete all build artifacts from a previous run before re-building the image. If incremental builds are enabled (see below), 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 (see below), specifying this option thrice will ensure the package cache is removed too, before the re-build is initiated. For the `clean` operation `-f` 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. `--bootable`, `-b` : Generate a bootable image. By default this will generate an image bootable on UEFI systems. Use `--boot-protocols=` to select support for a different boot protocol. `--boot-protocols=` : Pick one or more boot protocols to support when generating a bootable image, as enabled with `--bootable` above. Takes a comma-separated list of `uefi` or `bios`. May be specified more than once in which case the specified lists are merged. If `uefi` is specified the `sd-boot` UEFI boot loader is used, if `bios` is specified the GNU Grub boot loader is used. `--kernel-command-line=` : Use the specified kernel command line for when building bootable images. `--secure-boot` : Sign the resulting kernel/initrd image for UEFI SecureBoot `--secure-boot-key=` : Path to the PEM file containing the secret key for signing the UEFI kernel image, if `--secure-boot` is used. `--secure-boot-certificate=` : Path to the X.509 file containing the certificate for the signed UEFI kernel image, if `--secure-boot` is used. `--read-only` : Make root file system read-only. Only applies to `gpt_ext4`, `gpt_xfs`, `gpt-btrfs`, `subvolume` output formats, and implied on `gpt_squashfs` and `plain_squashfs`. `--encrypt` : Encrypt all partitions in the file system or just the root file system. Takes either `all` or `data` as argument. If `all` the root, `/home` and `/srv` file systems will be encrypted using dm-crypt/LUKS (with its default settings). If `data` the root file system will be left unencrypted, but `/home` and `/srv` will be encrypted. The passphrase to use is read from the `mkosi.passphrase` file in the current working directory (see below). Note that the UEFI System Partition (ESP) containing the boot loader and kernel to boot is never encrypted since it needs to be accessible by the firmware. `--verity` : Add an "Verity" integrity partition to the image. If enabled, the root partition is protected with `dm-verity` against off-line modification, the verification data is placed in an additional GPT partition. Implies `--read-only`. `--compress=` : Compress the generated file systems. Only applies to `gpt_btrfs`, `subvolume`, `gpt_squashfs`, `plain_squashfs`. Takes one of `zlib`, `lzo`, `zstd`, `lz4`, `xz` or a boolean value as argument. If the latter is used compression is enabled/disabled and the default algorithm is used. In case of the `squashfs` output formats compression is implied, however this option may be used to select the algorithm. `--mksquashfs=` : Set the path to the `mksquashfs` executable to use. This is useful in case the parameters for the tool shall be augmented, as the tool may be replaced by a script invoking it with the right parameters, this way. `--xz` : Compress the resulting image with `xz`. This only applies to `gpt_ext4`, `gpt_xfs`, `gpt_btrfs`, `gpt_squashfs` and is implied for `tar`. Note that when applied to the block device image types this means the image cannot be started directly but needs to be decompressed first. This also means that the `shell`, `boot`, `qemu` verbs are not available when this option is used. `--qcow2` : Encode the resulting image as QEMU QCOW2 image. This only applies to `gpt_ext4`, `gpt_xfs`, `gpt_btrfs`, `gpt_squashfs`. QCOW2 images can be read natively by `qemu`, but not by the Linux kernel. This means the `shell` and `boot` verbs are not available when this option is used, however `qemu` will work. `--hostname=` : Set the image's hostname to the specified name. `--no-chown` : By default, if `mkosi` is run inside a `sudo` environment all generated artifacts have their UNIX user/group ownership changed to the user which invoked `sudo`. With this option this may be turned off and all generated files are owned by `root`. `--incremental`, `-i` : Enable incremental build mode. This only applies if the two-phase `mkosi.build` build script logic is used. In this mode, a copy of the OS image is created immediately after all OS packages are unpacked but before the `mkosi.build` script is invoked in the development container. Similar a copy of the final image is created immediately before the build artifacts from the `mkosi.build` script are copied in. On subsequent invocations of `mkosi` with the `-i` switch these cached images may be used to skip the OS package unpacking, thus drastically speeding up repetitive build times. Note that when this is used and a pair of cached incremental images exists they are not automatically regenerated, even if options such as `--packages=` are modified. In order to force rebuilding of these cached images, combined `-i` with `-ff`, which ensures the cached images are removed first, and then re-created. `--package=`, `-p` : Install the specified distribution packages (i.e. RPM, DEB, …) in the image. Takes a comma separated list of packages. This option may be used multiple times in which case the specified package list is combined. Packaged specified this way will be installed both in the development and the final image (see below). Use `--build-package=` (see below) to specify packages that shall only be used for the image generated in the build image, but that shall not appear in the final image. `--with-docs` : Include documentation in the image built. By default if the underlying distribution package manager supports it documentation is not included in the image built. The `$WITH_DOCS` environment variable passed to the `mkosi.build` script indicates whether this option was used or not, see below. `--without-tests`, `-T` : If set the `$WITH_TESTS` environment variable is set to `0` when the `mkosi.build` script is invoked. This is supposed to be used by the build script 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 `mkosi.build` build script honors it. `--cache=` : Takes a path to a directory to use as package cache for the distribution package manager used. If this option is not used, but a `mkosi.cache/` directory is found in the local directory it is automatically used for this purpose (also see below). The directory configured this way is mounted into both the development and the final image while the package manager is running. `--extra-tree=` : Takes a path to a directory to copy on top of the OS tree the package manager generated. Use this to override any default configuration files shipped with the distribution. If this option is not used, but the `mkosi.extra/` directory is found in the local directory it is automatically used for this purpose (also see below). Instead of a directory a `tar` file may be specified too. In this case it is unpacked into the OS tree before the package manager is invoked. This mode of operation allows setting permissions and file ownership explicitly, in particular for projects stored in a version control system such as `git` which does retain full file ownership and access mode metadata for committed files. If a tar file `mkosi.extra.tar` is found in the local directory it automatically used for this purpose. `--skeleton-tree=` : Takes a path to a directory to copy into the OS tree before invoking the package manager. Use this to insert files and directories into the OS tree before the package manager installs any packages. If this option is not used, but the `mkosi.skeleton/` directory is found in the local directory it is automatically used for this purpose (also see below). As with the extra tree logic above, instead of a directory a `tar` file may be used too, and `mkosi.skeleton.tar` is automatically used. `--build-script=` : Takes a path to an executable that is used as build script for this image. If this option is used the build process will be two-phased instead of single-phased (see below). The specified script is copied onto the development image and executed inside an `systemd-nspawn` container environment. If this option is not used, but the `mkosi.build` file found in the local directory it is automatically used for this purpose (also see below). `--build-sources=` : Takes a path of a source tree to copy into the development image, if a build script is used. This only applies if a build script is used, and defaults to the local directory. Use `--source-file-transfer=` to configure how the files are transferred from the host to the container image. `--build-dir=` : Takes a path of a directory to use as 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. This directory is mounted into the development image when the build script is invoked. The build script can find the path to this directory in the `$BUILDDIR` environment variable. If this option is not specified, but a directory `mkosi.builddir/` exists in the local directory it is automatically used for this purpose (also see below). `--build-package=` : Similar to `--package=`, but configures packages to install only in the first phase of the build, into the development image. This option should be used to list packages containing header files, compilers, build systems, linkers and other build tools the `mkosi.build` script requires to operate. Note that packages listed here are only included in the image created during the first phase of the build, and are absent in the final image. use `--package=` to list packages that shall be included in both. `--postinst-script=` : Takes a path to an executable that is invoked inside the final image right after copying in the build artifacts generated in the first phase of the build. This script is invoked inside a `systemd-nspawn` container environment, and thus does not have access to host resources. If this option is not used, but an executable `mkosi.postinst` is found in the local directory, it is automatically used for this purpose (also see below). `--finalize-script=` : Takes a path to an executable that is invoked outside the final image right after copying in the build artifacts generated in the first phase of the build, and after having executed the `mkosi.postinst` script (see above). This script is invoked directly in the host environment, and hence has full access to the host's resources. If this option is not used, but an executable `mkosi.finalize` is found in the local directory, it is automatically used for this purpose (also see below). `--source-file-transfer=` : Configures how the source file tree (as configured with `--build-sources=`) is transferred into the container image during the first phase of the build. Takes one of `copy-all` (to copy all files from the source tree), `copy-git-cached` (to copy only those files `git-ls-files --cached` lists), `copy-git-others` (to copy only those files `git-ls-files --others` lists), `mount` to bind mount the source tree directly. Defaults to `copy-git-cached` if a `git` source tree is detected, otherwise `copy-all`. `--with-network` : Enables network connectivity while the build script `mkosi.build` is invoked. By default, the build script runs with networking turned off. The `$WITH_NETWORK` environment variable is passed to the `mkosi.build` build script indicating whether the build is done with or without this option. `--settings=` : Specifies a `.nspawn` settings file for `systemd-nspawn` to use in the `boot` and `shell` verbs, and to place next to the generated image file. This is useful to configure the `systemd-nspawn` environment when the image is run. If this setting is not used but an `mkosi.nspawn` file found in the local directory it is automatically used for this purpose (also see below). `--root-size=` : Takes a size in bytes for the root file system. The specified numeric value may be suffixed with `K`, `M`, `G` to indicate kilo-, mega- and gigabytes (all to the base of 1024). This applies to output formats `gpt_ext4`, `gpt_xfs`, `gpt_btrfs`. Defaults to 1G, except for `gpt_xfs` where it defaults to 1.3G. `--esp-size=` : Similar, and configures the size of the UEFI System Partition (ESP). This is only relevant if the `--bootable` option is used to generate a bootable image. Defaults to 256M. `--swap-size=` : Similar, and configures the size of a swap partition on the image. If omitted no swap partition is created. `--home-size=` : Similar, and configures the size of the `/home` partition. If omitted no separate `/home` partition is created. `--srv-size=` : Similar, and configures the size of the `/srv` partition. If omitted no separate `/srv` partition is created. `--checksum` : Generate a `SHA256SUMS` file of all generated artifacts after the build is complete. `--sign` : Sign the generated `SHA256SUMS` using `gpg` after completion. `--key=` : Select the `gpg` key to use for signing `SHA256SUMS`. This key is required to exist in the `gpg` keyring already. `--bmap` : Generate a `bmap` file for usage with `bmaptool` from the generated image file. `--password=` : Set the password of the `root` user. By default the `root` account is locked. If this option is not used but a file `mkosi.rootpw` exists in the local directory the root password is automatically read from it. `--extra-search-paths=` : List of colon-separated paths to look for tools in, before using the regular `$PATH` search path. `--directory=`, `-C` : Takes a path to a directory. `mkosi` switches to this directory before doing anything. Note that the various `mkosi.*` files are searched for only after changing to this directory, hence using this option is an effective way to build a project located in a specific directory. `--default=` : Loads additional settings from the specified settings file. Most command line options may also be configured in a settings file. See the table below to see which command line options match which settings file option. If this option is not used, but a file `mkosi.default` is found in the local directory it is automatically used for this purpose. If a setting is configured both on the command line and in the settings file, the command line generally wins, except for options taking lists in which case both lists are combined. `--all`, `-a` : Iterate through all files `mkosi.*` in the `mkosi.files/` subdirectory, and build each as if `--default=mkosi.files/mkosi.…` was invoked. This is a quick way to build a large number of images in one go. Any additional specified command line arguments override the relevant options in all files processed this way. `--all-directory=` : If specified, overrides the directory the `--all` logic described above looks for settings files in. If unspecified, defaults to `mkosi.files/` in the current working directory (see above). `--version` : Show package version. `--help`, `-h` : Show brief usage information. ## Command Line Parameters and their Settings File Counterparts Most command line parameters may also be placed in an `mkosi.default` settings file (or any other file `--default=` is used on). The following table shows which command lines parameters correspond with which settings file options. | Command Line Parameter | `mkosi.default` section | `mkosi.default` setting | |------------------------------|-------------------------|---------------------------| | `--distribution=`, `-d` | `[Distribution]` | `Distribution=` | | `--release=`, `-r` | `[Distribution]` | `Release=` | | `--repositories=` | `[Distribution]` | `Repositories=` | | `--mirror=`, `-m` | `[Distribution]` | `Mirror=` | | `--architecture=` | `[Distribution]` | `Architecture=` | | `--format=`, `-t` | `[Output]` | `Format=` | | `--output=`, `-o` | `[Output]` | `Output=` | | `--output-dir=`, `-O` | `[Output]` | `OutputDirectory=` | | `--force`, `-f` | `[Output]` | `Force=` | | `--bootable`, `-b` | `[Output]` | `Bootable=` | | `--boot-protocols=` | `[Output]` | `BootProtocols=` | | `--kernel-command-line=` | `[Output]` | `KernelCommandLine=` | | `--secure-boot` | `[Output]` | `SecureBoot=` | | `--secure-boot-key=` | `[Output]` | `SecureBootKey=` | | `--secure-boot-certificate=` | `[Output]` | `SecureBootCertificate=` | | `--read-only` | `[Output]` | `ReadOnly=` | | `--encrypt=` | `[Output]` | `Encrypt=` | | `--verity=` | `[Output]` | `Verity=` | | `--compress=` | `[Output]` | `Compress=` | | `--mksquashfs=` | `[Output]` | `Mksquashfs=` | | `--xz` | `[Output]` | `XZ=` | | `--qcow2` | `[Output]` | `QCow2=` | | `--hostname=` | `[Output]` | `Hostname=` | | `--package=` | `[Packages]` | `Packages=` | | `--with-docs` | `[Packages]` | `WithDocs=` | | `--without-tests`, `-T` | `[Packages]` | `WithTests=` | | `--cache=` | `[Packages]` | `Cache=` | | `--extra-tree=` | `[Packages]` | `ExtraTrees=` | | `--skeleton-tree=` | `[Packages]` | `SkeletonTrees=` | | `--build-script=` | `[Packages]` | `BuildScript=` | | `--build-sources=` | `[Packages]` | `BuildSources=` | | `--source-file-transfer=` | `[Packages]` | `SourceFileTransfer=` | | `--build-directory=` | `[Packages]` | `BuildDirectory=` | | `--build-packages=` | `[Packages]` | `BuildPackages=` | | `--postinst-script=` | `[Packages]` | `PostInstallationScript=` | | `--finalize-script=` | `[Packages]` | `FinalizeScript=` | | `--with-network` | `[Packages]` | `WithNetwork=` | | `--settings=` | `[Packages]` | `NSpawnSettings=` | | `--root-size=` | `[Partitions]` | `RootSize=` | | `--esp-size=` | `[Partitions]` | `ESPSize=` | | `--swap-size=` | `[Partitions]` | `SwapSize=` | | `--home-size=` | `[Partitions]` | `HomeSize=` | | `--srv-size=` | `[Partitions]` | `SrvSize=` | | `--checksum` | `[Validation]` | `CheckSum=` | | `--sign` | `[Validation]` | `Sign=` | | `--key=` | `[Validation]` | `Key=` | | `--bmap` | `[Validation]` | `BMap=` | | `--password=` | `[Validation]` | `Password=` | | `--extra-search-paths=` | `[Host]` | `ExtraSearchPaths=` | Command line options that take no argument are not suffixed with a `=` in their long version in the table above. In the `mkosi.default` file they are modeled as boolean option that take either `1`, `yes`, `true` for enabling, and `0`, `no`, `false` for disabling. ## Supported distributions Images may be created containing installations of the following *OS*es. * *Fedora* * *Debian* * *Ubuntu* * *Arch Linux* * *openSUSE* * *Mageia* * *CentOS* * *Clear Linux* 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 `debootstrap` may be used to build *Debian* or *Ubuntu* images. Any distribution that packages `dnf` may be used to build *Fedora* or *Mageia* images. Any distro that packages `pacstrap` may be used to build *Arch Linux* images. Any distribution that packages `zypper` may be used to build *openSUSE* images. Any distribution that packages `yum` (or the newer replacement `dnf`) may be used to build *CentOS* images. Currently, *Fedora* packages all relevant tools as of Fedora 28. ## Compatibility Generated images are *legacy-free*. This means only *GPT* disk labels (and no *MBR* disk labels) are supported, and only systemd based images may be generated. All generated *GPT* disk images may be booted in a local container directly with: ```bash systemd-nspawn -bi image.raw ``` Additionally, bootable *GPT* disk images (as created with the `--bootable` flag) work when booted directly by *EFI* and *BIOS* systems, for example in *KVM* via: ```bash qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -drive format=raw,file=image.raw ``` *EFI* bootable *GPT* images are larger than plain *GPT* images, as they additionally carry an *EFI* system partition containing a boot loader, as well as a kernel, kernel modules, udev and more. All directory or btrfs subvolume images may be booted directly with: ```bash systemd-nspawn -bD image ``` # 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 *source* tree. Specifically, the following files are used if they exist in the local directory: * `mkosi.default` may be used to configure mkosi's image building process. For example, you may configure the distribution to use (`fedora`, `ubuntu`, `debian`, `arch`, `opensuse`, `mageia`) for the image, or additional distribution packages to install. Note that all options encoded in this configuration file may also be set on the command line, and this file is hence little more than a way to make sure simply typing `mkosi` without further parameters in your *source* tree is enough to get the right image of your choice set up. Additionally if a `mkosi.default.d` directory exists, each file in it is loaded in the same manner adding/overriding the values specified in `mkosi.default`. The file format is inspired by Windows `.ini` files and supports multi-line assignments: any line with initial whitespace is considered a continuation line of the line before. Command-line arguments, as shown in the help description, have to be included in a configuration block (e.g. "[Packages]") corresponding to the argument group (e.g. "Packages"), and the argument gets converted as follows: "--with-network" becomes "WithNetwork=yes". For further details see the table above. * `mkosi.extra/` or `mkosi.extra.tar` may be respectively a directory or archive. If any exist all files contained in it are copied over the directory tree of the image after the *OS* was installed. This may be used to add in additional files to an image, on top of what the distribution includes in its packages. When using a directory file ownership is not preserved: all files copied will be owned by root. To preserve ownership use a tar archive. * `mkosi.skeleton/` or `mkosi.skeleton.tar` may be respectively a directory or archive, and they work in the same way as `mkosi.extra`/`mkosi.skeleton.tar`. However the files are copied before anything else so to have a skeleton tree for the OS. This allows to change the package manager and create files that need to be there before anything is installed. When using a directory file ownership is not preserved: all files copied will be owned by root. To preserve ownership use a tar archive. * `mkosi.build` may be an executable script. If it exists the image will be built twice: the first iteration will be the *development* image, the second iteration will be the *final* image. The *development* image is used to build the project in the current working directory (the *source* tree). For that the whole directory is copied into the image, along with the mkosi.build build script. The script is then invoked inside the image (via `systemd-nspawn`), with `$SRCDIR` pointing to the *source* tree. `$DESTDIR` points to a directory where the script should place any files generated it would like to end up in the *final* image. Note that `make`/`automake`/`meson` based build systems generally honor `$DESTDIR`, thus making it very natural to build *source* trees from the build script. After the *development* image was built and the build script ran inside of it, it is removed again. After that the *final* image is built, without any *source* tree or build script copied in. However, this time the contents of `$DESTDIR` are added into the image. When the source tree is copied into the *build* image, all files are copied, except for `mkosi.builddir/`, `mkosi.cache/` and `mkosi.output/`. That said, `.gitignore` is respected if the source tree is a `git` checkout. If multiple different images shall be built from the same source tree it's essential to exclude their output files from this copy operation, as otherwise a version of an image built earlier might be included in a later build, which is usually not intended. An alternative to excluding these built images via `.gitignore` entries is making use of the `mkosi.output/` directory (see below), which is an easy way to exclude all build artifacts. * `mkosi.postinst` may be an executable script. If it exists it is invoked as the penultimate step of preparing an image, from within the image context. It is once called for the *development* image (if this is enabled, see above) with the "build" command line parameter, right before invoking the build script. It is called a second time for the *final* image with the "final" command line parameter, right before the image is considered complete. This script may be used to alter the images without any restrictions, after all software packages and built sources have been installed. Note that this script is executed directly in the image context with the final root directory in place, without any `$SRCDIR`/`$DESTDIR` setup. * `mkosi.finalize` may be an executable script. If it exists it is invoked as last step of preparing an image, from the host system. It is once called for the *development* image (if this is enabled, see above) with the "build" command line parameter, as the last step before invoking the build script, after the `mkosi.postinst` script is invoked. It is called the second time with the "final" command line parameter as the last step before the image is considered complete. The environment variable `$BUILDROOT` points to the root directory of the installation image. Additional verbs may be added in the future, the script should be prepared for that. This script may be used to alter the images without any restrictions, after all software packages and built sources have been installed. This script is more flexible than `mkosi.postinst` in two regards: it has access to the host file system so it's easier to copy in additional files or to modify the image based on external configuration, and the script is run in the host, so it can be used even without emulation even if the image has a foreign architecture. * `mkosi.mksquashfs-tool` may be an executable script. If it exists is is called instead of `mksquashfs`. * `mkosi.nspawn` may be an nspawn settings file. If this exists it will be copied into the same place as the output image file. This is useful since nspawn looks for settings files next to image files it boots, for additional container runtime settings. * `mkosi.cache/` may be a directory. If so, it is automatically used as package download cache, in order to speed repeated runs of the tool. * `mkosi.builddir/` may be a directory. If so, it is automatically used as out-of-tree build directory, if the build commands in the `mkosi.build` script support it. Specifically, this directory will be mounted into the build container, and the `$BUILDDIR` environment variable will be set to it when the build script is invoked. The 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 `mkosi` is used in incremental mode (`-i`): not only the disk images but also the build tree is reused between subsequent invocations. Note that if this directory does not exist the `$BUILDDIR` environment variable is not set, and it is up to build script to decide whether to do in in-tree or an out-of-tree build, and which build directory to use. * `mkosi.rootpw` may be a file containing the password for the root user of the image to set. 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's default root password is set (which usually means access to the root user is blocked). * `mkosi.passphrase` may be a passphrase file 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 /etc/crypttab expect the passphrase files). The file must have an access mode of 0600 or less. If this file does not exist and encryption is requested the user is queried instead. * `mkosi.secure-boot.crt` and `mkosi.secure-boot.key` may contain an X.509 certificate and PEM private key to use when UEFI SecureBoot support is enabled. All EFI binaries included in the image's ESP are signed with this key, as a late step in the build process. * `mkosi.output/` may be a directory. If it exists, and the image output path is not configured (i.e. no `--output=` setting specified), or configured to a filename (i.e. a path containing no `/` character) all build artifacts (that is: the image itself, the root hash file in case Verity is used, the checksum and its signature if that's enabled, and the nspawn settings file if there is any) are placed in this directory. Note that this directory is not used if the image output path contains at least one slash, and has no effect in that case. This setting is particularly useful if multiple different images shall be built from the same working directory, as otherwise the build result of a preceding run might be copied into a build image as part of the source tree (see above). All these files are optional. Note that the location of all these files may also be configured during invocation via command line switches, and as settings in `mkosi.default`, in case the default settings are not acceptable for a project. # BUILD PHASES If no build script `mkosi.build` (see above) is used the build consists of a single phase only: the final image is generated as the combination of `mkosi.skeleton/` (see above), the unpacked distribution packages and `mkosi.extra/`. If a build script `mkosi.build` is used the build consists of two phases: in the the first `development` phase an image that includes necessary build tools (i.e. the combination of `Packages=` and `BuildPackages=` is installed) is generated (i.e. the combination of `mkosi.skeleton/` and unpacked distribution packages). Into this image the source tree is copied and `mkosi.build` executed. The artifacts the `mkosi.build` generates are saved. Then, the second `final` phase starts: an image that excludes the build tools (i.e. only `Packages=` is installed, `BuildPackages=` is not) is generated. This time the build artifacts saved from the first phase are copied in, and `mkosi.extra` copied on top, thus generating the final image. The two-phased approach ensures that source tree is executed in a clean and comprehensive environment, while at the same the final image remains minimal and contains only those packages necessary at runtime, but avoiding those necessary at build-time. Note that only the package cache `mkosi.cache/` (see below) is shared between the two phases. The distribution package manager is executed exactly once in each phase, always starting from a directory tree that is populated with `mkosi.skeleton` but nothing else. # CACHING `mkosi` supports three different caches for speeding up repetitive re-building of images. Specifically: 1. The package cache of the distribution package manager may be cached between builds. This is configured with the `--cache=` option or the `mkosi.cache/` directory. This form of caching relies on the distribution's package manager, and caches distribution packages (RPM, DEB, …) after they are downloaded, but before they are unpacked. 2. If an `mkosi.build` script is used, by enabling incremental build mode with `--incremental` (see above) a cached copy of the development and final images can be made immediately before the build sources are copied in (for the development image) or the artifacts generated by `mkosi.build` 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` switch. 3. Finally, between multiple builds the build artifact directory may be shared, using the `mkosi.builddir/` 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 the `mkosi.build` build script. The package cache (i.e. the first item above) is unconditionally useful. The latter two caches only apply to uses of `mkosi` 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: an OS image rebuilt will be almost as quick to build the source tree only. # ENVIRONMENT VARIABLES The build script `mkosi.build` receives the following environment variables: * `$SRCDIR` contains the path to the sources to build. * `$DESTDIR` is a directory into which any artifacts generated by the build script shall be placed. * `$BUILDDIR` is only defined if `mkosi.builddir` 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. * `$WITH_DOCS` is either `0` or `1` depending on whether a build without or with installed documentation was requested (see `--with-docs` above). The build script should suppress installation of any package documentation to `$DESTDIR` in case `$WITH_DOCS` is set to `0`. * `$WITH_TESTS` is either `0`or `1` depending on whether a build without or with running the test suite was requested (see `--without-tests` above). The build script should avoid running any unit or integration tests in case `$WITH_TESTS` is `0`. * `$WITH_NETWORK` is either `0`or `1` depending on whether a build without or with networking is being executed (see `--with-network` above). The build script should avoid any network communication in case `$WITH_NETWORK` is `0`. # EXAMPLES Create and run a raw *GPT* image with *ext4*, as `image.raw`: ```bash # mkosi # systemd-nspawn -b -i image.raw ``` Create and run a bootable btrfs *GPT* image, as `foobar.raw`: ```bash # mkosi -t gpt_btrfs --bootable -o foobar.raw # systemd-nspawn -b -i foobar.raw # qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -drive format=raw,file=foobar.raw ``` Create and run a *Fedora* image into a plain directory: ```bash # mkosi -d fedora -t directory -o quux # systemd-nspawn -b -D quux ``` Create a compressed image `image.raw.xz` and add a checksum file, and install *SSH* into it: ```bash # mkosi -d fedora -t gpt_squashfs --checksum --xz --package=openssh-clients ``` Inside the source directory of an `automake`-based project, configure *mkosi* so that simply invoking `mkosi` without any parameters builds an *OS* image containing a built version of the project in its current state: ```bash # cat > mkosi.default < mkosi.build <