{ description = "PhotonCloud - Japanese Cloud Platform"; # ============================================================================ # INPUTS: External dependencies # ============================================================================ inputs = { # Use unstable nixpkgs for latest packages nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # Rust overlay for managing Rust toolchains rust-overlay = { url = "github:oxalica/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; }; # Flake utilities for multi-system support flake-utils.url = "github:numtide/flake-utils"; # Disko for declarative disk partitioning disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; }; # Nix-NOS generic network operating system modules nix-nos = { url = "path:./nix-nos"; inputs.nixpkgs.follows = "nixpkgs"; }; }; # ============================================================================ # OUTPUTS: What this flake provides # ============================================================================ outputs = { self, nixpkgs, rust-overlay, flake-utils, disko, nix-nos, systems ? null }: flake-utils.lib.eachDefaultSystem (system: let # Apply rust-overlay to get rust-bin attribute overlays = [ (import rust-overlay) ]; pkgs = import nixpkgs { inherit system overlays; }; # Rust toolchain configuration # Using stable channel with rust-src (for rust-analyzer) and rust-analyzer rustToolchain = pkgs.rust-bin.stable.latest.default.override { extensions = [ "rust-src" "rust-analyzer" ]; }; # Common build inputs needed by all Rust packages commonBuildInputs = with pkgs; [ rocksdb # RocksDB storage engine openssl # TLS/SSL support ]; # Common native build inputs (build-time only) commonNativeBuildInputs = with pkgs; [ pkg-config # For finding libraries protobuf # Protocol Buffers compiler rustToolchain ]; # Common environment variables for building commonEnvVars = { LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib"; PROTOC = "${pkgs.protobuf}/bin/protoc"; ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; }; clusterPython = pkgs.python3.withPackages (ps: [ ps.python-snappy ]); # Keep package builds stable even when docs or archived assets change. repoSrc = pkgs.lib.cleanSourceWith { src = ./.; filter = path: type: let rel = pkgs.lib.removePrefix ((toString ./. ) + "/") (toString path); topLevel = builtins.head (pkgs.lib.splitString "/" rel); includedTopLevels = [ "apigateway" "chainfire" "coronafs" "crates" "creditservice" "deployer" "fiberlb" "flashdns" "flaredb" "iam" "k8shost" "lightningstor" "mtls-agent" "nightlight" "plasmavmc" "prismnet" ]; in rel == "" || builtins.elem rel [ "flake.nix" "flake.lock" ] || builtins.elem topLevel includedTopLevels; }; flakeBundleSrc = pkgs.lib.cleanSourceWith { src = ./.; filter = path: type: let rel = pkgs.lib.removePrefix ((toString ./. ) + "/") (toString path); topLevel = builtins.head (pkgs.lib.splitString "/" rel); includedTopLevels = [ "apigateway" "baremetal" "chainfire" "coronafs" "crates" "creditservice" "deployer" "fiberlb" "flashdns" "flaredb" "iam" "k8shost" "lightningstor" "mtls-agent" "nightlight" "nix" "nix-nos" "plasmavmc" "prismnet" ]; isTargetDir = builtins.match "(.*/)?target(/.*)?" rel != null; in !isTargetDir && ( rel == "" || builtins.elem rel [ "flake.nix" "flake.lock" ] || builtins.elem topLevel includedTopLevels ); }; flakeInputsBlock = '' inputs = { # Use unstable nixpkgs for latest packages nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # Rust overlay for managing Rust toolchains rust-overlay = { url = "github:oxalica/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; }; # Flake utilities for multi-system support flake-utils.url = "github:numtide/flake-utils"; # Disko for declarative disk partitioning disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; }; # Nix-NOS generic network operating system modules nix-nos = { url = "path:./nix-nos"; inputs.nixpkgs.follows = "nixpkgs"; }; }; ''; bundledInputsBlock = '' inputs = { nixpkgs.url = "path:./.bundle-inputs/nixpkgs"; rust-overlay = { url = "path:./.bundle-inputs/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; }; flake-utils = { url = "path:./.bundle-inputs/flake-utils"; inputs.systems.follows = "systems"; }; systems.url = "path:./.bundle-inputs/systems"; disko = { url = "path:./.bundle-inputs/disko"; inputs.nixpkgs.follows = "nixpkgs"; }; nix-nos = { url = "path:./nix-nos"; inputs.nixpkgs.follows = "nixpkgs"; }; }; ''; flakeHeaderBlock = '' # ============================================================================ # INPUTS: External dependencies # ============================================================================ inputs = { # Use unstable nixpkgs for latest packages nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # Rust overlay for managing Rust toolchains rust-overlay = { url = "github:oxalica/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; }; # Flake utilities for multi-system support flake-utils.url = "github:numtide/flake-utils"; # Disko for declarative disk partitioning disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; }; # Nix-NOS generic network operating system modules nix-nos = { url = "path:./nix-nos"; inputs.nixpkgs.follows = "nixpkgs"; }; }; # ============================================================================ # OUTPUTS: What this flake provides # ============================================================================ outputs = { self, nixpkgs, rust-overlay, flake-utils, disko, nix-nos, systems ? null }: ''; bundledHeaderBlock = '' # ============================================================================ # INPUTS: External dependencies # ============================================================================ inputs = { nixpkgs.url = "path:./.bundle-inputs/nixpkgs"; rust-overlay = { url = "path:./.bundle-inputs/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; }; flake-utils = { url = "path:./.bundle-inputs/flake-utils"; inputs.systems.follows = "systems"; }; systems.url = "path:./.bundle-inputs/systems"; disko = { url = "path:./.bundle-inputs/disko"; inputs.nixpkgs.follows = "nixpkgs"; }; nix-nos = { url = "path:./nix-nos"; inputs.nixpkgs.follows = "nixpkgs"; }; }; # ============================================================================ # OUTPUTS: What this flake provides # ============================================================================ outputs = { self, nixpkgs, rust-overlay, flake-utils, disko, nix-nos, systems ? null }: ''; bundledFlakeNix = pkgs.writeText "plasmacloud-bundled-flake.nix" ( builtins.replaceStrings [ flakeHeaderBlock ] [ bundledHeaderBlock ] (builtins.readFile ./flake.nix) ); bundledFlakeHeaderFile = pkgs.writeText "plasmacloud-bundled-flake-header" bundledHeaderBlock; baseFlakeLock = builtins.fromJSON (builtins.readFile ./flake.lock); bundleInputRelPaths = { nixpkgs = "./.bundle-inputs/nixpkgs"; "rust-overlay" = "./.bundle-inputs/rust-overlay"; "flake-utils" = "./.bundle-inputs/flake-utils"; disko = "./.bundle-inputs/disko"; systems = "./.bundle-inputs/systems"; }; fetchLockedInput = nodeName: let tree = builtins.fetchTree baseFlakeLock.nodes.${nodeName}.locked; in if builtins.isAttrs tree && tree ? outPath then tree.outPath else tree; vendoredFlakeInputs = { nixpkgs = fetchLockedInput "nixpkgs"; "rust-overlay" = fetchLockedInput "rust-overlay"; "flake-utils" = fetchLockedInput "flake-utils"; disko = fetchLockedInput "disko"; systems = fetchLockedInput "systems"; }; makeBundledLockNode = nodeName: relPath: let node = baseFlakeLock.nodes.${nodeName}; in node // { locked = { type = "path"; path = relPath; }; original = { type = "path"; path = relPath; }; }; bundledFlakeLock = baseFlakeLock // { nodes = baseFlakeLock.nodes // { root = baseFlakeLock.nodes.root // { inputs = baseFlakeLock.nodes.root.inputs // { systems = "systems"; }; }; nixpkgs = makeBundledLockNode "nixpkgs" bundleInputRelPaths.nixpkgs; "rust-overlay" = makeBundledLockNode "rust-overlay" bundleInputRelPaths."rust-overlay"; "flake-utils" = makeBundledLockNode "flake-utils" bundleInputRelPaths."flake-utils"; disko = makeBundledLockNode "disko" bundleInputRelPaths.disko; systems = makeBundledLockNode "systems" bundleInputRelPaths.systems; }; }; bundledFlakeLockFile = pkgs.writeText "plasmacloud-bundled-flake.lock" (builtins.toJSON bundledFlakeLock); inBundledEval = builtins.pathExists ./.bundle-eval-marker; bundledFlakeRootDrv = pkgs.runCommand "plasmacloud-bundled-flake-root" { nativeBuildInputs = [ pkgs.coreutils pkgs.python3 ]; } '' mkdir -p "$out" cp -a ${flakeBundleSrc}/. "$out"/ chmod -R u+w "$out" touch "$out/.bundle-eval-marker" mkdir -p "$out/.bundle-inputs" cp -a ${vendoredFlakeInputs.nixpkgs} "$out/.bundle-inputs/nixpkgs" cp -a ${vendoredFlakeInputs."rust-overlay"} "$out/.bundle-inputs/rust-overlay" cp -a ${vendoredFlakeInputs."flake-utils"} "$out/.bundle-inputs/flake-utils" cp -a ${vendoredFlakeInputs.disko} "$out/.bundle-inputs/disko" cp -a ${vendoredFlakeInputs.systems} "$out/.bundle-inputs/systems" cp ${bundledFlakeLockFile} "$out/flake.lock" python3 - <<'PY' "$out/flake.nix" ${bundledFlakeHeaderFile} from pathlib import Path import re import sys flake_path = Path(sys.argv[1]) header = Path(sys.argv[2]).read_text() source = flake_path.read_text() pattern = re.compile( r" # ============================================================================\n" r" # INPUTS: External dependencies\n" r" # ============================================================================\n" r" inputs = \{.*?\n" r" # ============================================================================\n" r" # OUTPUTS: What this flake provides\n" r" # ============================================================================\n" r" outputs = \{ self, nixpkgs, rust-overlay, flake-utils, disko, nix-nos, systems \? null \}:", re.S, ) rewritten, count = pattern.subn(header.rstrip("\n"), source, count=1) if count != 1: raise SystemExit(f"expected to rewrite 1 flake header, rewrote {count}") flake_path.write_text(rewritten) PY ''; bundledFlakeRoot = if inBundledEval then null else builtins.path { path = bundledFlakeRootDrv; name = "plasmacloud-bundled-flake-root-src"; }; bundledFlakeRootNarHashFile = if inBundledEval then null else pkgs.runCommand "plasmacloud-bundled-flake-root-narhash" { nativeBuildInputs = [ pkgs.nix ]; } '' ${pkgs.nix}/bin/nix \ --extra-experimental-features nix-command \ hash path --sri ${bundledFlakeRoot} \ | tr -d '\n' > "$out" ''; bundledFlakeRootNarHash = if inBundledEval then null else builtins.readFile bundledFlakeRootNarHashFile; bundledFlake = if inBundledEval then null else builtins.getFlake ( builtins.unsafeDiscardStringContext "path:${toString bundledFlakeRoot}?narHash=${bundledFlakeRootNarHash}" ); bundledVmSmokeTargetToplevel = if inBundledEval then null else bundledFlake.nixosConfigurations.vm-smoke-target.config.system.build.toplevel; # Helper function to build a Rust workspace package # Parameters: # name: package name (e.g., "chainfire-server") # workspaceSubdir: subdirectory containing Cargo.toml (e.g., "chainfire") # mainCrate: optional main crate name if different from workspace # description: package description for meta # doCheck: whether to run tests during build (default: true) buildRustWorkspace = { name, workspaceSubdir, mainCrate ? null, description ? "", doCheck ? true }: pkgs.rustPlatform.buildRustPackage ({ pname = name; version = "0.1.0"; src = repoSrc; cargoLock = { lockFile = ./${workspaceSubdir}/Cargo.lock; }; # Build from the workspace subdirectory buildAndTestSubdir = workspaceSubdir; # Copy Cargo.lock to root for nix validation (expects it at src root) postUnpack = '' cp $sourceRoot/${workspaceSubdir}/Cargo.lock $sourceRoot/Cargo.lock ''; nativeBuildInputs = commonNativeBuildInputs; buildInputs = commonBuildInputs; # Set environment variables for build inherit (commonEnvVars) LIBCLANG_PATH PROTOC ROCKSDB_LIB_DIR; # Enable cargo tests during build (can be overridden per-package) inherit doCheck; # Test flags: run tests for the main crate only cargoTestFlags = pkgs.lib.optionals (mainCrate != null) [ "-p" mainCrate ]; # Metadata for the package meta = with pkgs.lib; { description = description; homepage = "https://github.com/yourorg/plasmacloud"; license = licenses.asl20; # Apache 2.0 maintainers = [ ]; platforms = platforms.linux; }; # Build only the server binary if mainCrate is specified # This avoids building test binaries and examples } // pkgs.lib.optionalAttrs (mainCrate != null) { cargoBuildFlags = [ "-p" mainCrate ]; }); in { # ====================================================================== # DEVELOPMENT SHELL: Drop-in replacement for shell.nix # ====================================================================== devShells.default = pkgs.mkShell { name = "cloud-dev"; buildInputs = with pkgs; [ # Rust toolchain (replaces rustup/cargo/rustc from shell.nix) rustToolchain # Protocol Buffers protobuf # LLVM/Clang (for bindgen/clang-sys) llvmPackages.libclang llvmPackages.clang # Build essentials pkg-config openssl # Development tools git curl jq grpcurl openssh sshpass clusterPython qemu vde2 bind # For RocksDB (chainfire dependency) rocksdb ]; # Environment variables for clang-sys and other build tools LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib"; PROTOC = "${pkgs.protobuf}/bin/protoc"; ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; shellHook = '' echo "Cloud Platform Development Environment" echo "=======================================" echo "Rust: $(rustc --version)" echo "Protoc: $(protoc --version)" echo "Clang: $(clang --version | head -1)" echo "" echo "Environment variables set:" echo " LIBCLANG_PATH=$LIBCLANG_PATH" echo " PROTOC=$PROTOC" echo " ROCKSDB_LIB_DIR=$ROCKSDB_LIB_DIR" echo "" echo "Available workspaces:" echo " - chainfire (distributed cluster coordination store)" echo " - flaredb (distributed SQL/KV database for metadata and tenant data)" echo " - iam (identity & access management)" echo " - plasmavmc (VM control plane)" echo " - prismnet (SDN controller)" echo " - flashdns (DNS server)" echo " - fiberlb (load balancer)" echo " - lightningstor (block storage)" echo " - nightlight (metrics store)" echo " - creditservice (quota & billing)" echo " - k8shost (kubernetes hosting)" ''; }; # ====================================================================== # PACKAGES: Buildable artifacts from each workspace # ====================================================================== packages = { # -------------------------------------------------------------------- # Chainfire: Distributed Cluster Coordination Store # -------------------------------------------------------------------- chainfire-server = buildRustWorkspace { name = "chainfire-server"; workspaceSubdir = "chainfire"; mainCrate = "chainfire-server"; description = "Distributed cluster coordination store with consensus, watches, and membership"; }; # -------------------------------------------------------------------- # FlareDB: Distributed SQL/KV Database # -------------------------------------------------------------------- flaredb-server = buildRustWorkspace { name = "flaredb-server"; workspaceSubdir = "flaredb"; mainCrate = "flaredb-server"; description = "Distributed Postgres-like SQL/KV database for service metadata, tenant data, and DBaaS"; }; # -------------------------------------------------------------------- # IAM: Identity and Access Management Service # -------------------------------------------------------------------- iam-server = buildRustWorkspace { name = "iam-server"; workspaceSubdir = "iam"; mainCrate = "iam-server"; description = "Identity and access management service with RBAC and multi-tenant support"; }; # -------------------------------------------------------------------- # CoronaFS: Shared Block Volume Service # -------------------------------------------------------------------- coronafs-server = buildRustWorkspace { name = "coronafs-server"; workspaceSubdir = "coronafs"; mainCrate = "coronafs-server"; description = "Shared block volume service exporting raw VM volumes over NBD"; }; # -------------------------------------------------------------------- # PlasmaVMC: Virtual Machine Control Plane # -------------------------------------------------------------------- plasmavmc-server = buildRustWorkspace { name = "plasmavmc-server"; workspaceSubdir = "plasmavmc"; mainCrate = "plasmavmc-server"; description = "Virtual machine control plane for managing compute instances"; }; # -------------------------------------------------------------------- # PrismNet: Software-Defined Networking Controller # -------------------------------------------------------------------- prismnet-server = buildRustWorkspace { name = "prismnet-server"; workspaceSubdir = "prismnet"; mainCrate = "prismnet-server"; description = "Software-defined networking controller with OVN integration"; }; # -------------------------------------------------------------------- # FlashDNS: High-Performance DNS Server # -------------------------------------------------------------------- flashdns-server = buildRustWorkspace { name = "flashdns-server"; workspaceSubdir = "flashdns"; mainCrate = "flashdns-server"; description = "High-performance DNS server with pattern-based reverse DNS"; }; # -------------------------------------------------------------------- # FiberLB: Layer 4/7 Load Balancer # -------------------------------------------------------------------- fiberlb-server = buildRustWorkspace { name = "fiberlb-server"; workspaceSubdir = "fiberlb"; mainCrate = "fiberlb-server"; description = "Layer 4/7 load balancer for distributing traffic across services"; }; # -------------------------------------------------------------------- # LightningStor: Block Storage Service # -------------------------------------------------------------------- lightningstor-server = buildRustWorkspace { name = "lightningstor-server"; workspaceSubdir = "lightningstor"; mainCrate = "lightningstor-server"; description = "Distributed block storage service for persistent volumes"; }; lightningstor-node = buildRustWorkspace { name = "lightningstor-node"; workspaceSubdir = "lightningstor"; mainCrate = "lightningstor-node"; description = "LightningStor distributed storage node daemon"; }; # -------------------------------------------------------------------- # NightLight: Prometheus-compatible Metrics Store # -------------------------------------------------------------------- nightlight-server = buildRustWorkspace { name = "nightlight-server"; workspaceSubdir = "nightlight"; mainCrate = "nightlight-server"; description = "Prometheus-compatible metrics storage (NightLight)"; }; # -------------------------------------------------------------------- # CreditService: Quota and Billing Controller # -------------------------------------------------------------------- creditservice-server = buildRustWorkspace { name = "creditservice-server"; workspaceSubdir = "creditservice"; mainCrate = "creditservice-server"; description = "Credit/quota management service with billing integration"; }; # -------------------------------------------------------------------- # APIGateway: API Gateway Service # -------------------------------------------------------------------- apigateway-server = buildRustWorkspace { name = "apigateway-server"; workspaceSubdir = "apigateway"; mainCrate = "apigateway-server"; description = "API Gateway for PlasmaCloud services"; }; # -------------------------------------------------------------------- # k8shost: Kubernetes Hosting Component # -------------------------------------------------------------------- k8shost-server = buildRustWorkspace { name = "k8shost-server"; workspaceSubdir = "k8shost"; mainCrate = "k8shost-server"; description = "Lightweight Kubernetes hosting with multi-tenant isolation"; }; # -------------------------------------------------------------------- # Deployer: Bare-metal bootstrap orchestration service # -------------------------------------------------------------------- deployer-server = buildRustWorkspace { name = "deployer-server"; workspaceSubdir = "deployer"; mainCrate = "deployer-server"; description = "Node bootstrap and phone-home orchestration service"; }; deployer-ctl = buildRustWorkspace { name = "deployer-ctl"; workspaceSubdir = "deployer"; mainCrate = "deployer-ctl"; description = "Declarative control utility for PhotonCloud deployer state"; }; node-agent = buildRustWorkspace { name = "node-agent"; workspaceSubdir = "deployer"; mainCrate = "node-agent"; description = "Node-local runtime agent for PhotonCloud scheduled services"; }; nix-agent = buildRustWorkspace { name = "nix-agent"; workspaceSubdir = "deployer"; mainCrate = "nix-agent"; description = "Node-local NixOS reconciliation agent for PhotonCloud hosts"; }; plasmacloud-reconciler = buildRustWorkspace { name = "plasmacloud-reconciler"; workspaceSubdir = "deployer"; mainCrate = "plasmacloud-reconciler"; description = "Declarative reconciler for host rollouts and published resources"; }; plasmacloudFlakeBundle = pkgs.runCommand "plasmacloud-flake-bundle.tar.gz" { nativeBuildInputs = [ pkgs.coreutils pkgs.gnutar pkgs.gzip ]; } '' bundle_root="$(mktemp -d)" cp -a ${bundledFlakeRootDrv}/. "$bundle_root"/ chmod -R u+w "$bundle_root" tar \ --sort=name \ --mtime='@1' \ --owner=0 \ --group=0 \ --numeric-owner \ -C "$bundle_root" \ -cf - . \ | gzip -n > "$out" ''; # -------------------------------------------------------------------- # Fleet Scheduler: Non-Kubernetes service scheduler for bare-metal nodes # -------------------------------------------------------------------- fleet-scheduler = buildRustWorkspace { name = "fleet-scheduler"; workspaceSubdir = "deployer"; mainCrate = "fleet-scheduler"; description = "Label-aware service scheduler for PhotonCloud bare-metal fleets"; }; vmClusterDeployerState = self.nixosConfigurations.node01.config.system.build.plasmacloudDeployerClusterState; vmClusterFlakeBundle = self.packages.${system}.plasmacloudFlakeBundle; vmSmokeBundledTargetToplevel = bundledVmSmokeTargetToplevel; # -------------------------------------------------------------------- # Default package: Build all servers # -------------------------------------------------------------------- default = pkgs.symlinkJoin { name = "photoncloud-all"; paths = [ self.packages.${system}.chainfire-server self.packages.${system}.flaredb-server self.packages.${system}.iam-server self.packages.${system}.plasmavmc-server self.packages.${system}.prismnet-server self.packages.${system}.flashdns-server self.packages.${system}.fiberlb-server self.packages.${system}.lightningstor-server self.packages.${system}.lightningstor-node self.packages.${system}.nightlight-server self.packages.${system}.creditservice-server self.packages.${system}.apigateway-server self.packages.${system}.k8shost-server self.packages.${system}.deployer-server self.packages.${system}.deployer-ctl self.packages.${system}.plasmacloud-reconciler self.packages.${system}.nix-agent self.packages.${system}.node-agent self.packages.${system}.fleet-scheduler self.packages.${system}.vmClusterDeployerState ]; }; }; # ====================================================================== # APPS: Runnable applications from packages # ====================================================================== apps = { chainfire-server = flake-utils.lib.mkApp { drv = self.packages.${system}.chainfire-server; }; flaredb-server = flake-utils.lib.mkApp { drv = self.packages.${system}.flaredb-server; }; iam-server = flake-utils.lib.mkApp { drv = self.packages.${system}.iam-server; }; plasmavmc-server = flake-utils.lib.mkApp { drv = self.packages.${system}.plasmavmc-server; }; prismnet-server = flake-utils.lib.mkApp { drv = self.packages.${system}.prismnet-server; }; flashdns-server = flake-utils.lib.mkApp { drv = self.packages.${system}.flashdns-server; }; fiberlb-server = flake-utils.lib.mkApp { drv = self.packages.${system}.fiberlb-server; }; lightningstor-server = flake-utils.lib.mkApp { drv = self.packages.${system}.lightningstor-server; }; lightningstor-node = flake-utils.lib.mkApp { drv = self.packages.${system}.lightningstor-node; }; nightlight-server = flake-utils.lib.mkApp { drv = self.packages.${system}.nightlight-server; }; creditservice-server = flake-utils.lib.mkApp { drv = self.packages.${system}.creditservice-server; }; apigateway-server = flake-utils.lib.mkApp { drv = self.packages.${system}.apigateway-server; }; k8shost-server = flake-utils.lib.mkApp { drv = self.packages.${system}.k8shost-server; }; deployer-server = flake-utils.lib.mkApp { drv = self.packages.${system}.deployer-server; }; deployer-ctl = flake-utils.lib.mkApp { drv = self.packages.${system}.deployer-ctl; }; plasmacloud-reconciler = flake-utils.lib.mkApp { drv = self.packages.${system}.plasmacloud-reconciler; }; nix-agent = flake-utils.lib.mkApp { drv = self.packages.${system}.nix-agent; }; node-agent = flake-utils.lib.mkApp { drv = self.packages.${system}.node-agent; }; fleet-scheduler = flake-utils.lib.mkApp { drv = self.packages.${system}.fleet-scheduler; }; }; checks = { first-boot-topology-vm-smoke = pkgs.testers.runNixOSTest ( import ./nix/tests/first-boot-topology-vm-smoke.nix { inherit pkgs; photoncloudPackages = self.packages.${system}; photoncloudModule = self.nixosModules.default; nixNosModule = nix-nos.nixosModules.default; } ); deployer-vm-smoke = pkgs.testers.runNixOSTest ( import ./nix/tests/deployer-vm-smoke.nix { inherit pkgs; photoncloudPackages = self.packages.${system}; smokeTargetToplevel = self.packages.${system}.vmSmokeBundledTargetToplevel; } ); deployer-vm-rollback = pkgs.testers.runNixOSTest ( import ./nix/tests/deployer-vm-smoke.nix { inherit pkgs; photoncloudPackages = self.packages.${system}; smokeTargetToplevel = self.packages.${system}.vmSmokeBundledTargetToplevel; desiredSystemOverrides = { health_check_command = [ "false" ]; rollback_on_failure = true; }; expectedStatus = "rolled-back"; expectCurrentSystemMatchesTarget = false; expectMarkerPresent = false; } ); fiberlb-native-bgp-vm-smoke = pkgs.testers.runNixOSTest ( import ./nix/tests/fiberlb-native-bgp-vm-smoke.nix { inherit pkgs; photoncloudPackages = self.packages.${system}; photoncloudModule = self.nixosModules.default; nixNosModule = nix-nos.nixosModules.default; } ); fiberlb-native-bgp-multipath-vm-smoke = pkgs.testers.runNixOSTest ( import ./nix/tests/fiberlb-native-bgp-multipath-vm-smoke.nix { inherit pkgs; photoncloudPackages = self.packages.${system}; photoncloudModule = self.nixosModules.default; nixNosModule = nix-nos.nixosModules.default; } ); fiberlb-native-bgp-interop-vm-smoke = pkgs.testers.runNixOSTest ( import ./nix/tests/fiberlb-native-bgp-interop-vm-smoke.nix { inherit pkgs; photoncloudPackages = self.packages.${system}; photoncloudModule = self.nixosModules.default; nixNosModule = nix-nos.nixosModules.default; } ); fiberlb-native-bgp-ecmp-drain-vm-smoke = pkgs.testers.runNixOSTest ( import ./nix/tests/fiberlb-native-bgp-ecmp-drain-vm-smoke.nix { inherit pkgs; photoncloudPackages = self.packages.${system}; photoncloudModule = self.nixosModules.default; nixNosModule = nix-nos.nixosModules.default; } ); deployer-bootstrap-e2e = pkgs.runCommand "deployer-bootstrap-e2e" { nativeBuildInputs = with pkgs; [ bash coreutils curl findutils gawk gnugrep gnused procps python3 ]; PHOTONCLOUD_E2E_IN_NIX = "1"; PHOTONCLOUD_CHAINFIRE_SERVER_BIN = "${self.packages.${system}.chainfire-server}/bin/chainfire"; PHOTONCLOUD_DEPLOYER_SERVER_BIN = "${self.packages.${system}.deployer-server}/bin/deployer-server"; PHOTONCLOUD_DEPLOYER_CTL_BIN = "${self.packages.${system}.deployer-ctl}/bin/deployer-ctl"; } '' export HOME="$TMPDIR/home" mkdir -p "$HOME" export PATH="${pkgs.lib.makeBinPath [ pkgs.bash pkgs.coreutils pkgs.curl pkgs.findutils pkgs.gawk pkgs.gnugrep pkgs.gnused pkgs.procps pkgs.python3 ]}" bash ${./deployer/scripts/verify-deployer-bootstrap-e2e.sh} touch "$out" ''; host-lifecycle-e2e = pkgs.runCommand "host-lifecycle-e2e" { nativeBuildInputs = with pkgs; [ bash coreutils curl findutils gawk gnugrep gnused procps python3 ]; PHOTONCLOUD_E2E_IN_NIX = "1"; PHOTONCLOUD_CHAINFIRE_SERVER_BIN = "${self.packages.${system}.chainfire-server}/bin/chainfire"; PHOTONCLOUD_DEPLOYER_CTL_BIN = "${self.packages.${system}.deployer-ctl}/bin/deployer-ctl"; PHOTONCLOUD_PLASMACLOUD_RECONCILER_BIN = "${self.packages.${system}.plasmacloud-reconciler}/bin/plasmacloud-reconciler"; } '' export HOME="$TMPDIR/home" mkdir -p "$HOME" export PATH="${pkgs.lib.makeBinPath [ pkgs.bash pkgs.coreutils pkgs.curl pkgs.findutils pkgs.gawk pkgs.gnugrep pkgs.gnused pkgs.procps pkgs.python3 ]}" bash ${./deployer/scripts/verify-host-lifecycle-e2e.sh} touch "$out" ''; fleet-scheduler-e2e = pkgs.runCommand "fleet-scheduler-e2e" { nativeBuildInputs = with pkgs; [ bash coreutils curl findutils gawk gnugrep gnused procps python3 ]; PHOTONCLOUD_E2E_IN_NIX = "1"; PHOTONCLOUD_CHAINFIRE_SERVER_BIN = "${self.packages.${system}.chainfire-server}/bin/chainfire"; PHOTONCLOUD_DEPLOYER_CTL_BIN = "${self.packages.${system}.deployer-ctl}/bin/deployer-ctl"; PHOTONCLOUD_NODE_AGENT_BIN = "${self.packages.${system}.node-agent}/bin/node-agent"; PHOTONCLOUD_FLEET_SCHEDULER_BIN = "${self.packages.${system}.fleet-scheduler}/bin/fleet-scheduler"; } '' export HOME="$TMPDIR/home" mkdir -p "$HOME" export PATH="${pkgs.lib.makeBinPath [ pkgs.bash pkgs.coreutils pkgs.curl pkgs.findutils pkgs.gawk pkgs.gnugrep pkgs.gnused pkgs.procps pkgs.python3 ]}" bash ${./deployer/scripts/verify-fleet-scheduler-e2e.sh} touch "$out" ''; }; } ) // { # ======================================================================== # NIXOS MODULES: System-level service modules (non-system-specific) # ======================================================================== nixosModules.default = import ./nix/modules; nixosModules.photoncloud = import ./nix/modules; nixosModules.plasmacloud = import ./nix/modules; # backwards compatibility # ======================================================================== # NIXOS CONFIGURATIONS: Netboot images for bare-metal provisioning # ======================================================================== nixosConfigurations = { # Control Plane netboot image (all 8 services) netboot-control-plane = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ./nix/images/netboot-control-plane.nix ]; }; # Worker netboot image (compute-focused services) netboot-worker = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ./nix/images/netboot-worker.nix ]; }; # All-in-One netboot image (single-node deployment) netboot-all-in-one = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ./nix/images/netboot-all-in-one.nix ]; }; # Base netboot image (minimal, for VM testing and provisioning) netboot-base = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ./nix/images/netboot-base.nix ]; }; # Offline-friendly target used by deployer VM smoke tests. vm-smoke-target = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ./nix/images/deployer-vm-smoke-target.nix ]; }; # PlasmaCloud ISO (T061.S5 - bootable ISO with cluster-config embedding) plasmacloud-iso = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ./nix/iso/plasmacloud-iso.nix nix-nos.nixosModules.default self.nixosModules.default { nixpkgs.overlays = [ self.overlays.default ]; } ]; }; # T036 VM Cluster Nodes (for nixos-anywhere deployment) pxe-server = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ disko.nixosModules.disko ./baremetal/vm-cluster/pxe-server/configuration.nix ./baremetal/vm-cluster/pxe-server/disko.nix self.nixosModules.default { nixpkgs.overlays = [ self.overlays.default ]; } ]; }; node01 = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ disko.nixosModules.disko nix-nos.nixosModules.default ./nix/nodes/vm-cluster/node01/configuration.nix self.nixosModules.default ({ pkgs, ... }: { services.deployer = { enable = true; bindAddr = "0.0.0.0:8088"; chainfireEndpoints = [ "http://192.168.100.11:2379" ]; clusterId = "plasmacloud-vm-cluster"; requireChainfire = true; allowUnknownNodes = false; allowUnauthenticated = false; bootstrapToken = "vm-cluster-bootstrap-token"; adminToken = "vm-cluster-admin-token"; bootstrapFlakeBundle = pkgs.plasmacloudFlakeBundle; seedClusterState = true; }; services.nix-agent = { enable = true; chainfireEndpoint = "http://192.168.100.11:2379"; clusterId = "plasmacloud-vm-cluster"; nodeId = "node01"; flakeRoot = self.outPath; intervalSecs = 30; apply = true; }; }) { nixpkgs.overlays = [ self.overlays.default ]; } ]; }; node02 = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ disko.nixosModules.disko nix-nos.nixosModules.default ./nix/nodes/vm-cluster/node02/configuration.nix self.nixosModules.default { services.nix-agent = { enable = true; chainfireEndpoint = "http://192.168.100.11:2379"; clusterId = "plasmacloud-vm-cluster"; nodeId = "node02"; flakeRoot = self.outPath; intervalSecs = 30; apply = true; }; } { nixpkgs.overlays = [ self.overlays.default ]; } ]; }; node03 = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ disko.nixosModules.disko nix-nos.nixosModules.default ./nix/nodes/vm-cluster/node03/configuration.nix self.nixosModules.default { services.nix-agent = { enable = true; chainfireEndpoint = "http://192.168.100.11:2379"; clusterId = "plasmacloud-vm-cluster"; nodeId = "node03"; flakeRoot = self.outPath; intervalSecs = 30; apply = true; }; } { nixpkgs.overlays = [ self.overlays.default ]; } ]; }; }; # ======================================================================== # OVERLAY: Provides PhotonCloud packages to nixpkgs # ======================================================================== # Usage in NixOS configuration: # nixpkgs.overlays = [ inputs.photoncloud.overlays.default ]; overlays.default = final: prev: { chainfire-server = self.packages.${final.system}.chainfire-server; flaredb-server = self.packages.${final.system}.flaredb-server; iam-server = self.packages.${final.system}.iam-server; coronafs-server = self.packages.${final.system}.coronafs-server; plasmavmc-server = self.packages.${final.system}.plasmavmc-server; prismnet-server = self.packages.${final.system}.prismnet-server; flashdns-server = self.packages.${final.system}.flashdns-server; fiberlb-server = self.packages.${final.system}.fiberlb-server; lightningstor-server = self.packages.${final.system}.lightningstor-server; lightningstor-node = self.packages.${final.system}.lightningstor-node; nightlight-server = self.packages.${final.system}.nightlight-server; creditservice-server = self.packages.${final.system}.creditservice-server; apigateway-server = self.packages.${final.system}.apigateway-server; k8shost-server = self.packages.${final.system}.k8shost-server; deployer-server = self.packages.${final.system}.deployer-server; deployer-ctl = self.packages.${final.system}.deployer-ctl; plasmacloud-reconciler = self.packages.${final.system}.plasmacloud-reconciler; plasmacloudFlakeBundle = self.packages.${final.system}.plasmacloudFlakeBundle; nix-agent = self.packages.${final.system}.nix-agent; node-agent = self.packages.${final.system}.node-agent; fleet-scheduler = self.packages.${final.system}.fleet-scheduler; }; }; }