From 959d46ed5ae1fb49d99ca0568263fbc70aba9ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 8 Sep 2026 03:35:48 +0300 Subject: [PATCH] feat(nix): add nix-dl, retry+timeout wrapper for nix-store -r nix-store -r can stall indefinitely on a dropped connection without erroring out (NixOS/nix#2560); guard each path with a timeout and retry, matching the pattern already used in ansible/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh. site-extensions-update now uses it instead of a bare nix-store -r call. --- nix/packages/default.nix | 1 + nix/packages/extension-catalog.nix | 3 ++- nix/packages/nix-dl.nix | 36 ++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 nix/packages/nix-dl.nix diff --git a/nix/packages/default.nix b/nix/packages/default.nix index b7ad2b205b..2228bfd11e 100644 --- a/nix/packages/default.nix +++ b/nix/packages/default.nix @@ -5,6 +5,7 @@ ./postgres-env.nix ./site-env.nix ./extension-catalog.nix + ./nix-dl.nix ]; perSystem = { diff --git a/nix/packages/extension-catalog.nix b/nix/packages/extension-catalog.nix index d8d5591216..7de8d02522 100644 --- a/nix/packages/extension-catalog.nix +++ b/nix/packages/extension-catalog.nix @@ -152,13 +152,14 @@ name = "site-extensions-update"; runtimeInputs = [ self'.packages.site-extensions-resolve + self'.packages.nix-dl pkgs.nix ]; text = '' manifest="''${1:?Usage: $0 path-to/pg-extensions.json}" profile="''${NIX_PROFILE:-/nix/var/nix/profiles/site-extensions}" readarray -t paths < <(site-extensions-resolve "$manifest") - nix-store -r --option stalled-download-timeout 120 "''${paths[@]}" >/dev/null + nix-dl "''${paths[@]}" nix-env --profile "$profile" --install "''${paths[@]}" --remove-all ''; }; diff --git a/nix/packages/nix-dl.nix b/nix/packages/nix-dl.nix new file mode 100644 index 0000000000..c193112d35 --- /dev/null +++ b/nix/packages/nix-dl.nix @@ -0,0 +1,36 @@ +# Download nix store paths with timeout and retry. +{ + perSystem = + { pkgs, ... }: + { + packages.nix-dl = pkgs.writeShellApplication { + name = "nix-dl"; + runtimeInputs = [ + pkgs.coreutils + pkgs.nix + ]; + text = '' + # nix-store -r can stall indefinitely: https://github.com/NixOS/nix/issues/8758 + timeout_="''${NIX_DL_TIMEOUT:-120s}" + kill_grace="''${NIX_DL_KILL_GRACE:-10s}" + attempts="''${NIX_DL_ATTEMPTS:-3}" + + for path in "$@"; do + ok="false" + for attempt in $(seq 1 "$attempts"); do + if timeout -k "$kill_grace" "$timeout_" nix-store -r "$path" >/dev/null; then + ok="true" + break + fi + if [ "$attempt" -lt "$attempts" ]; then + echo "WARNING: nix-store -r attempt $attempt/$attempts for $path failed or stalled (>=$timeout_ + up to $kill_grace kill grace); retrying" >&2 + else + echo "ERROR: nix-store -r failed after $attempts attempts for $path" >&2 + fi + done + [ "$ok" = "true" ] || exit 1 + done + ''; + }; + }; +}