make_mirror.sh: also download a foreign architecture
This commit is contained in:
parent
7b4d052653
commit
7ca2e490d7
1 changed files with 98 additions and 91 deletions
189
make_mirror.sh
189
make_mirror.sh
|
@ -6,7 +6,11 @@ mirrordir="./mirror"
|
||||||
cachedir="./cache"
|
cachedir="./cache"
|
||||||
|
|
||||||
mirror="http://deb.debian.org/debian"
|
mirror="http://deb.debian.org/debian"
|
||||||
nativearch=$(dpkg --print-architecture)
|
arch1=$(dpkg --print-architecture)
|
||||||
|
arch2=armhf
|
||||||
|
if [ "$arch1" = "$arch2" ]; then
|
||||||
|
arch2=amd64
|
||||||
|
fi
|
||||||
components=main
|
components=main
|
||||||
|
|
||||||
if [ -e "$mirrordir/dists/unstable/Release" ]; then
|
if [ -e "$mirrordir/dists/unstable/Release" ]; then
|
||||||
|
@ -24,15 +28,17 @@ for dist in stable testing unstable; do
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
for dist in stable testing unstable; do
|
for nativearch in $arch1 $arch2; do
|
||||||
rootdir=$(mktemp --directory)
|
for dist in stable testing unstable; do
|
||||||
|
rootdir=$(mktemp --directory)
|
||||||
|
|
||||||
for p in /etc/apt/apt.conf.d /etc/apt/sources.list.d /etc/apt/preferences.d /var/cache/apt/archives /var/lib/apt/lists/partial /var/lib/dpkg; do
|
for p in /etc/apt/apt.conf.d /etc/apt/sources.list.d /etc/apt/preferences.d /var/cache/apt/archives /var/lib/apt/lists/partial /var/lib/dpkg; do
|
||||||
mkdir -p "$rootdir/$p"
|
mkdir -p "$rootdir/$p"
|
||||||
done
|
done
|
||||||
|
|
||||||
cat << END > "$rootdir/etc/apt/apt.conf"
|
cat << END > "$rootdir/etc/apt/apt.conf"
|
||||||
Apt::Architecture "$nativearch";
|
Apt::Architecture "$nativearch";
|
||||||
|
Apt::Architectures "$nativearch";
|
||||||
Dir::Etc "$rootdir/etc/apt";
|
Dir::Etc "$rootdir/etc/apt";
|
||||||
Dir::State "$rootdir/var/lib/apt";
|
Dir::State "$rootdir/var/lib/apt";
|
||||||
Dir::Cache "$rootdir/var/cache/apt";
|
Dir::Cache "$rootdir/var/cache/apt";
|
||||||
|
@ -42,102 +48,103 @@ Dir::Etc::Trusted "/etc/apt/trusted.gpg";
|
||||||
Dir::Etc::TrustedParts "/etc/apt/trusted.gpg.d";
|
Dir::Etc::TrustedParts "/etc/apt/trusted.gpg.d";
|
||||||
END
|
END
|
||||||
|
|
||||||
> "$rootdir/var/lib/dpkg/status"
|
> "$rootdir/var/lib/dpkg/status"
|
||||||
|
|
||||||
cat << END > "$rootdir/etc/apt/sources.list"
|
cat << END > "$rootdir/etc/apt/sources.list"
|
||||||
deb [arch=$nativearch] $mirror $dist $components
|
deb [arch=$nativearch] $mirror $dist $components
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
||||||
APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get update
|
APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get update
|
||||||
|
|
||||||
> "$rootdir/oldaptnames"
|
> "$rootdir/oldaptnames"
|
||||||
# before downloading packages and before replacing the old Packages
|
# before downloading packages and before replacing the old Packages
|
||||||
# file, copy all old *.deb packages from the mirror to
|
# file, copy all old *.deb packages from the mirror to
|
||||||
# /var/cache/apt/archives so that apt will not re-download *.deb
|
# /var/cache/apt/archives so that apt will not re-download *.deb
|
||||||
# packages that we already have
|
# packages that we already have
|
||||||
if [ -e "$mirrordir/dists/$dist/main/binary-$nativearch/Packages.gz" ]; then
|
if [ -e "$mirrordir/dists/$dist/main/binary-$nativearch/Packages.gz" ]; then
|
||||||
|
gzip -dc "$mirrordir/dists/$dist/main/binary-$nativearch/Packages.gz" \
|
||||||
|
| grep-dctrl --no-field-names --show-field=Package,Version,Architecture,Filename '' \
|
||||||
|
| paste -sd " \n" \
|
||||||
|
| while read name ver arch fname; do
|
||||||
|
if [ ! -e "$mirrordir/$fname" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# apt stores deb files with the colon encoded as %3a while
|
||||||
|
# mirrors do not contain the epoch at all #645895
|
||||||
|
case "$ver" in *:*) ver="${ver%%:*}%3a${ver#*:}";; esac
|
||||||
|
aptname="$rootdir/var/cache/apt/archives/${name}_${ver}_${arch}.deb"
|
||||||
|
# we have to cp and not mv because other
|
||||||
|
# distributions might still need this file
|
||||||
|
# we have to cp and not symlink because apt
|
||||||
|
# doesn't recognize symlinks
|
||||||
|
# we cannot do a hardlink because the two
|
||||||
|
# directories might be on different devices
|
||||||
|
cp -a "$mirrordir/$fname" "$aptname"
|
||||||
|
echo "$aptname" >> "$rootdir/oldaptnames"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
pkgs=$(APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get indextargets \
|
||||||
|
--format '$(FILENAME)' 'Created-By: Packages' "Architecture: $nativearch" \
|
||||||
|
| xargs --delimiter='\n' /usr/lib/apt/apt-helper cat-file \
|
||||||
|
| grep-dctrl --no-field-names --show-field=Package --exact-match \
|
||||||
|
\( --field=Essential yes --or --field=Priority required \
|
||||||
|
--or --field=Priority important --or --field=Priority standard \
|
||||||
|
--or --field=Package build-essential \) )
|
||||||
|
|
||||||
|
pkgs="$(echo $pkgs) build-essential"
|
||||||
|
|
||||||
|
APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get --yes install $pkgs
|
||||||
|
|
||||||
|
# to be able to also test gpg verification, we need to create a mirror
|
||||||
|
mkdir -p "$mirrordir/dists/$dist/" "$mirrordir/dists/$dist/main/binary-$nativearch/"
|
||||||
|
curl --location "$mirror/dists/$dist/Release" > "$mirrordir/dists/$dist/Release"
|
||||||
|
curl --location "$mirror/dists/$dist/Release.gpg" > "$mirrordir/dists/$dist/Release.gpg"
|
||||||
|
curl --location "$mirror/dists/$dist/main/binary-$nativearch/Packages.gz" > "$mirrordir/dists/$dist/main/binary-$nativearch/Packages.gz"
|
||||||
|
|
||||||
|
# the deb files downloaded by apt must be moved to their right locations in the
|
||||||
|
# pool directory
|
||||||
|
#
|
||||||
|
# Instead of parsing the Packages file, we could also attempt to move the deb
|
||||||
|
# files ourselves to the appropriate pool directories. But that approach
|
||||||
|
# requires re-creating the heuristic by which the directory is chosen, requires
|
||||||
|
# stripping the epoch from the filename and will break once mirrors change.
|
||||||
|
# This way, it doesn't matter where the mirror ends up storing the package.
|
||||||
|
> "$rootdir/newaptnames"
|
||||||
gzip -dc "$mirrordir/dists/$dist/main/binary-$nativearch/Packages.gz" \
|
gzip -dc "$mirrordir/dists/$dist/main/binary-$nativearch/Packages.gz" \
|
||||||
| grep-dctrl --no-field-names --show-field=Package,Version,Architecture,Filename '' \
|
| grep-dctrl --no-field-names --show-field=Package,Version,Architecture,Filename,MD5sum '' \
|
||||||
| paste -sd " \n" \
|
| paste -sd " \n" \
|
||||||
| while read name ver arch fname; do
|
| while read name ver arch fname md5; do
|
||||||
if [ ! -e "$mirrordir/$fname" ]; then
|
dir="${fname%/*}"
|
||||||
continue
|
|
||||||
fi
|
|
||||||
# apt stores deb files with the colon encoded as %3a while
|
# apt stores deb files with the colon encoded as %3a while
|
||||||
# mirrors do not contain the epoch at all #645895
|
# mirrors do not contain the epoch at all #645895
|
||||||
case "$ver" in *:*) ver="${ver%%:*}%3a${ver#*:}";; esac
|
case "$ver" in *:*) ver="${ver%%:*}%3a${ver#*:}";; esac
|
||||||
aptname="$rootdir/var/cache/apt/archives/${name}_${ver}_${arch}.deb"
|
aptname="$rootdir/var/cache/apt/archives/${name}_${ver}_${arch}.deb"
|
||||||
# we have to cp and not mv because other
|
if [ -e "$aptname" ]; then
|
||||||
# distributions might still need this file
|
# make sure that we found the right file by checking its hash
|
||||||
# we have to cp and not symlink because apt
|
echo "$md5 $aptname" | md5sum --check
|
||||||
# doesn't recognize symlinks
|
mkdir -p "$mirrordir/$dir"
|
||||||
# we cannot do a hardlink because the two
|
mv "$aptname" "$mirrordir/$fname"
|
||||||
# directories might be on different devices
|
echo "$aptname" >> "$rootdir/newaptnames"
|
||||||
cp -a "$mirrordir/$fname" "$aptname"
|
fi
|
||||||
echo "$aptname" >> "$rootdir/oldaptnames"
|
|
||||||
done
|
done
|
||||||
fi
|
|
||||||
|
|
||||||
pkgs=$(APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get indextargets \
|
rm "$rootdir/var/cache/apt/archives/lock"
|
||||||
--format '$(FILENAME)' 'Created-By: Packages' "Architecture: $nativearch" \
|
rmdir "$rootdir/var/cache/apt/archives/partial"
|
||||||
| xargs --delimiter='\n' /usr/lib/apt/apt-helper cat-file \
|
# remove all packages that were in the old Packages file but not in the
|
||||||
| grep-dctrl --no-field-names --show-field=Package --exact-match \
|
# new one anymore
|
||||||
\( --field=Essential yes --or --field=Priority required \
|
sort "$rootdir/oldaptnames" > "$rootdir/tmp"
|
||||||
--or --field=Priority important --or --field=Priority standard \
|
mv "$rootdir/tmp" "$rootdir/oldaptnames"
|
||||||
--or --field=Package build-essential \) )
|
sort "$rootdir/newaptnames" > "$rootdir/tmp"
|
||||||
|
mv "$rootdir/tmp" "$rootdir/newaptnames"
|
||||||
|
comm -23 "$rootdir/oldaptnames" "$rootdir/newaptnames" | xargs --delimiter="\n" --no-run-if-empty rm
|
||||||
|
# now the apt cache should be empty
|
||||||
|
if [ ! -z "$(ls -1qA "$rootdir/var/cache/apt/archives/")" ]; then
|
||||||
|
echo "/var/cache/apt/archives not empty"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
pkgs="$(echo $pkgs) build-essential"
|
rm -r "$rootdir"
|
||||||
|
done
|
||||||
APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get --yes install $pkgs
|
|
||||||
|
|
||||||
# to be able to also test gpg verification, we need to create a mirror
|
|
||||||
mkdir -p "$mirrordir/dists/$dist/" "$mirrordir/dists/$dist/main/binary-$nativearch/"
|
|
||||||
curl --location "$mirror/dists/$dist/Release" > "$mirrordir/dists/$dist/Release"
|
|
||||||
curl --location "$mirror/dists/$dist/Release.gpg" > "$mirrordir/dists/$dist/Release.gpg"
|
|
||||||
curl --location "$mirror/dists/$dist/main/binary-$nativearch/Packages.gz" > "$mirrordir/dists/$dist/main/binary-$nativearch/Packages.gz"
|
|
||||||
|
|
||||||
# the deb files downloaded by apt must be moved to their right locations in the
|
|
||||||
# pool directory
|
|
||||||
#
|
|
||||||
# Instead of parsing the Packages file, we could also attempt to move the deb
|
|
||||||
# files ourselves to the appropriate pool directories. But that approach
|
|
||||||
# requires re-creating the heuristic by which the directory is chosen, requires
|
|
||||||
# stripping the epoch from the filename and will break once mirrors change.
|
|
||||||
# This way, it doesn't matter where the mirror ends up storing the package.
|
|
||||||
> "$rootdir/newaptnames"
|
|
||||||
gzip -dc "$mirrordir/dists/$dist/main/binary-$nativearch/Packages.gz" \
|
|
||||||
| grep-dctrl --no-field-names --show-field=Package,Version,Architecture,Filename,MD5sum '' \
|
|
||||||
| paste -sd " \n" \
|
|
||||||
| while read name ver arch fname md5; do
|
|
||||||
dir="${fname%/*}"
|
|
||||||
# apt stores deb files with the colon encoded as %3a while
|
|
||||||
# mirrors do not contain the epoch at all #645895
|
|
||||||
case "$ver" in *:*) ver="${ver%%:*}%3a${ver#*:}";; esac
|
|
||||||
aptname="$rootdir/var/cache/apt/archives/${name}_${ver}_${arch}.deb"
|
|
||||||
if [ -e "$aptname" ]; then
|
|
||||||
# make sure that we found the right file by checking its hash
|
|
||||||
echo "$md5 $aptname" | md5sum --check
|
|
||||||
mkdir -p "$mirrordir/$dir"
|
|
||||||
mv "$aptname" "$mirrordir/$fname"
|
|
||||||
echo "$aptname" >> "$rootdir/newaptnames"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
rm "$rootdir/var/cache/apt/archives/lock"
|
|
||||||
rmdir "$rootdir/var/cache/apt/archives/partial"
|
|
||||||
# remove all packages that were in the old Packages file but not in the
|
|
||||||
# new one anymore
|
|
||||||
sort "$rootdir/oldaptnames" > "$rootdir/tmp"
|
|
||||||
mv "$rootdir/tmp" "$rootdir/oldaptnames"
|
|
||||||
sort "$rootdir/newaptnames" > "$rootdir/tmp"
|
|
||||||
mv "$rootdir/tmp" "$rootdir/newaptnames"
|
|
||||||
comm -23 "$rootdir/oldaptnames" "$rootdir/newaptnames" | xargs --delimiter="\n" --no-run-if-empty rm
|
|
||||||
# now the apt cache should be empty
|
|
||||||
if [ ! -z "$(ls -1qA "$rootdir/var/cache/apt/archives/")" ]; then
|
|
||||||
echo "/var/cache/apt/archives not empty"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -r "$rootdir"
|
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in a new issue