---
name: "image-garden"
section: "1"
platform: "linux"
package: "image-garden"
version: "0.2-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/image-garden"
---

# image-garden(1)

construct and operate test virtual machines

## NAME

**image-garden** – construct and operate test virtual machines

## SYNOPSIS

**image-garden** **make** \[**-n**\] \[*GOAL*\]

**image-garden** **allocate** \[**--premade**\] \[**--nice**\] *SYSTEM.ARCH*

**image-garden** **discard** *ADDRESS*

**image-garden** **version**

## 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.

### 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.seed.iso*

  ISO 9660 disk image with cloud-init files used during first boot.

- *$SYSTEM.user-data*

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

- *$SYSTEM.meta-data*

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

- *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}

  Alma Linux cloud images.

- alpine-cloud-3

  Alpine Linux cloud image.

- amazonliux-cloud-2023

  Amazon Linux cloud image.

- 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}

  Fedora cloud images.

- opensuse-cloud-{15.4,15.5,15.16,tumbleweed}

  openSUSE cloud images.

- oracle-cloud-{8,9}

  Oracle Linux cloud images.

- rocky-cloud-{8,9}

  Rocky Linux cloud images.

- ubuntu-cloud-14.04

  This system fails to boot correctly.

- ubuntu-cloud-{16,18,20,22,24}.04

  Ubuntu Long Term Support (LTS) cloud images.

- ubuntu-cloud-{24.10,25.04}

  Ubuntu development releases cloud images.

- ubuntu-core-{16,18,20,22,24}

  Ubuntu Core images. Core 16 and 18 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*".

- 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)](/qemu-img/1.md) 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\_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\_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.

- GENISOIMAGE

  Full path of the **genisoimage** 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)](/spread/1.md) 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

  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 -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)](/spread/1.md) 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)](/qemu/1.md)

## 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*⟩
