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>
148 lines
3.5 KiB
HCL
148 lines
3.5 KiB
HCL
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",
|
|
]
|
|
}
|
|
}
|