summaryrefslogtreecommitdiff
path: root/bin/db-update
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2017-06-10 15:39:41 +0200
committerErich Eckner <git@eckner.net>2017-06-10 15:39:41 +0200
commite4dad09e58f34a7fba6a6adf27370c37dc4dd448 (patch)
tree81e4ce2307db1981696396b7c78a22178151738f /bin/db-update
parentc9897d84bff4d2f484090661888f31c938be4947 (diff)
downloadbuilder-e4dad09e58f34a7fba6a6adf27370c37dc4dd448.tar.xz
bin/db-update: can move packages from staging to testing
Diffstat (limited to 'bin/db-update')
-rwxr-xr-xbin/db-update244
1 files changed, 244 insertions, 0 deletions
diff --git a/bin/db-update b/bin/db-update
new file mode 100755
index 0000000..630d99c
--- /dev/null
+++ b/bin/db-update
@@ -0,0 +1,244 @@
+#!/bin/bash
+
+# move binary packages from staging to testing (if possible [1]) and
+# additionally all packages specified on the command line from testing
+# to the respective stable repository
+
+# 1] Condition for moving a package A from staging to testing is that:
+# a) nothing on the build-list depends on A and
+# b) no done package B which is not being moved depends on A
+
+# TODO:
+# the meta data used to evaluate condition "b" might be for a different
+# version
+# correctly handle if multiple versions of a single package are marked
+# as "done"
+
+. "${0%/*}/../conf/default.conf"
+
+usage() {
+ >&2 echo ''
+ >&2 echo 'db-update [options] [packages]:'
+ >&2 echo ' move possible packages from staging to testing.'
+ >&2 echo ' move packages on the command line from testing to stable.'
+ >&2 echo ''
+ >&2 echo 'possible options:'
+ >&2 echo ' -b|--block: If necessary, wait for lock blocking.'
+ >&2 echo ' -h|--help: Show this help and exit.'
+ [ -z "$1" ] && exit 1 || exit $1
+}
+
+eval set -- "$(
+ getopt -o bh \
+ --long block \
+ --long help \
+ -n "$(basename "$0")" -- "$@" || \
+ echo usage
+)"
+
+block_flag='-n'
+
+while true
+do
+ case "$1" in
+ -b|--block)
+ block_flag=''
+ ;;
+ -h|--help)
+ usage 0
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ >&2 echo 'Whoops, forgot to implement option "'"$1"'" internally.'
+ exit -1
+ ;;
+ esac
+ shift
+done
+
+packages_to_stabilize=("${@}")
+
+# Create a lock file and a trap.
+
+exec 9> "${build_list_lock_file}"
+if ! flock ${block_flag} 9; then
+ >&2 echo 'come back (shortly) later - I cannot lock build list.'
+ exit 1
+fi
+
+exec 8> "${package_database_lock_file}"
+if ! flock ${block_flag} 8; then
+ >&2 echo 'come back (shortly) later - I cannot lock package database.'
+ exit 1
+fi
+
+function clean_up_lock_file {
+ rm -f "${package_database_lock_file}" "${build_list_lock_file}"
+}
+
+trap clean_up_lock_file EXIT
+
+# packages which can't be un-staged because they're still dependencies
+# of any job on the build-list
+
+keep_packages="$(
+ while read -r pkg pkg_rev mod_rev repo; do
+ cat "${work_dir}/package-infos/${pkg}.${pkg_rev}.${mod_rev}.depends"
+ done < \
+ "${work_dir}/build-list" | \
+ sort -u
+)"
+
+# sanity check
+
+if [ -n "$(
+ ls "${work_dir}/package-states" | \
+ grep '\.done$' | \
+ sed 's|\(\.[^.]\+\)\{4\}$||' | \
+ sort | \
+ uniq -d)" ]; then
+ >&2 echo 'Removing duplicates not yet implemented!'
+ exit 42
+fi
+
+# packages which are done
+
+done_packages="$(
+ ls "${work_dir}/package-states" | \
+ grep '\.done$' | \
+ sed 's|^\(.*\)\(\(\.[^.]\+\)\{3\}\)\.done$|\1 \1\2|' | \
+ sort
+)"
+
+# remove packages not yet done from keep-packages list
+
+keep_packages="$(
+ join -1 1 -2 1 -o 2.2 \
+ <(
+ echo "${keep_packages}"
+ ) \
+ <(
+ echo "${done_packages}"
+ )
+)"
+
+# packages which can't be unstaged
+
+new_keep_packages="${keep_packages}"
+keep_packages=''
+
+while [ -n "${new_keep_packages}" ]; do
+
+ for package in ${new_keep_packages}; do
+ if [ ! -f "${work_dir}/package-infos/${package%.*}.depends" ]; then
+ echo "missing meta data for an not unstageable package ('${package}') - abort unstaging!"
+ keep_packages=''
+ done_packages=''
+ break
+ fi
+ done
+ if [ -z "${done_packages}" ]; then
+ break
+ fi
+
+ keep_packages="$(
+ printf '%s\n' "${keep_packages}" "${new_keep_packages}" | \
+ sort -u | \
+ grep -v '^$'
+ )"
+
+ new_keep_packages="$(
+ join -1 1 -2 1 -o 2.2 \
+ <(
+ echo "${new_keep_packages}" | \
+ while read -r package; do
+ cat "${work_dir}/package-infos/${package%.*}.depends"
+ done | \
+ sort -u
+ ) \
+ <(
+ echo "${done_packages}"
+ )
+ )"
+
+ # "new" is only what has not been there before
+ new_keep_packages="$(
+ printf '%s\n' "${keep_packages}" "${keep_packages}" "${new_keep_packages}" | \
+ sort | \
+ uniq -u
+ )"
+
+done
+
+# unlock build list
+
+rm -f "${build_list_lock_file}"
+flock -u 9
+
+function clean_up_lock_file {
+ rm -f "${package_database_lock_file}"
+}
+
+# calculate unstageable packages from keep_packages and done_packages
+
+done_packages="$(
+ echo "${done_packages}" | \
+ cut -d' ' -f2
+)"
+
+done_packages="$(
+ (
+ printf '%s\n' "${done_packages}" "${keep_packages}"
+ ) | \
+ sort | \
+ uniq -u
+)"
+
+unset keep_packages
+
+for package in ${done_packages}; do
+ parts=($(cat "${work_dir}/package-states/${package}.done"))
+ parts_names=(
+ $(
+ printf '%s\n' "${parts[@]}" | \
+ sed 's|\(-[^-]\+\)\{3\}\.pkg\.tar\.xz$||'
+ )
+ )
+ case "${package##*.}" in
+ 'community')
+ destination='community-testing'
+ ;;
+ 'multilib')
+ a32_rev="${package%.*}"
+ a32_rev="${a32_rev##*.}"
+ if git -C "${repo_paths['archlinux32']}" archive --format=tar "${a32_rev}" | \
+ tar -Ox 'extra-from-multilib' | \
+ grep -q "^${package%.*.*.*}\$"; then
+ destination='testing'
+ else
+ destination='community-testing'
+ fi
+ ;;
+ *)
+ destination='testing'
+ esac
+
+ pushd "${master_mirror_directory}/i686/staging" > /dev/null
+ mkdir -p "../${destination}"
+ repo-remove 'staging.db.tar.gz' "${parts_names[@]}"
+ for part in "${parts[@]}"; do
+ mv "${part}"{,.sig} "../${destination}/"
+ done
+ popd > /dev/null
+ pushd "${master_mirror_directory}/i686/${destination}" > /dev/null
+ repo-add "${destination}.db.tar.gz" "${parts[@]}"
+ popd > /dev/null
+
+ mv "${work_dir}/package-states/${package}."{done,testing}
+done
+
+# TODO:
+# move packages from packages_to_stabilize from *testing/ to the stable repos