summaryrefslogtreecommitdiff
path: root/src/offload-build.in
blob: 7a8c1fd064c52692c02581550cae855ab1ca718b (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>
#
# SPDX-License-Identifier: GPL-3.0-or-later

_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/util/makepkg.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/makepkg.sh

source /usr/share/makepkg/util/config.sh

# Deprecation warning
if [[ -z $_DEVTOOLS_COMMAND ]]; then
	warning "${0##*/} is deprecated and will be removed. Use 'pkgctl build --offload' instead"
fi

# global defaults suitable for use by Arch staff
repo=extra
arch=x86_64
server=build.archlinux.org
rsyncopts=(-e ssh -c -h -L --progress --partial -y)

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_package || 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 '
            export TERM="'"${TERM}"'"
            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.conf.d/'"${arch}"'.conf" &&
            if [[ -f /usr/share/devtools/makepkg.conf.d/'"${repo}"'-'"${arch}"'.conf ]]; then
                makepkg_config="/usr/share/devtools/makepkg.conf.d/'"${repo}"'-'"${arch}"'.conf"
            fi &&
            while read -r file; do
                [[ -f "${file}" ]] && printf "%s\n" "${file}" ||:
            done < <(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...'
    rsync "${rsyncopts[@]}" "${files[@]/#/$server:}" "${TEMPDIR}/" || die
    mv "${TEMPDIR}"/*.pkg.tar* "${PKGDEST:-${PWD}}/"
    mv "${TEMPDIR}/PKGBUILD" "${PWD}/"
else
    exit 1
fi