Build image based on defined repo snapshot date

The repo snapshot date is determined automatically by a query to the archive mirror.
You can also set a different snapshot date with the -s option.

Before always the current packages were used. Use defined snapshots instead,
because a future commit will switch pacman within the image to use the snapshot too.
This commit is contained in:
Gerd v. Egidy 2021-12-05 00:10:40 +01:00
parent dc24c20e92
commit 1b1e63c883
3 changed files with 72 additions and 3 deletions

View file

@ -18,6 +18,7 @@ gpg_key=
arch="$(uname -m)" arch="$(uname -m)"
sfs_comp="xz" sfs_comp="xz"
sfs_opts="-Xbcj x86 -b 512k -Xdict-size 512k" sfs_opts="-Xbcj x86 -b 512k -Xdict-size 512k"
snapshot_date=""
verbose="" verbose=""
@ -29,12 +30,16 @@ case ${arch} in
efiboot="bootx64.efi" efiboot="bootx64.efi"
edk2arch="x64" edk2arch="x64"
mirrorlist_url='https://archlinux.org/mirrorlist/?country=all&protocol=http&use_mirror_status=on' mirrorlist_url='https://archlinux.org/mirrorlist/?country=all&protocol=http&use_mirror_status=on'
archive_prefix='https://archive.archlinux.org/repos/'
archive_mirrorlist_file='mirrorlist-snapshot-x86_64'
;; ;;
i686) i686)
efiarch="i386-efi" efiarch="i386-efi"
efiboot="bootia32.efi" efiboot="bootia32.efi"
edk2arch="ia32" edk2arch="ia32"
mirrorlist_url='https://archlinux32.org/mirrorlist/?country=all&protocol=http&use_mirror_status=on' mirrorlist_url='https://archlinux32.org/mirrorlist/?country=all&protocol=http&use_mirror_status=on'
archive_prefix='https://archive.archlinux32.org/repos/'
archive_mirrorlist_file='mirrorlist-snapshot-i686'
;; ;;
*) *)
echo "ERROR: Unsupported architecture: '${arch}'" echo "ERROR: Unsupported architecture: '${arch}'"
@ -63,11 +68,52 @@ _usage ()
echo " Default: ${work_dir}" echo " Default: ${work_dir}"
echo " -o <out_dir> Set the output directory" echo " -o <out_dir> Set the output directory"
echo " Default: ${out_dir}" echo " Default: ${out_dir}"
echo " -s <YYYY/MM/DD> Set the snapshot date to use the repository from"
echo " -v Enable verbose output" echo " -v Enable verbose output"
echo " -h This help message" echo " -h This help message"
exit ${1} exit ${1}
} }
# Determine the latest repository snapshot available at the Arch Linux Archive
determine_snapshot_date() {
# store the snapshot date in build.snapshot_date and read it out on later runs
# so don't run this function with run_once
if [[ -e ${work_dir}/build.snapshot_date ]]; then
snapshot_date=`cat ${work_dir}/build.snapshot_date`
return
fi
if [[ -z "$snapshot_date" ]]; then
# while archive.archlinux.org offers lastsync files we could read out, archive.archlinux32.org doesn't
# so use the current date (UTC), check if it's dir exists on the mirror, use the day before if not
local now=`date +%s`
local yesterday=$[$[now]-86400]
local today_ymd=`date --utc "+%Y/%m/%d" --date="@${now}"`
local yesterday_ymd=`date --utc "+%Y/%m/%d" --date="@${yesterday}"`
if curl --silent --show-error --fail --max-time 15 -o /dev/null "${archive_prefix}${today_ymd}/"; then
snapshot_date="${today_ymd}"
else
if curl --silent --show-error --fail --max-time 15 -o /dev/null "${archive_prefix}${yesterday_ymd}/"; then
snapshot_date="${yesterday_ymd}"
else
echo "can't determine latest snapshot date available at the archive, specify one with -s"
exit 1
fi
fi
else
# -s commandline option given
if [[ ! "$snapshot_date" =~ ^[0-9]{4}/(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1])$ ]]; then
echo "illegal snapshot date, format must be YYYY/MM/DD"
exit 1
fi
# we got a snapshot date that looks valid, use it without further network tests
fi
echo "$snapshot_date" >${work_dir}/build.snapshot_date
}
# Helper function to run make_*() only one time per architecture. # Helper function to run make_*() only one time per architecture.
run_once() { run_once() {
if [[ ! -e ${work_dir}/build.${1} ]]; then if [[ ! -e ${work_dir}/build.${1} ]]; then
@ -76,11 +122,17 @@ run_once() {
fi fi
} }
# Setup custom pacman.conf with current cache directories. # Setup custom pacman.conf with current cache directories, insert the snapshot date into the URLs
make_pacman_conf() { make_pacman_conf() {
local _cache_dirs local _cache_dirs
_cache_dirs=($(pacman -v 2>&1 | grep '^Cache Dirs:' | sed 's/Cache Dirs:\s*//g')) _cache_dirs=($(pacman -v 2>&1 | grep '^Cache Dirs:' | sed 's/Cache Dirs:\s*//g'))
sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${_cache_dirs[@]})|g; s|^Architecture\s*=.*$|Architecture = ${arch}|" ${script_path}/pacman.conf > ${work_dir}/pacman.conf sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${_cache_dirs[@]})|g;
s|^Architecture\s*=.*$|Architecture = ${arch}|;
s|^Include =.*$|Include = ${work_dir}/mirrorlist|g" \
${script_path}/pacman.conf > ${work_dir}/pacman.conf
sed "s|%SNAPSHOT_DATE%|${snapshot_date}|g;" \
${script_path}/${archive_mirrorlist_file} > ${work_dir}/mirrorlist
} }
# Base installation: base metapackage + syslinux (airootfs) # Base installation: base metapackage + syslinux (airootfs)
@ -262,7 +314,7 @@ if [[ ${EUID} -ne 0 ]]; then
_usage 1 _usage 1
fi fi
while getopts 'N:V:L:P:A:D:w:o:g:vh' arg; do while getopts 'N:V:L:P:A:D:w:o:g:s:vh' arg; do
case "${arg}" in case "${arg}" in
N) iso_name="${OPTARG}" ;; N) iso_name="${OPTARG}" ;;
V) iso_version="${OPTARG}" ;; V) iso_version="${OPTARG}" ;;
@ -273,6 +325,7 @@ while getopts 'N:V:L:P:A:D:w:o:g:vh' arg; do
w) work_dir="${OPTARG}" ;; w) work_dir="${OPTARG}" ;;
o) out_dir="${OPTARG}" ;; o) out_dir="${OPTARG}" ;;
g) gpg_key="${OPTARG}" ;; g) gpg_key="${OPTARG}" ;;
s) snapshot_date="${OPTARG}" ;;
v) verbose="-v" ;; v) verbose="-v" ;;
h) _usage 0 ;; h) _usage 0 ;;
*) *)
@ -284,6 +337,7 @@ done
mkdir -p ${work_dir} mkdir -p ${work_dir}
determine_snapshot_date
run_once make_pacman_conf run_once make_pacman_conf
run_once make_basefs run_once make_basefs
run_once make_packages run_once make_packages

6
mirrorlist-snapshot-i686 Normal file
View file

@ -0,0 +1,6 @@
#
# Mirrors for archive.archlinux32.org
# Currently just one stable mirror known, see https://bbs.archlinux32.org/viewforum.php?id=10
#
Server = https://archive.archlinux32.org/repos/%SNAPSHOT_DATE%/$repo/os/$arch

View file

@ -0,0 +1,9 @@
#
# Mirrors for archive.archlinux.org
# list taken from https://gitlab.archlinux.org/archlinux/infrastructure/-/blob/master/docs/servers.md#archive-mirrors
#
Server = https://archive.archlinux.org/repos/%SNAPSHOT_DATE%/$repo/os/$arch
Server = https://europe.archive.pkgbuild.com/repos/%SNAPSHOT_DATE%/$repo/os/$arch
Server = https://america.archive.pkgbuild.com/repos/%SNAPSHOT_DATE%/$repo/os/$arch
Server = https://asia.archive.pkgbuild.com/repos/%SNAPSHOT_DATE%/$repo/os/$arch