Commit Graph

30 Commits

Author SHA1 Message Date
Maarten 959cc0162c Convert all ASCII CLI output tables to native markdown tables
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:53:38 +01:00
Maarten 671d79b77f Convert all ASCII diagrams to mermaid with consistent styling
Replace ASCII art diagrams in 9 guide files with mermaid flowcharts
using a unified style system:

- 5 semantic colors (Okabe-Ito derived, color-blind safe):
  teal (nodes), sky blue (instances), blue (network),
  amber (load balancers), mauve (management)
- classDef for reusable styles, tinted subgraph fills
- Max 2 lines per node, specs in companion tables
- <br/> for line breaks (not \n, which Gitea renders literally)
- Solid arrows for data flow, dashed for control plane

Files converted:
- haproxy-guide.md (1 diagram)
- observability-guide.md (1 diagram)
- api-interception-guide.md (1 diagram)
- incusos-break-fix.md (3 diagrams: partitions, boot chain, updates)
- shared-storage-guide.md (3 diagrams: iSCSI arch, topology, multi-host)
- networking-guide.md (2 diagrams: bridge, OVN topology)
- operations-center-guide.md (1 diagram)
- ovn-deep-dive.md (3 diagrams: lab, bridges, Geneve mesh)
- production-lab-guide.md (1 diagram)
- mermaid-test.md updated as style reference with <br/> fix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:31:29 +01:00
Maarten 6293f7ab79 Redesign mermaid test with consistent style guidelines
- Define 5-color semantic palette (Okabe-Ito derived, color-blind safe)
- Use classDef for reusable styles instead of per-node statements
- Limit node text to 2 lines max, move specs to tables
- Consistent node shapes by role (rounded for network, stadium for external)
- Dashed arrows for control plane, solid for data plane
- Tinted subgraph fills matching dominant role color

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:17:39 +01:00
Maarten 07c289d75c Add mermaid diagram rendering test
Test file with 6 diagrams converted from ASCII to mermaid format
to verify Gitea renders them correctly before updating all docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:56:38 +01:00
Maarten 360fba5680 Execute break-fix exercises, document results and fix VMIDs
Exercises executed on 2026-02-24:
- Exercise 1 (Update Observation): observed download, A/B switch, DB-leader
  transfer during reboot. All 3 nodes updated to 202602240349.
- Exercise 3 (Network Isolation): OVN gateway is SPOF (no failover),
  east-west traffic survives, MAC change causes boot hang.
- Exercise 4 (Full Node Failure): 2/3 quorum held, ~20s detection,
  ~50s recovery, instances auto-restart.
- Exercise 2 (Simulated Failed Update): blocked (no update available).

Fixes: VMIDs corrected from 900-902 to 400-402, added MAC safety rule,
documented Proxmox API --data-urlencode requirement for MAC addresses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:51:26 +01:00
Maarten 95316a5bee Add IncusOS break-fix guide, incusos-health helper, immutability rules
Phase 4: Explore IncusOS immutability via the /os/1.0 API:
- incusos-health script with --status/--partitions/--tpm/--services/--network/--update
- Validated: TPM encryption (root+swap), Secure Boot with 4 certs, ZFS pool
- Documented A/B partition scheme, update mechanics, security chain
- Defined 4 break-fix exercises (update observation, failed update, network
  isolation, full node failure) with safety rules and pickup points

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:57:43 +01:00
Maarten cc017b648d Add observability stack: Prometheus, Grafana, Loki with dashboards
Deploy and validate full monitoring stack on the Incus cluster:
- Prometheus scraping 9 targets (3 Incus nodes, 2 HAProxy, 3 node-exporters, self)
- Grafana with 3 dashboards (cluster overview, HAProxy traffic, host resources)
- Loki + Promtail for log aggregation
- OVN network forward for LAN access (192.168.103.201:3000/9090)
- deploy-observability script with --deploy/--status/--cleanup/--doctor
- Solved OVN ACL challenges: Aether default-deny requires monitoring-allow ACL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:44:59 +01:00
Maarten 91a87456a5 Add API interception guide, incus-mitm helper, and payload rules
Phase 2: captured Aether↔Incus API traffic using the event stream.
Identified callers by TLS certificate fingerprint (CLI vs Aether vs
cluster nodes). Documented API patterns for stop/start/snapshot/exec.
Key finding: Aether subscribes to lifecycle events and reactively
queries affected resources.

Deliverables:
- notes/api-interception-guide.md: capture setup + all API patterns
- incusos/helpers/incus-mitm: --capture/--live/--analyze/--callers
- .claude/rules/aether-api-payloads.md: context for AI assistants
- .mcp.json: add --ignore-https-errors for Playwright

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:01:56 +01:00
Maarten 94eb3c7cc4 Add OVN deep-dive guide, ovn-inspect helper, and internals rules
Phase 1 of observability plan: mapped the complete OVN topology at
logical (NB), physical (SB), and OVS layers. Traced packet path from
LAN through VIP LB to HAProxy backends. Documented naming conventions,
gateway failover, Geneve tunnels, and MTU implications.

Deliverables:
- notes/ovn-deep-dive.md: comprehensive OVN internals guide
- incusos/helpers/ovn-inspect: --nb/--sb/--ovs/--full/--trace actions
- .claude/rules/ovn-internals.md: context for AI assistants

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:52:37 +01:00
Maarten c047bc6ed4 Add HAProxy LB guide, deploy script, Playwright helper; validate end-to-end
Tear down and fully re-deploy HAProxy infrastructure from scratch to
validate the guide reads correctly. Key fixes from re-validation:

- Fix session API field names: lb_vip (not vip), target_ip/target_port
  (not ip/port), health_check_enabled (not health_check)
- Document that Aether does NOT create the OVN load balancer — must be
  created manually via incus network load-balancer
- Fix internal VIP test: OVN LB doesn't hairpin, use localhost instead
- Document OVN LB has no health checking (HAProxy failover not instant)
- Add cleanup step for manually-created OVN LB
- Add aether-browser Playwright helper and .mcp.json config
- Add deploy-haproxy script, haproxy-lb rules, full guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:08:43 +01:00
Maarten 0100182dd8 Validate AWX guide, document Aether API, enforce API-first policy
- AWX guide: fix wrong project ID (6→9), add dynamic ID lookups,
  add missing Step 5 push commands, add migration pod to expected
  output, replace PostgreSQL workaround with Aether UI instructions,
  reference deploy-awx as automated path
- Aether guide: document JWT REST API (auth, clusters, ACLs),
  swagger UI at /api/docs, rate limits, coverage vs UI-only features
- CLAUDE.md: add Aether API capability, add interaction hierarchy
  (API first → UI fallback → never root/DB in guides)
- deploy-awx: fix PLAYBOOK_DIR from "ansible/playbooks" to "playbooks"
- post-deploy.yml: clarify cert push path vs EE runtime mount path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:33:46 +01:00
Maarten 0b82b9ce3b Validate AWX guide against real infrastructure, fix all bugs
End-to-end tested: Aether deploy triggers AWX post-deploy job,
container gets configured (hostname, packages, timezone, deploy-info),
decommission job runs on delete. All playbooks validated working.

Key fixes from testing:
- Playbooks: use Incus REST API (not SSH) — bridge subnet not routable
  from management VLAN, nftables blocks inbound forwarding
- Aether vars: ffsdn_* prefix (not vm_name/vm_ip/environment/owner)
- AWX EE paths: /runner/project/ (not /var/lib/awx/projects/)
- AWX access: NodePort 30080 (not Traefik ingress — 404 for IP access)
- deploy-awx: systemd-networkd (not netplan), manual project (not git
  SCM — EE can't reach private repo), Incus cert push, prereq install
- Remove unused base-config role (tasks inlined as setup script)
- Simplify ansible.cfg (no SSH settings needed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:53:54 +01:00
Maarten 6a74925fc4 WIP: Add AWX deployment, Ansible playbooks, and Aether integration
Work-in-progress commit to enable AWX project sync from git.
Files will be updated with validated output from real deployment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:04:28 +01:00
Maarten fd30ef27d4 Expand Aether guide: deploy forms, blueprints, instance mgmt, OVN recovery
Document the full Aether platform after hands-on testing:
- Deploy form fields, validation, IP reservation, AWX integration
- Blueprint design (cluster-agnostic, component structure, JSON API)
- Blueprint deployment lifecycle (3-phase deploy, decommission workflow)
- Instance management (state control, resources, snapshots, console, ACLs)
- OVN recovery procedure after ovn-central container move (5-phase)
- Node resize procedure (Proxmox disk grow + ZFS pool expansion)
- Update lab-oc-nodes defaults to match resized nodes (20G RAM, 100G disk)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 22:59:30 +01:00
Maarten d2b49f5ef0 Add Aether management platform guide and extracted help texts
Aether deployed on oc-node-01, connected to Incus cluster (trust token)
and Operations Center (mutual TLS). Extracted all 16 built-in help pages
(426 KB) covering cluster management, storage, profiles, instances,
HAProxy LB, firewall ACLs, blueprints, and health monitoring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:24:01 +01:00
Maarten 4854f15a16 Add shared storage guide: iSCSI + lvmcluster with tested output
Validated end-to-end on OC-managed 3-node cluster: iSCSI target
container (tgt), IncusOS iSCSI/LVM services, lvmcluster pool,
container migration (0.12s), VM live migration (~6s, RAM only).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 14:58:11 +01:00
Maarten 896731a7ed Validate OC guide: teardown + rebuild with fresh output
Full teardown and rebuild of the OC-managed cluster lab to validate
the guide works end-to-end with zero manual interventions. Key fixes:

- Add missing `provisioning channel add old-stable` step (was causing
  "Not found" error on `assign-channels`)
- Fix command paths: `examples/` → `incusos/examples/` (repo-relative)
- Fix version numbers: Incus 6.12 → 6.21, OC output format
- Fix update list table format (Severity not Sev, add Published At note)
- Fix cluster list: remove premature ovn-chassis roles at Section 4.4
- Add WARNING line to `admin os show` output
- Add TLS cert acceptance note for `remote add`
- Add cleanup --yes flag to teardown commands
- Add test container cleanup command in Section 5.7
- Note variable-per-deployment values (incusbr0 subnet, token UUIDs)
- Add `provisioning channel add` to Quick Reference and CLI table
- Add channel creation to troubleshooting table
- Use consistent <token-UUID> placeholder throughout

All 16 verification checklist items PASS. Lab left running.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:23:49 +01:00
Maarten b9f1894681 OC-managed cluster with OVN and HA nginx: full validated deployment
Deploy a 3-node OC-managed Incus cluster with OVN overlay networking
and an HA nginx workload behind an OVN load balancer. Key discoveries:

- OC needs_update blocker: OC tracks update delivery through its pipeline,
  not version comparison. Nodes deployed from the latest ISO are stuck at
  needs_update=true. Fix: generate ISO from older channel (--channel
  old-stable), let OC push the real update after registration.
- ISO upload skip bug: incusos-proxmox silently reused stale ISOs with the
  same filename. Fixed: --iso now replaces existing same-named ISOs.
- Empty app-seed-config ({}): avoids "Certificate already in trust store"
  Terraform error when cert is already injected via SEED_DATA.

Files changed:
- notes/operations-center-guide.md: full rewrite with real captured output
- CLAUDE.md: needs_update findings, ISO fix, OVN LB behavior
- incusos/examples/lab-oc-deploy.yaml: static IP for VLAN 69
- incusos/examples/lab-oc-nodes.yaml: static IPs + disk sizing
- incusos/incusos-proxmox: fix stale ISO reuse when --iso provided

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:08:28 +01:00
Maarten d8f2a067c4 Add production lab guide with validated output from real deployment
Comprehensive 1775-line guide (notes/production-lab-guide.md) covering
full lab lifecycle: OC dashboard, 3-node manual clustering, OVN overlay
networking, mixed workloads, live migration, network security, load
balancers, and cluster evacuation/restore. Every command was executed
on real infrastructure (2026-02-22) and output captured.

Key findings incorporated:
- IncusOS NIC is named `mgmt`, not `ens18` (UPLINK parent)
- OC CLI requires `remote switch`, not `remote:` suffix syntax
- LB/forward backends need IP addresses, not instance names
- Cluster auto-schedules without --target flag
- Migration ~7s at ~140 MB/s with heartbeat continuity

Also: lab-production.yaml config, lab-oc.yaml apply_defaults fix,
CLAUDE.md and networking-guide.md updates for mgmt/OC/LB findings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 23:46:10 +01:00
Maarten 9e3201393e Add VLAN 69 support, OVN networking guide, and lab-networking config
VLAN tagging: incusos-proxmox now reads optional `vlan` key from
proxmox.yaml and lab configs, appending `tag=N` to the VM NIC spec
in both SSH and API creation paths. Tested manually on VMID 850 —
VM received IP in 192.168.100.0/22 (Homelab VLAN). VLAN tag is
Proxmox-level only; IncusOS and Incus instances are unaware of it.

Networking guide: comprehensive tutorial covering bridge networking,
OVN overlay setup on IncusOS (services disabled by default, must
enable via REST API), cross-node connectivity, isolation, ACLs,
peering, load balancers, forwards, and DNS. All scenarios tested
on a 4-node OC-managed cluster.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 13:28:03 +01:00
Maarten 2e2447de06 Boot failure investigation: 67% crontab bug rate confirmed, version mismatch ruled out
Parallel investigation of IncusOS issue #843 across 20 VM deploys confirms
the "invalid crontab expression" error hits 67% of first boots. The bug is
a race condition in the daemon startup — NOT related to ISO/CDN version
mismatch, update downloads, or seed config. Sysext downloads occur on every
first boot even with matching versions.

New tools: investigate-parallel (parallel VM testing), pve-api (Python
Proxmox API helper avoiding bash ! quoting), investigate-boot (sequential
testing), test-boot-reliability (batch reliability testing).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 23:19:35 +01:00
Maarten 52d8dbdc89 OC v0.3.0 comprehensive test: retry logic, auto-heal, apply_defaults validation
Phase 0-10 of OC test plan completed:
- Add --retries N flag to incusos-proxmox (default 3, configurable boot retries)
- Add fix_scrub_schedule() auto-heal for IncusOS crontab bug via REST API
- Validate apply_defaults: false for OC-managed nodes (recommended approach)
- Test full OC lifecycle: deploy, provision, cluster, workloads, migration,
  evacuation, node failure/recovery, inventory query, REST API
- Update CLAUDE.md: OC v0.3.0 commands, --retries, scrub fix, node recovery
- Update operations-center-guide.md: v0.3.0, apply_defaults, scrub fix,
  node failure simulation, IncusOS REST API docs, inventory query

Key findings:
- apply_defaults: false lets OC Terraform handle everything cleanly
- fix_scrub_schedule() proactively heals ~50% crontab boot failure
- OC does not detect node failures (always shows "ready")
- inventory query (v0.3.0) provides cross-resource tree views
- Node crash recovery: auto-rejoin in ~60s, containers auto-start

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 21:41:34 +01:00
Maarten e0faba8980 Fix critical auth validation, role naming, Sys.Audit, and apply_defaults
Safety fix: --cleanup-all, --resources, --labs silently failed when
PROXMOX_TOKEN_SECRET was not set, reporting "No VMs found" instead of
an auth error. Added require_api_auth() gate and error propagation in
pve_list_vms() to fail loudly on API auth failures.

Also:
- Standardize role name to IncusOSDeployer across all docs and scripts
- Add Sys.Audit privilege to all setup command examples
- Document /nodes/pve ACL requirement for scoped permissions
- Update lab-cluster.yaml: apply_defaults: false for joining nodes
  (upstream IncusOS recommendation to avoid 8-command cleanup)
- Add full cluster automation to lab-test phase_cluster:
  core.https_address setup, remote cert fixup, automated join prompts,
  conditional defaults cleanup for apply_defaults: true nodes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 08:51:52 +01:00
Maarten ca660585dc Correct reboot diagnosis: OC-specific, not dqlite/TPM corruption
Volume testing with live Proxmox infrastructure proved that guest reboot
does NOT break standalone IncusOS nodes. Tested:
- 4 consecutive Proxmox stop/start cycles: all clean, data intact
- Single-node guest reboot: recovered in ~50s, containers auto-started
- Simultaneous 3-node guest reboot: all recovered, data integrity verified

The "reboot breaks IncusOS" issue is OC-specific. Console errors showed:
- Node 1: "failed to parse update frequency" (OC pushed bad crontab)
- Node 2: stuck at "starting application" (waiting for peers in loops)
- Node 3: "constraint violation" (OC re-registering existing server)

Updated all 8 references across CLAUDE.md, operations-center-guide.md,
and TESTING.md to reflect the corrected diagnosis.

Also fixed one more bare return bug in do_list_labs (empty pool path).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 00:48:06 +01:00
Maarten f812e04746 Add macOS support, multi-lab lifecycle, extended testing, and migration docs
Fix OC reboot diagnosis across all docs (dqlite corruption, not TPM PCR).
Add cross-platform support: genisoimage/mkisofs detection, portable dd/grep/
date usage. Add --lab-up/--lab-down/--resources/--labs to incusos-proxmox for
multi-lab coexistence. Add 7 new lab-test phases (storage, network, projects,
backup, limits, security, resilience). Fix VMID collision in lab-advanced
(910→930). Create migration guide and UTM design doc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 23:41:06 +01:00
Maarten 8ae8700346 Add Operations Center hands-on testing, hybrid deployment, and comprehensive guide
Deployed and tested the full OC provisioning pipeline on Proxmox:
- Hybrid approach: incusos-proxmox --iso with OC-provisioned ISOs
- Token seeds, auto-registration, single-command cluster formation
- Inventory sync, live migration visibility, evacuation, node replacement
- Discovered OC reboot breaks TPM encryption on Proxmox VMs

Key findings documented: dual-seed coexistence, apply_defaults conflict
with Terraform, inventory requires explicit resync, stale server entries
from out-of-band changes, meshbr0 network added by OC clustering.

New files:
- notes/operations-center-guide.md: full tested OC reference
- incusos/examples/lab-oc-deploy.yaml: OC server deployment config
- incusos/examples/lab-oc-nodes.yaml: 3-node OC cluster config

Updated: CLAUDE.md (OC section rewrite), TESTING.md (hybrid workflow),
.gitignore (env file with Proxmox secrets)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:55:48 +01:00
Maarten 732d70b38e Add advanced migration testing, cluster lifecycle, and clustering guide
- New lab-advanced.yaml (3-node 6/4/4 core heterogeneous cluster) and
  lab-replace.yaml (single replacement node) for advanced migration and
  cluster lifecycle testing
- New notes/clustering-guide.md with full clustering walkthrough: cluster
  formation, storage pool conflict fix, join workflow, VM live migration
  with limits.cpu range fix, multi-vCPU test results (2/3/4 vCPUs),
  edge cases (I/O, memory, concurrent), and node replacement lifecycle
- Updated CLAUDE.md with clustering docs, rebalancing config keys,
  cluster enable syntax fix (TWO args not one), cluster remove syntax,
  agent reconnect timing (3-4s not 1-2s), and lifecycle procedure
- proxmox.yaml.example for Proxmox connection config reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:46:55 +01:00
Maarten a0a4b48c73 Implement end-to-end IncusOS Proxmox deployment via API
Major changes to incusos-proxmox and incusos-seed to achieve fully automated
IncusOS deployment to Proxmox VE. Fixes multiple blockers discovered during
testing: FAT→ISO 9660 seed format (CD-ROM label detection), preseed YAML
structure (Go yaml:",inline"), disk target auto-detection, install completion
monitoring via blockstat disk I/O, install media ejection, and ARP-based IP
detection for the agent-less IncusOS.

Key changes:
- incusos-seed: add --format iso using genisoimage, fix preseed structure
- incusos-proxmox: ISO seeds, blockstat install detection, media ejection,
  ARP-based IP lookup, force_reboot requirement
- Documentation: comprehensive updates to CLAUDE.md, README.md, TESTING.md
- Examples: fix preseed.certificates path in all YAML examples
- Notes: full session progress with all bugs found and fixed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:26:58 +01:00
Maarten e2909c9149 version and certificate refinement 2026-02-18 14:49:31 +01:00
Maarten ef98e3f131 Initial Commit 2026-02-18 14:04:05 +01:00