mkosi

repository·main·Indexed 24 days ago

https://github.com/systemd/mkosi

A tool for building bespoke, customized operating system disk images. mkosi acts as a high-level wrapper around package managers such as dnf, apt, pacman, and zypper to generate, package, and boot OS images. It supports various output formats including GPT disk images, Tar archives, CPIO archives, USIs, and sysext. It can also function as a kernel-install plugin for building initrds or Unified Kernel Images (UKIs).

Tokens
56.1K
Snippets
78
Records
325
Agent score
81%

What's inside mkosi

  1. Overview of mkosi command line verbs

    main

    mkosi uses a verb-based CLI structure to manage the lifecycle of OS image building, from initialization to deployment. Common verbs include:

    • build: The default verb. Builds the image based on configuration files and command line settings. Use -- to pass arguments to build scripts.
    • init: A one-time operation to set up configuration files (e.g., setting up tmpfiles.d for the package cache).
    • summary: Displays a human-readable summary of all options used for building, parsed from both CLI and config files, without executing a build.
    • cat-config: Outputs the names and contents of all loaded configuration files to help debug configuration sources.
    • clean: Removes build artifacts. Use -f to also remove incremental build cache and tools tree; use -f twice to also remove the package cache.
    • dependencies: Lists packages required by mkosi to build and boot images. This list can be piped to a package manager.
    • help: Shows a brief usage explanation.
  2. Insert files into the image using skeleton and extra directories

    main

    When running mkosi from a source tree, you can use specific directories to inject files into the resulting OS image.

    • mkosi.skeleton/ or mkosi.skeleton.tar: Files are copied into the image before distribution packages are installed. Use this for early configuration (e.g., package manager settings or systemd presets).
    • mkosi.extra/ or mkosi.extra.tar: Files are copied into the image after the OS is installed. Use this for additional files that should sit on top of the distribution's default files.

    Note on Ownership: If you use a directory (e.g., mkosi.skeleton/), all files will be owned by root. To preserve specific file ownership, use a .tar archive instead.

  3. Use [Match] sections to gate configuration

    main

    The [Match] section allows you to apply configuration settings only when certain conditions are met. This is useful for creating drop-in configurations that apply to specific architectures, distributions, or images.

    Common Matchers

    MatcherDescription
    Profiles=Matches against configured profiles in mkosi.profiles/
    Distribution=Matches against the configured distribution (defaults to host)
    Release=Matches against the configured release (defaults to host)
    Architecture=Matches against the configured architecture (defaults to host). Use uefi to match any UEFI-supported architecture
    ImageId=Matches against the configured image ID (supports globs)
    ImageVersion=Matches against the configured image version (supports rich version comparisons like ==, !=, >=, <=, <, >)
    Bootable=Matches against the Bootable= setting (boolean or auto)
    Format=Matches against the configured output format
    SystemdVersion=Matches against the host systemd version (supports rich version comparisons)
    BuildSources=Matches if any configured build source uses the specified target path
    Environment=Matches a specific key/value pair from Environment= settings
    Image=Matches against the current (sub)image name. Use Image=main to gate settings for the top-level image vs subimages

    Matcher Capabilities

    MatcherGlobsRich Comparisons
    ImageId=YesNo
    ImageVersion=NoYes
    SystemdVersion=NoYes
    Architecture=NoNo
    Image=NoNo
  4. Use a Tools Tree for reproducible builds

    main

    To make image builds more reproducible, you can use a Tools Tree instead of relying on the host system's installed programs. A tools tree provides a consistent set of binaries used for building and booting the image.

    • ToolsTree= / --tools-tree=: Specifies the directory containing the tools tree. If not provided, mkosi automatically looks for a mkosi.tools/ directory in the local directory.
    • ToolsTreeDistribution= / --tools-tree-distribution=: Sets the distribution for the default tools tree. Defaults to the host distribution (with specific overrides for Ubuntu/Debian and RHEL/Fedora/etc.).
    • ToolsTreeRelease= / --tools-tree-release=: Sets the distribution release for the default tools tree.
    • ToolsTreeProfiles= / --tools-tree-profile=: Enables specific profiles in the tools tree. Takes a comma-delimited list: devel, misc, package-manager, and runtime. By default, all are enabled except devel and gui.
    • ToolsTreePackages= / --tools-tree-package=: Adds extra packages to the default tools tree (comma-separated list).
    • ToolsTreeCertificates= / --tools-tree-certificates=: Determines if certificates/keys from the tools tree are used (defaults to yes).

    Note: Binaries in paths configured via ExtraSearchPaths= will be executed using /usr/ from the tools tree rather than the host.

  5. Use Tools Trees for reproducible builds

    main

    A Tools Tree is a secondary image used by mkosi to build the actual target images. Using a tools tree improves reproducibility and allows you to use newer tooling than what is available on your host distribution.

    Configuration Options

    You can specify a tools tree using:

    • The ToolsTree= configuration option.
    • A directory named mkosi.tools.
    • Setting ToolsTree=yes to have mkosi build it automatically.

    Customizing Tools Trees

    Default tools trees can be customized via:

    • ToolsTree*= variables.
    • A mkosi.tools.conf configuration file or directory.

    Note: The output format for tools trees cannot currently be changed via configuration files.

    Building a custom tools tree

    You can build a custom tools tree just like any other image. To build one using the built-in mkosi-tools package set, use:

    mkosi --include=mkosi-tools --format=directory
  6. Manage image versions with bump

    main

    The bump verb increments the image version defined in mkosi.version and writes the new string back to the file. This is useful for automated versioning.

    • Automatic Bumping: You can use the --auto-bump or -B flag during a build to automatically trigger this logic.
    • Custom Logic: If a mkosi.bump file exists, mkosi will invoke it to generate the new version instead of using its internal logic.
    • Success Guarantee: The new version is only written to mkosi.version if the build succeeds when using auto-bump.
  7. Use mkosi.builddir for out-of-tree builds

    main

    If a mkosi.builddir/ directory exists in the source tree, mkosi will use it as an out-of-tree build directory.

    • The directory is mounted into the build container.
    • The $BUILDDIR environment variable is set to the path of this directory when mkosi.build scripts are invoked.
    • Build scripts (like automake or ninja) can use $BUILDDIR to perform out-of-tree builds, which significantly speeds up incremental builds (-i) by reusing the build tree between invocations.
  8. Pass data between scripts using the artifact directory

    main

    In v23, mkosi introduced an artifact directory that is made available to all running scripts. This directory can be used to pass data between different stages of the build process.

    mkosi specifically looks for microcode and initrds in the following subdirectories within the artifact directory:

    • io.mkosi.microcode
    • io.mkosi.initrd
  9. Provide extra credentials via mkosi.credentials

    main

    The mkosi.credentials/ directory acts as a source for extra credentials. For every file in this directory:

    1. The filename becomes the credential name.
    2. The file contents become the credential value.
    3. If the file is executable, mkosi runs the file and uses its stdout as the credential value (ignoring stderr).

    Precedence: Credentials explicitly configured via the Credentials= option in configuration take precedence over those found in mkosi.credentials/.

  10. Understand the mkosi build execution flow

    main

    When running mkosi build, the tool follows a specific sequence of steps to prepare the environment, install the distribution, and finalize the image. If --incremental=yes is used, mkosi utilizes a cache of the distribution installation to speed up consecutive runs.

    Phase 1: Environment Setup

    1. Parse CLI options and configuration files.
    2. Run mkosi.configure scripts.
    3. Setup namespaces (user and mount) and remount system directories (/usr, /etc, etc.) as read-only.

    Phase 2: Image Construction (Per Image)

    1. Preparation: Copy sandbox trees, sync package manager metadata (via mkosi.sync), and copy base trees (--base-tree=).
    2. Installation: Copy skeleton trees (mkosi.skeleton), install the distribution and packages, and run mkosi.prepare scripts with the final argument.
    3. Overlay/Build: If configured, install build packages in an overlay and run mkosi.prepare with the build argument.
    4. Build & Finalize: Run mkosi.build scripts, copy build script outputs, copy extra trees (mkosi.extra), and run mkosi.postinst scripts.
    5. System Configuration: Write config files for Ssh=, Autologin=, and MakeInitrd=. Install systemd-boot if --secure-boot=yes is set.
    6. Systemd Integration: Run systemd-sysusers, systemd-tmpfiles, systemctl preset-all, depmod, systemd-hwdb, and systemd-firstboot.
    7. Cleanup: Remove packages (RemovePackages=) and files (RemoveFiles=), and run SELinux relabel if applicable.
    8. Finalization: Run mkosi.finalize, generate Unified Kernel Images (UKI) if configured, generate the final output format, and run mkosi.postoutput scripts.
  11. Configure the package manager with mkosi.sandbox

    main

    Use the mkosi.sandbox/ directory or mkosi.sandbox.tar archive to provide files that configure the package manager during the build process without actually inserting those files into the final OS image.

    If you want the files to be included in the final image, use mkosi.skeleton/ instead.

  12. Speed up builds using mkosi caching mechanisms

    main

    mkosi provides several layers of caching to optimize repetitive builds:

    1. Package Cache: Caches downloaded distribution packages (RPM, deb, etc.) before unpacking.
      • Configure via PackageCacheDirectory= or the mkosi.pkgcache/ directory.
    2. Repository Metadata Cache: Caches distribution repository metadata.
      • Configure via CacheDirectory= or the mkosi.cache/ directory.
      • Resync behavior is controlled by CacheOnly=.
    3. Incremental Build Cache: When Incremental=yes is enabled, mkosi caches the final image and build overlay. This bypasss package unpacking if the package list is stable.
    4. Build Artifact Cache: Shares the build directory between builds to allow tools like Meson to reuse compiled objects.
      • Configure via BuildDirectory= or the mkosi.builddir/ directory.