From 22bb61d1f848d64708fbf10ee542c7f850d22dbe Mon Sep 17 00:00:00 2001 From: Guillaume Girol Date: Sun, 27 Jul 2025 12:00:00 +0000 Subject: [PATCH] nixos: add module for nixseparatedebuginfod2 --- nixos/modules/module-list.nix | 1 + .../development/nixseparatedebuginfod2.nix | 97 +++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/nixseparatedebuginfod2.nix | 72 ++++++++++++++ .../ni/nixseparatedebuginfod2/package.nix | 5 +- 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 nixos/modules/services/development/nixseparatedebuginfod2.nix create mode 100644 nixos/tests/nixseparatedebuginfod2.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 916b87d3ffab..9aad0d698b9b 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -590,6 +590,7 @@ ./services/development/jupyterhub/default.nix ./services/development/livebook.nix ./services/development/lorri.nix + ./services/development/nixseparatedebuginfod2.nix ./services/development/nixseparatedebuginfod.nix ./services/development/rstudio-server/default.nix ./services/development/vsmartcard-vpcd.nix diff --git a/nixos/modules/services/development/nixseparatedebuginfod2.nix b/nixos/modules/services/development/nixseparatedebuginfod2.nix new file mode 100644 index 000000000000..3cea2261ca1a --- /dev/null +++ b/nixos/modules/services/development/nixseparatedebuginfod2.nix @@ -0,0 +1,97 @@ +{ + pkgs, + lib, + config, + utils, + ... +}: +let + cfg = config.services.nixseparatedebuginfod2; + url = "127.0.0.1:${toString cfg.port}"; +in +{ + options = { + services.nixseparatedebuginfod2 = { + enable = lib.mkEnableOption "nixseparatedebuginfod2, a debuginfod server providing source and debuginfo for nix packages"; + port = lib.mkOption { + description = "port to listen"; + default = 1950; + type = lib.types.port; + }; + package = lib.mkPackageOption pkgs "nixseparatedebuginfod2" { }; + substituter = lib.mkOption { + description = "nix substituter to fetch debuginfo from. Either http/https substituters, or `local:` to use debuginfo present in the local store."; + default = "https://cache.nixos.org"; + example = "local:"; + type = lib.types.str; + }; + cacheExpirationDelay = lib.mkOption { + description = "keep unused cache entries for this long. A number followed by a unit"; + default = "1d"; + type = lib.types.str; + }; + }; + }; + config = lib.mkIf cfg.enable { + systemd.services.nixseparatedebuginfod2 = { + wantedBy = [ "multi-user.target" ]; + path = [ config.nix.package ]; + serviceConfig = { + ExecStart = [ + (utils.escapeSystemdExecArgs [ + (lib.getExe cfg.package) + "--listen-address" + url + "--substituter" + cfg.substituter + "--expiration" + cfg.cacheExpirationDelay + ]) + ]; + Restart = "on-failure"; + CacheDirectory = "nixseparatedebuginfod2"; + DynamicUser = true; + + # hardening + # Filesystem stuff + ProtectSystem = "strict"; # Prevent writing to most of / + ProtectHome = true; # Prevent accessing /home and /root + PrivateTmp = true; # Give an own directory under /tmp + PrivateDevices = true; # Deny access to most of /dev + ProtectKernelTunables = true; # Protect some parts of /sys + ProtectControlGroups = true; # Remount cgroups read-only + RestrictSUIDSGID = true; # Prevent creating SETUID/SETGID files + PrivateMounts = true; # Give an own mount namespace + RemoveIPC = true; + UMask = "0077"; + + # Capabilities + CapabilityBoundingSet = ""; # Allow no capabilities at all + NoNewPrivileges = true; # Disallow getting more capabilities. This is also implied by other options. + + # Kernel stuff + ProtectKernelModules = true; # Prevent loading of kernel modules + SystemCallArchitectures = "native"; # Usually no need to disable this + SystemCallFilter = "@system-service"; + ProtectKernelLogs = true; # Prevent access to kernel logs + ProtectClock = true; # Prevent setting the RTC + ProtectProc = "noaccess"; + ProcSubset = "pid"; + + # Networking + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; + + # Misc + LockPersonality = true; # Prevent change of the personality + ProtectHostname = true; # Give an own UTS namespace + RestrictRealtime = true; # Prevent switching to RT scheduling + MemoryDenyWriteExecute = true; # Maybe disable this for interpreters like python + RestrictNamespaces = true; + + }; + }; + + environment.debuginfodServers = [ "http://${url}" ]; + + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 82d53c0613c6..faea61e36884 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1047,6 +1047,7 @@ in }; nixpkgs = pkgs.callPackage ../modules/misc/nixpkgs/test.nix { inherit evalMinimalConfig; }; nixseparatedebuginfod = runTest ./nixseparatedebuginfod.nix; + nixseparatedebuginfod2 = runTest ./nixseparatedebuginfod2.nix; node-red = runTest ./node-red.nix; nomad = runTest ./nomad.nix; nominatim = runTest ./nominatim.nix; diff --git a/nixos/tests/nixseparatedebuginfod2.nix b/nixos/tests/nixseparatedebuginfod2.nix new file mode 100644 index 000000000000..34741ac2fa71 --- /dev/null +++ b/nixos/tests/nixseparatedebuginfod2.nix @@ -0,0 +1,72 @@ +{ pkgs, lib, ... }: +{ + name = "nixseparatedebuginfod2"; + # A binary cache with debug info and source for gnumake + nodes.cache = + { pkgs, ... }: + { + services.nginx = { + enable = true; + virtualHosts.default = { + default = true; + addSSL = false; + root = "/var/lib/thebinarycache"; + }; + }; + networking.firewall.allowedTCPPorts = [ 80 ]; + systemd.services.buildthebinarycache = { + before = [ "nginx.service" ]; + wantedBy = [ "nginx.service" ]; + script = '' + ${pkgs.nix}/bin/nix --extra-experimental-features nix-command copy --to file:///var/lib/thebinarycache?index-debug-info=true ${pkgs.gnumake.debug} ${pkgs.gnumake} ${pkgs.gnumake.src} ${pkgs.sl} + ''; + serviceConfig = { + User = "nginx"; + Group = "nginx"; + StateDirectory = "thebinarycache"; + Type = "oneshot"; + }; + }; + }; + # the machine where we need the debuginfo + nodes.machine = { + services.nixseparatedebuginfod2 = { + enable = true; + substituter = "http://cache"; + }; + environment.systemPackages = [ + pkgs.valgrind + pkgs.gdb + pkgs.gnumake + ]; + }; + testScript = '' + start_all() + cache.wait_for_unit("nginx.service") + cache.wait_for_open_port(80) + machine.wait_for_unit("nixseparatedebuginfod2.service") + machine.wait_for_open_port(1950) + + with subtest("check that the binary cache works"): + machine.succeed("nix-store --extra-substituters http://cache --option require-sigs false -r ${pkgs.sl}") + + # test debuginfod-find + machine.succeed("debuginfod-find debuginfo /run/current-system/sw/bin/make") + + # test that gdb can fetch source + out = machine.succeed("gdb /run/current-system/sw/bin/make --batch -x ${builtins.toFile "commands" '' + start + l + ''}") + print(out) + assert 'main (int argc, char **argv, char **envp)' in out + + # test that valgrind can display location information + # this relies on the fact that valgrind complains about gnumake + # because we also ask valgrind to show leak kinds + # which are usually false positives. + out = machine.succeed("valgrind --leak-check=full --show-leak-kinds=all make --version 2>&1") + print(out) + assert 'main.c' in out + ''; +} diff --git a/pkgs/by-name/ni/nixseparatedebuginfod2/package.nix b/pkgs/by-name/ni/nixseparatedebuginfod2/package.nix index 14c74fd86dac..2cffac191eef 100644 --- a/pkgs/by-name/ni/nixseparatedebuginfod2/package.nix +++ b/pkgs/by-name/ni/nixseparatedebuginfod2/package.nix @@ -8,6 +8,7 @@ bubblewrap, elfutils, nix, + nixosTests, }: rustPlatform.buildRustPackage rec { @@ -38,7 +39,9 @@ rustPlatform.buildRustPackage rec { env.OPENSSL_NO_VENDOR = "1"; - meta = with lib; { + passthru.tests = { inherit (nixosTests) nixseparatedebuginfod2; }; + + meta = { description = "Downloads and provides debug symbols and source code for nix derivations to gdb and other debuginfod-capable debuggers as needed"; homepage = "https://github.com/symphorien/nixseparatedebuginfod2"; license = lib.licenses.gpl3Only;