#!/bin/sh # report back on a build assignment # either on success via: # "$0 $package $revision $mod_revision $repository" and tar'ed packages and logs # (= a tar of package(s), signature(s) and log(s)) on stdin # or on failure via: # "$0 $package $revision $mod_revision $repository ERROR" and tar'ed logs # 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: sign 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 exec 8> "${sanity_check_lock_file}" if ! flock -s -n 8; then >&2 echo 'come back (shortly) later - sanity-check running.' 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 ! grep -qxF "$1 $2 $3 $4" "${work_dir}/build-list" || ! [ -f "${work_dir}/package-states/$1.$2.$3.$4.locked" ]; then # too late, package already outdated -> ignore error report exit 0 fi # shellcheck disable=SC2154 if [ "${slave}" != "$(head -n1 "${work_dir}/package-states/$1.$2.$3.$4.locked")" ]; then # whoops, this package is built by someone else exit 0 fi # save sent build logs tar -x \ -C "${build_log_directory}/error" \ --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@' ) find "${work_dir}/build-list.loops" -maxdepth 1 -regextype grep \ -regex '.*/loop_[0-9]\+' \ -exec grep -qxF "$1" '{}' \; \ -not -exec grep -qxF "${locked_packages}" '{}' \; \ -exec rm '{}.locked' \; # 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 7> "${package_database_lock_file}" if ! flock -n 7; 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' \ '*.pkg.tar.xz-namcap.log.gz' # check if all packages are signed and all signatures belong to a package missing_files=$( find . -maxdepth 1 -name '*.pkg.tar.xz' -o -name '*.pkg.tar.xz.sig' -o -name '*.pkg.tar.xz-namcap.log.gz' | \ sed ' s@\.sig$@ signature@ t s@-namcap\.log\.gz$@ namcap@ t s@$@ package@ ' | \ sort -k1,1 -k2,2 | \ sed ' :a $!N s/^\(\(\S\+\) [^\n]\+\)\n\2 /\1 / ta P D ' | \ sed -n ' s/$/ / / package /!{ h s/^\(\S\+\) .*$/Package "\1" is missing./ p g } / signature /!{ h s/^\(\S\+\) .*$/Signature of "\1" is missing./ p g } / namcap /!{ h s/^\(\S\+\) .*$/Namcap log of "\1" is missing./ p g } ' ) if [ -n "${missing_files}" ]; then >&2 echo 'The following packages lack a signature, namcap log or package file:' >&2 echo "${missing_files}" 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 namcap.logs find . -maxdepth 1 -name '*.pkg.tar.xz-namcap.log.gz' -execdir mv '{}' "${build_log_directory}/success/" \; # 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" or "tested" find "${work_dir}/package-states" -maxdepth 1 -regextype grep \ -not -name '*.testing' \ -not -name '*.tested' \ -regex ".*/$(str_to_regex "$1")\(\.[^.]\+\)\{4\}" \ -not -regex ".*/$(str_to_regex "$1.$2.$3.$4")\.[^.]\+" \ -exec rm '{}' \; # remove all loops which are broken by this package find "${work_dir}/build-list.loops" -maxdepth 1 -regextype grep \ -regex '.*/loop_[0-9]\+' \ -exec grep -qxF "$1" '{}' \; \ -exec rm '{}.locked' \; # 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"