Skip to content

Instantly share code, notes, and snippets.

@xenogenesi
Created July 7, 2017 07:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xenogenesi/a5dc5df3c8a52a5f24d4996866b17384 to your computer and use it in GitHub Desktop.
Save xenogenesi/a5dc5df3c8a52a5f24d4996866b17384 to your computer and use it in GitHub Desktop.
shell script to mirror locally a subset of packages from an external repository
#!/bin/sh -e
# - create a root directory (into /var/local or similar, eg: apt-repos/)
# - create a somerepo.conf file (will be sourced by this script)
#
# # _URL+_DIR is the path to download the source Packages.gz
# # "Filename:" in Packages is relative to _URL (eg: _URL/pool/...)
# SRC_REPO_URL="http://some-url"
# SRC_REPO_DIR="dists/sid/main/binary-amd64"
#
# # names of the packages to watch/mirror separated by space
# PACKAGES="package1 package2"
#
# # a label to be used as output directory/namespace
# OUT_REPO_DIR="somerepo-sid-amd64"
# - run the script like "script /var/local/my-repos/ /var/local/my-repos/somerepo.conf"
# ├── somerepo-sid-amd64
# │   ├── Packages
# │   ├── pool
# │   │   └── main
# │   │   └── p
# │   │   └── package1
# │   │   └── package1_bla_amd64.deb
# │   │   └── package2
# │   │   └── package2_bla_amd64.deb
# │   └── Release
# ├── somerepo.conf
# └── src
# └── somerepo-sid-amd64
# └── Packages.gz
# - add "deb [trust=yes] file:/var/local/somerepo-sid-amd64/ ./" to sources.list
# # careful with [trust]
# - (optional) add and edit /etc/apt/apt.conf.d/99-apt-watch
# APT::Update::Pre-Invoke { "/var/local/apt-repos/apt-local-mirror.sh /var/local/apt-repos /var/local/apt-repos/somerepo.conf" };
# - apt-get update
# to force an update just remove the generated Release
dl_src_repo_Packages() {
wget -q -P "$ROOT/$1" -N "$SRC_REPO_URL/$SRC_REPO_DIR/Packages.gz"
}
pkg_to_file() {
# TODO better way to escape special chars for awk's matches?
F="$(echo "$1" | sed 's/\+/\\+/g')"
zcat "$ROOT/$2/Packages.gz" | \
awk 'BEGIN{}/^Package: '"$F"'$/,/Filename:/{FILE=$2;next}END{print FILE}'
}
dl_package() {
wget -q -P "$(dirname "$1")" -N "$SRC_REPO_URL/$1"
}
main() {
if [ ! -e "$2" ]; then
echo "conf '$2' doesn't exist" >&2
exit 1
fi
. "$2"
SRC_REPO_NS="src/$OUT_REPO_DIR"
ROOT="$(realpath -e "$1")"
cd "$ROOT"
dl_src_repo_Packages "$SRC_REPO_NS"
[ -d "$OUT_REPO_DIR" ] || mkdir -p "$OUT_REPO_DIR"
cd "$OUT_REPO_DIR"
if [ ! -e ./Release ] \
|| [ "$ROOT/$SRC_REPO_NS/Packages.gz" -nt ./Release ] ;
then
for P in $PACKAGES; do
PKG="$(pkg_to_file "$P" "$SRC_REPO_NS")"
# if the file doesn't exists then is the first time or a new version
if [ ! -e "$PKG" ]; then
dl_package "$PKG"
fi
done
apt-ftparchive packages . > Packages
apt-ftparchive release . > Release
#gpg --clearsign --output InRelease Release
#echo "deb [trusted=yes] file:$PWD/ ./"
fi
}
usage() {
echo "command [root] [conf]" >&2
exit 1
}
if [ $# -lt 2 ] ; then
usage
fi
echo "apt-local-mirror: updating $2..." >&2
main "$1" "$2"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment