Changes in 0.6.3:

* Fix openSUSE Leap 16.0 image URLs which pointed to stale Build16.2 files
  that have been removed from the mirror network. The URLs now reference the
  final release images.

* Restore `centos-cloud-10.x86_64` checksum verification. The SHA256SUMS file
  which had been zero-sized (noted on May 20, 2026) is now serving valid
  checksums, so the commented-out verification line has been re-enabled.

Changes in 0.6.2:

* Fix QEMU run scripts failing with `set -e` when invoked from the snap.

  The generated `.run` scripts use `/bin/bash` with `set -e`. The previous
  pattern `$$(test -z "$${SNAP_INSTANCE_NAME-}" && echo $(SNAP_INSTANCE_NAME).)`
  embedded a failing `test -z` command substitution into the script when
  `SNAP_INSTANCE_NAME` was set (snap context), causing `set -e` to abort
  immediately.

  This affected aarch64, riscv64, s390x and ppc64 architectures. The x86_64
  architecture already used a safe `if [ -z ... ]; then ...; else ...; fi`
  pattern. All architectures now use the consistent safe pattern.

* Add `system.users.$N.username` and `system.users.$N.password` query properties.

  All generated `.run` scripts now expose SSH user credentials via the `--query`
  interface. For most systems, this includes root/root and a secondary user
  (e.g., ubuntu/ubuntu). Ubuntu Core systems only expose the ubuntu/ubuntu user
  since root password authentication is not available.

  Example output:
  ```bash
  $ ./ubuntu-cloud-24.04.x86_64.run --query
  vm.memory_mb=2048
  system.users.0.username=root
  system.users.0.password=root
  system.users.1.username=ubuntu
  system.users.1.password=ubuntu
  ```

  Ubuntu Core systems only expose the ubuntu user:
  ```bash
  $ ./ubuntu-core-24.x86_64.run --query
  vm.memory_mb=2048
  system.users.0.username=ubuntu
  system.users.0.password=ubuntu
  ```

  See [QUERY](QUERY) for a complete reference of all query properties.

Changes in 0.6.1:

* NEWS entries and Makefile in 0.6.0 release had stale version headers.
  There are no code changes in this release.

Changes in 0.6.0:

* Add named instance system — derive multiple distinct virtual machines from a
  single base system image.

  A named instance is defined in the project-local `.image-garden.mk` file using
  the `define-instance` macro:

  ```make
  $(eval $(call define-instance,ubuntu-cloud-24.04,webserver))
  ```

  The architecture suffix (.x86_64) can be omitted; `$(GARDEN_ARCH)` is used
  automatically. Pass it explicitly to target a different architecture.

  This creates a new system `ubuntu-cloud-24.04@webserver.x86_64` with its own
  disk image, cloud-init seed ISO, and run script. The instance inherits the
  base system's architecture, boot type (EFI/BIOS/platform), and cloud-init
  profile.

  Cloud-init templates can be overridden per instance, with a new
  per-group-instance fallback (`GROUP@instance_CLOUD_INIT_USER_DATA_TEMPLATE`):

  ```make
  # Per-release-instance override (most specific)
  define UBUNTU_24.04@webserver_CLOUD_INIT_USER_DATA_TEMPLATE
  $(CLOUD_INIT_USER_DATA_TEMPLATE)
  packages:
  - nginx
  endef

  # Per-group-instance override (matches any ubuntu release)
  define UBUNTU@webserver_CLOUD_INIT_USER_DATA_TEMPLATE
  $(CLOUD_INIT_USER_DATA_TEMPLATE)
  packages:
  - nginx
  endef
  ```

  The instance hostname follows the `base-release-instance` convention (e.g.,
  `ubuntu-24-04-webserver`).

  Multiple instances of the same base system are supported. Each instance
  produces a full set of build artifacts (`.qcow2`, `.run`, `.meta-data`,
  `.user-data`, `.seed.iso`) scoped to the instance name.

* QEMU run scripts now use `/bin/bash` and build the command as a bash array.

  The generated `.run` launch scripts now use bash arrays (`qemu_cmd+=()`)
  to construct the QEMU command line, then exec via `exec "${qemu_cmd[@]}"`.
  This properly handles environment variable values containing spaces and
  special characters without word splitting or globbing issues. The scripts
  also convert scalar environment variables to arrays at runtime for safe
  `set -u` compatibility.

* QEMU machine type is now configurable via Make variables.

  The `q35`, `pseries`, `virt`, and other machine types are no longer
  hardcoded in the run script generation. They are now controlled by
  `QEMU_SYSTEM_X86_64_MACHINE`, `QEMU_SYSTEM_PPC64_MACHINE`,
  `QEMU_SYSTEM_AARCH64_MACHINE`, `QEMU_SYSTEM_RISCV64_MACHINE`, and
  `QEMU_SYSTEM_S390X_MACHINE` Make variables.

* Add initial support for loongarch64 system emulation.

  LoongArch 64-bit architecture is now supported. The QEMU machine type is
  `virt` and the CPU model defaults to `max`. No distribution cloud images
  are available for loongarch64 yet, but the architecture support enables
  users to boot custom loongarch64 disk images.

* QEMU run script generation is now compatible with Make versions that
  do not handle double backslashes (`\\`) inside single-quoted `echo`
  statements correctly. The line continuation characters are now emitted
  as `@SLASH@` placeholders and replaced with real backslashes via `sed`
  at the end of the script preamble.

* Fedora 39 and Fedora 40 URLs have been updated to use the archive
  domain (`dl.fedoraproject.org/pub/archive/`). These releases are no
  longer available at the primary download location.

* Ubuntu 25.04 (plucky) URLs have been updated from the `plucky/current/`
  path to `releases/plucky/release/`. Plucky has reached end-of-life and
  its images are no longer available via the current symlink.

* Fedora 44 is now supported.

* Alpine Linux is updated to release 3.23.4, from 3.23.2.

* OpenSUSE Leap 16.0 URLs have been fixed, pointing to the appliances
  distribution path at `download.opensuse.org/distribution/leap/16.0/appliances/`.

* CentOS Stream 10 x86_64 SHA256SUM file is empty (zero bytes) — the
  image entries have been commented out until this is resolved.

Changes in 0.5.0:

* Add ubuntu-core-26 and ubuntu-core-26+dangerous image variants.

  The dangerous images use a model with `grade: dangerous` which allows
  some operations that are normally blocked, like installing unsigned gadget
  snaps. It is useful for exploration and development.

* Improve image preparation log readability with three-level formatting.

  Make-driven phases now use timestamped `=` boxed section banners, while
  `image-garden` internal download/checksum phases use timestamped `-` boxed
  section banners. Lower-priority steps use underlined subsection headings.

* Add explicit spread output mode with `image-garden allocate --spread`.

  The `allocate` command now supports an explicit `--spread` option that
  enables spread protocol output (`<ADDRESS ...>` / `<FATAL ...>`) in a
  reliable, topology-independent way.

  Legacy auto-detection based on process ancestry is still supported for
  compatibility, but now emits a prominent warning banner to encourage
  migration to explicit opt-in. This compatibility behavior is planned for
  removal in a future release.

* Add disambiguated local filenames for dynamic image URLs.

  Data definitions now support explicit local naming controls to avoid cache
  filename clashes when different URLs share the same basename.

  For `URL=` entries, use `LocalFilename`.
  For `URLProgram=` entries, use `URLPattern` and `LocalFilenameTemplate`.
  The template uses `@1` placeholders and `URLPattern` must define exactly one
  capture group.

* Fix checksum-verified downloads with custom local filenames.

  Commands `image-garden download-with-sha256sums` and
  `image-garden download-with-sha512sums` now verify checksums correctly when
  `FILENAME` differs from `basename(URL)`, while still storing the downloaded
  file under the custom local name.

* Add `-a` flag to `image-garden discard` to discard all running machines.

  The `image-garden discard` command now supports a `-a` flag that discards all
  allocated virtual machines at once, removing their pidfiles and metadata. This
  is useful for cleanup after testing sessions or in CI/CD environments. The
  original `image-garden discard ADDRESS` syntax remains unchanged for discarding
  specific machines.

* Add `--query` mode to generated `.run` scripts.

  All generated `.run` scripts now support a `--query` argument that outputs VM
  configuration properties in a safe `group.key=value` format, one per line.
  Currently exposes `vm.memory_mb` which reports the resolved memory
  requirement in megabytes, respecting the `QEMU_MEM_OPTION` environment
  variable.

  The query mode parses common QEMU memory formats including plain numbers
  (`-m 2048`), gigabyte suffixes (`-m 4G`), and megabyte suffixes (`-m 512M`,
  case-insensitive). Unsupported formats return `vm.memory_mb=error: ...` for
  safe error handling.

  This introspection capability enables external tools to make informed
  decisions about resource allocation. Additional properties (CPU count,
  architecture, etc.) may be added in future releases.

* Improve generated `.run` script structure and customization clarity.

  The generated `.run` launchers are now easier to read and maintain:

  - The `--query` preamble is generated from one shared definition, reducing
    duplication across generated rules and Ubuntu Core rules.
  - The QEMU launch command is emitted as a readable multi-line block instead
    of one very long line.
  - Launch-time defaults are split into explicit local variables and late-bound
    assignments, making it easier to see what each customization knob resolves
    to while preserving environment overrides.

  For local development speed, `.run` generation can now skip requiring the
  local `.qcow2` file by setting `GARDEN_RUN_REQUIRES_QCOW2=`.

* Add memory availability checking before VM allocation.

  The `image-garden allocate` command now checks if sufficient system memory is
  available before allocating a virtual machine, using the new `--query` mode
  to determine memory requirements.

  The check accounts for QEMU overhead (1.5x multiplier on VM memory) and
  reserves memory for the host system. The reserve defaults to 2048MB for
  graphical sessions (x11/wayland) or 1024MB for other session types, and can
  be customized via the `GARDEN_MEMORY_RESERVE` environment variable.

  A warning is displayed if `VM_memory × 1.5 + GARDEN_MEMORY_RESERVE >
  MemAvailable`, helping prevent out-of-memory situations and performance
  degradation from excessive swapping.

* Add support for listing running virtual machines with `image-garden ps`.
  The output includes ADDRESS, PID, RSS (memory in MB), and SYSTEM columns.

* Add support for EOL Ubuntu releases between 16.04 and 24.10.

  Missing interim cloud images are now available as x86_64 targets for
  Ubuntu 16.10, 17.04, 17.10, 18.10, 19.04, 19.10, 20.10, 21.04, 21.10,
  22.10, 23.04 and 24.10.

  Cloud-init APT configuration now uses
  `http://old-releases.ubuntu.com/ubuntu` for EOL Ubuntu interim releases in
  this range (currently 16.10 through 24.10). This extends the previous
  23.10-specific behavior to the full EOL interim set in that range.

* Add support for attempting to use a fixed port when allocating a virtual
  machine. When the `-p PORT` option is given to `image-garden allocate` then
  that port will be used, if it is free, instead of the randomized value. Note
  that selecting a port that is in use will still fall back to randomization.

* The generated release tarball no longer lacks the .mk files (oops).

* The `mkpasswd` program (from the `whois` package) is no longer required.
  Plain text passwords are now used instead of hashed passwords in the
  cloud-init configuration.

* Add ubuntu-core-22+dangerous and ubuntu-core-24+dangerous image variants.

  The dangerous images use a model with `grade: dangerous` which allows
  some operations that are normally blocked, like installing unsigned gadget
  snaps. It is useful for exploration and development.

Changes in 0.4.2:

* Add support for downloading images with a given, known checksum
  using the command `image-garden download-with-sha256sum URL SHA256`.

* Add well-known sha256 checksums to all Oracle cloud images.

* In the CI/CD configuration systems derived from RHEL 10 are now marked as
  needing at least a haswell CPU (aka x86_64-v3). Users of older hardware
  devices will not be able to boot such systems without setting
  `QEMU_CPU_X86_64=Haswell` (or newer). See the output of `qemu-system-x86_64
  -cpu help` for a complete list of options. For details as described by the
  Rocky project, see https://docs.rockylinux.org/10/guides/minimum_hardware_requirements/

* All cross-arch tests are marked as non-fatal as they time out on our aging
  and slow infrastructure.

* Alpine Linux is updated to release 3.23.2, and is verified with a sha256 checksum.

Changes in 0.4:

* Add `image-garden rebase SYSTEM.ARCH` command.

  This command can be used to reset the base image in the virtual machine disk
  image to the use image-garden cache directory of the current system. It is
  especially useful in Continuous Integration (CI) environments where cache
  from one system type may be used in another system type, where everything is
  compatible except for the effective location of `$GARDEN_DL_DIR`.

  Only images with a backing file, with a matching base image in
  `$GARDEN_DL_DIR`, can be rebased.

* Improve `image-garden allocate` used port detection.

  Port allocation is now using randomized probing in the range 5000-9999. This
  should reduce possibility of clashes caused by rapid parallel allocation, as
  well as properly detect occupied port numbers.

* Automatically use `nice` on desktop sessions.

  When `$XDG_SESSION_TYPE` is either `wayland` or `x11` (but not `tty`) then
  use `nice` to lower the priority of started virtual machines. This should
  make long-running tests less noticeable for interactive desktop work.

  Nice is also used for initial image construction.

* Introduce build-time rule generation system.

  This way the package build-depends on Python and retains the make interface
  that requires no complex downstream packaging updates. Ubuntu, Debian, Fedora,
  CentOS, Oracle, AlmaLinux, RockyLinux, AlmaLinux, ArchLinux, openSUSE and
  AmazonLinux cloud images are now defined in the `data/ubuntu.ini`,
  `data/debian.ini`, `data/fedora.ini`, `data/centos.ini`, `data/oracle.ini`,
  `data/almalinux.ini`, `data/rocky.ini`, `data/alpine.ini`,
  `data/archlinux.ini`, `data/opensuse.ini` and `data/amazonlinux.ini` files,
  and the long and repetitive make rules are removed.

* Fedora 38 download URL has been updated to
  `https://dl.fedoraproject.org/pub/archive/fedora/linux/releases/...` which
  restores access to an image that is not actively maintained in the mirror
  network.

* AlmaLinux 10 is now supported.

* RockyLinux 10 is now supported.

* OracleLinux 7 is now supported.

* OracleLinux 10 is now supported.

* AlpineLinux 3 is updated from release 3.21.2 to release 3.22.

* AmazonLinux 2 is now supported.

* Fedora 43 is now supported.

* openSUSE Leap 16.0 is now supported.

* It is recommended to escape `+` as `-plus-` for working with `spread`.

* Ubuntu 14.04 is finally supported.

* Ubuntu 24.10 is no longer supported, having been removed from Ubuntu servers.

* Ubuntu 26.04 is now supported.

* All images are downloaded using http protocol, to make it possible to use
  http proxies to avoid excessive traffic. This does come at the cost of
  lowered overall security.

* Nearly all images are now verified against a checksum file that is downloaded
  over https. The exceptions are: oracle, alpine and gentoo. Those will be supported
  in the future.

* The download routine is now more resilient against interruptions being mistreated
  as finished downloads. This should reduce the number of failed tests that are caused
  by silently corrupted or partial downloads.

* Use -cpu neoverse-n1 for amazonlinux-cloud-{2,2023}.aarch64 systems. Thanks
  to Alex Bennée for the suggestion.

* The default configuration for aarch64 virtual machines now allows
  more than eight virtual CPUs, where qemu version allows this. This is done by
  using the maxiumum version of GIC instead of the default version.

* Gentoo is now supported by image-garden, but not by spread. Upstream spread
  uses relatively old selection of crypto algorithms. At present the Go ssh
  client built into spread is unable to connect to a started instance.

* Initial support for riscv64 system emulation.

  A number of Ubuntu systems are supported (since Ubuntu 24.04).

  Fedora 42 is also supported.

* Initial support for s390x system emulation.

  A number of systems are supported: Ubuntu (since Ubuntu 18.04) as well as Fedora (since 42)

* Initial support for ppc64 system emulation.

  A small number of systems are supported: Ubuntu (since Ubuntu 14.04).

  Currently all systems emulate a virtual Power 9 processor in a P-Series machine.

* Cloud-init rules are now allowed to reboot the system. Cloud-init
  execution will continue normally until finished.

Changes in 0.3.4:

* This version had no public changes except for in the snap package.

Changes in 0.3.3:

* Make all systems compatible with `QEMU_ENV_QUIRKS` feature.
  The placement of `exec` has moved after the quirks are applied, allowing
  quirks to freely export environment variables.

Changes in 0.3.2:

* Allow root to authenticate with a password on Ubuntu 16.04 systems.

Changes in 0.3.1:

* Replace dependency on `genisoimage` with `xorriso`.

* Properly detect changes to `.image-garden.mk` when `.image-garden/` directory
  is used to isolate temporary files to a hidden sub-directory.

* Allow authenticating as `root` with password `root` to all images with
  the exception of Ubuntu Core systems.

Changes in 0.3:

* Remove support for Fedora 42 Beta.

* Add support for Fedora 42.

* Add support for Ubuntu 25.10.

* Add new command `image-garden news` shows the last changelog
  entry. An optional argument may be used to see more than one entry.
  For example `image-garden news 2` shows last two entries.

Changes in 0.2.2:

* Stage dependencies needed by `wget` in the snap package.

Changes in 0.2.1:

* Fedora 42 (beta) is now supported.

* Image Garden is now available as a snap package.

Changes in 0.2:

* Amazon Linux 2023 is now supported.

* `QEMU_ENV_QUIRKS` mechanism allows persistently customising environment
  variables before invoking QEMU. This allows selecting different network or
  storage details.

* Ubuntu Core 16, 18, 20, 22 and 24 are now supported.
  Ubuntu Core 16, 18 and 20 do not support aarch64 architecture with generic
  images.

* Debian Sid is now explicitly supported as a distinct entity.

* The `image-garden allocate` command allows allocating machine that persists
  changes from one invocation to another by setting the environment variable
  `QEMU_SNAPSHOT_OPTION=""` (the value is empty). This may allow debugging
  boot failures, especially when coupled with persistent journal inside the
  virtual machine or with systemd debug shell or systemd emergency shell.

* Presence of the `.image-garden` directory now causes `image-garden` to create
  all image and log files there. This mode can be used to significantly reduce
  clutter in the root directory of the project.

* `image-garden --version` is now equivalent to `image-garden version`.

Changes in 0.1.1:

* Presence of `.image-garden.mk` file is now correctly reflected in dependencies
  of the `*.user-data` files, so that editing the local makefile automatically
  causes all the disk images to become outdated.

* Using `image-garden make -B` should no longer re-download everything, as
  `wget` is now called with `--no-clobber` and is smart enough to notice that
  re-downloading complete images is not required.

* Image garden now comes with a manual page. See `man image-garden` to learn about
  all the documented features.

* Oracle Cloud release 8 is now supported.

* SSH service is configured with "UsePAM yes" by default.

Changes in 0.1:

 * Initial release.
