#!/bin/bash # build packages one by one, then upload the binary package to the repository server # Details: # https://github.com/archlinux32/builder/wiki/Build-system#build-packages # TODOs: # use different build commands for different repositories - do we need this actually? # send logs of failed builds . "${0%/*}/../conf/default.conf" usage() { >&2 echo '' >&2 echo 'build-packages: build package(s) on the build-list' >&2 echo '' >&2 echo 'possible options:' >&2 echo ' -h|--help: Show this help and exit.' >&2 echo ' -n count: Build $count packages (if available), then exit.' >&2 echo ' $count=0 is interpreted as infinity.' >&2 echo ' The default is $count=1.' [ -z "$1" ] && exit 1 || exit $1 } eval set -- "$( getopt -o hn: \ --long help \ -n "$(basename "$0")" -- "$@" || \ echo usage )" count=1 while true do case "$1" in -h|--help) usage 0 ;; -n) shift count="$1" [ ${count} -eq 0 ] && \ count=-1 ;; --) shift break ;; *) >&2 echo 'Whoops, forgot to implement option "'"$1"'" internally.' exit -1 ;; esac shift done if [ $# -ne 0 ]; then >&2 echo 'Too many arguments.' usage fi while [ ${count} -ne 0 ]; do package="$( ssh \ -i "${master_build_server_identity}" \ -p "${master_build_server_port}" \ "${master_build_server_user}@${master_build_server}" \ 'get-assignment' )" case $? in # 0: ok, I gave you an assignment 0) [ ${count} -gt 0 ] && \ count=$[${count}-1] repository="${package##* }" package="${package% *}" mod_git_revision="${package##* }" package="${package% *}" git_revision="${package##* }" package="${package% *}" # Update git repositories (official packages, community packages and the repository of package customizations). for repo in "${repo_paths[@]}"; do git -C "${repo}" clean -df git -C "${repo}" reset --hard git -C "${repo}" checkout master git -C "${repo}" pull done git -C "${repo_paths["$(find_repository_with_commit "${git_revision}")"]}" checkout "${git_revision}" &> /dev/null git -C "${repo_paths["archlinux32"]}" checkout "${mod_git_revision}" &> /dev/null PKGBUILD="$(find_pkgbuild "${package}" "${repository}")" if [ ! -r "${PKGBUILD}" ]; then echo "can't find PKGBUILD to package '${package}' from repository '${repository}': '${PKGBUILD}'" exit 1 fi cd "${PKGBUILD%/*}" success=false for parameters in '' '-c'; do rm -f *.pkg.tar.xz{,.sig} if staging-i486-build ${parameters}; then # build successful ls -1 *.pkg.tar.xz | \ xargs -rn1 gpg --local-user="${package_key}" --detach-sign tar -c 'package.tar' *.pkg.tar.xz{,.sig} while ! ssh \ -i "${master_build_server_identity}" \ -p "${master_build_server_port}" \ "${master_build_server_user}@${master_build_server}" \ 'return-assignment' "${package}" "${git_revision}" "${mod_git_revision}" "${repository}" \ < 'package.tar'; do case $? in 1) # 'return-assignment' was running already sleep $[15+$RANDOM%30] ;; 2) >&2 echo 'I was too slow, the package is outdated. I will continue ...' break ;; 3) >& echo "'return-assignment' reports a signature error." exit 1 ;; *) >&2 echo "unknown return code $? from 'return-assignment'" exit 1 esac done success=true break fi done if ! ${success}; then ssh \ -i "${master_build_server_identity}" \ -p "${master_build_server_port}" \ "${master_build_server_user}@${master_build_server}" \ 'return-assignment' "${package}" "${git_revision}" "${mod_git_revision}" "${repository}" 'ERROR' fi continue ;; # 1: come back (shortly) later - I was running already 1) sleep $[15+$RANDOM%30] continue ;; # 2: come back later - there are still packages to be built, # but currently none has all its dependencies ready 2) sleep $[60+$RANDOM%30] continue ;; # 3: come back after the next run of get-package-updates - currently # there are no pending packages 3) >&2 echo 'Done. No more packages left to build.' exit 0 ;; # 4: come back, when you've done your work - you hit the limit on # maximum allowed parallel jobs per ip 4) >&2 echo 'ERROR: There are too many parallel builds running on this machine.' exit 1 ;; *) >&2 echo "ERROR: Unknown exit code $? from 'get-assignment'." exit 1 ;; esac done >&2 echo 'Done.'