Ah, I forgot to handle the case where /srv/local-apt-repository doesn't exist
when the package is installed. This updated patch (and my latest push on
salsa.d.o) should fix that.
>From bd063c0a9ba11ff53ba9b233ed5c63a64ee97495 Mon Sep 17 00:00:00 2001
From: Darsey Litzenberger <[email protected]>
Date: Mon, 21 Jul 2025 16:15:08 -0600
Subject: [PATCH 6/7] Fix several error cases; improve comments
Most of the bugs fixed here are related to bash's inconsistent errexit
behavior. In bash, "set -e" (errexit) has no effect when a conditional
is being evaluated on a compound statement. For example:
# The following code prints "after false" and succeeds.
set -e
( false
echo after false
) || false
So, errors went uncaught if apt-ftparchive failed while generating
$REPO/Packages but succeeded while generating $REPO/Sources, or if dpkg
failed to print the architecture list for some reason.
The script might also have broken if apt-ftparchive generated partial
output and the 10-retry limit was exceeded.
---
rebuild | 70 ++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 47 insertions(+), 23 deletions(-)
diff --git a/rebuild b/rebuild
index 694491b..8178a9c 100755
--- a/rebuild
+++ b/rebuild
@@ -1,52 +1,76 @@
#!/bin/bash
-set -e
+set -eu
DEBS=/srv/local-apt-repository
REPO=/var/lib/local-apt-repository
CACHE=/var/cache/local-apt-repository
+ARCHS="$(dpkg --print-architecture && dpkg --print-foreign-architectures)"
-if ! test -d $DEBS
-then
- # We still need ot create the files lest apt will complain
- > $REPO/Packages
- > $REPO/Sources
- rm -f "$REPO"/Contents-*
+generate_index_files() {
+ # We need "|| return" after every command in this function, because "set -e"
+ # has no effect inside a conditional context.
+ # See https://mywiki.wooledge.org/BashPitfalls#errexit
+
+ # This function assumes that we are already inside the REPO directory.
+
+ apt-ftparchive packages --db "$CACHE/cache.db" ../../../"$DEBS" > Packages || return
+ apt-ftparchive sources --db "$CACHE/cache.db" ../../../"$DEBS" > Sources || return
+
+ rm -f Contents-* || return
+
+ for arch in $ARCHS
+ do
+ apt-ftparchive contents --db "$CACHE/cache.db" \
+ --arch "$arch" ../../../"$DEBS" > "Contents-$arch" || return
+ done
+}
+
+# We want apt-ftparchive to generate files with relative paths, and we want
+# this command to fail if the REPO directory does not exist, so change
+# directories before doing anything else.
+cd "$REPO"
-else
+has_directory=
+generated=
+if test -d "$DEBS"
+then
+ has_directory=1
# We want to cater for the possibility that something is added to $DEBS as we
# run, or that a file is slowly written. In this case, we want to wait a bit
# and restart. But lets bound this to 10 runs.
for n in $(seq 0 10)
do
- # This is the second round alreay, lets wait a while
+ # This is the second round already; let's wait a while.
if [ "$n" != "0" ]
then
echo "Further changes are coming in, waiting..."
sleep 10
fi
- # Relative paths work better than absolute
- (cd $REPO
- apt-ftparchive packages --db "$CACHE/cache.db" ../../../"$DEBS" > "$REPO/Packages"
- apt-ftparchive sources --db "$CACHE/cache.db" ../../../"$DEBS" > "$REPO/Sources"
- rm -f "$REPO"/Contents-*
- for arch in $(dpkg --print-architecture) $(dpkg --print-foreign-architectures)
- do
- apt-ftparchive contents --db "$CACHE/cache.db" --arch "$arch" \
- ../../../"$DEBS" > "$REPO/Contents-$arch"
- done
- ) && break || true
- # ^ this can fail during a partial write to the directory (which
- # would be detected by the loop), so ignore errors here
+ # apt-ftparchive can fail during a partial write to the directory, so
+ # repeat the loop on any errors.
+ generate_index_files || continue
+ generated=1
+ break
done
+fi
+if ! [ "$generated" ]
+then
+ # We still need to create the files lest apt will complain
+ > Packages
+ > Sources
+ rm -f Contents-*
fi
apt-ftparchive \
-o "APT::FTPArchive::Release::Origin=local-apt-repository" \
-o "APT::FTPArchive::Release::Description=Local repository created by local-apt-repository" \
- release $REPO > $REPO/Release
+ release . > Release
+if [ "$has_directory" ] && ! [ "$generated" ]; then
+ exit 1
+fi
--
2.50.0