#!/bin/sh # report back on a build assignment # either on success via: # "$0 $package $revision $mod_revision $repository $arch $sub_pkgrel" 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 $arch ERROR" and tar'ed logs # or to abort: # "$0 ABORT" # exit codes: # 0: ok # 1: another instance was already running # 2: outdated package # 3: signature error # 4: package error (e.g. wrong packages sent) # 5: wrong number of arguments # TODO: sign database # shellcheck disable=SC2119,SC2120 # shellcheck source=../lib/load-configuration . "${0%/*}/../lib/load-configuration" if [ -s "${work_dir}/build-master-sanity" ]; then >&2 echo 'Build master is not sane.' exit 1 fi # aborting does not need any locks if [ $# -eq 1 ] && \ [ "$1" = 'ABORT' ]; then # shellcheck disable=SC2016 { printf 'UPDATE `build_slaves`' printf ' SET `build_slaves`.`currently_building`=NULL' # shellcheck disable=SC2154 printf ' WHERE `build_slaves`.`id`=%s;\n' \ "${slave_id}" } | \ mysql_run_query exit fi if [ $# -ne 6 ]; then >&2 printf 'return-assignment: Wrong number of arguments (%s)\n' \ "$#" >&2 printf 'call either:\n' >&2 printf ' return-assignment ABORT\n' >&2 printf ' return-assignment pkgbase git_revision mod_git_revision repository arch ERROR\n' >&2 printf ' return-assignment pkgbase git_revision mod_git_revision repository arch sub-pkgrel\n' exit 5 fi # Create a lock file and a trap. exec 9> "${build_list_lock_file}" if ! verbose_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 ! verbose_flock -s -n 8; then >&2 echo 'come back (shortly) later - sanity-check running.' exit 1 fi if [ "$6" = 'ERROR' ]; then # the build failed on the build slave # shellcheck disable=SC2016 infos=$( { printf 'SELECT DISTINCT `build_assignments`.`id`,IF(`build_assignments`.`is_broken`,"true","false") FROM `build_slaves`' mysql_join_build_slaves_build_assignments mysql_join_build_assignments_package_sources mysql_join_package_sources_upstream_repositories mysql_join_build_assignments_binary_packages mysql_join_binary_packages_binary_packages_in_repositories mysql_join_build_assignments_architectures printf ' WHERE `build_slaves`.`id`=from_base64("%s")' \ "$( # shellcheck disable=SC2154 printf '%s' "${slave_id}" | \ base64 -w0 )" printf ' AND `package_sources`.`%s`=from_base64("%s")' \ 'pkgbase' "$(printf '%s' "$1" | base64 -w0)" \ 'git_revision' "$(printf '%s' "$2" | base64 -w0)" \ 'mod_git_revision' "$(printf '%s' "$3" | base64 -w0)" printf ' AND `upstream_repositories`.`name`=from_base64("%s")' \ "$(printf '%s' "$4" | base64 -w0)" printf ' AND `architectures`.`name`=from_base64("%s")' \ "$(printf '%s' "$5" | base64 -w0)" printf ' AND `binary_packages_in_repositories`.`repository`=%s;\n' \ "${repository_ids__any_build_list}" } | \ mysql_run_query | \ tr '\t' ' ' ) if [ -z "${infos}" ]; then >&2 echo 'You do not build this package (anymore) - move on.' exit 2 fi was_broken_before="${infos##* }" build_assignment_id="${infos%% *}" # save sent build logs saved_build_logs=$( tar -vx \ -C "${build_log_directory}/error" \ --wildcards \ --no-wildcards-match-slash \ --transform="s|^|$1.$2.$3.$4.$5.|" \ '*.build-log.gz' ) # shellcheck disable=SC2016 { if [ -n "${saved_build_logs}" ]; then printf 'CREATE TEMPORARY TABLE `failures` (' printf '`%s` %s,' \ 'date' 'TIMESTAMP' \ 'reason' 'SMALLINT' \ 'log_file' 'VARCHAR(512)' | \ sed 's/,$//' printf ');\n' fail_reason_identifiers=$( { printf 'SELECT `fail_reasons`.`id`,replace(to_base64(`fail_reasons`.`identifier`),"\\n","")' printf ' FROM `fail_reasons` ORDER BY `fail_reasons`.`severity`' } | \ mysql_run_query ) for saved_build_log in ${saved_build_logs}; do printf '%s\n' "${fail_reason_identifiers}" | \ while read -r reason_id identifier; do if zgrep -q "^$( printf '%s' "${identifier}" | \ base64 -d )\$" \ "${build_log_directory}/error/$1.$2.$3.$4.$5.${saved_build_log}"; then printf ' (from_base64("%s"),%s,from_base64("%s")),' \ "$( printf '%s' "${saved_build_log}" | \ sed 's|\.build-log\.gz$||;s|^.*\.||' | \ base64 -w0 )" \ "${reason_id}" \ "$( printf '%s' "$1.$2.$3.$4.$5.${saved_build_log}" | \ base64 -w0 )" break fi done done | \ sed ' 1 s/^/INSERT INTO `failures` (`date`,`reason`,`log_file`) VALUES / s/,$/;\n/ ' printf 'INSERT INTO `failed_builds` (`build_slave`,`build_assignment`,`date`,`reason`,`log_file`,`log_file_exists`)' printf ' SELECT ' printf 'from_base64("%s"),' \ "$(printf '%s' "${slave_id}" | base64 -w0)" \ "$(printf '%s' "${build_assignment_id}" | base64 -w0)" printf '`failures`.`%s`,' \ 'date' 'reason' 'log_file' printf '1' printf ' FROM `failures`;\n' printf 'DROP TEMPORARY TABLE `failures`;\n' printf 'COMMIT;\n' fi printf 'UPDATE `build_assignments`' printf ' SET `build_assignments`.`is_broken`=1,' printf '`build_assignments`.`priority`=0' printf ' WHERE `build_assignments`.`id`=from_base64("%s");\n' \ "$( printf '%s' "${build_assignment_id}" | \ base64 -w0 )" printf 'COMMIT;\n' printf 'UPDATE `build_slaves`' printf ' SET `build_slaves`.`currently_building`=NULL,' printf ' `build_slaves`.`last_action`=NULL,' printf ' `build_slaves`.`logged_lines`=NULL,' printf ' `build_slaves`.`trials`=NULL' printf ' WHERE `build_slaves`.`id`=from_base64("%s");\n' \ "$( printf '%s' "${slave_id}" | \ base64 -w0 )" } | \ mysql_run_query # release lock on build-list - otherwise seed-build-list won't run flock -u 9 if ! ${was_broken_before}; then haskell_rebuild_packages=$( find "${build_log_directory}/error" -type f \ -name "$1.$2.$3.$4.$5.*.build-log.gz" \ -exec zgrep -qFx ' The following packages are broken because other packages they depend on are missing. These broken packages must be rebuilt before they can be used.' {} \; \ -exec zcat {} \; | \ sed -n ' s/^installed package \(.*\) is broken due to missing package .*$/\1/ T p ' | \ tr ' ' '\n' | \ sed ' s/^/-p ^(haskell-)?/ s/-[0-9.]\+$/\$/ ' | \ sort -u ) rescheduled_packages=$( if [ -n "${haskell_rebuild_packages}" ]; then # shellcheck disable=SC2086 "${base_dir}/bin/seed-build-list" ${haskell_rebuild_packages} | \ sed 's/ .*$//' fi ) # shellcheck disable=SC2119 { # shellcheck disable=SC2154 printf '%s/%s is broken (says %s)' \ "$5" \ "$1" \ "${slave}" if [ "$1" = 'electron' ]; then printf -- ' - as usual' fi if [ -n "${rescheduled_packages}" ]; then printf -- ' - I rescheduled:' # shellcheck disable=SC2086 printf ' %s,' ${rescheduled_packages} | \ sed 's/,$//' fi printf '.\n' } | \ irc_say fi 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 ! verbose_flock -n 7; then >&2 echo 'come back (shortly) later - I cannot lock package database.' exit 1 fi # shellcheck disable=SC2016 build_assignment_id=$( { printf 'SELECT DISTINCT `build_assignments`.`id` FROM `build_slaves`' mysql_join_build_slaves_build_assignments mysql_join_build_assignments_package_sources mysql_join_package_sources_upstream_repositories mysql_join_build_assignments_binary_packages mysql_join_binary_packages_binary_packages_in_repositories printf ' JOIN `architecture_compatibilities`' printf ' ON `build_assignments`.`architecture`=`architecture_compatibilities`.`built_for`' printf ' AND `architecture_compatibilities`.`fully_compatible`' printf ' JOIN `architectures`' printf ' ON `architecture_compatibilities`.`runs_on`=`architectures`.`id`' printf ' WHERE `build_slaves`.`id`=from_base64("%s")' \ "$( # shellcheck disable=SC2154 printf '%s' "${slave_id}" | \ base64 -w0 )" printf ' AND `package_sources`.`%s`=from_base64("%s")' \ 'pkgbase' "$( printf '%s' "$1" | \ base64 -w0 )" \ 'git_revision' "$( printf '%s' "$2" | \ base64 -w0 )" \ 'mod_git_revision' "$( printf '%s' "$3" | \ base64 -w0 )" printf ' AND `upstream_repositories`.`name`=from_base64("%s")' \ "$( printf '%s' "$4" | \ base64 -w0 )" printf ' AND `architectures`.`name`=from_base64("%s")' \ "$( printf '%s' "$5" | \ base64 -w0 )" printf ' AND `binary_packages_in_repositories`.`repository`=%s' \ "${repository_ids__any_build_list}" printf ' AND `binary_packages`.`sub_pkgrel`=from_base64("%s");\n' \ "$( printf '%s' "$6" | \ base64 -w0 )" } | \ mysql_run_query | \ tr '\t' ' ' ) if [ -z "${build_assignment_id}" ]; 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}" } tmp_dir=$(mktemp -d "${work_dir}/tmp.return-assignment.XXXXXXXXXX") cd "${tmp_dir}" trap clean_up_tmp_dir EXIT export TMPDIR="${tmp_dir}" # extract package(s) tar -x \ --wildcards \ --no-wildcards-match-slash \ '*.pkg.tar.xz' \ '*.pkg.tar.xz.sig' \ '*.pkg.tar.xz-namcap.log.gz' \ '*.pkg.tar.xz.so.needs.gz' \ '*.pkg.tar.xz.so.provides.gz' # check if all packages come with: # - a package file # - a signature # - a namcap log # - a list of needed libraries # - a list of provided libraries missing_files=$( find . -maxdepth 1 \( \ \( \ -name '*.pkg.tar.xz' \ -printf '%f package\n' \ \) -o \ \( \ -name '*.pkg.tar.xz.sig' \ -printf '%f signature\n' \ \) -o \ \( \ -name '*.pkg.tar.xz-namcap.log.gz' \ -printf '%f namcap\n' \ \) -o \ \( \ -name '*.pkg.tar.xz.so.needs.gz' \ -printf '%f needed-libraries\n' \ \) -o \ \( \ -name '*.pkg.tar.xz.so.provides.gz' \ -printf '%f provided-libraries\n' \ \) \ \) | \ sed ' s/\(\.pkg\.tar\.xz\)\(\.sig\|\(-namcap\.log\|\.so\.\(provides\|needs\)\)\.gz\) /\1 / ' | \ 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 } / needed-libraries /!{ h s/^\(\S\+\) .*$/List of libraries needed by "\1" is missing./ p g } / provided-libraries /!{ h s/^\(\S\+\) .*$/List of libraries provided by "\1" is missing./ p g } ' ) if [ -n "${missing_files}" ]; then >&2 echo 'The following packages lack a signature, namcap log, package file or list of needed/provided libraries:' >&2 echo "${missing_files}" exit 3 fi # check if the signatures are valid signatures=$( find . -maxdepth 1 -name '*.pkg.tar.xz' \ -printf 'package file %f\n' \ -exec gpg --batch --status-fd 1 -q --homedir /etc/pacman.d/gnupg --verify '{}.sig' '{}' \; 2> /dev/null ) if [ -z "$( printf '%s\n' "${signatures}" | \ cut -d' ' -f2 | \ grep -x 'file\|TRUST_FULLY' | \ sort | \ uniq -c | \ awk '{print $1}' | \ uniq -d )" ]; then >&2 echo 'Signature(s) is/are not fully trusted:' >&2 printf '%s\n' "${signatures}" exit 3 fi # check if the package maintainer is set errors=$( find . -maxdepth 1 -name '*.pkg.tar.xz' | \ while read -r pkg; do tar -OxJf "${pkg}" '.BUILDINFO' 2>/dev/null | \ grep -vxF 'packager = Unknown Packager' | \ grep -q '^packager = ' || \ printf '%s misses a valid packager.\n' \ "${pkg##*/}" done ) if [ -n "${errors}" ]; then >&2 echo 'Packager error(s):' >&2 printf '%s' "${errors}" exit 3 fi # check if the sent packages are the expected ones find . -maxdepth 1 -name '*.pkg.tar.xz' -printf '%f\n' > \ "${tmp_dir}/packages" # shellcheck disable=SC2016 { printf 'SELECT' printf ' `binary_packages`.`id`,' mysql_package_name_query printf ' FROM `binary_packages`' mysql_join_binary_packages_architectures mysql_join_binary_packages_binary_packages_in_repositories printf ' WHERE `binary_packages`.`build_assignment`=from_base64("%s")' \ "$( printf '%s' "${build_assignment_id}" | \ base64 -w0 )" printf ' AND `binary_packages_in_repositories`.`repository`=%s' \ "${repository_ids__any_build_list}" printf ';\n' } | \ mysql_run_query | \ tr '\t' ' ' | \ sort -k2 > \ "${tmp_dir}/package-ids" package_errors=$( { sed ' s|^|was_built: | ' "${tmp_dir}/packages" sed ' s|^[0-9]\+ |expected: | ' "${tmp_dir}/package-ids" } | \ 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 if [ ! -s "${tmp_dir}/package-ids" ]; then >&2 echo 'No package was expected, no package was built.' >&2 echo 'That should not happen!' exit 4 fi # shellcheck disable=SC2016 { printf 'SELECT `binary_packages`.`id`,' mysql_package_name_query printf ',`t`.`id`,`t_a`.`name`,`t`.`name`' printf ' FROM `build_assignments`' mysql_join_build_assignments_binary_packages mysql_join_binary_packages_binary_packages_in_repositories printf ' AND `binary_packages_in_repositories`.`repository`=%s' \ "${repository_ids__any_build_list}" mysql_join_binary_packages_architectures mysql_join_build_assignments_package_sources mysql_join_package_sources_upstream_repositories mysql_join_upstream_repositories_repository_moves printf ' JOIN `repositories` as `t` ON `t`.`id`=`repository_moves`.`to_repository`' mysql_join_repositories_architectures 't' 't_a' printf ' JOIN `architecture_compatibilities`' printf ' ON `architecture_compatibilities`.`built_for`=`binary_packages`.`architecture`' printf ' AND `architecture_compatibilities`.`runs_on`=`t`.`architecture`' printf ' AND `architecture_compatibilities`.`fully_compatible`' printf ' WHERE `repository_moves`.`from_repository`=%s' \ "${repository_ids__any_build_list}" printf ' AND `build_assignments`.`id`=from_base64("%s");\n' \ "$( printf '%s' "${build_assignment_id}" | \ base64 -w0 )" } | \ mysql_run_query | \ tr '\t' ' ' | \ sort -u > \ "${tmp_dir}/repository-ids" errors=$( { cut -d' ' -f2 < \ "${tmp_dir}/repository-ids" | \ sort -u | \ sed 's/^/repository-was-found: /' cut -d' ' -f2 < \ "${tmp_dir}/package-ids" | \ sort -u | \ sed 's/^/package-was-sent: /' } | \ sort -k2 | \ uniq -uf1 ) if [ -n "${errors}" ]; then >&2 echo 'I cannot determine, where this package (or some part of it)' >&2 echo 'should be published:' >&2 printf '%s\n' "${errors}" >&2 echo 'This is some internal error and not (necessarily) your fault.' # We give a temporary error (although resolving this needs manual # intervention), because there is nothing wrong with the sent package # whence it does not need to be built again, but can simply be sent again. exit 1 fi mysql_load_min_and_max_versions while read -r package_id package_name; do # move namcap.logs mv \ "${tmp_dir}/${package_name}-namcap.log.gz" \ "${build_log_directory}/success/" # generate checksum sha512sum "${tmp_dir}/${package_name}" | \ awk '{print "'"${package_id}"'\t" $1}' >> \ "${tmp_dir}/sha512sums" # generate list of required/provided libraries for lib in 'provides' 'needs'; do zcat "${tmp_dir}/${package_name}.so.${lib}.gz" | \ sed ' s/\(=\|<\|<=\|>=\|>\)\([^[:space:]-]\+\)$/\t\1\t\2/ t h s/$/\t>=\t'"${min_version}"'/ '"$( if [ "${lib}" = 'provides' ]; then printf '%s\n' \ 'p' \ 'g' \ 's/$/\t<=\t'"${max_version}"'/' fi )" | \ sed ' s/\(\s[0-9]\+\):\(\S\+\)$/\1\t\2/ t coda s/\s\S\+$/\t0\0/ :coda s/^/'"${package_id}"'\t/ ' >> "${tmp_dir}/so.${lib}" done done < \ "${tmp_dir}/package-ids" # move packages cut -d' ' -f4,5 "${tmp_dir}/repository-ids" | \ sort -u | \ while read -r arch repo; do mkdir -p "${arch}/${repo}" failsafe_rsync \ "${master_mirror_rsync_directory}/${arch}/${repo}/${repo}.db."* \ "${master_mirror_rsync_directory}/${arch}/${repo}/${repo}.files."* \ "${arch}/${repo}/" grep " $(str_to_regex "${arch} ${repo}")\$" "${tmp_dir}/repository-ids" | \ cut -d' ' -f2 | \ xargs -r repo-add "${arch}/${repo}/${repo}.db.tar.gz" # xargs -r repo-add -v -s -k "${repo_key}" "${destination}.db.tar.gz" done # upload the packages into /pool failsafe_rsync -c --copy-dest=/.transfer \ ./*".pkg.tar.xz" \ ./*".pkg.tar.xz.sig" \ "${master_mirror_rsync_directory}/pool/" # create symlinks find . \( -name '*.pkg.tar.xz' -o -name '*.pkg.tar.xz.sig' \) -printf '%f\n' | \ while read -r file; do rm "${file}" ln -s "../../pool/${file}" "${file}" done # upload the database and the symlinks into /$arch/$repo cut -d' ' -f4,5 "${tmp_dir}/repository-ids" | \ sort -u | \ while read -r arch repo; do recompress_gz \ "${tmp_dir}" \ "${arch}/${repo}/${repo}."*".tar.gz" \ "${arch}/${repo}/${repo}."*".tar.gz.old" # shellcheck disable=SC2046 failsafe_rsync \ "${arch}/${repo}/${repo}.db."* \ "${arch}/${repo}/${repo}.files."* \ $( grep " $(str_to_regex "${arch} ${repo}")\$" "${tmp_dir}/repository-ids" | \ cut -d' ' -f2 | \ sed ' s,^,./, p s/$/.sig/ ' ) \ "${master_mirror_rsync_directory}/${arch}/${repo}/" done trigger_mirror_refreshs # shellcheck disable=SC2016 { # insert checksums into database printf 'CREATE TEMPORARY TABLE `pkg_hashes` (`pkgid` BIGINT, `sha512sum` VARCHAR(128));\n' printf 'LOAD DATA LOCAL INFILE "%s" INTO TABLE `pkg_hashes`;\n' \ "${tmp_dir}/sha512sums" printf 'UPDATE `binary_packages`' printf ' JOIN `pkg_hashes` ON `pkg_hashes`.`pkgid`=`binary_packages`.`id`' printf ' SET `binary_packages`.`sha512sum`=`pkg_hashes`.`sha512sum`;\n' printf 'COMMIT;\n' # insert provided/needed libraries into database for lib_link in 'pl:provides' 'nl:needs'; do printf 'CREATE TEMPORARY TABLE `%s` (' \ "${lib_link%:*}" printf '`pkgid` BIGINT,' printf '`lib` VARCHAR(128),' printf '`relation` VARCHAR(2),' printf '`epoch` MEDIUMINT,' printf '`version` VARCHAR(32)' printf ');\n' printf 'LOAD DATA LOCAL INFILE "%s" INTO TABLE `%s`;\n' \ "${tmp_dir}/so.${lib_link#*:}" "${lib_link%:*}" printf 'INSERT IGNORE INTO `install_targets` (`name`)' printf ' SELECT DISTINCT `%s`.`lib` FROM `%s`;\n' \ "${lib_link%:*}" "${lib_link%:*}" printf 'COMMIT;\n' # TODO: possibly remove install_target_providers with less restrictive # versions than we have now printf 'INSERT IGNORE INTO `versions` (`epoch`,`version`)' printf ' SELECT DISTINCT `%s`.`epoch`,`%s`.`version` FROM `%s`;\n' \ "${lib_link%:*}" "${lib_link%:*}" "${lib_link%:*}" printf 'COMMIT;\n' if [ "${lib_link%:*}" = 'pl' ]; then printf 'INSERT IGNORE INTO `install_target_providers` (`package`,`install_target`,`version`)' else printf 'INSERT IGNORE INTO `dependencies` (`dependent`,`depending_on`,`dependency_type`,`version_relation`,`version`)' fi printf ' SELECT `%s`.`pkgid`,`install_targets`.`id`,' \ "${lib_link%:*}" if [ "${lib_link%:*}" = 'nl' ]; then printf '`dependency_types`.`id`,' printf '`%s`.`relation`,' \ "${lib_link%:*}" fi printf '`versions`.`id`' printf ' FROM `install_targets`' if [ "${lib_link%:*}" = 'nl' ]; then printf ' JOIN `dependency_types`' printf ' ON `dependency_types`.`name`="link"' fi printf ' JOIN `%s`' \ "${lib_link%:*}" printf ' ON `%s`.`lib`=`install_targets`.`name`' \ "${lib_link%:*}" printf ' JOIN `versions`' printf ' ON `versions`.`epoch`=`%s`.`epoch`' \ "${lib_link%:*}" printf ' AND `versions`.`version`=`%s`.`version`' \ "${lib_link%:*}" printf ';\n' printf 'COMMIT;\n' done # remove build_assignment's markers printf 'UPDATE `build_assignments`' printf ' SET' printf ' `build_assignments`.`is_broken`=0,' printf ' `build_assignments`.`priority`=0,' printf ' `build_assignments`.`return_date`=NOW()' printf ' WHERE `build_assignments`.`id`=from_base64("%s");\n' \ "$( printf '%s' "${build_assignment_id}" | \ base64 -w0 )" printf 'COMMIT;\n' # insert into appropriate repositories and retrieve ids while read -r package_id _ repository_id _; do printf 'INSERT INTO `binary_packages_in_repositories` (`package`,`repository`,`is_to_be_deleted`) VALUES ' printf '(%s,%s,0);\n' \ "${package_id}" "${repository_id}" printf 'SELECT LAST_INSERT_ID();\n' done < \ "${tmp_dir}/repository-ids" printf 'COMMIT;\n' # reschedule toolchain packages if they were not fully unblocked printf 'INSERT IGNORE INTO `binary_packages` (' printf '`build_assignment`,' printf '`epoch`,' printf '`pkgver`,' printf '`pkgrel`,' printf '`has_issues`,' printf '`is_tested`,' printf '`pkgname`,' printf '`architecture`,' printf '`sub_pkgrel`)' printf ' SELECT ' printf '`binary_packages`.`%s`,' \ 'build_assignment' \ 'epoch' \ 'pkgver' \ 'pkgrel' \ 'has_issues' \ 'is_tested' \ 'pkgname' \ 'architecture' printf '`binary_packages`.`sub_pkgrel`+1' printf ' FROM `binary_packages`' printf ' JOIN `pkg_hashes`' printf ' ON `pkg_hashes`.`pkgid`=`binary_packages`.`id`' mysql_join_binary_packages_build_assignments mysql_join_build_assignments_package_sources printf ' JOIN `toolchain_order` AS `late`' printf ' ON `late`.`pkgbase`=`package_sources`.`pkgbase`' printf ' JOIN `toolchain_order` AS `early`' printf ' ON `early`.`number`<`late`.`number`' printf ' AND `early`.`pkgbase`!=`late`.`pkgbase`' printf ' JOIN `package_sources` AS `early_ps`' printf ' ON `early`.`pkgbase`=`early_ps`.`pkgbase`' mysql_join_package_sources_build_assignments 'early_ps' 'early_ba' mysql_join_build_assignments_binary_packages 'early_ba' 'early_bp' printf ' WHERE (' printf '`early_bp`.`architecture`=`binary_packages`.`architecture`' # shellcheck disable=SC2154 printf ' OR `%s`.`architecture`=%s' \ 'early_bp' "${architecture_ids__any}" \ 'binary_packages' "${architecture_ids__any}" printf ') AND NOT EXISTS (' printf 'SELECT 1' printf ' FROM `binary_packages` AS `early_bp`' mysql_join_binary_packages_binary_packages_in_repositories 'early_bp' 'early_bpir' mysql_join_binary_packages_in_repositories_repositories 'early_bpir' 'early_r' printf ' WHERE `early_r`.`is_on_master_mirror`' printf ' AND `early_bp`.`build_assignment`=`early_ba`.`id`' printf ');\n' join_part=$( printf ' JOIN `pkg_hashes`' printf ' ON `built_bp`.`id`=`pkg_hashes`.`pkgid`' printf ' JOIN `binary_packages` AS `new_bp`' printf ' ON' printf ' `built_bp`.`%s`=`new_bp`.`%s` AND' \ 'build_assignment' 'build_assignment' \ 'epoch' 'epoch' \ 'pkgver' 'pkgver' \ 'pkgrel' 'pkgrel' \ 'has_issues' 'has_issues' \ 'is_tested' 'is_tested' \ 'pkgname' 'pkgname' \ 'architecture' 'architecture' printf ' `built_bp`.`sub_pkgrel`+1=`new_bp`.`sub_pkgrel`' ) printf 'INSERT IGNORE INTO `binary_packages_in_repositories`' printf ' (`package`,`repository`,`is_to_be_deleted`)' printf ' SELECT `new_bp`.`id`,%s,0' \ "${repository_ids__any_build_list}" printf ' FROM `binary_packages` AS `built_bp`' printf '%s;\n' "${join_part}" printf 'INSERT IGNORE INTO `dependencies`' printf ' (`dependent`,`depending_on`,`dependency_type`,`version`,`version_relation`)' printf ' SELECT `new_bp`.`id`' printf ',`dependencies`.`%s`' \ 'depending_on' \ 'dependency_type' \ 'version' \ 'version_relation' printf ' FROM `dependencies`' mysql_join_dependencies_binary_packages '' 'built_bp' printf '%s;\n' "${join_part}" printf 'INSERT IGNORE INTO `install_target_providers`' printf ' (`package`,`install_target`)' printf ' SELECT `new_bp`.`id`,`install_target_providers`.`install_target`' printf ' FROM `install_target_providers`' mysql_join_install_target_providers_binary_packages '' 'built_bp' printf '%s;\n' "${join_part}" # remove from build-list printf 'DELETE `binary_packages_in_repositories`' printf ' FROM `binary_packages_in_repositories`' printf ' JOIN `pkg_hashes`' printf ' ON `pkg_hashes`.`pkgid`=`binary_packages_in_repositories`.`package`' printf ' WHERE `binary_packages_in_repositories`.`repository`=%s;\n' \ "${repository_ids__any_build_list}" printf 'COMMIT;\n' # update package information printf 'UPDATE `binary_packages`' printf ' SET' printf ' `binary_packages`.`has_issues`=0,' printf ' `binary_packages`.`is_tested`=0' printf ' WHERE `binary_packages`.`id` IN (' cut -d' ' -f1 < \ "${tmp_dir}/package-ids" | \ base64_encode_each | \ sed ' s/^/from_base64("/ s/$/"),/ $ s/,$// ' printf ');\n' printf 'COMMIT;\n' # remove from build slave's `currently_building` printf 'UPDATE `build_slaves`' printf ' SET `build_slaves`.`currently_building`=NULL,' printf ' `build_slaves`.`last_action`=NULL,' printf ' `build_slaves`.`logged_lines`=NULL,' printf ' `build_slaves`.`trials`=NULL' printf ' WHERE `build_slaves`.`currently_building`=from_base64("%s");\n' \ "$( printf '%s' "${build_assignment_id}" | \ base64 -w0 )" printf 'COMMIT;\n' # remove broken loops printf 'CREATE TEMPORARY TABLE `loops_to_delete` (`loop` MEDIUMINT);\n' printf 'INSERT INTO `loops_to_delete`' printf ' SELECT `build_dependency_loops`.`loop` FROM `build_dependency_loops`' mysql_join_build_dependency_loops_binary_packages mysql_join_binary_packages_binary_packages_in_repositories printf ' WHERE NOT `binary_packages_in_repositories`.`repository`=%s;\n' \ "${repository_ids__any_build_list}" printf 'COMMIT;\n' printf 'DELETE FROM `build_dependency_loops` WHERE EXISTS (' printf 'SELECT 1 FROM `loops_to_delete`' printf ' WHERE `loops_to_delete`.`loop`=`build_dependency_loops`.`loop`' printf ');\n' printf 'DROP TEMPORARY TABLE `loops_to_delete`;\n' } | \ mysql_run_query | \ sort -u | \ remove_old_package_versions