From 705284d913642bfce2db8d895eb6a3f90d548b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 8 Sep 2026 22:40:51 +0300 Subject: [PATCH 01/14] ci: fail nix package builds that exceed glibc 2.31 floor Guards against binaries silently requiring a newer glibc than customer AMIs ship. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/nix-build.yml | 6 ++++++ scripts/check-glibc-floor.sh | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100755 scripts/check-glibc-floor.sh diff --git a/.github/workflows/nix-build.yml b/.github/workflows/nix-build.yml index e286015cca..f379d07a59 100644 --- a/.github/workflows/nix-build.yml +++ b/.github/workflows/nix-build.yml @@ -73,6 +73,9 @@ jobs: uses: ./.github/actions/nix-build-retry with: attr: .#${{ matrix.attr }} + - name: Check glibc floor + if: ${{ matrix.attr != '' }} + run: ./scripts/check-glibc-floor.sh "${{ matrix.attr }}" nix-build-checks-aarch64-linux: name: >- @@ -192,6 +195,9 @@ jobs: uses: ./.github/actions/nix-build-retry with: attr: .#${{ matrix.attr }} + - name: Check glibc floor + if: ${{ matrix.attr != '' }} + run: ./scripts/check-glibc-floor.sh "${{ matrix.attr }}" nix-build-checks-x86_64-linux: name: >- diff --git a/scripts/check-glibc-floor.sh b/scripts/check-glibc-floor.sh new file mode 100755 index 0000000000..6d888a9d50 --- /dev/null +++ b/scripts/check-glibc-floor.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Fails if any file in ./result requires a glibc symbol version above MAX_ALLOWED. +set -Eeu -o pipefail + +MAX_ALLOWED="2.31" + +FLOOR=$(find -L result -type f -exec objdump -T {} \; 2>/dev/null \ + | grep -oE 'GLIBC_[0-9.]+' | sed 's/GLIBC_//' | sort -V | tail -1) + +if [ -z "$FLOOR" ]; then + exit 0 +fi + +echo "glibc floor: $FLOOR (max allowed: $MAX_ALLOWED)" +if [ "$(printf '%s\n%s' "$MAX_ALLOWED" "$FLOOR" | sort -V | tail -1)" != "$MAX_ALLOWED" ]; then + echo "::error::glibc floor $FLOOR exceeds max allowed $MAX_ALLOWED in ${1:-result}" + exit 1 +fi From e77bbbdd8bdb499bde74dda9fcccf659a2ffb21a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 8 Sep 2026 23:03:12 +0300 Subject: [PATCH 02/14] ci: report offending file path in glibc floor check Co-Authored-By: Claude Sonnet 5 --- scripts/check-glibc-floor.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/check-glibc-floor.sh b/scripts/check-glibc-floor.sh index 6d888a9d50..d3230167ca 100755 --- a/scripts/check-glibc-floor.sh +++ b/scripts/check-glibc-floor.sh @@ -4,15 +4,17 @@ set -Eeu -o pipefail MAX_ALLOWED="2.31" -FLOOR=$(find -L result -type f -exec objdump -T {} \; 2>/dev/null \ - | grep -oE 'GLIBC_[0-9.]+' | sed 's/GLIBC_//' | sort -V | tail -1) +HIT=$(find -L result -type f -exec sh -c \ + 'objdump -T "$1" 2>/dev/null | grep -oE "GLIBC_[0-9.]+" | sed -E "s#GLIBC_([0-9.]+)#\1 $1#"' _ {} \; \ + | sort -V | tail -1) -if [ -z "$FLOOR" ]; then +if [ -z "$HIT" ]; then exit 0 fi +FLOOR=${HIT%% *} echo "glibc floor: $FLOOR (max allowed: $MAX_ALLOWED)" if [ "$(printf '%s\n%s' "$MAX_ALLOWED" "$FLOOR" | sort -V | tail -1)" != "$MAX_ALLOWED" ]; then - echo "::error::glibc floor $FLOOR exceeds max allowed $MAX_ALLOWED in ${1:-result}" + echo "::error::glibc floor $HIT exceeds max allowed $MAX_ALLOWED in ${1:-result}" exit 1 fi From d4127eaca9d93d1742b345fe33373e8c2fb6d24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 8 Sep 2026 23:17:16 +0300 Subject: [PATCH 03/14] style: shfmt check-glibc-floor.sh Co-Authored-By: Claude Sonnet 5 --- scripts/check-glibc-floor.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/check-glibc-floor.sh b/scripts/check-glibc-floor.sh index d3230167ca..ce2d178736 100755 --- a/scripts/check-glibc-floor.sh +++ b/scripts/check-glibc-floor.sh @@ -5,16 +5,16 @@ set -Eeu -o pipefail MAX_ALLOWED="2.31" HIT=$(find -L result -type f -exec sh -c \ - 'objdump -T "$1" 2>/dev/null | grep -oE "GLIBC_[0-9.]+" | sed -E "s#GLIBC_([0-9.]+)#\1 $1#"' _ {} \; \ - | sort -V | tail -1) + 'objdump -T "$1" 2>/dev/null | grep -oE "GLIBC_[0-9.]+" | sed -E "s#GLIBC_([0-9.]+)#\1 $1#"' _ {} \; | + sort -V | tail -1) if [ -z "$HIT" ]; then - exit 0 + exit 0 fi FLOOR=${HIT%% *} echo "glibc floor: $FLOOR (max allowed: $MAX_ALLOWED)" if [ "$(printf '%s\n%s' "$MAX_ALLOWED" "$FLOOR" | sort -V | tail -1)" != "$MAX_ALLOWED" ]; then - echo "::error::glibc floor $HIT exceeds max allowed $MAX_ALLOWED in ${1:-result}" - exit 1 + echo "::error::glibc floor $HIT exceeds max allowed $MAX_ALLOWED in ${1:-result}" + exit 1 fi From 1a8820eb4f9d0ad2c4181e807a93288631e027e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 22:07:34 +0300 Subject: [PATCH 04/14] ci: move glibc floor check into nix flake check Runs as checks..glibc-floor, auto-discovered by the existing nix-eval matrix generator, so no workflow changes are needed. Scans every legacyPackages derivation instead of one step per matrix leg. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/nix-build.yml | 6 ------ nix/checks.nix | 27 +++++++++++++++++++++++++++ scripts/check-glibc-floor.sh | 20 -------------------- 3 files changed, 27 insertions(+), 26 deletions(-) delete mode 100755 scripts/check-glibc-floor.sh diff --git a/.github/workflows/nix-build.yml b/.github/workflows/nix-build.yml index f379d07a59..e286015cca 100644 --- a/.github/workflows/nix-build.yml +++ b/.github/workflows/nix-build.yml @@ -73,9 +73,6 @@ jobs: uses: ./.github/actions/nix-build-retry with: attr: .#${{ matrix.attr }} - - name: Check glibc floor - if: ${{ matrix.attr != '' }} - run: ./scripts/check-glibc-floor.sh "${{ matrix.attr }}" nix-build-checks-aarch64-linux: name: >- @@ -195,9 +192,6 @@ jobs: uses: ./.github/actions/nix-build-retry with: attr: .#${{ matrix.attr }} - - name: Check glibc floor - if: ${{ matrix.attr != '' }} - run: ./scripts/check-glibc-floor.sh "${{ matrix.attr }}" nix-build-checks-x86_64-linux: name: >- diff --git a/nix/checks.nix b/nix/checks.nix index 3fdd5ba2c0..7e1135ad7e 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -954,6 +954,33 @@ postgresql_17_src ; psql_orioledb-17_exts_orioledb_debug = self'.legacyPackages.psql_orioledb-17.exts.orioledb.debug; + glibc-floor = + pkgs.runCommand "glibc-floor-check" + { + nativeBuildInputs = [ pkgs.binutils ]; + paths = lib.collect lib.isDerivation self'.legacyPackages; + } + '' + MAX_ALLOWED="2.31" + HIT=$( + for p in $paths; do find -L "$p" -type f; done \ + | while IFS= read -r f; do + objdump -T "$f" 2>/dev/null | grep -oE 'GLIBC_[0-9.]+' | sed -E "s#GLIBC_([0-9.]+)#\1 $f#" + done \ + | sort -V | tail -1 + ) + + if [ -n "$HIT" ]; then + FLOOR=''${HIT%% *} + echo "glibc floor: $FLOOR (max allowed: $MAX_ALLOWED)" + if [ "$(printf '%s\n%s' "$MAX_ALLOWED" "$FLOOR" | sort -V | tail -1)" != "$MAX_ALLOWED" ]; then + echo "glibc floor $HIT exceeds max allowed $MAX_ALLOWED" + exit 1 + fi + fi + + touch $out + ''; }; }; } diff --git a/scripts/check-glibc-floor.sh b/scripts/check-glibc-floor.sh deleted file mode 100755 index ce2d178736..0000000000 --- a/scripts/check-glibc-floor.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -# Fails if any file in ./result requires a glibc symbol version above MAX_ALLOWED. -set -Eeu -o pipefail - -MAX_ALLOWED="2.31" - -HIT=$(find -L result -type f -exec sh -c \ - 'objdump -T "$1" 2>/dev/null | grep -oE "GLIBC_[0-9.]+" | sed -E "s#GLIBC_([0-9.]+)#\1 $1#"' _ {} \; | - sort -V | tail -1) - -if [ -z "$HIT" ]; then - exit 0 -fi - -FLOOR=${HIT%% *} -echo "glibc floor: $FLOOR (max allowed: $MAX_ALLOWED)" -if [ "$(printf '%s\n%s' "$MAX_ALLOWED" "$FLOOR" | sort -V | tail -1)" != "$MAX_ALLOWED" ]; then - echo "::error::glibc floor $HIT exceeds max allowed $MAX_ALLOWED in ${1:-result}" - exit 1 -fi From 19a5573700f8d0485c9a867d17051129197efa63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 22:17:05 +0300 Subject: [PATCH 05/14] ci: rewrite glibc-floor check logic in nushell Same find/objdump/version-compare logic, packaged via pkgs.writers.writeNuBin. Verified standalone against a fake objdump (pass/fail/no-match cases) since the local linux-builder VM's clock is currently skewed and blocking real nix builds unrelated to this change. Co-Authored-By: Claude Sonnet 5 --- nix/checks.nix | 35 ++++++++++------------------ nix/tools/check-glibc-floor.nu | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 23 deletions(-) create mode 100644 nix/tools/check-glibc-floor.nu diff --git a/nix/checks.nix b/nix/checks.nix index 7e1135ad7e..91a31a4046 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -955,30 +955,19 @@ ; psql_orioledb-17_exts_orioledb_debug = self'.legacyPackages.psql_orioledb-17.exts.orioledb.debug; glibc-floor = - pkgs.runCommand "glibc-floor-check" - { - nativeBuildInputs = [ pkgs.binutils ]; - paths = lib.collect lib.isDerivation self'.legacyPackages; - } + let + checkScript = pkgs.writers.writeNuBin "check-glibc-floor" { + makeWrapperArgs = [ + "--prefix" + "PATH" + ":" + "${lib.makeBinPath [ pkgs.binutils ]}" + ]; + } (builtins.readFile ./tools/check-glibc-floor.nu); + in + pkgs.runCommand "glibc-floor-check" { paths = lib.collect lib.isDerivation self'.legacyPackages; } '' - MAX_ALLOWED="2.31" - HIT=$( - for p in $paths; do find -L "$p" -type f; done \ - | while IFS= read -r f; do - objdump -T "$f" 2>/dev/null | grep -oE 'GLIBC_[0-9.]+' | sed -E "s#GLIBC_([0-9.]+)#\1 $f#" - done \ - | sort -V | tail -1 - ) - - if [ -n "$HIT" ]; then - FLOOR=''${HIT%% *} - echo "glibc floor: $FLOOR (max allowed: $MAX_ALLOWED)" - if [ "$(printf '%s\n%s' "$MAX_ALLOWED" "$FLOOR" | sort -V | tail -1)" != "$MAX_ALLOWED" ]; then - echo "glibc floor $HIT exceeds max allowed $MAX_ALLOWED" - exit 1 - fi - fi - + ${lib.getExe checkScript} 2.31 $paths touch $out ''; }; diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu new file mode 100644 index 0000000000..f0c89bbfcf --- /dev/null +++ b/nix/tools/check-glibc-floor.nu @@ -0,0 +1,42 @@ +# Fails if any file under the given paths requires a glibc symbol version +# above the allowed floor. + +def "ver-key" [ver: string] { + $ver | split row "." | each { into int } +} + +def main [max_allowed: string, ...paths: string] { + let hits = ( + $paths + | each { |p| glob ($p + "/**/*") } + | flatten + | where { |f| ($f | path type) == file } + | each { |f| + let res = (do { ^objdump -T $f } | complete) + if $res.exit_code != 0 { + [] + } else { + $res.stdout | parse -r 'GLIBC_(?[0-9.]+)' | each { |m| { ver: $m.ver, file: $f } } + } + } + | flatten + ) + + if ($hits | is-empty) { + exit 0 + } + + let worst = ( + $hits + | insert key { |h| ver-key $h.ver } + | sort-by key + | last + ) + + print $"glibc floor: ($worst.ver) \(max allowed: ($max_allowed)\) — ($worst.file)" + + if (ver-key $worst.ver) > (ver-key $max_allowed) { + print $"glibc floor ($worst.ver) exceeds max allowed ($max_allowed) in ($worst.file)" + exit 1 + } +} From 06ebba7e1d5a440342e60b280e2aabed04e6f05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 22:27:03 +0300 Subject: [PATCH 06/14] ci: list every offending file in glibc-floor check Drop the single-worst summary line; print one line per file that exceeds the floor (deduped to its own worst symbol version), plus a short pass line when nothing offends. Co-Authored-By: Claude Sonnet 5 --- nix/tools/check-glibc-floor.nu | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu index f0c89bbfcf..03e569f005 100644 --- a/nix/tools/check-glibc-floor.nu +++ b/nix/tools/check-glibc-floor.nu @@ -6,37 +6,37 @@ def "ver-key" [ver: string] { } def main [max_allowed: string, ...paths: string] { - let hits = ( + let max_key = (ver-key $max_allowed) + + let offenders = ( $paths | each { |p| glob ($p + "/**/*") } | flatten | where { |f| ($f | path type) == file } | each { |f| let res = (do { ^objdump -T $f } | complete) - if $res.exit_code != 0 { + let vers = (if $res.exit_code == 0 { + $res.stdout | parse -r 'GLIBC_(?[0-9.]+)' | get ver + } else { [] + }) + if ($vers | is-empty) { + null } else { - $res.stdout | parse -r 'GLIBC_(?[0-9.]+)' | each { |m| { ver: $m.ver, file: $f } } + { file: $f, ver: ($vers | sort-by { |v| ver-key $v } | last) } } } - | flatten + | compact + | where { |h| (ver-key $h.ver) > $max_key } ) - if ($hits | is-empty) { + if ($offenders | is-empty) { + print $"glibc floor OK \(<= ($max_allowed)\)" exit 0 } - let worst = ( - $hits - | insert key { |h| ver-key $h.ver } - | sort-by key - | last - ) - - print $"glibc floor: ($worst.ver) \(max allowed: ($max_allowed)\) — ($worst.file)" - - if (ver-key $worst.ver) > (ver-key $max_allowed) { - print $"glibc floor ($worst.ver) exceeds max allowed ($max_allowed) in ($worst.file)" - exit 1 + for o in $offenders { + print $"glibc floor ($o.ver) exceeds max allowed ($max_allowed) in ($o.file)" } + exit 1 } From e6578892e4b6c1300a74eb75a3072c2458dfffb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 22:43:08 +0300 Subject: [PATCH 07/14] ci: idiomatic nushell refactor for glibc-floor check Print offenders as a table instead of hand-formatted strings, run objdump via par-each, drop the do{}/exit_code plumbing (a failing objdump naturally yields no stdout, so it's already filtered out). Co-Authored-By: Claude Sonnet 5 --- nix/tools/check-glibc-floor.nu | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu index 03e569f005..1218a65c52 100644 --- a/nix/tools/check-glibc-floor.nu +++ b/nix/tools/check-glibc-floor.nu @@ -1,7 +1,7 @@ # Fails if any file under the given paths requires a glibc symbol version # above the allowed floor. -def "ver-key" [ver: string] { +def ver-key [ver: string] { $ver | split row "." | each { into int } } @@ -10,24 +10,19 @@ def main [max_allowed: string, ...paths: string] { let offenders = ( $paths - | each { |p| glob ($p + "/**/*") } + | each { |p| glob $"($p)/**/*" } | flatten | where { |f| ($f | path type) == file } - | each { |f| - let res = (do { ^objdump -T $f } | complete) - let vers = (if $res.exit_code == 0 { - $res.stdout | parse -r 'GLIBC_(?[0-9.]+)' | get ver - } else { - [] - }) - if ($vers | is-empty) { + | par-each { |file| + let versions = (^objdump -T $file | complete | get stdout | parse -r 'GLIBC_(?[0-9.]+)' | get ver) + if ($versions | is-empty) { null } else { - { file: $f, ver: ($vers | sort-by { |v| ver-key $v } | last) } + { file: $file, version: ($versions | sort-by { |v| ver-key $v } | last) } } } | compact - | where { |h| (ver-key $h.ver) > $max_key } + | where { |h| (ver-key $h.version) > $max_key } ) if ($offenders | is-empty) { @@ -35,8 +30,6 @@ def main [max_allowed: string, ...paths: string] { exit 0 } - for o in $offenders { - print $"glibc floor ($o.ver) exceeds max allowed ($max_allowed) in ($o.file)" - } + print $offenders exit 1 } From c5d724d22d02088108a845fc7cf2dd62b6b05023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 22:50:41 +0300 Subject: [PATCH 08/14] ci: scan both legacyPackages and packages in glibc-floor check packages is missing site-extensions-versions-* and only exposes flat psql_X/bin (not individual .exts.*), so union both trees rather than choosing one and risking a coverage gap. Co-Authored-By: Claude Sonnet 5 --- nix/checks.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nix/checks.nix b/nix/checks.nix index 91a31a4046..8ed069bb1f 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -965,7 +965,10 @@ ]; } (builtins.readFile ./tools/check-glibc-floor.nu); in - pkgs.runCommand "glibc-floor-check" { paths = lib.collect lib.isDerivation self'.legacyPackages; } + pkgs.runCommand "glibc-floor-check" + { + paths = lib.collect lib.isDerivation (self'.legacyPackages // self'.packages); + } '' ${lib.getExe checkScript} 2.31 $paths touch $out From 897948dd6192e8cd6df566e6679eb12e7aeea7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 22:55:28 +0300 Subject: [PATCH 09/14] ci: filter to real ELF files before running objdump Packages contain far more non-ELF files (docs, control files, SQL, scripts) than ELF ones. Checking the magic bytes natively in nushell avoids spawning an objdump process per file that could never match. Co-Authored-By: Claude Sonnet 5 --- nix/tools/check-glibc-floor.nu | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu index 1218a65c52..bd20d601c1 100644 --- a/nix/tools/check-glibc-floor.nu +++ b/nix/tools/check-glibc-floor.nu @@ -5,6 +5,10 @@ def ver-key [ver: string] { $ver | split row "." | each { into int } } +def is-elf [file: string] { + (open --raw $file | bytes at 0..<4) == 0x[7f454c46] +} + def main [max_allowed: string, ...paths: string] { let max_key = (ver-key $max_allowed) @@ -13,6 +17,7 @@ def main [max_allowed: string, ...paths: string] { | each { |p| glob $"($p)/**/*" } | flatten | where { |f| ($f | path type) == file } + | where { |f| is-elf $f } | par-each { |file| let versions = (^objdump -T $file | complete | get stdout | parse -r 'GLIBC_(?[0-9.]+)' | get ver) if ($versions | is-empty) { From 7f22b52cb28034864e7a8e0d1bcf2f279a50db32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 22:59:13 +0300 Subject: [PATCH 10/14] ci: fold file-type check into is-elf, add a return type is-elf now guards its own path-type check, collapsing the two where clauses into one. Also tried adding a `-> list` return type to ver-key, but nushell's static checker rejects `>` on that type even though it works fine at runtime on inferred lists, so left it untyped. Co-Authored-By: Claude Sonnet 5 --- nix/tools/check-glibc-floor.nu | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu index bd20d601c1..766225688b 100644 --- a/nix/tools/check-glibc-floor.nu +++ b/nix/tools/check-glibc-floor.nu @@ -5,8 +5,12 @@ def ver-key [ver: string] { $ver | split row "." | each { into int } } -def is-elf [file: string] { - (open --raw $file | bytes at 0..<4) == 0x[7f454c46] +def is-elf [path: string]: nothing -> bool { + if ($path | path type) != file { + false + } else { + (open --raw $path | bytes at 0..<4) == 0x[7f454c46] + } } def main [max_allowed: string, ...paths: string] { @@ -16,7 +20,6 @@ def main [max_allowed: string, ...paths: string] { $paths | each { |p| glob $"($p)/**/*" } | flatten - | where { |f| ($f | path type) == file } | where { |f| is-elf $f } | par-each { |file| let versions = (^objdump -T $file | complete | get stdout | parse -r 'GLIBC_(?[0-9.]+)' | get ver) From 9ba877941ebad821d58c8c87007467c008a8bae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 23:00:12 +0300 Subject: [PATCH 11/14] ci: simplify is-elf to a single short-circuit expression Co-Authored-By: Claude Sonnet 5 --- nix/tools/check-glibc-floor.nu | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu index 766225688b..3d5ecba57e 100644 --- a/nix/tools/check-glibc-floor.nu +++ b/nix/tools/check-glibc-floor.nu @@ -6,11 +6,7 @@ def ver-key [ver: string] { } def is-elf [path: string]: nothing -> bool { - if ($path | path type) != file { - false - } else { - (open --raw $path | bytes at 0..<4) == 0x[7f454c46] - } + ($path | path type) == file and (open --raw $path | bytes at 0..<4) == 0x[7f454c46] } def main [max_allowed: string, ...paths: string] { From 2c45b748ae276b5327c5b42707329e383e37e6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 23:03:49 +0300 Subject: [PATCH 12/14] ci: make is-elf consume \$in for point-free where usage Co-Authored-By: Claude Sonnet 5 --- nix/tools/check-glibc-floor.nu | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu index 3d5ecba57e..299d7d3bed 100644 --- a/nix/tools/check-glibc-floor.nu +++ b/nix/tools/check-glibc-floor.nu @@ -5,8 +5,8 @@ def ver-key [ver: string] { $ver | split row "." | each { into int } } -def is-elf [path: string]: nothing -> bool { - ($path | path type) == file and (open --raw $path | bytes at 0..<4) == 0x[7f454c46] +def is-elf []: string -> bool { + ($in | path type) == file and (open --raw $in | bytes at 0..<4) == 0x[7f454c46] } def main [max_allowed: string, ...paths: string] { @@ -16,7 +16,7 @@ def main [max_allowed: string, ...paths: string] { $paths | each { |p| glob $"($p)/**/*" } | flatten - | where { |f| is-elf $f } + | where { is-elf } | par-each { |file| let versions = (^objdump -T $file | complete | get stdout | parse -r 'GLIBC_(?[0-9.]+)' | get ver) if ($versions | is-empty) { From 2e2af84f408d1d2919ee236432d81f91312088df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 13 Sep 2026 23:06:31 +0300 Subject: [PATCH 13/14] ci: drop if/else + compact for a single filter [] | last returns null rather than erroring, so building the record unconditionally and filtering null versions out in one where clause replaces the separate if/else + compact step. Co-Authored-By: Claude Sonnet 5 --- nix/tools/check-glibc-floor.nu | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu index 299d7d3bed..4fde55b689 100644 --- a/nix/tools/check-glibc-floor.nu +++ b/nix/tools/check-glibc-floor.nu @@ -18,15 +18,16 @@ def main [max_allowed: string, ...paths: string] { | flatten | where { is-elf } | par-each { |file| - let versions = (^objdump -T $file | complete | get stdout | parse -r 'GLIBC_(?[0-9.]+)' | get ver) - if ($versions | is-empty) { - null - } else { - { file: $file, version: ($versions | sort-by { |v| ver-key $v } | last) } + { + file: $file, + version: ( + ^objdump -T $file | complete | get stdout + | parse -r 'GLIBC_(?[0-9.]+)' | get ver + | sort-by { |v| ver-key $v } | last + ), } } - | compact - | where { |h| (ver-key $h.version) > $max_key } + | where { |h| $h.version != null and (ver-key $h.version) > $max_key } ) if ($offenders | is-empty) { From 696473b5ade3039a0ac0d3f4ecc089a8c53745ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Mon, 14 Sep 2026 08:49:50 +0300 Subject: [PATCH 14/14] ci: rewrite glibc floor check as glibc-version-check, idiomatic nushell Renamed away from "floor" terminology (the function computes each file's max required glibc version, not a floor) across the nix check attribute, script filename, and its docstring/output text. Also rewrote the check logic itself in idiomatic nushell: is-elf and max-glibc-version as named helpers, ELF detection via magic-byte check (skips non-ELF files instead of shelling out to objdump for every file), version comparison via parsed int lists, and offending files printed as a table. Co-Authored-By: Claude Sonnet 5 --- nix/checks.nix | 8 +++---- nix/tools/check-glibc-floor.nu | 40 -------------------------------- nix/tools/check-glibc-version.nu | 38 ++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 44 deletions(-) delete mode 100644 nix/tools/check-glibc-floor.nu create mode 100755 nix/tools/check-glibc-version.nu diff --git a/nix/checks.nix b/nix/checks.nix index 8ed069bb1f..a6b66eb8a8 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -954,18 +954,18 @@ postgresql_17_src ; psql_orioledb-17_exts_orioledb_debug = self'.legacyPackages.psql_orioledb-17.exts.orioledb.debug; - glibc-floor = + glibc-version-check = let - checkScript = pkgs.writers.writeNuBin "check-glibc-floor" { + checkScript = pkgs.writers.writeNuBin "check-glibc-version" { makeWrapperArgs = [ "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.binutils ]}" ]; - } (builtins.readFile ./tools/check-glibc-floor.nu); + } (builtins.readFile ./tools/check-glibc-version.nu); in - pkgs.runCommand "glibc-floor-check" + pkgs.runCommand "glibc-version-check" { paths = lib.collect lib.isDerivation (self'.legacyPackages // self'.packages); } diff --git a/nix/tools/check-glibc-floor.nu b/nix/tools/check-glibc-floor.nu deleted file mode 100644 index 4fde55b689..0000000000 --- a/nix/tools/check-glibc-floor.nu +++ /dev/null @@ -1,40 +0,0 @@ -# Fails if any file under the given paths requires a glibc symbol version -# above the allowed floor. - -def ver-key [ver: string] { - $ver | split row "." | each { into int } -} - -def is-elf []: string -> bool { - ($in | path type) == file and (open --raw $in | bytes at 0..<4) == 0x[7f454c46] -} - -def main [max_allowed: string, ...paths: string] { - let max_key = (ver-key $max_allowed) - - let offenders = ( - $paths - | each { |p| glob $"($p)/**/*" } - | flatten - | where { is-elf } - | par-each { |file| - { - file: $file, - version: ( - ^objdump -T $file | complete | get stdout - | parse -r 'GLIBC_(?[0-9.]+)' | get ver - | sort-by { |v| ver-key $v } | last - ), - } - } - | where { |h| $h.version != null and (ver-key $h.version) > $max_key } - ) - - if ($offenders | is-empty) { - print $"glibc floor OK \(<= ($max_allowed)\)" - exit 0 - } - - print $offenders - exit 1 -} diff --git a/nix/tools/check-glibc-version.nu b/nix/tools/check-glibc-version.nu new file mode 100755 index 0000000000..fb5617e884 --- /dev/null +++ b/nix/tools/check-glibc-version.nu @@ -0,0 +1,38 @@ +#!/usr/bin/env nu + +def parse-version [] { + split row "." | each { into int } +} + +def is-elf []: path -> bool { + (open --raw $in | bytes at 0..<4) == ("\u{7f}ELF" | into binary) +} + +def max-glibc-version [path: path] { + ^objdump -T $path | complete | get stdout + | parse -r 'GLIBC_(?[0-9.]+)' | get ver + | each { parse-version } + | sort + | last +} + +# Fails if any file under the given paths requires a newer glibc than max_version. +def main [max_version: string, ...paths: path] { + let offenders = ( + $paths + | each { glob $"($in)/**/*" } | flatten + | where { ($in | path type) == file } + | where { is-elf } + | par-each { |f| { file: $f, version: (max-glibc-version $f) } } + | compact version + | where version > ($max_version | parse-version) + ) + + if ($offenders | is-empty) { + print $"glibc version OK \(<= ($max_version)\)" + exit 0 + } + + print $offenders + exit 1 +}