diff --git a/README.md b/README.md index d2fab3e..6dc7186 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # wafrn-nix -example: +By default this module uses a flake-pinned Wafrn source, so you do not need to clone Wafrn manually. You can still override `services.wafrn.source` if you want a local checkout. + +Example: ```nix { @@ -16,7 +18,8 @@ example: services.wafrn = { enable = true; - source = "/srv/wafrn"; + # optional: override source checkout path + # source = "/srv/wafrn"; stateDir = "/var/lib/wafrn"; secretsFile = "/run/secrets/wafrn.env"; diff --git a/flake.lock b/flake.lock index dd9771a..6a18516 100644 --- a/flake.lock +++ b/flake.lock @@ -18,7 +18,25 @@ }, "root": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "wafrn-src": "wafrn-src" + } + }, + "wafrn-src": { + "flake": false, + "locked": { + "lastModified": 1770394446, + "narHash": "sha256-yUGn0HjwEDJOLlwcNP+ZfCjU04x9Y6PkmeahdcEP23A=", + "ref": "main", + "rev": "01e89d8fd0ba56d5781e4671a54531563d1a46c6", + "revCount": 6083, + "type": "git", + "url": "https://codeberg.org/wafrn/wafrn" + }, + "original": { + "ref": "main", + "type": "git", + "url": "https://codeberg.org/wafrn/wafrn" } } }, diff --git a/flake.nix b/flake.nix index d5b85c5..44e32d6 100644 --- a/flake.nix +++ b/flake.nix @@ -3,11 +3,18 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; + wafrn-src = { + url = "git+https://codeberg.org/wafrn/wafrn?ref=main"; + flake = false; + }; }; - outputs = { self, ... }: { + outputs = { self, wafrn-src, ... }: { nixosModules = { - wafrn = import ./modules/wafrn.nix; + wafrn = { ... }: { + imports = [ ./modules/wafrn.nix ]; + _module.args.wafrnSrc = wafrn-src; + }; default = self.nixosModules.wafrn; }; }; diff --git a/modules/wafrn.nix b/modules/wafrn.nix index 2b6fd06..952c776 100644 --- a/modules/wafrn.nix +++ b/modules/wafrn.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ config, lib, pkgs, wafrnSrc ? null, ... }: let inherit (lib) concatStringsSep @@ -105,7 +105,14 @@ let serviceEnvFile = "${cfg.stateDir}/.env"; composeFile = "${cfg.stateDir}/docker-compose.yml"; - sourcePath = cfg.source; + sourcePath = + if cfg.source != null then + cfg.source + else if wafrnSrc != null then + toString wafrnSrc + else + ""; + preparedSourcePath = "${cfg.stateDir}/source"; publishedPorts = lib.optionals (cfg.httpPort != null) [ "${toString cfg.httpPort}:80" ] @@ -121,7 +128,7 @@ let }; backendBuild = { - context = sourcePath; + context = preparedSourcePath; dockerfile = "packages/backend/Dockerfile"; }; @@ -160,7 +167,7 @@ let frontend = serviceCommon // { build = { - context = sourcePath; + context = preparedSourcePath; dockerfile = "packages/frontend/Dockerfile"; }; restart = "unless-stopped"; @@ -170,7 +177,7 @@ let "${cfg.stateDir}/caddy:/data" "${cfg.stateDir}/frontend:/var/www/html/frontend" "${cfg.stateDir}/uploads:/var/www/html/uploads" - "${sourcePath}/packages/caddy:/etc/caddy/config" + "${preparedSourcePath}/packages/caddy:/etc/caddy/config" ]; }; @@ -256,9 +263,10 @@ in enable = mkEnableOption "Wafrn social platform"; source = mkOption { - type = types.str; + type = types.nullOr types.str; + default = null; example = "/srv/wafrn"; - description = "Path to a Wafrn source checkout (used as Docker build context)."; + description = "Optional path to a Wafrn source checkout. If null, the module uses the pinned source from this flake input."; }; stateDir = mkOption { @@ -343,6 +351,10 @@ in assertion = config.virtualisation.docker.enable; message = "services.wafrn requires virtualisation.docker.enable = true;"; } + { + assertion = cfg.source != null || wafrnSrc != null; + message = "services.wafrn.source is null and no flake-pinned wafrn source is available."; + } { assertion = cfg.httpPort != null || cfg.httpsPort != null; message = "services.wafrn requires at least one published port (httpPort or httpsPort)."; @@ -357,6 +369,7 @@ in "d ${cfg.stateDir}/cache 0750 root root -" "d ${cfg.stateDir}/caddy 0750 root root -" "d ${cfg.stateDir}/frontend 0750 root root -" + "d ${cfg.stateDir}/source 0750 root root -" ] ++ lib.optionals (cfg.bluesky.enable && cfg.bluesky.useBundledPds) [ "d ${cfg.stateDir}/pds 0750 root root -" ]; @@ -376,16 +389,19 @@ in script = '' set -euo pipefail - if [ ! -d "${cfg.source}" ]; then - echo "wafrn-nix: source directory does not exist: ${cfg.source}" >&2 + if [ ! -d "${sourcePath}" ]; then + echo "wafrn-nix: source directory does not exist: ${sourcePath}" >&2 exit 1 fi - if [ ! -f "${cfg.source}/package-lock.json" ]; then + rm -rf "${preparedSourcePath}" + mkdir -p "${preparedSourcePath}" + cp -a "${sourcePath}/." "${preparedSourcePath}/" + chmod -R u+w "${preparedSourcePath}" + + if [ ! -f "${preparedSourcePath}/package-lock.json" ]; then echo "wafrn-nix: package-lock.json missing, generating with npm" >&2 - if ! (cd "${cfg.source}" && npm install --package-lock-only --ignore-scripts); then - echo "wafrn-nix: failed to generate package-lock.json, continuing with existing source" >&2 - fi + (cd "${preparedSourcePath}" && npm install --package-lock-only --ignore-scripts) fi install -m 0600 ${envTemplate} ${serviceEnvFile}