summaryrefslogtreecommitdiff
path: root/src/chroot-tools/libremakepkg
diff options
context:
space:
mode:
Diffstat (limited to 'src/chroot-tools/libremakepkg')
-rwxr-xr-xsrc/chroot-tools/libremakepkg289
1 files changed, 289 insertions, 0 deletions
diff --git a/src/chroot-tools/libremakepkg b/src/chroot-tools/libremakepkg
new file mode 100755
index 0000000..a226e38
--- /dev/null
+++ b/src/chroot-tools/libremakepkg
@@ -0,0 +1,289 @@
+#!/usr/bin/env bash
+set -euE
+# libremakepkg
+
+# Copyright (C) 2010-2012 Nicolás Reynolds <fauno@parabola.nu>
+# Copyright (C) 2010-2012 Joshua Ismael Haase Hernández (xihh) <hahj87@gmail.com>
+# Copyright (C) 2012 Michał Masłowski <mtjm@mtjm.eu>
+# Copyright (C) 2012-2015 Luke Shumaker <lukeshu@sbcglobal.net>
+#
+# License: GNU GPLv2+
+#
+# This file is part of Parabola.
+#
+# Parabola 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.
+#
+# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>.
+
+. "$(librelib conf)"
+. "$(librelib messages)"
+. "$(librelib chroot/makechrootpkg.sh)"
+
+set -o pipefail
+shopt -s nullglob
+umask 0022
+
+# Global variables:
+readonly _indent="$(librelib chroot/indent)"
+readonly INCHROOT=$([[ -f /.arch-chroot ]] && echo true || echo false)
+NONET=true # can be changed with the -N flag
+# {PKG,SRC,SRCPKG,LOG}DEST set at runtime by makepkg.conf
+# MAKEFLAGS, PACKAGER set at runtime by makepkg.conf
+# LIBREUSER, LIBREHOME are set by conf.sh
+librechroot_flags=()
+
+# Hooks ########################################################################
+
+hook_pre_build=(:)
+hook_post_build=(:)
+hook_check_pkgbuild=(:)
+hook_check_pkg=(:)
+. "$(librelib chroot/hooks-chcleanup.sh)"
+. "$(librelib chroot/hooks-check.sh)"
+. "$(librelib chroot/hooks-distcc.sh)"
+
+# Boring/mundane functions #####################################################
+
+indent() {
+ "$_indent" ' | '
+}
+
+# Usage: exit_copy $copydir $src_owner
+# End immediately, but copy log files out
+exit_copy() {
+ local copydir=$1
+ local src_owner=$2
+ if ! $INCHROOT; then
+ msg "Copying log and package files out of the chroot..."
+ move_products "$copydir" "$src_owner"
+ fi
+}
+
+# Usage; run_hook $hookname $args...
+run_hook() {
+ local hookname=$1; shift
+ local hookvar="hook_${hookname}[@]"
+
+ local fails=()
+ for hook in "${!hookvar}"; do
+ "$hook" "$@" || fails+=("$hook")
+ done |& indent
+
+ if [[ ${#fails[@]} -gt 0 ]]; then
+ error "Failure(s) in %s: %s" "$hookname" "${fails[*]}"
+ return 1
+ else
+ return 0
+ fi
+}
+
+# Usage: add_to_local_repo $copydir $pkgfiles...
+add_to_local_repo() {
+ local copydir=$1; shift
+ mkdir -p "$copydir/repo"
+ local pkgfile
+ for pkgfile in "$@"; do
+ cp "$pkgfile" "$copydir/repo"
+ pushd "$copydir/repo" >/dev/null
+ repo-add repo.db.tar.gz "${pkgfile##*/}"
+ popd >/dev/null
+ done
+}
+
+hook_post_build+=('cleanup')
+cleanup() {
+ local copydir=$1
+ rm -f -- "$copydir"/chroot{prepare,build}
+}
+
+build() (
+ local copydir=$1
+ local repack=$2
+ local makepkg_args=("${@:3}")
+
+ local run_ynet=()
+ local run_nnet=()
+ if $INCHROOT; then
+ run_ynet=(unshare)
+ run_nnet=(unshare -n)
+ else
+ run_ynet=(librechroot "${librechroot_flags[@]}" run)
+ run_nnet=(librechroot "${librechroot_flags[@]}" -N run)
+ fi
+ $NONET || run_nnet=("${run_ynet[@]}")
+
+ prepare_chroot "$copydir" "$LIBREHOME" "$repack" false
+ "${run_ynet[@]}" /chrootprepare "${makepkg_args[@]}" |& indent
+ run_hook pre_build "$copydir"
+ trap "run_hook post_build $(printf '%q' "$copydir")" EXIT
+ "${run_nnet[@]}" /chrootbuild "${makepkg_args[@]}" |& indent
+)
+
+# The main program #############################################################
+
+usage() {
+ print "Usage: %s [options]" "${0##*/}"
+ print 'This program will build your package.'
+ echo
+ prose 'If run from outside of a chroot, command will make the following
+ configuration changes in the chroot:'
+ bullet 'whatever changes `librechroot` makes.'
+ bullet 'set `{PKG,SRC,SRCPKG,LOG}DEST` in `/etc/makepkg.conf`'
+ bullet 'set `PACKAGER` in `/etc/makepkg.conf` to reflect the value
+ outside of the chroot.'
+ bullet '(maybe) delete `/build/.makepkg.conf`'
+ bullet '(maybe) delete `/build/.ssh/config`'
+ prose 'If run from inside of a chroot, this command will:'
+ bullet '(maybe) delete `~/.makepkg.conf`'
+ bullet '(maybe) delete `~/.ssh/config`'
+ prose 'The above "maybe"s happen as part of the workarounds to make
+ distcc work in a network-less environment. They will happen if
+ both `socat` and `distcc` are installed in the chroot.'
+ echo
+ prose 'The `-n` and `-l` options behave identically to librechroot, see
+ the documentation there.'
+ echo
+ print 'Options:'
+ print ' %s options:' librechroot
+ flag "-n <$(_ CHROOT)>" 'Name of the chroot to use'
+ flag "-l <$(_ COPY)>" 'Name of, or absolute path to, the chroot copy to use'
+ flag "-w <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read/write'
+ flag "-r <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read-only'
+ print ' %s options:' libremakepkg
+ flag '-N' "Don't disable networking during build() and
+ package(). PLEASE don't use this unless you
+ have a special reason, its use is a violation
+ of Parabola policy."
+ flag '-R' 'Repackage contents of the package without rebuilding'
+ flag '-h' 'Show this message'
+}
+
+# Convenience method for use in option parsing
+err_chflag() {
+ local flag=$1
+ error 'The -%s flag does not make sense inside of a chroot' "$flag"
+ return 1
+}
+
+main() {
+ # Initial variable values ##############################################
+ local copy=$([[ $LIBREUSER == root ]] && echo copy || echo "$LIBREUSER")
+ local makepkg_args=(-s --noconfirm -L)
+ local repack=false
+ local chroot=''
+
+ # Parse command line options ###########################################
+ while getopts 'n:l:w:r:NRh' flag ; do
+ case "${flag}" in
+ n) if $INCHROOT; then err_chflag "$flag"; else
+ chroot=$OPTARG; fi;;
+ l) if $INCHROOT; then err_chflag "$flag"; else
+ copy=$OPTARG; fi;;
+ w|r) if $INCHROOT; then err_chflag "$flag"; else
+ librechroot_flags+=(-$flag "$OPTARG"); fi;;
+ N) NONET=false;;
+ R) repack=true; makepkg_args+=(-R);;
+ h) usage; return 0;;
+ *) usage >&2; return 1;;
+ esac
+ done
+ shift $(($OPTIND - 1))
+ if [[ $# != 0 ]]; then
+ error 'Extra arguments: %s' "$*"
+ return 1
+ fi
+
+ # Resolve the chroot path ##############################################
+ local copydir
+ if $INCHROOT; then
+ copydir='/'
+ else
+ load_files chroot
+ check_vars chroot CHROOTDIR CHROOT
+ [[ -z ${chroot} ]] || CHROOT=$chroot
+ if [[ ${copy:0:1} = / ]]; then
+ copydir=$copy
+ else
+ copydir="${CHROOTDIR}/${CHROOT}/${copy}"
+ fi
+ unset CHROOTDIR CHROOTEXTRAPKG
+ fi
+ unset chroot
+
+ # Load makepkg configuration ###########################################
+ # Note that all of these are globals
+ PKGDEST="$(get_var makepkg PKGDEST "$PWD")"
+ SRCDEST="$(get_var makepkg SRCDEST "$PWD")"
+ SRCPKGDEST="$(get_var makepkg SRCPKGDEST "$PWD")"
+ LOGDEST="$(get_var makepkg LOGDEST "$PWD")"
+ MAKEFLAGS="$(get_var makepkg MAKEFLAGS '')"
+ PACKAGER="$(get_var makepkg PACKAGER '')"
+
+ # Quick sanity check ###################################################
+
+ if (( EUID )); then
+ error "This program must be run as root"
+ exit 1
+ fi
+
+ if [[ ! -f PKGBUILD ]]; then
+ # This is the message used by makepkg
+ error "PKGBUILD does not exist."
+ exit 1
+ fi
+
+ # Make sure that the various *DEST directories exist
+ mkdir -p -- "$PKGDEST" "$SRCDEST" "$SRCPKGDEST" "$LOGDEST"
+
+ # OK, we are starting now ##############################################
+
+ if $INCHROOT; then
+ lock 9 "/build/.lock" \
+ "Waiting for existing lock on build directory to be released"
+ else
+ librechroot_flags+=(
+ -r "$PWD:/startdir_host"
+ -r "$SRCDEST:/srcdest_host"
+ -n "$CHROOT"
+ -l "$copy"
+ )
+
+ # Obtain a lock on the chroot
+ lock 9 "$copydir.lock" \
+ "Waiting for existing lock on chroot copy to be released: [%s]" "$copy"
+ # Create the chroot if it does not exist
+ msg 'Initializing the chroot...'
+ librechroot "${librechroot_flags[@]}" make |& indent
+ fi
+
+ # Set target CARCH
+ # note that we waited until after locking/creating the chroot to do this
+ export CARCH="$(MAKEPKG_CONF=$copydir/etc/makepkg.conf get_var makepkg CARCH)"
+
+ # Pre-build
+ msg 'Starting pre-build activities...'
+ run_hook check_pkgbuild
+ msg 'Downloading sources...'
+ download_sources "$copydir" "$LIBREUSER" |& indent
+
+ # Build
+ msg 'Starting to build the package...'
+ trap "exit_copy '$copydir' '$LIBREUSER'" EXIT
+ build "$copydir" "$repack" "${makepkg_args[@]}"
+
+ # Post-build
+ msg 'Starting post-build activities...'
+ run_hook check_pkg
+ add_to_local_repo "$copydir" "$copydir"/pkgdest/*.pkg.tar* |& indent
+}
+
+main "$@"