docs: Copilot update all docs files
All checks were successful
CI / Format Check (push) Successful in 6s
CI / Flake Check (push) Successful in 1m25s
CI / Evaluate Key Configurations (nix-builder) (push) Successful in 10s
CI / Evaluate Key Configurations (nix-desktop1) (push) Successful in 11s
CI / Evaluate Key Configurations (nix-laptop1) (push) Successful in 8s
CI / Evaluate Artifacts (installer-iso-nix-laptop1) (push) Successful in 16s
CI / Evaluate Artifacts (lxc-nix-builder) (push) Successful in 10s

This commit is contained in:
UGA Innovation Factory
2026-01-05 10:05:41 -05:00
parent 0378268dcc
commit f07ccc071e
8 changed files with 2052 additions and 1136 deletions

View File

@@ -1,6 +1,6 @@
# External Configuration Modules
This guide explains how to use external modules for system and user configurations in nixos-systems.
Guide to using external modules for system and user configurations.
## Table of Contents
@@ -8,116 +8,125 @@ This guide explains how to use external modules for system and user configuratio
- [System Modules](#system-modules)
- [User Modules](#user-modules)
- [Fetch Methods](#fetch-methods)
- [Templates](#templates)
- [Integration Details](#integration-details)
- [Creating External Modules](#creating-external-modules)
- [Best Practices](#best-practices)
## Overview
External modules allow you to maintain configurations in separate Git repositories and reference them from `inventory.nix` (for systems) or `users.nix` (for users).
External modules allow you to maintain configurations in separate Git repositories and reference them from Athenix.
**Benefits:**
- **Separation:** Keep configs in separate repositories
- **Versioning:** Pin to specific commits for reproducibility
- **Reusability:** Share configurations across deployments
- **Flexibility:** Mix external modules with local overrides
- **Separation** - Keep complex configs in separate repositories
- **Reproducibility** - Pin specific commits for deterministic builds
- **Reusability** - Share configurations across multiple deployments
- **Flexibility** - Mix external modules with local configuration
- **Ownership** - Users maintain their own dotfiles
## System Modules
External system modules provide complete NixOS configurations for hosts.
External system modules provide host-specific NixOS configurations.
### Usage in inventory.nix
### Usage
In `inventory.nix`, reference an external module as a device:
```nix
nix-lxc = {
devices = {
# Traditional inline configuration
# Inline configuration
"local-server" = {
athenix.users.admin.enable = true;
athenix.sw.type = "headless";
services.nginx.enable = true;
};
# External module from Git
# External module
"remote-server" = builtins.fetchGit {
url = "https://git.factory.uga.edu/org/server-config";
rev = "abc123..."; # Pin to specific commit
rev = "abc123def456..."; # Must pin to specific commit
};
};
};
```
### External Repository Structure
### Repository Structure
```
server-config/
├── default.nix # Required: NixOS module
── README.md # Optional: Documentation
├── default.nix # Required: NixOS module
── README.md # Recommended: Documentation
└── optional/
├── config/ # Optional: Configuration files
└── scripts/ # Optional: Helper scripts
```
**default.nix:**
### Module Content (default.nix)
```nix
# The module receives inputs and standard NixOS module parameters
{ inputs, ... }:
{ config, lib, pkgs, ... }:
{
# Your NixOS configuration
# Use any standard NixOS option or athenix.* options
services.nginx = {
enable = true;
virtualHosts."example.com" = {
root = "/var/www";
forceSSL = true;
enableACME = true;
};
};
# Use athenix namespace options
athenix.users.admin.enable = true;
# Use athenix options
athenix.sw.type = "headless";
athenix.sw.extraPackages = with pkgs; [ git htop ];
# Standard NixOS configuration
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.openssh.enable = true;
}
```
### What External Modules Receive
### What System Modules Receive
- **`inputs`** - All flake inputs (nixpkgs, home-manager, etc.)
- **`config`** - Full NixOS configuration
- **`inputs`** - All flake inputs (nixpkgs, home-manager, disko, etc.)
- **`config`** - Current NixOS configuration (read/write)
- **`lib`** - Nixpkgs library functions
- **`pkgs`** - Package set
### Module Integration Order
### Configuration Order
When a host is built, modules are loaded in this order:
When a host is built, modules load in this order:
1. User NixOS modules (from `users.nix` - `nixos.nix` files)
2. Host type module (from `hosts/types/`)
3. Configuration overrides (from `inventory.nix`)
4. Hostname assignment
5. External system module (if using `builtins.fetchGit`)
1. Hardware type module (from `hosts/types/nix-*.nix`)
2. Host common configuration (from `hosts/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`)
6. External system module (if present)
Later modules can override earlier ones using standard NixOS module precedence.
### Template
Create a new system module:
```bash
nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#system
```
See [templates/system/](../templates/system/) for the complete template.
Each later module can override earlier ones using standard NixOS precedence rules.
## User Modules
External user modules provide home-manager configurations (dotfiles, packages, programs).
External user modules provide home-manager configurations (dotfiles, environment setup).
### Usage in users.nix
### Usage
In `users.nix`, reference an external user module:
```nix
athenix.users = {
# External user module (dotfiles, home-manager, and user options)
myuser = builtins.fetchGit {
# External user module
myuser.external = builtins.fetchGit {
url = "https://git.factory.uga.edu/username/dotfiles";
rev = "abc123...";
rev = "abc123def456..."; # Pin to specific commit
};
# Inline user definition
inlineuser = {
description = "Inline User";
otheruser = {
description = "Other User";
extraGroups = [ "wheel" ];
shell = pkgs.zsh;
hashedPassword = "$6$...";
@@ -125,148 +134,179 @@ athenix.users = {
};
```
### External Repository Structure
Then enable on hosts in `inventory.nix`:
```
dotfiles/
├── user.nix # Required: User options AND home-manager config
├── nixos.nix # Optional: System-level config
└── config/ # Optional: Actual dotfiles
├── bashrc
└── vimrc
```
**user.nix (required):**
```nix
nix-laptop = {
devices = 5;
overrides.athenix.users.myuser.enable = true;
};
```
### Repository Structure
```
my-dotfiles/
├── user.nix # Required: User options + home-manager config
├── nixos.nix # Optional: System-level configuration
├── README.md # Recommended: Documentation
└── config/ # Optional: Your actual dotfiles
├── zshrc
├── vimrc
├── nvim/
└── ...
```
### user.nix (Required)
Provides both user account settings AND home-manager configuration:
```nix
# Receives { inputs } and standard home-manager module parameters
{ inputs, ... }:
{ config, lib, pkgs, osConfig ? null, ... }:
{
# ========== User Account Configuration ==========
# These options define the user account itself
athenix.users.myusername = {
description = "Your Full Name";
description = "My Full Name";
extraGroups = [ "wheel" "docker" ];
shell = pkgs.zsh;
hashedPassword = "!";
opensshKeys = [ "ssh-ed25519 AAAA..." ];
hashedPassword = "!"; # SSH keys only
opensshKeys = [
"ssh-ed25519 AAAA... user@laptop"
];
useZshTheme = true;
useNvimPlugins = true;
};
# ========== Home Manager Configuration ==========
# User environment, packages, and dotfiles
# Packages
home.packages = with pkgs; [
vim
git
htop
ripgrep
fzf
] ++ lib.optional (osConfig.athenix.sw.type or null == "desktop") firefox;
# Programs
programs.git = {
enable = true;
userName = "My Name";
userEmail = "me@example.com";
extraConfig = {
init.defaultBranch = "main";
core.editor = "vim";
};
};
programs.zsh = {
enable = true;
initExtra = ''
# Your Zsh configuration
export EDITOR=vim
'';
};
# Manage dotfiles
home.file.".bashrc".source = ./dotfiles/bashrc;
home.file.".zshrc".source = ./config/zshrc;
home.file.".vimrc".source = ./config/vimrc;
home.file.".config/nvim".source = ./config/nvim;
# Services
services.gpg-agent.enable = true;
}
```
**nixos.nix (optional):**
### nixos.nix (Optional)
System-level configuration for this user (rarely needed):
```nix
{ inputs, ... }:
{ config, lib, pkgs, ... }:
{
# System-level configuration for this user
users.users.myuser.extraGroups = [ "docker" ];
# System-level configuration
# Only needed if the user requires specific system-wide settings
users.users.myusername.extraGroups = [ "docker" ];
environment.systemPackages = [ pkgs.docker ];
# Security settings
security.sudo.extraRules = [{
users = [ "myusername" ];
commands = [{
command = "/usr/bin/something";
options = [ "NOPASSWD" ];
}];
}];
}
```
### What User Modules Receive
**In user.nix:**
- **`inputs`** - Flake inputs (nixpkgs, home-manager, etc.)
- **`config`** - Home-manager configuration
- **`inputs`** - All flake inputs (nixpkgs, home-manager, etc.)
- **`config`** - Home-manager configuration (read/write)
- **`lib`** - Nixpkgs library functions
- **`pkgs`** - Package set
- **`osConfig`** - OS-level configuration (read-only)
- **`osConfig`** - OS configuration (read-only) - useful for conditional setup
**In nixos.nix:**
- **`inputs`** - Flake inputs
- **`config`** - NixOS configuration
- **`lib`** - Nixpkgs library functions
- **`config`** - NixOS configuration (read/write)
- **`lib`** - Nixpkgs library functions
- **`pkgs`** - Package set
### User Options in users.nix
### Conditional Setup Example
Use `osConfig` to conditionally set up dotfiles based on the system type:
```nix
username = {
# Identity
description = "Full Name";
# External configuration
external = builtins.fetchGit { ... };
# System settings
extraGroups = [ "wheel" "networkmanager" ];
hashedPassword = "$6$...";
opensshKeys = [ "ssh-ed25519 ..." ];
shell = pkgs.zsh;
# Theme integration
useZshTheme = true; # Apply system zsh theme (default: true)
useNvimPlugins = true; # Apply system nvim config (default: true)
# Enable on specific systems (see docs/INVENTORY.md)
enable = false; # Set in inventory.nix via athenix.users.username.enable
};
# In user.nix
{ inputs, ... }:
{ config, lib, pkgs, osConfig ? null, ... }:
{
athenix.users.myuser = { /* ... */ };
# Install Firefox only on desktop systems
home.packages = with pkgs; [
ripgrep
] ++ lib.optional (osConfig.athenix.sw.type or null == "desktop") firefox;
# Different shell config per system
programs.zsh.initExtra = ''
${lib.optionalString (osConfig.athenix.sw.type or null == "headless") "
# Headless-only settings
"}
'';
}
```
### Template
Create a new user module:
```bash
nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#user
```
See [templates/user/](../templates/user/) for the complete template.
## Fetch Methods
### Recommended: fetchGit with Revision
### builtins.fetchGit (Recommended)
Pin to a specific commit for reproducibility:
Pin to a specific Git revision:
```nix
builtins.fetchGit {
url = "https://github.com/user/repo";
rev = "abc123def456..."; # Full commit hash (40 characters)
ref = "main"; # Optional: branch name
url = "https://git.factory.uga.edu/username/dotfiles";
rev = "abc123def456..."; # Required: specific commit hash
}
```
**Finding the commit hash:**
```bash
# Latest commit on main branch
git ls-remote https://github.com/user/repo main
**Advantages:**
- Reproducible (pinned to exact commit)
- Works with any Git repository
- Supports SSH or HTTPS URLs
# Or from a local clone
git rev-parse HEAD
```
**Important:** Always specify `rev` (commit hash) for reproducibility. Don't use branches which can change.
### fetchGit with Branch (Less Reproducible)
Always fetches latest from branch:
```nix
builtins.fetchGit {
url = "https://github.com/user/repo";
ref = "develop";
}
```
⚠️ **Warning:** Builds may not be reproducible as the branch HEAD can change.
### fetchTarball (For Releases)
### builtins.fetchTarball
Download specific release archives:
@@ -287,174 +327,141 @@ nix-prefetch-url --unpack https://github.com/user/repo/archive/v1.0.0.tar.gz
Use local directories during development:
```nix
/home/username/dev/my-config
# users.nix
athenix.users.myuser.external = /home/user/my-dotfiles;
# Or relative to repository
./my-local-config
```
⚠️ **Warning:** Only for testing. Use Git-based methods for production.
## Templates
### System Module Template
```bash
# Initialize in new directory
mkdir my-server-config
cd my-server-config
nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#system
```
See [templates/system/README.md](../templates/system/README.md) for detailed usage.
### User Module Template
```bash
# Initialize in new directory
mkdir my-dotfiles
cd my-dotfiles
nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#user
```
See [templates/user/README.md](../templates/user/README.md) for detailed usage.
## Integration Details
### Detection Logic
The system automatically detects external modules when a device or user value is:
- A path (`builtins.isPath`)
- A string starting with `/` (absolute path)
- A derivation (`lib.isDerivation`)
- An attrset with `outPath` attribute (result of `fetchGit`/`fetchTarball`)
### System Module Integration
External system modules are imported and merged into the NixOS configuration:
```nix
import externalModulePath { inherit inputs; }
```
They can use all standard NixOS options plus `athenix.*` namespace options.
### User Module Integration
External user modules are loaded in two contexts:
**User options (NixOS module context):**
```nix
import (externalPath + "/user.nix") { inherit inputs; }
# Evaluated as NixOS module to extract athenix.users.<username> options
```
**Home-manager configuration:**
```nix
import (externalPath + "/user.nix") { inherit inputs; }
# Imported into home-manager for home.*, programs.*, services.* options
```
**System-level config (optional):**
```nix
import (externalPath + "/nixos.nix") { inherit inputs; }
# If present, imported as NixOS module for system-level configuration
```
### Combining External and Local Config
You can mix external modules with local overrides:
```nix
nix-lxc = {
# inventory.nix
nix-laptop = {
devices = {
"server" = builtins.fetchGit {
url = "https://git.factory.uga.edu/org/base-config";
rev = "abc123...";
};
};
overrides = {
# Apply to all devices, including external ones
athenix.users.admin.enable = true;
networking.firewall.allowedTCPPorts = [ 80 443 ];
"dev".athenix.users.myuser.enable = true;
};
};
```
### Minimal User Module
**Note:** Only works if the path exists on the machine running `nix flake check` or `nix build`.
**user.nix:**
## Creating External Modules
### System Module Template
Create a new system module repository from the template:
```bash
nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#system
```
This creates:
```
my-system-config/
├── flake.nix # Optional: for testing standalone
├── default.nix # Your NixOS module
└── README.md # Documentation
```
### User Module Template
Create a new user module repository:
```bash
nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#user
```
This creates:
```
my-dotfiles/
├── flake.nix # Optional: for testing standalone
├── user.nix # User options + home-manager config
├── nixos.nix # Optional: system-level config
└── README.md # Documentation
```
### Testing External Modules
Test your external module locally before pushing:
```bash
# In your module repository
cd /path/to/my-module
# Test the Nix syntax
nix flake check
```
## Best Practices
### 1. Always Pin to Specific Commits
❌ Wrong - using branch names:
```nix
{ inputs, ... }:
{ config, lib, pkgs, osConfig ? null, ... }:
{
# User account options
athenix.users.myusername = {
description = "My Name";
shell = pkgs.zsh;
hashedPassword = "!";
};
# Home-manager config
home.packages = with pkgs; [ vim git ];
builtins.fetchGit {
url = "https://git.factory.uga.edu/username/dotfiles";
# No rev specified or using "main"
}
```
### Full User Module with Dotfiles
```
dotfiles/
├── user.nix
├── nixos.nix
└── config/
├── bashrc
├── vimrc
└── gitconfig
```
**user.nix:**
✅ Correct - using commit hash:
```nix
{ inputs, ... }:
{ config, lib, pkgs, osConfig ? null, ... }:
{
# User account configuration
athenix.users.myusername = {
description = "My Full Name";
shell = pkgs.zsh;
extraGroups = [ "wheel" "networkmanager" ];
hashedPassword = "!";
opensshKeys = [ "ssh-ed25519 AAAA..." ];
useZshTheme = true;
useNvimPlugins = true;
};
# Home-manager configuration
home.packages = with pkgs; [
ripgrep
fd
bat
] ++ lib.optional (osConfig.athenix.sw.type or null == "desktop") firefox;
programs.git = {
enable = true;
userName = "My Full Name";
userEmail = "me@example.com";
extraConfig.init.defaultBranch = "main";
};
home.file = {
".bashrc".source = ./config/bashrc;
".vimrc".source = ./config/vimrc;
".gitconfig".source = ./config/gitconfig;
};
builtins.fetchGit {
url = "https://git.factory.uga.edu/username/dotfiles";
rev = "abc123def456789...";
}
```
### 2. Keep External Modules Focused
Each external module should have a clear purpose:
- User dotfiles (one repo per user)
- System service configuration (one repo per service/cluster)
- Hardware-specific config (one repo per hardware setup)
### 3. Document Your Modules
Include a README with:
- What the module configures
- Required dependencies
- Usage examples
- Configuration options
### 4. Use Semantic Versioning
Tag releases in Git:
```bash
git tag v1.0.0
git push origin v1.0.0
```
Reference specific versions:
```nix
builtins.fetchGit {
url = "https://git.factory.uga.edu/org/server-config";
rev = "v1.0.0"; # Can use tags too
}
```
### 5. Test Before Updating Pins
When updating commit hashes:
```bash
# Test new revision locally
nix flake update
# Validate all configurations
nix flake check --show-trace
# Only commit after validation
git add . && git commit -m "Update module versions"
```
## See Also
- [INVENTORY.md](INVENTORY.md) - Host configuration guide
- [USER_CONFIGURATION.md](USER_CONFIGURATION.md) - User management guide
- [NAMESPACE.md](NAMESPACE.md) - Configuration options reference
- [templates/system/](../templates/system/) - System module template
- [templates/user/](../templates/user/) - User module template
- [USER_CONFIGURATION.md](USER_CONFIGURATION.md) - User management
- [INVENTORY.md](INVENTORY.md) - Host configuration
- [NAMESPACE.md](NAMESPACE.md) - Configuration options
- [README.md](../README.md) - Main documentation
- [templates/user/](../templates/user/) - User module template
- [templates/system/](../templates/system/) - System module template