upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-01-21 15:17:10 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-01-21 15:17:10 +0000
commit7da6c0c601d276340fada02d4bd45080d927a16b (patch)
treeaade6beac6d3553533d799e26cb33d4e9da357f0
parent81ef29e8589ac4e10b6f67b4ab4049645f05c020 (diff)
fix(nix): use separate setup service to create dataDir before namespace setup
The main service uses ReadWritePaths for security hardening, but systemd requires these paths to exist BEFORE setting up the mount namespace. ExecStartPre runs AFTER namespace setup, so it cannot create the directories. This fix adds a separate oneshot setup service (ngit-grasp-{name}-setup) that: - Runs before the main service without namespace restrictions - Creates dataDir and subdirectories (git/, relay/) with mkdir -p - Sets proper ownership (user:group) and permissions (750) - Uses RemainAfterExit so it only runs once per boot The main service now depends on the setup service via requires/after. Fixes: 'Failed to set up mount namespacing: /path: No such file or directory'
-rw-r--r--nix/module.nix41
1 files changed, 25 insertions, 16 deletions
diff --git a/nix/module.nix b/nix/module.nix
index e192f95..4a6fc94 100644
--- a/nix/module.nix
+++ b/nix/module.nix
@@ -283,10 +283,27 @@ let
283 }; 283 };
284 }; 284 };
285 285
286 # Create systemd setup service to ensure directories exist before main service
287 # This runs without namespace restrictions so it can create directories
288 # that ReadWritePaths needs to exist before namespace setup
289 mkSetupService = name: cfg: {
290 description = "Create data directories for ngit-grasp (${name})";
291 before = [ "ngit-grasp-${name}.service" ];
292 requiredBy = [ "ngit-grasp-${name}.service" ];
293
294 serviceConfig = {
295 Type = "oneshot";
296 RemainAfterExit = true;
297 ExecStart =
298 "${pkgs.bash}/bin/bash -c '${pkgs.coreutils}/bin/mkdir -p \"${cfg.dataDir}/git\" \"${cfg.dataDir}/relay\" && ${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} \"${cfg.dataDir}\" && ${pkgs.coreutils}/bin/chmod 750 \"${cfg.dataDir}\" \"${cfg.dataDir}/git\" \"${cfg.dataDir}/relay\"'";
299 };
300 };
301
286 # Create systemd service config for an instance 302 # Create systemd service config for an instance
287 mkService = name: cfg: { 303 mkService = name: cfg: {
288 description = "ngit-grasp GRASP relay (${name})"; 304 description = "ngit-grasp GRASP relay (${name})";
289 after = [ "network.target" ]; 305 after = [ "network.target" "ngit-grasp-${name}-setup.service" ];
306 requires = [ "ngit-grasp-${name}-setup.service" ];
290 wantedBy = [ "multi-user.target" ]; 307 wantedBy = [ "multi-user.target" ];
291 308
292 environment = { 309 environment = {
@@ -341,19 +358,8 @@ let
341 # Working directory where .relay-owner.nsec will be created if needed 358 # Working directory where .relay-owner.nsec will be created if needed
342 WorkingDirectory = cfg.dataDir; 359 WorkingDirectory = cfg.dataDir;
343 360
344 # Ensure data directories exist before service starts 361 # Directory creation is handled by ngit-grasp-${name}-setup.service
345 # The + prefix runs these commands as root 362 # which runs before this service and creates dataDir with proper ownership
346 # This is necessary because tmpfiles.rules aren't automatically executed
347 # during nixos-rebuild switch, causing service failures with custom dataDirs
348 ExecStartPre = [
349 "+${pkgs.coreutils}/bin/mkdir -p '${cfg.dataDir}'"
350 "+${pkgs.coreutils}/bin/mkdir -p '${cfg.dataDir}/git'"
351 "+${pkgs.coreutils}/bin/mkdir -p '${cfg.dataDir}/relay'"
352 "+${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} '${cfg.dataDir}'"
353 "+${pkgs.coreutils}/bin/chmod 750 '${cfg.dataDir}'"
354 "+${pkgs.coreutils}/bin/chmod 750 '${cfg.dataDir}/git'"
355 "+${pkgs.coreutils}/bin/chmod 750 '${cfg.dataDir}/relay'"
356 ];
357 363
358 # Add git, openssh, and coreutils to PATH for purgatory sync operations 364 # Add git, openssh, and coreutils to PATH for purgatory sync operations
359 Environment = 365 Environment =
@@ -453,9 +459,12 @@ in {
453 users.groups.ngit-grasp = { }; 459 users.groups.ngit-grasp = { };
454 460
455 # Create systemd services for all enabled instances 461 # Create systemd services for all enabled instances
456 systemd.services = mapAttrs' 462 # Each instance has a setup service (creates directories) and main service
463 systemd.services = (mapAttrs'
457 (name: cfg: nameValuePair "ngit-grasp-${name}" (mkService name cfg)) 464 (name: cfg: nameValuePair "ngit-grasp-${name}" (mkService name cfg))
458 enabledInstances; 465 enabledInstances) // (mapAttrs' (name: cfg:
466 nameValuePair "ngit-grasp-${name}-setup" (mkSetupService name cfg))
467 enabledInstances);
459 468
460 # Create data directories with proper ownership using tmpfiles 469 # Create data directories with proper ownership using tmpfiles
461 # This runs as root before the service starts 470 # This runs as root before the service starts