From 00d89868c87a837008c3d8fa4469739ebcc71ca4 Mon Sep 17 00:00:00 2001 From: mia26MAjFm Date: Wed, 24 Jun 2026 06:59:55 -0400 Subject: [PATCH] build-image: clean step now umounts + detaches loops before rm Cachyos build on minipc-gh-2 failed with "Directory not empty" because a previous run left a loop device backed by a (deleted) file in image/work/, and rm -rf can't cross the live mountpoint. Lazy- umount everything under the workspace + detach matching loops before the rm so stale mounts don't fail subsequent runs. --- .github/workflows/build-image.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index d42dc31..1bd927c 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -63,7 +63,28 @@ jobs: echo "Invalid GITHUB_WORKSPACE" >&2 exit 1 fi - sudo rm -rf "$GITHUB_WORKSPACE/image" + # A previous run can leave loop mounts (kpartx / losetup -P) and + # bind mounts (distrobuilder chroots) live inside image/work/. + # rm -rf then trips on "Directory not empty" because it can't + # cross the mountpoint. Unmount everything under the workspace + # first, then detach any loop devices still backed by files in + # the workspace, then rm. + WS="$GITHUB_WORKSPACE" + # Lazy-unmount any mount whose target is under the workspace. + # Reverse order so deepest mounts go first. + for m in $(findmnt -rn -o TARGET | grep "^$WS/" | sort -r || true); do + echo "unmounting stale $m" + sudo umount -l "$m" || true + done + # Detach any loop device whose backing file lives under the + # workspace (or shows '(deleted)' against one — that means the + # backing file was removed but the loop wasn't released). + for l in $(sudo losetup -l --noheadings -O NAME,BACK-FILE 2>/dev/null \ + | awk -v ws="$WS" '$2 ~ "^"ws || $2 ~ ws"/" || $2 ~ "\\(deleted\\)$" {print $1}'); do + echo "detaching stale loop $l" + sudo losetup -d "$l" || true + done + sudo rm -rf "$WS/image" - name: Checkout image builder uses: actions/checkout@v6