Skip to content

Instantly share code, notes, and snippets.

@olafdietsche
Created December 10, 2025 17:56
Show Gist options
  • Select an option

  • Save olafdietsche/a3e3ab4b4083ace315a71564f328b61e to your computer and use it in GitHub Desktop.

Select an option

Save olafdietsche/a3e3ab4b4083ace315a71564f328b61e to your computer and use it in GitHub Desktop.
Create a Debian mirror from /var/cache/apt, /var/lib/apt and /var/lib/dpkg. Mirror directory can then be used as "file:///path/to/mirror"
#! /bin/bash
if test $# -ne 2; then
echo "usage: $0 <chroot-dir> <mirror-dir>" >&2
exit 2
fi
chroot_dir="$1"
mirror_dir="$2"
# collect path information
dpkg_dir="/var/lib/dpkg"
dpkg_available="${chroot_dir}/${dpkg_dir}/available"
declare -A dpkg_filenames
# pipeline doesn't work here, because of while subprocess
# awk '$1 == "Filename:" {print $2;}' "${dpkg_available}" | while read f; do
while read f; do
base="${f##*/}"
path="${f%/*}"
dpkg_filenames["${base}"]="${path}"
done < <(awk '$1 == "Filename:" {print $2;}' "${dpkg_available}")
# create pool directories
apt_cache_dir="/var/cache/apt"
apt_archives="${apt_cache_dir}/archives"
cd "${chroot_dir}/${apt_archives}"
for f in *.deb; do
# drop epoch prefix
pkg="${f/?%3a}"
path="${dpkg_filenames[${pkg}]}"
mkdir -p "${mirror_dir}/${path}"
cp "$f" "${mirror_dir}/${path}/${pkg}"
done
# create dists directories
apt_lib_dir="/var/lib/apt"
apt_lists_dir="${apt_lib_dir}/lists"
cd "${chroot_dir}/${apt_lists_dir}"
for f in *_dists_*; do
# replace underscores with slashes
: "${f//_/\/}"
filename="${_##*/dists/}"
base="${filename##*/}"
path="${filename%/*}"
mkdir -p "${mirror_dir}/dists/${path}"
cp "$f" "${mirror_dir}/dists/${filename}"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment