diff options
Diffstat (limited to 'src/chroot-tools/libremakepkg')
-rwxr-xr-x | src/chroot-tools/libremakepkg | 410 |
1 files changed, 135 insertions, 275 deletions
diff --git a/src/chroot-tools/libremakepkg b/src/chroot-tools/libremakepkg index a1d30d4..22e7a7f 100755 --- a/src/chroot-tools/libremakepkg +++ b/src/chroot-tools/libremakepkg @@ -20,251 +20,94 @@ # 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.sh) -load_files chroot - -. libremessages -makechrootpkg=$(librelib makechrootpkg) +. $(librelib conf) +. $(librelib messages) +. $(librelib chroot/makechrootpkg.sh) shopt -s nullglob umask 0022 -# Boring/mundane functions ##################################################### - -# End inmediately but print a useful message -trap_exit() { - error "$*" - $INCHROOT || chroot_copy_out "$copydir" "$LIBREUSER" - exit 1 -} - -# Usage run [-N] $copydir "$cmd" -# Runs cmd properly, whether in a chroot already or not. -# -# Note that $cmd is a quoted string, not a list of arguments. -# $copydir=/ if INCHROOT=true -# -# Environment -# - $INCHROOT is set -run() ( - local HASNET=true - [[ $1 == -N ]] && { HASNET=false; shift; } - local copydir=$1; shift - local cmd="$*" +# Global variables: +readonly INCHROOT=$([[ -f /.arch-chroot ]] && echo true || echo false) +NONET=true # can be changed with the -N flag +# {SRC,LOG,PKG}DEST set at runtime by makepkg.conf +# MAKEFLAGS, PACKAGER set at runtime by makepkg.conf +# LIBREUSER, LIBREHOME are set by conf.sh - if $HASNET; then - trap "rm -f -- '$copydir/chrootexec'" EXIT - else - distcc_start "$copydir" - trap "rm -f -- '$copydir/chrootexec'; distcc_stop '$copydir'" EXIT - fi +# Hooks ######################################################################## - cat >"$copydir/chrootexec" <<EOF -#!/bin/bash -. /etc/profile -${INCHROOT} || export HOME=/build -${INCHROOT} || cd /build +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) -${cmd} -EOF - chmod 755 "$copydir/chrootexec" - - local flags='' - if $INCHROOT; then - $HASNET || flags='-n' - unshare $flags -- /chrootexec - else - $HASNET || flags='-N' - librechroot $flags -l "$copydir" run /chrootexec - fi -) +# Boring/mundane functions ##################################################### -distcc_start() { +# Usage: exit_copy $copydir $src_owner +# End immediately, but copy log files out +exit_copy() { local copydir=$1 - # Because /{,usr/}{,s}bin are all symlinked together for - # fileystem 2013.05-2 and up, I can take shortcuts when checking for - # existance of programs. - if [[ -f "$copydir/bin/socat" && -f "$copydir/bin/distcc" ]]; then - local home=$LIBREHOME - $INCHROOT || home="$copydir/build" - - cp -a "$(which distcc-tool)" "$copydir/distcc-tool" - - mkdir -p "$home/.ssh" - - printf '%s\n' \ - '/distcc-tool idaemon "$DISTCC_HOSTS" &' \ - 'DISTCC_HOSTS="$(/distcc-tool rewrite "$DISTCC_HOSTS")"' \ - > "$home/.makepkg.conf" - - printf '%s\n' \ - 'Host *' \ - ' ProxyCommand /distcc-tool client %h %p' \ - > "$home/.ssh/config" - - distcc-tool odaemon "$copydir" & - echo $! > "$copydir/distcc-tool.pid" + local src_owner=$2 + if ! $INCHROOT; then + msg "Copying log and package files out of the chroot..." + move_products "$copydir" "$src_owner" fi } -distcc_stop() { - local copydir=$1 - local home=$LIBREHOME - $INCHROOT || home="$copydir/build" - if [[ -f "$copydir/distcc-tool.pid" ]]; then - - odaemon=$(cat "$copydir/distcc-tool.pid") - kill -- $odaemon - - rm -f -- \ - "$copydir/distcc-tool" \ - "$home/.makepkg.conf" \ - "$home/.ssh/config" \ - "$copydir/distcc-tool.pid" +# Usage; run_hook $hookname $args... +run_hook() { + local hookname=$1; shift + local hookvar="hook_${hookname}[@]" + local fails=() + msg "Running hook: %s" "$hookname" + for hook in "${!hookvar}"; do + msg2 'hook: %s' "$hook" + "$hook" "$@" || { error "result: %s" $?; fails+=("$hook"); } + done + if [[ ${#fails[@]} -gt 0 ]]; then + error "Failure(s) in %s: %s" "$hookname" "${fails[*]}" + return 1 fi + return 0 } # Usage: add_to_local_repo $copydir $pkgfiles... -add_to_local_repo() ( - set +euE - . $makechrootpkg - chroot_add_to_local_repo "$@" -) - -# Usage: chroot_copy_in $copydir -# Environment: -# - In the dirctory of a PKGBUILD -# - $SRCDEST is set -chroot_copy_in() ( - set +euE - . $makechrootpkg - chroot_copy_in "$@" -) - -# Usage: chroot_copy_out $copydir $owner -# Environment: -# - $SRCDEST is set -# - $PKGDEST is set -chroot_copy_out() ( - set +euE - . $makechrootpkg - chroot_copy_out_pkgs "$@" - chroot_copy_out_logs "$@" - chroot_copy_out_srcs "$@" -) - -# Usage: chroot_let_nobody_use_pacman $copydir -chroot_let_nobody_use_pacman() ( - set +euE - . $makechrootpkg - chroot_let_nobody_use_pacman "$@" -) - -# Usage: chroot_init $copydir $repack -# Environment -# - $LIBREHOME is set -chroot_init() { - local copydir=$1 - local repack=$2 - - librechroot -l "$copydir" make # make sure the chroot exists - mkdir -p "$copydir"/{build,pkgdest,srcdest} - - # Remove anything in there UNLESS -R (repack) was passed - $repack || rm -rf "$copydir"/build/* - - if [[ -r "$LIBREHOME/.gnupg/pubring.gpg" ]]; then - install -D "$LIBREHOME/.gnupg/pubring.gpg" "$copydir/build/.gnupg/pubring.gpg" - fi - rm -f "$copydir/build/.makepkg.conf" - - MAKEPKG_CONF="$copydir/etc/makepkg.conf" set_conf_makepkg PKGDEST /pkgdest - MAKEPKG_CONF="$copydir/etc/makepkg.conf" set_conf_makepkg SRCDEST /srcdest - local PACKAGER="$(get_conf_makepkg PACKAGER '')" - if [[ -n $PACKAGER ]]; then - MAKEPKG_CONF="$copydir/etc/makepkg.conf" set_conf_makepkg PACKAGER "$PACKAGER" - fi - unset PACKAGER - - if ! grep -q '^\[repo\]' "$copydir/etc/pacman.conf"; then - cat >> "$copydir/etc/pacman.conf" <<EOF -[repo] -SigLevel = Optional TrustAll -Server = file:///repo -EOF - fi - - chroot_let_nobody_use_pacman "$copydir" +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 } -# Core functions ############################################################### +build() ( + local copydir=$1; shift + local cmd=(/chrootbuild "$@") -# Usage: extract -# Extracts the sources (`makepkg -o`) -# Environment: -# - $INCHROOT is set -# - $copydir is set -# - $LIBREUSER is set -extract() ( - local user=$LIBREUSER - $INCHROOT || user=nobody + run_hook pre_build "$copydir" + trap "run_hook post_build '$copydir'" EXIT - local clean + local netflag='' if $INCHROOT; then - clean=chcleanup + ! $NONET || netflag='-n' + unshare $netflag -- "${cmd[@]}" else - trap "rm -f '$copydir/clean'" EXIT - cp -a "$(which chcleanup)" "${copydir}/clean" - clean=/clean + ! $NONET || netflag='-N' + librechroot $netflag \ + -r "$PWD:/startdir_host" \ + -r "$SRCDEST:/srcdest_host" \ + -l "$copydir" \ + run "${cmd[@]}" fi - - run "$copydir" "${clean} && sudo -u ${user} -- makepkg ${makepkg_args} -o" ) -# Usage: build -# Builds the package (`makepkg -e`) -# Environment: -# - $INCHROOT is set -# - $copydir is set -# - $LIBREUSER is set -build() { - local user=$LIBREUSER - $INCHROOT || user=nobody - - if $NONET; then - run -N "$copydir" "sudo -u ${user} -- makepkg ${makepkg_args} -e" - else - run "$copydir" "sudo -u ${user} -- makepkg ${makepkg_args} -e" - fi -} - -# Functions that check for issues with the build ############################### - -check_pkgbuild() { - msg "Checking PKGBUILD for issues" - # TODO - if ! pkgbuild-check-nonfree -f; then - if [[ $? -eq 15 ]]; then - # other errors mean fail, not nonfree - error "PKGBUILD contains non-free issues" - exit 15 - else - warning "PKGBUILD couldn't be check aganist non-free issues" - fi - fi -} - -check_src() { - msg "Checking src directory for issues" - # TODO -} - -check_pkg() { - msg "Checking final package for issues" - # TODO -} - - # The main program ############################################################# usage() { @@ -291,59 +134,65 @@ usage() { echo print 'Options:' flag "-n <$(_ CHROOT)>" 'Name of the chroot to use' - flag "-l <$(_ COPY)>" 'Name of, or absolute path to, the copy to use' - 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 "-l <$(_ COPY)>" 'Name of, or absolute path to, the chroot copy to use' + 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' } -# Globals: $CHROOTDIR, $CHROOT, $COPY and $copydir -# Globals: $makepkg_args, $INCHROOT -main() { - # Parse command line ################################################### - - COPY=$LIBREUSER - [[ $COPY != root ]] || COPY=copy +# 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 +} - makepkg_args='-s --noconfirm -L ' +main() { + # Initial variable values ############################################## + local copy=$([[ $LIBREUSER == root ]] && echo copy || echo "$LIBREUSER") + local makepkg_args=(-s --noconfirm -L) local repack=false + local chroot='' - INCHROOT=false - if [[ -f /.arch-chroot ]]; then - INCHROOT=true - fi - - NONET=true - while getopts 'n:l:NRh' arg ; do - case "${arg}" in - n) CHROOT=$OPTARG;; - l) COPY=$OPTARG;; + # Parse command line options ########################################### + while getopts 'n:l: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;; N) NONET=false;; - R) repack=true; makepkg_args+=" -R";; + R) repack=true; makepkg_args+=(-R);; h) usage; return 0;; - *) usage; return 1;; + *) usage >&2; return 1;; esac done shift $(($OPTIND - 1)) # Pass all arguments after -- right to makepkg - makepkg_args+=" $*" + makepkg_args+=("$@") + # Resolve the chroot path ############################################## + local copydir if $INCHROOT; then copydir='/' else + load_files chroot check_vars chroot CHROOTDIR CHROOT - if [[ ${COPY:0:1} = / ]]; then - copydir=$COPY + [[ -z ${chroot} ]] || CHROOT=$chroot + if [[ ${copy:0:1} = / ]]; then + copydir=$copy else - copydir="${CHROOTDIR}/${CHROOT}/${COPY}" + copydir="${CHROOTDIR}/${CHROOT}/${copy}" fi + unset CHROOTDIR CHROOTEXTRAPKG fi + unset chroot - # Init ################################################################# + # Quick sanity check ################################################### if (( EUID )); then - error "This script must be run as root" + error "This program must be run as root" exit 1 fi @@ -353,36 +202,47 @@ main() { exit 1 fi - # Trap signals from makepkg - trap 'trap_exit "(libremakepkg): TERM signal caught. Exiting..."' TERM HUP QUIT - trap 'trap_exit "(libremakepkg): Aborted by user! Exiting..."' INT - trap 'trap_exit "(libremakepkg): An error has occurred. Exiting..."' ERR - - SRCDEST="$(get_conf_makepkg SRCDEST .)" - PKGDEST="$(get_conf_makepkg PKGDEST .)" - - # OK, we're starting now ############################################### - - $INCHROOT || lock_open_write 9 "$copydir" \ - "Waiting for existing lock on chroot copy to be released: [%s]" "$COPY" + # Load makepkg configuration ########################################### + # Note that all of these are globals + SRCDEST="$(get_conf_makepkg SRCDEST "$PWD")" + PKGDEST="$(get_conf_makepkg PKGDEST "$PWD")" + LOGDEST="$(get_conf_makepkg LOGDEST "$PWD")" + mkdir -p "$SRCDEST" "$PKGDEST" "$LOGDEST" + MAKEFLAGS="$(get_conf_makepkg MAKEFLAGS '')" + PACKAGER="$(get_conf_makepkg PACKAGER '')" - # Set target CARCH as it might be used within the PKGBUILD to select - # correct sources - MAKEPKG_CONF=$copydir/etc/makepkg.conf - export CARCH="$(get_conf_makepkg CARCH)" - unset MAKEPKG_CONF + # OK, we are starting now ############################################## - $INCHROOT || chroot_init "$copydir" "$repack" - - check_pkgbuild - $INCHROOT || chroot_copy_in "$copydir" - $repack || extract - check_src - build - check_pkg + if $INCHROOT; then + lock 9 "/build/.lock" \ + "Waiting for existing lock on build directory to be released" + else + # 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 + librechroot -n "$CHROOT" -l "$copy" make + 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_conf_makepkg CARCH)" + + # Pre-build + run_hook check_pkgbuild + download_sources "$copydir" "$LIBREUSER" + prepare_chroot "$copydir" "$LIBREHOME" "$repack" false + clean_chroot "$copydir" + + # Build + trap "exit_copy '$copydir' '$LIBREUSER'" EXIT + warning 'Entering build...' + build "$copydir" "${makepkg_args[@]}" + # Post-build + warning 'Entering hook check_pkg...' + run_hook check_pkg + warning 'Entering add_to_local_repo ...' add_to_local_repo "$copydir" "$copydir"/pkgdest/*.pkg.tar* - $INCHROOT || chroot_copy_out "$copydir" "$LIBREUSER" } main "$@" |