{ 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 }: 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 ); }; # 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"; }; plasmacloudFlakeBundle = pkgs.runCommand "plasmacloud-flake-bundle.tar.gz" { nativeBuildInputs = [ pkgs.gnutar pkgs.gzip ]; } '' tar \ --sort=name \ --mtime='@1' \ --owner=0 \ --group=0 \ --numeric-owner \ -C ${flakeBundleSrc} \ -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; # -------------------------------------------------------------------- # 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}.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; }; 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; }; }; } ) // { # ======================================================================== # 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 ]; }; # 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; 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; }; }; }