mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
186 lines
6.9 KiB
YAML
186 lines
6.9 KiB
YAML
name: Publish System AMIs
|
|
|
|
# Builds the system AMIs (libguestfs, on the runner) and publishes each
|
|
# compressed qcow2 + .sha256 sidecar to the Cloudflare R2 bucket that backs
|
|
# iso.mulgadc.com/system-ami/. Six images ship:
|
|
# spinifex-eks-node Alpine EKS K3s node (server|agent, role at boot)
|
|
# spinifex-ecs-node Alpine ECS container instance
|
|
# spinifex-eks-node-gpu Ubuntu EKS K3s GPU worker (NVIDIA driver + toolkit)
|
|
# spinifex-ecs-node-gpu Ubuntu ECS GPU container instance
|
|
# spinifex-rds-postgres Alpine RDS PostgreSQL instance
|
|
# spinifex-rds-mariadb Alpine RDS MariaDB instance
|
|
# Operators then install them on any cluster with:
|
|
# spx admin images import --name spinifex-eks-node
|
|
# spx admin images import --name spinifex-ecs-node
|
|
# spx admin images import --name spinifex-eks-node-gpu
|
|
# spx admin images import --name spinifex-ecs-node-gpu
|
|
# spx admin images import --name spinifex-rds-postgres
|
|
# spx admin images import --name spinifex-rds-mariadb
|
|
#
|
|
# Publishing overwrites the mirror artifact, so it is a deliberate action, not
|
|
# something every push should trigger: it runs manually, or from release.yml
|
|
# once a tag has passed its gates. The `variant` input scopes which images
|
|
# build — the Ubuntu GPU legs are 16G and much slower (NVIDIA driver download +
|
|
# DKMS build), so publishing only the CPU AMIs stays cheap.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
variant:
|
|
description: "Which images to build"
|
|
type: choice
|
|
default: all
|
|
options:
|
|
- all
|
|
- cpu
|
|
- gpu
|
|
- rds
|
|
dry_run:
|
|
description: "Build + convert only; skip the R2 upload"
|
|
type: boolean
|
|
default: false
|
|
workflow_call:
|
|
inputs:
|
|
variant:
|
|
description: "Which images to build (all|cpu|gpu|rds)"
|
|
type: string
|
|
default: all
|
|
dry_run:
|
|
description: "Build + convert only; skip the R2 upload"
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: publish-eks-ami
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
matrix:
|
|
name: Resolve image matrix
|
|
runs-on: [ self-hosted, ci-single ]
|
|
outputs:
|
|
images: ${{ steps.gen.outputs.images }}
|
|
steps:
|
|
- name: Select images for variant
|
|
id: gen
|
|
env:
|
|
VARIANT: ${{ inputs.variant }}
|
|
run: |
|
|
set -euo pipefail
|
|
cpu='{"name":"spinifex-eks-node","manifest":"scripts/images/eks-node/manifest.conf"},{"name":"spinifex-ecs-node","manifest":"scripts/images/ecs-agent/manifest.conf"}'
|
|
gpu='{"name":"spinifex-eks-node-gpu","manifest":"scripts/images/eks-node-gpu/manifest.conf"},{"name":"spinifex-ecs-node-gpu","manifest":"scripts/images/ecs-agent-gpu/manifest.conf"}'
|
|
rds='{"name":"spinifex-rds-postgres","manifest":"scripts/images/rds-postgres/manifest.conf"},{"name":"spinifex-rds-mariadb","manifest":"scripts/images/rds-mariadb/manifest.conf"}'
|
|
case "${VARIANT}" in
|
|
cpu) items="${cpu}" ;;
|
|
gpu) items="${gpu}" ;;
|
|
rds) items="${rds}" ;;
|
|
*) items="${cpu},${gpu},${rds}" ;;
|
|
esac
|
|
echo "images={\"include\":[${items}]}" >> "$GITHUB_OUTPUT"
|
|
|
|
publish:
|
|
name: Build + publish ${{ matrix.name }}
|
|
needs: matrix
|
|
runs-on: [ self-hosted, ci-single ]
|
|
strategy:
|
|
fail-fast: false
|
|
# ci-single is one runner and each GPU build needs ~16G of scratch disk;
|
|
# serialise the legs so they never contend for /_temp or the mirror.
|
|
max-parallel: 1
|
|
matrix: ${{ fromJSON(needs.matrix.outputs.images) }}
|
|
|
|
steps:
|
|
- name: Checkout Spinifex
|
|
uses: actions/checkout@v7
|
|
with:
|
|
path: spinifex
|
|
|
|
- name: Checkout Viperblock
|
|
uses: actions/checkout@v7
|
|
with:
|
|
repository: mulgadc/viperblock
|
|
ref: dev
|
|
path: viperblock
|
|
|
|
- name: Checkout Predastore
|
|
uses: actions/checkout@v7
|
|
with:
|
|
repository: mulgadc/predastore
|
|
ref: dev
|
|
path: predastore
|
|
|
|
- name: Checkout Northstar
|
|
uses: actions/checkout@v7
|
|
with:
|
|
repository: mulgadc/northstar
|
|
ref: dev
|
|
path: northstar
|
|
|
|
- name: Checkout Bluebottle
|
|
uses: actions/checkout@v7
|
|
with:
|
|
repository: mulgadc/bluebottle
|
|
ref: dev
|
|
path: bluebottle
|
|
|
|
- name: Setup Go
|
|
uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: "spinifex/go.mod"
|
|
# Self-hosted runner: the Go module + build cache already persists on
|
|
# local disk between runs. setup-go's cache-save ("Post Setup Go")
|
|
# otherwise re-uploads hundreds of MB to the Actions cache backend,
|
|
# taking longer than the build itself.
|
|
cache: false
|
|
|
|
- name: Setup Go Workspace
|
|
# Idempotent: the ci-single runner reuses one workspace across matrix
|
|
# legs and runs, and checkout never scrubs the root go.work. Remove any
|
|
# stale file so each leg re-inits cleanly instead of failing on
|
|
# "go.work already exists".
|
|
run: |
|
|
rm -f go.work go.work.sum
|
|
go work init ./spinifex ./viperblock ./predastore ./northstar ./bluebottle
|
|
|
|
- name: Install build + upload tooling
|
|
run: |
|
|
set -euo pipefail
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y --no-install-recommends libguestfs-tools qemu-utils
|
|
if ! command -v aws &>/dev/null; then
|
|
curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip
|
|
unzip -q /tmp/awscliv2.zip -d /tmp/aws-install
|
|
sudo /tmp/aws-install/aws/install
|
|
rm -rf /tmp/awscliv2.zip /tmp/aws-install
|
|
fi
|
|
|
|
- name: Build + publish ${{ matrix.name }} to R2
|
|
working-directory: spinifex
|
|
env:
|
|
# Map the repo's R2 secrets onto the names publish-system-image.sh reads.
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_SECRET_ACCESS_KEY }}
|
|
R2_ENDPOINT: ${{ secrets.CF_R2_ENDPOINT_URL }}
|
|
R2_BUCKET: spinifex-iso
|
|
DRY_RUN: ${{ inputs.dry_run }}
|
|
MANIFEST: ${{ matrix.manifest }}
|
|
# Ubuntu GPU images are 16G — a RAM-backed /tmp cannot hold the qcow2 +
|
|
# expanded raw, so point the build scratch at the runner's on-disk
|
|
# _temp. Harmless for the small Alpine legs too.
|
|
SYSTEM_IMAGE_BUILD_DIR: ${{ runner.temp }}/system-image-build
|
|
run: |
|
|
set -euo pipefail
|
|
# libguestfs needs to read a host kernel; Ubuntu ships it mode 0600.
|
|
# direct backend = no libvirt on the runner.
|
|
export LIBGUESTFS_BACKEND=direct
|
|
sudo chmod 0644 /boot/vmlinuz-* || true
|
|
mkdir -p "${SYSTEM_IMAGE_BUILD_DIR}"
|
|
FLAGS=(--build)
|
|
if [[ "${DRY_RUN}" == "true" ]]; then
|
|
FLAGS+=(--dry-run)
|
|
fi
|
|
./scripts/publish-system-image.sh "${MANIFEST}" "${FLAGS[@]}"
|