image-garden(1)

NAME
image-garden - construct and operate test virtual machines

SYNOPSIS
image-garden make [-n] [GOAL]
image-garden allocate [--premade] [--nice] SYSTEM.ARCH
image-garden rebase SYSTEM.ARCH
image-garden discard ADDRESS
image-garden version
image-garden news N
image-garden download-with-sha512sums URL [SHA512SUMS_URL [DIRECTORY_PREFIX [FILENAME]]]
image-garden download-with-sha256sums URL [SHA256SUMS_URL [DIRECTORY_PREFIX [FILENAME]]]
image-garden download-with-sha256sum URL [SHA256SUM [DIRECTORY_PREFIX [FILENAME]]]
image-garden download URL [DIRECTORY_PREFIX [FILENAME]]

DESCRIPTION
image-garden downloads, initializes and optionally operates virtual machine images for popular operating systems. All the systems are designed for testing and come configured with well-known username and password, usually matching the name of the system.

Options recognized by image-garden make

-n  Display commands instead of executing them. This option is useful for learning how to make individual disk images.

Options recognized by image-garden allocate

--premade
    Assume presence of pre-made disk images and do not re-generate them even if they are out-of-date. This option is useful for ensuring that CI/CD jobs do not re-build disk images even if timestamps would suggest they should.

--nice
    Wrap execution of virtual machines with nice, so that it does not compete for CPU with other applications. This is implicitly set when XDG_SESSION_TYPE is either wayland or x11.

  Make Goals
The image-garden make sub-command allows building one or more goals corresponding to virtual machine images and their support files.

The following goals are documented. Note that ARCH and SYSTEM are placeholders for CPU architecture as named by the Linux kernel and standardized distribution name, respectively. Please see the table for a complete list of valid SYSTEM-ARCH combinations.

help
    Display help message specific to the set of make rules contained within image-garden

all Build all of the images for the native CPU architecture.

fetch
    Fetch all the base cloud images or installers, so that further work can be done mostly offline. The only exception is installation if packages described by per-project cloud-init profiles.

clean
    Remove all the generated disk images from the current directory.

distclean
    Remove all the base cloud images and installer images from the per-user cache directory.

$SYSTEM.$ARCH.qcow2
    qemu disk image of operating system $SYSTEM for CPU architecture $ARCH. Cloud disks contain internal reference to base image stored in per-user cache directory. Both files are required at runtime.

$SYSTEM.$ARCH.qcow2.log
    Serial console output collected during first boot of the machine.

$SYSTEM.$ARCH.run
    Shell script for running the virtual machine. This script supports extensive customization through environment variables and command line arguments. Command line arguments are passed directly to image-garden qemu-system-$ARCH . Recognized environment variables are described in a dedicated section below.

$SYSTEM.$ARCH.efi-code.img
    Symbolic link to efi-code.$ARCH.img.

$SYSTEM.$ARCH.efi-vars.img
    Disk image with current state of the boot firmware corresponding to $SYSTEM.$ARCH.qcow2.

$SYSTEM.$ARCH.seed.iso
    ISO 9660 disk image with cloud-init files used during first boot.

$SYSTEM.$ARCH.user-data
    Text of the cloud-init user data. This file exists briefly as a prerequisite for $SYSTEM.$ARCH.seed.iso.

$SYSTEM.$ARCH.meta-data
    Text of the cloud-init meta data. This file exists briefly as a prerequisite for $SYSTEM.$ARCH.seed.iso.

efi-code.riscv64.img
    Disk image of EFI firmware for riscv64 CPU architecture.

efi-vars.riscv64.img
    Disk image of with the unmodified state of EFI firmware for the riscv64 CPU architecture.

efi-code.aarch64.img
    Disk image of EFI firmware for aarch64 CPU architecture.

efi-vars.aarch64.img
    Disk image of with the unmodified state of EFI firmware for the aarch64 CPU architecture.

efi-code.x86_64.img
    Disk image of EFI firmware for the x86_64 CPU architecture.

efi-vars.x86_64.img
    Disk image of with the unmodified state of EFI firmware for the x86_64 CPU architecture.

  System Names
Systems are identifiers for a particular operating system, variant, release and CPU architecture. The following list contains all the systems recognized by image-garden.

almalinux-cloud-{8,9,10}
    Alma Linux cloud images.

alpine-cloud-3
    Alpine Linux cloud image.

amazonlinux-cloud-{2,2023}
    Amazon Linux cloud images.

archlinux-cloud
    Arch Linux cloud image. This system is only supported on the x86_64 CPU architecture.

centos-cloud-{9,10}
    CentOS cloud images (usually CentOS stream).

debian-cloud-{10,11,12,13,sid}
    Debian cloud images.

fedora-cloud-{38,39,40,41,42,43}
    Fedora cloud images. Fedora 42, only, is also supported on the riscv64 CPU architecture. Fedora 42 and 43 are also supported on the s390x CPU architecture.

opensuse-cloud-{15.4,15.5,15.16,tumbleweed}
    openSUSE cloud images.

oracle-cloud-{7,8,9}
    Oracle Linux cloud images. Oracle Linux 7 is only supported on the x86_64 CPU architecture.

rocky-cloud-{8,9}
    Rocky Linux cloud images.

ubuntu-cloud-{14,16,18,20,22,24,26}.04
    Ubuntu Long Term Support (LTS) cloud images.

ubuntu-cloud-{25.04,25.10}
    Ubuntu development releases cloud images. Ubuntu 24.04, 25.04 and 25.10 are also supported for riscv64 CPU architecture. Ubuntu 18.04, 20.04, 22.04, 24.04, 25.04, 25.10 and 26.04 are also supported for s390x CPU architecture. Ubuntu 14.04, 16.04, 18.04, 20.04, 22.04, 24.04, 25.04, 25.10 and 26.04 are also supported for ppc64 CPU architecture.

ubuntu-core-{16,18,20,22,24}
    Ubuntu Core images. Core 16, 18 and 20 are only supported on the x86_64 CPU architecture.

FILES

.image-garden
    Sub-directory containing all image, log and lock files. If this directory does not exist then all such files are placed in the directory where image-garden is invoked from.

.image-garden.mk
    Makefile implicitly included by image-garden make. This file is designed for defining cloud-init user-data templates with project-specific build and test dependencies.

$HOME/.cache/image-garden/dl
    Directory with downloaded, unmodified virtual machine images. The files are organized into sub-directories specific to each distribution. Inside symbolic links provide an unified naming scheme regardless of the naming scheme used by a particular distributor.

ENVIRONMENT
Environment variables are split into sections to indicate which of the sub-commands uses them.

  Environment for image-garden make

XDG_CACHE_HOME
    Directory with per-user cache files that may be safely deleted. According to the specification the default value is "$HOME/.cache".

GARDEN_CACHE_DIR
    Directory with non-essential files that can be reused across projects. The default value is "$XDG_CACHE_HOME/image-garden", except when used as a snap where the default value is "$SNAP_USER_COMMON/cache".

GARDEN_DL_DIR
    Directory where downloaded operating system images are stored. Those images may be sizable so care needs to be taken to avoid using excessive amount of disk space. All the images stored here are used in read-only mode and are automatically shared by different project developed by the same user. The default value is "$GARDEN_CACHE_DIR/dl".

QEMU_ENV_QUIRKS
    A list of environment variables to set before invoking qemu. This was introduced to allow expressing that a given system cannot boot with virtio disk and needs to use SCSI disks instead.

QEMU_MEM_SIZE
    Amount of memory, in megabytes, to provide to each virtual machine. This value is copied into the generated $SYSTEM.run scripts. The default value is "2048", for 2GB of runtime memory. Not to be confused with similarly-named QEMU_MEM_OPTION.

QEMU_IMG_SIZE
    Size of the virtual disk image created by qemu-img(1) when invoked from image-garden. The default value is "64G". Note that images use a format with internal representation of sparse areas. The required disk space is much smaller than this size.

QEMU_SMP_X86_64
    The number of virtual CPU cores for virtual machines emulating the x86_64 CPU architecture. The default value is "4" when the CPU architecture of the host and the guest are the same or "1" otherwise. Not to be confused with similarly-named QEMU_SMP_OPTION.

QEMU_SMP_AARCH64
    The number of virtual CPU cores for virtual machines emulating the aarch64 CPU architecture. The default value is "4" when the CPU architecture of the host and the guest are the same or "1" otherwise. Not to be confused with similarly-named QEMU_SMP_OPTION.

QEMU_SMP_RISCV64
    The number of virtual CPU cores for virtual machines emulating the riscv64 CPU architecture. The default value is "4" when the CPU architecture of the host and the guest are the same or "1" otherwise. Not to be confused with similarly-named QEMU_SMP_OPTION.

QEMU_SYSTEM_X86_64
    Full path of the qemu-system-x86_64 program to use instead of the one found on PATH.

QEMU_SYSTEM_AARCH64
    Full path of the qemu-system-aarch64 program to use instead of the one found on PATH.

QEMU_SYSTEM_RISCV64
    Full path of the qemu-system-riscv64 program to use instead of the one found on PATH.

QEMU_CPU_RISCV64
    Virtual CPU type to use for systems using the riscv64 CPU architecture. The default value is max.

QEMU_CPU_X86_64
    Virtual CPU type to use for systems using the x86_64 CPU architecture. The default value is max.

QEMU_CPU_AARCH64
    Virtual CPU type to use for systems using the aarch64 CPU architecture. The default value is max. The amazonlinux-cloud-2 and amazonlinux-cloud-2023 systems use the value neoverse-n1.

QEMU_IMG
    Full path of the qemu-img program to use instead of the one found on PATH.

MKPASSWD
    Full path of the mkpasswd program to use instead of the one found on PATH.

XORRISO
    Full path of the xorriso program to use instead of the one found on PATH.

WGET
    Full path of the wget program to use instead of the one found on PATH.

  Environment for image-garden allocate

XDG_RUNTIME_DIR
    Directory with per-user runtime files that do not persist across reboots. According to the specification the default value is "/run/user/$UID". The image-garden program, when used as a back-end for the spread(1) test system uses this directory to keep track of running virtual machines and their TCP port numbers.

QEMU_SNAPSHOT_OPTION
    Overrides the in-memory snapshot option. Set this to the empty string to allocate a machine that persists all changes on disk.

  Environment for .run scripts.

The following environment variables are used by generated .run scripts.

QEMU_MEM_OPTION
    Memory configuration options to pass to qemu. Example value is "-m 1024".

QEMU_SMP_OPTION
    CPU topology options to pass to qemu. When unset the default value is "-smp $QEMU_SMP_$(uname -m)". Example value is "-smp $(nproc)".

QEMU_DISPLAY_OPTION
    Graphical display options to pass to qemu. When unset the default value is "-nographic". Example value is "-display gtk".

QEMU_BOOT_FIRMWARE_OPTION
    Boot firmware options to pass to qemu. The default value depends on the requirement of the booted system. For systems booting with EFI a pair of "-drive pflash" arguments is used for representing EFI code and EFI variables. For systems booting with legacy BIOS no options are provided.

QEMU_RNG_OPTION
    Random-number configuration options to pass to qemu. When unset the default value is "-device virtio-rng-pci"

QEMU_NET_OPTION_X86_64

QEMU_NET_OPTION_AARCH64

QEMU_NET_OPTION_RISCV64
    Network configuration options to pass to qemu. When unset the default value is "-netdev user,id=netdev0${QEMU_NETDEV_USER_EXTRA:-} -device virtio-net-pci,netdev=netdev0,id=net0" For x86_64 and aarch64 CPU architectures the value also includes the suffix. "-smbios type=41,designation=Virtual-LAN,instance=1,kind=ethernet,pcidev=net0"

EXAMPLES
To create a bootable image of cloud variant of Debian 13 (trixie) for x86_64 architecture run:

    image-garden make debian-cloud-13.x86_64.run

To use image-garden together with spread(1) put the following snippet into your spread.yaml file. Note that using exec allows image-garden to automatically perform the equivalent of calling spread shell functions ADDRESS, FATAL or ERROR.

    backends:
      garden:
        type: adhoc
        allocate: exec image-garden allocate "$SPREAD_SYSTEM"."$(uname -m)"
        discard: exec image-garden discard "$SPREAD_SYSTEM_ADDRESS"
        systems:
          - debian-cloud-13:
              username: debian
              password: debian

To customize the virtual machine to a particular project create a .image-garden.mk file in the root of the project and define one or more cloud-init user-data templates which contain list of packages to install or commands to run. Make sure to include the default template that is essential for image-garden operation. You can assume that the default template ends with a section that runs one or more commands and append your commands as a YAML list. Other cloud-init features must be used explicitly.

    # Cloud-init template for Debian 13 (Trixie).
    define DEBIAN_13_CLOUD_INIT_USER_DATA_TEMPLATE
    $(CLOUD_INIT_USER_DATA_TEMPLATE)
    packages:
    - build-essential
    - libfoo-dev
    endef
    # Cloud-init user-data template for all versions of Ubuntu.
    define UBUNTU_CLOUD_INIT_USER_DATA_TEMPLATE
    $(CLOUD_INIT_USER_DATA_TEMPLATE)
    packages:
    - build-essential
    - libfoo-dev
    endef

SEE ALSO
qemu(1)

HISTORY
Image garden was developed in stages throughout late 2023, with first commits appearing in early 2024.

BUGS
Known bugs can be listed by looking at GitLab issues: https://gitlab.com/zygoon/image-garden/-/issues.

AUTHORS
Zygmunt Krynicki <me@zygoon.pl>