incus-contrib/CLAUDE.md

5.4 KiB

CLAUDE.md - Project context for AI assistants

What this repository is

A collection of peripheral tools, scripts, and snippets for working with Incus, IncusOS, and the broader ecosystem (Operations Center, Migration Manager). Primarily targeting home lab environments but aiming for production-quality scripts.

Repository structure

incu-contrib/
├── CLAUDE.md              # This file -- project context
├── README.md              # Main overview
├── .gitignore
├── incusos/               # IncusOS installation tooling
│   ├── README.md          # Detailed usage docs
│   ├── incusos-iso        # ISO/IMG builder (wraps flasher-tool)
│   ├── incusos-seed       # Seed archive generator
│   ├── incusos-proxmox    # Declarative Proxmox VM deployment
│   └── examples/          # Example seed + Proxmox YAML files
└── notes/                 # Research notes and reference material

Key technical context

Incus version differences

  • Debian stable ships Incus 6.0 LTS which is significantly behind upstream. The Zabbly repo (https://github.com/zabbly/incus) provides latest on Debian/Ubuntu.
  • macOS (Homebrew) and Arch Linux both track latest upstream (currently 6.21). macOS is client-only by design; Arch has no client-only split package.
  • incus remote get-client-certificate was added in Incus 6.3+ and does not exist in 6.0 LTS. Scripts must never depend on it as the only cert path.
  • Always prefer reading ~/.config/incus/client.crt directly from disk. Fall back to the CLI command only as a secondary option.
  • See notes/incus-version-compatibility.md for full platform matrix and install instructions.

IncusOS flasher-tool

  • Install: go install github.com/lxc/incus-os/incus-osd/cmd/flasher-tool@latest
  • Actual CLI flags: -f/--format, -s/--seed, -c/--channel, -i/--image, -v/--version
  • There is NO --seed-tar flag -- it's just --seed (or -s).
  • There is NO --arch flag -- architecture is determined by the downloaded image. For cross-arch builds, download the image manually and pass via --image.
  • CDN index: https://images.linuxcontainers.org/os/index.json
  • CDN images: https://images.linuxcontainers.org/os/{version}/{arch}/IncusOS_{version}.{format}.gz

Seed archives

  • Tar archives containing YAML files at the root level.
  • Written to byte offset 2148532224 (the seed partition) in the image.
  • Alternative: FAT image labeled SEED_DATA as external boot media.
  • Key files: install.yaml, applications.yaml, incus.yaml, operations-center.yaml, network.yaml, update.yaml.

Client certificates

  • Stored at ~/.config/incus/client.crt and ~/.config/incus/client.key.
  • Running incus remote list triggers auto-generation if no keypair exists.
  • For Incus seed: injected under preseed.server.certificates[].
  • For Operations Center seed: injected under trusted_client_certificates[].
  • Operations Center requires at least one trusted certificate -- without it, you are locked out after installation.

Proxmox VE deployment

  • incusos-proxmox reads a YAML config, generates per-VM SEED_DATA images via incusos-seed --format fat, uploads the ISO + seeds to Proxmox, creates VMs with IncusOS-correct settings, and boots them through installation.
  • Connection methods: SSH (default, ssh root@host qm ...) or API (curl -k https://host:8006/api2/json/... with PVEAPIToken header).
  • Minimum API privileges for token-based access:
    VM.Allocate VM.Config.Disk VM.Config.CPU VM.Config.Memory
    VM.Config.Network VM.Config.CDROM VM.Config.Options VM.Config.HWType
    VM.PowerMgmt VM.Audit Datastore.AllocateSpace Datastore.AllocateTemplate
    Datastore.Audit SDN.Use
    
  • Required VM settings (getting any wrong causes IncusOS install failure):
    • bios=ovmf, machine=q35 -- UEFI boot required
    • efidisk0: pre-enrolled-keys=0 -- IncusOS enrolls its own Secure Boot keys
    • tpmstate0: version=v2.0 -- required for disk encryption
    • cpu=host -- needed for x86_64_v3 instruction set requirement
    • scsihw=virtio-scsi-pci + scsi0 -- VirtIO-blk is broken with IncusOS
    • balloon=0 -- IncusOS manages memory internally
    • ide3 -- SEED_DATA FAT image attached as second CD-ROM
    • Minimum 50 GiB disk, minimum 4096 MiB RAM
  • Install flow: boot from ISO (ide2) -> read SEED_DATA (ide3) -> install to disk (scsi0) -> force_reboot -> boot from disk. Boot order is swapped to order=scsi0;ide2 immediately after first start so the reboot lands on disk.

Coding conventions for scripts

  • Shell: bash with set -euo pipefail
  • Arithmetic: use var=$((var + 1)) instead of ((var++)) to avoid false exits under set -e when the value is 0.
  • Colors: support NO_COLOR=1 and TERM=dumb; use setup_colors() pattern.
  • Flags: support both short (-d) and long (--defaults) options.
  • Defaults: sane defaults so the script does something useful with zero flags.
  • Dry run: all scripts should support --dry-run to preview actions.
  • Cert detection order: files on disk first, CLI command second.
  • Error messages: include actionable remediation steps, not just "failed".
  • No hardcoded package managers: say "install the Incus client" with a link, not "sudo apt install incus".

Git workflow

  • Main branch: main
  • Development happens on feature branches
  • Remote: private Gitea at ssh://git@192.168.1.200:2222/maarten/incu-contrib.git