Signed Octavia amphora-haproxy images for OpenStack LBaaS, built per
OpenStack stable release
Report a bug
·
Request a feature
This repo builds Octavia amphora images — the qcow2 images deployed by OpenStack Octavia LBaaS as load-balancer instances. Unlike the other openimages.cloud repos (alpaquita, alpine, AL2023, …) which republish OS images for end-users, amphora is an OpenStack control plane component: it's consumed by the Octavia service in your cluster, not by tenants directly.
The build follows Octavia's own diskimage-create
workflow, which wraps diskimage-builder with the Octavia-specific
amphora-agent element + a curated set of dependencies. We let it
drive the build and republish through the openimages.cloud
signed-release pipeline.
The build pipeline is shared with the rest of open-img-cloud:
this repo only ships the VERSION, build/dib-build.sh, and a thin
caller workflow that delegates to the reusable build-dib-image.yml
in open-img-cloud/.github (@main).
<version> is the OpenStack series (e.g. 2025.2 for "Flamingo"),
which maps to the matching stable/X.Y branch of
opendev.org/openstack/octavia. The build pulls Octavia at that branch,
installs its diskimage-create requirements via a Python venv, and
runs the script with the corresponding upper-constraints URL from
opendev.org/openstack/requirements.
Tag your release as v<version> (e.g. v2025.2) to publish.
| OpenStack series | Codename | Octavia branch |
|---|---|---|
| 2024.1 | Caracal | stable/2024.1 |
| 2024.2 | Dalmatian | stable/2024.2 |
| 2025.1 | Epoxy | stable/2025.1 |
| 2025.2 | Flamingo | stable/2025.2 ← default |
| 2026.1 | TBD | stable/2026.1 |
Public CDN, served via Cloudflare in front of an R2 bucket (mirror of the source-of-truth Garage):
| URL pattern | Cache policy |
|---|---|
https://images.openimages.cloud/octavia-amphora/<version>/<filename> |
max-age=31536000, immutable |
https://images.openimages.cloud/octavia-amphora/latest/<filename> |
max-age=300 |
Browse: images.openimages.cloud/octavia-amphora/latest/
Filename: amphora-<version>-amd64-haproxy.qcow2 (e.g.
amphora-2025.2-amd64-haproxy.qcow2).
cosign 3.x:
sha256sum -c <filename>.sha256 # integrity
cosign verify-blob \
--bundle <filename>.bundle \
--new-bundle-format \
--certificate-identity-regexp '^https://github.com/open-img-cloud/\.github/\.github/workflows/build-dib-image\.yml@' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
<filename> # provenanceThe certificate identity points at the reusable DIB build workflow
in open-img-cloud/.github — that's where GitHub's OIDC binds the SAN
for keyless signing. To tie the artifact back to this repo's commit,
also check MANIFEST.json (commit, build_url, builder digest).
Once published, point your Octavia controller at the qcow2 in Glance:
# Pull the qcow2 (replace <V> with the OpenStack series, e.g. 2025.2)
curl -fLO https://images.openimages.cloud/octavia-amphora/<V>/amphora-<V>-amd64-haproxy.qcow2
# Upload to Glance with the amphora tag Octavia looks up
openstack image create \
--disk-format qcow2 --container-format bare \
--tag amphora \
--file amphora-<V>-amd64-haproxy.qcow2 \
"amphora-<V>-amd64-haproxy"
# Octavia will pick the latest image with the `amphora` tag at next
# load-balancer provisioning. To force migration of existing LBs:
# openstack loadbalancer failover <lb_id>- Maintainer bumps
VERSIONto the target OpenStack series (nowatch.ymlhere — OpenStack ships every 6 months on a known schedule, manual bump is fine). - Tag
v<version>triggersrelease.yml, which calls the sharedbuild-dib-image.yml@mainreusable workflow. - The reusable workflow runs
build/dib-build.shinside anubuntu:24.04container with--privileged(DIB needs loopback mounts for debootstrap). - The script clones
opendev.org/openstack/octaviaatstable/<version>, installs itsdiskimage-create/requirements.txtin a venv, then runsdiskimage-create.shwith the matching upper-constraints URL. - Output qcow2 is signed (cosign keyless), bundled with MANIFEST,
uploaded to Garage + R2, and Cloudflare cache for
latest/is purged.
VERSION single line, e.g. "2025.2"
build/
dib-build.sh DIB build hook (out_dir as $1, version as $2)
.github/workflows/
release.yml calls build-dib-image.yml on tag push
.gitignore repo-local override for global build/ exclusion
LICENSE GPL-2.0
- No cloud-init policy drop-in. Amphora isn't bootable by end-users
— its userdata is consumed by the
amphora-agentrunning inside the image, not generic cloud-init. The99_oic-policy.cfginjection that the libguestfs reusable does for OS images is irrelevant here. - No smoke test. Amphora boots into a constrained network namespace
driven by Octavia; the reusable
build-dib-image.ymlworkflow deliberately doesn't have a smoke step. Validation happens post-deploy via Octavia's own health checks. - Build container is
ubuntu:24.04, not the stackopshq libguestfs image, because the ubuntu-minimal DIB element needsdebootstrap+ apt deps. As a consequenceverify_builder: false— we trust Docker Hub'subuntu:24.04here. This may tighten later if we ship our own dib-builder image.
Fork, branch, PR. Keep the dib-build script focused on Octavia's
upstream diskimage-create.sh invocation; complex env wiring should
move to the workflow inputs rather than be hardcoded.
Distributed under the GPL-2.0 License. See LICENSE.
Kevin Allioli — kevin@stackops.ch · @stackopshq
Project: open-img-cloud/octavia-amphora