refactor: Move sw into properly nested modules with unconditional import #30
@@ -79,3 +79,39 @@ jobs:
|
|||||||
echo "Evaluating artifact ${{ matrix.artifact }}"
|
echo "Evaluating artifact ${{ matrix.artifact }}"
|
||||||
nix eval .#${{ matrix.artifact }}.drvPath \
|
nix eval .#${{ matrix.artifact }}.drvPath \
|
||||||
--show-trace
|
--show-trace
|
||||||
|
|
||||||
|
build-docs:
|
||||||
|
name: Build and Publish Documentation
|
||||||
|
runs-on: [self-hosted, nix-builder]
|
||||||
|
needs: [flake-check]
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build documentation
|
||||||
|
run: |
|
||||||
|
echo "Building Athenix documentation"
|
||||||
|
nix build .#docs --print-build-logs
|
||||||
|
|
||||||
|
- name: Clone wiki repository
|
||||||
|
run: |
|
||||||
|
git clone https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.wiki.git wiki
|
||||||
|
cd wiki
|
||||||
|
git config user.name "Athenix CI"
|
||||||
|
git config user.email "ci@athenix.factory.uga.edu"
|
||||||
|
|
||||||
|
- name: Update wiki with documentation
|
||||||
|
run: |
|
||||||
|
# Copy documentation to wiki
|
||||||
|
cp -r result/* wiki/
|
||||||
|
|
||||||
|
# Commit and push changes
|
||||||
|
cd wiki
|
||||||
|
git add .
|
||||||
|
if git diff --staged --quiet; then
|
||||||
|
echo "No documentation changes to commit"
|
||||||
|
else
|
||||||
|
git commit -m "Update documentation from commit ${{ github.sha }}"
|
||||||
|
git push
|
||||||
|
fi
|
||||||
|
|||||||
34
.github/workflows/docs.yml
vendored
Normal file
34
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: Build Documentation
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-docs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: DeterminateSystems/nix-installer-action@main
|
||||||
|
|
||||||
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
|
|
||||||
|
- name: Build documentation
|
||||||
|
run: |
|
||||||
|
nix build .#docs
|
||||||
|
nix build .#athenix-options
|
||||||
|
|
||||||
|
- name: Upload documentation
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: athenix-docs
|
||||||
|
path: result/
|
||||||
|
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
uses: peaceiris/actions-gh-pages@v4
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
publish_dir: ./result
|
||||||
18
.nixd.json
Normal file
18
.nixd.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"eval": {
|
||||||
|
"target": {
|
||||||
|
"installable": ".#nixosConfigurations.nix-desktop1.options"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"formatting": {
|
||||||
|
"command": ["nixfmt"]
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"nixos": {
|
||||||
|
"expr": "(builtins.getFlake \"/home/engr-ugaif/athenix\").nixosConfigurations.nix-desktop1.options"
|
||||||
|
},
|
||||||
|
"home-manager": {
|
||||||
|
"expr": "(builtins.getFlake \"/home/engr-ugaif/athenix\").nixosConfigurations.nix-desktop1.config.home-manager.users.engr-ugaif.options"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -80,6 +80,7 @@
|
|||||||
./parts/nixos-modules.nix
|
./parts/nixos-modules.nix
|
||||||
./parts/packages.nix
|
./parts/packages.nix
|
||||||
./parts/templates.nix
|
./parts/templates.nix
|
||||||
|
./parts/docs.nix
|
||||||
./inventory.nix
|
./inventory.nix
|
||||||
./users.nix
|
./users.nix
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -24,14 +24,28 @@
|
|||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
Convenience option to configure a host for a specific user.
|
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.
|
When set, automatically:
|
||||||
|
- Enables the user account (athenix.users.<username>.enable = true)
|
||||||
|
- Sets as default WSL user (on WSL systems)
|
||||||
|
|
||||||
|
The username must exist in athenix.users (defined in users.nix).
|
||||||
'';
|
'';
|
||||||
|
example = "engr-ugaif";
|
||||||
};
|
};
|
||||||
host.useHostPrefix = lib.mkOption {
|
host.useHostPrefix = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Whether to prepend the host prefix to the hostname (used in inventory and hosts/default.nix).";
|
description = ''
|
||||||
|
Whether to prepend the hardware type prefix to the hostname.
|
||||||
|
|
||||||
|
When true:
|
||||||
|
- "nix-laptop" with device "1" → hostname "nix-laptop1"
|
||||||
|
- "nix-wsl" with device "alice" → hostname "nix-wsl-alice"
|
||||||
|
|
||||||
|
When false:
|
||||||
|
- Device name becomes the full hostname (useful for custom names)
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Fleet Option Definition
|
# Fleet Option Definition
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# This module only defines the athenix.fleet option without any dependencies.
|
# This module defines the athenix.fleet and athenix.hwTypes options.
|
||||||
# Used by fleet/default.nix to evaluate inventory data without circular dependencies.
|
# Self-contained fleet management without dependencies on user configuration.
|
||||||
{ inputs, lib, ... }:
|
{ inputs, lib, ... }:
|
||||||
let
|
let
|
||||||
fleetDefinition = lib.mkOption {
|
fleetDefinition = lib.mkOption {
|
||||||
@@ -59,40 +59,67 @@ let
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
# Submodule defining the structure of a user account
|
|
||||||
|
# Forward declaration for user options (full definition in user-config.nix)
|
||||||
|
# This allows users.nix to be evaluated at flake level
|
||||||
userSubmodule = lib.types.submodule {
|
userSubmodule = lib.types.submodule {
|
||||||
options = {
|
options = {
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether this user account is enabled on this system.";
|
||||||
|
};
|
||||||
isNormalUser = lib.mkOption {
|
isNormalUser = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
|
description = "Whether this is a normal user account (vs system user).";
|
||||||
};
|
};
|
||||||
description = lib.mkOption {
|
description = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = null;
|
default = null;
|
||||||
|
description = "Full name or description of the user (GECOS field).";
|
||||||
|
example = "John Doe";
|
||||||
};
|
};
|
||||||
extraGroups = lib.mkOption {
|
extraGroups = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
description = "Additional groups for the user (wheel, docker, etc.).";
|
||||||
|
example = [
|
||||||
|
"wheel"
|
||||||
|
"networkmanager"
|
||||||
|
"docker"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
hashedPassword = lib.mkOption {
|
hashedPassword = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "!";
|
default = "!";
|
||||||
|
description = ''
|
||||||
|
Hashed password for the user account.
|
||||||
|
Generate with: mkpasswd -m sha-512
|
||||||
|
Default "!" means account is locked (SSH key only).
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
extraPackages = lib.mkOption {
|
extraPackages = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.package;
|
type = lib.types.listOf lib.types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
description = "Additional system packages available to this user.";
|
||||||
|
example = lib.literalExpression "[ pkgs.vim pkgs.git ]";
|
||||||
};
|
};
|
||||||
excludePackages = lib.mkOption {
|
excludePackages = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.package;
|
type = lib.types.listOf lib.types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
description = "System packages to exclude for this user.";
|
||||||
};
|
};
|
||||||
homePackages = lib.mkOption {
|
homePackages = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.package;
|
type = lib.types.listOf lib.types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
description = "Packages to install in the user's home-manager profile.";
|
||||||
|
example = lib.literalExpression "[ pkgs.firefox pkgs.vscode ]";
|
||||||
};
|
};
|
||||||
extraImports = lib.mkOption {
|
extraImports = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.path;
|
type = lib.types.listOf lib.types.path;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
description = "Additional home-manager modules to import for this user.";
|
||||||
};
|
};
|
||||||
external = lib.mkOption {
|
external = lib.mkOption {
|
||||||
type = lib.types.nullOr (
|
type = lib.types.nullOr (
|
||||||
@@ -104,21 +131,22 @@ let
|
|||||||
);
|
);
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
External user configuration module. Can be:
|
External user configuration module from Git or local path.
|
||||||
- A path to a local module directory
|
|
||||||
- A fetchGit/fetchTarball result pointing to a repository
|
|
||||||
|
|
||||||
The external module can contain:
|
Should contain user.nix (user options + home-manager config)
|
||||||
- user.nix (optional): Sets athenix.users.<name> options AND home-manager config
|
and optionally nixos.nix (system-level config).
|
||||||
- nixos.nix (optional): System-level NixOS configuration
|
|
||||||
|
|
||||||
Example: builtins.fetchGit { url = "https://github.com/user/dotfiles"; rev = "..."; }
|
|
||||||
'';
|
'';
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
builtins.fetchGit {
|
||||||
|
url = "https://github.com/username/dotfiles";
|
||||||
|
rev = "abc123...";
|
||||||
|
}'';
|
||||||
};
|
};
|
||||||
opensshKeys = lib.mkOption {
|
opensshKeys = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = "List of SSH public keys for the user.";
|
description = "SSH public keys for the user (authorized_keys).";
|
||||||
|
example = [ "ssh-ed25519 AAAAC3Nza... user@host" ];
|
||||||
};
|
};
|
||||||
shell = lib.mkOption {
|
shell = lib.mkOption {
|
||||||
type = lib.types.nullOr (
|
type = lib.types.nullOr (
|
||||||
@@ -130,7 +158,7 @@ let
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
default = "bash";
|
default = "bash";
|
||||||
description = "The shell for this user.";
|
description = "Default shell for the user.";
|
||||||
};
|
};
|
||||||
editor = lib.mkOption {
|
editor = lib.mkOption {
|
||||||
type = lib.types.nullOr (
|
type = lib.types.nullOr (
|
||||||
@@ -143,23 +171,18 @@ let
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
default = "neovim";
|
default = "neovim";
|
||||||
description = "The default editor for this user.";
|
description = "Default text editor for the user (sets EDITOR).";
|
||||||
};
|
};
|
||||||
useZshTheme = lib.mkOption {
|
useZshTheme = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Whether to apply the system Zsh theme.";
|
description = "Whether to apply the system Zsh theme (Oh My Posh).";
|
||||||
};
|
};
|
||||||
useNvimPlugins = lib.mkOption {
|
useNvimPlugins = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Whether to apply the system Neovim configuration.";
|
description = "Whether to apply the system Neovim configuration.";
|
||||||
};
|
};
|
||||||
enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Whether this user account is enabled on this system.";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
|||||||
27
fleet/fs.nix
27
fleet/fs.nix
@@ -13,17 +13,38 @@
|
|||||||
device = lib.mkOption {
|
device = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = null;
|
default = null;
|
||||||
description = "The main disk device to use for installation.";
|
description = ''
|
||||||
|
The main disk device to use for automated partitioning and installation.
|
||||||
|
|
||||||
|
When set, enables disko for declarative disk management with:
|
||||||
|
- 1GB EFI boot partition
|
||||||
|
- Optional swap partition (see swapSize)
|
||||||
|
- Root partition using remaining space
|
||||||
|
|
||||||
|
Leave null for systems that don't need disk partitioning (containers, WSL).
|
||||||
|
'';
|
||||||
|
example = "/dev/nvme0n1";
|
||||||
};
|
};
|
||||||
useSwap = lib.mkOption {
|
useSwap = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Whether to create and use a swap partition.";
|
description = ''
|
||||||
|
Whether to create and use a swap partition.
|
||||||
|
Disable for systems with ample RAM or SSDs where swap is undesirable.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
swapSize = lib.mkOption {
|
swapSize = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = null;
|
default = null;
|
||||||
description = "The size of the swap partition.";
|
description = ''
|
||||||
|
Size of the swap partition (e.g., "16G", "32G").
|
||||||
|
|
||||||
|
Recommended sizes:
|
||||||
|
- 8-16GB for desktops with 16GB+ RAM
|
||||||
|
- 32GB for laptops (enables hibernation)
|
||||||
|
- Match RAM size for systems <8GB RAM
|
||||||
|
'';
|
||||||
|
example = "32G";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,9 +9,8 @@
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
# User Configuration Module
|
# User Configuration Module
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# This module defines the schema for user accounts and handles their creation.
|
# This module implements user account creation and home-manager setup.
|
||||||
# It bridges the gap between the data in 'users.nix' and the actual NixOS
|
# Options are defined in fleet-option.nix for early availability.
|
||||||
# and Home Manager configuration.
|
|
||||||
|
|
||||||
let
|
let
|
||||||
# Helper: Resolve external module path from fetchGit/fetchTarball/path
|
# Helper: Resolve external module path from fetchGit/fetchTarball/path
|
||||||
|
|||||||
@@ -46,5 +46,5 @@
|
|||||||
|
|
||||||
# ========== Software Profile ==========
|
# ========== Software Profile ==========
|
||||||
athenix.sw.enable = lib.mkDefault true;
|
athenix.sw.enable = lib.mkDefault true;
|
||||||
athenix.sw.type = lib.mkDefault "desktop";
|
athenix.sw.desktop.enable = lib.mkDefault true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,5 @@
|
|||||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
|
||||||
athenix.sw.enable = lib.mkDefault true;
|
athenix.sw.enable = lib.mkDefault true;
|
||||||
athenix.sw.type = lib.mkDefault "stateless-kiosk";
|
athenix.sw.stateless-kiosk.enable = lib.mkDefault true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,5 +59,5 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
athenix.sw.enable = lib.mkDefault true;
|
athenix.sw.enable = lib.mkDefault true;
|
||||||
athenix.sw.type = lib.mkDefault "desktop";
|
athenix.sw.desktop.enable = lib.mkDefault true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,5 +56,5 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
athenix.sw.enable = lib.mkDefault true;
|
athenix.sw.enable = lib.mkDefault true;
|
||||||
athenix.sw.type = lib.mkDefault "headless";
|
athenix.sw.headless.enable = lib.mkDefault true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,5 +65,5 @@ in
|
|||||||
|
|
||||||
# ========== Software Profile ==========
|
# ========== Software Profile ==========
|
||||||
athenix.sw.enable = lib.mkDefault true;
|
athenix.sw.enable = lib.mkDefault true;
|
||||||
athenix.sw.type = lib.mkDefault "tablet-kiosk"; # Touch-optimized kiosk mode
|
athenix.sw.tablet-kiosk.enable = lib.mkDefault true; # Touch-optimized kiosk mode
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,13 @@
|
|||||||
options.athenix.host.wsl.user = lib.mkOption {
|
options.athenix.host.wsl.user = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "engr-ugaif";
|
default = "engr-ugaif";
|
||||||
description = "The default user to log in as in WSL.";
|
description = ''
|
||||||
|
The default user to automatically log in as when starting WSL.
|
||||||
|
|
||||||
|
This user must be enabled via athenix.users.<username>.enable = true.
|
||||||
|
Tip: Use athenix.forUser = "username" as a shortcut to set both.
|
||||||
|
'';
|
||||||
|
example = "alice";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
@@ -32,7 +38,7 @@
|
|||||||
|
|
||||||
# ========== Software Profile ==========
|
# ========== Software Profile ==========
|
||||||
athenix.sw.enable = lib.mkDefault true;
|
athenix.sw.enable = lib.mkDefault true;
|
||||||
athenix.sw.type = lib.mkDefault "headless";
|
athenix.sw.headless.enable = lib.mkDefault true;
|
||||||
|
|
||||||
# ========== Remote Development ==========
|
# ========== Remote Development ==========
|
||||||
services.vscode-server.enable = true;
|
services.vscode-server.enable = true;
|
||||||
|
|||||||
@@ -45,5 +45,5 @@
|
|||||||
|
|
||||||
# ========== Software Profile ==========
|
# ========== Software Profile ==========
|
||||||
athenix.sw.enable = lib.mkDefault true;
|
athenix.sw.enable = lib.mkDefault true;
|
||||||
athenix.sw.type = lib.mkDefault "desktop";
|
athenix.sw.desktop.enable = lib.mkDefault true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
# Software configuration module - main module with all athenix.sw options
|
# Software configuration module - main module with all athenix.sw options
|
||||||
# Use athenix.sw.type to select profile: "desktop", "tablet-kiosk", "headless", "stateless-kiosk"
|
# Use athenix.sw.<type>.enable to enable software profiles: desktop, tablet-kiosk, headless, stateless-kiosk, builders
|
||||||
hw = hostTypes;
|
hw = hostTypes;
|
||||||
sw =
|
sw =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,10 +92,10 @@
|
|||||||
nix-surface = {
|
nix-surface = {
|
||||||
defaultCount = 3;
|
defaultCount = 3;
|
||||||
devices = {
|
devices = {
|
||||||
"1".athenix.sw.kioskUrl = "https://google.com";
|
"1".athenix.sw.tablet-kiosk.kioskUrl = "https://google.com";
|
||||||
};
|
};
|
||||||
overrides = {
|
overrides = {
|
||||||
athenix.sw.kioskUrl = "https://yahoo.com";
|
athenix.sw.tablet-kiosk.kioskUrl = "https://yahoo.com";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,11 +106,10 @@
|
|||||||
"nix-builder" = {
|
"nix-builder" = {
|
||||||
# Gitea Actions self-hosted runner configuration
|
# Gitea Actions self-hosted runner configuration
|
||||||
athenix.sw = {
|
athenix.sw = {
|
||||||
type = [
|
headless.enable = true;
|
||||||
"headless"
|
builders = {
|
||||||
"builders"
|
enable = true;
|
||||||
];
|
giteaRunner = {
|
||||||
builders.giteaRunner = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
url = "https://git.factory.uga.edu";
|
url = "https://git.factory.uga.edu";
|
||||||
# Token file must be created manually at this path with a Gitea runner token
|
# Token file must be created manually at this path with a Gitea runner token
|
||||||
@@ -127,6 +126,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
"usda-dash".external = 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";
|
||||||
|
|||||||
132
parts/docs.nix
Normal file
132
parts/docs.nix
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Documentation generation
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
self,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
|
||||||
|
|
||||||
|
# Extract options from a sample configuration
|
||||||
|
getAthenixOptions =
|
||||||
|
configName:
|
||||||
|
let
|
||||||
|
nixosConfig = self.nixosConfigurations.${configName};
|
||||||
|
evaledOptions = nixosConfig.options;
|
||||||
|
|
||||||
|
# Filter to just athenix namespace
|
||||||
|
athenixOptions = evaledOptions.athenix or { };
|
||||||
|
in
|
||||||
|
athenixOptions;
|
||||||
|
|
||||||
|
# Generate markdown documentation from options
|
||||||
|
optionsToMarkdown =
|
||||||
|
options:
|
||||||
|
pkgs.writeText "options.md" ''
|
||||||
|
# Athenix Configuration Options
|
||||||
|
|
||||||
|
This document describes all available configuration options in the Athenix namespace.
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
- **athenix.sw** - Software configuration (desktop, headless, kiosk modes)
|
||||||
|
- **athenix.users** - User account management
|
||||||
|
- **athenix.host** - Host-specific settings (filesystem, build methods)
|
||||||
|
- **athenix.fleet** - Fleet inventory definitions
|
||||||
|
- **athenix.forUser** - Convenience option to enable a user
|
||||||
|
- **athenix.system.gc** - Garbage collection settings
|
||||||
|
|
||||||
|
## Detailed Options
|
||||||
|
|
||||||
|
For detailed option information, use:
|
||||||
|
```bash
|
||||||
|
# View all athenix options
|
||||||
|
nix eval .#nixosConfigurations.nix-desktop1.options.athenix --apply builtins.attrNames
|
||||||
|
|
||||||
|
# View specific option description
|
||||||
|
nix eval .#nixosConfigurations.nix-desktop1.options.athenix.sw.desktop.enable.description
|
||||||
|
|
||||||
|
# Export all options to JSON
|
||||||
|
nix build .#athenix-options
|
||||||
|
cat result | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
## Software Types
|
||||||
|
|
||||||
|
Enable different system configurations:
|
||||||
|
|
||||||
|
- **desktop** - Full KDE Plasma desktop environment
|
||||||
|
- **headless** - Server/container configuration
|
||||||
|
- **tablet-kiosk** - Touch-optimized kiosk for tablets
|
||||||
|
- **stateless-kiosk** - Diskless PXE boot kiosk
|
||||||
|
- **builders** - Build server with optional Gitea Actions runner
|
||||||
|
|
||||||
|
See the individual option descriptions for detailed information.
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{ system, ... }:
|
||||||
|
lib.mkIf (system == "x86_64-linux") {
|
||||||
|
packages = {
|
||||||
|
# Generate option documentation in markdown
|
||||||
|
docs =
|
||||||
|
pkgs.runCommand "athenix-docs"
|
||||||
|
{
|
||||||
|
nativeBuildInputs = [ pkgs.jq ];
|
||||||
|
}
|
||||||
|
''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
# Copy existing documentation
|
||||||
|
${if builtins.pathExists ../README.md then "cp ${../README.md} $out/README.md" else ""}
|
||||||
|
${if builtins.pathExists ../docs then "cp -r ${../docs} $out/guides" else ""}
|
||||||
|
|
||||||
|
# Generate options reference
|
||||||
|
cat > $out/OPTIONS.md << 'EOF'
|
||||||
|
${builtins.readFile (optionsToMarkdown (getAthenixOptions "nix-desktop1"))}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Documentation generated in $out"
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Extract just the athenix namespace options as JSON
|
||||||
|
athenix-options =
|
||||||
|
let
|
||||||
|
nixosConfig =
|
||||||
|
self.nixosConfigurations.nix-desktop1
|
||||||
|
or (builtins.head (builtins.attrValues self.nixosConfigurations));
|
||||||
|
|
||||||
|
# Recursively extract option information
|
||||||
|
extractOption =
|
||||||
|
opt:
|
||||||
|
if opt ? _type && opt._type == "option" then
|
||||||
|
{
|
||||||
|
inherit (opt) description;
|
||||||
|
type = opt.type.description or (opt.type.name or "unknown");
|
||||||
|
default =
|
||||||
|
if opt ? default then
|
||||||
|
if builtins.isAttrs opt.default && opt.default ? _type then "<special>" else opt.default
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
example =
|
||||||
|
if opt ? example then
|
||||||
|
if builtins.isAttrs opt.example && opt.example ? _type then "<special>" else opt.example
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
}
|
||||||
|
else if builtins.isAttrs opt then
|
||||||
|
lib.mapAttrs (name: value: extractOption value) (
|
||||||
|
# Filter out internal attributes
|
||||||
|
lib.filterAttrs (n: _: !lib.hasPrefix "_" n) opt
|
||||||
|
)
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
|
||||||
|
athenixOpts = nixosConfig.options.athenix or { };
|
||||||
|
in
|
||||||
|
pkgs.writeText "athenix-options.json" (builtins.toJSON (extractOption athenixOpts));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -11,7 +11,96 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
lib.mkMerge [
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.athenix.sw.builders;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.athenix.sw.builders = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable build server configuration.
|
||||||
|
|
||||||
|
Includes:
|
||||||
|
- SSH host keys for common Git servers (factory.uga.edu, github.com)
|
||||||
|
- Gitea Actions runner support (optional)
|
||||||
|
- Build tools and dependencies
|
||||||
|
|
||||||
|
Recommended for: CI/CD servers, build containers, development infrastructure
|
||||||
|
'';
|
||||||
|
example = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
giteaRunner = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable Gitea Actions self-hosted runner.
|
||||||
|
|
||||||
|
This runner will connect to a Gitea instance and execute CI/CD workflows.
|
||||||
|
Requires manual setup of the token file before the service will start.
|
||||||
|
'';
|
||||||
|
example = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
url = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
URL of the Gitea instance to connect to.
|
||||||
|
This should be the base URL without any path components.
|
||||||
|
'';
|
||||||
|
example = "https://git.factory.uga.edu";
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/gitea-runner-token";
|
||||||
|
description = ''
|
||||||
|
Path to file containing Gitea runner registration token.
|
||||||
|
|
||||||
|
To generate:
|
||||||
|
1. Go to your Gitea repository settings
|
||||||
|
2. Navigate to Actions > Runners
|
||||||
|
3. Click "Create new Runner"
|
||||||
|
4. Save the token to this file:
|
||||||
|
echo "TOKEN=your-token-here" | sudo tee /var/lib/gitea-runner-token > /dev/null
|
||||||
|
|
||||||
|
The service will not start until this file exists.
|
||||||
|
'';
|
||||||
|
example = "/var/secrets/gitea-runner-token";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraLabels = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = ''
|
||||||
|
Additional labels to identify this runner in workflow files.
|
||||||
|
Use labels to target specific runners for different job types.
|
||||||
|
'';
|
||||||
|
example = [
|
||||||
|
"self-hosted"
|
||||||
|
"nix"
|
||||||
|
"x86_64-linux"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "athenix";
|
||||||
|
description = ''
|
||||||
|
Unique name for this runner instance.
|
||||||
|
Shown in Gitea's runner list and logs.
|
||||||
|
'';
|
||||||
|
example = "nix-builder-1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [
|
||||||
(import ./programs.nix {
|
(import ./programs.nix {
|
||||||
inherit
|
inherit
|
||||||
config
|
config
|
||||||
@@ -28,4 +117,5 @@ lib.mkMerge [
|
|||||||
inputs
|
inputs
|
||||||
;
|
;
|
||||||
})
|
})
|
||||||
]
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
|
||||||
inputs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
@@ -10,7 +8,7 @@ with lib;
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.athenix.sw;
|
cfg = config.athenix.sw;
|
||||||
basePackages = with pkgs; [
|
basePackages = [
|
||||||
# Build-related packages can be added here if needed
|
# Build-related packages can be added here if needed
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
|
|||||||
169
sw/default.nix
169
sw/default.nix
@@ -10,19 +10,14 @@
|
|||||||
# Software Module Entry Point
|
# Software Module Entry Point
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# This module manages the software configuration for the system. It provides
|
# This module manages the software configuration for the system. It provides
|
||||||
# options to select the system type ('desktop' or 'kiosk') and handles
|
# enable options for each system type (desktop, headless, builders, etc.)
|
||||||
# the conditional importation of the appropriate sub-modules.
|
# that can be enabled independently or in combination. Each type is a proper
|
||||||
|
# NixOS submodule with its own enable flag and type-specific options.
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.athenix.sw;
|
cfg = config.athenix.sw;
|
||||||
|
|
||||||
# Normalize type to always be a list
|
|
||||||
swTypes = if isList cfg.type then cfg.type else [ cfg.type ];
|
|
||||||
|
|
||||||
# Helper to check if a type is enabled
|
|
||||||
hasType = type: elem type swTypes;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
@@ -31,98 +26,64 @@ in
|
|||||||
./gc.nix
|
./gc.nix
|
||||||
./updater.nix
|
./updater.nix
|
||||||
./update-ref.nix
|
./update-ref.nix
|
||||||
|
./desktop
|
||||||
|
./headless
|
||||||
|
./builders
|
||||||
|
./tablet-kiosk
|
||||||
|
./stateless-kiosk
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
inputs.agenix.nixosModules.default
|
inputs.agenix.nixosModules.default
|
||||||
inputs.disko.nixosModules.disko
|
inputs.disko.nixosModules.disko
|
||||||
];
|
];
|
||||||
|
|
||||||
options.athenix.sw = {
|
options.athenix.sw = {
|
||||||
enable = mkEnableOption "Standard Workstation Configuration";
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable standard workstation configuration with base packages.
|
||||||
|
|
||||||
|
Provides:
|
||||||
|
- Base CLI tools (htop, git, binutils)
|
||||||
|
- Shell configuration (Zsh)
|
||||||
|
- Secret management (agenix)
|
||||||
|
- Oh My Posh shell theme
|
||||||
|
|
||||||
|
This is typically enabled automatically when any sw type is enabled.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# DEPRECATED: Backwards compatibility for external modules
|
||||||
|
# Use athenix.sw.<type>.enable instead
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
type = types.oneOf [
|
type = types.nullOr (types.either types.str (types.listOf types.str));
|
||||||
(types.enum [
|
default = null;
|
||||||
"desktop"
|
description = "DEPRECATED: Use athenix.sw.<type>.enable instead. Legacy type selection.";
|
||||||
"tablet-kiosk"
|
visible = false;
|
||||||
"headless"
|
|
||||||
"stateless-kiosk"
|
|
||||||
"builders"
|
|
||||||
])
|
|
||||||
(types.listOf (
|
|
||||||
types.enum [
|
|
||||||
"desktop"
|
|
||||||
"tablet-kiosk"
|
|
||||||
"headless"
|
|
||||||
"stateless-kiosk"
|
|
||||||
"builders"
|
|
||||||
]
|
|
||||||
))
|
|
||||||
];
|
|
||||||
default = "desktop";
|
|
||||||
description = "Type(s) of system configuration. Can be a single type or a list of types to combine multiple configurations.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extraPackages = mkOption {
|
extraPackages = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = "Extra packages to install.";
|
description = ''
|
||||||
|
Additional system packages to install beyond the defaults.
|
||||||
|
These packages are added to environment.systemPackages.
|
||||||
|
'';
|
||||||
|
example = lib.literalExpression "[ pkgs.vim pkgs.wget pkgs.curl ]";
|
||||||
};
|
};
|
||||||
|
|
||||||
excludePackages = mkOption {
|
excludePackages = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = "Packages to exclude from the default list.";
|
|
||||||
};
|
|
||||||
|
|
||||||
kioskUrl = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "https://ha.factory.uga.edu";
|
|
||||||
description = "URL to open in Chromium kiosk mode.";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Builders-specific options
|
|
||||||
builders = mkOption {
|
|
||||||
type = types.submodule {
|
|
||||||
options = {
|
|
||||||
giteaRunner = {
|
|
||||||
enable = mkEnableOption "Gitea Actions self-hosted runner";
|
|
||||||
|
|
||||||
url = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "Gitea instance URL for the runner";
|
|
||||||
};
|
|
||||||
|
|
||||||
tokenFile = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
default = "/var/lib/gitea-runner-token";
|
|
||||||
description = ''
|
description = ''
|
||||||
Path to file containing Gitea runner token.
|
Packages to exclude from the default package list.
|
||||||
Generate in Gitea repository settings under Actions > Runners.
|
Useful for removing unwanted default packages.
|
||||||
The token must have runner registration access.
|
|
||||||
'';
|
'';
|
||||||
};
|
example = lib.literalExpression "[ pkgs.htop ]";
|
||||||
|
|
||||||
extraLabels = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Extra labels to identify this runner in workflows";
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "athenix";
|
|
||||||
description = "Name of the Gitea runner service";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { };
|
|
||||||
description = "Builder-specific configuration options";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (mkMerge [
|
config = mkIf cfg.enable {
|
||||||
{
|
|
||||||
# ========== System-Wide Configuration ==========
|
# ========== System-Wide Configuration ==========
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
@@ -143,57 +104,5 @@ in
|
|||||||
age-plugin-fido2-hmac # age FIDO2 support
|
age-plugin-fido2-hmac # age FIDO2 support
|
||||||
inputs.agenix.packages.${stdenv.hostPlatform.system}.default # Secret management
|
inputs.agenix.packages.${stdenv.hostPlatform.system}.default # Secret management
|
||||||
];
|
];
|
||||||
}
|
};
|
||||||
# ========== Software Profile Imports ==========
|
|
||||||
(mkIf (hasType "desktop") (
|
|
||||||
import ./desktop {
|
|
||||||
inherit
|
|
||||||
config
|
|
||||||
lib
|
|
||||||
pkgs
|
|
||||||
inputs
|
|
||||||
;
|
|
||||||
}
|
|
||||||
))
|
|
||||||
(mkIf (hasType "tablet-kiosk") (
|
|
||||||
import ./tablet-kiosk {
|
|
||||||
inherit
|
|
||||||
config
|
|
||||||
lib
|
|
||||||
pkgs
|
|
||||||
inputs
|
|
||||||
;
|
|
||||||
}
|
|
||||||
))
|
|
||||||
(mkIf (hasType "headless") (
|
|
||||||
import ./headless {
|
|
||||||
inherit
|
|
||||||
config
|
|
||||||
lib
|
|
||||||
pkgs
|
|
||||||
inputs
|
|
||||||
;
|
|
||||||
}
|
|
||||||
))
|
|
||||||
(mkIf (hasType "stateless-kiosk") (
|
|
||||||
import ./stateless-kiosk {
|
|
||||||
inherit
|
|
||||||
config
|
|
||||||
lib
|
|
||||||
pkgs
|
|
||||||
inputs
|
|
||||||
;
|
|
||||||
}
|
|
||||||
))
|
|
||||||
(mkIf (hasType "builders") (
|
|
||||||
import ./builders {
|
|
||||||
inherit
|
|
||||||
config
|
|
||||||
lib
|
|
||||||
pkgs
|
|
||||||
inputs
|
|
||||||
;
|
|
||||||
}
|
|
||||||
))
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,35 @@
|
|||||||
inputs,
|
inputs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
lib.mkMerge [
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.athenix.sw.desktop;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.athenix.sw.desktop = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable full desktop environment with KDE Plasma 6.
|
||||||
|
|
||||||
|
Includes:
|
||||||
|
- KDE Plasma 6 desktop with SDDM display manager
|
||||||
|
- Full graphical software suite (Firefox, Chromium, LibreOffice)
|
||||||
|
- Printing and scanning support (CUPS)
|
||||||
|
- Virtualization (libvirt, virt-manager)
|
||||||
|
- Bluetooth and audio (PipeWire)
|
||||||
|
- Video conferencing (Zoom, Teams)
|
||||||
|
|
||||||
|
Recommended for: Workstations, development machines, user desktops
|
||||||
|
'';
|
||||||
|
example = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [
|
||||||
(import ./programs.nix {
|
(import ./programs.nix {
|
||||||
inherit
|
inherit
|
||||||
config
|
config
|
||||||
@@ -27,4 +55,5 @@ lib.mkMerge [
|
|||||||
inputs
|
inputs
|
||||||
;
|
;
|
||||||
})
|
})
|
||||||
]
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
inputs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
|
|||||||
27
sw/gc.nix
27
sw/gc.nix
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
@@ -10,22 +9,40 @@
|
|||||||
enable = lib.mkOption {
|
enable = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Whether to enable automatic garbage collection.";
|
description = ''
|
||||||
|
Enable automatic garbage collection of old NixOS generations.
|
||||||
|
Helps keep disk usage under control on long-running systems.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
frequency = lib.mkOption {
|
frequency = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "weekly";
|
default = "weekly";
|
||||||
description = "How often to run garbage collection (systemd timer format).";
|
description = ''
|
||||||
|
How often to run garbage collection (systemd timer format).
|
||||||
|
|
||||||
|
Common values: "daily", "weekly", "monthly"
|
||||||
|
Advanced: "*-*-* 03:00:00" (daily at 3 AM)
|
||||||
|
'';
|
||||||
|
example = "daily";
|
||||||
};
|
};
|
||||||
retentionDays = lib.mkOption {
|
retentionDays = lib.mkOption {
|
||||||
type = lib.types.int;
|
type = lib.types.int;
|
||||||
default = 30;
|
default = 30;
|
||||||
description = "Number of days to keep old generations before deletion.";
|
description = ''
|
||||||
|
Number of days to keep old system generations before deletion.
|
||||||
|
|
||||||
|
Older generations allow rolling back system changes.
|
||||||
|
Recommended: 30-90 days for workstations, 7-14 for servers.
|
||||||
|
'';
|
||||||
|
example = 60;
|
||||||
};
|
};
|
||||||
optimise = lib.mkOption {
|
optimise = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Whether to automatically optimize the Nix store.";
|
description = ''
|
||||||
|
Whether to automatically hard-link identical files in the Nix store.
|
||||||
|
Can save significant disk space but uses CPU during optimization.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|||||||
@@ -11,7 +11,32 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
lib.mkMerge [
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.athenix.sw.headless;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.athenix.sw.headless = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable minimal headless server configuration.
|
||||||
|
|
||||||
|
Includes:
|
||||||
|
- SSH server with password authentication
|
||||||
|
- Minimal CLI tools (tmux, man)
|
||||||
|
- Systemd-networkd for networking
|
||||||
|
- No graphical environment
|
||||||
|
|
||||||
|
Recommended for: Servers, containers (LXC), WSL, remote systems
|
||||||
|
'';
|
||||||
|
example = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [
|
||||||
(import ./programs.nix {
|
(import ./programs.nix {
|
||||||
inherit
|
inherit
|
||||||
config
|
config
|
||||||
@@ -28,4 +53,5 @@ lib.mkMerge [
|
|||||||
inputs
|
inputs
|
||||||
;
|
;
|
||||||
})
|
})
|
||||||
]
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
inputs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,46 @@
|
|||||||
inputs,
|
inputs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
lib.mkMerge [
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.athenix.sw.stateless-kiosk;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.athenix.sw.stateless-kiosk = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable stateless kiosk mode for diskless PXE boot systems.
|
||||||
|
|
||||||
|
Includes:
|
||||||
|
- Sway (Wayland compositor)
|
||||||
|
- Chromium in fullscreen kiosk mode
|
||||||
|
- MAC address-based URL routing
|
||||||
|
- Network-only boot (no local storage)
|
||||||
|
- Auto-start browser on boot
|
||||||
|
|
||||||
|
Recommended for: Assembly line stations, diskless kiosks, PXE boot displays
|
||||||
|
'';
|
||||||
|
example = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
kioskUrl = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "https://ha.factory.uga.edu";
|
||||||
|
description = ''
|
||||||
|
Default URL to display in the kiosk browser.
|
||||||
|
|
||||||
|
Note: For stateless-kiosk, MAC address-based routing may override this.
|
||||||
|
See sw/stateless-kiosk/mac-hostmap.nix for MAC-to-URL mappings.
|
||||||
|
'';
|
||||||
|
example = "https://homeassistant.lan:8123/lovelace/dashboard";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [
|
||||||
(import ./kiosk-browser.nix {
|
(import ./kiosk-browser.nix {
|
||||||
inherit
|
inherit
|
||||||
config
|
config
|
||||||
@@ -40,4 +79,5 @@ lib.mkMerge [
|
|||||||
inputs
|
inputs
|
||||||
;
|
;
|
||||||
})
|
})
|
||||||
]
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# This module configures Chromium for kiosk mode under Sway.
|
# This module configures Chromium for kiosk mode under Sway.
|
||||||
# It includes a startup script that determines the kiosk URL based on the machine's MAC address.
|
# It includes a startup script that determines the kiosk URL based on the machine's MAC address.
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -5,7 +5,45 @@
|
|||||||
inputs,
|
inputs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
lib.mkMerge [
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.athenix.sw.tablet-kiosk;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.athenix.sw.tablet-kiosk = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable tablet kiosk mode with touch-optimized interface.
|
||||||
|
|
||||||
|
Includes:
|
||||||
|
- Phosh mobile desktop environment
|
||||||
|
- Chromium in fullscreen kiosk mode
|
||||||
|
- On-screen keyboard (Squeekboard)
|
||||||
|
- Auto-login and auto-start browser
|
||||||
|
- Touch gesture support
|
||||||
|
- Optimized for Surface Pro tablets
|
||||||
|
|
||||||
|
Recommended for: Surface tablets, touchscreen kiosks, interactive displays
|
||||||
|
'';
|
||||||
|
example = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
kioskUrl = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "https://ha.factory.uga.edu";
|
||||||
|
description = ''
|
||||||
|
URL to display in the kiosk browser on startup.
|
||||||
|
The browser will automatically navigate to this URL in fullscreen mode.
|
||||||
|
'';
|
||||||
|
example = "https://dashboard.example.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [
|
||||||
(import ./programs.nix {
|
(import ./programs.nix {
|
||||||
inherit
|
inherit
|
||||||
config
|
config
|
||||||
@@ -30,4 +68,5 @@ lib.mkMerge [
|
|||||||
inputs
|
inputs
|
||||||
;
|
;
|
||||||
})
|
})
|
||||||
]
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -155,7 +155,7 @@
|
|||||||
--noerrdialogs \
|
--noerrdialogs \
|
||||||
--disable-session-crashed-bubble \
|
--disable-session-crashed-bubble \
|
||||||
--disable-infobars \
|
--disable-infobars \
|
||||||
${config.athenix.sw.kioskUrl}
|
${config.athenix.sw.tablet-kiosk.kioskUrl}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
config,
|
config,
|
||||||
osConfig,
|
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|||||||
@@ -14,22 +14,42 @@ with lib;
|
|||||||
hosts = mkOption {
|
hosts = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [ "engr-ugaif@192.168.11.133 x86_64-linux" ];
|
default = [ "engr-ugaif@192.168.11.133 x86_64-linux" ];
|
||||||
description = "List of remote build hosts for system rebuilding.";
|
description = ''
|
||||||
|
List of remote build hosts for system rebuilding.
|
||||||
|
|
||||||
|
Format: "user@hostname architecture"
|
||||||
|
Each host must have SSH access and nix-daemon available.
|
||||||
|
|
||||||
|
Useful for offloading builds from low-power devices (tablets, laptops)
|
||||||
|
to more powerful build servers.
|
||||||
|
'';
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
[
|
||||||
|
"builder@nix-builder x86_64-linux"
|
||||||
|
"user@192.168.1.100 aarch64-linux"
|
||||||
|
]'';
|
||||||
};
|
};
|
||||||
|
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "Whether to enable remote build for 'update-system' command.";
|
description = ''
|
||||||
|
Whether to enable remote builds for the 'update-system' command.
|
||||||
|
|
||||||
|
When enabled, 'update-system' will use the configured remote hosts
|
||||||
|
to build the new system configuration instead of building locally.
|
||||||
|
|
||||||
|
Automatically enabled for tablet-kiosk systems.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
default = { };
|
default = { };
|
||||||
description = "Remote build configuration";
|
description = "Remote build configuration for system updates.";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
athenix.sw.remoteBuild.enable = lib.mkDefault (config.athenix.sw.type == "tablet-kiosk");
|
athenix.sw.remoteBuild.enable = lib.mkDefault (config.athenix.sw.tablet-kiosk.enable);
|
||||||
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
(pkgs.writeShellScriptBin "update-system" ''
|
(pkgs.writeShellScriptBin "update-system" ''
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ inputs, ... }:
|
{ ... }:
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# User Configuration
|
# User Configuration
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
# nixos-systems configuration (nixpkgs, home-manager, etc.).
|
# nixos-systems configuration (nixpkgs, home-manager, etc.).
|
||||||
|
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
osConfig ? null, # Only available in home-manager context
|
osConfig ? null, # Only available in home-manager context
|
||||||
@@ -60,7 +59,7 @@
|
|||||||
fd
|
fd
|
||||||
bat
|
bat
|
||||||
]
|
]
|
||||||
++ lib.optional (osConfig.athenix.sw.type or null == "desktop") firefox;
|
++ lib.optional (osConfig.athenix.sw.desktop.enable or false) firefox;
|
||||||
# Conditionally add packages based on system type
|
# Conditionally add packages based on system type
|
||||||
|
|
||||||
# ========== Programs ==========
|
# ========== Programs ==========
|
||||||
|
|||||||
Reference in New Issue
Block a user