summaryrefslogtreecommitdiff
path: root/src/offload-build.in
diff options
context:
space:
mode:
Diffstat (limited to 'src/offload-build.in')
-rw-r--r--src/offload-build.in121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/offload-build.in b/src/offload-build.in
new file mode 100644
index 0000000..9e9d71e
--- /dev/null
+++ b/src/offload-build.in
@@ -0,0 +1,121 @@
+#!/bin/bash
+#
+# offload-build - build a PKGBUILD on a remote server using makechrootpkg.
+#
+# Copyright (c) 2019 by Eli Schwartz <eschwartz@archlinux.org>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+source /usr/share/makepkg/util/config.sh
+
+
+# global defaults suitable for use by Arch staff
+repo=extra
+arch=x86_64
+server=build.archlinux.org
+
+die() { printf "error: $1\n" "${@:2}"; exit 1; }
+
+usage() {
+ cat <<- _EOF_
+ Usage: ${BASH_SOURCE[0]##*/} [--repo REPO] [--arch ARCHITECTURE] [--server SERVER] -- [ARCHBUILD_ARGS]
+
+ Build a PKGBUILD on a remote server using makechrootpkg. Requires a remote user
+ that can run archbuild without password auth. Options passed after a -- are
+ passed on to archbuild, and eventually to makechrootpkg.
+
+ OPTIONS
+ -r, --repo Build against a specific repository (current: $repo)
+ -a, --arch Build against a specific architecture (current: $arch)
+ -s, --server Offload to a specific build server (current: $server)
+ -h, --help Show this help text
+_EOF_
+}
+
+# option checking
+while (( $# )); do
+ case $1 in
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ -r|--repo)
+ repo=$2
+ shift 2
+ ;;
+ -a|--arch)
+ arch=$2
+ shift 2
+ ;;
+ -s|--server)
+ server=$2
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ die "invalid argument: %s" "$1"
+ ;;
+ esac
+done
+
+# multilib must be handled specially
+archbuild_arch="${arch}"
+if [[ $repo = multilib* ]]; then
+ archbuild_arch=
+fi
+
+archbuild_cmd=("${repo}${archbuild_arch:+-$archbuild_arch}-build" "$@")
+
+trap 'rm -rf $TEMPDIR' EXIT INT TERM QUIT
+
+# Load makepkg.conf variables to be available
+load_makepkg_config
+
+# Use a source-only tarball as an intermediate to transfer files. This
+# guarantees the checksums are okay, and guarantees that all needed files are
+# transferred, including local sources, install scripts, and changelogs.
+export TEMPDIR=$(mktemp -d --tmpdir offload-build.XXXXXXXXXX)
+export SRCPKGDEST=${TEMPDIR}
+makepkg --source || die "unable to make source package"
+
+# Temporary cosmetic workaround makepkg if SRCDEST is set somewhere else
+# but an empty src dir is created in PWD. Remove once fixed in makepkg.
+rmdir --ignore-fail-on-non-empty src 2>/dev/null || true
+
+mapfile -t files < <(
+ # This is sort of bash golfing but it allows running a mildly complex
+ # command over ssh with a single connection.
+ # shellcheck disable=SC2145
+ cat "$SRCPKGDEST"/*"$SRCEXT" |
+ ssh $server '
+ temp="${XDG_CACHE_HOME:-$HOME/.cache}/offload-build" &&
+ mkdir -p "$temp" &&
+ temp=$(mktemp -d -p "$temp") &&
+ cd "$temp" &&
+ {
+ bsdtar --strip-components 1 -xvf - &&
+ script -qefc "'"${archbuild_cmd[@]@Q}"'" /dev/null &&
+ printf "%s\n" "" "-> build complete" &&
+ printf "\t%s\n" "$temp"/*
+ } >&2 &&
+ makepkg_user_config="${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" &&
+ makepkg_config="/usr/share/devtools/makepkg-'"${arch}"'.conf" &&
+ if [[ -f /usr/share/devtools/makepkg-'"${repo}"'-'"${arch}"'.conf ]]; then
+ makepkg_config="/usr/share/devtools/makepkg-'"${repo}"'-'"${arch}"'.conf"
+ fi &&
+ makepkg --config <(cat "${makepkg_user_config}" "${makepkg_config}" 2>/dev/null) --packagelist &&
+ printf "%s\n" "${temp}/PKGBUILD"
+')
+
+
+if (( ${#files[@]} )); then
+ printf '%s\n' '' '-> copying files...'
+ scp "${files[@]/#/$server:}" "${TEMPDIR}/"
+ mv "${TEMPDIR}"/*.pkg.tar* "${PKGDEST:-${PWD}}/"
+ mv "${TEMPDIR}/PKGBUILD" "${PWD}/"
+else
+ exit 1
+fi