Files
athenix/README.md
UGA Innovation Factory 5f716eae72 readme formatting
2025-12-16 16:20:42 -05:00

658 lines
18 KiB
Markdown

# UGA Innovation Factory - NixOS Systems
This repository contains the NixOS configuration for the Innovation Factory's fleet of laptops, desktops, surface tablets, and containers. It provides a declarative, reproducible system configuration using Nix flakes.
## Table of Contents
- [Quick Start](#quick-start)
- [Repository Structure](#repository-structure)
- [Configuration Namespace](#configuration-namespace)
- [User Management](#user-management)
- [Host Configuration](#host-configuration)
- [External Modules](#external-modules)
- [Building Artifacts](#building-artifacts)
- [Development](#development)
- [Troubleshooting](#troubleshooting)
## Quick Start
### For End Users: Updating Your System
Update your system to the latest configuration from GitHub:
```bash
update-system
```
This command automatically:
- Fetches the latest configuration
- Rebuilds your system
- Uses remote builders on Surface tablets to speed up builds
**Note:** If you use external user configurations (personal dotfiles), run `sudo nixos-rebuild switch --flake github:UGA-Innovation-Factory/nixos-systems --impure` instead.
### For Administrators: Applying Configuration Changes
1. Make changes to configuration files
2. Test the configuration builds:
```bash
nix flake check
```
3. Commit and push changes:
```bash
git add .
git commit -m "Description of changes"
git push
```
4. Users can now run `update-system` to get the changes
## Repository Structure
```
nixos-systems/
├── flake.nix # Flake entry point with inputs/outputs
├── inventory.nix # Fleet inventory (hosts, types, counts)
├── users.nix # User account definitions
├── hosts/ # Host generation logic and hardware types
│ ├── default.nix # Core host generation functions
│ ├── types/ # Hardware type definitions
│ │ ├── nix-desktop.nix
│ │ ├── nix-laptop.nix
│ │ ├── nix-surface.nix
│ │ ├── nix-lxc.nix
│ │ ├── nix-wsl.nix
│ │ └── nix-ephemeral.nix
│ └── user-config.nix # User configuration integration
├── sw/ # Software configurations by system type
│ ├── desktop/ # Desktop system software
│ ├── tablet-kiosk/ # Surface tablet kiosk mode
│ ├── stateless-kiosk/# Stateless kiosk systems
│ ├── headless/ # Headless server systems
│ ├── ghostty.nix # Ghostty terminal emulator
│ ├── nvim.nix # Neovim configuration
│ ├── python.nix # Python development tools
│ ├── theme.nix # UI theme configuration
│ └── updater.nix # System update service
├── installer/ # Build artifact generation
│ ├── artifacts.nix # ISO, LXC, Proxmox builds
│ ├── auto-install.nix # Automated installer
│ └── modules.nix # Exported modules
├── templates/ # Templates for external configs
│ ├── system/ # System configuration template
│ └── user/ # User configuration template
└── assets/ # Assets (Plymouth theme, etc.)
```
## Configuration Namespace
All UGA Innovation Factory-specific options are under the `ugaif` namespace:
### `ugaif.host` - Hardware Configuration
- **`ugaif.host.filesystem`**: Disk device and swap size settings
- `ugaif.host.filesystem.device` - Boot disk device (default: `/dev/sda`)
- `ugaif.host.filesystem.swapSize` - Swap file size (default: `"32G"`)
- **`ugaif.host.buildMethods`**: List of supported artifact types (`["iso"]`, `["lxc", "proxmox"]`, etc.)
- **`ugaif.host.useHostPrefix`**: Whether to prepend type prefix to hostname (default: `true`)
- **`ugaif.host.wsl`**: WSL-specific configuration
- `ugaif.host.wsl.user` - Default WSL user
### `ugaif.sw` - Software Configuration
- **`ugaif.sw.enable`**: Enable software configuration module (default: `true`)
- **`ugaif.sw.type`**: System type - `"desktop"`, `"tablet-kiosk"`, `"stateless-kiosk"`, or `"headless"`
- **`ugaif.sw.kioskUrl`**: URL for kiosk mode browsers
- **`ugaif.sw.python`**: Python development tools configuration
- `ugaif.sw.python.enable` - Enable Python tools (pixi, uv)
- **`ugaif.sw.remoteBuild`**: Remote build configuration
- `ugaif.sw.remoteBuild.enable` - Use remote builders (default: enabled on tablets)
- `ugaif.sw.remoteBuild.hosts` - List of build servers
- **`ugaif.sw.extraPackages`**: Additional system packages to install
### `ugaif.users` - User Management
- **`ugaif.users.accounts`**: Attrset of user definitions with account settings
- **`ugaif.users.enabledUsers`**: List of users to enable on this system (default: `["root", "engr-ugaif"]`)
- **`ugaif.forUser`**: Convenience option to set up a system for a specific user (sets `enabledUsers` and `wslUser`)
### Prerequisites
To work with this repository, install Nix with flakes support:
```bash
# Recommended: Determinate Systems installer (includes flakes)
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
# Alternative: Official installer (requires enabling flakes)
sh <(curl -L https://nixos.org/nix/install) --daemon
```
## User Management
### Understanding User Configuration
Users are defined in `users.nix` but are **not enabled by default** on all systems. Each system must explicitly enable users via `ugaif.users.enabledUsers` in `inventory.nix`.
**Default enabled users on all systems:**
- `root` - System administrator
- `engr-ugaif` - Innovation Factory default account
### Adding a New User
1. Edit `users.nix` and add a new user:
```nix
ugaif.users.accounts = {
# ... existing users ...
myuser = {
description = "My Full Name";
extraGroups = [ "networkmanager" "wheel" ];
shell = pkgs.zsh; # or pkgs.bash, pkgs.fish
hashedPassword = "$6$..."; # Generate with: mkpasswd -m sha-512
opensshKeys = [
"ssh-ed25519 AAAA... user@machine"
];
# enable = false; # Will be enabled per-system in inventory.nix
};
};
```
2. Generate a hashed password:
```bash
mkpasswd -m sha-512 # Enter password when prompted
```
3. Enable the user on specific hosts in `inventory.nix`:
```nix
nix-laptop = {
devices = 2;
overrides.extraUsers = [ "myuser" ]; # Enables on all nix-laptop hosts
};
# Or for individual devices:
nix-desktop = {
devices = {
"1".extraUsers = [ "myuser" "otheruser" ];
};
};
```
### User Configuration Options
Each user in `users.nix` can have:
```nix
myuser = {
description = "Full Name"; # User's full name
isNormalUser = true; # Default: true
extraGroups = [ ... ]; # Additional groups (wheel, docker, etc.)
shell = pkgs.zsh; # Login shell
hashedPassword = "$6$..."; # Hashed password
opensshKeys = [ "ssh-ed25519 ..." ]; # SSH public keys
homePackages = with pkgs; [ ... ]; # Home-manager packages (if no external config)
useZshTheme = true; # Use system Zsh theme (default: true)
useNvimPlugins = true; # Use system Neovim config (default: true)
# External home-manager configuration (optional)
home = builtins.fetchGit {
url = "https://github.com/username/dotfiles";
rev = "abc123...";
};
};
```
### External User Configuration
Users can maintain their dotfiles and home-manager configuration in separate repositories. See [External Modules](#external-modules) and [USER_CONFIGURATION.md](USER_CONFIGURATION.md) for details.
**Quick example:**
```nix
myuser = {
description = "My Name";
home = builtins.fetchGit {
url = "https://github.com/username/dotfiles";
rev = "commit-hash";
};
};
```
The external repository should contain:
- `home.nix` (required) - Home-manager configuration
- `nixos.nix` (optional) - System-level user configuration
**Create a template:**
```bash
nix flake init -t github:UGA-Innovation-Factory/nixos-systems#user
```
## Host Configuration
### Understanding Inventory Structure
The `inventory.nix` file defines all hosts in the fleet using a flexible system:
**Hostname Generation Rules:**
- Numeric suffixes: no dash (e.g., `nix-laptop1`, `nix-laptop2`)
- Non-numeric suffixes: with dash (e.g., `nix-laptop-alpha`, `nix-laptop-beta`)
- Set `ugaif.host.useHostPrefix = false` to use suffix as full hostname
### Adding Hosts
**Method 1: Quick count (simplest)**
```nix
nix-laptop = {
devices = 5; # Creates: nix-laptop1, nix-laptop2, ..., nix-laptop5
};
```
**Method 2: Explicit count with overrides**
```nix
nix-laptop = {
devices = 5;
overrides = {
# Applied to ALL nix-laptop hosts
extraUsers = [ "student" ];
ugaif.sw.extraPackages = with pkgs; [ vim git ];
};
};
```
**Method 3: Individual device configuration**
```nix
nix-surface = {
devices = {
"1".ugaif.sw.kioskUrl = "https://dashboard1.example.com";
"2".ugaif.sw.kioskUrl = "https://dashboard2.example.com";
"3".ugaif.sw.kioskUrl = "https://dashboard3.example.com";
};
};
```
**Method 4: Mixed (default count + custom devices)**
```nix
nix-surface = {
defaultCount = 2; # Creates nix-surface1, nix-surface2
devices = {
"special" = { # Creates nix-surface-special
ugaif.sw.kioskUrl = "https://special-dashboard.example.com";
};
};
overrides = {
# Applied to all devices (including "special")
ugaif.sw.kioskUrl = "https://default-dashboard.example.com";
};
};
```
### Device Configuration Options
**Convenience shortcuts** (automatically converted to proper options):
- `extraUsers` → `ugaif.users.enabledUsers`
- `hostname` → Custom hostname (overrides default naming)
- `buildMethods` → `ugaif.host.buildMethods`
- `wslUser` → `ugaif.host.wsl.user`
**Direct configuration** (any NixOS or ugaif option):
```nix
"1" = {
# Convenience
extraUsers = [ "myuser" ];
# UGAIF options
ugaif.host.filesystem.swapSize = "64G";
ugaif.sw.extraPackages = with pkgs; [ docker ];
ugaif.sw.kioskUrl = "https://example.com";
# Standard NixOS options
networking.firewall.enable = false;
services.openssh.enable = true;
time.timeZone = "America/New_York";
};
```
### Convenience: `ugaif.forUser`
Quick setup for single-user systems (especially WSL):
```nix
nix-wsl = {
devices = {
"alice".ugaif.forUser = "alice-username";
};
};
```
This automatically:
- Adds user to `extraUsers` (enables the account)
- Sets `ugaif.host.wsl.user` to the username (for WSL)
### External System Configuration
For complex configurations, use external modules. See [External Modules](#external-modules) and [EXTERNAL_MODULES.md](EXTERNAL_MODULES.md).
```nix
nix-lxc = {
devices = {
"special-server" = builtins.fetchGit {
url = "https://github.com/org/server-config";
rev = "abc123...";
};
};
};
```
**Create a template:**
```bash
nix flake init -t github:UGA-Innovation-Factory/nixos-systems#system
```
## External Modules
External modules allow you to maintain user or system configurations in separate Git repositories and reference them from `users.nix` or `inventory.nix`.
### 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
### Templates
Initialize a new external configuration:
```bash
# User configuration (home-manager, dotfiles)
nix flake init -t github:UGA-Innovation-Factory/nixos-systems#user
# System configuration (services, packages, hardware)
nix flake init -t github:UGA-Innovation-Factory/nixos-systems#system
```
### User Module Example
In `users.nix`:
```nix
myuser = {
description = "My Name";
home = builtins.fetchGit {
url = "https://github.com/username/dotfiles";
rev = "abc123..."; # Pin to specific commit
};
};
```
External repository structure:
```
dotfiles/
├── home.nix # Required: Home-manager configuration
└── nixos.nix # Optional: System-level user configuration
```
See [USER_CONFIGURATION.md](USER_CONFIGURATION.md) and [templates/user/](templates/user/) for details.
### System Module Example
In `inventory.nix`:
```nix
nix-lxc = {
devices = {
"custom-server" = builtins.fetchGit {
url = "https://github.com/org/server-config";
rev = "abc123...";
};
};
};
```
External repository structure:
```
server-config/
└── default.nix # Required: NixOS module
```
See [EXTERNAL_MODULES.md](EXTERNAL_MODULES.md) and [templates/system/](templates/system/) for details.
### Fetch Methods
**Recommended: fetchGit with revision**
```nix
builtins.fetchGit {
url = "https://github.com/user/repo";
rev = "abc123def456..."; # Full commit hash
ref = "main"; # Optional: branch name
}
```
**Local path (for testing)**
```nix
/path/to/local/config
```
**Tarball (for releases)**
```nix
builtins.fetchTarball {
url = "https://github.com/user/repo/archive/v1.0.0.tar.gz";
sha256 = "sha256:...";
}
```
## Building Artifacts
Build installation media and container images from this flake.
### Installer ISOs
Build an auto-install ISO for a specific host:
```bash
# Build locally
nix build github:UGA-Innovation-Factory/nixos-systems#installer-iso-nix-laptop1
# Build using remote builder
nix build github:UGA-Innovation-Factory/nixos-systems#installer-iso-nix-laptop1 \
--builders "ssh://engr-ugaif@nix-builder x86_64-linux"
```
Result: `result/iso/nixos-*.iso`
### Available Artifacts
```bash
# List all available builds
nix flake show github:UGA-Innovation-Factory/nixos-systems
# Common artifacts:
nix build .#installer-iso-nix-laptop1 # Installer ISO
nix build .#iso-nix-ephemeral1 # Live ISO (no installer)
nix build .#ipxe-nix-ephemeral1 # iPXE netboot
nix build .#lxc-nix-builder # LXC container tarball
nix build .#proxmox-nix-builder # Proxmox VMA
```
### Using Remote Builders
Speed up builds by offloading to a build server:
```bash
# In ~/.config/nix/nix.conf or /etc/nix/nix.conf:
builders = ssh://engr-ugaif@nix-builder x86_64-linux
# Or use --builders flag for one-time builds
nix build ... --builders "ssh://engr-ugaif@nix-builder x86_64-linux"
```
## Development
### Testing Configuration Changes
Before committing changes:
```bash
# Check all configurations build correctly
nix flake check
# Check with verbose trace on error
nix flake check --show-trace
# Build a specific host configuration
nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel
# Test rebuild locally
sudo nixos-rebuild test --flake .
```
### Manual System Rebuilds
For testing or emergency fixes:
```bash
# Rebuild current host from local directory
sudo nixos-rebuild switch --flake .
# Rebuild specific host
sudo nixos-rebuild switch --flake .#nix-laptop1
# Test without switching (temporary, doesn't persist reboot)
sudo nixos-rebuild test --flake .#nix-laptop1
# Rebuild from GitHub
sudo nixos-rebuild switch --flake github:UGA-Innovation-Factory/nixos-systems
```
### Updating Flake Inputs
Update nixpkgs, home-manager, and other dependencies:
```bash
# Update all inputs
nix flake update
# Update specific input
nix flake lock --update-input nixpkgs
# After updating, test and commit
git add flake.lock
git commit -m "Update flake inputs"
```
### Python Development
All systems include `pixi` and `uv` for project-based Python environments:
**Pixi (recommended for projects):**
```bash
pixi init my-project
cd my-project
pixi add pandas numpy matplotlib
pixi run python script.py
```
**uv (quick virtual environments):**
```bash
uv venv
source .venv/bin/activate
uv pip install requests
```
### Adding Packages System-Wide
**To all desktop systems:**
- Edit `sw/desktop/programs.nix`
**To all tablet kiosks:**
- Edit `sw/tablet-kiosk/programs.nix`
**To all headless systems:**
- Edit `sw/headless/programs.nix`
**To specific hosts:**
- Add to `ugaif.sw.extraPackages` in `inventory.nix`
Example:
```nix
nix-laptop = {
devices = 2;
overrides = {
ugaif.sw.extraPackages = with pkgs; [ vim docker ];
};
};
```
### Changing System Type
System types are defined in `hosts/types/` and set the software profile:
- **`desktop`**: Full desktop environment (GNOME)
- **`tablet-kiosk`**: Surface tablets with kiosk mode browser
- **`stateless-kiosk`**: Diskless PXE boot kiosks
- **`headless`**: Servers and containers without GUI
To change a host's type, edit the type module it imports in `hosts/types/`.
## Troubleshooting
### Common Issues
**"error: executing 'git': No such file or directory"**
- The `update-system` service needs git in PATH (fixed in latest version)
- Workaround: Run `sudo nixos-rebuild switch --flake github:UGA-Innovation-Factory/nixos-systems` manually
**Build errors after flake update**
```bash
# Check what changed
git diff flake.lock
# Try with show-trace for details
nix flake check --show-trace
# Revert if needed
git checkout flake.lock
```
**External modules not loading**
- Ensure repository is accessible (public or SSH configured)
- Module must export proper structure (see templates)
- For users: requires `home.nix` and optionally `nixos.nix`
- For systems: requires `default.nix` that accepts `{ inputs, ... }`
**Remote build failures**
```bash
# Test SSH access
ssh engr-ugaif@nix-builder
# Check builder disk space
ssh engr-ugaif@nix-builder df -h
# Temporarily disable remote builds in inventory.nix:
ugaif.sw.remoteBuild.enable = false;
```
**"dirty git tree" warnings**
- Commit or stash uncommitted changes
- These warnings don't prevent builds but affect reproducibility
### Getting Help
- Check documentation: [USER_CONFIGURATION.md](USER_CONFIGURATION.md), [EXTERNAL_MODULES.md](EXTERNAL_MODULES.md)
- Review templates: `templates/user/` and `templates/system/`
- Contact Innovation Factory IT team
### Useful Commands
```bash
# Show all available outputs
nix flake show
# Evaluate a specific option
nix eval .#nixosConfigurations.nix-laptop1.config.networking.hostName
# List all hosts
nix eval .#nixosConfigurations --apply builtins.attrNames
# Check flake metadata
nix flake metadata
# Update and show what changed
nix flake update && git diff flake.lock
```