#!/bin/sh # 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 42 ;; esac shift done packages_to_stabilize=${@} for package in ${packages_to_stabilize}; do # some sanity checks if [ ! -f "${work_dir}/package-states/${package}.testing" ]; then >&2 echo "Package '${package}' is not in testing!" exit 2 fi done updated_package_database=false # 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 tmp_dir="$(mktemp -d)" clean_up_lock_file() { rm -f "${package_database_lock_file}" "${build_list_lock_file}" rm -rf --one-file-system "${tmp_dir}" } trap clean_up_lock_file EXIT # 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 can't be un-staged because they're still dependencies # of any job on the build-list 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 > \ "${tmp_dir}/keep_packages" # packages which are done ls "${work_dir}/package-states" | \ grep '\.done$' | \ sed 's|^\(.*\)\(\(\.[^.]\+\)\{3\}\)\.done$|\1 \1\2|' | \ sort > \ "${tmp_dir}/done_packages" # remove packages not yet done from keep-packages list keep_packages="$( join -1 1 -2 1 -o 2.2 \ "${tmp_dir}/keep_packages" \ "${tmp_dir}/done_packages" )" printf '%s\n' "${keep_packages}" | \ grep -vxF '' || true > \ "${tmp_dir}/keep_packages" # find all dependencies of the unstageable packages mv \ "${tmp_dir}/keep_packages" \ "${tmp_dir}/new_keep_packages" keep_packages='' while [ -s "${tmp_dir}/new_keep_packages" ]; do while read -r package; do generate_package_metadata "${package}" done < "${tmp_dir}/new_keep_packages" keep_packages="$( ( printf '%s\n' "${keep_packages}" cat "${tmp_dir}/new_keep_packages" ) | \ sort -u )" new_keep_packages="$( while read -r package; do cat "${work_dir}/package-infos/${package%.*}.depends" done < \ "${tmp_dir}/new_keep_packages" | \ sort -u )" printf '%s\n' "${new_keep_packages}" > \ "${tmp_dir}/new_keep_packages" new_keep_packages="$( join -1 1 -2 1 -o 2.2 \ "${tmp_dir}/new_keep_packages" \ "${tmp_dir}/done_packages" )" # "new" is only what has not been there before printf '%s\n' "${keep_packages}" "${keep_packages}" "${new_keep_packages}" | \ sort | \ uniq -u > \ "${tmp_dir}/new_keep_packages" done done_packages="$(cat "${tmp_dir}/done_packages")" # if build list is empty, remember all entries of 'deletion-list' if [ -s "${work_dir}/build-list" ]; then delete_packages='' else delete_packages="$( cat "${work_dir}/deletion-list" )" fi if [ -z "${delete_packages}" ]; then # unlock build list rm -f "${build_list_lock_file}" flock -u 9 rm -rf --one-file-system "${tmp_dir}" clean_up_lock_file() { rm -f "${package_database_lock_file}" } else rm -rf --one-file-system "${tmp_dir}" clean_up_lock_file() { rm -f "${package_database_lock_file}" "${build_list_lock_file}" } fi # 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 if [ -z "${package}" ]; then continue fi parts=$(cat "${work_dir}/package-states/${package}.done") parts_names=$( printf '%s\n' ${parts} | \ sed 's|\(-[^-]\+\)\{3\}\.pkg\.tar\.xz$||' ) is_community="$(official_or_community "${package}")" cd "${master_mirror_directory}/i686/${is_community}staging" mkdir -p "../${is_community}testing" repo-remove "${is_community}staging.db.tar.gz" ${parts_names} for part in ${parts}; do mv "${part}" "${part}.sig" "../${is_community}testing/" updated_package_database=true done cd "${master_mirror_directory}/i686/${is_community}testing" repo-add "${is_community}testing.db.tar.gz" ${parts} for part in ${parts}; do remove_old_package_versions "${part}" done mv \ "${work_dir}/package-states/${package}.done" \ "${work_dir}/package-states/${package}.testing" done # move packages in packages_to_stabilize from *testing/ to the stable repos for package in ${packages_to_stabilize}; do parts=$(cat "${work_dir}/package-states/${package}.testing") parts_names=$( printf '%s\n' ${parts} | \ sed 's|\(-[^-]\+\)\{3\}\.pkg\.tar\.xz$||' ) source="$(official_or_community ${package})testing" destination="${package##*.}" cd "${master_mirror_directory}/i686/${source}" repo-remove "${source}.db.tar.gz" ${parts_names} for part in ${parts}; do mv "${part}" "${part}.sig" "../${destination}/" updated_package_database=true done cd "${master_mirror_directory}/i686/${destination}" repo-add "${destination}.db.tar.gz" ${parts} for part in ${parts}; do remove_old_package_versions "${part}" done rm "${work_dir}/package-states/${package}.testing" done if [ -n "${delete_packages}" ]; then echo "there is something to delete:" echo "${delete_packages}" fi if ${updated_package_database}; then date '+%s' > \ "${master_mirror_directory}/lastupdate" fi