# node-vm: a single MAAS-managed OpenStack node VM (D-103's "OpenTofu creates
# the node-VM libvirt domains (SHIM -- Section 9)" -- Stage 3 / buildout-design
# Phase 2). BLANK disk, PXE-boot -- this is deliberately NOT the cloud-init +
# pre-built-image pattern (that's a separate, still-unbuilt module for Office1
# service VMs / OPNsense; see opentofu/README.md). MAAS enlists, commissions,
# and deploys these VMs after OpenTofu creates them; OpenTofu does not image
# them itself.
#
# Every attribute below is used exactly as shown in the provider's own
# examples/domain_with_network.tf and examples/alpine_cloudinit.tf (fetched
# and read directly this session, tag v0.9.8) -- attribute-style nested
# objects (`os = { ... }`, `devices = { ... }`), NOT classic HCL blocks. The
# ONE inference in this file, clearly marked below, is the per-device `boot`
# object's internal shape (`order`) -- confirmed to EXIST as a field name on
# both `interfaces` and `disks` entries (matching native libvirt's per-device
# <boot order='N'/>), but its exact internal shape was not independently
# confirmed from a real example. VERIFY with `tofu providers schema -json`
# before the first real apply; if wrong, `tofu plan` will simply reject the
# attribute name, not silently misconfigure anything.

resource "libvirt_volume" "disk" {
  name     = "${var.vm_name}-disk.qcow2"
  pool     = var.pool_name
  capacity = var.disk_size_bytes
  format = {
    type = "qcow2"
  }
}

resource "libvirt_domain" "node" {
  name   = var.vm_name
  memory = var.memory_mib
  vcpu   = var.vcpu
  type   = "kvm"
  running = true

  os = {
    type         = "hvm"
    type_arch    = "x86_64"
    type_machine = "q35"
  }

  devices = {
    disks = [
      {
        source = {
          volume = {
            pool   = libvirt_volume.disk.pool
            volume = libvirt_volume.disk.name
          }
        }
        target = {
          dev = "vda"
          bus = "virtio"
        }
        driver = {
          type = "qcow2"
        }
        # boot.order shape UNVERIFIED (see file header) -- disk boots second,
        # network boots first (PXE).
        boot = {
          order = 2
        }
      }
    ]

    interfaces = [
      for i, net_name in var.network_names : {
        model = {
          type = "virtio"
        }
        source = {
          network = {
            network = net_name
          }
        }
        # only the first (PXE) interface gets an explicit boot order;
        # see the disk boot-order note above for the same caveat.
        boot = i == 0 ? { order = 1 } : null
      }
    ]
  }
}
