summaryrefslogtreecommitdiff
path: root/src/chroot-tools/libremakepkg
diff options
context:
space:
mode:
authorLuke Shumaker <LukeShu@sbcglobal.net>2013-09-11 10:56:46 -0400
committerLuke Shumaker <LukeShu@sbcglobal.net>2013-09-11 15:55:15 -0400
commit6eddc77d5e6abb25f33751308419fa0c62518188 (patch)
tree4f1d004e46d5be3f54efb04d6fd6c5cc6b50c0da /src/chroot-tools/libremakepkg
parent2a971c6ad1e55f95f5486b265307160e57b47e5f (diff)
Update to the new version of devtools (huge commit).
User-facing changes: - libremessages: `lock_open_write` became `lock` - libremessages: `lock_open_read` became `slock` - librechroot: learned the `-r` and `-w` flags to do bind mounts. Internal changes: The changes to librechroot were pretty straight-forward; the biggest change is that `archroot` got split into `mkarchroot` and `arch-nspawn`. libremakepkg got a major overhaul Honestly, the changes to libremakepklg probably could have been a lot smaller, but... I wanted to do it right/be clean. makechrootpkg in devtools got cleaned up a lot, actually a lot of the same changes I was making. But, the small differences between the way we did things made it less than simple to adjust. The biggest changes in terms of conflict for me are how devtools now uses bind-mounts to put files in the chroot, and that the /chrootbuild file is more complicated. I handled a lot of the complexity by moving things out of the main program, and adding hooks for non-core functionality, including chcleanup, distcc compatability hacks, and PKGBUILD/pkg checking. Unfortunately, the files containing the hooks are currently hard-coded. Perhaps they will be truly pluggable in the future. That might be neat. Or over-complicated. We'll see where it goes.
Diffstat (limited to 'src/chroot-tools/libremakepkg')
-rwxr-xr-xsrc/chroot-tools/libremakepkg410
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 "$@"