From 6eddc77d5e6abb25f33751308419fa0c62518188 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 11 Sep 2013 10:56:46 -0400 Subject: 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. --- src/chroot-tools/librechroot | 128 +++++++++++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 42 deletions(-) (limited to 'src/chroot-tools/librechroot') diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot index e82b18c..e5ca1f7 100755 --- a/src/chroot-tools/librechroot +++ b/src/chroot-tools/librechroot @@ -25,18 +25,26 @@ # - the commands=() array # - the case statement in main() -. $(librelib conf.sh) +. $(librelib conf) load_files chroot . libremessages -. $(librelib makechrootpkg) + +shopt -s nullglob +umask 0022 + +readonly _arch_nspawn=$(librelib chroot/arch-nspawn) +readonly _mkarchroot=$(librelib chroot/mkarchroot) +readonly _makechrootpkg=$(librelib chroot/makechrootpkg.sh) # Because the makechrootpkg.sh library functions don't work with -euE -normshell() ( +_makechrootpkg() ( set +euE + . "$_makechrootpkg" "$@" ) +# Usage: make_empty_repo $copydir make_empty_repo() { local copydir=$1 mkdir -p "${copydir}/repo" @@ -44,8 +52,21 @@ make_empty_repo() { ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db" } +# Usage: chroot_add_to_local_repo $copydir $pkgfiles... +chroot_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 +} + usage() { - calculate_directories + eval "$(calculate_directories)" print "Usage: %s [OPTIONS] COMMAND [ARGS...]" "${0##*/}" print 'Interacts with an archroot (arch chroot).' echo @@ -99,6 +120,8 @@ usage() { flag '-N' 'Disable networking in the chroot' flag "-C <$(_ FILE)>" 'Copy this file to `$copydir/etc/pacman.conf`' flag "-M <$(_ FILE)>" 'Copy this file to `$copydir/etc/makepkg.conf`' + flag "-w <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read/write' + flag "-r <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read-only' echo print 'Commands:' print ' Create/copy/delete:' @@ -120,7 +143,7 @@ usage() { flag 'clean-repo' 'Clean /repo in the chroot copy' flag 'help' 'Show this message' } -commands=( +readonly commands=( noop make sync delete install-file install-name update clean-pkgs run enter clean-repo help @@ -130,6 +153,7 @@ commands=( calculate_directories() { # Don't assume that CHROOTDIR or CHROOT are set, # but assume that COPY is set. + local rootdir copydir if [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then rootdir="${CHROOTDIR}/${CHROOT}/root" @@ -144,6 +168,18 @@ calculate_directories() { else copydir='' fi + + declare -p rootdir + declare -p copydir +} + +arch_nspawn_flags=() +sysd_nspawn_flags=() +arch-nspawn() { + local copydir=$1; shift + set +u # if an array is empty, it counts as unbound + "$_arch_nspawn" "${arch_nspawn_flags[@]}" "$copydir" "${sysd_nspawn_flags[@]}" -- "$@" + set -u } # Globals: $CHROOTDIR, $CHROOT, $COPY, $rootdir and $copydir @@ -152,19 +188,14 @@ main() { [[ $COPY != root ]] || COPY=copy local mode=enter - local archroot_args=() - while getopts 'n:l:NC:M:' arg; do - case $arg in + while getopts 'n:l:NC:M:w:r:' opt; do + case $opt in n) CHROOT=$OPTARG;; l) COPY=$OPTARG;; - N) - # We do this so that it carries through to - # chroot_* functions - archroot() { - $(which archroot) -N "$@" - } - ;; - C|M) archroot_args+=(-$arg "$OPTARG");; + N) sysd_nspawn_flags+=(--private-network);; + C|M) arch_nspawn_flags+=(-$opt "$OPTARG");; + w) sysd_nspawn_flags+=("--bind=$OPTARG");; + r) sysd_nspawn_flags+=("--bind-ro=$OPTARG");; *) usage >/dev/stderr; return 1;; esac done @@ -188,7 +219,12 @@ main() { fi check_vars chroot CHROOTDIR CHROOT - calculate_directories + eval "$(calculate_directories)" + + readonly LIBREUSER LIBREHOME + readonly CHROOTDIR CHROOT COPY + readonly rootdir copydir + readonly mode ######################################################################## @@ -200,29 +236,27 @@ main() { umask 0022 # Keep this lock as long as we are running - # Note that '9' is the same FD number as in (mk)archroot - lock_open_write 9 "$copydir" \ + # Note that '9' is the same FD number as in mkarchroot et al. + lock 9 "$copydir.lock" \ "Waiting for existing lock on chroot copy to be released: [%s]" "$COPY" if [[ ! -d $rootdir ]]; then msg "Creating 'root' copy for chroot [%s]" "$CHROOT" - set +u # if archroot_args is empty, it counts as unbound - archroot "${archroot_args[@]}" -m "$rootdir" base-devel + set +u # if an array is empty, it counts as unbound + "$_mkarchroot" "${arch_nspawn_flags[@]}" "$rootdir" base-devel set -u make_empty_repo "$rootdir" fi if [[ ! -d $copydir ]] || [[ $mode == sync ]]; then msg "Syncing copy [%s] with root copy" "$COPY" - normshell chroot_sync "$CHROOTDIR/$CHROOT" "$COPY" + _makechrootpkg sync_chroot "$CHROOTDIR/$CHROOT" "$COPY" fi mkdir -p "$copydir/etc/libretools.d" { - if [[ -n ${CHROOTEXTRAPKG[@]:-} ]]; then - printf 'CHROOTEXTRAPKG=(' - printf "'%s' " "${CHROOTEXTRAPKG[@]}" - printf ')\n' + if [[ -n ${CHROOTEXTRAPKG[*]:-} ]]; then + declare -p CHROOTEXTRAPKG | sed -r 's/declare( -.)* //' else printf 'CHROOTEXTRAPKG=()\n' fi @@ -234,9 +268,8 @@ main() { # - overwrite \`/etc/pacman.d/mirrorlist'" # - set \`CacheDir' in \`/etc/pacman.conf'" # - apply -C or -M flags - set +u # if archroot_args is empty, it counts as unbound - archroot "${archroot_args[@]}" -r "$copydir" true - set -u + arch-nspawn "$copydir" true + arch_nspawn_flags=() # XXX dirty hack, don't apply -C or -M again fi ######################################################################## @@ -246,30 +279,41 @@ main() { noop|make|sync) :;; delete) if [[ -d $copydir ]]; then - normshell chroot_delete "$copydir" + _makechrootpkg delete_chroot "$copydir" "$COPY" fi ;; # Dealing with packages install-file) - normshell chroot_install_pkgs "$copydir" "$@" - normshell chroot_add_to_local_repo "$copydir" "$@" + _makechrootpkg install_packages "$copydir" "$@" + chroot_add_to_local_repo "$copydir" "$@" + ;; + install-name) + arch-nspawn "$copydir" pacman -Sy "$@" + ;; + update) + arch-nspawn "$copydir" pacman -Syu --noconfirm ;; - install-name) archroot -r "$copydir" pacman -Sy "$@";; - update) archroot -u "$copydir";; clean-pkgs) - trap "rm -f '$copydir'/clean '$copydir'/chrootexec" EXIT - cp -a "$(which chcleanup)" "$copydir/clean" - echo '#!/bin/bash' > "$copydir/chrootexec" - echo 'mkdir -p /build' >> "$copydir/chrootexec" - echo 'cd /build; /clean' >> "$copydir/chrootexec" + trap "rm -f '$copydir'/bin/chcleanup '$copydir'/chrootexec" EXIT + install -m755 "$(librelib chroot/chcleanup)" "$copydir/bin/chcleanup" + printf '%s\n' \ + '#!/bin/bash' \ + 'mkdir -p /build' \ + 'cd /build' \ + '/bin/chcleanup' \ + > "$copydir/chrootexec" chmod 755 "$copydir/chrootexec" - archroot -r "$copydir" /chrootexec + arch-nspawn "$copydir" /chrootexec ;; # Other - run) archroot -r "$copydir" "$@";; - enter) archroot -r "$copydir" bash;; + run) + arch-nspawn "$copydir" "$@" + ;; + enter) + arch-nspawn "$copydir" bash + ;; clean-repo) rm -rf "${copydir}"/repo/* make_empty_repo "$copydir" -- cgit v1.2.2