ci: storage and answer services move to a VM inside the CI sandbox (1/2)

The nested PVE guests live on an isolated VLAN with no route to the
runner network (ADR 0032, homelab repo), and the runner-hosted Docker
services died with each ephemeral ARC pod anyway. A small cloud-image VM
in the ci pool now serves NFS, iSCSI, and the auto-install answer files
from inside the sandbox. Includes fixes from Codex and in-house review:
bpg provider >= 0.79.0, serial console for the resized cloud image,
key-based SSH (cloud images refuse password auth), CIDR validation,
storage VM in the headroom check, docker socket mounts removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
goodolclint-claude[bot]
2026-08-31 19:52:36 +00:00
committed by GitHub
parent dc4d01c6fe
commit f48f0ea9ae
7 changed files with 228 additions and 49 deletions
+7 -10
View File
@@ -24,6 +24,9 @@ name: Integration Tests
# node with the most free memory and refuses to run when
# no node has enough headroom — the token's user needs
# PVEAuditor on /nodes for the memory stats.
# STORAGE_VM_IP - Static CIDR address for the shared storage/answer-server
# VM on the CI VLAN (default: 172.16.60.60/24)
# STORAGE_VM_GATEWAY - Gateway + DNS for that VM (default: 172.16.60.1)
#
# Optional secrets (for skip_provision mode):
# PVETEST_HOST - Hostname or IP of a pre-existing nested PVE
@@ -122,11 +125,6 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
volumes:
- /opt/pve-integration:/opt/pve-integration
# WARNING: The Docker socket is mounted to allow storage containers to be
# managed from within the job container. This grants root-equivalent access
# to the runner's Docker daemon. Only use on dedicated, isolated self-hosted
# runners — never on shared runners.
- /var/run/docker.sock:/var/run/docker.sock
steps:
- uses: actions/checkout@v7
@@ -138,6 +136,8 @@ jobs:
PVE_API_TOKEN: ${{ secrets.PVE_API_TOKEN }}
PVE_TARGET_NODE: ${{ vars.PVE_TARGET_NODE }}
PVE_PASSWORD: ${{ secrets.PVE_TEST_PASSWORD }}
STORAGE_VM_IP: ${{ vars.STORAGE_VM_IP }}
STORAGE_VM_GATEWAY: ${{ vars.STORAGE_VM_GATEWAY }}
TF_VAR_disk_storage: ${{ vars.DISK_STORAGE }}
TF_VAR_iso_storage: ${{ vars.ISO_STORAGE }}
TF_VAR_network_bridge: ${{ vars.NETWORK_BRIDGE }}
@@ -201,11 +201,6 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
volumes:
- /opt/pve-integration:/opt/pve-integration
# WARNING: The Docker socket is mounted to allow storage containers to be
# stopped from within the job container. This grants root-equivalent access
# to the runner's Docker daemon. Only use on dedicated, isolated self-hosted
# runners — never on shared runners.
- /var/run/docker.sock:/var/run/docker.sock
steps:
- uses: actions/checkout@v7
@@ -217,6 +212,8 @@ jobs:
PVE_API_TOKEN: ${{ secrets.PVE_API_TOKEN }}
PVE_TARGET_NODE: ${{ vars.PVE_TARGET_NODE }}
PVE_PASSWORD: ${{ secrets.PVE_TEST_PASSWORD }}
STORAGE_VM_IP: ${{ vars.STORAGE_VM_IP }}
STORAGE_VM_GATEWAY: ${{ vars.STORAGE_VM_GATEWAY }}
TF_VAR_disk_storage: ${{ vars.DISK_STORAGE }}
TF_VAR_iso_storage: ${{ vars.ISO_STORAGE }}
TF_VAR_network_bridge: ${{ vars.NETWORK_BRIDGE }}