diff --git a/nixos/modules/services/networking/ncps.nix b/nixos/modules/services/networking/ncps.nix index 96f557edd41f..589d115a5632 100644 --- a/nixos/modules/services/networking/ncps.nix +++ b/nixos/modules/services/networking/ncps.nix @@ -97,7 +97,6 @@ let lock = { backend = cfg.cache.lock.backend; redis.key-prefix = cfg.cache.lock.redisKeyPrefix; - postgres.key-prefix = cfg.cache.lock.postgresKeyPrefix; download-lock-ttl = cfg.cache.lock.downloadTTL; lru-lock-ttl = cfg.cache.lock.lruTTL; retry = { @@ -151,6 +150,14 @@ in "ncps" "dbmatePackage" ] "dbmate is now wrapped within ncps package, you need to override ncps to change dbmate package") + + (lib.mkRemovedOptionModule [ + "services" + "ncps" + "cache" + "lock" + "postgresKeyPrefix" + ] "PostgreSQL lock backend was removed upstream") ]; options = { @@ -285,22 +292,11 @@ in type = lib.types.enum [ "local" "redis" - "postgres" ]; default = "local"; description = '' Lock backend to use: 'local' (single instance), 'redis' - (distributed), 'postgres' (distributed, requires PostgreSQL). - - Advisory Locks and Connection Pools: If you use PostgreSQL as - your distributed lock backend, each active lock consumes a - dedicated connection from the pool. A single request can consume - up to 3 connections simultaneously. - - To avoid deadlocks under concurrent load, ensure - {option}`services.ncps.cache.database.pool.maxOpenConns` is - significantly higher than your expected concurrency (at least - 50-100 is recommended). + (distributed). ''; }; @@ -313,15 +309,6 @@ in ''; }; - postgresKeyPrefix = lib.mkOption { - type = lib.types.str; - default = "ncps:lock:"; - description = '' - Prefix for all PostgreSQL advisory lock keys (only used when - PostgreSQL is configured as lock backend). - ''; - }; - downloadTTL = lib.mkOption { type = lib.types.str; default = "5m0s"; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 11317df27c0a..9331257a6dfe 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1049,7 +1049,6 @@ in imports = [ ./ncps.nix ]; defaults.services.ncps.cache.storage.local = "/path/to/ncps"; }; - ncps-ha-pg = runTest ./ncps-ha-pg.nix; ncps-ha-pg-redis = runTest ./ncps-ha-pg-redis.nix; ndppd = runTest ./ndppd.nix; nebula-lighthouse-service = runTest ./nebula-lighthouse-service.nix; diff --git a/nixos/tests/ncps-ha-pg.nix b/nixos/tests/ncps-ha-pg.nix deleted file mode 100644 index f650a1bcd1ed..000000000000 --- a/nixos/tests/ncps-ha-pg.nix +++ /dev/null @@ -1,169 +0,0 @@ -{ - lib, - pkgs, - ... -}: -let - # s3 creds - bucket = "ncps"; - region = "us-west-1"; - accessKey = builtins.toFile "minio-access-key" "easy-key"; - secretKey = builtins.toFile "minio-secret-key" "easy-secret"; - - # pg creds - postgresPassword = "easypwd"; - - initMinio = pkgs.writeShellScriptBin "init-minio.sh" '' - set -euo pipefail - - mc alias set local "http://127.0.0.1:9000" minioadmin minioadmin - mc mb local/${bucket} - mc admin user svcacct add --access-key "$(cat ${accessKey})" --secret-key "$(cat ${secretKey})" local minioadmin - ''; - - ncpsAttrs = hostname: { - services.ncps = { - enable = true; - - analytics.reporting.enable = false; - - cache = { - hostName = hostname; - - databaseURL = "postgres://ncps:${lib.escapeURL postgresPassword}@postgres:5432/ncps?sslmode=disable"; - - lock.backend = "postgres"; - - secretKeyPath = builtins.toString ( - pkgs.writeText "ncps-cache-key" "ncps:dcrGsrku0KvltFhrR5lVIMqyloAdo0y8vYZOeIFUSLJS2IToL7dPHSSCk/fi+PJf8EorpBn8PU7MNhfvZoI8mA==" - ); - - storage.s3 = { - inherit bucket region; - - endpoint = "http://minio:9000"; - - accessKeyIdPath = accessKey; - secretAccessKeyPath = secretKey; - }; - - upstream = { - urls = [ "http://harmonia:5000" ]; - publicKeys = [ - "cache.example.com-1:eIGQXcGQpc00x6/XFcyacLEUmC07u4RAEHt5Y8vdglo=" - ]; - }; - }; - }; - - networking.firewall.allowedTCPPorts = [ 8501 ]; - }; -in -{ - name = "ncps-storage-s3"; - meta = with lib.maintainers; { - maintainers = [ - aciceri - kalbasit - ]; - }; - - nodes = { - client0 = { - nix.settings = { - substituters = lib.mkForce [ "http://ncps0:8501" ]; - trusted-public-keys = lib.mkForce [ - "ncps:UtiE6C+3Tx0kgpP34vjyX/BKK6QZ/D1OzDYX72aCPJg=" - ]; - }; - }; - - client1 = { - nix.settings = { - substituters = lib.mkForce [ "http://ncps1:8501" ]; - trusted-public-keys = lib.mkForce [ - "ncps:UtiE6C+3Tx0kgpP34vjyX/BKK6QZ/D1OzDYX72aCPJg=" - ]; - }; - }; - - harmonia = { - services.harmonia = { - enable = true; - signKeyPaths = [ - (pkgs.writeText "cache-key" "cache.example.com-1:9FhO0w+7HjZrhvmzT1VlAZw4OSAlFGTgC24Seg3tmPl4gZBdwZClzTTHr9cVzJpwsRSYLTu7hEAQe3ljy92CWg==") - ]; - settings.priority = 35; - }; - - networking.firewall.allowedTCPPorts = [ 5000 ]; - system.extraDependencies = [ pkgs.emptyFile ]; - }; - - minio = { - services.minio = { - inherit region; - - enable = true; - }; - - networking.firewall.allowedTCPPorts = [ 9000 ]; - environment.systemPackages = [ - pkgs.minio-client - initMinio - ]; - }; - - ncps0 = lib.mkMerge [ - (ncpsAttrs "ncps0") - { - services.ncps.cache.databaseURL = lib.mkForce null; - services.ncps.cache.databaseURLFile = builtins.toFile "db-url" "postgres://ncps:${lib.escapeURL postgresPassword}@postgres:5432/ncps?sslmode=disable"; - } - ]; - ncps1 = ncpsAttrs "ncps1"; - - postgres = { - services.postgresql = { - enable = true; - enableTCPIP = true; - authentication = '' - host all all all scram-sha-256 - ''; - initialScript = pkgs.writeText "init-postgres.sql" '' - CREATE DATABASE "ncps" WITH ENCODING = 'UTF8'; - CREATE ROLE "ncps" WITH LOGIN PASSWORD '${ - builtins.replaceStrings [ "'" ] [ "''" ] postgresPassword - }'; - ALTER DATABASE "ncps" OWNER TO "ncps"; - ''; - }; - - networking.firewall.allowedTCPPorts = [ 5432 ]; - }; - }; - - testScript = - { nodes, ... }: - '' - harmonia.start() - minio.start() - postgres.start() - - minio.wait_for_unit("minio.service") - - minio.wait_until_succeeds("init-minio.sh") - - postgres.wait_for_unit("postgresql.service") - - start_all() - - harmonia.wait_for_unit("harmonia.service") - - ncps0.wait_for_unit("ncps.service") - ncps1.wait_for_unit("ncps.service") - - client0.wait_until_succeeds("curl -f http://ncps0:8501/ | grep '\"hostname\":\"${toString nodes.ncps0.services.ncps.cache.hostName}\"' >&2") - client1.wait_until_succeeds("curl -f http://ncps1:8501/ | grep '\"hostname\":\"${toString nodes.ncps1.services.ncps.cache.hostName}\"' >&2") - ''; -} diff --git a/pkgs/by-name/nc/ncps/package.nix b/pkgs/by-name/nc/ncps/package.nix index 48c27d66d60b..197ffc0c52e0 100644 --- a/pkgs/by-name/nc/ncps/package.nix +++ b/pkgs/by-name/nc/ncps/package.nix @@ -3,45 +3,58 @@ curl, dbmate, fetchFromGitHub, + go, jq, lib, makeWrapper, mariadb, minio, minio-client, + nix-update-script, + nixosTests, postgresql, python3, redis, writeShellScriptBin, - nixosTests, - nix-update-script, + xz, }: -let - dbmate-real = writeShellScriptBin "dbmate.real" '' - exec ${dbmate}/bin/dbmate "$@" - ''; -in buildGoModule (finalAttrs: { pname = "ncps"; - version = "0.8.6"; + version = "0.9.1"; src = fetchFromGitHub { owner = "kalbasit"; repo = "ncps"; tag = "v${finalAttrs.version}"; - hash = "sha256-Ep83aGlwf8qq7fmSCCH9zUztlXf4D3vvs9jkBBoN6Yw="; + hash = "sha256-cu7fgzQTpo8aLpK0/kJ3xcCVFCmFMQ6RKwUWW5Zwu6s="; }; - vendorHash = "sha256-AcgC+zTS3eVsbcs0jim4zDBGc3lIjwPbdVT7/KQ9Lkc="; + # XXX: ncps is built with Go 1.25.6 that is available in release-25.11 but + # master is currently still using 1.25.5 (update waiting in the + # staging/staging-next branches.) This is a workaround for this issue and + # will automatically becomes no-op once Go is updated. + preBuild = lib.optionalString (go.version == "1.25.5") '' + sed -e 's:go 1.25.6:go 1.25.5:g' -i go.mod + sed -e 's:go 1.25.6:go 1.25.5:g' -i nix/dbmate-wrapper/src/go.mod + ''; + + vendorHash = "sha256-QZikr0kE/kvnI4RG02lxVpG4teTg3Uo68st9xLlbfm0="; ldflags = [ "-X github.com/kalbasit/ncps/pkg/ncps.Version=v${finalAttrs.version}" ]; - subPackages = [ "." ]; + excludedPackages = [ + "nix/dbmate-wrapper/src" + "nix/gen-db-wrappers/src" + ]; + + buildInputs = [ xz ]; nativeBuildInputs = [ + makeWrapper # used for wrapping the binary so it can always find the xz binary + curl # used for checking MinIO health check dbmate # used for testing jq # used for testing by the init-minio @@ -51,16 +64,23 @@ buildGoModule (finalAttrs: { postgresql # PostgreSQL for integration tests python3 # used for generating the ports redis # Redis for distributed locking integration tests - makeWrapper # For wrapping dbmate. ]; postInstall = '' mkdir -p $out/share/ncps cp -r db $out/share/ncps/db + # ncps makes use of xz for decompression as it's 3-5x faster than + # using the native Go implementation of xz. By wrapping ncps, and + # setting the XZ_BINARY_PATH environment variable, we ensure that + # ncps can always find the xz binary. This environment variable is + # read by a flag in pkg/ncps and can be overriden by using calling + # ncps with the --xz-binary-path flag. + wrapProgram $out/bin/ncps --set XZ_BINARY_PATH ${lib.getExe' xz "xz"} + + # Wrap the dbmate-wrapper and set the NCPS_DB_MIGRATIONS_DIR environment variable makeWrapper ${finalAttrs.passthru.dbmate-wrapper}/bin/dbmate-wrapper \ $out/bin/dbmate-ncps \ - --prefix PATH : ${dbmate-real}/bin \ --set NCPS_DB_MIGRATIONS_DIR $out/share/ncps/db/migrations ''; @@ -92,8 +112,24 @@ buildGoModule (finalAttrs: { src = "${finalAttrs.src}/nix/dbmate-wrapper/src"; + # XXX: ncps is built with Go 1.25.6 that is available in release-25.11 but + # master is currently still using 1.25.5 (update waiting in the + # staging/staging-next branches.) This is a workaround for this issue and + # will automatically becomes no-op once Go is updated. + preBuild = lib.optionalString (go.version == "1.25.5") '' + sed -e 's:go 1.25.6:go 1.25.5:g' -i go.mod + ''; + vendorHash = null; + buildInputs = lib.singleton dbmate; + nativeBuildInputs = lib.singleton makeWrapper; + + postInstall = '' + # the dbmate-wrapper needs access to the original dbmate executable, wrap it so it can find it correctly. + wrapProgram $out/bin/dbmate-wrapper --set DBMATE_BIN ${lib.getExe dbmate} + ''; + subPackages = [ "." ]; }; @@ -102,7 +138,6 @@ buildGoModule (finalAttrs: { ncps ncps-custom-sqlite-directory ncps-custom-storage-local - ncps-ha-pg ncps-ha-pg-redis ; };