From 22b1fc549bf587d6c5933709afee69b589ff3eed Mon Sep 17 00:00:00 2001 From: Hunter Halloran Date: Wed, 17 Dec 2025 09:25:51 -0500 Subject: [PATCH] documentation overhaul --- EXTERNAL_MODULES.md | 109 ------ README.md | 700 ++++++++----------------------------- USER_CONFIGURATION.md | 288 --------------- docs/BUILDING.md | 264 ++++++++++++++ docs/DEVELOPMENT.md | 355 +++++++++++++++++++ docs/EXTERNAL_MODULES.md | 418 ++++++++++++++++++++++ docs/INVENTORY.md | 190 ++++++++++ docs/NAMESPACE.md | 275 +++++++++++++++ docs/USER_CONFIGURATION.md | 486 +++++++++++++++++++++++++ 9 files changed, 2141 insertions(+), 944 deletions(-) delete mode 100644 EXTERNAL_MODULES.md delete mode 100644 USER_CONFIGURATION.md create mode 100644 docs/BUILDING.md create mode 100644 docs/DEVELOPMENT.md create mode 100644 docs/EXTERNAL_MODULES.md create mode 100644 docs/INVENTORY.md create mode 100644 docs/NAMESPACE.md create mode 100644 docs/USER_CONFIGURATION.md diff --git a/EXTERNAL_MODULES.md b/EXTERNAL_MODULES.md deleted file mode 100644 index e336f80..0000000 --- a/EXTERNAL_MODULES.md +++ /dev/null @@ -1,109 +0,0 @@ -# External Module Support Implementation - -## Summary - -Modified `nixos-systems` to support external system configurations via Nix modules instead of flakes. Device configurations can now point to URLs using `builtins.fetchGit`, `builtins.fetchTarball`, or local paths. - -## Changes Made - -### 1. `inventory.nix` -- Added documentation for external module syntax -- Added comprehensive examples showing different fetch methods -- Demonstrated usage: `devices."hostname" = builtins.fetchGit { url = "..."; rev = "..."; }` - -### 2. `hosts/default.nix` -- Modified `mkHost` function to accept `externalModulePath` parameter -- Added logic to import and integrate external modules into the module list -- Updated device processing to detect path/derivation types (from fetchGit/fetchTarball) -- External modules are imported with `{ inputs; }` parameter, receiving same flake inputs -- External modules are merged alongside other configuration modules - -### 3. `system-module-template/` -- Created `default.nix` template showing proper module structure -- Created `README.md` with usage instructions and examples -- Documented how external modules integrate with nixos-systems - -## How It Works - -### In inventory.nix: -```nix -{ - "my-type" = { - devices = { - # Option 1: Traditional config attrset - "local-host" = { - extraUsers = [ "user1" ]; - # ... normal NixOS config - }; - - # Option 2: External module from Git - "remote-host" = builtins.fetchGit { - url = "https://github.com/org/config"; - rev = "abc123..."; - }; - }; - }; -} -``` - -### Detection Logic: -The system detects if a device value is: -1. A path (`builtins.isPath`) -2. A string starting with `/` (absolute path) -3. A derivation (`lib.isDerivation`) - -If any of these are true, it treats it as an external module path. - -### Module Import: -External modules are imported as: -```nix -import externalModulePath { inherit inputs; } -``` - -They receive the same flake inputs and can use all available modules and packages. - -### Integration Order: -1. User flake modules (from users.nix) -2. Host type module (from hosts/types/) -3. Config override module -4. Hostname assignment -5. External flake module (if flakeUrl specified in config) -6. External path module (if fetchGit/fetchurl/path detected) - -## Benefits - -- **Separation**: Keep system configs in separate repos -- **Reusability**: Share configs across multiple deployments -- **Versioning**: Pin to specific commits for reproducibility -- **Flexibility**: Mix external modules with local overrides -- **Compatibility**: Works with all existing build methods (ISO, LXC, Proxmox) - -## Testing - -All existing configurations continue to work: -```bash -nix flake check # Passes ✓ -nix eval .#nixosConfigurations.nix-desktop1.config.networking.hostName # Works ✓ -``` - -## Example External Module Repository Structure - -``` -my-server-config/ -├── default.nix # Main module (required) -├── README.md # Documentation -└── custom-service.nix # Additional modules (optional) -``` - -The `default.nix` must export a NixOS module: -```nix -{ inputs, ... }: - -{ config, lib, pkgs, ... }: - -{ - config = { - # Your configuration here - }; -} -``` diff --git a/README.md b/README.md index e147171..755a3fc 100644 --- a/README.md +++ b/README.md @@ -1,118 +1,105 @@ # 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. +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 +## Documentation -- [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](#quick-start)** - Get started in 5 minutes +- **[docs/INVENTORY.md](docs/INVENTORY.md)** - Configure hosts and fleet inventory +- **[docs/NAMESPACE.md](docs/NAMESPACE.md)** - Configuration options reference (`ugaif.*`) +- **[docs/USER_CONFIGURATION.md](docs/USER_CONFIGURATION.md)** - User account management +- **[docs/EXTERNAL_MODULES.md](docs/EXTERNAL_MODULES.md)** - External configuration modules +- **[docs/BUILDING.md](docs/BUILDING.md)** - Build ISOs and container images +- **[docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)** - Development and testing workflow ## Quick Start -### For End Users: Updating Your System +### For End Users -Update your system to the latest configuration from GitHub: +Update your system to the latest configuration: ```bash update-system ``` -This command automatically: -- Fetches the latest configuration -- Rebuilds your system -- Uses remote builders on Surface tablets to speed up builds +This command automatically fetches the latest configuration, rebuilds your system, and 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. +**Note:** If you use external user configurations (personal dotfiles), run: +```bash +sudo nixos-rebuild switch --flake github:UGA-Innovation-Factory/nixos-systems --impure +``` -### For Administrators: Applying Configuration Changes +### For Administrators -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 +```bash +# 1. Make changes to configuration files +vim inventory.nix + +# 2. Test configuration +nix flake check + +# 3. Format code +nix fmt + +# 4. Commit and push +git add . +git commit -m "Description of changes" +git push +``` + +Users can now run `update-system` to get the changes. + +**See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for detailed development workflow.** ## 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 +├── flake.nix # Flake entry point +├── inventory.nix # Fleet inventory - Define hosts here +├── users.nix # User accounts - Define users here +├── hosts/ # Host generation logic +│ ├── types/ # Hardware types (desktop, laptop, surface, lxc, wsl, ephemeral) +│ └── ... ├── 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 +│ ├── desktop/ # Full desktop environment +│ ├── tablet-kiosk/ # Surface kiosk mode +│ ├── stateless-kiosk/# Diskless PXE kiosks +│ ├── headless/ # Servers and containers +│ └── ... +├── installer/ # ISO and container builds ├── templates/ # Templates for external configs │ ├── system/ # System configuration template │ └── user/ # User configuration template +├── docs/ # Documentation +│ ├── INVENTORY.md # Host configuration guide +│ ├── NAMESPACE.md # Option reference +│ ├── BUILDING.md # Building artifacts +│ └── DEVELOPMENT.md # Development guide └── assets/ # Assets (Plymouth theme, etc.) ``` -## Configuration Namespace +## Configuration Overview -All UGA Innovation Factory-specific options are under the `ugaif` namespace: +All Innovation Factory options use the `ugaif.*` namespace. See **[docs/NAMESPACE.md](docs/NAMESPACE.md)** for complete reference. -### `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 +**Quick examples:** -### `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 +```nix +# Host configuration +ugaif.host.filesystem.device = "/dev/nvme0n1"; +ugaif.host.filesystem.swapSize = "64G"; -### `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`) +# Software configuration +ugaif.sw.type = "desktop"; # or "headless", "tablet-kiosk" +ugaif.sw.extraPackages = with pkgs; [ vim docker ]; -### Prerequisites +# User management +ugaif.users.myuser.enable = true; +ugaif.forUser = "myuser"; # Convenience shortcut +``` + +## Prerequisites To work with this repository, install Nix with flakes support: @@ -120,538 +107,157 @@ To work with this repository, install Nix with flakes support: # 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) +# Alternative: Official installer (requires enabling flakes manually) 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 +## Common Tasks ### Adding a New User -1. Edit `users.nix` and add a new user: +1. Edit `users.nix`: ```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 - }; +myuser = { + description = "My Full Name"; + extraGroups = [ "wheel" "networkmanager" ]; + shell = pkgs.zsh; + hashedPassword = "$6$..."; # Generate with: mkpasswd -m sha-512 + opensshKeys = [ "ssh-ed25519 AAAA... user@host" ]; }; ``` -2. Generate a hashed password: -```bash -mkpasswd -m sha-512 # Enter password when prompted -``` - -3. Enable the user on specific hosts in `inventory.nix`: +2. Enable on hosts in `inventory.nix`: ```nix nix-laptop = { devices = 2; - overrides.extraUsers = [ "myuser" ]; # Enables on all nix-laptop hosts + overrides.ugaif.users.myuser.enable = true; +}; +``` + +**See [docs/USER_CONFIGURATION.md](docs/USER_CONFIGURATION.md) for complete user management guide.** + +### Adding Hosts + +Edit `inventory.nix`: + +```nix +# Simple: Create 5 laptops +nix-laptop = { + devices = 5; # Creates nix-laptop1 through nix-laptop5 }; -# Or for individual devices: -nix-desktop = { +# With configuration +nix-surface = { devices = { - "1".extraUsers = [ "myuser" "otheruser" ]; + "1".ugaif.sw.kioskUrl = "https://dashboard1.example.com"; + "2".ugaif.sw.kioskUrl = "https://dashboard2.example.com"; + }; +}; + +# With overrides for all devices +nix-desktop = { + devices = 3; + overrides = { + ugaif.users.student.enable = true; + ugaif.sw.extraPackages = with pkgs; [ vim ]; }; }; ``` -### User Configuration Options +**See [docs/INVENTORY.md](docs/INVENTORY.md) for complete host configuration guide.** -Each user in `users.nix` can have: +### Using External Configurations + +Users and systems can reference external Git repositories for configuration: ```nix +# In users.nix - External dotfiles 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) + description = "My Name"; 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 +# In inventory.nix - External system config nix-lxc = { - devices = { - "special-server" = builtins.fetchGit { - url = "https://github.com/org/server-config"; - rev = "abc123..."; - }; + devices."server" = builtins.fetchGit { + url = "https://github.com/org/server-config"; + rev = "abc123..."; }; }; ``` -**Create a template:** +**Create templates:** ```bash +# User configuration (dotfiles) +nix flake init -t github:UGA-Innovation-Factory/nixos-systems#user + +# System configuration nix flake init -t github:UGA-Innovation-Factory/nixos-systems#system ``` -## External Modules +**See [docs/EXTERNAL_MODULES.md](docs/EXTERNAL_MODULES.md) for complete guide.** -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: +### Building Installation Media ```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 +# Build installer ISO 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" -``` +# Build LXC container +nix build .#lxc-nix-builder -Result: `result/iso/nixos-*.iso` - -### Available Artifacts - -```bash -# List all available builds +# List all available artifacts 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 +**See [docs/BUILDING.md](docs/BUILDING.md) for complete guide on building ISOs, containers, and using remote builders.** -Speed up builds by offloading to a build server: +## System Types -```bash -# In ~/.config/nix/nix.conf or /etc/nix/nix.conf: -builders = ssh://engr-ugaif@nix-builder x86_64-linux +- **`desktop`** - Full GNOME desktop environment +- **`tablet-kiosk`** - Surface tablets in kiosk mode +- **`stateless-kiosk`** - Diskless PXE boot kiosks +- **`headless`** - Servers and containers (no GUI) -# Or use --builders flag for one-time builds -nix build ... --builders "ssh://engr-ugaif@nix-builder x86_64-linux" -``` +Set via `ugaif.sw.type` option. See [docs/NAMESPACE.md](docs/NAMESPACE.md) for all options. ## Development -### Testing Configuration Changes - -Before committing changes: - +**Quick commands:** ```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 . +nix flake check # Validate all configurations +nix fmt # Format code +nix flake update # Update dependencies +nix build .#installer-iso-nix-laptop1 # Build specific artifact ``` -### 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/`. +**See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for complete development guide.** ## Troubleshooting -### Common Issues +**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:** Run `nix flake check --show-trace` for details +- **External modules not loading:** Check repository access and module structure (see templates) +- **Remote build failures:** Test SSH access: `ssh engr-ugaif@nix-builder` +- **Out of disk space:** Run `nix-collect-garbage -d && nix store optimise` -**Build errors after flake update** +**Useful commands:** ```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 +nix flake show # List all available outputs +nix flake metadata # Show flake info +nix eval .#nixosConfigurations --apply builtins.attrNames # List all hosts ``` -**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, ... }` +**See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) and [docs/BUILDING.md](docs/BUILDING.md) for detailed troubleshooting.** -**Remote build failures** -```bash -# Test SSH access -ssh engr-ugaif@nix-builder +## Getting Help -# 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/` +- Review documentation in `docs/` directory +- Check 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 -``` diff --git a/USER_CONFIGURATION.md b/USER_CONFIGURATION.md deleted file mode 100644 index f9ef083..0000000 --- a/USER_CONFIGURATION.md +++ /dev/null @@ -1,288 +0,0 @@ -# External User Configuration - -This document explains how to use external modules for user configuration in nixos-systems. - -## Overview - -Users can now maintain their home-manager configurations in separate Git repositories and reference them from `users.nix` using `builtins.fetchGit`, similar to how external system configurations work. - -## Changes from Previous System - -### Before (Flakes) -```nix -hdh20267 = { - description = "Hunter Halloran"; - flakeUrl = "github:hdh20267/dotfiles"; -}; -``` - -### After (Modules with fetchGit) -```nix -hdh20267 = { - description = "Hunter Halloran"; - home = builtins.fetchGit { - url = "https://github.com/hdh20267/dotfiles"; - rev = "abc123..."; - }; -}; -``` - -## Configuration Methods - -### 1. External Repository (fetchGit) - -```nix -myuser = { - description = "My Name"; - extraGroups = [ "wheel" "networkmanager" ]; - home = builtins.fetchGit { - url = "https://github.com/username/dotfiles"; - rev = "commit-hash"; # For reproducibility - ref = "main"; # Optional branch - }; -}; -``` - -### 2. Local Path (for testing) - -```nix -myuser = { - description = "My Name"; - home = /home/username/dev/dotfiles; -}; -``` - -### 3. Inline Configuration - -```nix -myuser = { - description = "My Name"; - home = { - home.packages = with pkgs; [ vim git ]; - programs.git = { - enable = true; - userName = "My Name"; - }; - }; -}; -``` - -### 4. No External Config (legacy) - -```nix -myuser = { - description = "My Name"; - homePackages = [ pkgs.vim ]; - # home = null; # Default -}; -``` - -## External Repository Structure - -When using `fetchGit` or a path, the repository must contain: - -### Required: home.nix - -```nix -{ inputs, ... }: - -{ config, lib, pkgs, osConfig, ... }: - -{ - # Home-manager configuration - home.packages = with pkgs; [ ... ]; - programs.git = { ... }; -} -``` - -### Optional: nixos.nix - -```nix -{ inputs, ... }: - -{ config, lib, pkgs, ... }: - -{ - # System-level configuration (if needed) - users.users.myuser.extraGroups = [ "docker" ]; -} -``` - -## Integration with System - -External user modules: - -1. **Receive inputs**: Same flake inputs as nixos-systems (nixpkgs, home-manager, etc.) -2. **Access osConfig**: Can read system configuration via `osConfig` parameter -3. **Merged with system settings**: Combined with inventory.nix user settings -4. **System themes applied**: Zsh/nvim themes from system if enabled - -### Module Loading Order - -For home-manager configuration: -1. External module (`home.nix`) -2. System theme module (if `useZshTheme = true`) -3. System nvim config (if `useNvimPlugins = true`) - -For NixOS configuration: -1. User's NixOS module (`nixos.nix`, if exists) -2. All other system modules - -## Available Parameters - -In `home.nix`, you receive: -- `inputs` - Flake inputs (nixpkgs, home-manager, etc.) -- `config` - Home-manager configuration -- `lib` - Nixpkgs library functions -- `pkgs` - Package set -- `osConfig` - OS-level configuration (readonly) - -In `nixos.nix`, you receive: -- `inputs` - Flake inputs -- `config` - NixOS configuration -- `lib` - Nixpkgs library functions -- `pkgs` - Package set - -## User Options in users.nix - -When defining a user with external config: - -```nix -username = { - # Required - description = "Full Name"; - - # External configuration - home = builtins.fetchGit { ... }; - - # System settings (still configured here) - extraGroups = [ "wheel" ]; - hashedPassword = "$6$..."; - opensshKeys = [ "ssh-ed25519 ..." ]; - shell = pkgs.zsh; - - # Control system integration - useZshTheme = true; # Apply system zsh theme - useNvimPlugins = true; # Apply system nvim config - - # Legacy options (ignored if home is set) - homePackages = [ ]; # Use home.packages in home.nix instead - extraImports = [ ]; # Use imports in home.nix instead -}; -``` - -## Examples - -### Minimal Dotfiles Repository - -``` -my-dotfiles/ -├── home.nix -└── README.md -``` - -**home.nix:** -```nix -{ inputs, ... }: -{ config, lib, pkgs, ... }: -{ - home.packages = with pkgs; [ vim git htop ]; - - programs.git = { - enable = true; - userName = "My Name"; - userEmail = "me@example.com"; - }; -} -``` - -### With Dotfiles - -``` -my-dotfiles/ -├── home.nix -├── nixos.nix -├── dotfiles/ -│ ├── bashrc -│ └── vimrc -└── README.md -``` - -**home.nix:** -```nix -{ inputs, ... }: -{ config, lib, pkgs, ... }: -{ - home.file.".bashrc".source = ./dotfiles/bashrc; - home.file.".vimrc".source = ./dotfiles/vimrc; - - programs.git = { - enable = true; - userName = "My Name"; - userEmail = "me@example.com"; - }; -} -``` - -### With System Configuration - -**nixos.nix:** -```nix -{ inputs, ... }: -{ config, lib, pkgs, ... }: -{ - # Add user to docker group - users.users.myusername.extraGroups = [ "docker" ]; - - # Install system-level packages - environment.systemPackages = [ pkgs.docker ]; -} -``` - -## Migration Guide - -### From flakeUrl to home - -1. **Update users.nix:** - ```diff - - flakeUrl = "github:user/dotfiles"; - + home = builtins.fetchGit { - + url = "https://github.com/user/dotfiles"; - + rev = "latest-commit-hash"; - + }; - ``` - -2. **Update your dotfiles repository:** - - Rename or ensure you have `home.nix` (not `flake.nix`) - - Change module signature from flake to simple module: - ```diff - - { inputs, outputs, ... }: - + { inputs, ... }: - { config, lib, pkgs, ... }: - ``` - -3. **Optional: Add nixos.nix** for system-level config - -4. **Test locally first:** - ```nix - home = /path/to/local/dotfiles; - ``` - -5. **Deploy:** - ```bash - nix flake check - ./deploy hostname - ``` - -## Benefits - -- **No Flakes Required**: Simpler for users unfamiliar with flakes -- **Explicit Versioning**: Pin to specific commits with `rev` -- **Faster Evaluation**: No flake evaluation overhead -- **Local Testing**: Easy to test with local paths -- **Flexibility**: Supports Git, paths, or inline configs -- **Reproducibility**: Commit hashes ensure exact versions - -## Templates - -See `/home/engr-ugaif/user-config-template/` for templates and detailed examples. diff --git a/docs/BUILDING.md b/docs/BUILDING.md new file mode 100644 index 0000000..a523ec4 --- /dev/null +++ b/docs/BUILDING.md @@ -0,0 +1,264 @@ +# Building Installation Media + +This guide covers building installer ISOs, live images, and container artifacts from the nixos-systems flake. + +## Table of Contents + +- [Quick Start](#quick-start) +- [Available Artifacts](#available-artifacts) +- [Installer ISOs](#installer-isos) +- [Live ISOs](#live-isos) +- [Container Images](#container-images) +- [Remote Builders](#remote-builders) +- [Troubleshooting](#troubleshooting) + +## Quick Start + +```bash +# Build an installer ISO for a specific host +nix build github:UGA-Innovation-Factory/nixos-systems#installer-iso-nix-laptop1 + +# Result will be in result/iso/ +ls -lh result/iso/ +``` + +## Available Artifacts + +List all available build outputs: + +```bash +nix flake show github:UGA-Innovation-Factory/nixos-systems +``` + +Common artifact types: + +| Artifact Type | Description | Example | +|--------------|-------------|---------| +| `installer-iso-*` | Auto-install ISO that installs configuration to disk | `installer-iso-nix-laptop1` | +| `iso-*` | Live ISO (bootable without installation) | `iso-nix-ephemeral1` | +| `ipxe-*` | iPXE netboot artifacts (kernel, initrd, script) | `ipxe-nix-ephemeral1` | +| `lxc-*` | LXC container tarball | `lxc-nix-builder` | +| `proxmox-*` | Proxmox VMA archive | `proxmox-nix-builder` | + +## Installer ISOs + +Installer ISOs automatically install the NixOS configuration to disk on first boot. + +### Building Locally + +```bash +# Build installer for a specific host +nix build .#installer-iso-nix-laptop1 + +# Result location +ls -lh result/iso/nixos-*.iso + +# Copy to USB drive (replace /dev/sdX with your USB device) +sudo dd if=result/iso/nixos-*.iso of=/dev/sdX bs=4M status=progress +``` + +### Building from GitHub + +```bash +nix build github:UGA-Innovation-Factory/nixos-systems#installer-iso-nix-laptop1 +``` + +### Using the Installer + +1. Boot from the ISO +2. The system will automatically partition the disk and install NixOS +3. After installation completes, remove the USB drive and reboot +4. Log in with the configured user credentials + +**Note:** The installer will **erase all data** on the target disk specified in `ugaif.host.filesystem.device`. + +## Live ISOs + +Live ISOs boot into a temporary system without installing to disk. Useful for: +- Testing configurations +- Recovery operations +- Ephemeral/stateless systems + +### Building Live ISOs + +```bash +# Build live ISO +nix build .#iso-nix-ephemeral1 + +# Result location +ls -lh result/iso/nixos-*.iso +``` + +### Stateless Kiosk Systems + +For PXE netboot kiosks, use the `ipxe-*` artifacts: + +```bash +# Build iPXE artifacts +nix build .#ipxe-nix-ephemeral1 + +# Result contains: +# - bzImage (kernel) +# - initrd (initial ramdisk) +# - netboot.ipxe (iPXE script) +ls -lh result/ +``` + +## Container Images + +### LXC Containers + +Build LXC container tarballs for Proxmox or other LXC hosts: + +```bash +# Build LXC tarball +nix build .#lxc-nix-builder + +# Result location +ls -lh result/tarball/nixos-*.tar.xz +``` + +**Importing to Proxmox:** + +```bash +# Copy tarball to Proxmox host +scp result/tarball/nixos-*.tar.xz root@proxmox:/var/lib/vz/template/cache/ + +# Create container from Proxmox CLI +pct create 100 local:vztmpl/nixos-*.tar.xz \ + --hostname nix-builder \ + --memory 4096 \ + --cores 4 \ + --net0 name=eth0,bridge=vmbr0,ip=dhcp +``` + +See [installer/PROXMOX_LXC.md](../installer/PROXMOX_LXC.md) for detailed Proxmox deployment instructions. + +### Proxmox VMA + +Build Proxmox-specific VMA archives: + +```bash +# Build Proxmox VMA +nix build .#proxmox-nix-builder + +# Result location +ls -lh result/ +``` + +## Remote Builders + +Speed up builds by offloading to build servers. + +### One-Time Remote Build + +```bash +nix build .#installer-iso-nix-laptop1 \ + --builders "ssh://engr-ugaif@nix-builder x86_64-linux" +``` + +### Persistent Configuration + +Add to `~/.config/nix/nix.conf` or `/etc/nix/nix.conf`: + +```conf +builders = ssh://engr-ugaif@nix-builder x86_64-linux +``` + +Then build normally: + +```bash +nix build .#installer-iso-nix-laptop1 +``` + +### SSH Key Setup + +For remote builders, ensure SSH keys are configured: + +```bash +# Generate SSH key if needed +ssh-keygen -t ed25519 + +# Copy to builder +ssh-copy-id engr-ugaif@nix-builder + +# Test connection +ssh engr-ugaif@nix-builder +``` + +### Multiple Builders + +Configure multiple build servers: + +```conf +builders = ssh://engr-ugaif@nix-builder x86_64-linux ; ssh://engr-ugaif@nix-builder2 x86_64-linux +``` + +## Troubleshooting + +### Build Errors + +**Check configuration validity:** +```bash +nix flake check --show-trace +``` + +**Test specific host build:** +```bash +nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel +``` + +### Remote Builder Issues + +**Test SSH access:** +```bash +ssh engr-ugaif@nix-builder +``` + +**Check builder disk space:** +```bash +ssh engr-ugaif@nix-builder df -h +``` + +**Temporarily disable remote builds:** + +In `inventory.nix`: +```nix +ugaif.sw.remoteBuild.enable = false; +``` + +### Out of Disk Space + +**Clean up Nix store:** +```bash +nix-collect-garbage -d +nix store optimise +``` + +**Check space:** +```bash +df -h /nix +``` + +### ISO Won't Boot + +**Verify ISO integrity:** +```bash +sha256sum result/iso/nixos-*.iso +``` + +**Check USB write:** +```bash +# Use correct block size and sync +sudo dd if=result/iso/nixos-*.iso of=/dev/sdX bs=4M status=progress && sync +``` + +**Try alternative boot mode:** +- UEFI systems: Try legacy BIOS mode +- Legacy BIOS: Try UEFI mode + +## See Also + +- [README.md](../README.md) - Main documentation +- [INVENTORY.md](INVENTORY.md) - Host configuration guide +- [installer/PROXMOX_LXC.md](../installer/PROXMOX_LXC.md) - Proxmox deployment guide diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md new file mode 100644 index 0000000..28b947c --- /dev/null +++ b/docs/DEVELOPMENT.md @@ -0,0 +1,355 @@ +# Development Guide + +This guide covers development workflows for maintaining and extending the nixos-systems repository. + +## Table of Contents + +- [Prerequisites](#prerequisites) +- [Testing Changes](#testing-changes) +- [System Rebuilds](#system-rebuilds) +- [Updating Dependencies](#updating-dependencies) +- [Adding Packages](#adding-packages) +- [Python Development](#python-development) +- [Contributing](#contributing) + +## Prerequisites + +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 manually) +sh <(curl -L https://nixos.org/nix/install) --daemon +``` + +## Testing Changes + +Always test configuration changes before committing. + +### Validate All Configurations + +```bash +# Check all configurations build correctly +nix flake check + +# Check with verbose error traces +nix flake check --show-trace +``` + +### Test Specific Host Build + +```bash +# Build a specific host's configuration +nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel + +# Build installer for specific host +nix build .#installer-iso-nix-laptop1 +``` + +### Test Local Changes + +If you're on a NixOS system managed by this flake: + +```bash +# Test changes without committing (temporary, doesn't survive reboot) +sudo nixos-rebuild test --flake . + +# Apply and switch to new configuration +sudo nixos-rebuild switch --flake . + +# Build without switching +sudo nixos-rebuild build --flake . +``` + +## System Rebuilds + +### From Local Directory + +```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 + +# Build a new generation without activating it +sudo nixos-rebuild build --flake . +``` + +### From GitHub + +```bash +# Rebuild from GitHub main branch +sudo nixos-rebuild switch --flake github:UGA-Innovation-Factory/nixos-systems + +# Use --impure for external user configurations with fetchGit +sudo nixos-rebuild switch --flake github:UGA-Innovation-Factory/nixos-systems --impure + +# Rebuild specific host from GitHub +sudo nixos-rebuild switch --flake github:UGA-Innovation-Factory/nixos-systems#nix-laptop1 +``` + +### Boot into Previous Generation + +If something breaks: + +```bash +# List generations +sudo nixos-rebuild list-generations + +# Rollback to previous generation +sudo nixos-rebuild switch --rollback + +# Or select specific generation at boot (GRUB menu) +# Reboot and select "NixOS - Configuration X" from boot menu +``` + +## Updating Dependencies + +### Update All Inputs + +```bash +# Update all flake inputs (nixpkgs, home-manager, etc.) +nix flake update + +# Review changes +git diff flake.lock + +# Test the updates +nix flake check + +# Commit if successful +git add flake.lock +git commit -m "Update flake inputs" +git push +``` + +### Update Specific Input + +```bash +# Update only nixpkgs +nix flake lock --update-input nixpkgs + +# Update home-manager +nix flake lock --update-input home-manager + +# Update multiple specific inputs +nix flake lock --update-input nixpkgs --update-input home-manager +``` + +### Check for Security Updates + +```bash +# After updating, check for known vulnerabilities +nix flake check + +# Review nixpkgs changelog +git log HEAD..nixpkgs/nixos-25.11 --oneline | head -20 +``` + +## Adding Packages + +### System-Wide Packages by Type + +Add packages based on system type: + +**Desktop systems:** +```bash +# Edit sw/desktop/programs.nix +vim sw/desktop/programs.nix +``` + +**Tablet kiosks:** +```bash +# Edit sw/tablet-kiosk/programs.nix +vim sw/tablet-kiosk/programs.nix +``` + +**Headless systems:** +```bash +# Edit sw/headless/programs.nix +vim sw/headless/programs.nix +``` + +### Packages for Specific Hosts + +Add to `ugaif.sw.extraPackages` in `inventory.nix`: + +```nix +nix-laptop = { + devices = 2; + overrides = { + ugaif.sw.extraPackages = with pkgs; [ + vim + docker + kubernetes-helm + ]; + }; +}; +``` + +### User-Specific Packages + +Add to user's home-manager configuration in `users.nix` or external dotfiles: + +```nix +myuser = { + homePackages = with pkgs; [ + ripgrep + fd + bat + ]; +}; +``` + +### Search for Packages + +```bash +# Search nixpkgs +nix search nixpkgs firefox +nix search nixpkgs python3 + +# Show package details +nix eval nixpkgs#firefox.meta.description +``` + +## Python Development + +All systems include modern Python tools: `pixi` and `uv`. + +### Pixi (Recommended for Projects) + +```bash +# Initialize new project +pixi init my-project +cd my-project + +# Add dependencies +pixi add pandas numpy matplotlib jupyter + +# Run Python +pixi run python + +# Run Jupyter +pixi run jupyter notebook + +# Run scripts +pixi run python script.py + +# Shell with dependencies +pixi shell +``` + +### uv (Quick Virtual Environments) + +```bash +# Create virtual environment +uv venv + +# Activate +source .venv/bin/activate + +# Install packages +uv pip install requests pandas + +# Freeze requirements +uv pip freeze > requirements.txt + +# Install from requirements +uv pip install -r requirements.txt +``` + +### System Python + +Python development tools are configured in `sw/python.nix` and can be controlled via: + +```nix +ugaif.sw.python.enable = true; # Default: enabled +``` + +## Contributing + +### Code Style + +- Run formatter before committing: `nix fmt` +- Follow existing code structure and conventions +- Add comments for complex logic +- Use the `ugaif.*` namespace for all custom options + +### Testing Workflow + +1. Make changes +2. Run formatter: `nix fmt` +3. Test locally: `nix flake check` +4. Test specific builds if needed +5. Commit changes +6. Push to GitHub + +```bash +# Full workflow +nix fmt +nix flake check +git add . +git commit -m "Description of changes" +git push +``` + +### Documentation + +Update relevant documentation when making changes: + +- `README.md` - Overview and quick start +- `docs/INVENTORY.md` - Inventory configuration +- `docs/NAMESPACE.md` - Configuration options +- `USER_CONFIGURATION.md` - User management +- `EXTERNAL_MODULES.md` - External modules + +### Creating Issues + +When reporting bugs or requesting features: + +1. Check existing issues first +2. Provide clear description +3. Include error messages and traces +4. Specify which hosts are affected +5. Include `flake.lock` info if relevant + +## Useful Commands + +```bash +# Show all available outputs +nix flake show + +# Evaluate 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 + +# Show evaluation trace +nix eval --show-trace .#nixosConfigurations.nix-laptop1 + +# Build and enter debug shell +nix develop + +# Clean up old generations +nix-collect-garbage -d + +# Optimize Nix store +nix store optimise +``` + +## See Also + +- [README.md](../README.md) - Main documentation +- [INVENTORY.md](INVENTORY.md) - Host inventory configuration +- [BUILDING.md](BUILDING.md) - Building installation media +- [USER_CONFIGURATION.md](USER_CONFIGURATION.md) - User management diff --git a/docs/EXTERNAL_MODULES.md b/docs/EXTERNAL_MODULES.md new file mode 100644 index 0000000..30a06ff --- /dev/null +++ b/docs/EXTERNAL_MODULES.md @@ -0,0 +1,418 @@ +# External Configuration Modules + +This guide explains how to use external modules for system and user configurations in nixos-systems. + +## Table of Contents + +- [Overview](#overview) +- [System Modules](#system-modules) +- [User Modules](#user-modules) +- [Fetch Methods](#fetch-methods) +- [Templates](#templates) +- [Integration Details](#integration-details) + +## 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). + +**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 + +## System Modules + +External system modules provide complete NixOS configurations for hosts. + +### Usage in inventory.nix + +```nix +nix-lxc = { + devices = { + # Traditional inline configuration + "local-server" = { + ugaif.users.admin.enable = true; + services.nginx.enable = true; + }; + + # External module from Git + "remote-server" = builtins.fetchGit { + url = "https://github.com/org/server-config"; + rev = "abc123..."; # Pin to specific commit + }; + }; +}; +``` + +### External Repository Structure + +``` +server-config/ +├── default.nix # Required: NixOS module +└── README.md # Optional: Documentation +``` + +**default.nix:** +```nix +{ inputs, ... }: +{ config, lib, pkgs, ... }: +{ + # Your NixOS configuration + services.nginx = { + enable = true; + virtualHosts."example.com" = { + root = "/var/www"; + }; + }; + + # Use ugaif namespace options + ugaif.users.admin.enable = true; + ugaif.sw.type = "headless"; +} +``` + +### What External Modules Receive + +- **`inputs`** - All flake inputs (nixpkgs, home-manager, etc.) +- **`config`** - Full NixOS configuration +- **`lib`** - Nixpkgs library functions +- **`pkgs`** - Package set + +### Module Integration Order + +When a host is built, modules are loaded 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`) + +Later modules can override earlier ones using standard NixOS module precedence. + +### Template + +Create a new system module: + +```bash +nix flake init -t github:UGA-Innovation-Factory/nixos-systems#system +``` + +See [templates/system/](../templates/system/) for the complete template. + +## User Modules + +External user modules provide home-manager configurations (dotfiles, packages, programs). + +### Usage in users.nix + +```nix +ugaif.users = { + myuser = { + description = "My Name"; + extraGroups = [ "wheel" "networkmanager" ]; + hashedPassword = "$6$..."; + + # External home-manager configuration + home = builtins.fetchGit { + url = "https://github.com/username/dotfiles"; + rev = "abc123..."; + }; + }; +}; +``` + +### External Repository Structure + +``` +dotfiles/ +├── home.nix # Required: Home-manager config +├── nixos.nix # Optional: System-level config +└── dotfiles/ # Optional: Actual dotfiles + ├── bashrc + └── vimrc +``` + +**home.nix (required):** +```nix +{ inputs, ... }: +{ config, lib, pkgs, osConfig, ... }: +{ + # Home-manager configuration + home.packages = with pkgs; [ vim git htop ]; + + programs.git = { + enable = true; + userName = "My Name"; + userEmail = "me@example.com"; + }; + + # Manage dotfiles + home.file.".bashrc".source = ./dotfiles/bashrc; +} +``` + +**nixos.nix (optional):** +```nix +{ inputs, ... }: +{ config, lib, pkgs, ... }: +{ + # System-level configuration for this user + users.users.myuser.extraGroups = [ "docker" ]; + environment.systemPackages = [ pkgs.docker ]; +} +``` + +### What User Modules Receive + +**In home.nix:** +- **`inputs`** - Flake inputs (nixpkgs, home-manager, etc.) +- **`config`** - Home-manager configuration +- **`lib`** - Nixpkgs library functions +- **`pkgs`** - Package set +- **`osConfig`** - OS-level configuration (read-only) + +**In nixos.nix:** +- **`inputs`** - Flake inputs +- **`config`** - NixOS configuration +- **`lib`** - Nixpkgs library functions +- **`pkgs`** - Package set + +### User Options in users.nix + +```nix +username = { + # Identity + description = "Full Name"; + + # External configuration + home = 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 ugaif.users.username.enable +}; +``` + +### Template + +Create a new user module: + +```bash +nix flake init -t github:UGA-Innovation-Factory/nixos-systems#user +``` + +See [templates/user/](../templates/user/) for the complete template. + +## Fetch Methods + +### Recommended: fetchGit with Revision + +Pin to a specific commit for reproducibility: + +```nix +builtins.fetchGit { + url = "https://github.com/user/repo"; + rev = "abc123def456..."; # Full commit hash (40 characters) + ref = "main"; # Optional: branch name +} +``` + +**Finding the commit hash:** +```bash +# Latest commit on main branch +git ls-remote https://github.com/user/repo main + +# Or from a local clone +git rev-parse HEAD +``` + +### 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) + +Download specific release archives: + +```nix +builtins.fetchTarball { + url = "https://github.com/user/repo/archive/v1.0.0.tar.gz"; + sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; +} +``` + +**Get the hash:** +```bash +nix-prefetch-url --unpack https://github.com/user/repo/archive/v1.0.0.tar.gz +``` + +### Local Path (For Testing) + +Use local directories during development: + +```nix +/home/username/dev/my-config + +# 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 github:UGA-Innovation-Factory/nixos-systems#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 github:UGA-Innovation-Factory/nixos-systems#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 `ugaif.*` namespace options. + +### User Module Integration + +External user modules are loaded separately for home-manager (`home.nix`) and NixOS (`nixos.nix` if it exists): + +**Home-manager:** +```nix +import (externalHomePath + "/home.nix") { inherit inputs; } +``` + +**NixOS (optional):** +```nix +import (externalHomePath + "/nixos.nix") { inherit inputs; } +``` + +### Combining External and Local Config + +You can mix external modules with local overrides: + +```nix +nix-lxc = { + devices = { + "server" = builtins.fetchGit { + url = "https://github.com/org/base-config"; + rev = "abc123..."; + }; + }; + overrides = { + # Apply to all devices, including external ones + ugaif.users.admin.enable = true; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + }; +}; +``` + +## Examples + +### Minimal System Module + +**default.nix:** +```nix +{ inputs, ... }: +{ config, lib, pkgs, ... }: +{ + ugaif.sw.type = "headless"; + services.nginx.enable = true; +} +``` + +### Minimal User Module + +**home.nix:** +```nix +{ inputs, ... }: +{ config, lib, pkgs, ... }: +{ + home.packages = with pkgs; [ vim git ]; +} +``` + +### Full User Module with Dotfiles + +``` +dotfiles/ +├── home.nix +├── nixos.nix +└── config/ + ├── bashrc + ├── vimrc + └── gitconfig +``` + +**home.nix:** +```nix +{ inputs, ... }: +{ config, lib, pkgs, ... }: +{ + home.packages = with pkgs; [ ripgrep fd bat ]; + + home.file = { + ".bashrc".source = ./config/bashrc; + ".vimrc".source = ./config/vimrc; + ".gitconfig".source = ./config/gitconfig; + }; +} +``` + +## See Also + +- [docs/INVENTORY.md](INVENTORY.md) - Host configuration guide +- [docs/NAMESPACE.md](NAMESPACE.md) - Configuration options reference +- [templates/system/](../templates/system/) - System module template +- [templates/user/](../templates/user/) - User module template +- [README.md](../README.md) - Main documentation diff --git a/docs/INVENTORY.md b/docs/INVENTORY.md new file mode 100644 index 0000000..1cb4302 --- /dev/null +++ b/docs/INVENTORY.md @@ -0,0 +1,190 @@ +# Host Inventory Configuration + +This guide explains how to configure hosts in `inventory.nix` to define your fleet of devices. + +## Table of Contents + +- [Understanding Inventory Structure](#understanding-inventory-structure) +- [Hostname Generation Rules](#hostname-generation-rules) +- [Adding Hosts](#adding-hosts) +- [Device Configuration Options](#device-configuration-options) +- [Examples](#examples) + +## Understanding Inventory Structure + +The `inventory.nix` file defines all hosts in the fleet using a flexible system. Top-level keys are always hostname **prefixes**, and actual hostnames are generated from device configurations. + +## 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`) +- **Custom hostnames**: 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 + ugaif.users.student.enable = true; + 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 + +### Direct Configuration (Recommended) + +Use any NixOS or `ugaif.*` option: + +```nix +"1" = { + # UGAIF options + ugaif.users.myuser.enable = true; + 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 enables the user account. + +### External System Configuration + +For complex configurations, use external modules (see [EXTERNAL_MODULES.md](../EXTERNAL_MODULES.md)): + +```nix +nix-lxc = { + devices = { + "special-server" = builtins.fetchGit { + url = "https://github.com/org/server-config"; + rev = "abc123..."; + }; + }; +}; +``` + +## Examples + +### Simple Lab Computers + +```nix +nix-laptop = { + devices = 10; # Creates nix-laptop1 through nix-laptop10 + overrides = { + ugaif.users.student.enable = true; + }; +}; +``` + +### Mixed Surface Tablets + +```nix +nix-surface = { + defaultCount = 5; # nix-surface1 through nix-surface5 (default config) + devices = { + "admin" = { # nix-surface-admin (special config) + ugaif.sw.type = "desktop"; # Full desktop instead of kiosk + ugaif.users.admin.enable = true; + }; + }; + overrides = { + ugaif.sw.type = "tablet-kiosk"; + ugaif.sw.kioskUrl = "https://dashboard.factory.uga.edu"; + }; +}; +``` + +### LXC Containers + +```nix +nix-lxc = { + devices = { + "nix-builder" = { + ugaif.sw.type = "headless"; + }; + "webserver" = { + ugaif.sw.type = "headless"; + services.nginx.enable = true; + }; + }; + overrides = { + ugaif.host.useHostPrefix = false; # Use exact device key as hostname + }; +}; +``` + +### WSL Instances + +```nix +nix-wsl = { + devices = { + "alice".ugaif.forUser = "alice-uga"; + "bob".ugaif.forUser = "bob-uga"; + }; +}; +``` + +## See Also + +- [USER_CONFIGURATION.md](USER_CONFIGURATION.md) - User account management +- [EXTERNAL_MODULES.md](EXTERNAL_MODULES.md) - External configuration modules +- [Configuration Namespace Reference](NAMESPACE.md) - All `ugaif.*` options diff --git a/docs/NAMESPACE.md b/docs/NAMESPACE.md new file mode 100644 index 0000000..1824e8e --- /dev/null +++ b/docs/NAMESPACE.md @@ -0,0 +1,275 @@ +# Configuration Namespace Reference + +All UGA Innovation Factory-specific options are under the `ugaif` namespace to avoid conflicts with standard NixOS options. + +## Table of Contents + +- [Host Configuration (`ugaif.host`)](#host-configuration-ugaifhost) +- [Software Configuration (`ugaif.sw`)](#software-configuration-ugaifsw) +- [User Management (`ugaif.users`)](#user-management-ugaifusers) +- [System Configuration (`ugaif.system`)](#system-configuration-ugaifsystem) +- [Convenience Options](#convenience-options) + +## Host Configuration (`ugaif.host`) + +Hardware and host-specific settings. + +### `ugaif.host.filesystem` + +Disk and storage configuration. + +**Options:** +- `ugaif.host.filesystem.device` - Boot disk device (default: `/dev/sda`) +- `ugaif.host.filesystem.swapSize` - Swap file size (default: `"32G"`) + +**Example:** +```nix +ugaif.host.filesystem = { + device = "/dev/nvme0n1"; + swapSize = "64G"; +}; +``` + +### `ugaif.host.buildMethods` + +List of supported build artifact types for this host. + +**Type:** List of strings + +**Options:** `"installer-iso"`, `"iso"`, `"ipxe"`, `"lxc"`, `"proxmox"` + +**Default:** `["installer-iso"]` + +**Example:** +```nix +ugaif.host.buildMethods = [ "lxc" "proxmox" ]; +``` + +### `ugaif.host.useHostPrefix` + +Whether to prepend the host type prefix to the hostname (used in inventory generation). + +**Type:** Boolean + +**Default:** `true` + +**Example:** +```nix +ugaif.host.useHostPrefix = false; # "builder" instead of "nix-lxc-builder" +``` + +### `ugaif.host.wsl` + +WSL-specific configuration options. + +**Options:** +- `ugaif.host.wsl.user` - Default WSL user for this instance + +**Example:** +```nix +ugaif.host.wsl.user = "myusername"; +``` + +## Software Configuration (`ugaif.sw`) + +System software and application configuration. + +### `ugaif.sw.enable` + +Enable the software configuration module. + +**Type:** Boolean + +**Default:** `true` + +### `ugaif.sw.type` + +System type that determines the software profile. + +**Type:** Enum + +**Options:** +- `"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 + +**Default:** `"desktop"` + +**Example:** +```nix +ugaif.sw.type = "headless"; +``` + +### `ugaif.sw.kioskUrl` + +URL to display in kiosk mode browsers (for `tablet-kiosk` and `stateless-kiosk` types). + +**Type:** String + +**Default:** `"https://ha.factory.uga.edu"` + +**Example:** +```nix +ugaif.sw.kioskUrl = "https://dashboard.example.com"; +``` + +### `ugaif.sw.python` + +Python development tools configuration. + +**Options:** +- `ugaif.sw.python.enable` - Enable Python tools (pixi, uv) (default: `true`) + +**Example:** +```nix +ugaif.sw.python.enable = true; +``` + +### `ugaif.sw.remoteBuild` + +Remote build server configuration for offloading builds. + +**Options:** +- `ugaif.sw.remoteBuild.enable` - Use remote builders (default: enabled on tablets) +- `ugaif.sw.remoteBuild.hosts` - List of build server hostnames + +**Example:** +```nix +ugaif.sw.remoteBuild = { + enable = true; + hosts = [ "nix-builder" "nix-builder2" ]; +}; +``` + +### `ugaif.sw.extraPackages` + +Additional system packages to install beyond the type defaults. + +**Type:** List of packages + +**Default:** `[]` + +**Example:** +```nix +ugaif.sw.extraPackages = with pkgs; [ + vim + htop + docker +]; +``` + +### `ugaif.sw.excludePackages` + +Packages to exclude from the default list for this system type. + +**Type:** List of packages + +**Default:** `[]` + +**Example:** +```nix +ugaif.sw.excludePackages = with pkgs; [ + firefox # Remove Firefox from default desktop packages +]; +``` + +## User Management (`ugaif.users`) + +User account configuration and management. + +### `ugaif.users..enable` + +Enable a specific user account on this system. + +**Type:** Boolean + +**Default:** `false` (except `root` and `engr-ugaif` which default to `true`) + +**Example:** +```nix +ugaif.users = { + myuser.enable = true; + student.enable = true; +}; +``` + +### User Account Options + +Each user in `users.nix` can be configured with: + +```nix +ugaif.users.myuser = { + description = "Full Name"; + isNormalUser = true; # Default: true + extraGroups = [ "wheel" "docker" ]; # Additional groups + shell = pkgs.zsh; # Login shell + hashedPassword = "$6$..."; # Hashed password + opensshKeys = [ "ssh-ed25519 ..." ]; # SSH public keys + homePackages = with pkgs; [ ... ]; # User packages + useZshTheme = true; # Use system Zsh theme + useNvimPlugins = true; # Use system Neovim config + + # External home-manager configuration (optional) + home = builtins.fetchGit { + url = "https://github.com/username/dotfiles"; + rev = "abc123..."; + }; + + enable = false; # Enable per-system in inventory.nix +}; +``` + +## System Configuration (`ugaif.system`) + +System-wide settings and services. + +### `ugaif.system.gc` + +Automatic garbage collection configuration. + +**Options:** +- `ugaif.system.gc.enable` - Enable automatic garbage collection (default: `true`) +- `ugaif.system.gc.frequency` - How often to run (default: `"weekly"`) +- `ugaif.system.gc.retentionDays` - Days to keep old generations (default: `30`) +- `ugaif.system.gc.optimise` - Optimize Nix store automatically (default: `true`) + +**Example:** +```nix +ugaif.system.gc = { + enable = true; + frequency = "daily"; + retentionDays = 14; + optimise = true; +}; +``` + +## Convenience Options + +### `ugaif.forUser` + +Quick setup option that enables a user account in one line. + +**Type:** String (username) or null + +**Default:** `null` + +**Example:** +```nix +ugaif.forUser = "myusername"; # Equivalent to ugaif.users.myusername.enable = true +``` + +**Usage in inventory.nix:** +```nix +nix-wsl = { + devices = { + "alice".ugaif.forUser = "alice-uga"; + }; +}; +``` + +## See Also + +- [INVENTORY.md](INVENTORY.md) - Host inventory configuration guide +- [USER_CONFIGURATION.md](../USER_CONFIGURATION.md) - User management guide +- [README.md](../README.md) - Main documentation diff --git a/docs/USER_CONFIGURATION.md b/docs/USER_CONFIGURATION.md new file mode 100644 index 0000000..0e7321d --- /dev/null +++ b/docs/USER_CONFIGURATION.md @@ -0,0 +1,486 @@ +# User Configuration Guide + +Complete guide to managing user accounts in nixos-systems. + +## Table of Contents + +- [Overview](#overview) +- [Quick Start](#quick-start) +- [User Account Options](#user-account-options) +- [External User Configurations](#external-user-configurations) +- [Enabling Users on Hosts](#enabling-users-on-hosts) +- [Password Management](#password-management) +- [SSH Keys](#ssh-keys) +- [Examples](#examples) + +## Overview + +Users are defined in `users.nix` but are **not enabled by default** on all systems. Each system must explicitly enable users in `inventory.nix`. + +**Default enabled users:** +- `root` - System administrator +- `engr-ugaif` - Innovation Factory default account + +## Quick Start + +### 1. Define User in users.nix + +```nix +ugaif.users = { + myuser = { + description = "My Full Name"; + extraGroups = [ "wheel" "networkmanager" ]; + shell = pkgs.zsh; + hashedPassword = "$6$..."; # Generate with: mkpasswd -m sha-512 + opensshKeys = [ + "ssh-ed25519 AAAA... user@machine" + ]; + }; +}; +``` + +### 2. Enable User on Hosts + +In `inventory.nix`: + +```nix +nix-laptop = { + devices = 2; + overrides.ugaif.users.myuser.enable = true; # Enables on all nix-laptop hosts +}; + +# Or for specific devices +nix-desktop = { + devices = { + "1".ugaif.users.myuser.enable = true; + "2".ugaif.users.otheruser.enable = true; + }; +}; + +# Or use convenience option +nix-wsl = { + devices."alice".ugaif.forUser = "alice-user"; # Automatically enables user +}; +``` + +## User Account Options + +Each user in `users.nix` can have the following options: + +```nix +username = { + # === Identity === + description = "Full Name"; # User's full name + + # === System Access === + isNormalUser = true; # Default: true (false for root) + extraGroups = [ # Additional Unix groups + "wheel" # Sudo access + "networkmanager" # Network configuration + "docker" # Docker access + "video" # Video device access + "audio" # Audio device access + ]; + shell = pkgs.zsh; # Login shell (default: pkgs.bash) + hashedPassword = "$6$..."; # Hashed password (see below) + + # === SSH Access === + opensshKeys = [ # SSH public keys + "ssh-ed25519 AAAA... user@host" + "ssh-rsa AAAA... user@otherhost" + ]; + + # === Home Configuration === + home = builtins.fetchGit { ... }; # External home-manager config (see below) + + # OR (if not using external config): + homePackages = with pkgs; [ # User packages + ripgrep + fd + bat + ]; + extraImports = [ ./my-module.nix ]; # Additional home-manager modules + + # === Theme Integration === + useZshTheme = true; # Apply system Zsh theme (default: true) + useNvimPlugins = true; # Apply system Neovim config (default: true) + + # === System Enablement === + enable = false; # Enable on this system (set in inventory.nix) +}; +``` + +## External User Configurations + +Users can maintain their dotfiles and home-manager configuration in separate Git repositories. + +### Basic External Configuration + +In `users.nix`: + +```nix +myuser = { + description = "My Name"; + extraGroups = [ "wheel" ]; + hashedPassword = "$6$..."; + + # Point to external dotfiles repository + 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 configuration +└── config/ # Optional: Your dotfiles + ├── bashrc + ├── vimrc + └── ... +``` + +**home.nix (required):** +```nix +{ inputs, ... }: +{ config, lib, pkgs, osConfig, ... }: +{ + home.packages = with pkgs; [ vim git htop ]; + + programs.git = { + enable = true; + userName = "My Name"; + userEmail = "me@example.com"; + }; + + home.file.".bashrc".source = ./config/bashrc; +} +``` + +**nixos.nix (optional):** +```nix +{ inputs, ... }: +{ config, lib, pkgs, ... }: +{ + # System-level configuration + users.users.myusername.extraGroups = [ "docker" ]; + environment.systemPackages = [ pkgs.docker ]; +} +``` + +### What External Modules Receive + +**In home.nix:** +- `inputs` - Flake inputs (nixpkgs, home-manager, etc.) +- `config` - Home-manager configuration +- `lib` - Nixpkgs library functions +- `pkgs` - Package set +- `osConfig` - OS-level configuration (read-only) + +**In nixos.nix:** +- `inputs` - Flake inputs +- `config` - NixOS configuration +- `lib` - Nixpkgs library functions +- `pkgs` - Package set + +### Alternative Configuration Methods + +**Local path (for testing):** +```nix +home = /home/username/dev/dotfiles; +``` + +**Inline configuration:** +```nix +home = { + home.packages = with pkgs; [ vim ]; + programs.git.enable = true; +}; +``` + +**No external config (legacy):** +```nix +homePackages = with pkgs; [ vim git ]; +# home = null; # Default +``` + +### Create User Template + +```bash +nix flake init -t github:UGA-Innovation-Factory/nixos-systems#user +``` + +See [templates/user/README.md](../templates/user/README.md) for complete template. + +## Enabling Users on Hosts + +Users must be explicitly enabled on each host in `inventory.nix`. + +### Method 1: Enable in Overrides (All Devices) + +```nix +nix-laptop = { + devices = 5; + overrides = { + ugaif.users.student.enable = true; # All 5 laptops get this user + }; +}; +``` + +### Method 2: Enable per Device + +```nix +nix-desktop = { + devices = { + "1".ugaif.users.alice.enable = true; + "2".ugaif.users.bob.enable = true; + "3" = { + ugaif.users.alice.enable = true; + ugaif.users.bob.enable = true; + }; + }; +}; +``` + +### Method 3: Convenience Option (ugaif.forUser) + +Quick setup for single-user systems: + +```nix +nix-wsl = { + devices = { + "alice".ugaif.forUser = "alice-user"; # Automatically enables alice-user + "bob".ugaif.forUser = "bob-user"; + }; +}; +``` + +This is equivalent to `ugaif.users.alice-user.enable = true`. + +## Password Management + +### Generate Hashed Password + +```bash +mkpasswd -m sha-512 +# Enter password when prompted +# Copy the output hash +``` + +### In users.nix + +```nix +myuser = { + hashedPassword = "$6$rounds=656000$..."; # Paste hash here +}; +``` + +### Disable Password Login + +```nix +myuser = { + hashedPassword = "!"; # Locks password, SSH key only + opensshKeys = [ "ssh-ed25519 ..." ]; +}; +``` + +### Change Password Later + +On the system: +```bash +sudo passwd myuser +``` + +Or regenerate hash and update `users.nix`. + +## SSH Keys + +### Adding SSH Keys + +```nix +myuser = { + opensshKeys = [ + "ssh-ed25519 AAAAC3Nza... user@laptop" + "ssh-rsa AAAAB3NzaC1... user@desktop" + ]; +}; +``` + +### Generate SSH Key + +```bash +ssh-keygen -t ed25519 -C "user@hostname" +cat ~/.ssh/id_ed25519.pub # Copy this +``` + +### Multiple Keys + +Users can have multiple SSH keys for different machines: + +```nix +opensshKeys = [ + "ssh-ed25519 ... user@work-laptop" + "ssh-ed25519 ... user@home-desktop" + "ssh-ed25519 ... user@tablet" +]; +``` + +## Examples + +### Basic User + +```nix +student = { + description = "Student Account"; + extraGroups = [ "networkmanager" ]; + shell = pkgs.bash; + hashedPassword = "$6$..."; +}; +``` + +### Admin User with SSH + +```nix +admin = { + description = "System Administrator"; + extraGroups = [ "wheel" "networkmanager" "docker" ]; + shell = pkgs.zsh; + hashedPassword = "$6$..."; + opensshKeys = [ + "ssh-ed25519 AAAA... admin@laptop" + ]; +}; +``` + +### User with External Dotfiles + +```nix +developer = { + description = "Developer"; + extraGroups = [ "wheel" "docker" ]; + shell = pkgs.zsh; + hashedPassword = "$6$..."; + home = builtins.fetchGit { + url = "https://github.com/username/dotfiles"; + rev = "abc123def456..."; + }; +}; +``` + +### WSL User + +```nix +wsl-user = { + description = "WSL User"; + extraGroups = [ "wheel" ]; + shell = pkgs.zsh; + hashedPassword = "$6$..."; + home = builtins.fetchGit { + url = "https://github.com/username/dotfiles"; + rev = "abc123..."; + }; +}; +``` + +Enable in inventory.nix: +```nix +nix-wsl = { + devices."my-wsl".ugaif.forUser = "wsl-user"; +}; +``` + +### User Without System Themes + +For users who want complete control over their shell/editor: + +```nix +poweruser = { + description = "Power User"; + extraGroups = [ "wheel" ]; + shell = pkgs.zsh; + hashedPassword = "$6$..."; + useZshTheme = false; # Don't apply system theme + useNvimPlugins = false; # Don't apply system nvim config + home = builtins.fetchGit { + url = "https://github.com/username/custom-dotfiles"; + rev = "abc123..."; + }; +}; +``` + +## Theme Integration + +### System Zsh Theme + +When `useZshTheme = true` (default), the system applies: +- Oh My Posh with custom theme +- History substring search +- Vi mode (for non-root users) +- Zsh plugins (zplug) + +Disable if you want full control in your dotfiles. + +### System Neovim Config + +When `useNvimPlugins = true` (default), the system applies: +- LazyVim distribution +- TreeSitter parsers +- Language servers + +Disable if you want to configure Neovim yourself. + +## Troubleshooting + +### User Can't Login + +**Check if enabled on host:** +```bash +nix eval .#nixosConfigurations.nix-laptop1.config.ugaif.users.myuser.enable +``` + +**Check if user exists:** +```bash +# On the system +id myuser +``` + +### SSH Key Not Working + +**Check key in configuration:** +```bash +nix eval .#nixosConfigurations.nix-laptop1.config.users.users.myuser.openssh.authorizedKeys.keys +``` + +**Verify key format:** +- Should start with `ssh-ed25519`, `ssh-rsa`, or `ssh-dss` +- Should be all on one line +- Should end with comment (optional) + +### External Config Not Loading + +**Check repository access:** +```bash +git ls-remote https://github.com/username/dotfiles +``` + +**Verify structure:** +- Must have `home.nix` at repository root +- `nixos.nix` is optional +- Check file permissions + +**Test with local path first:** +```nix +home = /path/to/local/dotfiles; +``` + +## See Also + +- [docs/EXTERNAL_MODULES.md](EXTERNAL_MODULES.md) - External module guide +- [docs/INVENTORY.md](INVENTORY.md) - Host configuration +- [docs/NAMESPACE.md](NAMESPACE.md) - Configuration options +- [templates/user/](../templates/user/) - User module template +- [README.md](../README.md) - Main documentation