diff --git a/core b/core new file mode 100644 index 0000000..f379909 Binary files /dev/null and b/core differ diff --git a/flake.lock b/flake.lock index f076fab..2f10472 100644 --- a/flake.lock +++ b/flake.lock @@ -159,6 +159,26 @@ } }, "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1768135262, + "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { "inputs": { "nixpkgs-lib": [ "lazyvim-nixvim", @@ -386,7 +406,7 @@ }, "lazyvim-nixvim": { "inputs": { - "flake-parts": "flake-parts", + "flake-parts": "flake-parts_2", "nixpkgs": "nixpkgs", "nixvim": "nixvim" }, @@ -608,6 +628,7 @@ "inputs": { "agenix": "agenix", "disko": "disko", + "flake-parts": "flake-parts", "home-manager": "home-manager_2", "lazyvim-nixvim": "lazyvim-nixvim", "nixos-generators": "nixos-generators", diff --git a/flake.nix b/flake.nix index e1cd249..8d72f30 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,7 @@ # ============================================================================ # This file defines the inputs (dependencies) and outputs (configurations) # for Athenix. It ties together the hardware, software, and user - # configurations into deployable systems. + # configurations into deployable systems using flake-parts. inputs = { # Core NixOS package repository (Release 25.11) @@ -13,6 +13,12 @@ # Older kernel packages for Surface compatibility if needed nixpkgs-old-kernel.url = "github:NixOS/nixpkgs/nixos-25.05"; + # Flake-parts for modular flake organization + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + # Home Manager for user environment management home-manager = { url = "github:nix-community/home-manager/release-25.11"; @@ -54,51 +60,27 @@ inputs.nixpkgs.follows = "nixpkgs"; }; }; + outputs = - inputs@{ - self, - nixpkgs, - nixpkgs-old-kernel, - home-manager, - disko, - agenix, - lazyvim-nixvim, - nixos-hardware, - vscode-server, - nixos-generators, - ... - }: - let - fleet = self.lib.mkFleet { inherit inputs; }; - linuxSystem = "x86_64-linux"; - artifacts = import ./installer/artifacts.nix { - inherit inputs fleet self; - system = linuxSystem; - }; - forAllSystems = nixpkgs.lib.genAttrs [ + inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + # Support all common systems + systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; - in - { - # Formatter for 'nix fmt' - formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style); - # Generate NixOS configurations from fleet generator - nixosConfigurations = fleet.nixosConfigurations; - - # Expose artifacts to all systems, but they are always built for x86_64-linux - packages.${linuxSystem} = artifacts; - - # Expose host type modules and installer modules for external use - nixosModules = import ./installer/modules.nix { inherit inputs; }; - - # Library functions - lib = import ./lib { inherit inputs; }; - - # Templates for external configurations - templates = import ./templates; + # Import flake-parts modules + imports = [ + ./parts/formatter.nix + ./parts/lib.nix + ./parts/fleet-data.nix + ./parts/nixos-configurations.nix + ./parts/nixos-modules.nix + ./parts/packages.nix + ./parts/templates.nix + ]; }; } diff --git a/fleet/common.nix b/fleet/common.nix index 5bc95bf..5f4cbe7 100644 --- a/fleet/common.nix +++ b/fleet/common.nix @@ -12,6 +12,7 @@ }: { imports = [ + (import ./fleet-data.nix { inherit inputs lib; }) ./fs.nix ./boot.nix ./user-config.nix diff --git a/fleet/default.nix b/fleet/default.nix index e870fbd..8fa9298 100644 --- a/fleet/default.nix +++ b/fleet/default.nix @@ -1,7 +1,7 @@ { inputs, - fleet ? null, - hwTypes ? null, + lib, + config, ... }: @@ -13,26 +13,12 @@ # configurations with flexible type associations. let - nixpkgs = inputs.nixpkgs; - lib = nixpkgs.lib; # Evaluate inventory to get fleet data # Import fleet-option.nix (defines athenix.fleet) and inventory.nix (sets values) # We use a minimal module here to avoid circular dependencies from common.nix's imports - inventoryModule = lib.evalModules { - modules = [ - (import ./fleet-option.nix { inherit inputs; }) - { - _module.args = { - pkgs = nixpkgs.legacyPackages.x86_64-linux; - }; - } - (lib.mkIf (fleet != null) { athenix.fleet = lib.mkForce fleet; }) - (lib.mkIf (hwTypes != null) { athenix.hwTypes = lib.mkForce hwTypes; }) - ]; - }; - - hostTypes = inventoryModule.config.athenix.hwTypes; + + hostTypes = config.athenix.hwTypes; # Helper to create a single NixOS system configuration mkHost = @@ -64,9 +50,7 @@ let null; # Load users.nix to find external user modules - pkgs = nixpkgs.legacyPackages.${system}; - usersData = import ../users.nix { inherit pkgs; }; - accounts = usersData.athenix.users or { }; + accounts = config.athenix.users or { }; # Build a map of user names to their nixos module paths (if they exist) # We'll use this to conditionally import modules based on user.enable @@ -285,7 +269,7 @@ let lib.recursiveUpdate deviceHosts countHosts ); - fleetData = inventoryModule.config.athenix.fleet; + fleetData = config.athenix.fleet; # Flatten the nested structure allHosts = lib.foldl' lib.recursiveUpdate { } (lib.attrValues (processInventory fleetData)); diff --git a/fleet/fleet-data.nix b/fleet/fleet-data.nix new file mode 100644 index 0000000..12c6721 --- /dev/null +++ b/fleet/fleet-data.nix @@ -0,0 +1,65 @@ +# ============================================================================ +# Fleet Data for NixOS Configurations +# ============================================================================ +# This module exposes only the fleet inventory data (not hwTypes module functions) +# to individual NixOS configurations. Used by fleet/common.nix. +{ inputs, lib, ... }: +let + fleetDefinition = lib.mkOption { + description = "Hardware types definitions for the fleet."; + type = lib.types.attrsOf ( + lib.types.submodule ( + { name, ... }: + { + options = { + type = lib.mkOption { + type = lib.types.oneOf [ + lib.types.str + lib.types.listOf lib.types.str + ]; + default = name; + description = "Type(s) of system configuration for this device."; + }; + system = lib.mkOption { + type = lib.types.str; + default = "x86_64-linux"; + description = "NixOS system architecture for this hardware type."; + }; + devices = lib.mkOption { + type = lib.types.oneOf [ + lib.types.int + (lib.types.attrsOf ( + lib.types.submodule ( + { name, ... }: + { + freeformType = lib.types.attrs; + } + ) + )) + ]; + }; + count = lib.mkOption { + type = lib.types.int; + default = 0; + description = "Number of devices of this type to create."; + }; + defaultCount = lib.mkOption { + type = lib.types.int; + default = 0; + description = "Default number of devices to create with default configurations and numbered hostnames."; + }; + overrides = lib.mkOption { + type = lib.types.attrs; + default = { }; + description = "Overrides to apply to all devices of this type."; + }; + }; + } + ) + ); + }; +in +{ + imports = [ ../inventory.nix ]; + options.athenix.fleet = fleetDefinition; +} diff --git a/fleet/fleet-option.nix b/fleet/fleet-option.nix index 7dc136b..88e9f32 100644 --- a/fleet/fleet-option.nix +++ b/fleet/fleet-option.nix @@ -3,8 +3,7 @@ # ============================================================================ # This module only defines the athenix.fleet option without any dependencies. # Used by fleet/default.nix to evaluate inventory data without circular dependencies. -{ inputs, ... }: -{ lib, ... }: +{ inputs, lib, ... }: let fleetDefinition = lib.mkOption { description = "Hardware types definitions for the fleet."; @@ -70,6 +69,5 @@ in }; }; - config.athenix.fleet = lib.mkDefault (import ../inventory.nix); config.athenix.hwTypes = lib.mkDefault (import ../hw { inherit inputs; }); } diff --git a/fleet/user-config.nix b/fleet/user-config.nix index 299acef..7f33c83 100644 --- a/fleet/user-config.nix +++ b/fleet/user-config.nix @@ -15,8 +15,7 @@ let # Load users.nix to get account definitions - usersData = import ../users.nix { inherit pkgs; }; - accounts = usersData.athenix.users or { }; + accounts = config.athenix.users or { }; # Helper: Resolve external module path from fetchGit/fetchTarball/path resolveExternalPath = diff --git a/inventory.nix b/inventory.nix index 0338d8f..25eff41 100644 --- a/inventory.nix +++ b/inventory.nix @@ -70,85 +70,87 @@ # rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014"; # }; # }; -{ - # ========== Lab Laptops ========== - # Creates: nix-laptop1, nix-laptop2 - # Both get hdh20267 user via overrides - nix-laptop = { - devices = 2; - overrides.athenix.users.hdh20267.enable = true; - }; - - # ========== Desktop ========== - # Creates: nix-desktop1 - nix-desktop = { - devices = 1; - }; - - # ========== Surface Tablets (Kiosk Mode) ========== - # Creates: nix-surface1 (custom), nix-surface2, nix-surface3 (via defaultCount) - nix-surface = { - defaultCount = 3; - devices = { - "1".athenix.sw.kioskUrl = "https://google.com"; +{...}: { + athenix.fleet = { + # ========== Lab Laptops ========== + # Creates: nix-laptop1, nix-laptop2 + # Both get hdh20267 user via overrides + nix-laptop = { + devices = 2; + overrides.athenix.users.hdh20267.enable = true; }; - overrides = { - athenix.sw.kioskUrl = "https://yahoo.com"; - }; - }; - # ========== LXC Containers ========== - # Creates: nix-builder (without lxc prefix) - nix-lxc = { - devices = { - "nix-builder" = { - # Gitea Actions self-hosted runner configuration - athenix.sw = { - type = [ - "headless" - "builders" - ]; - builders.giteaRunner = { - enable = true; - url = "https://git.factory.uga.edu"; - # Token file must be created manually at this path with a Gitea runner token - # Generate in repository settings: Settings > Actions > Runners > Create new Runner - # echo "TOKEN=YOUR_TOKEN_HERE" | sudo tee /var/lib/gitea-runner-token > /dev/null - tokenFile = "/var/lib/gitea-runner-token"; - # Labels to identify this runner in workflows - extraLabels = [ - "self-hosted" - "nix-builder" + # ========== Desktop ========== + # Creates: nix-desktop1 + nix-desktop = { + devices = 1; + }; + + # ========== Surface Tablets (Kiosk Mode) ========== + # Creates: nix-surface1 (custom), nix-surface2, nix-surface3 (via defaultCount) + nix-surface = { + defaultCount = 3; + devices = { + "1".athenix.sw.kioskUrl = "https://google.com"; + }; + overrides = { + athenix.sw.kioskUrl = "https://yahoo.com"; + }; + }; + + # ========== LXC Containers ========== + # Creates: nix-builder (without lxc prefix) + nix-lxc = { + devices = { + "nix-builder" = { + # Gitea Actions self-hosted runner configuration + athenix.sw = { + type = [ + "headless" + "builders" ]; - # Runner service name - name = "athenix"; + builders.giteaRunner = { + enable = true; + url = "https://git.factory.uga.edu"; + # Token file must be created manually at this path with a Gitea runner token + # Generate in repository settings: Settings > Actions > Runners > Create new Runner + # echo "TOKEN=YOUR_TOKEN_HERE" | sudo tee /var/lib/gitea-runner-token > /dev/null + tokenFile = "/var/lib/gitea-runner-token"; + # Labels to identify this runner in workflows + extraLabels = [ + "self-hosted" + "nix-builder" + ]; + # Runner service name + name = "athenix"; + }; }; }; + "usda-dash".external = builtins.fetchGit { + url = "https://git.factory.uga.edu/MODEL/usda-dash-config.git"; + rev = "dab32f5884895cead0fae28cb7d88d17951d0c12"; + submodules = true; + }; }; - "usda-dash".external = builtins.fetchGit { - url = "https://git.factory.uga.edu/MODEL/usda-dash-config.git"; - rev = "dab32f5884895cead0fae28cb7d88d17951d0c12"; - submodules = true; + overrides = { + athenix.host.useHostPrefix = false; }; }; - overrides = { - athenix.host.useHostPrefix = false; + + # ========== WSL Instances ========== + # Creates: nix-wsl-alireza + nix-wsl = { + devices = { + "alireza".athenix.forUser = "sv22900"; + }; }; + + # ========== ZimaBoard Desktops ========== + # Creates: nix-zima1, nix-zima2, nix-zima3 + nix-zima.devices = 3; + + # ========== Ephemeral/Netboot System ========== + # Creates: nix-ephemeral1 + nix-ephemeral.devices = 1; }; - - # ========== WSL Instances ========== - # Creates: nix-wsl-alireza - nix-wsl = { - devices = { - "alireza".athenix.forUser = "sv22900"; - }; - }; - - # ========== ZimaBoard Desktops ========== - # Creates: nix-zima1, nix-zima2, nix-zima3 - nix-zima.devices = 3; - - # ========== Ephemeral/Netboot System ========== - # Creates: nix-ephemeral1 - nix-ephemeral.devices = 1; } diff --git a/lib/mkFleet.nix b/lib/mkFleet.nix index 94a034c..e9cd399 100644 --- a/lib/mkFleet.nix +++ b/lib/mkFleet.nix @@ -2,10 +2,9 @@ # Usage: nixosConfigurations = athenix.lib.mkFleet { fleet = { ... }; hwTypes = { ... }; } { inputs, - fleet ? null, - hwTypes ? null, + lib, + config }: import ../fleet/default.nix { - inherit inputs; - inherit fleet hwTypes; + inherit inputs lib config; } diff --git a/parts/formatter.nix b/parts/formatter.nix new file mode 100644 index 0000000..eea1ade --- /dev/null +++ b/parts/formatter.nix @@ -0,0 +1,9 @@ +# Formatter configuration for flake-parts +{ ... }: +{ + perSystem = + { pkgs, ... }: + { + formatter = pkgs.nixfmt-rfc-style; + }; +} diff --git a/parts/lib.nix b/parts/lib.nix new file mode 100644 index 0000000..efa3287 --- /dev/null +++ b/parts/lib.nix @@ -0,0 +1,5 @@ +# Library functions for flake-parts +{ inputs, ... }: +{ + flake.lib = import ../lib { inherit inputs; }; +} diff --git a/parts/nixos-configurations.nix b/parts/nixos-configurations.nix new file mode 100644 index 0000000..dcf2ce2 --- /dev/null +++ b/parts/nixos-configurations.nix @@ -0,0 +1,12 @@ +# NixOS configurations generated from fleet +{ inputs, self, lib, pkgs, config, ... }: +{ + imports = [ + (import ../fleet/fleet-option.nix { inherit inputs lib pkgs config; }) + ]; + flake.nixosConfigurations = + let + fleet = self.lib.mkFleet { inherit inputs lib pkgs config; }; + in + fleet.nixosConfigurations; +} diff --git a/parts/nixos-modules.nix b/parts/nixos-modules.nix new file mode 100644 index 0000000..6bc4965 --- /dev/null +++ b/parts/nixos-modules.nix @@ -0,0 +1,5 @@ +# Expose host type modules and installer modules for external use +{ inputs, ... }: +{ + flake.nixosModules = import ../installer/modules.nix { inherit inputs; }; +} diff --git a/parts/packages.nix b/parts/packages.nix new file mode 100644 index 0000000..0207533 --- /dev/null +++ b/parts/packages.nix @@ -0,0 +1,27 @@ +# Build artifacts (ISOs, LXC containers, etc.) +{ + inputs, + self, + lib, + config, + ... +}: +{ + perSystem = + { system, ... }: + lib.mkIf (system == "x86_64-linux") { + packages = + let + fleet = self.lib.mkFleet { inherit inputs lib config; }; + artifacts = import ../installer/artifacts.nix { + inherit + inputs + fleet + self + system + ; + }; + in + artifacts; + }; +} diff --git a/parts/templates.nix b/parts/templates.nix new file mode 100644 index 0000000..96cce47 --- /dev/null +++ b/parts/templates.nix @@ -0,0 +1,5 @@ +# Templates for external configurations +{ ... }: +{ + flake.templates = import ../templates; +}