Compare commits
7 Commits
67e7a57402
...
d39e9ee253
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d39e9ee253 | ||
|
|
6bf939a305 | ||
|
|
97358a6aee | ||
|
|
854882cbb9 | ||
|
|
acbc7518e8 | ||
|
|
005207d3e4 | ||
|
|
d34325de53 |
41
flake.lock
generated
41
flake.lock
generated
@@ -159,6 +159,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-parts": {
|
"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": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
"lazyvim-nixvim",
|
"lazyvim-nixvim",
|
||||||
@@ -318,11 +338,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767619900,
|
"lastModified": 1767910483,
|
||||||
"narHash": "sha256-KpoCBPvwHz3gAQtIUkohE2InRBFK3r0/FM6z5SPWfvM=",
|
"narHash": "sha256-MOU5YdVu4DVwuT5ztXgQpPuRRBjSjUGIdUzOQr9iQOY=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "6bd04da47cfb48dfd15eabf08364b78ad894f5b2",
|
"rev": "82fb7dedaad83e5e279127a38ef410bcfac6d77c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -386,7 +406,7 @@
|
|||||||
},
|
},
|
||||||
"lazyvim-nixvim": {
|
"lazyvim-nixvim": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts_2",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixvim": "nixvim"
|
"nixvim": "nixvim"
|
||||||
},
|
},
|
||||||
@@ -518,11 +538,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-old-kernel": {
|
"nixpkgs-old-kernel": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767051569,
|
"lastModified": 1767313136,
|
||||||
"narHash": "sha256-0MnuWoN+n1UYaGBIpqpPs9I9ZHW4kynits4mrnh1Pk4=",
|
"narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "40ee5e1944bebdd128f9fbada44faefddfde29bd",
|
"rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -534,11 +554,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767480499,
|
"lastModified": 1768242861,
|
||||||
"narHash": "sha256-8IQQUorUGiSmFaPnLSo2+T+rjHtiNWc+OAzeHck7N48=",
|
"narHash": "sha256-F4IIxa5xDHjtrmMcayM8lHctUq1oGltfBQu2+oqDWP4=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "30a3c519afcf3f99e2c6df3b359aec5692054d92",
|
"rev": "1327e798cb055f96f92685df444e9a2c326ab5ed",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -608,6 +628,7 @@
|
|||||||
"inputs": {
|
"inputs": {
|
||||||
"agenix": "agenix",
|
"agenix": "agenix",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
"home-manager": "home-manager_2",
|
"home-manager": "home-manager_2",
|
||||||
"lazyvim-nixvim": "lazyvim-nixvim",
|
"lazyvim-nixvim": "lazyvim-nixvim",
|
||||||
"nixos-generators": "nixos-generators",
|
"nixos-generators": "nixos-generators",
|
||||||
|
|||||||
63
flake.nix
63
flake.nix
@@ -4,7 +4,7 @@
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
# This file defines the inputs (dependencies) and outputs (configurations)
|
# This file defines the inputs (dependencies) and outputs (configurations)
|
||||||
# for Athenix. It ties together the hardware, software, and user
|
# for Athenix. It ties together the hardware, software, and user
|
||||||
# configurations into deployable systems.
|
# configurations into deployable systems using flake-parts.
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
# Core NixOS package repository (Release 25.11)
|
# Core NixOS package repository (Release 25.11)
|
||||||
@@ -13,6 +13,12 @@
|
|||||||
# Older kernel packages for Surface compatibility if needed
|
# Older kernel packages for Surface compatibility if needed
|
||||||
nixpkgs-old-kernel.url = "github:NixOS/nixpkgs/nixos-25.05";
|
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 for user environment management
|
||||||
home-manager = {
|
home-manager = {
|
||||||
url = "github:nix-community/home-manager/release-25.11";
|
url = "github:nix-community/home-manager/release-25.11";
|
||||||
@@ -54,51 +60,28 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
inputs@{
|
inputs@{ flake-parts, ... }:
|
||||||
self,
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
nixpkgs,
|
# Support all common systems
|
||||||
nixpkgs-old-kernel,
|
systems = [
|
||||||
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 [
|
|
||||||
"x86_64-linux"
|
"x86_64-linux"
|
||||||
"aarch64-linux"
|
"aarch64-linux"
|
||||||
"x86_64-darwin"
|
"x86_64-darwin"
|
||||||
"aarch64-darwin"
|
"aarch64-darwin"
|
||||||
];
|
];
|
||||||
in
|
|
||||||
{
|
|
||||||
# Formatter for 'nix fmt'
|
|
||||||
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style);
|
|
||||||
|
|
||||||
# Generate NixOS configurations from fleet generator
|
# Import flake-parts modules
|
||||||
nixosConfigurations = fleet.nixosConfigurations;
|
imports = [
|
||||||
|
./parts/formatter.nix
|
||||||
# Expose artifacts to all systems, but they are always built for x86_64-linux
|
./parts/lib.nix
|
||||||
packages.${linuxSystem} = artifacts;
|
./parts/nixos-configurations.nix
|
||||||
|
./parts/nixos-modules.nix
|
||||||
# Expose host type modules and installer modules for external use
|
./parts/packages.nix
|
||||||
nixosModules = import ./installer/modules.nix { inherit inputs; };
|
./parts/templates.nix
|
||||||
|
./inventory.nix
|
||||||
# Library functions
|
./users.nix
|
||||||
lib = import ./lib { inherit inputs; };
|
];
|
||||||
|
|
||||||
# Templates for external configurations
|
|
||||||
templates = import ./templates;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
./fs.nix
|
./fs.nix
|
||||||
./boot.nix
|
./boot.nix
|
||||||
./user-config.nix
|
./user-config.nix
|
||||||
|
./fleet-option.nix
|
||||||
../sw
|
../sw
|
||||||
../users.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
options.athenix = {
|
options.athenix = {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
inputs,
|
inputs,
|
||||||
fleet ? null,
|
lib,
|
||||||
hwTypes ? null,
|
config,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
@@ -13,26 +13,12 @@
|
|||||||
# configurations with flexible type associations.
|
# configurations with flexible type associations.
|
||||||
|
|
||||||
let
|
let
|
||||||
nixpkgs = inputs.nixpkgs;
|
|
||||||
lib = nixpkgs.lib;
|
|
||||||
|
|
||||||
# Evaluate inventory to get fleet data
|
# Evaluate inventory to get fleet data
|
||||||
# Import fleet-option.nix (defines athenix.fleet) and inventory.nix (sets values)
|
# 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
|
# 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
|
# Helper to create a single NixOS system configuration
|
||||||
mkHost =
|
mkHost =
|
||||||
@@ -64,9 +50,7 @@ let
|
|||||||
null;
|
null;
|
||||||
|
|
||||||
# Load users.nix to find external user modules
|
# Load users.nix to find external user modules
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
accounts = config.athenix.users or { };
|
||||||
usersData = import ../users.nix { inherit pkgs; };
|
|
||||||
accounts = usersData.athenix.users or { };
|
|
||||||
|
|
||||||
# Build a map of user names to their nixos module paths (if they exist)
|
# 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
|
# We'll use this to conditionally import modules based on user.enable
|
||||||
@@ -285,7 +269,7 @@ let
|
|||||||
lib.recursiveUpdate deviceHosts countHosts
|
lib.recursiveUpdate deviceHosts countHosts
|
||||||
);
|
);
|
||||||
|
|
||||||
fleetData = inventoryModule.config.athenix.fleet;
|
fleetData = config.athenix.fleet;
|
||||||
|
|
||||||
# Flatten the nested structure
|
# Flatten the nested structure
|
||||||
allHosts = lib.foldl' lib.recursiveUpdate { } (lib.attrValues (processInventory fleetData));
|
allHosts = lib.foldl' lib.recursiveUpdate { } (lib.attrValues (processInventory fleetData));
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
# This module only defines the athenix.fleet option without any dependencies.
|
# This module only defines the athenix.fleet option without any dependencies.
|
||||||
# Used by fleet/default.nix to evaluate inventory data without circular dependencies.
|
# Used by fleet/default.nix to evaluate inventory data without circular dependencies.
|
||||||
{ inputs, ... }:
|
{ inputs, lib, ... }:
|
||||||
{ lib, ... }:
|
|
||||||
let
|
let
|
||||||
fleetDefinition = lib.mkOption {
|
fleetDefinition = lib.mkOption {
|
||||||
description = "Hardware types definitions for the fleet.";
|
description = "Hardware types definitions for the fleet.";
|
||||||
@@ -60,6 +59,109 @@ let
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
# Submodule defining the structure of a user account
|
||||||
|
userSubmodule = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
isNormalUser = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
description = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
extraGroups = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
hashedPassword = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "!";
|
||||||
|
};
|
||||||
|
extraPackages = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.package;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
excludePackages = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.package;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
homePackages = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.package;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
extraImports = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.path;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
external = lib.mkOption {
|
||||||
|
type = lib.types.nullOr (
|
||||||
|
lib.types.oneOf [
|
||||||
|
lib.types.path
|
||||||
|
lib.types.package
|
||||||
|
lib.types.attrs
|
||||||
|
]
|
||||||
|
);
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
External user configuration module. Can be:
|
||||||
|
- A path to a local module directory
|
||||||
|
- A fetchGit/fetchTarball result pointing to a repository
|
||||||
|
|
||||||
|
The external module can contain:
|
||||||
|
- user.nix (optional): Sets athenix.users.<name> options AND home-manager config
|
||||||
|
- nixos.nix (optional): System-level NixOS configuration
|
||||||
|
|
||||||
|
Example: builtins.fetchGit { url = "https://github.com/user/dotfiles"; rev = "..."; }
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
opensshKeys = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of SSH public keys for the user.";
|
||||||
|
};
|
||||||
|
shell = lib.mkOption {
|
||||||
|
type = lib.types.nullOr (
|
||||||
|
lib.types.enum [
|
||||||
|
"bash"
|
||||||
|
"zsh"
|
||||||
|
"fish"
|
||||||
|
"tcsh"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
default = "bash";
|
||||||
|
description = "The shell for this user.";
|
||||||
|
};
|
||||||
|
editor = lib.mkOption {
|
||||||
|
type = lib.types.nullOr (
|
||||||
|
lib.types.enum [
|
||||||
|
"vim"
|
||||||
|
"neovim"
|
||||||
|
"emacs"
|
||||||
|
"nano"
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
default = "neovim";
|
||||||
|
description = "The default editor for this user.";
|
||||||
|
};
|
||||||
|
useZshTheme = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to apply the system Zsh theme.";
|
||||||
|
};
|
||||||
|
useNvimPlugins = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to apply the system Neovim configuration.";
|
||||||
|
};
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether this user account is enabled on this system.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.athenix = {
|
options.athenix = {
|
||||||
@@ -68,8 +170,12 @@ in
|
|||||||
description = "Hardware types definitions for the fleet.";
|
description = "Hardware types definitions for the fleet.";
|
||||||
type = lib.types.attrs;
|
type = lib.types.attrs;
|
||||||
};
|
};
|
||||||
|
users = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf userSubmodule;
|
||||||
|
default = { };
|
||||||
|
description = "User accounts configuration. Set enable=true for users that should exist on this system.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config.athenix.fleet = lib.mkDefault (import ../inventory.nix);
|
|
||||||
config.athenix.hwTypes = lib.mkDefault (import ../hw { inherit inputs; });
|
config.athenix.hwTypes = lib.mkDefault (import ../hw { inherit inputs; });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,6 @@
|
|||||||
# and Home Manager configuration.
|
# and Home Manager configuration.
|
||||||
|
|
||||||
let
|
let
|
||||||
# Load users.nix to get account definitions
|
|
||||||
usersData = import ../users.nix { inherit pkgs; };
|
|
||||||
accounts = usersData.athenix.users or { };
|
|
||||||
|
|
||||||
# Helper: Resolve external module path from fetchGit/fetchTarball/path
|
# Helper: Resolve external module path from fetchGit/fetchTarball/path
|
||||||
resolveExternalPath =
|
resolveExternalPath =
|
||||||
external:
|
external:
|
||||||
@@ -34,149 +30,9 @@ let
|
|||||||
path != null
|
path != null
|
||||||
&& (builtins.isPath path || (builtins.isString path && lib.hasPrefix "/" path))
|
&& (builtins.isPath path || (builtins.isString path && lib.hasPrefix "/" path))
|
||||||
&& builtins.pathExists path;
|
&& builtins.pathExists path;
|
||||||
|
|
||||||
# Extract athenix.users options from external user.nix modules
|
|
||||||
# First, build a cache of options per user from their external user.nix (if any).
|
|
||||||
externalUserModuleOptions = lib.genAttrs (lib.attrNames accounts) (
|
|
||||||
name:
|
|
||||||
let
|
|
||||||
user = accounts.${name};
|
|
||||||
externalPath = resolveExternalPath (user.external or null);
|
|
||||||
userNixPath = if externalPath != null then externalPath + "/user.nix" else null;
|
|
||||||
in
|
|
||||||
if isValidPath userNixPath then
|
|
||||||
let
|
|
||||||
# Import and evaluate the module with minimal args
|
|
||||||
outerModule = import userNixPath { inherit inputs; };
|
|
||||||
evaluatedModule = outerModule {
|
|
||||||
config = { };
|
|
||||||
inherit lib pkgs;
|
|
||||||
osConfig = null;
|
|
||||||
};
|
|
||||||
# Extract just the athenix.users.<name> options
|
|
||||||
athenixUsers = evaluatedModule.athenix.users or { };
|
|
||||||
in
|
|
||||||
athenixUsers.${name} or { }
|
|
||||||
else
|
|
||||||
{ }
|
|
||||||
);
|
|
||||||
|
|
||||||
# externalUserOptions only contains users that actually have options defined
|
|
||||||
externalUserOptions = lib.filterAttrs (
|
|
||||||
_: moduleOptions: moduleOptions != { }
|
|
||||||
) externalUserModuleOptions;
|
|
||||||
|
|
||||||
# Submodule defining the structure of a user account
|
|
||||||
userSubmodule = lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
isNormalUser = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
description = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
extraGroups = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
hashedPassword = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "!";
|
|
||||||
};
|
|
||||||
extraPackages = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.package;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
excludePackages = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.package;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
homePackages = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.package;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
extraImports = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.path;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
external = lib.mkOption {
|
|
||||||
type = lib.types.nullOr (
|
|
||||||
lib.types.oneOf [
|
|
||||||
lib.types.path
|
|
||||||
lib.types.package
|
|
||||||
lib.types.attrs
|
|
||||||
]
|
|
||||||
);
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
External user configuration module. Can be:
|
|
||||||
- A path to a local module directory
|
|
||||||
- A fetchGit/fetchTarball result pointing to a repository
|
|
||||||
|
|
||||||
The external module can contain:
|
|
||||||
- user.nix (optional): Sets athenix.users.<name> options AND home-manager config
|
|
||||||
- nixos.nix (optional): System-level NixOS configuration
|
|
||||||
|
|
||||||
Example: builtins.fetchGit { url = "https://github.com/user/dotfiles"; rev = "..."; }
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
opensshKeys = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = "List of SSH public keys for the user.";
|
|
||||||
};
|
|
||||||
shell = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.package;
|
|
||||||
default = null;
|
|
||||||
description = "The shell for this user.";
|
|
||||||
};
|
|
||||||
editor = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.package;
|
|
||||||
default = null;
|
|
||||||
description = "The default editor for this user.";
|
|
||||||
};
|
|
||||||
useZshTheme = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Whether to apply the system Zsh theme.";
|
|
||||||
};
|
|
||||||
useNvimPlugins = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Whether to apply the system Neovim configuration.";
|
|
||||||
};
|
|
||||||
enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Whether this user account is enabled on this system.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
||||||
options.athenix.users = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf userSubmodule;
|
|
||||||
default = { };
|
|
||||||
description = "User accounts configuration. Set enable=true for users that should exist on this system.";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
# Merge user definitions from users.nix with options from external user.nix modules
|
|
||||||
# External options take precedence over users.nix (which uses lib.mkDefault)
|
|
||||||
athenix.users = lib.mapAttrs (
|
|
||||||
name: user:
|
|
||||||
user
|
|
||||||
// {
|
|
||||||
description = lib.mkDefault (user.description or null);
|
|
||||||
shell = lib.mkDefault (user.shell or null);
|
|
||||||
extraGroups = lib.mkDefault (user.extraGroups or [ ]);
|
|
||||||
}
|
|
||||||
// (externalUserOptions.${name} or { })
|
|
||||||
) accounts;
|
|
||||||
|
|
||||||
# Generate NixOS users
|
# Generate NixOS users
|
||||||
users.users =
|
users.users =
|
||||||
let
|
let
|
||||||
@@ -188,16 +44,31 @@ in
|
|||||||
isPlasma6 = config.services.desktopManager.plasma6.enable;
|
isPlasma6 = config.services.desktopManager.plasma6.enable;
|
||||||
defaultPackages = lib.optionals (isPlasma6 && name != "root") [ pkgs.kdePackages.kate ];
|
defaultPackages = lib.optionals (isPlasma6 && name != "root") [ pkgs.kdePackages.kate ];
|
||||||
finalPackages = lib.subtractLists user.excludePackages (defaultPackages ++ user.extraPackages);
|
finalPackages = lib.subtractLists user.excludePackages (defaultPackages ++ user.extraPackages);
|
||||||
|
shells = {
|
||||||
|
bash = pkgs.bash;
|
||||||
|
zsh = pkgs.zsh;
|
||||||
|
fish = pkgs.fish;
|
||||||
|
tcsh = pkgs.tcsh;
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
rec {
|
||||||
inherit (user) isNormalUser extraGroups hashedPassword;
|
inherit (user) isNormalUser extraGroups hashedPassword;
|
||||||
description = if user.description != null then user.description else lib.mkDefault "";
|
description = if user.description != null then user.description else lib.mkDefault "";
|
||||||
openssh.authorizedKeys.keys = user.opensshKeys;
|
openssh.authorizedKeys.keys = user.opensshKeys;
|
||||||
packages = finalPackages;
|
shell = if user.shell != null then shells.${user.shell} else pkgs.bash;
|
||||||
shell = if user.shell != null then user.shell else pkgs.bash;
|
packages = finalPackages ++ [ shell ];
|
||||||
|
group = if user.isNormalUser then name else lib.mkDefault "root";
|
||||||
}
|
}
|
||||||
) enabledAccounts;
|
) enabledAccounts;
|
||||||
|
|
||||||
|
# Generate user groups for normal users
|
||||||
|
users.groups =
|
||||||
|
let
|
||||||
|
enabledAccounts = lib.filterAttrs (_: user: user.enable) config.athenix.users;
|
||||||
|
normalUsers = lib.filterAttrs (_: user: user.isNormalUser) enabledAccounts;
|
||||||
|
in
|
||||||
|
lib.mapAttrs (_: _: { }) normalUsers;
|
||||||
|
|
||||||
# Home Manager configs per user
|
# Home Manager configs per user
|
||||||
home-manager = {
|
home-manager = {
|
||||||
useGlobalPkgs = true;
|
useGlobalPkgs = true;
|
||||||
@@ -264,6 +135,10 @@ in
|
|||||||
home.username = name;
|
home.username = name;
|
||||||
home.homeDirectory = if name == "root" then "/root" else "/home/${name}";
|
home.homeDirectory = if name == "root" then "/root" else "/home/${name}";
|
||||||
home.stateVersion = "25.11";
|
home.stateVersion = "25.11";
|
||||||
|
programs.${user.editor} = {
|
||||||
|
enable = true;
|
||||||
|
defaultEditor = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
(lib.mkIf (!hasExternal) {
|
(lib.mkIf (!hasExternal) {
|
||||||
# For local users only, add their packages
|
# For local users only, add their packages
|
||||||
|
|||||||
144
inventory.nix
144
inventory.nix
@@ -70,85 +70,89 @@
|
|||||||
# rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014";
|
# rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014";
|
||||||
# };
|
# };
|
||||||
# };
|
# };
|
||||||
|
{ ... }:
|
||||||
{
|
{
|
||||||
# ========== Lab Laptops ==========
|
athenix.fleet = {
|
||||||
# Creates: nix-laptop1, nix-laptop2
|
# ========== Lab Laptops ==========
|
||||||
# Both get hdh20267 user via overrides
|
# Creates: nix-laptop1, nix-laptop2
|
||||||
nix-laptop = {
|
# Both get hdh20267 user via overrides
|
||||||
devices = 2;
|
nix-laptop = {
|
||||||
overrides.athenix.users.hdh20267.enable = true;
|
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";
|
|
||||||
};
|
};
|
||||||
overrides = {
|
|
||||||
athenix.sw.kioskUrl = "https://yahoo.com";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# ========== LXC Containers ==========
|
# ========== Desktop ==========
|
||||||
# Creates: nix-builder (without lxc prefix)
|
# Creates: nix-desktop1
|
||||||
nix-lxc = {
|
nix-desktop = {
|
||||||
devices = {
|
devices = 1;
|
||||||
"nix-builder" = {
|
};
|
||||||
# Gitea Actions self-hosted runner configuration
|
|
||||||
athenix.sw = {
|
# ========== Surface Tablets (Kiosk Mode) ==========
|
||||||
type = [
|
# Creates: nix-surface1 (custom), nix-surface2, nix-surface3 (via defaultCount)
|
||||||
"headless"
|
nix-surface = {
|
||||||
"builders"
|
defaultCount = 3;
|
||||||
];
|
devices = {
|
||||||
builders.giteaRunner = {
|
"1".athenix.sw.kioskUrl = "https://google.com";
|
||||||
enable = true;
|
};
|
||||||
url = "https://git.factory.uga.edu";
|
overrides = {
|
||||||
# Token file must be created manually at this path with a Gitea runner token
|
athenix.sw.kioskUrl = "https://yahoo.com";
|
||||||
# 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
|
# ========== LXC Containers ==========
|
||||||
extraLabels = [
|
# Creates: nix-builder (without lxc prefix)
|
||||||
"self-hosted"
|
nix-lxc = {
|
||||||
"nix-builder"
|
devices = {
|
||||||
|
"nix-builder" = {
|
||||||
|
# Gitea Actions self-hosted runner configuration
|
||||||
|
athenix.sw = {
|
||||||
|
type = [
|
||||||
|
"headless"
|
||||||
|
"builders"
|
||||||
];
|
];
|
||||||
# Runner service name
|
builders.giteaRunner = {
|
||||||
name = "athenix";
|
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".athenix.users.engr-ugaif.enable = true;
|
||||||
};
|
};
|
||||||
"usda-dash".external = builtins.fetchGit {
|
overrides = {
|
||||||
url = "https://git.factory.uga.edu/MODEL/usda-dash-config.git";
|
athenix.host.useHostPrefix = false;
|
||||||
rev = "dab32f5884895cead0fae28cb7d88d17951d0c12";
|
|
||||||
submodules = true;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
# Usage: nixosConfigurations = athenix.lib.mkFleet { fleet = { ... }; hwTypes = { ... }; }
|
# Usage: nixosConfigurations = athenix.lib.mkFleet { fleet = { ... }; hwTypes = { ... }; }
|
||||||
{
|
{
|
||||||
inputs,
|
inputs,
|
||||||
fleet ? null,
|
lib,
|
||||||
hwTypes ? null,
|
config,
|
||||||
}:
|
}:
|
||||||
import ../fleet/default.nix {
|
import ../fleet/default.nix {
|
||||||
inherit inputs;
|
inherit inputs lib config;
|
||||||
inherit fleet hwTypes;
|
|
||||||
}
|
}
|
||||||
|
|||||||
9
parts/formatter.nix
Normal file
9
parts/formatter.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Formatter configuration for flake-parts
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
formatter = pkgs.nixfmt-rfc-style;
|
||||||
|
};
|
||||||
|
}
|
||||||
5
parts/lib.nix
Normal file
5
parts/lib.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Library functions for flake-parts
|
||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
flake.lib = import ../lib { inherit inputs; };
|
||||||
|
}
|
||||||
20
parts/nixos-configurations.nix
Normal file
20
parts/nixos-configurations.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# NixOS configurations generated from fleet
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
self,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
../fleet/fleet-option.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
flake.nixosConfigurations =
|
||||||
|
let
|
||||||
|
fleet = self.lib.mkFleet { inherit inputs lib config; };
|
||||||
|
in
|
||||||
|
fleet.nixosConfigurations;
|
||||||
|
}
|
||||||
5
parts/nixos-modules.nix
Normal file
5
parts/nixos-modules.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Expose host type modules and installer modules for external use
|
||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
flake.nixosModules = import ../installer/modules.nix { inherit inputs; };
|
||||||
|
}
|
||||||
27
parts/packages.nix
Normal file
27
parts/packages.nix
Normal file
@@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
5
parts/templates.nix
Normal file
5
parts/templates.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Templates for external configurations
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
flake.templates = import ../templates;
|
||||||
|
}
|
||||||
7
parts/users.nix
Normal file
7
parts/users.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Flake-parts wrapper for users.nix
|
||||||
|
{ inputs, ... }:
|
||||||
|
let
|
||||||
|
# Minimal pkgs just for shell paths - will be overridden in actual NixOS configs
|
||||||
|
pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
|
||||||
|
in
|
||||||
|
import ../users.nix { inherit pkgs; }
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# User Definitions
|
# User Definitions
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
hdh20267 = {
|
hdh20267 = {
|
||||||
external = builtins.fetchGit {
|
external = builtins.fetchGit {
|
||||||
url = "https://git.factory.uga.edu/hdh20267/hdh20267-nix";
|
url = "https://git.factory.uga.edu/hdh20267/hdh20267-nix";
|
||||||
rev = "c538e0c0510045b58264627bb897fc499dc7c490";
|
rev = "dbdf65c7bd59e646719f724a3acd2330e0c922ec";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
sv22900 = {
|
sv22900 = {
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
"networkmanager"
|
"networkmanager"
|
||||||
"wheel"
|
"wheel"
|
||||||
];
|
];
|
||||||
shell = pkgs.zsh;
|
shell = "zsh";
|
||||||
# enable = false by default, set to true per-system
|
# enable = false by default, set to true per-system
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user