Skip to content

ADR 0037: S3 Artifact and Metadata Publishing Contract Between Builder and GLCI

Date: 2026-08-04

Status

Accepted

Supersedes ADR 31

Context

  • Build artifacts produced by the Garden Linux builder are to be published and later consumed by GLCI.
  • AWS S3 was chosen as the interface between build and consumption:
    • GitHub Actions (or equivalent CI) running the image build upload artifacts and metadata to S3.
    • GLCI consumes artifacts and metadata from S3 asynchronously, potentially long after the build finished.
  • For this workflow to be reliable, a clear, documented interface is required that specifies:
    • Which files are uploaded
    • Where they are uploaded in S3
    • Which metadata is produced
    • Which builder outputs are authoritative inputs for that metadata
  • Currently, the upload to S3 and metadata generation is handled by python-gardenlinux-lib.
  • Misalignment between builder output and how metadata is derived has caused issues, most notably while consolidating openstack / openstackbaremetal into openstack and openstack-metal.
  • ADR 31 established this interface. It assumed a one-to-one relationship between a build and a published artifact, and it defined the default value of any non-required requirements field as false.
  • Two needs have since emerged that the ADR 31 contract cannot express:
    • Some artifacts must be published as a single combined artifact assembled from several builds — the motivating case being container images, published as one multi-architecture image. The interface must carry abuild-provided signal of which builds belong together.
    • Expressing that signal requires an optional field that is not a boolean, but the ADR 31 default-value rule only defines a default for booleans.
  • A clear documented interface between build artifacts and GLCI inputs is required to avoid future ambiguity and regressions.

This ADR supersedes ADR 31 and restates the interface in full so that it remains the single authoritative document.

Decision

1. Authoritative Inputs

The builder output files are the sole authoritative inputs for publishing artifacts and metadata to S3.

The task of the upload logic is:

  • to upload files to S3, and
  • to translate builder output into metadata understood by GLCI.

It must not:

  • enforce additional assumptions about structure,
  • reinterpret semantics,
  • or impose constraints beyond what is explicitly defined in this and subsequent ADRs.

1.1 Release Metadata File (*.release)

Format: key-value file compatible with os-release style

Required fields

FieldMeaning
GARDENLINUX_CNAMECanonical name, uniquely identifying the build target
GARDENLINUX_VERSIONVersion string
GARDENLINUX_COMMIT_IDCommit identifier (may be local)
GARDENLINUX_COMMIT_ID_LONGCommit hash or local
GARDENLINUX_PLATFORMSingle authoritative platform
GARDENLINUX_FEATURESComma-separated feature list
GARDENLINUX_FEATURES_ELEMENTSFeature elements (informational only, not used in publishing)
GARDENLINUX_FEATURES_FLAGSFeature flags (informational only, not used in publishing)
GARDENLINUX_FEATURES_PLATFORMSFeature platforms (informational only, not used in publishing)

Optional fields

FieldMeaning
GARDENLINUX_PLATFORM_VARIANTPlatform sub-variant

Platform semantics

  • GARDENLINUX_PLATFORM is the one and only platform value used for publishing.
  • This guarantees exactly one platform value, or a deliberate “frankenstein” value if a non-standard image was built.
  • GARDENLINUX_FEATURES_PLATFORMS must not be used as input to any publishing or routing decision:
    • It may contain zero, one, or multiple values.
    • It reflects feature graph structure, not publishing semantics.

1.2 Requirements File (*.requirements)

Format: simple key-value file (one key=value entry per line).

Fields

FieldTypeRequiredMeaning
archstringyesArchitecture of the image
publishing_groupstringnoOpaque group identifier, builds sharing a value are published as one artifact, empty means standalone
securebootboolnoSecure Boot is required
tpm2boolnoTPM 2.0 is required
uefiboolnoUEFI is required (not merely supported, for hybrid legacy and UEFI images this must be false)

For non-required fields, the default value is the zero value of the field's type: false for a bool, the empty string for a string.

1.3 Artifact Files

  • All remaining files in the artifact directory.
  • Each file represents a build output to be uploaded to S3.
  • Artifact files are opaque to the publishing contract; their internal structure is not interpreted.

2. Metadata Assembly

Exactly one metadata document is produced per build, referred to as the singles metadata.

2.1 Metadata Fields

The metadata document contains the following information:

Metadata KeyTypeSource
platformstringGARDENLINUX_PLATFORM
platform_variantstringGARDENLINUX_PLATFORM_VARIANT (if present)
architecturestringarch from requirements file
versionstringGARDENLINUX_VERSION
gardenlinux_epochintMajor version component of GARDENLINUX_VERSION
build_committishstringGARDENLINUX_COMMIT_ID_LONG
build_timestamptimestamp^1Filesystem timestamp of the release file
modifiersList of stringsParsed list from GARDENLINUX_FEATURES
require_uefibooluefi from requirements file
securebootboolsecureboot from requirements file
tpm2booltpm2 from requirements file
publishing_groupstringpublishing_group from requirements file (if present)
paths(see below)List of uploaded artifact descriptors
s3_bucketstringTarget S3 bucket
s3_keystringS3 path of the metadata document

The artifact descriptors in paths are of the form:

yaml
- name: <artifact_base_name>.<artifact_file_extension>
  suffix: .<artifact_file_extension>
  md5sum: <md5sum_of_artifact>
  sha256sum: <sha256sum_of_artifact>
  s3_key: <path_to_uploaded_artifact_object>
  s3_bucket_name: <s3_bucket>

No additional interpretation or normalization of these values is performed beyond format translation.

3. S3 Layout

3.1 Artifact Files

  • Artifact files are uploaded to S3 under implementation-defined paths.
  • Their placement is opaque to GLCI and not part of this contract.
  • The path to find the artifacts at is defined in the artifact descriptor keys s3_bucket_name and s3_key

3.2 Singles Metadata Document

  • Exactly one metadata document is uploaded per build.
  • Location (fixed and stable): meta/singles/<artifact_base_name>
  • Format: YAML
  • This document is the primary entry point for GLCI to discover build artifacts and associated metadata.

4. Responsibilities and Non-Responsibilities

Responsibilities of the Upload Logic

  • Upload build artifacts to S3.
  • Translate builder output into metadata consumable by GLCI.
  • Preserve builder intent and semantics exactly as expressed in the release file and requirements file.

Explicit Non-Responsibilities

  • Enforcing assumptions about naming conventions beyond documented extraction rules.
  • Inferring architecture from the canonical name or any other source than the requirements file.
  • Inferring platform semantics from feature graphs.
  • Inferring publishing group membership from any source other than the publishing_group value in the requirements file.

Consequences

  • The interface between builder output and GLCI input is explicit and stable.
  • Architecture handling is unambiguous and future-proof.
  • Platform handling is unambiguous and future-proof.
  • Build grouping is unambiguous and future-proof.
  • Builder semantics are preserved without reinterpretation.
  • Future refactors of publishing logic can be validated against this ADR.
  • Ambiguity and hidden assumptions in metadata generation are eliminated.