#!/bin/bash -euE # librechroot # Copyright 2010 Nicolás Reynolds # Copyright 2011 Joshua Haase # Copyright 2012 Luke Shumaker # # 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 3 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 . . /etc/libretools.conf # This file (librechroot) is GPLv3+, but I would like to use some code # modified from devtools' "makechrootpkg", which is GPLv2. . "$(dirname "$0")/librechroot.gpl2" # This gives us the functions: # - sync cleanup=(':'); cleanup() { for cmd in "${cleanup[@]}"; do $cmd done } cmd=${0##*/} usage() { echo "Usage: $cmd [OPTIONS] " echo 'Interacts with a chroot.' echo '' echo "The default CHROOT is \`${CHROOT}'." echo '' echo 'Options:' echo ' Settings:' echo " -n Use this chroot instead of \`$CHROOT'" echo ' -l Use this as the chroot copy instead of basing it' echo ' on the username' echo ' -N Disable networking in the chroot' echo '' echo ' Modes: (the last mode given will be used)' echo ' -C Clean /repo in the chroot' echo ' -c Clean the packages installed in the chroot' echo ' -I Install the package FILE into the chroot' echo ' -i Install the package PKG from repos into the chroot' echo ' -m Make sure the chroot exists; do nothing else' echo ' -r Run CMD in the chroot' echo " -s Sync the copy with the 'root' copy" echo ' -u Update the chroot' echo ' -h Print this message' } main() { CHROOTCOPY=$LIBREUSER [[ $CHROOTCOPY != root ]] || CHROOTCOPY=copy local mode=enter local archroot_args=(-f) local ARG='' while getopts 'n:l:NCcI:i:mrsuh' arg; do case $arg in n) CHROOT=$OPTARG;; l) CHROOTCOPY=$OPTARG;; N) archroot_args+=(-N);; C) mode=clean_repo;; c) mode=clean_pacman;; I) mode=install_file; ARG=$OPTARG;; i) mode=install_pkg; ARG=$OPTARG;; m) mode=noop;; r) mode=run; ARG=$OPTARG;; s) mode=sync;; u) mode=update;; h) usage; exit 0;; *) usage; exit 1;; esac done shift $(($OPTIND - 1)) if [[ $# > 0 ]]; then usage exit 1 fi # not local rootdir="${CHROOTDIR}/${CHROOT}/root" copydir="${CHROOTDIR}/${CHROOT}/${CHROOTCOPY}" ######################################################################## if (( EUID )); then error "This script must be run as root." exit 1 fi # 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" "Locking chroot copy '$CHROOTCOPY'" if [[ ! -d $rootdir ]]; then libremkchroot "$CHROOT" fi if [[ ! -d $copydir ]] && [[ $mode != sync ]]; then sync fi ######################################################################## trap cleanup EXIT case "$mode" in clean_repo) rm -rf "${copydir}/repo/*" bsdtar -czf "${copydir}/repo/repo.db.tar.gz" -T /dev/null ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db" ;; clean_pacman) cleanup+=("rm -f '$copydir/clean' '$copydir/chrootexec'") cp -a "$(which chcleanup)" "${copydir}/clean" echo '#!/bin/bash' > "${copydir}/chrootexec" echo 'mkdir /build' >> "${copydir}/chrootexec" echo 'cd /build; /clean' >> "${copydir}/chrootexec" chmod 755 "${copydir}/chrootexec" archroot "${archroot_args[@]}" "${copydir}" -r /chrootexec ;; install_file) cleanup+=("rm '$copydir/${ARG##*/}'") cp "$ARG" "$copydir/${ARG##*/}" archroot "${archroot_args[@]}" "${copydir}" -r "pacman -U /${ARG##*/} --noconfirm" ;; install_pkg) archroot "${archroot_args[@]}" "${copydir}" -i $ARG ;; noop) :;; run) archroot "${archroot_args[@]}" "${copydir}" -r "$ARG" ;; sync) sync;; update) archroot "${archroot_args[@]}" "${copydir}" -u ;; enter) archroot "${archroot_args[@]}" "${copydir}" -r bash ;; esac } main "$@"