feat: Refactor to use flake-parts and import inventory and users thru the flake parts
This commit is contained in:
@@ -76,11 +76,12 @@
|
||||
imports = [
|
||||
./parts/formatter.nix
|
||||
./parts/lib.nix
|
||||
./parts/fleet-option.nix
|
||||
./parts/nixos-configurations.nix
|
||||
./parts/nixos-modules.nix
|
||||
./parts/packages.nix
|
||||
./parts/templates.nix
|
||||
./inventory.nix
|
||||
./users.nix
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,12 +12,11 @@
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
(import ./fleet-data.nix { inherit inputs lib; })
|
||||
./fs.nix
|
||||
./boot.nix
|
||||
./user-config.nix
|
||||
./fleet-option.nix
|
||||
../sw
|
||||
../users.nix
|
||||
];
|
||||
|
||||
options.athenix = {
|
||||
|
||||
@@ -17,7 +17,7 @@ let
|
||||
# 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
|
||||
|
||||
|
||||
hostTypes = config.athenix.hwTypes;
|
||||
|
||||
# Helper to create a single NixOS system configuration
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# ============================================================================
|
||||
# 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;
|
||||
}
|
||||
@@ -59,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
|
||||
{
|
||||
options.athenix = {
|
||||
@@ -67,6 +170,11 @@ in
|
||||
description = "Hardware types definitions for the fleet.";
|
||||
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.hwTypes = lib.mkDefault (import ../hw { inherit inputs; });
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
# and Home Manager configuration.
|
||||
|
||||
let
|
||||
# Load users.nix to get account definitions
|
||||
accounts = config.athenix.users or { };
|
||||
|
||||
# Helper: Resolve external module path from fetchGit/fetchTarball/path
|
||||
resolveExternalPath =
|
||||
external:
|
||||
@@ -33,149 +30,9 @@ let
|
||||
path != null
|
||||
&& (builtins.isPath path || (builtins.isString path && lib.hasPrefix "/" 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
|
||||
{
|
||||
|
||||
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 = {
|
||||
# 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
|
||||
users.users =
|
||||
let
|
||||
@@ -187,16 +44,31 @@ in
|
||||
isPlasma6 = config.services.desktopManager.plasma6.enable;
|
||||
defaultPackages = lib.optionals (isPlasma6 && name != "root") [ pkgs.kdePackages.kate ];
|
||||
finalPackages = lib.subtractLists user.excludePackages (defaultPackages ++ user.extraPackages);
|
||||
shells = {
|
||||
bash = pkgs.bash;
|
||||
zsh = pkgs.zsh;
|
||||
fish = pkgs.fish;
|
||||
tcsh = pkgs.tcsh;
|
||||
};
|
||||
in
|
||||
{
|
||||
rec {
|
||||
inherit (user) isNormalUser extraGroups hashedPassword;
|
||||
description = if user.description != null then user.description else lib.mkDefault "";
|
||||
openssh.authorizedKeys.keys = user.opensshKeys;
|
||||
packages = finalPackages;
|
||||
shell = if user.shell != null then user.shell else pkgs.bash;
|
||||
shell = if user.shell != null then shells.${user.shell} else pkgs.bash;
|
||||
packages = finalPackages ++ [ shell ];
|
||||
group = if user.isNormalUser then name else lib.mkDefault "root";
|
||||
}
|
||||
) 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 = {
|
||||
useGlobalPkgs = true;
|
||||
@@ -263,6 +135,10 @@ in
|
||||
home.username = name;
|
||||
home.homeDirectory = if name == "root" then "/root" else "/home/${name}";
|
||||
home.stateVersion = "25.11";
|
||||
programs.${user.editor} = {
|
||||
enable = true;
|
||||
defaultEditor = true;
|
||||
};
|
||||
}
|
||||
(lib.mkIf (!hasExternal) {
|
||||
# For local users only, add their packages
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
rev = "dab32f5884895cead0fae28cb7d88d17951d0c12";
|
||||
submodules = true;
|
||||
};
|
||||
"usda-dash".athenix.users.engr-ugaif.enable = true;
|
||||
};
|
||||
overrides = {
|
||||
athenix.host.useHostPrefix = false;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
config
|
||||
config,
|
||||
}:
|
||||
import ../fleet/default.nix {
|
||||
inherit inputs lib config;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# Flake-parts wrapper for fleet-option.nix
|
||||
{ inputs, self, lib, config, ... }:
|
||||
let
|
||||
fleetModule = import ../fleet/fleet-option.nix { inherit inputs lib; };
|
||||
inventoryModule = import ../inventory.nix { };
|
||||
in
|
||||
{
|
||||
imports = [ fleetModule inventoryModule ];
|
||||
}
|
||||
@@ -1,6 +1,17 @@
|
||||
# NixOS configurations generated from fleet
|
||||
{ inputs, self, lib, config, ... }:
|
||||
{
|
||||
inputs,
|
||||
self,
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
../fleet/fleet-option.nix
|
||||
];
|
||||
|
||||
flake.nixosConfigurations =
|
||||
let
|
||||
fleet = self.lib.mkFleet { inherit inputs lib config; };
|
||||
|
||||
16
users.nix
16
users.nix
@@ -1,4 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{ ... }:
|
||||
{
|
||||
# ============================================================================
|
||||
# User Definitions
|
||||
@@ -46,19 +46,19 @@
|
||||
];
|
||||
enable = true; # Default user, enabled everywhere
|
||||
};
|
||||
hdh20267 = {
|
||||
external = builtins.fetchGit {
|
||||
url = "https://git.factory.uga.edu/hdh20267/hdh20267-nix";
|
||||
rev = "c538e0c0510045b58264627bb897fc499dc7c490";
|
||||
};
|
||||
};
|
||||
#hdh20267 = {
|
||||
# external = builtins.fetchGit {
|
||||
# url = "https://git.factory.uga.edu/hdh20267/hdh20267-nix";
|
||||
# rev = "c538e0c0510045b58264627bb897fc499dc7c490";
|
||||
# };
|
||||
#};
|
||||
sv22900 = {
|
||||
description = "Alireza Vaezi";
|
||||
extraGroups = [
|
||||
"networkmanager"
|
||||
"wheel"
|
||||
];
|
||||
shell = pkgs.zsh;
|
||||
shell = "zsh";
|
||||
# enable = false by default, set to true per-system
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user