#!/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 function is almost verbatim from makechrootpkg ## sync() { if [[ $CHROOTCOPY = root ]]; then error "Cannot sync the root copy with itself" exit 1 fi lock_open_read 8 "$rootdir" "Locking clean chroot" stat_busy 'Creating clean working copy' local use_rsync=false if type -P btrfs >/dev/null; then [[ -d $copydir ]] && btrfs subvolume delete "$copydir" &>/dev/null btrfs subvolume snapshot "$chrootdir/root" "$copydir" &>/dev/null || use_rsync=true else use_rsync=true fi if $use_rsync; then mkdir -p "$copydir" rsync -a --delete -q -W -x "$CHROOTDIR/$CHROOT/root/" "$copydir" fi stat_done lock_close 8 } 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=() 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 '$copy'" 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" mkdir -p "$copydir/build" archroot "${archroot_args[@]}" "${copydir}" -r "cd /build; /clean" ;; 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 "$@"