feat(railiance): implement CUST-WP-0032 Haskell build machine infra
Packer build definition, cloud-init autoinstall, GHCup toolchain script, boot-time registration agent (state-hub + autossh dual tunnel), systemd unit, key injection, remote-build Makefile, smoke test, and deployment README. All 15 tasks complete. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
147
infra/build-machines/haskell/haskell-build.pkr.hcl
Normal file
147
infra/build-machines/haskell/haskell-build.pkr.hcl
Normal file
@@ -0,0 +1,147 @@
|
||||
packer {
|
||||
required_plugins {
|
||||
virtualbox = {
|
||||
version = ">= 1.1.0"
|
||||
source = "github.com/hashicorp/virtualbox"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "vm_name" {
|
||||
type = string
|
||||
default = "haskell-build"
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
type = number
|
||||
default = 40960
|
||||
}
|
||||
|
||||
variable "memory" {
|
||||
type = number
|
||||
default = 8192
|
||||
}
|
||||
|
||||
variable "cpus" {
|
||||
type = number
|
||||
default = 4
|
||||
}
|
||||
|
||||
variable "ghc_primary_version" {
|
||||
type = string
|
||||
default = "9.8.4"
|
||||
}
|
||||
|
||||
variable "ghc_secondary_version" {
|
||||
type = string
|
||||
default = "9.6.6"
|
||||
}
|
||||
|
||||
variable "cabal_version" {
|
||||
type = string
|
||||
default = "3.12.1.0"
|
||||
}
|
||||
|
||||
variable "iso_url" {
|
||||
type = string
|
||||
default = "https://releases.ubuntu.com/24.04/ubuntu-24.04.2-live-server-amd64.iso"
|
||||
}
|
||||
|
||||
variable "iso_checksum" {
|
||||
type = string
|
||||
default = "sha256:d6dab0c3a657988501b4bd76f1297c053df710e06e0c3aece60dead24f270b4d"
|
||||
}
|
||||
|
||||
locals {
|
||||
timestamp = formatdate("YYYYMMDD", timestamp())
|
||||
}
|
||||
|
||||
source "virtualbox-iso" "haskell-build" {
|
||||
vm_name = var.vm_name
|
||||
guest_os_type = "Ubuntu_64"
|
||||
disk_size = var.disk_size
|
||||
hard_drive_interface = "sata"
|
||||
|
||||
memory = var.memory
|
||||
cpus = var.cpus
|
||||
|
||||
iso_url = var.iso_url
|
||||
iso_checksum = var.iso_checksum
|
||||
|
||||
# NAT during build — Packer needs internet for ISO + packages.
|
||||
# Bridged networking is set post-import by setup-vm.sh (adapter names
|
||||
# are laptop-specific and cannot be baked into the image).
|
||||
vboxmanage = [
|
||||
["modifyvm", "{{.Name}}", "--nat-localhostreachable1", "on"],
|
||||
]
|
||||
|
||||
http_directory = "files/cloud-init"
|
||||
|
||||
boot_wait = "5s"
|
||||
boot_command = [
|
||||
"c<wait>",
|
||||
"linux /casper/vmlinuz --- autoinstall ds='nocloud;s=http://{{.HTTPIP}}:{{.HTTPPort}}/'<enter><wait>",
|
||||
"initrd /casper/initrd<enter><wait>",
|
||||
"boot<enter>",
|
||||
]
|
||||
|
||||
ssh_username = "build"
|
||||
ssh_password = "build"
|
||||
ssh_timeout = "30m"
|
||||
ssh_handshake_attempts = 100
|
||||
shutdown_command = "echo 'build' | sudo -S shutdown -P now"
|
||||
|
||||
# File provisioners — stage agent files before install script runs
|
||||
# (Packer uploads to /tmp by default for file provisioners)
|
||||
|
||||
output_directory = "output-${var.vm_name}"
|
||||
output_filename = "${var.vm_name}"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["source.virtualbox-iso.haskell-build"]
|
||||
|
||||
# Stage agent files to /tmp (install-agent.sh moves them into place)
|
||||
provisioner "file" {
|
||||
source = "files/build-agent.py"
|
||||
destination = "/tmp/build-agent.py"
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
source = "files/build-agent.service"
|
||||
destination = "/tmp/build-agent.service"
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
source = "files/build-agent.env.template"
|
||||
destination = "/tmp/build-agent.env.template"
|
||||
}
|
||||
|
||||
# Install Haskell toolchain (GHCup + GHC + Cabal)
|
||||
provisioner "shell" {
|
||||
execute_command = "echo 'build' | sudo -S env {{ .Vars }} bash '{{ .Path }}'"
|
||||
script = "scripts/install-haskell.sh"
|
||||
environment_vars = [
|
||||
"GHC_PRIMARY_VERSION=${var.ghc_primary_version}",
|
||||
"GHC_SECONDARY_VERSION=${var.ghc_secondary_version}",
|
||||
"CABAL_VERSION=${var.cabal_version}",
|
||||
]
|
||||
}
|
||||
|
||||
# Install build-agent + systemd unit
|
||||
provisioner "shell" {
|
||||
execute_command = "echo 'build' | sudo -S env {{ .Vars }} bash '{{ .Path }}'"
|
||||
script = "scripts/install-agent.sh"
|
||||
}
|
||||
|
||||
# Export as OVA
|
||||
post-processor "vagrant" {
|
||||
only = [] # disabled — we use the raw OVA below
|
||||
}
|
||||
|
||||
post-processor "shell-local" {
|
||||
inline = [
|
||||
"cd output-${var.vm_name} && mv ${var.vm_name}.ova ../haskell-build-${local.timestamp}.ova || true",
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user