summaryrefslogtreecommitdiff
path: root/offload-build.in
blob: d40b0048b7268d655315591ca55b257f8bd3856f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/bash
#
#   offload-build - build a PKGBUILD on a remote server using makechrootpkg.
#
#   Copyright (c) 2019 by Eli Schwartz <eschwartz@archlinux.org>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <https://www.gnu.org/licenses/>.
#

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