diff --git a/flake.nix b/flake.nix index 5f939db..a702334 100644 --- a/flake.nix +++ b/flake.nix @@ -27,11 +27,6 @@ inputs.nixpkgs.follows = "nixpkgs"; }; - # nixos-generators = { - # url = "github:nix-community/nixos-generators"; - # inputs.nixpkgs.follows = "nixpkgs"; - # }; - impermanence.url = "github:nix-community/impermanence"; lanzaboote.url = "github:nix-community/lanzaboote/v1.0.0"; @@ -144,7 +139,6 @@ systems = { # common modules modules.nixos = with inputs; [ - # nix-cachyos-kernel.nixosModules.default authentik-nix.nixosModules.default disko.nixosModules.disko impermanence.nixosModules.impermanence diff --git a/lib/README.md b/lib/README.md index c0be221..4f503b0 100644 --- a/lib/README.md +++ b/lib/README.md @@ -1,130 +1,44 @@ # mjallen-lib Utility Functions -This directory contains utility functions that can be used to enhance your Nix configuration. These functions are inspired by the khanelinix repository and provide a more explicit and modular approach to building Nix configurations. +Utility functions for the NixOS/nix-darwin configuration. Exposed via Snowfall Lib as `lib.mjallen.*`. ## Directory Structure -- `default.nix`: Main entry point that imports and exposes all utility functions -- `module/`: Utilities for module creation and option handling -- `file/`: Utilities for file handling and module discovery -- `system/`: Utilities for system configuration building +- `default.nix`: Main entry point — exports `module`, `file`, and `versioning` +- `module/`: Module creation helpers (`mkModule`, `mkOpt`, `mkBoolOpt`, etc.) +- `file/`: File and path utilities +- `versioning/`: Multi-source version pinning helpers (used by packages) -## How to Use +## Module Utilities (`lib.mjallen.module`) -### 1. Import the Library +| Function | Description | +|---|---| +| `mkModule` | Create a NixOS module with standard options (enable, port, reverseProxy, firewall, user, postgresql, redis) | +| `mkOpt` | `type → default → description → mkOption` shorthand | +| `mkOpt'` | `mkOpt` without description | +| `mkBoolOpt` | Boolean `mkOpt` shorthand | +| `mkBoolOpt'` | Boolean `mkOpt` without description | +| `mkReverseProxyOpt` | Standard Caddy reverse proxy sub-options | +| `enabled` | `{ enable = true; }` shorthand | +| `disabled` | `{ enable = false; }` shorthand | +| `capitalize` | Capitalise the first character of a string | +| `boolToNum` | Convert a boolean to 0 or 1 | +| `default-attrs` | Apply `lib.mkDefault` to every value in an attrset | +| `force-attrs` | Apply `lib.mkForce` to every value in an attrset | +| `nested-default-attrs` | Apply `default-attrs` one level deeper | +| `nested-force-attrs` | Apply `force-attrs` one level deeper | +| `enableForSystem` | Filter a module list to only those that match a given system string | -The library is already imported in your flake.nix file through the outputs-builder: +## File Utilities (`lib.mjallen.file`) -```nix -outputs-builder = channels: { - formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix; - - # Add mjallen-lib to the flake outputs - overlays = { - mjallen-lib = final: prev: { - mjallen-lib = (import ./lib { inherit inputs; }).mjallen-lib; - }; - }; -}; -``` +| Function | Description | +|---|---| +| `getFile` | Resolve a path relative to the flake root | +| `safeImport` | Import a Nix file with a fallback on error | +| `scanDir` | Return a list of directory names under a path | +| `importModulesRecursive` | Recursively discover and import all `default.nix` files under a directory | -This makes the mjallen-lib available to all your modules through the extended lib. +## Versioning Utilities (`lib.mjallen.versioning`) -### 2. Use the Module Utilities - -The module utilities provide functions for creating modules with consistent options: - -```nix -{ lib, ... }: -let - inherit (lib.mjallen.module) mkModule mkOpt mkBoolOpt; -in -mkModule { - name = "mymodule"; - description = "My awesome module"; - options = { - setting1 = mkOpt lib.types.str "default" "Description of setting1"; - setting2 = mkBoolOpt false "Description of setting2"; - }; - config = { - # Module implementation - }; -} -``` - -### 3. Use the File Utilities - -The file utilities provide functions for file handling and module discovery: - -```nix -{ lib, ... }: -let - inherit (lib.mjallen.file) safeImport importModulesRecursive; -in -{ - # Import a file with error handling - myConfig = safeImport ./my-config.nix {}; - - # Import all modules recursively - imports = importModulesRecursive ./modules; -} -``` - -### 4. Use the System Utilities - -The system utilities provide functions for building system configurations: - -```nix -{ lib, ... }: -let - inherit (lib.mjallen.system.common) mkHomeManagerConfig; -in -{ - # Build home-manager configurations - homeManagerConfig = mkHomeManagerConfig { - extendedLib = lib; - inputs = inputs; - system = "x86_64-linux"; - matchingHomes = { ... }; - }; -} -``` - -## Available Functions - -### Module Utilities - -- `mkModule`: Create a module with common options -- `mkOpt`: Create an option with a type, default value, and description -- `mkOpt'`: Create an option with a type and default value (no description) -- `mkBoolOpt`: Create a boolean option with a default value and description -- `mkBoolOpt'`: Create a boolean option with a default value (no description) -- `enabled`: Standard enable pattern -- `disabled`: Standard disable pattern -- `capitalize`: Capitalize a string -- `boolToNum`: Convert a boolean to a number -- `default-attrs`: Apply mkDefault to all attributes -- `force-attrs`: Apply mkForce to all attributes -- `nested-default-attrs`: Apply default-attrs to nested attributes -- `nested-force-attrs`: Apply force-attrs to nested attributes - -### File Utilities - -- `readFile`: Read a file and return its contents -- `pathExists`: Check if a file exists -- `safeImport`: Import a nix file with error handling -- `scanDir`: Scan a directory and return directory names -- `getFile`: Get a file path relative to the flake root -- `importModulesRecursive`: Recursively discover and import all Nix modules in a directory tree -- `scanSystems`: Recursively scan systems directory structure -- `filterNixOSSystems`: Filter systems for NixOS (Linux) -- `filterDarwinSystems`: Filter systems for Darwin (macOS) -- `scanHomes`: Scan homes directory structure for home configurations - -### System Utilities - -- `mkExtendedLib`: Extend the nixpkgs lib with mjallen-lib -- `mkNixpkgsConfig`: Create a nixpkgs configuration -- `mkHomeConfigs`: Create home configurations for a system and hostname -- `mkHomeManagerConfig`: Create a home-manager configuration -- `mkSpecialArgs`: Create special arguments for a system configuration +Used by packages that track multiple upstream variants (e.g. `linux-rpi`, `proton-cachyos`). +See `lib/versioning/default.nix` for the full API. diff --git a/modules/nixos/hardware/raspberry-pi/default.nix b/modules/nixos/hardware/raspberry-pi/default.nix index 1e421a2..d628a07 100644 --- a/modules/nixos/hardware/raspberry-pi/default.nix +++ b/modules/nixos/hardware/raspberry-pi/default.nix @@ -219,6 +219,25 @@ in default = "uefi"; }; + nixosGenerationsDir = lib.mkOption { + type = lib.types.str; + default = "/boot/nixos-generations"; + description = "Directory on the boot partition where NixOS generations are stored (kernel bootType only)."; + }; + + firmwarePackage = lib.mkOption { + type = lib.types.package; + default = null; + defaultText = lib.literalExpression "pkgs.\${namespace}.raspberrypifw"; + description = "Raspberry Pi firmware package used for device-tree installation (kernel/uboot bootType)."; + }; + + useGenerationDeviceTree = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to install a per-generation device tree alongside the kernel (kernel bootType only)."; + }; + apply-overlays-dtmerge = { enable = lib.mkEnableOption "" // { description = '' diff --git a/modules/nixos/services/ai/default.nix b/modules/nixos/services/ai/default.nix index 3094b60..34762cf 100755 --- a/modules/nixos/services/ai/default.nix +++ b/modules/nixos/services/ai/default.nix @@ -76,7 +76,6 @@ let host = "0.0.0.0"; port = 8888; openFirewall = cfg.openFirewall; - # stateDir = "/media/nas/main/nix-app-data/open-webui"; environmentFile = config.sops.secrets."jallen-nas/open-webui".path; environment = { OPENID_PROVIDER_URL = "https://authentik.mjallen.dev/application/o/chat/.well-known/openid-configuration"; diff --git a/modules/nixos/services/calibre/default.nix b/modules/nixos/services/calibre/default.nix index b626e76..242b58e 100644 --- a/modules/nixos/services/calibre/default.nix +++ b/modules/nixos/services/calibre/default.nix @@ -5,10 +5,10 @@ namespace, ... }: -with lib; let name = "calibre"; cfg = config.${namespace}.services.${name}; + cfgWeb = config.${namespace}.services."${name}-web"; calibreConfig = lib.${namespace}.mkModule { inherit config name; @@ -16,15 +16,11 @@ let description = "Calibre Server"; options = { }; moduleConfig = { - services = { - calibre-server = { - enable = false; - openFirewall = true; - port = cfg.port; - libraries = [ - "${cfg.dataDir}/books" - ]; - }; + services.calibre-server = { + enable = false; + openFirewall = true; + port = cfg.port; + libraries = [ "${cfg.dataDir}/books" ]; }; }; }; @@ -39,15 +35,15 @@ let enable = true; openFirewall = true; package = pkgs.stable.calibre-web; - dataDir = "${cfg.configDir}/calibre-web"; + dataDir = "${cfgWeb.configDir}/calibre-web"; listen = { ip = "0.0.0.0"; - port = cfg.port; + port = cfgWeb.port; }; options = { enableBookUploading = true; enableBookConversion = true; - calibreLibrary = "${cfg.dataDir}/books"; + calibreLibrary = "${cfgWeb.dataDir}/books"; }; }; }; diff --git a/modules/nixos/services/glance/default.nix b/modules/nixos/services/glance/default.nix index da1a085..50493af 100644 --- a/modules/nixos/services/glance/default.nix +++ b/modules/nixos/services/glance/default.nix @@ -11,7 +11,13 @@ let glanceConfig = lib.${namespace}.mkModule { inherit config name; description = "glance"; - options = { }; + options = { + nasPoolPath = lib.mkOption { + type = lib.types.str; + default = cfg.dataDir; + description = "Path to the NAS pool mount to display in server-stats."; + }; + }; moduleConfig = { sops = { secrets = { @@ -75,7 +81,7 @@ let "/home" = { name = "Home"; }; - "/media/nas/main" = { + "${cfg.nasPoolPath}" = { name = "nas_pool"; }; }; diff --git a/systems/x86_64-linux/jallen-nas/services.nix b/systems/x86_64-linux/jallen-nas/services.nix index ef47ea3..3f164e7 100755 --- a/systems/x86_64-linux/jallen-nas/services.nix +++ b/systems/x86_64-linux/jallen-nas/services.nix @@ -2,6 +2,9 @@ pkgs, ... }: +let + nasData = "/media/nas/main"; +in { systemd.network.wait-online.enable = false; # Force tailscaled to use nftables (Critical for clean nftables-only systems) @@ -37,7 +40,7 @@ enable = true; package = pkgs.postgresql_16; enableTCPIP = true; - dataDir = "/media/nas/main/databases/postgresql"; + dataDir = "${nasData}/databases/postgresql"; ensureDatabases = [ "authentik" "homeassistant" @@ -95,7 +98,7 @@ mysql = { enable = true; package = pkgs.mariadb; # explicit MariaDB package - dataDir = "/media/nas/main/databases/mariadb"; + dataDir = "${nasData}/databases/mariadb"; settings.mysqld = { bind-address = "0.0.0.0"; port = 3306;