#!/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 "$@"