Refactored the repository structure by renaming variants/ to hw and glue/ to fleet, fixing an infinite recursion bug by separating fleet options evaluation, and adding a lib.mkFleet function to enable external flakes to reuse Athenix's fleet generation #29
24
.github/copilot-instructions.md
vendored
24
.github/copilot-instructions.md
vendored
@@ -26,8 +26,8 @@ This is a **NixOS system configuration repository** that uses:
|
||||
- **`flake.nix`**: Entry point - inputs and outputs only
|
||||
- **`inventory.nix`**: Fleet definitions - host configurations
|
||||
- **`users.nix`**: User account definitions
|
||||
- **`variants/`**: Hardware type modules (desktop, laptop, surface, lxc, wsl, etc.)
|
||||
- **`glue/`**: Fleet generation logic and common system configuration
|
||||
- **`hw/`**: Hardware type modules (desktop, laptop, surface, lxc, wsl, etc.)
|
||||
- **`fleet/`**: Fleet generation logic and common system configuration
|
||||
- **`sw/`**: Software configurations by system type
|
||||
- **`installer/`**: Build artifact generation (ISO, LXC, etc.)
|
||||
- **`templates/`**: Templates for external configurations
|
||||
@@ -45,9 +45,12 @@ All Innovation Factory-specific options MUST use the `athenix` namespace:
|
||||
### Host Options (`athenix.host.*`)
|
||||
```nix
|
||||
athenix.host = {
|
||||
filesystem.device = "/dev/sda"; # Boot disk
|
||||
filesystem.swapSize = "32G"; # Swap size
|
||||
buildMethods = [ "iso" ]; # Artifact types
|
||||
filesystem.device = "/dev/nvme0n1"; # Boot disk (default: null)
|
||||
filesystem.swapSize = "32G"; # Swap size (default: null)
|
||||
buildMethods = [ "installer-iso" ]; # Artifact types (defined in sw/gc.nix)
|
||||
useHostPrefix = true; # Hostname prefix behavior
|
||||
wsl.user = "username"; # WSL default user
|
||||
};
|
||||
useHostPrefix = true; # Hostname prefix behavior
|
||||
wsl.user = "username"; # WSL default user
|
||||
};
|
||||
@@ -114,6 +117,17 @@ athenix.forUser = "username"; # Convenience: enable user + set WSL us
|
||||
3. System modules: Provide `default.nix` that accepts `{ inputs, ... }`
|
||||
4. Reference in `inventory.nix` or `users.nix` using `builtins.fetchGit`
|
||||
|
||||
#### Using Athenix as a Library
|
||||
External flakes can use Athenix's fleet generator:
|
||||
```nix
|
||||
outputs = { athenix, ... }: {
|
||||
nixosConfigurations = athenix.lib.mkFleet {
|
||||
fleet = import ./custom-inventory.nix;
|
||||
hwTypes = import ./custom-hardware.nix;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Important Constraints
|
||||
|
||||
### What NOT to Do
|
||||
|
||||
35
README.md
35
README.md
@@ -54,7 +54,7 @@ users.nix # User account definitions
|
||||
|
||||
flake.lock # Locked dependency versions
|
||||
|
||||
variants/ # Hardware type modules (exportable as nixosModules)
|
||||
hw/ # Hardware type modules (exportable as nixosModules)
|
||||
├── default.nix # Auto-exports all variant types
|
||||
├── nix-desktop.nix # Desktop workstations
|
||||
├── nix-laptop.nix # Laptop systems
|
||||
@@ -64,8 +64,8 @@ variants/ # Hardware type modules (exportable as nixosModules)
|
||||
├── 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
|
||||
fleet/ # Fleet generation and common configuration
|
||||
├── default.nix # Processes inventory.nix to generate all hosts
|
||||
├── common.nix # Common NixOS configuration (all hosts)
|
||||
├── boot.nix # Boot and filesystem configuration
|
||||
└── user-config.nix # User account and home-manager integration
|
||||
@@ -233,6 +233,35 @@ nix flake show
|
||||
|
||||
**See [docs/BUILDING.md](docs/BUILDING.md) for complete guide.**
|
||||
|
||||
### Using Athenix as a Library
|
||||
|
||||
Import Athenix in your own flake to use its fleet generation logic with custom inventory:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.athenix.url = "git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git";
|
||||
|
||||
outputs = { self, athenix, ... }: {
|
||||
# Generate configurations with custom fleet and hardware types
|
||||
nixosConfigurations = athenix.lib.mkFleet {
|
||||
fleet = import ./my-inventory.nix;
|
||||
hwTypes = import ./my-hardware-types.nix;
|
||||
};
|
||||
|
||||
# Or use individual modules
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
modules = [
|
||||
athenix.nixosModules.hw.nix-desktop # Use Athenix hardware configs
|
||||
athenix.nixosModules.sw # Use Athenix software configs
|
||||
./configuration.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**Exported modules:** `nix-desktop`, `nix-laptop`, `nix-surface`, `nix-lxc`, `nix-wsl`, `nix-ephemeral`, `nix-zima`, `sw`, `common`
|
||||
|
||||
## System Types
|
||||
|
||||
Set via `athenix.sw.type`:
|
||||
|
||||
@@ -115,8 +115,8 @@ server-config/
|
||||
|
||||
When a host is built, modules load in this order:
|
||||
|
||||
1. Hardware type module (from `variants/nix-*.nix`)
|
||||
2. Common system configuration (from `glue/common.nix`)
|
||||
1. Hardware type module (from `hw/nix-*.nix`)
|
||||
2. Common system configuration (from `fleet/common.nix`)
|
||||
3. Software type module (from `sw/{type}/`)
|
||||
4. User NixOS modules (from `users.nix` - `nixos.nix` files)
|
||||
5. Device-specific overrides (from `inventory.nix`)
|
||||
|
||||
@@ -17,9 +17,9 @@ Hardware and boot-related settings.
|
||||
|
||||
Boot disk device path.
|
||||
|
||||
**Type:** String
|
||||
**Type:** String or null
|
||||
|
||||
**Default:** `"/dev/sda"`
|
||||
**Default:** `null` (must be set by hardware type or per-host)
|
||||
|
||||
**Example:**
|
||||
```nix
|
||||
@@ -30,9 +30,9 @@ athenix.host.filesystem.device = "/dev/nvme0n1";
|
||||
|
||||
Swap partition size.
|
||||
|
||||
**Type:** String (size with unit, e.g., `"32G"`, `"2G"`)
|
||||
**Type:** String (size with unit, e.g., `"32G"`, `"2G"`) or null
|
||||
|
||||
**Default:** `"32G"`
|
||||
**Default:** `null` (must be set by hardware type or per-host)
|
||||
|
||||
**Example:**
|
||||
```nix
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
fleet = import ./glue/fleet.nix { inherit inputs; };
|
||||
fleet = self.lib.mkFleet { inherit inputs; };
|
||||
linuxSystem = "x86_64-linux";
|
||||
artifacts = import ./installer/artifacts.nix {
|
||||
inherit inputs fleet self;
|
||||
@@ -90,11 +90,14 @@
|
||||
nixosConfigurations = fleet.nixosConfigurations;
|
||||
|
||||
# Expose artifacts to all systems, but they are always built for x86_64-linux
|
||||
packages = forAllSystems (_: artifacts);
|
||||
packages.${linuxSystem} = artifacts;
|
||||
|
||||
# Expose host type modules and installer modules for external use
|
||||
nixosModules = import ./installer/modules.nix { inherit inputs; };
|
||||
|
||||
# Library functions
|
||||
lib = import ./lib { inherit inputs; };
|
||||
|
||||
# Templates for external configurations
|
||||
templates = import ./templates;
|
||||
};
|
||||
|
||||
48
fleet/boot.nix
Normal file
48
fleet/boot.nix
Normal file
@@ -0,0 +1,48 @@
|
||||
# ============================================================================
|
||||
# Boot configuration module
|
||||
# ============================================================================
|
||||
# This module defines:
|
||||
# - Bootloader configuration (systemd-boot with Plymouth)
|
||||
# - Timezone and locale settings
|
||||
# - Systemd sleep configuration
|
||||
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
boot = {
|
||||
loader.systemd-boot.enable = lib.mkDefault true;
|
||||
loader.efi.canTouchEfiVariables = lib.mkDefault true;
|
||||
plymouth.enable = lib.mkDefault 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
|
||||
'';
|
||||
}
|
||||
51
fleet/common.nix
Normal file
51
fleet/common.nix
Normal file
@@ -0,0 +1,51 @@
|
||||
# ============================================================================
|
||||
# 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 = [
|
||||
./fs.nix
|
||||
./boot.nix
|
||||
./user-config.nix
|
||||
../sw
|
||||
../users.nix
|
||||
];
|
||||
|
||||
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 and hosts/default.nix).";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf (config.athenix.forUser != null) {
|
||||
athenix.users.${config.athenix.forUser}.enable = true;
|
||||
})
|
||||
{
|
||||
system.stateVersion = "25.11";
|
||||
nix.settings.experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
inputs,
|
||||
fleet ? import ../inventory.nix,
|
||||
fleet ? null,
|
||||
hwTypes ? null,
|
||||
...
|
||||
}:
|
||||
|
||||
@@ -15,8 +16,23 @@ let
|
||||
nixpkgs = inputs.nixpkgs;
|
||||
lib = nixpkgs.lib;
|
||||
|
||||
# Load all available host types from hosts/
|
||||
hostTypes = import ../variants { inherit inputs; };
|
||||
# Evaluate inventory to get fleet data
|
||||
# Import fleet-option.nix (defines athenix.fleet) and inventory.nix (sets values)
|
||||
# We use a minimal module here to avoid circular dependencies from common.nix's imports
|
||||
inventoryModule = lib.evalModules {
|
||||
modules = [
|
||||
(import ./fleet-option.nix { inherit inputs; })
|
||||
{
|
||||
_module.args = {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
};
|
||||
}
|
||||
(lib.mkIf (fleet != null) { athenix.fleet = lib.mkForce fleet; })
|
||||
(lib.mkIf (hwTypes != null) { athenix.hwTypes = lib.mkForce hwTypes; })
|
||||
];
|
||||
};
|
||||
|
||||
hostTypes = inventoryModule.config.athenix.hwTypes;
|
||||
|
||||
# Helper to create a single NixOS system configuration
|
||||
mkHost =
|
||||
@@ -135,7 +151,7 @@ let
|
||||
allModules =
|
||||
userNixosModules
|
||||
++ [
|
||||
(import ./common.nix { inherit inputs; })
|
||||
./common.nix
|
||||
typeModule
|
||||
overrideModule
|
||||
{ networking.hostName = hostName; }
|
||||
@@ -267,10 +283,12 @@ let
|
||||
{ };
|
||||
in
|
||||
lib.recursiveUpdate deviceHosts countHosts
|
||||
) fleet;
|
||||
);
|
||||
|
||||
fleetData = inventoryModule.config.athenix.fleet;
|
||||
|
||||
# Flatten the nested structure
|
||||
allHosts = lib.foldl' lib.recursiveUpdate { } (lib.attrValues processInventory);
|
||||
allHosts = lib.foldl' lib.recursiveUpdate { } (lib.attrValues (processInventory fleetData));
|
||||
in
|
||||
{
|
||||
nixosConfigurations = lib.mapAttrs (n: v: v.system) allHosts;
|
||||
75
fleet/fleet-option.nix
Normal file
75
fleet/fleet-option.nix
Normal file
@@ -0,0 +1,75 @@
|
||||
# ============================================================================
|
||||
# Fleet Option Definition
|
||||
# ============================================================================
|
||||
# This module only defines the athenix.fleet option without any dependencies.
|
||||
# Used by fleet.nix to evaluate inventory data without circular dependencies.
|
||||
{ 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
|
||||
{
|
||||
options.athenix = {
|
||||
fleet = fleetDefinition;
|
||||
hwTypes = lib.mkOption {
|
||||
description = "Hardware types definitions for the fleet.";
|
||||
type = lib.types.attrs;
|
||||
};
|
||||
};
|
||||
|
||||
config.athenix.fleet = lib.mkDefault (import ../inventory.nix);
|
||||
config.athenix.hwTypes = lib.mkDefault (import ../hw { inherit inputs; });
|
||||
}
|
||||
90
fleet/fs.nix
Normal file
90
fleet/fs.nix
Normal file
@@ -0,0 +1,90 @@
|
||||
# ============================================================================
|
||||
# FS & Storage Configuration
|
||||
# ============================================================================
|
||||
# This module defines:
|
||||
# - Disko partition layout (EFI, swap, root)
|
||||
# - Filesystem options (device, swap size)
|
||||
|
||||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
options.athenix = {
|
||||
host.filesystem = {
|
||||
device = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
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.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "The size of the swap partition.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
# ========== Disk Partitioning (Disko) ==========
|
||||
disko.enableConfig = lib.mkDefault (config.athenix.host.filesystem.device != null);
|
||||
|
||||
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"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
137
glue/boot.nix
137
glue/boot.nix
@@ -1,137 +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 (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
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
# ============================================================================
|
||||
# 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;
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -2,13 +2,12 @@
|
||||
# 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.
|
||||
# Each type is a NixOS module (a function suitable for lib.types.submodule).
|
||||
|
||||
{ inputs }:
|
||||
let
|
||||
inherit (builtins) readDir attrNames;
|
||||
lib = inputs.nixpkgs.lib;
|
||||
inherit (builtins) readDir attrNames;
|
||||
inherit (lib) filterAttrs removeSuffix genAttrs;
|
||||
|
||||
files = readDir ./.;
|
||||
@@ -20,4 +19,5 @@ let
|
||||
|
||||
moduleNames = map (name: removeSuffix ".nix" name) (attrNames nixFiles);
|
||||
in
|
||||
genAttrs moduleNames (name: import ./${name}.nix { inherit inputs; })
|
||||
# Export: { name = <module function from ./name.nix>; }
|
||||
genAttrs moduleNames (name: import (./. + ("/" + name + ".nix")))
|
||||
@@ -4,7 +4,6 @@
|
||||
# Hardware and boot configuration for standard desktop workstations.
|
||||
# Includes Intel CPU support and NVMe storage.
|
||||
|
||||
{ inputs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
@@ -5,7 +5,6 @@
|
||||
# Suitable for kiosks, netboot clients, and stateless workstations.
|
||||
# All data is lost on reboot.
|
||||
|
||||
{ inputs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
@@ -4,7 +4,6 @@
|
||||
# Hardware and boot configuration for laptop systems with mobile features.
|
||||
# Includes power management, lid switch handling, and Intel graphics fixes.
|
||||
|
||||
{ inputs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
@@ -4,11 +4,11 @@
|
||||
# Configuration for lightweight Linux containers running in Proxmox.
|
||||
# Disables boot/disk management and enables remote development support.
|
||||
|
||||
{ inputs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
@@ -4,22 +4,13 @@
|
||||
# Hardware configuration for Surface Go tablets in kiosk mode.
|
||||
# Uses nixos-hardware module and older kernel for Surface-specific drivers.
|
||||
|
||||
{ inputs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# Use older kernel version for better Surface Go compatibility
|
||||
refSystem = inputs.nixpkgs-old-kernel.lib.nixosSystem {
|
||||
system = pkgs.stdenv.hostPlatform.system;
|
||||
modules = [ inputs.nixos-hardware.nixosModules.microsoft-surface-go ];
|
||||
};
|
||||
refKernelPackages = refSystem.config.boot.kernelPackages;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
@@ -51,9 +42,6 @@ in
|
||||
"i915.enable_dc=0" # Disable display power saving
|
||||
];
|
||||
|
||||
# Use older kernel for better Surface hardware support
|
||||
boot.kernelPackages = lib.mkForce refKernelPackages;
|
||||
|
||||
# ========== Filesystem Configuration ==========
|
||||
athenix.host.filesystem.swapSize = lib.mkDefault "8G";
|
||||
athenix.host.filesystem.device = lib.mkDefault "/dev/mmcblk0"; # eMMC storage # eMMC storage
|
||||
@@ -4,10 +4,10 @@
|
||||
# Configuration for NixOS running in WSL2 on Windows.
|
||||
# Integrates with nixos-wsl for WSL-specific functionality.
|
||||
|
||||
{ inputs, ... }:
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
@@ -4,7 +4,6 @@
|
||||
# Hardware and boot configuration for standard desktop workstations.
|
||||
# Includes Intel CPU support and NVMe storage.
|
||||
|
||||
{ inputs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
@@ -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 (`variants/nix-lxc.nix`) should include:
|
||||
Your host type configuration (`hw/nix-lxc.nix`) should include:
|
||||
|
||||
```nix
|
||||
{
|
||||
|
||||
@@ -13,12 +13,15 @@
|
||||
# inputs.athenix.nixosModules.sw
|
||||
|
||||
{ inputs }:
|
||||
# Automatically import all variant modules from variants/ directory
|
||||
# This returns an attribute set like: { nix-desktop = ...; nix-laptop = ...; nix-lxc = ...; sw = ...; }
|
||||
(import ../variants { inherit inputs; })
|
||||
// {
|
||||
# Expose hardware type modules from hw/ directory
|
||||
# This returns an attribute set like: { nix-desktop = ...; nix-laptop = ...; nix-lxc = ...; }
|
||||
let
|
||||
hostTypes = import ../hw { inherit inputs; };
|
||||
in
|
||||
{
|
||||
# Software configuration module - main module with all athenix.sw options
|
||||
# Use athenix.sw.type to select profile: "desktop", "tablet-kiosk", "headless", "stateless-kiosk"
|
||||
hw = hostTypes;
|
||||
sw =
|
||||
{
|
||||
inputs,
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
# rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014";
|
||||
# };
|
||||
# };
|
||||
|
||||
{
|
||||
# ========== Lab Laptops ==========
|
||||
# Creates: nix-laptop1, nix-laptop2
|
||||
|
||||
4
lib/default.nix
Normal file
4
lib/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ inputs }:
|
||||
{
|
||||
mkFleet = import ./mkFleet.nix;
|
||||
}
|
||||
11
lib/mkFleet.nix
Normal file
11
lib/mkFleet.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
# Generate fleet configurations with custom fleet and hardware types
|
||||
# Usage: nixosConfigurations = athenix.lib.mkFleet { fleet = { ... }; hwTypes = { ... }; }
|
||||
{
|
||||
inputs,
|
||||
fleet ? null,
|
||||
hwTypes ? null,
|
||||
}:
|
||||
import ../fleet/default.nix {
|
||||
inherit inputs;
|
||||
inherit fleet hwTypes;
|
||||
}
|
||||
@@ -28,8 +28,12 @@ in
|
||||
imports = [
|
||||
./python.nix
|
||||
./ghostty.nix
|
||||
./gc.nix
|
||||
./updater.nix
|
||||
./update-ref.nix
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
inputs.agenix.nixosModules.default
|
||||
inputs.disko.nixosModules.disko
|
||||
];
|
||||
|
||||
options.athenix.sw = {
|
||||
|
||||
58
sw/gc.nix
Normal file
58
sw/gc.nix
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options.athenix = {
|
||||
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 = {
|
||||
# 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;
|
||||
};
|
||||
}
|
||||
@@ -26,5 +26,5 @@
|
||||
};
|
||||
|
||||
# Disable systemd-networkd and systemd-hostnamed
|
||||
systemd.network.enable = false;
|
||||
systemd.network.enable = lib.mkForce false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user