- Update README.md structure section - Update DEVELOPMENT.md, EXTERNAL_MODULES.md, INVENTORY.md - Update GitHub Copilot instructions - Update PROXMOX_LXC.md references - Clarify new directory organization and purpose
8.8 KiB
Development Guide
Comprehensive guide for maintaining and extending Athenix.
Table of Contents
- Prerequisites
- Development Workflow
- Testing Changes
- Continuous Integration
- Common Tasks
- Debugging
- Troubleshooting
Prerequisites
Install Nix with Flakes
# Recommended: Determinate Systems installer
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
# Or official installer
sh <(curl -L https://nixos.org/nix/install) --daemon
# Enable flakes in existing installation
mkdir -p ~/.config/nix
echo 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf
Clone Repository
git clone https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git
cd athenix
# Optional: enable direnv for automatic Nix environment
direnv allow
Development Workflow
Making Changes
-
Edit configuration files - Modify
inventory.nix,users.nix, or host/software config -
Validate - Check syntax and configuration
nix flake check
- Format code - Apply consistent formatting
nix fmt
- Test - Build specific artifacts or configurations
# Test specific host
nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel
# Or build an artifact
nix build .#installer-iso-nix-laptop1
- Commit and push
git add .
git commit -m "Brief description of changes"
git push
Example: Adding a New User
- Define user in
users.nix:
athenix.users.newuser = {
description = "New User";
extraGroups = [ "wheel" "networkmanager" ];
shell = pkgs.zsh;
hashedPassword = "..."; # mkpasswd -m sha-512
};
- Enable on fleet in
inventory.nix:
nix-laptop = {
devices = 5;
overrides.athenix.users.newuser.enable = true;
};
- Validate and commit:
nix flake check
nix fmt
git add . && git commit -m "Add newuser account"
git push
Testing Changes
Validate Configuration Syntax
Always run before committing:
nix flake check
Shows any configuration errors across all ~50+ hosts. Output:
checking 50 configurations...
✓ All checks passed
Test Specific Host Build
# Build specific host (shows if config actually compiles)
nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel
# Shorter form
nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel -L
Test Installer Build
# Test that installer ISO builds
nix build .#installer-iso-nix-laptop1 -L
Test on Running NixOS System
If you're on a NixOS system managed by Athenix:
# Test changes temporarily (won't survive reboot)
sudo nixos-rebuild test --flake .
# Apply and switch (persistent)
sudo nixos-rebuild switch --flake .
# Build without switching
sudo nixos-rebuild build --flake .
# Show what will change
sudo nixos-rebuild dry-activate --flake .
Rollback
If a build breaks your system:
# List recent generations
nix-env --list-generations
# Rollback to previous generation
nix-env --rollback
# Or switch to specific generation
nix-env --switch-generation 42
Continuous Integration
CI Pipeline
All pushes and pull requests trigger automated tests on the self-hosted nix-builder:
- Flake Check -
nix flake checkvalidates all 50+ configurations - Format Check - Verifies code formatted with
nix fmt - Build Key Hosts - Builds
nix-builder,nix-laptop1,nix-desktop1 - Build Artifacts - Tests
lxc-nix-builderandinstaller-iso-nix-laptop1
Viewing CI Status
# Web interface
https://git.factory.uga.edu/UGA-Innovation-Factory/athenix/actions
# Or check locally
git log --oneline -n 5
# Look for ✓ or ✗ next to commits
Running CI Checks Locally
Test before pushing:
# Flake check
nix flake check --show-trace
# Format check
nix fmt --check
# Format code
nix fmt **/*.nix
# Build key configurations
nix build .#nixosConfigurations.nix-builder.config.system.build.toplevel -L
nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel -L
Common Tasks
Adding a New Host
Edit inventory.nix:
nix-surface = {
devices = 3; # Creates nix-surface1, nix-surface2, nix-surface3
overrides = {
athenix.sw.type = "tablet-kiosk";
athenix.sw.kioskUrl = "https://dashboard.example.com";
};
};
Test:
nix flake check
nix build .#installer-iso-nix-surface1 -L
Modifying Software Configuration
Edit appropriate file in sw/:
# Desktop software
vim sw/desktop/programs.nix
# Or for all systems
vim sw/default.nix
Use athenix.sw.extraPackages for host-specific additions:
nix-laptop = {
devices = 5;
overrides.athenix.sw.extraPackages = with pkgs; [ special-tool ];
};
Adding a System Type
Create new type in sw/:
mkdir -p sw/my-type
touch sw/my-type/{default.nix,programs.nix,services.nix}
Then reference in sw/default.nix:
{
imports = [
./my-type/default.nix
# ... other types
];
}
Using External Configurations
For user dotfiles:
# users.nix
athenix.users.myuser.external = builtins.fetchGit {
url = "https://git.factory.uga.edu/username/dotfiles";
rev = "abc123..."; # Pin to commit
};
For system config:
# inventory.nix
nix-lxc = {
devices."server".external = builtins.fetchGit {
url = "https://git.factory.uga.edu/org/server-config";
rev = "abc123...";
};
};
Updating Dependencies
# Update all flake inputs
nix flake update
# Update specific input
nix flake update nixpkgs
# Show what changed
git diff flake.lock
# Test after update
nix flake check --show-trace
# If tests pass, commit
git add flake.lock && git commit -m "Update dependencies"
Debugging
Verbose Output
Get detailed error messages:
# Show full error traces
nix flake check --show-trace
# With maximum verbosity
nix build .#installer-iso-nix-laptop1 -vvv
# Show build log
nix build .#installer-iso-nix-laptop1 -L
Inspect Configuration
# Evaluate configuration for specific host
nix eval .#nixosConfigurations.nix-laptop1.config.athenix.sw --json
# Get all host names
nix eval .#nixosConfigurations --apply builtins.attrNames
# Check specific option
nix eval .#nixosConfigurations.nix-laptop1.config.users.users
Test Module Loading
# Evaluate specific module
nix-build -A nixosConfigurations.nix-laptop1.config.system.build.toplevel
# Or with flakes
nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel --verbose
Check Derivation Dependencies
# Show what dependencies a build needs
nix show-derivation .#installer-iso-nix-laptop1
# Or human-readable
nix build .#installer-iso-nix-laptop1 --dry-run
Troubleshooting
Common Errors
"Evaluation error"
error: evaluation aborted with the following error message: '...'
Solution: Check syntax in modified files. Use nix fmt and nix flake check --show-trace.
"Unknown variable" or "Option does not exist"
error: The option `athenix.xyz' does not exist.
Solution: Check NAMESPACE.md for available options. Options must be in athenix.* namespace.
"Hash mismatch" (for external modules)
error: Hash mismatch in fetched input
Solution: Update the pin. For builtins.fetchGit, use actual commit hash. Or:
nix flake update
Build runs out of memory
# Reduce parallel jobs
nix build . --max-jobs 1
"No such file or directory" in build
# Check path exists
ls -la /path/to/file
# Or check relative to repo
ls -la sw/my-file.nix
Helpful Diagnostics
# List all hosts
nix eval .#nixosConfigurations --apply builtins.attrNames
# Show flake structure
nix flake show | head -50
# Check Nix store size
du -sh /nix/store
# List top space users in store
nix store du --human-readable | head -20
# Find store paths for a package
nix store path-info -rS $(which some-package)
Getting Help
- Check documentation - Review relevant doc file
- Look at existing examples - Check
inventory.nixorusers.nix - Search for similar patterns -
grep -r "athenix.option" . - Run tests locally -
nix flake check --show-tracewith full output - Review git history -
git log --patch -- filename.nix
See Also
- BUILDING.md - Building artifacts
- INVENTORY.md - Host configuration
- NAMESPACE.md - Configuration options
- USER_CONFIGURATION.md - User management
- EXTERNAL_MODULES.md - External modules
- README.md - Main documentation