# Development Guide Comprehensive guide for maintaining and extending Athenix. ## Table of Contents - [Prerequisites](#prerequisites) - [Development Workflow](#development-workflow) - [Testing Changes](#testing-changes) - [Continuous Integration](#continuous-integration) - [Common Tasks](#common-tasks) - [Debugging](#debugging) - [Troubleshooting](#troubleshooting) ## Prerequisites ### Install Nix with Flakes ```bash # 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 ```bash 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 1. **Edit configuration files** - Modify `inventory.nix`, `users.nix`, or host/software config 2. **Validate** - Check syntax and configuration ```bash nix flake check ``` 3. **Format code** - Apply consistent formatting ```bash nix fmt ``` 4. **Test** - Build specific artifacts or configurations ```bash # Test specific host nix build .#nixosConfigurations.nix-laptop1.config.system.build.toplevel # Or build an artifact nix build .#installer-iso-nix-laptop1 ``` 5. **Commit and push** ```bash git add . git commit -m "Brief description of changes" git push ``` ### Example: Adding a New User 1. Define user in `users.nix`: ```nix athenix.users.newuser = { description = "New User"; extraGroups = [ "wheel" "networkmanager" ]; shell = pkgs.zsh; hashedPassword = "..."; # mkpasswd -m sha-512 }; ``` 2. Enable on fleet in `inventory.nix`: ```nix nix-laptop = { devices = 5; overrides.athenix.users.newuser.enable = true; }; ``` 3. Validate and commit: ```bash nix flake check nix fmt git add . && git commit -m "Add newuser account" git push ``` ## Testing Changes ### Validate Configuration Syntax Always run before committing: ```bash nix flake check ``` Shows any configuration errors across all ~50+ hosts. Output: ``` checking 50 configurations... ✓ All checks passed ``` ### Test Specific Host Build ```bash # 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 ```bash # 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: ```bash # 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: ```bash # 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`: 1. **Flake Check** - `nix flake check` validates all 50+ configurations 2. **Format Check** - Verifies code formatted with `nix fmt` 3. **Build Key Hosts** - Builds `nix-builder`, `nix-laptop1`, `nix-desktop1` 4. **Build Artifacts** - Tests `lxc-nix-builder` and `installer-iso-nix-laptop1` ### Viewing CI Status ```bash # 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: ```bash # 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 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: ```bash nix flake check nix build .#installer-iso-nix-surface1 -L ``` ### Modifying Software Configuration Edit appropriate file in `sw/`: ```bash # Desktop software vim sw/desktop/programs.nix # Or for all systems vim sw/default.nix ``` Use `athenix.sw.extraPackages` for host-specific additions: ```nix nix-laptop = { devices = 5; overrides.athenix.sw.extraPackages = with pkgs; [ special-tool ]; }; ``` ### Adding a System Type Create new type in `sw/`: ```bash mkdir -p sw/my-type touch sw/my-type/{default.nix,programs.nix,services.nix} ``` Then reference in `sw/default.nix`: ```nix { imports = [ ./my-type/default.nix # ... other types ]; } ``` ### Using External Configurations For user dotfiles: ```nix # users.nix athenix.users.myuser.external = builtins.fetchGit { url = "https://git.factory.uga.edu/username/dotfiles"; rev = "abc123..."; # Pin to commit }; ``` For system config: ```nix # inventory.nix nix-lxc = { devices."server".external = builtins.fetchGit { url = "https://git.factory.uga.edu/org/server-config"; rev = "abc123..."; }; }; ``` ### Updating Dependencies ```bash # 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: ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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: ```bash nix flake update ``` #### Build runs out of memory ```bash # Reduce parallel jobs nix build . --max-jobs 1 ``` #### "No such file or directory" in build ```bash # Check path exists ls -la /path/to/file # Or check relative to repo ls -la sw/my-file.nix ``` ### Helpful Diagnostics ```bash # 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 1. **Check documentation** - Review relevant doc file 2. **Look at existing examples** - Check `inventory.nix` or `users.nix` 3. **Search for similar patterns** - `grep -r "athenix.option" .` 4. **Run tests locally** - `nix flake check --show-trace` with full output 5. **Review git history** - `git log --patch -- filename.nix` ## See Also - [BUILDING.md](BUILDING.md) - Building artifacts - [INVENTORY.md](INVENTORY.md) - Host configuration - [NAMESPACE.md](NAMESPACE.md) - Configuration options - [USER_CONFIGURATION.md](USER_CONFIGURATION.md) - User management - [EXTERNAL_MODULES.md](EXTERNAL_MODULES.md) - External modules - [README.md](../README.md) - Main documentation