Merge branch 'options-refactor' to ensure options are defined where they are used, standardize the module input of 'variants' (formerly 'hosts'), and add a 'glue' directory for piecing together the final flake outputs #26
5
.github/copilot-instructions.md
vendored
5
.github/copilot-instructions.md
vendored
@@ -26,8 +26,9 @@ This is a **NixOS system configuration repository** that uses:
|
|||||||
- **`flake.nix`**: Entry point - inputs and outputs only
|
- **`flake.nix`**: Entry point - inputs and outputs only
|
||||||
- **`inventory.nix`**: Fleet definitions - host configurations
|
- **`inventory.nix`**: Fleet definitions - host configurations
|
||||||
- **`users.nix`**: User account definitions
|
- **`users.nix`**: User account definitions
|
||||||
- **`hosts/`**: Host generation logic and hardware types
|
- **`variants/`**: Hardware type modules (desktop, laptop, surface, lxc, wsl, etc.)
|
||||||
- **`sw/`**: Software configurations organized by system type
|
- **`glue/`**: Fleet generation logic and common system configuration
|
||||||
|
- **`sw/`**: Software configurations by system type
|
||||||
- **`installer/`**: Build artifact generation (ISO, LXC, etc.)
|
- **`installer/`**: Build artifact generation (ISO, LXC, etc.)
|
||||||
- **`templates/`**: Templates for external configurations
|
- **`templates/`**: Templates for external configurations
|
||||||
|
|
||||||
|
|||||||
25
README.md
25
README.md
@@ -54,18 +54,21 @@ users.nix # User account definitions
|
|||||||
|
|
||||||
flake.lock # Locked dependency versions
|
flake.lock # Locked dependency versions
|
||||||
|
|
||||||
hosts/ # Host generation logic
|
variants/ # Hardware type modules (exportable as nixosModules)
|
||||||
├── default.nix # Main host generator
|
├── default.nix # Auto-exports all variant types
|
||||||
|
├── nix-desktop.nix # Desktop workstations
|
||||||
|
├── nix-laptop.nix # Laptop systems
|
||||||
|
├── nix-surface.nix # Surface Pro tablets
|
||||||
|
├── nix-lxc.nix # LXC containers
|
||||||
|
├── nix-wsl.nix # WSL instances
|
||||||
|
├── nix-zima.nix # ZimaBoard systems
|
||||||
|
└── nix-ephemeral.nix # Diskless/netboot systems
|
||||||
|
|
||||||
|
glue/ # Fleet generation and common configuration
|
||||||
|
├── fleet.nix # Processes inventory.nix to generate all hosts
|
||||||
|
├── common.nix # Common NixOS configuration (all hosts)
|
||||||
├── boot.nix # Boot and filesystem configuration
|
├── boot.nix # Boot and filesystem configuration
|
||||||
├── common.nix # Common system configuration
|
└── user-config.nix # User account and home-manager integration
|
||||||
├── user-config.nix # User configuration integration
|
|
||||||
└── types/ # Hardware type modules
|
|
||||||
├── nix-desktop.nix
|
|
||||||
├── nix-laptop.nix
|
|
||||||
├── nix-surface.nix
|
|
||||||
├── nix-lxc.nix
|
|
||||||
├── nix-wsl.nix
|
|
||||||
└── nix-ephemeral.nix
|
|
||||||
|
|
||||||
sw/ # Software configurations by system type
|
sw/ # Software configurations by system type
|
||||||
├── default.nix # Software module entry point
|
├── default.nix # Software module entry point
|
||||||
|
|||||||
Submodule assets/plymouth-theme deleted from 8658f4fb40
@@ -87,7 +87,7 @@ athenix.users.newuser = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Enable on hosts in `inventory.nix`:
|
2. Enable on fleet in `inventory.nix`:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
nix-laptop = {
|
nix-laptop = {
|
||||||
@@ -294,7 +294,7 @@ For system config:
|
|||||||
```nix
|
```nix
|
||||||
# inventory.nix
|
# inventory.nix
|
||||||
nix-lxc = {
|
nix-lxc = {
|
||||||
devices."server" = builtins.fetchGit {
|
devices."server".external = builtins.fetchGit {
|
||||||
url = "https://git.factory.uga.edu/org/server-config";
|
url = "https://git.factory.uga.edu/org/server-config";
|
||||||
rev = "abc123...";
|
rev = "abc123...";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,26 +28,42 @@ External system modules provide host-specific NixOS configurations.
|
|||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
In `inventory.nix`, reference an external module as a device:
|
In `inventory.nix`, reference an external module using the `external` field:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
nix-lxc = {
|
nix-lxc = {
|
||||||
devices = {
|
devices = {
|
||||||
# Inline configuration
|
# Inline configuration (traditional method)
|
||||||
"local-server" = {
|
"local-server" = {
|
||||||
athenix.sw.type = "headless";
|
athenix.sw.type = "headless";
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# External module
|
# External module (lazy evaluation - fetched only when building this host)
|
||||||
"remote-server" = builtins.fetchGit {
|
"remote-server".external = builtins.fetchGit {
|
||||||
url = "https://git.factory.uga.edu/org/server-config";
|
url = "https://git.factory.uga.edu/org/server-config";
|
||||||
rev = "abc123def456..."; # Must pin to specific commit
|
rev = "abc123def456..."; # Must pin to specific commit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# External module with additional local config
|
||||||
|
"mixed-server" = {
|
||||||
|
external = builtins.fetchGit {
|
||||||
|
url = "https://git.factory.uga.edu/org/server-config";
|
||||||
|
rev = "abc123def456...";
|
||||||
|
};
|
||||||
|
# Additional local overrides
|
||||||
|
athenix.users.admin.enable = true;
|
||||||
|
services.openssh.permitRootLogin = "no";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- **Lazy Evaluation**: External modules are only fetched when building the specific host
|
||||||
|
- **Efficient Rebuilds**: Other hosts can be rebuilt without fetching unrelated external modules
|
||||||
|
- **Submodule Support**: Works with Git submodules without affecting other hosts
|
||||||
|
|
||||||
### Repository Structure
|
### Repository Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -99,8 +115,8 @@ server-config/
|
|||||||
|
|
||||||
When a host is built, modules load in this order:
|
When a host is built, modules load in this order:
|
||||||
|
|
||||||
1. Hardware type module (from `hosts/types/nix-*.nix`)
|
1. Hardware type module (from `variants/nix-*.nix`)
|
||||||
2. Host common configuration (from `hosts/common.nix`)
|
2. Common system configuration (from `glue/common.nix`)
|
||||||
3. Software type module (from `sw/{type}/`)
|
3. Software type module (from `sw/{type}/`)
|
||||||
4. User NixOS modules (from `users.nix` - `nixos.nix` files)
|
4. User NixOS modules (from `users.nix` - `nixos.nix` files)
|
||||||
5. Device-specific overrides (from `inventory.nix`)
|
5. Device-specific overrides (from `inventory.nix`)
|
||||||
|
|||||||
@@ -123,11 +123,11 @@ nix-surface = {
|
|||||||
|
|
||||||
### Method 4: External Module
|
### Method 4: External Module
|
||||||
|
|
||||||
Reference a Git repository instead of inline configuration:
|
Reference a Git repository using the `external` field (lazy evaluation):
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
nix-lxc = {
|
nix-lxc = {
|
||||||
devices."builder" = builtins.fetchGit {
|
devices."builder".external = builtins.fetchGit {
|
||||||
url = "https://git.factory.uga.edu/org/builder-config";
|
url = "https://git.factory.uga.edu/org/builder-config";
|
||||||
rev = "abc123...";
|
rev = "abc123...";
|
||||||
};
|
};
|
||||||
|
|||||||
10
flake.nix
10
flake.nix
@@ -69,10 +69,10 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
hosts = import ./hosts { inherit inputs; };
|
fleet = import ./glue/fleet.nix { inherit inputs; };
|
||||||
linuxSystem = "x86_64-linux";
|
linuxSystem = "x86_64-linux";
|
||||||
artifacts = import ./installer/artifacts.nix {
|
artifacts = import ./installer/artifacts.nix {
|
||||||
inherit inputs hosts self;
|
inherit inputs fleet self;
|
||||||
system = linuxSystem;
|
system = linuxSystem;
|
||||||
};
|
};
|
||||||
forAllSystems = nixpkgs.lib.genAttrs [
|
forAllSystems = nixpkgs.lib.genAttrs [
|
||||||
@@ -86,13 +86,13 @@
|
|||||||
# Formatter for 'nix fmt'
|
# Formatter for 'nix fmt'
|
||||||
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style);
|
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style);
|
||||||
|
|
||||||
# Generate NixOS configurations from hosts/default.nix
|
# Generate NixOS configurations from fleet generator
|
||||||
nixosConfigurations = hosts.nixosConfigurations;
|
nixosConfigurations = fleet.nixosConfigurations;
|
||||||
|
|
||||||
# Expose artifacts to all systems, but they are always built for x86_64-linux
|
# Expose artifacts to all systems, but they are always built for x86_64-linux
|
||||||
packages = forAllSystems (_: artifacts);
|
packages = forAllSystems (_: artifacts);
|
||||||
|
|
||||||
# Expose modules for external use
|
# Expose host type modules and installer modules for external use
|
||||||
nixosModules = import ./installer/modules.nix { inherit inputs; };
|
nixosModules = import ./installer/modules.nix { inherit inputs; };
|
||||||
|
|
||||||
# Templates for external configurations
|
# Templates for external configurations
|
||||||
|
|||||||
137
glue/boot.nix
Normal file
137
glue/boot.nix
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# Boot & Storage Configuration
|
||||||
|
# ============================================================================
|
||||||
|
# This module defines:
|
||||||
|
# - Disko partition layout (EFI, swap, root)
|
||||||
|
# - Bootloader configuration (systemd-boot with Plymouth)
|
||||||
|
# - Filesystem options (device, swap size)
|
||||||
|
# - Build method options (used by installer/artifacts.nix)
|
||||||
|
# - Convenience options (forUser, useHostPrefix)
|
||||||
|
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
options.athenix = {
|
||||||
|
host = {
|
||||||
|
useHostPrefix = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to prepend the host prefix to the hostname (used in inventory and hosts/default.nix).";
|
||||||
|
};
|
||||||
|
filesystem = {
|
||||||
|
device = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The main disk device to use for installation.";
|
||||||
|
};
|
||||||
|
useSwap = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to create and use a swap partition.";
|
||||||
|
};
|
||||||
|
swapSize = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The size of the swap partition.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# ========== Disk Partitioning (Disko) ==========
|
||||||
|
disko.enableConfig = lib.mkDefault true;
|
||||||
|
|
||||||
|
disko.devices = {
|
||||||
|
disk.main = {
|
||||||
|
type = "disk";
|
||||||
|
device = config.athenix.host.filesystem.device;
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
# EFI System Partition
|
||||||
|
ESP = {
|
||||||
|
name = "ESP";
|
||||||
|
label = "BOOT";
|
||||||
|
size = "1G";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
mountOptions = [ "umask=0077" ];
|
||||||
|
extraArgs = [
|
||||||
|
"-n"
|
||||||
|
"BOOT"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Swap Partition (size configurable per host)
|
||||||
|
swap = lib.mkIf config.athenix.host.filesystem.useSwap {
|
||||||
|
name = "swap";
|
||||||
|
label = "swap";
|
||||||
|
size = config.athenix.host.filesystem.swapSize;
|
||||||
|
content = {
|
||||||
|
type = "swap";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Root Partition (takes remaining space)
|
||||||
|
root = {
|
||||||
|
name = "root";
|
||||||
|
label = "root";
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "ext4";
|
||||||
|
mountpoint = "/";
|
||||||
|
extraArgs = [
|
||||||
|
"-L"
|
||||||
|
"ROOT"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Bootloader Configuration
|
||||||
|
boot = {
|
||||||
|
loader.systemd-boot.enable = true;
|
||||||
|
loader.efi.canTouchEfiVariables = true;
|
||||||
|
plymouth.enable = true;
|
||||||
|
|
||||||
|
# Enable "Silent boot"
|
||||||
|
consoleLogLevel = 3;
|
||||||
|
initrd.verbose = false;
|
||||||
|
|
||||||
|
# Hide the OS choice for bootloaders.
|
||||||
|
# It's still possible to open the bootloader list by pressing any key
|
||||||
|
# It will just not appear on screen unless a key is pressed
|
||||||
|
loader.timeout = lib.mkDefault 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Set your time zone.
|
||||||
|
time.timeZone = "America/New_York";
|
||||||
|
|
||||||
|
# Select internationalisation properties.
|
||||||
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|
||||||
|
i18n.extraLocaleSettings = {
|
||||||
|
LC_ADDRESS = "en_US.UTF-8";
|
||||||
|
LC_IDENTIFICATION = "en_US.UTF-8";
|
||||||
|
LC_MEASUREMENT = "en_US.UTF-8";
|
||||||
|
LC_MONETARY = "en_US.UTF-8";
|
||||||
|
LC_NAME = "en_US.UTF-8";
|
||||||
|
LC_NUMERIC = "en_US.UTF-8";
|
||||||
|
LC_PAPER = "en_US.UTF-8";
|
||||||
|
LC_TELEPHONE = "en_US.UTF-8";
|
||||||
|
LC_TIME = "en_US.UTF-8";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.sleep.extraConfig = ''
|
||||||
|
SuspendState=freeze
|
||||||
|
HibernateDelaySec=2h
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
99
glue/common.nix
Normal file
99
glue/common.nix
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# Common Host Module
|
||||||
|
# ============================================================================
|
||||||
|
# This module contains all the common configuration shared by all host types.
|
||||||
|
# It is automatically imported by the fleet generator for every host.
|
||||||
|
|
||||||
|
{ inputs }:
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./boot.nix
|
||||||
|
./user-config.nix
|
||||||
|
../sw
|
||||||
|
../users.nix
|
||||||
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
inputs.agenix.nixosModules.default
|
||||||
|
inputs.disko.nixosModules.disko
|
||||||
|
];
|
||||||
|
|
||||||
|
# Define garbage collection options here since they're consumed in this module
|
||||||
|
options.athenix = {
|
||||||
|
forUser = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Convenience option to configure a host for a specific user.
|
||||||
|
Automatically enables the user (sets athenix.users.username.enable = true).
|
||||||
|
Value should be a username from athenix.users.accounts.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.gc = {
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to enable automatic garbage collection.";
|
||||||
|
};
|
||||||
|
frequency = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "weekly";
|
||||||
|
description = "How often to run garbage collection (systemd timer format).";
|
||||||
|
};
|
||||||
|
retentionDays = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 30;
|
||||||
|
description = "Number of days to keep old generations before deletion.";
|
||||||
|
};
|
||||||
|
optimise = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to automatically optimize the Nix store.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
host.buildMethods = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ "installer-iso" ];
|
||||||
|
description = ''
|
||||||
|
List of allowed build methods for this host (used by installer/artifacts.nix).
|
||||||
|
Supported methods:
|
||||||
|
- "installer-iso": Generates an auto-install ISO that installs this configuration to disk.
|
||||||
|
- "iso": Generates a live ISO (using nixos-generators).
|
||||||
|
- "ipxe": Generates iPXE netboot artifacts (kernel, initrd, script).
|
||||||
|
- "lxc": Generates an LXC container tarball.
|
||||||
|
- "proxmox": Generates a Proxmox VMA archive.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
|
# Enable forUser if specified
|
||||||
|
(lib.mkIf (config.athenix.forUser != null) {
|
||||||
|
athenix.users.${config.athenix.forUser}.enable = true;
|
||||||
|
})
|
||||||
|
|
||||||
|
{
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
|
||||||
|
nix.settings.experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Automatic Garbage Collection
|
||||||
|
nix.gc = lib.mkIf config.athenix.system.gc.enable {
|
||||||
|
automatic = true;
|
||||||
|
dates = config.athenix.system.gc.frequency;
|
||||||
|
options = "--delete-older-than ${toString config.athenix.system.gc.retentionDays}d";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optimize storage
|
||||||
|
nix.optimise.automatic = config.athenix.system.gc.optimise;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -1,36 +1,23 @@
|
|||||||
{
|
{
|
||||||
inputs,
|
inputs,
|
||||||
hosts ? import ../inventory.nix,
|
fleet ? import ../inventory.nix,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Host Generator
|
# Fleet Generator
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# This file contains the logic to generate NixOS configurations for all hosts
|
# This file contains the logic to generate NixOS configurations for all hosts
|
||||||
# defined in inventory.nix. It supports both hostname-based and count-based
|
# defined in inventory.nix. It supports both hostname-based and count-based
|
||||||
# configurations with flexible type associations.
|
# configurations with flexible type associations.
|
||||||
#
|
|
||||||
# Inventory format:
|
|
||||||
# {
|
|
||||||
# "my-hostname" = {
|
|
||||||
# type = "nix-desktop"; # Host type module to use
|
|
||||||
# system = "x86_64-linux"; # Optional
|
|
||||||
# # ... any athenix.* options or device-specific config
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# "lab-prefix" = {
|
|
||||||
# type = "nix-laptop";
|
|
||||||
# count = 5; # Generates lab-prefix1, lab-prefix2, ... lab-prefix5
|
|
||||||
# devices = {
|
|
||||||
# "machine-1" = { ... }; # Override for lab-prefix1
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# }
|
|
||||||
|
|
||||||
let
|
let
|
||||||
nixpkgs = inputs.nixpkgs;
|
nixpkgs = inputs.nixpkgs;
|
||||||
lib = nixpkgs.lib;
|
lib = nixpkgs.lib;
|
||||||
|
|
||||||
|
# Load all available host types from hosts/
|
||||||
|
hostTypes = import ../variants { inherit inputs; };
|
||||||
|
|
||||||
# Helper to create a single NixOS system configuration
|
# Helper to create a single NixOS system configuration
|
||||||
mkHost =
|
mkHost =
|
||||||
{
|
{
|
||||||
@@ -38,9 +25,28 @@ let
|
|||||||
system ? "x86_64-linux",
|
system ? "x86_64-linux",
|
||||||
hostType,
|
hostType,
|
||||||
configOverrides ? { },
|
configOverrides ? { },
|
||||||
externalModulePath ? null,
|
externalModuleThunk ? null,
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
# Lazy evaluation: only fetch external module when building this host
|
||||||
|
externalModulePath =
|
||||||
|
if externalModuleThunk != null then
|
||||||
|
let
|
||||||
|
# Force evaluation of the thunk (fetchGit, fetchTarball, etc.)
|
||||||
|
fetchedPath = externalModuleThunk;
|
||||||
|
# Extract outPath from fetchGit/fetchTarball results
|
||||||
|
extractedPath =
|
||||||
|
if builtins.isAttrs fetchedPath && fetchedPath ? outPath then fetchedPath.outPath else fetchedPath;
|
||||||
|
in
|
||||||
|
if builtins.isPath extractedPath then
|
||||||
|
extractedPath + "/default.nix"
|
||||||
|
else if lib.isDerivation extractedPath then
|
||||||
|
extractedPath + "/default.nix"
|
||||||
|
else
|
||||||
|
extractedPath + "/default.nix"
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
|
||||||
# Load users.nix to find external user modules
|
# Load users.nix to find external user modules
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
usersData = import ../users.nix { inherit pkgs; };
|
usersData = import ../users.nix { inherit pkgs; };
|
||||||
@@ -94,13 +100,10 @@ let
|
|||||||
}
|
}
|
||||||
) userNixosModulePaths;
|
) userNixosModulePaths;
|
||||||
|
|
||||||
# Load the host type module
|
# Get the host type module from the hostTypes attribute set
|
||||||
typeFile = ./types + "/${hostType}.nix";
|
|
||||||
typeModule =
|
typeModule =
|
||||||
if builtins.pathExists typeFile then
|
hostTypes.${hostType}
|
||||||
import typeFile { inherit inputs; }
|
or (throw "Host type '${hostType}' not found. Available types: ${lib.concatStringsSep ", " (lib.attrNames hostTypes)}");
|
||||||
else
|
|
||||||
throw "Host type '${hostType}' not found in hosts/types/";
|
|
||||||
|
|
||||||
# External module from fetchGit/fetchurl
|
# External module from fetchGit/fetchurl
|
||||||
externalPathModule =
|
externalPathModule =
|
||||||
@@ -132,6 +135,7 @@ let
|
|||||||
allModules =
|
allModules =
|
||||||
userNixosModules
|
userNixosModules
|
||||||
++ [
|
++ [
|
||||||
|
(import ./common.nix { inherit inputs; })
|
||||||
typeModule
|
typeModule
|
||||||
overrideModule
|
overrideModule
|
||||||
{ networking.hostName = hostName; }
|
{ networking.hostName = hostName; }
|
||||||
@@ -192,48 +196,22 @@ let
|
|||||||
lib.mapAttrsToList (
|
lib.mapAttrsToList (
|
||||||
deviceKey: deviceConfig:
|
deviceKey: deviceConfig:
|
||||||
let
|
let
|
||||||
# Check if deviceConfig is a path/derivation (from fetchGit, fetchurl, etc.)
|
# Check if deviceConfig has an 'external' field for lazy evaluation
|
||||||
# fetchGit/fetchTarball return an attrset with outPath attribute
|
hasExternalField = builtins.isAttrs deviceConfig && deviceConfig ? external;
|
||||||
isExternalModule =
|
|
||||||
(builtins.isPath deviceConfig)
|
|
||||||
|| (builtins.isString deviceConfig && lib.hasPrefix "/" deviceConfig)
|
|
||||||
|| (lib.isDerivation deviceConfig)
|
|
||||||
|| (builtins.isAttrs deviceConfig && deviceConfig ? outPath);
|
|
||||||
|
|
||||||
# Extract the actual path from fetchGit/fetchTarball results
|
# Extract external module thunk if present (don't evaluate yet!)
|
||||||
extractedPath =
|
externalModuleThunk = if hasExternalField then deviceConfig.external else null;
|
||||||
if builtins.isAttrs deviceConfig && deviceConfig ? outPath then
|
|
||||||
deviceConfig.outPath
|
|
||||||
else
|
|
||||||
deviceConfig;
|
|
||||||
|
|
||||||
# If external module, we use base config + overrides as the config
|
# Remove 'external' from config to avoid conflicts
|
||||||
# and pass the module path separately
|
cleanDeviceConfig =
|
||||||
actualConfig =
|
if hasExternalField then lib.removeAttrs deviceConfig [ "external" ] else deviceConfig;
|
||||||
if isExternalModule then (lib.recursiveUpdate baseConfig overrides) else deviceConfig;
|
|
||||||
|
|
||||||
# Merge: base config -> overrides -> device-specific config (only if not external module)
|
# Merge: base config -> overrides -> device-specific config
|
||||||
mergedConfig =
|
mergedConfig = lib.recursiveUpdate (lib.recursiveUpdate baseConfig overrides) cleanDeviceConfig;
|
||||||
if isExternalModule then
|
|
||||||
actualConfig
|
|
||||||
else
|
|
||||||
lib.recursiveUpdate (lib.recursiveUpdate baseConfig overrides) deviceConfig;
|
|
||||||
|
|
||||||
# Check useHostPrefix from the merged config
|
# Check useHostPrefix from the merged config
|
||||||
usePrefix = mergedConfig.athenix.host.useHostPrefix or true;
|
usePrefix = mergedConfig.athenix.host.useHostPrefix or true;
|
||||||
hostName = mkHostName prefix deviceKey usePrefix;
|
hostName = mkHostName prefix deviceKey usePrefix;
|
||||||
|
|
||||||
# If external module, also add a default.nix path for import
|
|
||||||
externalModulePath =
|
|
||||||
if isExternalModule then
|
|
||||||
if builtins.isPath extractedPath then
|
|
||||||
extractedPath + "/default.nix"
|
|
||||||
else if lib.isDerivation extractedPath then
|
|
||||||
extractedPath + "/default.nix"
|
|
||||||
else
|
|
||||||
extractedPath + "/default.nix"
|
|
||||||
else
|
|
||||||
null;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
name = hostName;
|
name = hostName;
|
||||||
@@ -242,7 +220,7 @@ let
|
|||||||
hostName
|
hostName
|
||||||
system
|
system
|
||||||
hostType
|
hostType
|
||||||
externalModulePath
|
externalModuleThunk
|
||||||
;
|
;
|
||||||
configOverrides = mergedConfig;
|
configOverrides = mergedConfig;
|
||||||
};
|
};
|
||||||
@@ -289,7 +267,7 @@ let
|
|||||||
{ };
|
{ };
|
||||||
in
|
in
|
||||||
lib.recursiveUpdate deviceHosts countHosts
|
lib.recursiveUpdate deviceHosts countHosts
|
||||||
) hosts;
|
) fleet;
|
||||||
|
|
||||||
# Flatten the nested structure
|
# Flatten the nested structure
|
||||||
allHosts = lib.foldl' lib.recursiveUpdate { } (lib.attrValues processInventory);
|
allHosts = lib.foldl' lib.recursiveUpdate { } (lib.attrValues processInventory);
|
||||||
194
hosts/boot.nix
194
hosts/boot.nix
@@ -1,194 +0,0 @@
|
|||||||
# ============================================================================
|
|
||||||
# Boot & Storage Configuration
|
|
||||||
# ============================================================================
|
|
||||||
# This module defines:
|
|
||||||
# - Disko partition layout (EFI, swap, root)
|
|
||||||
# - Bootloader configuration (systemd-boot with Plymouth)
|
|
||||||
# - Filesystem options (device, swap size)
|
|
||||||
# - Build method options (ISO, iPXE, LXC, Proxmox)
|
|
||||||
# - Garbage collection settings
|
|
||||||
# - Convenience options (forUser, useHostPrefix)
|
|
||||||
|
|
||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
options.athenix = {
|
|
||||||
forUser = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Convenience option to configure a host for a specific user.
|
|
||||||
Automatically enables the user (sets athenix.users.username.enable = true).
|
|
||||||
Value should be a username from athenix.users.accounts.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
host = {
|
|
||||||
useHostPrefix = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Whether to prepend the host prefix to the hostname (used in inventory).";
|
|
||||||
};
|
|
||||||
filesystem = {
|
|
||||||
device = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = "The main disk device to use for installation.";
|
|
||||||
};
|
|
||||||
useSwap = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Whether to create and use a swap partition.";
|
|
||||||
};
|
|
||||||
swapSize = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = "The size of the swap partition.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
buildMethods = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [ "installer-iso" ];
|
|
||||||
description = ''
|
|
||||||
List of allowed build methods for this host.
|
|
||||||
Supported methods:
|
|
||||||
- "installer-iso": Generates an auto-install ISO that installs this configuration to disk.
|
|
||||||
- "iso": Generates a live ISO (using nixos-generators).
|
|
||||||
- "ipxe": Generates iPXE netboot artifacts (kernel, initrd, script).
|
|
||||||
- "lxc": Generates an LXC container tarball.
|
|
||||||
- "proxmox": Generates a Proxmox VMA archive.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
system.gc = {
|
|
||||||
enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Whether to enable automatic garbage collection.";
|
|
||||||
};
|
|
||||||
frequency = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "weekly";
|
|
||||||
description = "How often to run garbage collection (systemd timer format).";
|
|
||||||
};
|
|
||||||
retentionDays = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 30;
|
|
||||||
description = "Number of days to keep old generations before deletion.";
|
|
||||||
};
|
|
||||||
optimise = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Whether to automatically optimize the Nix store.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkMerge [
|
|
||||||
# Enable forUser if specified
|
|
||||||
(lib.mkIf (config.athenix.forUser != null) {
|
|
||||||
athenix.users.${config.athenix.forUser}.enable = true;
|
|
||||||
})
|
|
||||||
|
|
||||||
# Main configuration
|
|
||||||
{
|
|
||||||
# ========== Disk Partitioning (Disko) ==========
|
|
||||||
disko.enableConfig = lib.mkDefault true;
|
|
||||||
|
|
||||||
disko.devices = {
|
|
||||||
disk.main = {
|
|
||||||
type = "disk";
|
|
||||||
device = config.athenix.host.filesystem.device;
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
# EFI System Partition
|
|
||||||
ESP = {
|
|
||||||
name = "ESP";
|
|
||||||
label = "BOOT";
|
|
||||||
size = "1G";
|
|
||||||
type = "EF00";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "vfat";
|
|
||||||
mountpoint = "/boot";
|
|
||||||
mountOptions = [ "umask=0077" ];
|
|
||||||
extraArgs = [
|
|
||||||
"-n"
|
|
||||||
"BOOT"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Swap Partition (size configurable per host)
|
|
||||||
swap = lib.mkIf config.athenix.host.filesystem.useSwap {
|
|
||||||
name = "swap";
|
|
||||||
label = "swap";
|
|
||||||
size = config.athenix.host.filesystem.swapSize;
|
|
||||||
content = {
|
|
||||||
type = "swap";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Root Partition (takes remaining space)
|
|
||||||
root = {
|
|
||||||
name = "root";
|
|
||||||
label = "root";
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "ext4";
|
|
||||||
mountpoint = "/";
|
|
||||||
extraArgs = [
|
|
||||||
"-L"
|
|
||||||
"ROOT"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Bootloader Configuration
|
|
||||||
boot = {
|
|
||||||
loader.systemd-boot.enable = true;
|
|
||||||
loader.efi.canTouchEfiVariables = true;
|
|
||||||
plymouth.enable = true;
|
|
||||||
|
|
||||||
# Enable "Silent boot"
|
|
||||||
consoleLogLevel = 3;
|
|
||||||
initrd.verbose = false;
|
|
||||||
|
|
||||||
# Hide the OS choice for bootloaders.
|
|
||||||
# It's still possible to open the bootloader list by pressing any key
|
|
||||||
# It will just not appear on screen unless a key is pressed
|
|
||||||
loader.timeout = lib.mkDefault 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Set your time zone.
|
|
||||||
time.timeZone = "America/New_York";
|
|
||||||
|
|
||||||
# Select internationalisation properties.
|
|
||||||
i18n.defaultLocale = "en_US.UTF-8";
|
|
||||||
|
|
||||||
i18n.extraLocaleSettings = {
|
|
||||||
LC_ADDRESS = "en_US.UTF-8";
|
|
||||||
LC_IDENTIFICATION = "en_US.UTF-8";
|
|
||||||
LC_MEASUREMENT = "en_US.UTF-8";
|
|
||||||
LC_MONETARY = "en_US.UTF-8";
|
|
||||||
LC_NAME = "en_US.UTF-8";
|
|
||||||
LC_NUMERIC = "en_US.UTF-8";
|
|
||||||
LC_PAPER = "en_US.UTF-8";
|
|
||||||
LC_TELEPHONE = "en_US.UTF-8";
|
|
||||||
LC_TIME = "en_US.UTF-8";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.sleep.extraConfig = ''
|
|
||||||
SuspendState=freeze
|
|
||||||
HibernateDelaySec=2h
|
|
||||||
'';
|
|
||||||
|
|
||||||
system.stateVersion = "25.11"; # Did you read the comment?
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# ============================================================================
|
|
||||||
# Common Modules
|
|
||||||
# ============================================================================
|
|
||||||
# This module contains all the common configuration shared by all host types.
|
|
||||||
# It includes:
|
|
||||||
# - Boot and user configuration
|
|
||||||
# - Software configurations
|
|
||||||
# - User management (users.nix)
|
|
||||||
# - Home Manager integration
|
|
||||||
# - Secret management (agenix)
|
|
||||||
# - Disk partitioning (disko)
|
|
||||||
# - System-wide Nix settings (experimental features, garbage collection)
|
|
||||||
|
|
||||||
{ inputs }:
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./boot.nix
|
|
||||||
./user-config.nix
|
|
||||||
../sw
|
|
||||||
../users.nix
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
inputs.agenix.nixosModules.default
|
|
||||||
inputs.disko.nixosModules.disko
|
|
||||||
];
|
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
|
||||||
|
|
||||||
nix.settings.experimental-features = [
|
|
||||||
"nix-command"
|
|
||||||
"flakes"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Automatic Garbage Collection
|
|
||||||
nix.gc = lib.mkIf config.athenix.system.gc.enable {
|
|
||||||
automatic = true;
|
|
||||||
dates = config.athenix.system.gc.frequency;
|
|
||||||
options = "--delete-older-than ${toString config.athenix.system.gc.retentionDays}d";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Optimize storage
|
|
||||||
nix.optimise.automatic = config.athenix.system.gc.optimise;
|
|
||||||
}
|
|
||||||
@@ -46,7 +46,7 @@ Add the host to `inventory.nix` with the `nix-lxc` type or ensure it has the app
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Your host type configuration (`hosts/types/nix-lxc.nix`) should include:
|
Your host type configuration (`variants/nix-lxc.nix`) should include:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
inputs,
|
inputs,
|
||||||
hosts,
|
fleet,
|
||||||
self,
|
self,
|
||||||
system,
|
system,
|
||||||
}:
|
}:
|
||||||
@@ -45,7 +45,7 @@ let
|
|||||||
nixos-generators.nixosGenerate {
|
nixos-generators.nixosGenerate {
|
||||||
inherit system;
|
inherit system;
|
||||||
specialArgs = { inherit inputs; };
|
specialArgs = { inherit inputs; };
|
||||||
modules = hosts.modules.${hostName} ++ [
|
modules = fleet.modules.${hostName} ++ [
|
||||||
{
|
{
|
||||||
disko.enableConfig = lib.mkForce false;
|
disko.enableConfig = lib.mkForce false;
|
||||||
services.upower.enable = lib.mkForce false;
|
services.upower.enable = lib.mkForce false;
|
||||||
@@ -61,7 +61,7 @@ let
|
|||||||
nixpkgs.lib.nixosSystem {
|
nixpkgs.lib.nixosSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
specialArgs = { inherit inputs; };
|
specialArgs = { inherit inputs; };
|
||||||
modules = hosts.modules.${hostName} ++ [
|
modules = fleet.modules.${hostName} ++ [
|
||||||
"${nixpkgs}/nixos/modules/installer/netboot/netboot.nix"
|
"${nixpkgs}/nixos/modules/installer/netboot/netboot.nix"
|
||||||
{
|
{
|
||||||
disko.enableConfig = lib.mkForce false;
|
disko.enableConfig = lib.mkForce false;
|
||||||
@@ -70,14 +70,14 @@ let
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
hostNames = builtins.attrNames hosts.nixosConfigurations;
|
hostNames = builtins.attrNames fleet.nixosConfigurations;
|
||||||
|
|
||||||
# Generate installer ISOs for hosts that have "installer-iso" in their buildMethods
|
# Generate installer ISOs for hosts that have "installer-iso" in their buildMethods
|
||||||
installerPackages = lib.listToAttrs (
|
installerPackages = lib.listToAttrs (
|
||||||
lib.concatMap (
|
lib.concatMap (
|
||||||
name:
|
name:
|
||||||
let
|
let
|
||||||
cfg = hosts.nixosConfigurations.${name};
|
cfg = fleet.nixosConfigurations.${name};
|
||||||
in
|
in
|
||||||
if lib.elem "installer-iso" cfg.config.athenix.host.buildMethods then
|
if lib.elem "installer-iso" cfg.config.athenix.host.buildMethods then
|
||||||
[
|
[
|
||||||
@@ -96,7 +96,7 @@ let
|
|||||||
lib.concatMap (
|
lib.concatMap (
|
||||||
name:
|
name:
|
||||||
let
|
let
|
||||||
cfg = hosts.nixosConfigurations.${name};
|
cfg = fleet.nixosConfigurations.${name};
|
||||||
in
|
in
|
||||||
if lib.elem "iso" cfg.config.athenix.host.buildMethods then
|
if lib.elem "iso" cfg.config.athenix.host.buildMethods then
|
||||||
[
|
[
|
||||||
@@ -115,7 +115,7 @@ let
|
|||||||
lib.concatMap (
|
lib.concatMap (
|
||||||
name:
|
name:
|
||||||
let
|
let
|
||||||
cfg = hosts.nixosConfigurations.${name};
|
cfg = fleet.nixosConfigurations.${name};
|
||||||
in
|
in
|
||||||
if lib.elem "ipxe" cfg.config.athenix.host.buildMethods then
|
if lib.elem "ipxe" cfg.config.athenix.host.buildMethods then
|
||||||
[
|
[
|
||||||
@@ -145,7 +145,7 @@ let
|
|||||||
lib.concatMap (
|
lib.concatMap (
|
||||||
name:
|
name:
|
||||||
let
|
let
|
||||||
cfg = hosts.nixosConfigurations.${name};
|
cfg = fleet.nixosConfigurations.${name};
|
||||||
in
|
in
|
||||||
if lib.elem "lxc" cfg.config.athenix.host.buildMethods then
|
if lib.elem "lxc" cfg.config.athenix.host.buildMethods then
|
||||||
[
|
[
|
||||||
@@ -164,7 +164,7 @@ let
|
|||||||
lib.concatMap (
|
lib.concatMap (
|
||||||
name:
|
name:
|
||||||
let
|
let
|
||||||
cfg = hosts.nixosConfigurations.${name};
|
cfg = fleet.nixosConfigurations.${name};
|
||||||
in
|
in
|
||||||
if lib.elem "proxmox" cfg.config.athenix.host.buildMethods then
|
if lib.elem "proxmox" cfg.config.athenix.host.buildMethods then
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -6,40 +6,23 @@
|
|||||||
#
|
#
|
||||||
# Usage in another flake:
|
# Usage in another flake:
|
||||||
# # Full host type configurations (includes hardware + software + system config)
|
# # Full host type configurations (includes hardware + software + system config)
|
||||||
# inputs.nixos-systems.nixosModules.nix-desktop
|
# inputs.athenix.nixosModules.nix-desktop
|
||||||
# inputs.nixos-systems.nixosModules.nix-laptop
|
# inputs.athenix.nixosModules.nix-laptop
|
||||||
#
|
#
|
||||||
# # Software-only configurations (for custom hardware setups)
|
# # Software-only configuration (for custom hardware setups)
|
||||||
# # Note: These include theme.nix in home-manager.sharedModules automatically
|
# inputs.athenix.nixosModules.sw
|
||||||
# inputs.nixos-systems.nixosModules.sw-desktop
|
|
||||||
# inputs.nixos-systems.nixosModules.sw-headless
|
|
||||||
#
|
|
||||||
# # Home Manager modules (user-level configuration)
|
|
||||||
# # Theme module (no parameters):
|
|
||||||
# home-manager.users.myuser.imports = [ inputs.nixos-systems.homeManagerModules.theme ];
|
|
||||||
#
|
|
||||||
# # Neovim module (requires user parameter):
|
|
||||||
# home-manager.users.myuser.imports = [
|
|
||||||
# (inputs.nixos-systems.homeManagerModules.nvim {
|
|
||||||
# user = config.athenix.users.accounts.myuser;
|
|
||||||
# })
|
|
||||||
# ];
|
|
||||||
|
|
||||||
{ inputs }:
|
{ inputs }:
|
||||||
{
|
# Automatically import all variant modules from variants/ directory
|
||||||
# ========== Full Host Type Modules ==========
|
# This returns an attribute set like: { nix-desktop = ...; nix-laptop = ...; nix-lxc = ...; sw = ...; }
|
||||||
# Complete system configurations including hardware, boot, and software
|
(import ../variants { inherit inputs; })
|
||||||
nix-desktop = import ../hosts/types/nix-desktop.nix { inherit inputs; }; # Desktop workstations
|
// {
|
||||||
nix-laptop = import ../hosts/types/nix-laptop.nix { inherit inputs; }; # Laptop systems
|
# Software configuration module - main module with all athenix.sw options
|
||||||
nix-surface = import ../hosts/types/nix-surface.nix { inherit inputs; }; # Surface tablets
|
|
||||||
nix-lxc = import ../hosts/types/nix-lxc.nix { inherit inputs; }; # Proxmox containers
|
|
||||||
nix-wsl = import ../hosts/types/nix-wsl.nix { inherit inputs; }; # WSL2 systems
|
|
||||||
nix-ephemeral = import ../hosts/types/nix-ephemeral.nix { inherit inputs; }; # Diskless/RAM-only
|
|
||||||
|
|
||||||
# ========== Software Configuration Module ==========
|
|
||||||
# Main software module with all athenix.sw options
|
|
||||||
# Use athenix.sw.type to select profile: "desktop", "tablet-kiosk", "headless", "stateless-kiosk"
|
# Use athenix.sw.type to select profile: "desktop", "tablet-kiosk", "headless", "stateless-kiosk"
|
||||||
# Use athenix.sw.extraPackages to add additional packages
|
sw =
|
||||||
# Use athenix.sw.kioskUrl to set kiosk mode URL
|
{
|
||||||
sw = { inputs, ... }@args: (import ../sw/default.nix (args // { inherit inputs; }));
|
inputs,
|
||||||
|
...
|
||||||
|
}@args:
|
||||||
|
(import ../sw/default.nix (args // { inherit inputs; }));
|
||||||
}
|
}
|
||||||
|
|||||||
174
inventory.nix
174
inventory.nix
@@ -1,72 +1,78 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# Fleet Inventory
|
||||||
|
# ============================================================================
|
||||||
|
# Top-level keys are ALWAYS hostname prefixes. Actual hostnames are generated
|
||||||
|
# from the devices map or count.
|
||||||
|
#
|
||||||
|
# Hostname generation rules:
|
||||||
|
# - Numeric suffixes: no dash (e.g., "nix-surface1", "nix-surface2")
|
||||||
|
# - Non-numeric suffixes: add dash (e.g., "nix-surface-alpha", "nix-surface-beta")
|
||||||
|
# - Set athenix.host.useHostPrefix = false to use suffix as full hostname
|
||||||
|
#
|
||||||
|
# Format:
|
||||||
|
# "prefix" = {
|
||||||
|
# type = "nix-desktop"; # Optional: defaults to prefix name
|
||||||
|
# system = "x86_64-linux"; # Optional: default is x86_64-linux
|
||||||
|
#
|
||||||
|
# # Option 1: Simple count (quick syntax)
|
||||||
|
# devices = 5; # Creates: prefix1, prefix2, ..., prefix5
|
||||||
|
#
|
||||||
|
# # Option 2: Explicit count
|
||||||
|
# count = 5; # Creates: prefix1, prefix2, ..., prefix5
|
||||||
|
#
|
||||||
|
# # Option 3: Default count (for groups with mixed devices)
|
||||||
|
# defaultCount = 3; # Creates default numbered hosts
|
||||||
|
#
|
||||||
|
# # Option 4: Named device configurations
|
||||||
|
# devices = {
|
||||||
|
# "1" = { ... }; # Creates: prefix1
|
||||||
|
# "alpha" = { ... }; # Creates: prefix-alpha
|
||||||
|
# "custom" = { # Creates: custom (no prefix)
|
||||||
|
# athenix.host.useHostPrefix = false;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# # Common config for all devices in this group
|
||||||
|
# overrides = {
|
||||||
|
# athenix.users.user1.enable = true; # Applied to all devices in this group
|
||||||
|
# # ... any other config
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# Convenience options:
|
||||||
|
# athenix.forUser = "username"; # Automatically enables user (sets athenix.users.username.enable = true)
|
||||||
|
#
|
||||||
|
# External modules (instead of config):
|
||||||
|
# Device values can be a config attrset with an optional 'external' field:
|
||||||
|
# devices."hostname" = {
|
||||||
|
# external = builtins.fetchGit { ... }; # Lazy: only fetched when building this host
|
||||||
|
# # ... additional config options
|
||||||
|
# };
|
||||||
|
# The external module will be imported and evaluated only when this specific host is built.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# "lab" = { devices = 3; }; # Quick: lab1, lab2, lab3
|
||||||
|
# "lab" = { count = 3; }; # Same as above
|
||||||
|
# "kiosk" = {
|
||||||
|
# defaultCount = 2; # kiosk1, kiosk2 (default)
|
||||||
|
# devices."special" = {}; # kiosk-special (custom)
|
||||||
|
# };
|
||||||
|
# "laptop" = {
|
||||||
|
# devices = 5;
|
||||||
|
# overrides.athenix.users.student.enable = true; # All 5 laptops get this user
|
||||||
|
# };
|
||||||
|
# "wsl" = {
|
||||||
|
# devices."alice".athenix.forUser = "alice123"; # Sets up for user alice123
|
||||||
|
# };
|
||||||
|
# "external" = {
|
||||||
|
# devices."remote".external = builtins.fetchGit { # External module via Git (lazy)
|
||||||
|
# url = "https://github.com/example/config";
|
||||||
|
# rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014";
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
{
|
{
|
||||||
# ============================================================================
|
# ========== Lab Laptops ==========
|
||||||
# Fleet Inventory
|
|
||||||
# ============================================================================
|
|
||||||
# Top-level keys are ALWAYS hostname prefixes. Actual hostnames are generated
|
|
||||||
# from the devices map or count.
|
|
||||||
#
|
|
||||||
# Hostname generation rules:
|
|
||||||
# - Numeric suffixes: no dash (e.g., "nix-surface1", "nix-surface2")
|
|
||||||
# - Non-numeric suffixes: add dash (e.g., "nix-surface-alpha", "nix-surface-beta")
|
|
||||||
# - Set athenix.host.useHostPrefix = false to use suffix as full hostname
|
|
||||||
#
|
|
||||||
# Format:
|
|
||||||
# "prefix" = {
|
|
||||||
# type = "nix-desktop"; # Optional: defaults to prefix name
|
|
||||||
# system = "x86_64-linux"; # Optional: default is x86_64-linux
|
|
||||||
#
|
|
||||||
# # Option 1: Simple count (quick syntax)
|
|
||||||
# devices = 5; # Creates: prefix1, prefix2, ..., prefix5
|
|
||||||
#
|
|
||||||
# # Option 2: Explicit count
|
|
||||||
# count = 5; # Creates: prefix1, prefix2, ..., prefix5
|
|
||||||
#
|
|
||||||
# # Option 3: Default count (for groups with mixed devices)
|
|
||||||
# defaultCount = 3; # Creates default numbered hosts
|
|
||||||
#
|
|
||||||
# # Option 4: Named device configurations
|
|
||||||
# devices = {
|
|
||||||
# "1" = { ... }; # Creates: prefix1
|
|
||||||
# "alpha" = { ... }; # Creates: prefix-alpha
|
|
||||||
# "custom" = { # Creates: custom (no prefix)
|
|
||||||
# athenix.host.useHostPrefix = false;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# # Common config for all devices in this group
|
|
||||||
# overrides = {
|
|
||||||
# athenix.users.user1.enable = true; # Applied to all devices in this group
|
|
||||||
# # ... any other config
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# Convenience options:
|
|
||||||
# athenix.forUser = "username"; # Automatically enables user (sets athenix.users.username.enable = true)
|
|
||||||
#
|
|
||||||
# External modules (instead of config):
|
|
||||||
# Device values can be either a config attrset OR a fetchGit/fetchurl call
|
|
||||||
# that points to an external Nix module. The module will be imported and evaluated.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# "lab" = { devices = 3; }; # Quick: lab1, lab2, lab3
|
|
||||||
# "lab" = { count = 3; }; # Same as above
|
|
||||||
# "kiosk" = {
|
|
||||||
# defaultCount = 2; # kiosk1, kiosk2 (default)
|
|
||||||
# devices."special" = {}; # kiosk-special (custom)
|
|
||||||
# };
|
|
||||||
# "laptop" = {
|
|
||||||
# devices = 5;
|
|
||||||
# overrides.athenix.users.student.enable = true; # All 5 laptops get this user
|
|
||||||
# };
|
|
||||||
# "wsl" = {
|
|
||||||
# devices."alice".athenix.forUser = "alice123"; # Sets up for user alice123
|
|
||||||
# };
|
|
||||||
# "external" = {
|
|
||||||
# devices."remote" = builtins.fetchGit { # External module via Git
|
|
||||||
# url = "https://github.com/example/config";
|
|
||||||
# rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014";
|
|
||||||
# };
|
|
||||||
# }; # ========== Lab Laptops ==========
|
|
||||||
# Creates: nix-laptop1, nix-laptop2
|
# Creates: nix-laptop1, nix-laptop2
|
||||||
# Both get hdh20267 user via overrides
|
# Both get hdh20267 user via overrides
|
||||||
nix-laptop = {
|
nix-laptop = {
|
||||||
@@ -120,7 +126,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"usda-dash" = builtins.fetchGit {
|
"usda-dash".external = builtins.fetchGit {
|
||||||
url = "https://git.factory.uga.edu/MODEL/usda-dash-config.git";
|
url = "https://git.factory.uga.edu/MODEL/usda-dash-config.git";
|
||||||
rev = "dab32f5884895cead0fae28cb7d88d17951d0c12";
|
rev = "dab32f5884895cead0fae28cb7d88d17951d0c12";
|
||||||
submodules = true;
|
submodules = true;
|
||||||
@@ -146,34 +152,4 @@
|
|||||||
# ========== Ephemeral/Netboot System ==========
|
# ========== Ephemeral/Netboot System ==========
|
||||||
# Creates: nix-ephemeral1
|
# Creates: nix-ephemeral1
|
||||||
nix-ephemeral.devices = 1;
|
nix-ephemeral.devices = 1;
|
||||||
|
|
||||||
# ========== Example: External Module Configurations ==========
|
|
||||||
# Uncomment to use external modules from Git repositories:
|
|
||||||
#
|
|
||||||
# external-systems = {
|
|
||||||
# devices = {
|
|
||||||
# # Option 1: fetchGit with specific revision (recommended for reproducibility)
|
|
||||||
# "prod-server" = builtins.fetchGit {
|
|
||||||
# url = "https://github.com/example/server-config";
|
|
||||||
# rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014"; # Full commit hash
|
|
||||||
# ref = "main"; # Optional: branch/tag name
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# # Option 2: fetchGit with latest from branch (less reproducible)
|
|
||||||
# "dev-server" = builtins.fetchGit {
|
|
||||||
# url = "https://github.com/example/server-config";
|
|
||||||
# ref = "develop";
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# # Option 3: fetchTarball for specific release
|
|
||||||
# "test-server" = builtins.fetchTarball {
|
|
||||||
# url = "https://github.com/example/server-config/archive/v1.0.0.tar.gz";
|
|
||||||
# sha256 = "sha256:0000000000000000000000000000000000000000000000000000";
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# # Option 4: Mix external module with local overrides
|
|
||||||
# # Note: The external module's default.nix should export a NixOS module
|
|
||||||
# # that accepts { inputs, ... } as parameters
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
variants/default.nix
Normal file
23
variants/default.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# Host Types Module
|
||||||
|
# ============================================================================
|
||||||
|
# This module exports all available host types as an attribute set.
|
||||||
|
# Each type is a NixOS module function that takes { inputs } and returns
|
||||||
|
# a module configuration.
|
||||||
|
|
||||||
|
{ inputs }:
|
||||||
|
let
|
||||||
|
inherit (builtins) readDir attrNames;
|
||||||
|
lib = inputs.nixpkgs.lib;
|
||||||
|
inherit (lib) filterAttrs removeSuffix genAttrs;
|
||||||
|
|
||||||
|
files = readDir ./.;
|
||||||
|
|
||||||
|
# Keep only regular *.nix files except default.nix
|
||||||
|
nixFiles = filterAttrs (
|
||||||
|
name: type: type == "regular" && lib.hasSuffix ".nix" name && name != "default.nix"
|
||||||
|
) files;
|
||||||
|
|
||||||
|
moduleNames = map (name: removeSuffix ".nix" name) (attrNames nixFiles);
|
||||||
|
in
|
||||||
|
genAttrs moduleNames (name: import ./${name}.nix { inherit inputs; })
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(import ../common.nix { inherit inputs; })
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(import ../common.nix { inherit inputs; })
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(import ../common.nix { inherit inputs; })
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(import ../common.nix { inherit inputs; })
|
|
||||||
inputs.vscode-server.nixosModules.default
|
inputs.vscode-server.nixosModules.default
|
||||||
"${modulesPath}/virtualisation/proxmox-lxc.nix"
|
"${modulesPath}/virtualisation/proxmox-lxc.nix"
|
||||||
];
|
];
|
||||||
@@ -22,7 +22,6 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(import ../common.nix { inherit inputs; })
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
inputs.nixos-hardware.nixosModules.microsoft-surface-go
|
inputs.nixos-hardware.nixosModules.microsoft-surface-go
|
||||||
];
|
];
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(import ../common.nix { inherit inputs; })
|
|
||||||
inputs.nixos-wsl.nixosModules.default
|
inputs.nixos-wsl.nixosModules.default
|
||||||
inputs.vscode-server.nixosModules.default
|
inputs.vscode-server.nixosModules.default
|
||||||
];
|
];
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(import ../common.nix { inherit inputs; })
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
Reference in New Issue
Block a user