#!/bin/sh # report back on a build assignment # either on success via: # "$0 $package $revision $mod_revision $repository" and tar'ed packages (= a tar of # package(s) and signature(s)) on stdin # or on failure via: # "$0 $package $revision $mod_revision $repository ERROR" # exit codes: # 0: ok # 1: another instance was already running # 2: outdated package # 3: signature error # 4: package error (e.g. wrong packages sent) # TODO: # fix signing of database # shellcheck source=conf/default.conf . "${0%/*}/../conf/default.conf" if [ -s "${work_dir}/build-master-sanity" ]; then >&2 echo 'Build master is not sane.' exit 1 fi # Create a lock file and a trap. exec 9> "${build_list_lock_file}" if ! flock -n 9; then >&2 echo 'come back (shortly) later - I cannot lock build list.' exit 1 fi clean_up_lock_file() { rm -f "${build_list_lock_file}" } trap clean_up_lock_file EXIT if [ "$5" = 'ERROR' ]; then # the build failed on the build slave if [ ! -f "${work_dir}/package-states/$1.$2.$3.$4.locked" ]; then # too late, package already outdated -> ignore error report exit 0 fi # save sent build logs tar -x \ -C "${build_log_directory}" \ --wildcards \ --no-wildcards-match-slash \ --transform="s|^|$1.$2.$3.$4.|" \ '*.build-log.gz' head -n1 \ "${work_dir}/package-states/$1.$2.$3.$4.locked" >> \ "${work_dir}/package-states/$1.$2.$3.$4.broken" rm "${work_dir}/package-states/$1.$2.$3.$4.locked" # unlock every loop this package would have broken and which is not # broken by another locked package locked_packages=$( find "${work_dir}/package-states/" -maxdepth 1 -name '*.locked' -printf '%f\n' | \ sed 's@^\(.\+\)\.\([0-9a-f]\{40\}\.\)\{2\}[^.]\+\.locked$@\1@' ) grep -lxF "${1}" "${work_dir}/build-list.loops/loop_"* 2> /dev/null | \ while read -r loop; do if [ -z "$( ( echo "${locked_packages}" cat "${loop}" ) | \ sort | \ uniq -d )" ]; then rm -f "${loop}.locked" fi done # move build order to end of build list sed -i \ "/^$(str_to_regex "$1 $2 $3 $4")\$/d" \ "${work_dir}/build-list" echo "$1 $2 $3 $4" >> \ "${work_dir}/build-list" exit 0 fi # the build was successful on the build slave # so we also need a lock on the package database exec 8> "${package_database_lock_file}" if ! flock -n 8; then >&2 echo 'come back (shortly) later - I cannot lock package database.' exit 1 fi clean_up_lock_file() { rm -f "${build_list_lock_file}" rm -f "${package_database_lock_file}" } if ! grep -qxF "$1 $2 $3 $4" "${work_dir}/build-list" || ! [ -f "${work_dir}/package-states/$1.$2.$3.$4.locked" ]; then >&2 echo 'Sorry, the sent package is outdated.' exit 2 fi clean_up_tmp_dir() { cd "${base_dir}" rm -rf --one-file-system "${tmp_dir}" clean_up_lock_file } tmp_dir=$(mktemp -d "${work_dir}/tmp.XXXXXX") cd "${tmp_dir}" trap clean_up_tmp_dir EXIT # extract package(s) tar -x \ --wildcards \ --no-wildcards-match-slash \ '*.pkg.tar.xz' \ '*.pkg.tar.xz.sig' # check if all packages are signed and all signatures belong to a package signature_errors=$( find . -maxdepth 1 -name '*.pkg.tar.xz' -o -name '*.pkg.tar.xz.sig' | \ sed 's|\.sig$||' | \ sort | \ uniq -c | \ grep -v '^\s*2\s' | \ awk '{print $2}' ) if [ -n "${signature_errors}" ]; then >&2 echo 'The following packages lack a signature or vice versa:' >&2 echo "${signature_errors}" exit 3 fi # check if the sent packages are the expected ones packages=$( find . -maxdepth 1 -name '*.pkg.tar.xz' -printf '%f\n' ) package_errors=$( ( # shellcheck disable=SC2086 printf '%s\n' ${packages} | \ sed ' s@\(-[^-]\+\)\{2\}-\([^-]\+\)\.pkg\.tar\.xz$@ \2@ / any$/{ s|any$|i686| } s|^|was_built: | ' sed ' s|$| i686| s|^|expected: | ' "${work_dir}/package-infos/$1.$2.$3.$4.packages" ) | \ sort -k2 | \ uniq -u -f1 ) if [ -n "${package_errors}" ]; then >&2 echo 'The following packages should have been built but are missing or vice versa:' >&2 echo "${package_errors}" exit 4 fi # move packages destination=$(official_or_community "$1.$2.$3.$4" 'staging') ${master_mirror_rsync_command} \ "${master_mirror_rsync_directory}/i686/${destination}/${destination}.db."* \ "${master_mirror_rsync_directory}/i686/${destination}/${destination}.files."* \ . # shellcheck disable=SC2086 repo-add "${destination}.db.tar.gz" ${packages} # repo-add -v -s -k "${repo_key}" "${destination}.db.tar.gz" ${packages} ${master_mirror_rsync_command} \ "${destination}.db."* \ "${destination}.files."* \ ./*".pkg.tar.xz" \ ./*".pkg.tar.xz.sig" \ "${master_mirror_rsync_directory}/i686/${destination}/" for package in ${packages}; do remove_old_package_versions "i686/${destination}" "${package}" done # remove old state files (these should be only "done" markers, but # actually we don't care what it is) - as long as it's not "testing" find "${work_dir}/package-states" -maxdepth 1 | \ grep "/$(str_to_regex "$1")\(\.[^.]\+\)\{4\}\$" | \ grep -v "/$(str_to_regex "$1.$2.$3.$4")\.[^.]\+\$" | \ grep -v '\.testing$' | \ xargs -rn1 rm -f # remove all loops which are broken by this package grep -lxF "$1" "${work_dir}/build-list.loops/loop_"* 2> /dev/null | \ sed 'p;s|$|.locked|' | \ xargs -rn1 rm -f if ! find "${work_dir}/build-list.loops" -maxdepth 1 -printf '%f\n' | \ grep -q '^loop_[0-9]\+$'; then # no loops left sed -i '/^break_loops$/d' "${work_dir}/build-list" fi # remove package from build list sed -i "/^$(str_to_regex "$1 $2 $3 $4")\$/d" "${work_dir}/build-list" # remove package lock file if ! [ "${destination}" = 'build-support' ]; then # shellcheck disable=SC2086 printf '%s\n' ${packages} > \ "${work_dir}/package-states/$1.$2.$3.$4.done" fi rm -f \ "${work_dir}/package-states/$1.$2.$3.$4.locked" \ "${work_dir}/package-states/$1.$2.$3.$4.broken"