feat(runners): decoupled Pulumi stack for the fenced runner fleet (R5)
All checks were successful
CI / preflight (push) Successful in 4s
CI / typecheck (push) Successful in 13s
pulumi-preview / preview (push) Successful in 17s

A separate, isolated Pulumi project (peer to bootstrap/provision/offsite-backup)
that provisions runner VM(s) on a libvirt host and registers Forgejo Actions
runners with a distinct `fenced` label — so ecosystem/untrusted jobs run OFF the
forge VM.

Decoupled ON PURPOSE: a @pulumi/libvirt provider dials the runner host on every
up/refresh, so keeping it in `bootstrap` would make the foundation undeployable/
unrefreshable whenever the host (crunchy01) is down or unreachable (the Terraform
coupling trap). As its own stack, bootstrap never imports it — foundation ops
never touch crunchy01, and this stack's health is independent. One-way dependency:
it mints a runner token FROM the forge, i.e. runs after the foundation stands.

Codifies what was built + hardened by hand this session (runners/README.md):
Ubuntu VM on the LAN bridge (docker + qemu-guest-agent via cloud-init), the
kube-router-proof FORWARD timer, and runner registration. Typechecked; the live
`pulumi up` cutover from the hand-built VM is the remaining validation step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Andreas Niemann 2026-07-01 03:15:39 +02:00
parent 9bea030a47
commit cfa71847ba
8 changed files with 402 additions and 1 deletions

View file

@ -98,6 +98,21 @@
"typescript": "^5.0.0",
},
},
"runners": {
"name": "@olsitec/foundation-runners",
"version": "0.0.0",
"dependencies": {
"@pulumi/command": "^1.1.3",
"@pulumi/libvirt": "^0.5.3",
"@pulumi/pulumi": "^3.138.0",
"js-yaml": "^4.1.0",
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
"@types/node": "^18",
"typescript": "^5.0.0",
},
},
},
"packages": {
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
@ -180,6 +195,8 @@
"@olsitec/foundation-provision": ["@olsitec/foundation-provision@workspace:provision"],
"@olsitec/foundation-runners": ["@olsitec/foundation-runners@workspace:runners"],
"@olsitec/pulumi-docker": ["@olsitec/pulumi-docker@workspace:packages/pulumi-docker"],
"@olsitec/pulumi-hetzner": ["@olsitec/pulumi-hetzner@workspace:packages/pulumi-hetzner"],
@ -252,6 +269,8 @@
"@pulumi/hcloud": ["@pulumi/hcloud@1.39.0", "", { "dependencies": { "@pulumi/pulumi": "^3.142.0" } }, "sha512-rrjOZ1bPliOpsuoGBrd6b9GOeM+CoNSLTJrd061JzwAREdztVP6vy8UEROQj7zIUypEI0+eCqXAA1bxYIQSwkQ=="],
"@pulumi/libvirt": ["@pulumi/libvirt@0.5.4", "", { "dependencies": { "@pulumi/pulumi": "^3.142.0" } }, "sha512-iStzokbaU71cySC05IS+OX9Rx+CpfZIYeRiehqSZ60DKpd4Ou4XgZEp7GmQE8E2Cd/Ou7HA/MUnDxyKk9TmsPQ=="],
"@pulumi/minio": ["@pulumi/minio@0.16.9", "", { "dependencies": { "@pulumi/pulumi": "^3.142.0" } }, "sha512-druJ9i1edmXbzTTyHaH2W5xK2BRB4k4O02jTV6FBk1cRp8na9y5dDIrzWjDTRTEqXSRjSNruEWzltyj6Bh2aVg=="],
"@pulumi/pulumi": ["@pulumi/pulumi@3.248.0", "", { "dependencies": { "@grpc/grpc-js": "^1.10.1", "@logdna/tail-file": "^2.0.6", "@npmcli/arborist": "^9.0.0", "@opentelemetry/api": "^1.9", "@opentelemetry/exporter-trace-otlp-grpc": "^0.57", "@opentelemetry/exporter-zipkin": "^1.30", "@opentelemetry/instrumentation": "^0.57", "@opentelemetry/instrumentation-grpc": "^0.57", "@opentelemetry/resources": "^1.30", "@opentelemetry/sdk-trace-base": "^1.30", "@opentelemetry/sdk-trace-node": "^1.30", "@types/google-protobuf": "^3.15.5", "@types/semver": "^7.5.6", "@types/tmp": "^0.2.6", "execa": "^5.1.0", "fdir": "^6.5.0", "google-protobuf": "^3.21.4", "ini": "^2.0.0", "js-yaml": "^4.0.0", "minimist": "^1.2.6", "normalize-package-data": "^6.0.0", "picomatch": "^4.0.0", "require-from-string": "^2.0.1", "semver": "^7.5.2", "source-map-support": "^0.5.6", "tmp": "^0.2.4", "upath": "^1.1.0" }, "peerDependencies": { "ts-node": ">= 7.0.1 < 12", "typescript": ">= 3.8.3 < 7" }, "optionalPeers": ["ts-node", "typescript"] }, "sha512-EqgeHjVIqMS8voAM7F8SOzFAMHnVXUDdKTNF1o3Lg85YwVI0j4/eIlWG0iIVAWJl3DX0KOOM6++X0wLKHWWwmQ=="],