Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ self-hosted-runner:
- blacksmith-4vcpu-ubuntu-2404
- blacksmith-4vcpu-ubuntu-2404-arm
- blacksmith-8vcpu-ubuntu-2404
- blacksmith-16vcpu-ubuntu-2404
- blacksmith-32vcpu-ubuntu-2404
- large-linux-arm
- large-linux-x86
45 changes: 37 additions & 8 deletions .github/workflows/qemu-image-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@ on:
push:
paths:
- .github/workflows/qemu-image-build.yml
- Dockerfile-kubernetes
- ansible/vars.yml
- ebssurrogate/scripts/*
- nix/packages/build-qemu-image/*
- qemu.pkr.hcl
workflow_dispatch:
inputs:
arch:
description: 'Guest architecture (amd64 is experimental and publishes only to staging)'
type: choice
default: arm64
options:
- arm64
- amd64

permissions:
contents: read
Expand All @@ -34,7 +43,10 @@ jobs:
strategy:
matrix:
postgres_version: ${{ fromJson(needs.prepare.outputs.postgres_versions) }}
runs-on: arm-native-runner
arch: ["${{ inputs.arch || 'arm64' }}"]
runs-on: ${{ matrix.arch == 'amd64' && 'blacksmith-16vcpu-ubuntu-2404' || 'arm-native-runner' }}
env:
TARGET_ARCH: ${{ matrix.arch }}
timeout-minutes: 150
permissions:
contents: write
Expand All @@ -59,14 +71,28 @@ jobs:
uses: ./.github/actions/nix-install-ephemeral

- name: Run checks if triggered manually
if: ${{ github.event_name == 'workflow_dispatch' }}
if: ${{ github.event_name == 'workflow_dispatch' && matrix.arch == 'arm64' }}
run: |
SUFFIX=$(nix run nixpkgs#yq -- ".postgres_release[\"postgres${{ matrix.postgres_version }}\"]" ansible/vars.yml | sed -E 's/[0-9\.]+(.*)$/\1/')
if [[ -z $SUFFIX ]] ; then
echo "Version must include non-numeric characters if built manually."
exit 1
fi

- name: Verify QEMU can use KVM
shell: bash
run: |
case "$TARGET_ARCH" in
amd64) QEMU=qemu-system-x86_64; MACHINE=q35 ;;
arm64) QEMU=qemu-system-aarch64; MACHINE=virt,gic-version=max,highmem=on ;;
*) echo "Unsupported architecture: $TARGET_ARCH" >&2; exit 1 ;;
esac
printf '%s\n' '{"execute":"qmp_capabilities"}' '{"execute":"query-kvm"}' '{"execute":"quit"}' |
nix shell --inputs-from . nixpkgs#qemu --command \
"$QEMU" -machine "$MACHINE,accel=kvm" -cpu host \
-m 128M -nodefaults -display none -S -qmp stdio |
jq -se 'any(.[]; .return.enabled == true)'

- name: Resolve git sha
id: resolve-git-sha
uses: ./.github/actions/resolve-git-sha
Expand All @@ -76,12 +102,15 @@ jobs:
- name: Build QEMU artifact
env:
GIT_SHA: ${{ steps.resolve-git-sha.outputs.sha }}
run: BUILD_QEMU_IMAGE_HW_VIRT_ONLY=1 nix run .#build-qemu-image "${{ matrix.postgres_version }}" arm64
run: BUILD_QEMU_IMAGE_HW_VIRT_ONLY=1 nix run .#build-qemu-image "${{ matrix.postgres_version }}" "$TARGET_ARCH"

- name: Grab release version
id: process_release_version
run: |
PG_VERSION=$(nix run nixpkgs#yq -- -r '.postgres_release["postgres'${{ matrix.postgres_version }}'"]' ansible/vars.yml)
if [[ "$TARGET_ARCH" == amd64 ]]; then
PG_VERSION="$PG_VERSION-amd64-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT"
fi
echo "version=$PG_VERSION" >> $GITHUB_OUTPUT

- name: configure aws credentials - staging
Expand All @@ -100,7 +129,7 @@ jobs:
env:
IMAGE_TAG: ${{ steps.process_release_version.outputs.version }}
run: |
docker build -f Dockerfile-kubernetes -t "postgres:$IMAGE_TAG" packer-work-qemu-*
docker build --platform "linux/$TARGET_ARCH" -f Dockerfile-kubernetes -t "postgres:$IMAGE_TAG" packer-work-qemu-*

- name: Push docker image to Amazon ECR
if: ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/') }}
Expand All @@ -114,19 +143,19 @@ jobs:

# TODO (darora): temporarily also push to prod account from here - add a guard to only publish proper tagged releases to prod?
- name: configure aws credentials - prod
if: ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/') }}
if: ${{ matrix.arch == 'arm64' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/')) }}
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
with:
role-to-assume: ${{ secrets.CONTROL_PLANE_PROD_ROLE }}
aws-region: "us-east-1"

- name: Login to Amazon ECR Prod
if: ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/') }}
if: ${{ matrix.arch == 'arm64' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/')) }}
id: login-ecr-private-prod
uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076 # v2.0.1

- name: Push docker image to Amazon ECR
if: ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/') }}
- name: Push docker image to Amazon ECR Prod
if: ${{ matrix.arch == 'arm64' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/')) }}
env:
REGISTRY: 156470330064.dkr.ecr.us-east-1.amazonaws.com
REPOSITORY: postgres-vm-image
Expand Down
24 changes: 18 additions & 6 deletions Dockerfile-kubernetes
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,23 @@ FROM alpine:3.23

ADD output-cloudimg/packer-cloudimg /disk/image.qcow2

RUN apk add --no-cache qemu-system-aarch64 qemu-img openssh-client aavmf virtiofsd \
&& truncate -s 64M /root/varstore.img \
&& truncate -s 64M /root/efi.img \
&& dd if=/usr/share/AAVMF/QEMU_EFI.fd of=/root/efi.img conv=notrunc \
&& qemu-img create -f qcow2 /tmp/disk.qcow2 -b /disk/image.qcow2 -F qcow2 \
&& apk del --no-cache aavmf qemu-img
RUN set -eux; \
case "$(apk --print-arch)" in \
aarch64) \
apk add --no-cache qemu-system-aarch64 aavmf; \
truncate -s 64M /root/varstore.img; \
truncate -s 64M /root/efi.img; \
dd if=/usr/share/AAVMF/QEMU_EFI.fd of=/root/efi.img conv=notrunc; \
apk del --no-cache aavmf ;; \
x86_64) \
apk add --no-cache qemu-system-x86_64 ovmf; \
cp /usr/share/OVMF/OVMF_CODE.fd /root/efi.img; \
cp /usr/share/OVMF/OVMF_VARS.fd /root/varstore.img; \
apk del --no-cache ovmf ;; \
*) echo "Unsupported architecture" >&2; exit 1 ;; \
esac; \
apk add --no-cache qemu-img openssh-client virtiofsd; \
qemu-img create -f qcow2 /tmp/disk.qcow2 -b /disk/image.qcow2 -F qcow2; \
apk del --no-cache qemu-img

CMD exec /bin/sh -c "trap : TERM INT; sleep 9999999999d & wait"
Loading