From 05013ad3dac3576e01b6b1a50e01bc5730ca0dac Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 19 Aug 2026 00:03:04 -0700 Subject: [PATCH] ci: fall through to another Ubuntu mirror when one is unreachable (#10828) The e2e image pointed both archive and security at azure.archive.ubuntu.com and nothing else, and the samba and pjdfstest images inherit that list. When Azure is unreachable the build has nowhere to go: Acquire::Retries just retries a dead host, every package fails, and apt exits 100 before a single test runs. Two different workflows lost runs to it tonight. Install through a helper that starts from the pristine sources.list each time and walks a list of mirrors, so Azure stays the preferred one - the reason it was pinned in the first place - without being the only one. Verified both paths against a real build: the normal one installs from Azure, and with the first entry pointed at an unroutable host the fallback logs the skip and installs from archive.ubuntu.com. --- docker/Dockerfile.e2e | 26 +++++++++++--------------- docker/apt-install | 23 +++++++++++++++++++++++ test/pjdfstest/Dockerfile | 9 ++------- test/samba/Dockerfile | 9 ++------- 4 files changed, 38 insertions(+), 29 deletions(-) create mode 100755 docker/apt-install diff --git a/docker/Dockerfile.e2e b/docker/Dockerfile.e2e index 99b2b9163..4ffad1c15 100644 --- a/docker/Dockerfile.e2e +++ b/docker/Dockerfile.e2e @@ -2,25 +2,21 @@ FROM ubuntu:22.04 LABEL author="Chris Lu" -# Use Azure's Ubuntu mirror — much faster than archive.ubuntu.com from GitHub-hosted runners, -# which have been hanging long enough on Ign:/retry to trip the 10-min step timeout. # Note: This e2e test image intentionally runs as root for simplicity and compatibility. # Production images (Dockerfile.go_build) use proper user isolation with su-exec. # For testing purposes, running as root avoids permission complexities and dependency # on Alpine-specific tools like su-exec (not available in Ubuntu repos). -RUN sed -i 's|http://archive.ubuntu.com/ubuntu|http://azure.archive.ubuntu.com/ubuntu|g; s|http://security.ubuntu.com/ubuntu|http://azure.archive.ubuntu.com/ubuntu|g' /etc/apt/sources.list && \ - apt-get -o Acquire::http::Timeout=15 update && \ - DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::http::Timeout=15 install -y \ - --no-install-recommends \ - --no-install-suggests \ - curl \ - fio \ - fuse \ - ca-certificates \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /tmp/* \ - && rm -rf /var/tmp/* + +# apt-install prefers Azure's mirror, which archive.ubuntu.com is slow enough from +# GitHub-hosted runners to justify, and falls through to archive.ubuntu.com when +# Azure is unreachable - which it periodically is, and Acquire::Retries against a +# single mirror just retries a dead host. Images built FROM this one install +# through it for the same reason. +COPY apt-install /usr/local/bin/apt-install +RUN chmod +x /usr/local/bin/apt-install && \ + apt-install curl fio fuse ca-certificates && \ + rm -rf /tmp/* /var/tmp/* + RUN mkdir -p /etc/seaweedfs /data/filerldb2 COPY ./weed /usr/bin/ diff --git a/docker/apt-install b/docker/apt-install new file mode 100755 index 000000000..f534a4e9f --- /dev/null +++ b/docker/apt-install @@ -0,0 +1,23 @@ +#!/bin/sh +# Install packages, falling through to the next Ubuntu mirror when one is +# unreachable. See docker/Dockerfile.e2e. +set -e + +# Every rewrite starts from the pristine list, so a mirror that just failed does +# not become the pattern the next rewrite has to match. +[ -f /etc/apt/sources.list.orig ] || cp /etc/apt/sources.list /etc/apt/sources.list.orig + +for mirror in azure.archive.ubuntu.com archive.ubuntu.com; do + sed "s|http://archive\.ubuntu\.com/ubuntu|http://$mirror/ubuntu|g; s|http://security\.ubuntu\.com/ubuntu|http://$mirror/ubuntu|g" \ + /etc/apt/sources.list.orig > /etc/apt/sources.list + if apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=15 update && \ + DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=15 install -y \ + --no-install-recommends --no-install-suggests "$@"; then + apt-get clean + rm -rf /var/lib/apt/lists/* + exit 0 + fi + echo "apt: $mirror unreachable, trying the next mirror" >&2 +done + +exit 1 diff --git a/test/pjdfstest/Dockerfile b/test/pjdfstest/Dockerfile index 9aeb1c3ca..aec78954e 100644 --- a/test/pjdfstest/Dockerfile +++ b/test/pjdfstest/Dockerfile @@ -1,17 +1,12 @@ FROM chrislusf/seaweedfs:e2e -RUN apt-get -o Acquire::Retries=5 -o Acquire::http::Timeout=30 update && \ - DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=5 -o Acquire::http::Timeout=30 install -y \ - --no-install-recommends \ - --no-install-suggests \ +RUN apt-install \ autoconf \ automake \ build-essential \ git \ libtap-harness-archive-perl \ - perl \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* + perl ARG PJDFSTEST_REPO=https://github.com/sanwan/pjdfstest.git ARG PJDFSTEST_REF=d25636a227606f8960e5179741d8f4ad7030ef41 diff --git a/test/samba/Dockerfile b/test/samba/Dockerfile index e2756a586..8e8bbf296 100644 --- a/test/samba/Dockerfile +++ b/test/samba/Dockerfile @@ -1,14 +1,9 @@ FROM chrislusf/seaweedfs:e2e -RUN apt-get -o Acquire::Retries=5 -o Acquire::http::Timeout=30 update && \ - DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=5 -o Acquire::http::Timeout=30 install -y \ - --no-install-recommends \ - --no-install-suggests \ +RUN apt-install \ samba \ smbclient \ - python3-minimal \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* + python3-minimal COPY smb.conf.template /smb.conf.template COPY smb_tests.sh /smb_tests.sh