Skip to content
Closed
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
9 changes: 8 additions & 1 deletion .github/workflows/qemu-emulator-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,27 @@ jobs:
- name: Generate emulator env
run: node docker/local-emulator/generate-env-development.mjs

# VM boot + service verification is amd64-only. Under same-arch TCG on
# the arm64 runner there's no KVM, and the Next.js backend can't come
# up within any reasonable window under software emulation — same
# reason the build-time smoke test is skipped on arm64. The arm64
# image is built and uploaded blind; it runs on real arm64 hardware.
- name: Start emulator and verify
if: matrix.arch == 'amd64'
run: |
chmod +x docker/local-emulator/qemu/run-emulator.sh
EMULATOR_ARCH=${{ matrix.arch }} \
EMULATOR_READY_TIMEOUT=3200 \
docker/local-emulator/qemu/run-emulator.sh start

- name: Verify services are healthy
if: matrix.arch == 'amd64'
run: |
EMULATOR_ARCH=${{ matrix.arch }} \
docker/local-emulator/qemu/run-emulator.sh status

- name: Stop emulator
if: always()
if: always() && matrix.arch == 'amd64'
run: |
EMULATOR_ARCH=${{ matrix.arch }} \
docker/local-emulator/qemu/run-emulator.sh stop
Expand Down
31 changes: 12 additions & 19 deletions docker/local-emulator/qemu/cloud-init/emulator/user-data
Original file line number Diff line number Diff line change
Expand Up @@ -399,28 +399,21 @@ write_files:
- stack-local-emulator:final
log "Flatten done."

log "Saving final image to /var/tmp..."
log "Pruning intermediate images in place..."
docker rm flatten
docker save stack-local-emulator:final -o /var/tmp/final-image.tar
mv /var/lib/docker/volumes /var/tmp/volumes-backup
log "Nuking Docker storage and reloading..."
systemctl stop docker containerd
rm -rf /var/lib/docker /var/lib/containerd
systemctl start docker containerd
until docker info >/dev/null 2>&1; do sleep 1; done
docker load -i /var/tmp/final-image.tar
docker rmi stack-local-emulator stack-local-emulator-slim || true
docker tag stack-local-emulator:final stack-local-emulator
docker rmi stack-local-emulator:final || true
rm -f /var/tmp/final-image.tar
systemctl stop docker
rm -rf /var/lib/docker/volumes
mv /var/tmp/volumes-backup /var/lib/docker/volumes
systemctl start docker
log "Docker storage rebuilt."

log "Zeroing free space for qcow2 compression..."
dd if=/dev/zero of=/zero.fill bs=1M 2>/dev/null || true
rm -f /zero.fill
docker builder prune -af || true
# Must be `prune -f` (dangling only), NOT `prune -af`. With -a, docker
# deletes every image that isn't referenced by a running/stopped
# container — at this point stack.service is only systemctl enable'd,
# not yet started, so the freshly-tagged stack-local-emulator image
# has zero container refs and would be nuked, bricking the final qcow2.
docker image prune -f || true
log "Intermediate images pruned."

log "Releasing free space for qcow2 compression (fstrim)..."
sync
fstrim -av 2>/dev/null || true
log "slim-docker-image done."
Expand Down
Loading