# ============================================================================ # Common Host Module # ============================================================================ # This module contains all the common configuration shared by all host types. # It is automatically imported by the fleet generator for every host. { config, lib, inputs, ... }: let # Import all hardware modules so they're available for enabling hwTypes = import ../hw { inherit inputs; }; hwModules = lib.attrValues hwTypes; # User account submodule definition userSubmodule = lib.types.submodule { options = { enable = lib.mkOption { type = lib.types.bool; default = false; description = "Whether this user account is enabled on this system."; }; isNormalUser = lib.mkOption { type = lib.types.bool; default = true; description = "Whether this is a normal user account (vs system user)."; }; description = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Full name or description of the user (GECOS field)."; example = "John Doe"; }; extraGroups = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; description = "Additional groups for the user (wheel, docker, etc.)."; }; hashedPassword = lib.mkOption { type = lib.types.str; default = "!"; description = "Hashed password for the user account. Default '!' means locked."; }; extraPackages = lib.mkOption { type = lib.types.listOf lib.types.package; default = [ ]; description = "Additional system packages available to this user."; }; excludePackages = lib.mkOption { type = lib.types.listOf lib.types.package; default = [ ]; description = "System packages to exclude for this user."; }; homePackages = lib.mkOption { type = lib.types.listOf lib.types.package; default = [ ]; description = "Packages to install in the user's home-manager profile."; }; extraImports = lib.mkOption { type = lib.types.listOf lib.types.path; default = [ ]; description = "Additional home-manager modules to import for this user."; }; external = lib.mkOption { type = lib.types.nullOr ( lib.types.oneOf [ lib.types.path (lib.types.submodule { options = { url = lib.mkOption { type = lib.types.str; description = "Git repository URL to fetch user configuration from."; }; rev = lib.mkOption { type = lib.types.str; description = "Git commit hash, tag, or branch to fetch."; }; submodules = lib.mkOption { type = lib.types.bool; default = false; description = "Whether to fetch Git submodules."; }; }; }) ] ); default = null; description = "External dotfiles repository (user.nix + optional nixos.nix)."; }; opensshKeys = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; description = "SSH public keys for the user (authorized_keys)."; }; shell = lib.mkOption { type = lib.types.nullOr ( lib.types.enum [ "bash" "zsh" "fish" "tcsh" ] ); default = "bash"; description = "Default shell for the user."; }; editor = lib.mkOption { type = lib.types.nullOr ( lib.types.enum [ "vim" "neovim" "emacs" "nano" "code" ] ); default = "neovim"; description = "Default text editor for the user (sets EDITOR)."; }; useZshTheme = lib.mkOption { type = lib.types.bool; default = true; description = "Whether to apply the system Zsh theme (Oh My Posh)."; }; useNvimPlugins = lib.mkOption { type = lib.types.bool; default = true; description = "Whether to apply the system Neovim configuration."; }; }; }; in { imports = [ ./fs.nix ./boot.nix ./user-config.nix ../sw inputs.vscode-server.nixosModules.default inputs.nixos-wsl.nixosModules.default ] ++ hwModules; options.athenix.users = lib.mkOption { type = lib.types.attrsOf userSubmodule; default = { }; description = "User accounts configuration. Set enable=true for users that should exist on this system."; }; options.athenix = { forUser = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = '' Convenience option to configure a host for a specific user. When set, automatically: - Enables the user account (athenix.users..enable = true) - Sets as default WSL user (on WSL systems) The username must exist in athenix.users (defined in users.nix). ''; example = "engr-ugaif"; }; host.useHostPrefix = lib.mkOption { type = lib.types.bool; default = true; description = '' Whether to prepend the hardware type prefix to the hostname. When true: - "nix-laptop" with device "1" → hostname "nix-laptop1" - "nix-wsl" with device "alice" → hostname "nix-wsl-alice" When false: - Device name becomes the full hostname (useful for custom names) ''; }; }; config = lib.mkMerge [ (lib.mkIf (config.athenix.forUser != null) { athenix.users.${config.athenix.forUser}.enable = true; }) { system.stateVersion = "25.11"; nix.settings.experimental-features = [ "nix-command" "flakes" ]; } ]; }