From 3cd16c94dc2ec3440e3d2d80b5111a46d6501414 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 25 Sep 2026 12:47:06 +0000 Subject: [PATCH 1/2] buildenv: provide file-io >= 0.2.0 so standalone builds get OsPath Our debianstandalone builds report no OsPath in "build flags", e.g. 10.20260901+git60-g7c2e8019c9-1~ndall+1: build flags: Assistant Webapp Inotify DBus DesktopNotify TorrentParser MagicMime Benchmark Feeds Testsuite S3 WebDAV Servant The OsPath flag is Default: True but not Manual, so `./Setup configure` quietly turns it off when a dependency is missing. In this image (GHC 9.10.3) filepath 1.5.4.0, os-string 2.0.7 and directory 1.3.8.5 already satisfy its bounds; only file-io is absent. Since 10.20260213 git-annex requires file-io >= 0.2.0, while Debian ships only libghc-file-io-dev 0.1.5, so `apt-get build-dep` cannot provide it. Build file-io 0.2.0 from Hackage (checksum-pinned) into the global GHC package db. It only depends on GHC boot packages. Verified in the current image: `./Setup configure -v2` of git-annex 10.20260901 goes from "ospath=False" to "Dependency file-io >=0.2.0: using file-io-0.2.0". Without OsPath, git-annex keeps known issues fixed only in OsPath builds, e.g. https://git-annex.branchable.com/bugs/35_failed_tests_on_beegfs/ and fd leaks to child processes (per upstream CHANGELOG). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013n9Q2igij49kxdtiakUzYv --- .../containers/buildenv-git-annex/Dockerfile | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/tools/containers/buildenv-git-annex/Dockerfile b/.github/workflows/tools/containers/buildenv-git-annex/Dockerfile index 455c0ca48c..702215ee5b 100644 --- a/.github/workflows/tools/containers/buildenv-git-annex/Dockerfile +++ b/.github/workflows/tools/containers/buildenv-git-annex/Dockerfile @@ -33,3 +33,27 @@ RUN set -ex; \ apt-get install -y vim wget strace time ncdu gnupg curl procps datalad pigz less tree; \ apt-get clean; \ rm -rf /var/lib/apt/lists/* + +# git-annex's OsPath build flag (Default: True, but automatic, so ./Setup +# configure silently drops it when a dependency is missing) needs +# file-io >= 0.2.0 since 10.20260213. GHC 9.10 here already provides +# filepath >= 1.5.2, os-string >= 2.0 and directory >= 1.3.8.3, but Debian +# ships only libghc-file-io-dev 0.1.5, so without this builds lack OsPath +# (and with it the fixes e.g. for rename handling on BeeGFS: +# https://git-annex.branchable.com/bugs/35_failed_tests_on_beegfs/). +# file-io only needs GHC boot packages, so register it into the global +# package db. Drop once Debian provides libghc-file-io-dev (>= 0.2.0). +ARG FILE_IO_VERSION=0.2.0 +ARG FILE_IO_SHA256=8e75f8905d7c9f114e6164779e7a19ff0e2968015ecf686934e38250575dabe7 +RUN set -ex; \ + cd /tmp; \ + curl -fsSL -o file-io.tar.gz "https://hackage.haskell.org/package/file-io-${FILE_IO_VERSION}/file-io-${FILE_IO_VERSION}.tar.gz"; \ + echo "${FILE_IO_SHA256} file-io.tar.gz" | sha256sum -c -; \ + tar xzf file-io.tar.gz; \ + cd "file-io-${FILE_IO_VERSION}"; \ + printf 'import Distribution.Simple\nmain = defaultMain\n' > Setup.hs; \ + runghc Setup.hs configure --global --prefix=/usr/local; \ + runghc Setup.hs build; \ + runghc Setup.hs install; \ + ghc-pkg field file-io version; \ + cd /; rm -rf /tmp/file-io* From 7942b0668bc4d514a9a96d96397c0c71154150e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 25 Sep 2026 20:40:46 +0000 Subject: [PATCH 2/2] buildenv: pin snapshot.debian.org sources directly instead of nd_freeze The buildenv image build for #295 hung for the full 6h job limit right after nd_freeze printed "INFO: Refreshing apt cache", with no further output. After that first `apt-get update`, nd_freeze scrapes snapshot.debian.org via get_www_content(): a raw-socket HTTP/1.1 GET without "Connection: close" and with no timeout, reading until EOF, and it logs nothing there unless --debug. A stalled connection there hangs forever silently. Write deb822 sources for snapshot.debian.org ourselves instead, as of DEBIAN_SNAPSHOT (an ARG, now 20260924T000000Z). snapshot.debian.org serves the latest snapshot at or before the given timestamp. This also drops what only existed to work around nd_freeze: the neurodebian-freeze install from deb.debian.org, disabling debian.sources, and the sed adding deb-src lines (the deb822 stanzas carry "Types: deb deb-src"). Add Acquire::http::Timeout so a stalled transfer fails and gets retried (Acquire::Retries 10) instead of hanging. build-linux-buildenv.yaml derived the image tag's date by grepping for nd_freeze; it now reads DEBIAN_SNAPSHOT (YYYYMMDD part), so tags keep the forky-YYYYMMDD- shape. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013n9Q2igij49kxdtiakUzYv --- .github/workflows/build-linux-buildenv.yaml | 2 +- .../containers/buildenv-git-annex/Dockerfile | 41 ++++++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build-linux-buildenv.yaml b/.github/workflows/build-linux-buildenv.yaml index 79ef441d11..1db920990a 100644 --- a/.github/workflows/build-linux-buildenv.yaml +++ b/.github/workflows/build-linux-buildenv.yaml @@ -24,7 +24,7 @@ jobs: run: | set -eux release=$(sed -nE -e '/FROM/s,.*:(.*),\1,gp' Dockerfile) - freeze_date=$(sed -nE '/nd_freeze/s,.* (20[0-9]*).*,\1,gp' Dockerfile) + freeze_date=$(sed -nE 's,^ARG DEBIAN_SNAPSHOT=(20[0-9]{6}).*,\1,p' Dockerfile) commit=$(git rev-parse --short=4 HEAD) docker build \ -t "datalad/buildenv-git-annex:latest" \ diff --git a/.github/workflows/tools/containers/buildenv-git-annex/Dockerfile b/.github/workflows/tools/containers/buildenv-git-annex/Dockerfile index 702215ee5b..5ce5628d56 100644 --- a/.github/workflows/tools/containers/buildenv-git-annex/Dockerfile +++ b/.github/workflows/tools/containers/buildenv-git-annex/Dockerfile @@ -8,22 +8,33 @@ RUN echo 'Acquire::http::Dl-Limit "200";' >| /etc/apt/apt.conf.d/20snapshots \ && echo 'Acquire::https::Dl-Limit "200";' >> /etc/apt/apt.conf.d/20snapshots \ && echo 'Acquire::Retries "10";' >> /etc/apt/apt.conf.d/20snapshots -# Notes: -# - in APT for NeuroDebian we have #deb-src for debian-devel, so we need to change -# that too. -# - APT specification switched away from .list to .sources format in bookworm. -# nd_freeze works on policy output so works fine but does not disable old source -# file, so we are moving it to .disabled "manually" here if we do not detect -# use of snapshot url there (we might implement support that way). -# Remove after https://github.com/neurodebian/neurodebian/issues/90 is fixed/released -# for the used date of nd_freeze. -# - Originally used neurodebian, now switched to debian based for trixie +# Pin APT to a snapshot.debian.org timestamp by writing the deb822 sources +# directly, instead of via nd_freeze. nd_freeze scrapes snapshot.debian.org +# with a raw HTTP/1.1 socket read that has no timeout, and a build once hung +# there silently until the 6h job limit. snapshot.debian.org serves the most +# recent snapshot at or before the given timestamp. deb-src is needed for +# `apt-get build-dep`. The Release files on snapshots are past their +# Valid-Until, hence Check-Valid-Until=false. +# NB: the build-linux-buildenv workflow parses DEBIAN_SNAPSHOT for image tags. +ARG DEBIAN_SNAPSHOT=20260924T000000Z RUN set -ex; \ - apt update; \ - apt install neurodebian-freeze; \ - nd_freeze 20260425; \ - f=/etc/apt/sources.list.d/debian.sources; if [ -e "$f" ] && ! grep -q "^URIs:.*snapshot\." "$f"; then mv "$f" "$f.disabled"; fi; \ - sed -i -e 's,\(^deb\) \(.*\),\1 \2\ndeb-src \2,g' /etc/apt/sources.list.d/*.list; \ + echo 'Acquire::Check-Valid-Until "false";' >| /etc/apt/apt.conf.d/10no-check-valid-until; \ + echo 'Acquire::http::Timeout "120";' >> /etc/apt/apt.conf.d/20snapshots; \ + rm -f /etc/apt/sources.list /etc/apt/sources.list.d/*; \ + printf '%s\n' \ + 'Types: deb deb-src' \ + "URIs: http://snapshot.debian.org/archive/debian/${DEBIAN_SNAPSHOT}" \ + 'Suites: forky forky-updates' \ + 'Components: main' \ + 'Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp' \ + '' \ + 'Types: deb deb-src' \ + "URIs: http://snapshot.debian.org/archive/debian-security/${DEBIAN_SNAPSHOT}" \ + 'Suites: forky-security' \ + 'Components: main' \ + 'Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp' \ + >| /etc/apt/sources.list.d/debian-snapshot.sources; \ + cat /etc/apt/sources.list.d/debian-snapshot.sources; \ apt-get update -qq; \ export DEBIAN_FRONTEND=noninteractive; \ apt-get build-dep -y -q git-annex; \