#!/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 cmd=${0##*/} usage() { echo "Usage: $cmd [OPTIONS] [CHROOT] " echo 'Interacts with a chroot.' echo '' echo "The default CHROOT is \`${CHROOT}'." echo '' echo 'Options:' echo ' Settings:' 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 ' -n No-op, just make sure that the chroot exists' 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 'l:NCcI:i:nrsuh' arg; do case $arg in 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;; n) 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)) case $# in 0) :;; 1) CHROOT="$1";; *) usage; exit 1;; esac # 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 case "$mode" in clean_repo) msg "Cleaning local pacman repository" rm -rf "${copydir}/repo" mkdir "${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) msg "Intelligently cleaning packages" cp -a "$(dirname $0)/chcleanup" "${copydir}/clean" echo '#!/bin/bash' > "${copydir}/cleanstrap" echo 'mkdir /build' >> "${copydir}/cleanstrap" echo 'cd /build; /clean' >> "${copydir}/cleanstrap" chmod 755 "${copydir}/cleanstrap" archroot "${archroot_args[@]}" "${copydir}" -r /cleanstrap ;; install_file) msg "Installing package file: $ARG" cp "$ARG" "$copydir/${ARG##*/}" archroot "${archroot_args[@]}" "$copydir" -r "pacman -U /${ARG##*/} --noconfirm" rm "$copydir/${ARG##*/}" ;; install_pkg) msg "Installing package(s): $ARG" archroot "${archroot_args[@]}" "$copydir" -i $ARG ;; noop) :;; run) msg "Running command" archroot "${archroot_args[@]}" "${copydir}" -r "$ARG" ;; sync) sync;; update) msg "Updating chroot" archroot "${archroot_args[@]}" "${copydir}" -u ;; enter) msg "Entering chroot" archroot "${archroot_args[@]}" "${copydir}" -r bash ;; esac } main "$@"