From 070092d2492c6d21f42d2bb8d47bfd5e4a4ecfa5 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 15 Feb 2017 14:03:56 -0500 Subject: Apply patches from libretools. --- arch-nspawn.in | 17 +++++- checkpkg.in | 27 +++++++++- find-libdeps.in | 28 ++++++++-- finddeps.in | 18 ++++--- lddd.in | 18 ++++++- lib/common.sh | 55 +++++++++++++------ makechrootpkg.in | 162 ++++++++++++++++++++++++++++++++++++++++++++++--------- mkarchroot.in | 21 +++++++- 8 files changed, 289 insertions(+), 57 deletions(-) diff --git a/arch-nspawn.in b/arch-nspawn.in index fd4c583..85af8c5 100644 --- a/arch-nspawn.in +++ b/arch-nspawn.in @@ -16,6 +16,8 @@ CHROOT_VERSION='v3' working_dir='' +files=() + usage() { echo "Usage: ${0##*/} [options] working-dir [systemd-nspawn arguments]" echo "A wrapper around systemd-nspawn. Provides support for pacman." @@ -24,17 +26,21 @@ usage() { echo ' -C Location of a pacman config file' echo ' -M Location of a makepkg config file' echo ' -c Set pacman cache' + echo ' -f Copy file from the host to the chroot' + echo ' -s Do not run setarch' echo ' -h This message' exit 1 } orig_argv=("$@") -while getopts 'hC:M:c:' arg; do +while getopts 'hC:M:c:f:s' arg; do case "$arg" in C) pac_conf="$OPTARG" ;; M) makepkg_conf="$OPTARG" ;; c) cache_dir="$OPTARG" ;; + f) files+=("$OPTARG") ;; + s) nosetarch=1 ;; h|?) usage ;; *) error "invalid argument '%s'" "$arg"; usage ;; esac @@ -80,6 +86,12 @@ copy_hostconf () { [[ -n $pac_conf ]] && cp $pac_conf "$working_dir/etc/pacman.conf" [[ -n $makepkg_conf ]] && cp $makepkg_conf "$working_dir/etc/makepkg.conf" + local file + for file in "${files[@]}"; do + mkdir -p "$(dirname "$working_dir$file")" + cp -T "$file" "$working_dir$file" + done + sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${cache_dirs[@]})|g" -i "$working_dir/etc/pacman.conf" } # }}} @@ -94,6 +106,7 @@ elif [[ $(cat "$working_dir/.arch-chroot") != $CHROOT_VERSION ]]; then fi build_mount_args +cache_dirs+=('/repo/') copy_hostconf eval $(grep '^CARCH=' "$working_dir/etc/makepkg.conf") @@ -101,6 +114,8 @@ case "$CARCH" in armv7h) CARCH=armv7l;; esac +[[ -z $nosetarch ]] || unset CARCH + exec ${CARCH:+setarch "$CARCH"} systemd-nspawn -q \ -D "$working_dir" \ --register=no \ diff --git a/checkpkg.in b/checkpkg.in index fbd30d3..6904e32 100644 --- a/checkpkg.in +++ b/checkpkg.in @@ -3,7 +3,28 @@ shopt -s extglob -m4_include(lib/common.sh) +. "$(librelib messages)" + +usage() { + print 'Usage: %s [-h]' "${0##*/}" + print 'Compare a locally built a package with the one in the repositories.' + echo + prose 'This should be run from a directory containing a + PKGBUILD. It searches for a locally built package + corresponding to the PKGBUILD, and downloads the last + version of that package from the pacman repositories. + It then compares the list of .so files provided by each + version of the package. It does this for each part of + a split package.' +} + +if [[ $1 = '-h' ]]; then + usage + exit 0 +elif [[ $# -gt 0 ]]; then + usage >&2 + exit 1 +fi # Source makepkg.conf; fail if it is not found if [[ -r '/etc/makepkg.conf' ]]; then @@ -18,7 +39,9 @@ if [[ -r ~/.makepkg.conf ]]; then fi if [[ ! -f PKGBUILD ]]; then - die 'This must be run in the directory of a built package.' + error 'This must be run in the directory of a built package.' + usage >&2 + exit 1 fi . ./PKGBUILD diff --git a/find-libdeps.in b/find-libdeps.in index 5c350a9..794a2cd 100644 --- a/find-libdeps.in +++ b/find-libdeps.in @@ -1,7 +1,7 @@ #!/bin/bash # License: Unspecified -m4_include(lib/common.sh) +. "$(librelib messages)" set -e shopt -s extglob @@ -20,12 +20,32 @@ case $script_mode in *) die "Unknown mode %s" "$script_mode" ;; esac +usage() { + print "Usage: find-lib(deps|provides) [options] " + print "Find library dependencies or provides of a package." + echo + prose 'Prints a list of library dependencies in the format:' + echo + print ' =-' + echo + prose 'Where is the shared library version, or + repeated if there is no version attached; and + is the architecture of the library (either `32` + or `64`, based on the ELF Class).' + echo + print "Options:" + flag "--ignore-internal" "Ignore internal libraries; libraries + without a version attached" + flag "-h" "Show this message" +} if [[ -z $1 ]]; then - echo "${0##*/} [options] " - echo "Options:" - echo " --ignore-internal ignore internal libraries" + usage >&2 exit 1 fi +if [[ $1 = '-h' ]]; then + usage + exit 0 +fi if [[ -d $1 ]]; then pushd $1 >/dev/null diff --git a/finddeps.in b/finddeps.in index 89ccc41..cc1ffab 100644 --- a/finddeps.in +++ b/finddeps.in @@ -4,18 +4,24 @@ # # License: Unspecified -m4_include(lib/common.sh) +. "$(librelib messages)" match=$1 +usage() { + print 'Usage: %s ' "${0##*/}" + print 'Find packages that depend on a given depname.' + echo + prose 'Run this script from the top-level directory of your ABS tree.' +} if [[ -z $match ]]; then - echo 'Usage: finddeps ' - echo '' - echo 'Find packages that depend on a given depname.' - echo 'Run this script from the top-level directory of your ABS tree.' - echo '' + usage >&2 exit 1 fi +if [[ $match = '-h' ]]; then + usage + exit 0 +fi find . -type d | while read d; do if [[ -f "$d/PKGBUILD" ]]; then diff --git a/lddd.in b/lddd.in index f01ebf9..09e0d07 100644 --- a/lddd.in +++ b/lddd.in @@ -4,7 +4,23 @@ # # License: Unspecified -m4_include(lib/common.sh) +. "$(librelib messages)" + +usage() { + print "Usage: %s [-h]" "${0##*/}" + print "Find broken library links on your machine." + echo + prose 'Scans $PATH and library directories for ELF files with + references to missing shared libraries.' +} + +if [[ $1 = '-h' ]]; then + usage + exit 0 +elif [[ $# -gt 0 ]]; then + usage >&2 + exit 1 +fi ifs=$IFS IFS="${IFS}:" diff --git a/lib/common.sh b/lib/common.sh index 62f4e72..bb46f6c 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -1,7 +1,28 @@ +#!/hint/bash +# This may be included with or without `set -euE` + +# This file is included by libremessages. +# You should probably use libremessages instead of this. + # License: Unspecified -# Avoid any encoding problems -export LANG=C +shopt -s extglob + +if [[ -z ${_INCLUDE_COMMON_SH:-} ]]; then +_INCLUDE_COMMON_SH=true + +[[ -n ${TEXTDOMAIN:-} ]] || export TEXTDOMAIN='libretools' +[[ -n ${TEXTDOMAINDIR:-} ]] || export TEXTDOMAINDIR='/usr/share/locale' + +if type gettext &>/dev/null; then + _() { gettext "$@"; } +else + _() { echo "$@"; } +fi + +_l() { + TEXTDOMAIN='librelib' TEXTDOMAINDIR='/usr/share/locale' "$@" +} shopt -s extglob @@ -28,37 +49,37 @@ fi readonly ALL_OFF BOLD BLUE GREEN RED YELLOW plain() { - local mesg=$1; shift + local mesg="$(_ "$1")"; shift printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } msg() { - local mesg=$1; shift + local mesg="$(_ "$1")"; shift printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } msg2() { - local mesg=$1; shift + local mesg="$(_ "$1")"; shift printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } warning() { - local mesg=$1; shift - printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 + local mesg="$(_ "$1")"; shift + printf "${YELLOW}==> $(_l _ "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } error() { - local mesg=$1; shift - printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 + local mesg="$(_ "$1")"; shift + printf "${RED}==> $(_l _ "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } stat_busy() { - local mesg=$1; shift + local mesg="$(_ "$1")"; shift printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" "$@" >&2 } stat_done() { - printf "${BOLD}$(gettext "done")${ALL_OFF}\n" >&2 + printf "${BOLD}$(_l _ "done")${ALL_OFF}\n" >&2 } _setup_workdir=false @@ -77,7 +98,7 @@ cleanup() { } abort() { - error 'Aborting...' + _l error 'Aborting...' cleanup 255 } @@ -142,7 +163,8 @@ get_full_version() { ## # usage : lock( $fd, $file, $message, [ $message_arguments... ] ) ## -lock() { +lock() +{ local fd=$1 local file=$2 local mesg=("${@:3}") @@ -163,7 +185,8 @@ lock() { ## # usage : slock( $fd, $file, $message, [ $message_arguments... ] ) ## -slock() { +slock() +{ local fd=$1 local file=$2 local mesg=("${@:3}") @@ -255,7 +278,7 @@ find_cached_package() { return 0 ;; *) - error 'Multiple packages found:' + _l error 'Multiple packages found:' printf '\t%s\n' "${results[@]}" >&2 return 1 esac @@ -272,3 +295,5 @@ check_root() { exec su root -c "$(printf ' %q' "$@")" fi } + +fi diff --git a/makechrootpkg.in b/makechrootpkg.in index fe6cdbe..35a1286 100644 --- a/makechrootpkg.in +++ b/makechrootpkg.in @@ -14,6 +14,7 @@ m4_include(lib/common.sh) shopt -s nullglob +init_variables() { default_makepkg_args=(-s --noconfirm -L --holdver) makepkg_args=("${default_makepkg_args[@]}") repack=false @@ -31,9 +32,10 @@ bindmounts_ro=() bindmounts_rw=() copy=$USER -[[ -n $SUDO_USER ]] && copy=$SUDO_USER +[[ -n ${SUDO_USER:-} ]] && copy=$SUDO_USER [[ -z "$copy" || $copy = root ]] && copy=copy src_owner=${SUDO_USER:-$USER} +} usage() { echo "Usage: ${0##*/} [options] -r [--] [makepkg args]" @@ -70,13 +72,21 @@ usage() { } # {{{ functions +# Usage: load_vars $makepkg_conf +# Globals: +# - SRCDEST +# - SRCPKGDEST +# - PKGDEST +# - LOGDEST +# - MAKEFLAGS +# - PACKAGER load_vars() { local makepkg_conf="$1" var [[ -f $makepkg_conf ]] || return 1 for var in {SRC,SRCPKG,PKG,LOG}DEST MAKEFLAGS PACKAGER; do - [[ -z ${!var} ]] && eval $(grep "^${var}=" "$makepkg_conf") + [[ -z ${!var:-} ]] && eval $(grep "^${var}=" "$makepkg_conf") done return 0 @@ -137,16 +147,31 @@ btrfs_subvolume_delete() { btrfs subvolume delete "$dir" } -create_chroot() { - # Lock the chroot we want to use. We'll keep this lock until we exit. - lock 9 "$copydir.lock" "Locking chroot copy [%s]" "$copy" +# Usage: sync_chroot $CHROOTDIR/$CHROOT <$CHROOTCOPY|$copydir> +sync_chroot() { + local chrootdir=$1 + local copy=$2 + local copydir='' + if [[ ${copy:0:1} = / ]]; then + copydir=$copy + else + copydir="$chrootdir/$copy" + fi + + if [[ "$chrootdir/root" -ef "$copydir" ]]; then + error 'Cannot sync copy with itself: %s' "$copydir" + return 1 + fi + + # Detect chrootdir filesystem type + local chroottype=$(stat -f -c %T "$chrootdir") - if [[ ! -d $copydir ]] || $clean_first; then # Get a read lock on the root chroot to make # sure we don't clone a half-updated chroot - slock 8 "$chrootdir/root.lock" "Locking clean chroot" + slock 8 "$chrootdir/root.lock" \ + "Locking clean chroot [%s]" "$chrootdir/root" - stat_busy "Creating clean working copy [%s]" "$copy" + stat_busy "Synchronizing chroot copy [%s] -> [%s]" "$chrootdir/root" "$copydir" if [[ "$chroottype" == btrfs ]] && ! mountpoint -q "$copydir"; then if [[ -d $copydir ]]; then btrfs_subvolume_delete "$copydir" >/dev/null || @@ -162,14 +187,18 @@ create_chroot() { # Drop the read lock again lock_close 8 - fi # Update mtime touch "$copydir" } -clean_temporary() { - stat_busy "Removing temporary copy [%s]" "$copy" +# Usage: delete_chroot $copydir +delete_chroot() { + local copydir=$1 + # Detect chrootdir filesystem type + local chroottype=$(stat -f -c %T "$copydir") + + stat_busy "Removing chroot copy [%s]" "$copydir" if [[ "$chroottype" == btrfs ]] && ! mountpoint -q "$copydir"; then btrfs_subvolume_delete "$copydir" >/dev/null || die "Unable to delete subvolume %s" "$copydir" @@ -184,9 +213,14 @@ clean_temporary() { stat_done } +# Usage: install_packages $copydir $pkgs... install_packages() { + local copydir=$1 + local install_pkgs=("${@:2}") + declare -i ret=0 local pkgname + local install_pkg for install_pkg in "${install_pkgs[@]}"; do pkgname="${install_pkg##*/}" cp "$install_pkg" "$copydir/$pkgname" @@ -199,11 +233,19 @@ install_packages() { rm "$copydir/$pkgname" done - # If there is no PKGBUILD we are done - [[ -f PKGBUILD ]] || exit $ret + return $ret } +# Usage: prepare_chroot $copydir $HOME $repack $run_namcap +# Globals: +# - MAKEFLAGS +# - PACKAGER prepare_chroot() { + local copydir=$1 + local USER_HOME=$2 + local repack=$3 + local run_namcap=$4 + $repack || rm -rf "$copydir/build" mkdir -p "$copydir/build" @@ -250,12 +292,12 @@ prepare_chroot() { printf 'builduser:x:%d:100:builduser:/build:/bin/bash\n' "$builduser_uid" >>"$copydir/etc/passwd" chown -R "$builduser_uid" "$copydir"/{build,pkgdest,srcpkgdest,logdest,srcdest,startdir} - if [[ -n $MAKEFLAGS ]]; then + if [[ -n ${MAKEFLAGS:-} ]]; then sed -i '/^MAKEFLAGS=/d' "$copydir/etc/makepkg.conf" echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf" fi - if [[ -n $PACKAGER ]]; then + if [[ -n ${PACKAGER:-} ]]; then sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf" echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf" fi @@ -268,8 +310,23 @@ EOF chmod 440 "$copydir/etc/sudoers.d/builduser-pacman" fi + if ! grep -q '^\[repo\]' "$copydir/etc/pacman.conf"; then + local line=$(grep -n '^\[' "$copydir/etc/pacman.conf" |grep -Fv ':[options]'|sed 's/:.*//;1q') + local ins='[repo] +SigLevel = Optional TrustAll +Server = file:///repo +' + sed -i "${line}i${ins//$'\n'/\\n}" "$copydir/etc/pacman.conf" + fi + # This is a little gross, but this way the script is recreated every time in the # working copy + { + printf '#!/bin/bash\n' + declare -f _chrootprepare + printf '_chrootprepare "$@"\n' + } > "$copydir/chrootprepare" + chmod +x "$copydir/chrootprepare" { printf '#!/bin/bash\n' declare -f _chrootbuild @@ -288,13 +345,19 @@ EOF chmod +x "$copydir/chrootbuild" } +# Usage: download_sources $copydir $src_owner +# Globals: +# - SRCDEST download_sources() { + local copydir=$1 + local src_owner=$2 + local builddir="$(mktemp -d)" chmod 1777 "$builddir" # Ensure sources are downloaded - if [[ -n $SUDO_USER ]]; then - sudo -u $SUDO_USER env SRCDEST="$SRCDEST" BUILDDIR="$builddir" \ + if [[ $USER != $src_owner ]]; then + sudo -u $src_owner env SRCDEST="$SRCDEST" BUILDDIR="$builddir" \ makepkg --config="$copydir/etc/makepkg.conf" --verifysource -o else ( export SRCDEST BUILDDIR="$builddir" @@ -304,10 +367,10 @@ download_sources() { (( $? != 0 )) && die "Could not download sources." # Clean up garbage from verifysource - rm -rf $builddir + rm -rf "$builddir" } -_chrootbuild() { +_chrootprepare() { # This function isn't run in makechrootpkg, # so no global variables @@ -316,6 +379,7 @@ _chrootbuild() { shopt -s nullglob # XXX: Workaround makepkg disliking read-only dirs + rm -rf -- /srcdest/* /startdir/* ln -sft /srcdest /srcdest_host/* ln -sft /startdir /startdir_host/* @@ -345,15 +409,42 @@ _chrootbuild() { exit 1 fi - sudo -u builduser makepkg "$@" + # Sync deps now, as networking may be disabled during _chrootbuild + cp /repo/repo.db /var/lib/pacman/sync/repo.db + sudo -u builduser makepkg "$@" --nobuild } +_chrootbuild() { + # This function isn't run in makechrootpkg, + # so no global variables + + . /etc/profile + export HOME=/build + shopt -s nullglob + + cd /startdir + + sudo -u builduser makepkg "$@" --noextract --noprepare +} + +# Usage: move_products $copydir $owner +# Globals: +# - PKGDEST +# - LOGDEST move_products() { + local copydir=$1 + local src_owner=$2 + + local pkgfile for pkgfile in "$copydir"/pkgdest/*; do chown "$src_owner" "$pkgfile" mv "$pkgfile" "$PKGDEST" + if [[ $PKGDEST != $PWD ]]; then + ln -sf "$PKGDEST/${pkgfile##*/}" . + fi done + local l for l in "$copydir"/logdest/*; do [[ $l == */logpipe.* ]] && continue chown "$src_owner" "$l" @@ -367,6 +458,9 @@ move_products() { } # }}} +main() { +init_variables + orig_argv=("$@") while getopts 'hcur:I:l:nTD:d:' arg; do @@ -432,30 +526,45 @@ load_vars /etc/makepkg.conf [[ -d $SRCPKGDEST ]] || SRCPKGDEST=$PWD [[ -d $LOGDEST ]] || LOGDEST=$PWD -create_chroot +# Lock the chroot we want to use. We'll keep this lock until we exit. +lock 9 "$copydir.lock" "Locking chroot copy [%s]" "$copy" + +if [[ ! -d $copydir ]] || $clean_first; then + sync_chroot "$chrootdir" "$copy" +fi $update_first && arch-nspawn "$copydir" \ "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ pacman -Syu --noconfirm -[[ -n ${install_pkgs[*]} ]] && install_packages +if [[ -n ${install_pkgs[*]:-} ]]; then + install_packages "$copydir" "${install_pkgs[@]}" + ret=$? + # If there is no PKGBUILD we have done + [[ -f PKGBUILD ]] || exit $ret +fi -download_sources +download_sources "$copydir" "$src_owner" -prepare_chroot +prepare_chroot "$copydir" "$USER_HOME" "$repack" if arch-nspawn "$copydir" \ + --bind-ro="$PWD:/startdir_host" \ + --bind-ro="$SRCDEST:/srcdest_host" \ + "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ + /chrootprepare "${makepkg_args[@]}" && + arch-nspawn "$copydir" \ --bind-ro="$PWD:/startdir_host" \ --bind-ro="$SRCDEST:/srcdest_host" \ "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ /chrootbuild "${makepkg_args[@]}" then - move_products + move_products "$copydir" "$src_owner" else (( ret += 1 )) fi -$temp_chroot && clean_temporary +$temp_chroot && delete_chroot "$copydir" if (( ret != 0 )); then if $temp_chroot; then @@ -466,3 +575,4 @@ if (( ret != 0 )); then else true fi +} diff --git a/mkarchroot.in b/mkarchroot.in index 656c74e..f86ae35 100644 --- a/mkarchroot.in +++ b/mkarchroot.in @@ -16,23 +16,29 @@ CHROOT_VERSION='v3' working_dir='' +files=() + usage() { echo "Usage: ${0##*/} [options] working-dir package-list..." echo ' options:' echo ' -C Location of a pacman config file' echo ' -M Location of a makepkg config file' echo ' -c Set pacman cache' + echo ' -f Copy file from the host to the chroot' + echo ' -s Do not run setarch' echo ' -h This message' exit 1 } orig_argv=("$@") -while getopts 'hC:M:c:' arg; do +while getopts 'hC:M:c:f:s' arg; do case "$arg" in C) pac_conf="$OPTARG" ;; M) makepkg_conf="$OPTARG" ;; c) cache_dir="$OPTARG" ;; + f) files+=("$OPTARG") ;; + s) nosetarch=1 ;; h|?) usage ;; *) error "invalid argument '%s'" "$arg"; usage ;; esac @@ -70,6 +76,16 @@ if [[ $(stat -f -c %T "$working_dir") == btrfs ]]; then chmod 0755 "$working_dir" fi +for file in "${files[@]}"; do + mkdir -p "$(dirname "$working_dir$file")" + cp "$file" "$working_dir$file" +done + +_env=() +while read -r varname; do + _env+=("$varname=${!varname}") +done < <(declare -x | sed -r 's/^declare -x ([^=]*)=.*/\1/' | grep -i '_proxy$') +env -i "${_env[@]}" \ pacstrap -GMcd ${pac_conf:+-C "$pac_conf"} "$working_dir" \ "${cache_dirs[@]/#/--cachedir=}" "$@" || die 'Failed to install all packages' @@ -79,7 +95,8 @@ echo "$CHROOT_VERSION" > "$working_dir/.arch-chroot" systemd-machine-id-setup --root="$working_dir" -exec arch-nspawn \ +exec "$(librelib chroot/arch-nspawn)" \ + ${nosetarch:+-s} \ ${pac_conf:+-C "$pac_conf"} \ ${makepkg_conf:+-M "$makepkg_conf"} \ ${cache_dir:+-c "$cache_dir"} \ -- cgit v1.2.3-54-g00ecf