From 1b1e63c8835b09ea4230514b24400d658374105c Mon Sep 17 00:00:00 2001 From: "Gerd v. Egidy" Date: Sun, 5 Dec 2021 00:10:40 +0100 Subject: [PATCH] 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. --- build.sh | 60 ++++++++++++++++++++++++++++++++++++-- mirrorlist-snapshot-i686 | 6 ++++ mirrorlist-snapshot-x86_64 | 9 ++++++ 3 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 mirrorlist-snapshot-i686 create mode 100644 mirrorlist-snapshot-x86_64 diff --git a/build.sh b/build.sh index 70a0652..5ea0d2c 100755 --- a/build.sh +++ b/build.sh @@ -18,6 +18,7 @@ gpg_key= arch="$(uname -m)" sfs_comp="xz" sfs_opts="-Xbcj x86 -b 512k -Xdict-size 512k" +snapshot_date="" verbose="" @@ -29,12 +30,16 @@ case ${arch} in efiboot="bootx64.efi" edk2arch="x64" 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) efiarch="i386-efi" efiboot="bootia32.efi" edk2arch="ia32" 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}'" @@ -63,11 +68,52 @@ _usage () echo " Default: ${work_dir}" echo " -o Set the output directory" echo " Default: ${out_dir}" + echo " -s Set the snapshot date to use the repository from" echo " -v Enable verbose output" echo " -h This help message" 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. run_once() { if [[ ! -e ${work_dir}/build.${1} ]]; then @@ -76,11 +122,17 @@ run_once() { 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() { local _cache_dirs _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) @@ -262,7 +314,7 @@ if [[ ${EUID} -ne 0 ]]; then _usage 1 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 N) iso_name="${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}" ;; o) out_dir="${OPTARG}" ;; g) gpg_key="${OPTARG}" ;; + s) snapshot_date="${OPTARG}" ;; v) verbose="-v" ;; h) _usage 0 ;; *) @@ -284,6 +337,7 @@ done mkdir -p ${work_dir} +determine_snapshot_date run_once make_pacman_conf run_once make_basefs run_once make_packages diff --git a/mirrorlist-snapshot-i686 b/mirrorlist-snapshot-i686 new file mode 100644 index 0000000..2d4818e --- /dev/null +++ b/mirrorlist-snapshot-i686 @@ -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 + diff --git a/mirrorlist-snapshot-x86_64 b/mirrorlist-snapshot-x86_64 new file mode 100644 index 0000000..f1abdbb --- /dev/null +++ b/mirrorlist-snapshot-x86_64 @@ -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 +