IMAGE-GARDEN(1)
π IMAGE-GARDEN(1) β the manual, but make it slay π
local Β· untitled Β· bestie edition β¨
okay so. <rainbow>image-garden</rainbow> is a whole entire tool for constructing and operating test virtual machines, and ngl it eats. It's from the <pink>LOCAL</pink> manual section, it's filed under <purple>UNTITLED()</purple> (iconic of it tbh), and this is the page that tells you literally everything. Let's go π
β¨ 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]]
like. look at all those sub-commands. she's versatile π
β¨ DESCRIPTION β¨
So image-garden downloads, initializes, and optionally operates virtual machine images for a bunch of popular operating systems. π¦
Every single system in here is built for testing, and they all come pre-configured with a well-known username and password β which usually matches the name of the system. iykyk. π
options that image-garden make recognizes
-nβ Display commands instead of actually executing them. This one is genuinely so useful if you're trying to learn how individual disk images get made. Like, it shows you the receipts instead of doing the thing. π
options that image-garden allocate recognizes
--premadeβ Assume pre-made disk images are already sitting there and do not re-generate them, even if they're out-of-date. This is the move for making sure your CI/CD jobs don't re-build disk images just because some timestamps are acting like they know something. β°π--niceβ Wraps the execution of virtual machines withnice, so it doesn't fight other applications for CPU. Bestie behaviour fr fr π«Ά. This is implicitly set whenXDG_SESSION_TYPEis eitherwaylandorx11.
π Make Goals π
The image-garden make sub-command lets you build one or more goals corresponding to virtual machine images and their support files. very build-a-bear of her π
Here are the documented goals. Heads up: ARCH and SYSTEM are placeholders β ARCH is a CPU architecture as named by the Linux kernel, and SYSTEM is a standardized distribution name. For the complete list of valid SYSTEM-ARCH combos, please see the table. π
helpβ Display a help message specific to the set of make rules contained withinimage-garden.allβ Build all of the images for the native CPU architecture. everything. the whole closet. π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. bye bye π§Ήdistcleanβ Remove all the base cloud images and installer images from the per-user cache directory. the deep clean π$SYSTEM.$ARCH.qcow2β qemu disk image of operating system$SYSTEMfor CPU architecture$ARCH. Cloud disks contain an internal reference to the base image stored in the per-user cache directory. Both files are required at runtime. β οΈ$SYSTEM.$ARCH.qcow2.logβ Serial console output collected during the first boot of the machine. the birth vlog πΌ$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 toimage-garden qemu-system-$ARCH. The recognized environment variables are described in a dedicated section below. π§$SYSTEM.$ARCH.efi-code.imgβ Symbolic link toefi-code.$ARCH.img.$SYSTEM.$ARCH.efi-vars.imgβ Disk image with the 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 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 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 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. get comfy, it's a long one ποΈβ¨
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. btw π«Ά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 whereimage-gardenis invoked from. ποΈ.image-garden.mkβ Makefile implicitly included byimage-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 a unified naming scheme regardless of the naming scheme used by a particular distributor. π
π± ENVIRONMENT π±
okay bestie, so like β the env vars are split into little sections so you know which sub-command is actually out here reading them. very organized, very demure π
β¨ Environment for image-garden make β¨
XDG_CACHE_HOMEβ the directory holding your per-user cache files that you can delete whenever, no biggie, they're safe to yeet. Per the spec, the default is"$HOME/.cache".GARDEN_CACHE_DIRβ the directory with non-essential files that get reused across different projects. Default is"$XDG_CACHE_HOME/image-garden"β¦ except when it's running as a snap, where the default becomes"$SNAP_USER_COMMON/cache".GARDEN_DL_DIRβ where the downloaded OS images live. These can be big, so please be mindful and don't gobble up your whole disk. Every image in here is used in read-only mode and gets automatically shared between the different projects made by the same user. Default is"$GARDEN_CACHE_DIR/dl".QEMU_ENV_QUIRKSβ a list of environment variables to set before qemu gets invoked. This exists so you can say stuff like "this system literally cannot boot with a virtio disk, it needs SCSI disks instead."QEMU_MEM_SIZEβ how much memory, in megabytes, each virtual machine gets. This value gets copied straight into the generated$SYSTEM.runscripts. Default is"2048"(that's 2GB of runtime memory). β οΈ do not confuse it with the similarly-namedQEMU_MEM_OPTION.QEMU_IMG_SIZEβ the size of the virtual disk image thatqemu-img(1)creates when it's called from image-garden. Default is"64G". heads up: these images use a format with an internal representation of sparse areas, so the actual disk space needed is way smaller than this number. π«ΆQEMU_SMP_X86_64β number of virtual CPU cores for VMs emulating thex86_64CPU architecture. Default is"4"when the host and guest CPU architectures match, or"1"otherwise. And ngl, don't confuse it with the similarly-namedQEMU_SMP_OPTION.QEMU_SMP_AARCH64β number of virtual CPU cores for VMs emulating theaarch64CPU architecture. Default is"4"when host and guest CPU architectures match, or"1"otherwise. Again: not the same asQEMU_SMP_OPTION, bestie.QEMU_SMP_RISCV64β number of virtual CPU cores for VMs emulating theriscv64CPU architecture. Default is"4"when host and guest CPU architectures match, or"1"otherwise. Yes, same warning: not to be confused withQEMU_SMP_OPTION. πQEMU_SYSTEM_X86_64β full path of theqemu-system-x86_64program to use instead of whatever one is found onPATH.QEMU_SYSTEM_AARCH64β full path of theqemu-system-aarch64program to use instead of the one found onPATH.QEMU_SYSTEM_RISCV64β full path of theqemu-system-riscv64program to use instead of the one found onPATH.QEMU_CPU_RISCV64β the virtual CPU type to use for systems on theriscv64CPU architecture. Default ismax.QEMU_CPU_X86_64β the virtual CPU type for systems on thex86_64CPU architecture. Default ismax.QEMU_CPU_AARCH64β the virtual CPU type for systems on theaarch64CPU architecture. Default ismax. But theamazonlinux-cloud-2andamazonlinux-cloud-2023systems use the valueneoverse-n1instead. πΈQEMU_IMGβ full path of theqemu-imgprogram to use instead of the one found onPATH.MKPASSWDβ full path of themkpasswdprogram to use instead of the one found onPATH.XORRISOβ full path of thexorrisoprogram to use instead of the one found onPATH.WGETβ full path of thewgetprogram to use instead of the one found onPATH.
β¨ Environment for image-garden allocate β¨
XDG_RUNTIME_DIRβ directory with per-user runtime files that do not survive a reboot. Per the spec, the default is"/run/user/$UID". When image-garden is used as a back-end for thespread(1)test system, it 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 it to the empty string if you want to allocate a machine that persists all its changes on disk. (yes, this is the "commit to it" switch π)
β¨ Environment for .run scripts. β¨
The following environment variables are used by the generated .run scripts. π
QEMU_MEM_OPTIONβ memory configuration options passed to qemu. An example value is"-m 1024".QEMU_SMP_OPTIONβ CPU topology options passed to qemu. When it's unset, the default value is"-smp $QEMU_SMP_$(uname -m)". An example value is"-smp $(nproc)".QEMU_DISPLAY_OPTIONβ graphical display options passed to qemu. When unset, the default value is"-nographic". An example value is"-display gtk".QEMU_BOOT_FIRMWARE_OPTIONβ boot firmware options passed to qemu. The default value depends on what the booted system requires. For systems booting with EFI, a pair of"-drive pflash"arguments is used to represent EFI code and EFI variables. For systems booting with legacy BIOS, no options are provided at all.QEMU_RNG_OPTIONβ random-number configuration options passed to qemu. When unset, the default value is"-device virtio-rng-pci".QEMU_NET_OPTION_X86_64QEMU_NET_OPTION_AARCH64QEMU_NET_OPTION_RISCV64β network configuration options passed 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 π
Wanna make a bootable image of the cloud variant of Debian 13 (trixie) for the x86_64 architecture? say less:
image-garden make debian-cloud-13.x86_64.run
To use image-garden together with spread(1), drop this little snippet into your spread.yaml file. And psst β using exec lets image-garden automatically do the equivalent of calling the spread shell functions ADDRESS, FATAL or ERROR. iconic behaviour honestly:
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 for a particular project, create a .image-garden.mk file at the root of the project and define one or more cloud-init user-data templates containing the list of packages to install or commands to run. Just make sure you include the default template, because it is essential for image-garden to actually work. You can assume the default template ends with a section that runs one or more commands, and you can append your commands as a YAML list. Any other cloud-init features have to be used explicitly. no shortcuts bestie π
# 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 π¦
π HISTORY π
Image garden was developed in stages throughout late 2023, with the first commits showing up in early 2024. a little glow-up arc, we love to see it β¨
π BUGS π
You can browse the known bugs by looking at the GitLab issues: https://gitlab.com/zygoon/image-garden/-/issues.
π AUTHORS π
Zygmunt Krynicki <me@zygoon.pl>
and that's the whole page, bestie!! π this is image-garden version 0.4.2, dated Jan 19, 2026 β go forth and garden those images, you absolute main character π«Άβ¨
π¦ where this page comes from
- ubuntu resolute: image-garden 0.4.2-3 Β· Apache-2.0
- ubuntu stonking: image-garden 0.4.2-3 Β· Apache-2.0
- π the page's license: Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms