image-garden —
construct and operate test virtual machines
image-garden |
make [-n]
[GOAL] |
image-garden
allocate |
[--premade] [--nice]
SYSTEM.ARCH |
image-garden rebase
SYSTEM.ARCH |
|
image-garden discard
ADDRESS |
|
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.
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.
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 is also supported on the
riscv64 CPU architecture.
- fedora-cloud+uki-43
- Fedora 43 variant using unified kernel image.
- 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}.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-core-{16,18,20,22,24}
- Ubuntu Core images. Core 16, 18 and 20 are only supported on the
x86_64 CPU architecture.
- .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 variables are split into sections to indicate which of
the sub-commands uses them.
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.
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.
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"
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
Image garden was developed in stages throughout late 2023, with
first commits appearing in early 2024.