diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index ec213e5f2f7..0e1ba793891 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -58,6 +58,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [gmediarender](https://github.com/hzeller/gmrender-resurrect), a simple, headless UPnP/DLNA renderer. Available as [services.gmediarender](options.html#opt-services.gmediarender.enable). +- [harmonia](https://github.com/nix-community/harmonia/), Nix binary cache implemented in rust using libnix-store. Available as [services.harmonia](options.html#opt-services.harmonia.enable). + - [hyprland](https://github.com/hyprwm/hyprland), a dynamic tiling Wayland compositor that doesn't sacrifice on its looks. Available as [programs.hyprland](#opt-programs.hyprland.enable). - [minipro](https://gitlab.com/DavidGriffith/minipro/), an open source program for controlling the MiniPRO TL866xx series of chip programmers. Available as [programs.minipro](options.html#opt-programs.minipro.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index d15d8503b09..d1e1130e58a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -873,6 +873,7 @@ ./services/networking/gobgpd.nix ./services/networking/gvpe.nix ./services/networking/hans.nix + ./services/networking/harmonia.nix ./services/networking/haproxy.nix ./services/networking/headscale.nix ./services/networking/hostapd.nix diff --git a/nixos/modules/services/networking/harmonia.nix b/nixos/modules/services/networking/harmonia.nix new file mode 100644 index 00000000000..0f9d328d005 --- /dev/null +++ b/nixos/modules/services/networking/harmonia.nix @@ -0,0 +1,92 @@ +{ config, pkgs, lib, ... }: +let + cfg = config.services.harmonia; + + format = pkgs.formats.toml { }; +in +{ + options = { + services.harmonia = { + enable = lib.mkEnableOption (lib.mdDoc "Harmonia: Nix binary cache written in Rust"); + + signKeyPath = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = lib.mdDoc "Path to the signing key to use for signing the cache"; + }; + + package = lib.mkPackageOptionMD pkgs "harmonia" { }; + + settings = lib.mkOption { + inherit (format) type; + description = lib.mdDoc "Settings to merge with the default configuration"; + }; + }; + }; + + config = lib.mkIf cfg.enable { + services.harmonia.settings.bind = lib.mkDefault "[::]:5000"; + + systemd.services.harmonia = { + description = "harmonia binary cache service"; + + requires = [ "nix-daemon.socket" ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = { + CONFIG_FILE = format.generate "harmonia.toml" cfg.settings; + SIGN_KEY_PATH = lib.mkIf (cfg.signKeyPath != null) "%d/sign-key"; + # Note: it's important to set this for nix-store, because it wants to use + # $HOME in order to use a temporary cache dir. bizarre failures will occur + # otherwise + HOME = "/run/harmonia"; + }; + + serviceConfig = { + ExecStart = lib.getExe cfg.package; + + User = "harmonia"; + Group = "harmonia"; + DynamicUser = true; + PrivateUsers = true; + DeviceAllow = [ "" ]; + UMask = "0066"; + + RuntimeDirectory = "harmonia"; + LoadCredential = lib.optional (cfg.signKeyPath != null) "sign-key:${cfg.signKeyPath}"; + + SystemCallFilter = [ + "@system-service" + "~@privileged" + "~@resources" + ]; + CapabilityBoundingSet = ""; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProtectKernelLogs = true; + ProtectHostname = true; + ProtectClock = true; + RestrictRealtime = true; + MemoryDenyWriteExecute = true; + ProcSubset = "pid"; + ProtectProc = "invisible"; + RestrictNamespaces = true; + SystemCallArchitectures = "native"; + + PrivateNetwork = false; + PrivateTmp = true; + PrivateDevices = true; + PrivateMounts = true; + NoNewPrivileges = true; + ProtectSystem = "strict"; + ProtectHome = true; + LockPersonality = true; + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; + + LimitNOFILE = 65536; + }; + }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 5dd39c9b142..1bcfcef5f9a 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -295,6 +295,7 @@ in { haste-server = handleTest ./haste-server.nix {}; haproxy = handleTest ./haproxy.nix {}; hardened = handleTest ./hardened.nix {}; + harmonia = handleTest ./harmonia.nix {}; headscale = handleTest ./headscale.nix {}; healthchecks = handleTest ./web-apps/healthchecks.nix {}; hbase2 = handleTest ./hbase.nix { package=pkgs.hbase2; }; diff --git a/nixos/tests/harmonia.nix b/nixos/tests/harmonia.nix new file mode 100644 index 00000000000..95fb7ea18cf --- /dev/null +++ b/nixos/tests/harmonia.nix @@ -0,0 +1,33 @@ +import ./make-test-python.nix ({ pkgs, ... }: +{ + name = "harmonia"; + nodes = { + harmonia = { + services.harmonia = { + enable = true; + signKeyPath = pkgs.writeText "cache-key" + "cache.example.com-1:9FhO0w+7HjZrhvmzT1VlAZw4OSAlFGTgC24Seg3tmPl4gZBdwZClzTTHr9cVzJpwsRSYLTu7hEAQe3ljy92CWg=="; + }; + + networking.firewall.allowedTCPPorts = [ 5000 ]; + system.extraDependencies = [ pkgs.hello ]; + }; + + client01 = { lib, ... }: { + nix.settings = { + substituters = lib.mkForce [ "http://harmonia:5000" ]; + trusted-public-keys = lib.mkForce [ "cache.example.com-1:eIGQXcGQpc00x6/XFcyacLEUmC07u4RAEHt5Y8vdglo=" ]; + }; + }; + }; + + testScript = '' + start_all() + + client01.wait_until_succeeds("curl -f http://harmonia:5000/version") + client01.succeed("curl -f http://harmonia:5000/nix-cache-info") + + client01.succeed("cat /etc/nix/nix.conf >&2") + client01.wait_until_succeeds("nix-store --realise ${pkgs.hello} --store /root/other-store") + ''; +}) diff --git a/pkgs/tools/package-management/harmonia/default.nix b/pkgs/tools/package-management/harmonia/default.nix index 01155ebbf19..267b04a700a 100644 --- a/pkgs/tools/package-management/harmonia/default.nix +++ b/pkgs/tools/package-management/harmonia/default.nix @@ -6,6 +6,7 @@ , pkg-config , rustPlatform , nix-update-script +, nixosTests }: rustPlatform.buildRustPackage rec { @@ -35,6 +36,7 @@ rustPlatform.buildRustPackage rec { updateScript = nix-update-script { extraArgs = [ "--version-regex" "harmonia-v(.*)" ]; }; + tests = { inherit (nixosTests) harmonia; }; }; meta = with lib; {