id: T061 name: PlasmaCloud Deployer & Cluster Management goal: Implement PlasmaCloud-specific layers (L2/L3) for cluster and deployment management status: complete completed: 2025-12-13 01:44 JST priority: P0 owner: peerA created: 2025-12-13 depends_on: [T062] blocks: [] context: | **User Direction (2025-12-13 00:46 JST):** Three-layer architecture with separate Nix-NOS repo: **Layer 1 (T062):** Nix-NOS generic network module (separate repo) **Layer 2 (T061):** PlasmaCloud Network - FiberLB BGP, PrismNET integration **Layer 3 (T061):** PlasmaCloud Cluster - cluster-config, Deployer, orchestration **Key Principle:** PlasmaCloud modules DEPEND ON Nix-NOS, not the other way around. Nix-NOS remains generic and reusable by other projects. **Repository:** github.com/centra/plasmacloud (existing repo) **Path:** nix/modules/plasmacloud-*.nix acceptance: - plasmacloud.cluster defines node topology and generates cluster-config.json - plasmacloud.network uses nix-nos.bgp for FiberLB VIP advertisement - Deployer Rust service for node lifecycle management - PlasmaCloud flake.nix imports nix-nos as input steps: - step: S1 name: PlasmaCloud Cluster Module (Layer 3) done: plasmacloud-cluster.nix for topology and cluster-config generation status: complete completed: 2025-12-13 00:58 JST owner: peerB priority: P0 notes: | Create nix/modules/plasmacloud-cluster.nix: options.plasmacloud.cluster = { name = mkOption { type = str; }; nodes = mkOption { type = attrsOf (submodule { role = enum [ "control-plane" "worker" ]; ip = str; services = listOf str; }); }; bootstrap.initialPeers = listOf str; bgp.asn = int; }; config = { # Generate cluster-config.json environment.etc."nixos/secrets/cluster-config.json".text = ...; # Map to nix-nos.topology }; outputs: - path: nix/modules/plasmacloud-cluster.nix note: Complete module with options, validation, and cluster-config.json generation (175L) - path: .cccc/work/test-plasmacloud-cluster.nix note: Test configuration validating module evaluation - step: S2 name: PlasmaCloud Network Module (Layer 2) done: plasmacloud-network.nix using nix-nos.bgp for FiberLB status: complete completed: 2025-12-13 01:11 JST owner: peerB priority: P0 depends_on: [T062.S2] notes: | Create nix/modules/plasmacloud-network.nix: options.plasmacloud.network = { fiberlbBgp = { enable = mkEnableOption "FiberLB BGP"; vips = listOf str; }; prismnetIntegration.enable = mkEnableOption "PrismNET OVN"; }; config = mkIf fiberlbBgp.enable { nix-nos.bgp = { enable = true; backend = "gobgp"; # FiberLB uses GoBGP asn = cluster.bgp.asn; announcements = map vipToAnnouncement vips; }; services.fiberlb.bgp.gobgpAddress = "127.0.0.1:50051"; }; outputs: - path: nix/modules/plasmacloud-network.nix note: Complete Layer 2 module bridging plasmacloud.network → nix-nos.bgp (130L) - path: .cccc/work/test-plasmacloud-network.nix note: Test configuration with FiberLB BGP + VIP advertisement - step: S3 name: Deployer Core (Rust) done: Deployer service with Phone Home API and ChainFire state status: complete completed: 2025-12-13 01:28 JST owner: peerB priority: P1 notes: | Create deployer/ Rust workspace: - Phone Home API for node registration - State management via ChainFire (in-memory for now, ChainFire integration TODO) - Node lifecycle: Pending → Provisioning → Active → Failed - REST API with /health and /api/v1/phone-home endpoints Phase 1 (minimal scaffolding) complete. Future work: gRPC API, full ChainFire integration, health monitoring. outputs: - path: deployer/Cargo.toml note: Workspace definition with deployer-types and deployer-server - path: deployer/crates/deployer-types/src/lib.rs note: NodeState enum, NodeInfo struct, PhoneHomeRequest/Response types (110L) - path: deployer/crates/deployer-server/src/main.rs note: Binary entry point with tracing initialization (24L) - path: deployer/crates/deployer-server/src/lib.rs note: Router setup with /health and /api/v1/phone-home routes (71L) - path: deployer/crates/deployer-server/src/config.rs note: Configuration loading with ChainFire settings (93L) - path: deployer/crates/deployer-server/src/phone_home.rs note: Phone Home API endpoint handler with in-memory state (120L) - path: deployer/crates/deployer-server/src/state.rs note: AppState with RwLock for node registry (36L) - step: S4 name: Flake Integration done: Update plasmacloud flake.nix to import nix-nos status: complete completed: 2025-12-13 01:03 JST owner: peerB priority: P1 depends_on: [T062.S1] notes: | Update flake.nix: inputs = { nix-nos.url = "github:centra/nix-nos"; nix-nos.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { nix-nos, ... }: { nixosConfigurations.node01 = { modules = [ nix-nos.nixosModules.default ./nix/modules/plasmacloud-cluster.nix ./nix/modules/plasmacloud-network.nix ]; }; }; outputs: - path: flake.nix note: Added nix-nos input (path:./nix-nos) and wired to node01 configuration (+8L) - path: flake.lock note: Locked nix-nos dependency - step: S5 name: ISO Pipeline done: Automated ISO generation with embedded cluster-config status: complete completed: 2025-12-13 01:44 JST owner: peerB priority: P2 notes: | Created ISO pipeline for PlasmaCloud first-boot: - nix/iso/plasmacloud-iso.nix - ISO configuration with Phone Home service - nix/iso/build-iso.sh - Build script with cluster-config embedding - flake.nix plasmacloud-iso configuration - Phone Home service contacts Deployer at http://deployer:8080/api/v1/phone-home - Extracts node info from cluster-config.json (node_id, IP, role, config hash) - Retry logic with exponential backoff (5 attempts) - DHCP networking enabled by default - SSH enabled with default password for ISO outputs: - path: nix/iso/plasmacloud-iso.nix note: ISO configuration with Phone Home service and cluster-config embedding (132L) - path: nix/iso/build-iso.sh note: ISO build script with validation and user-friendly output (65L) - path: flake.nix note: Added plasmacloud-iso nixosConfiguration (+8L) evidence: - item: T061.S1 PlasmaCloud Cluster Module desc: Complete plasmacloud-cluster.nix with nodeType, generateClusterConfig, assertions total_loc: 162 validation: nix-instantiate returns lambda, cluster-config.json generation verified - item: T061.S4 Flake Integration desc: nix-nos imported as flake input, wired to node01 configuration total_loc: 8 validation: nix eval .#nixosConfigurations.node01.config.nix-nos.bgp returns bgp_exists - item: T061.S2 PlasmaCloud Network Module desc: plasmacloud-network.nix bridges Layer 2 → Layer 1 for FiberLB BGP total_loc: 124 validation: nix-instantiate returns LAMBDA, nix-nos.bgp wired from fiberlbBgp - item: T061.S3 Deployer Core (Rust) desc: Deployer workspace with Phone Home API and in-memory state management total_loc: 454 validation: cargo check passes, cargo test passes (7 tests) - item: T061.S5 ISO Pipeline desc: Bootable ISO with Phone Home service and cluster-config embedding total_loc: 197 validation: nix-instantiate evaluates successfully, Phone Home service configured notes: | Reference: /home/centra/cloud/Nix-NOS.md This is Layers 2+3 of the three-layer architecture. Depends on T062 (Nix-NOS generic) for Layer 1. Data flow: User → plasmacloud.cluster → plasmacloud.network → nix-nos.bgp → NixOS standard modules