summaryrefslogtreecommitdiff
path: root/src/chroot-tools/librechroot
diff options
context:
space:
mode:
Diffstat (limited to 'src/chroot-tools/librechroot')
-rwxr-xr-xsrc/chroot-tools/librechroot208
1 files changed, 134 insertions, 74 deletions
diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot
index 7f113f5..368ecc1 100755
--- a/src/chroot-tools/librechroot
+++ b/src/chroot-tools/librechroot
@@ -3,7 +3,7 @@
# Copyright 2010 Nicolás Reynolds
# Copyright 2011 Joshua Haase
-# Copyright 2012 Luke Shumaker
+# Copyright 2012-2013 Luke Shumaker
#
# This file is part of Parabola.
#
@@ -23,20 +23,41 @@
. /usr/share/libretools/conf.sh
load_conf_libretools_chroot
-. "$(which libremessages)"
+. libremessages
. /usr/share/devtools/makechrootpkg.sh
-cleanup=(':');
-cleanup() {
- for cmd in "${cleanup[@]}"; do
- $cmd
- done
-}
+# Because the makechrootpkg.sh library functions don't work with -euE
+normshell() (
+ set +euE
+ "$@"
+)
cmd=${0##*/}
usage() {
- echo "Usage: $cmd [OPTIONS] "
- echo 'Interacts with a chroot.'
+ echo "Usage: $cmd [OPTIONS] COMMAND [ARGS...]"
+ echo 'Interacts with an archroot (arch chroot).'
+ echo ''
+ echo 'There may be multiple chroots; they are stored in $CHROOTDIR.'
+ echo ''
+ echo 'Each chroot is named; the default is configured with $CHROOT.'
+ echo ''
+ echo "Each named chroot has a master clean copy (named 'root'), and any"
+ echo 'number of other named copies; the copy used by default is the'
+ echo "current username (or \$SUDO_USER, or 'copy' if root)."
+ echo ''
+ echo 'The full path to the chroot copy is "$CHROOTDIR/$CHROOT/$COPY",'
+ echo 'Unless the copy name is manually specified as an absolute path,'
+ echo 'in which case, that path is used.'
+ echo ''
+ echo 'The current settings for the above varibles are:'
+ echo " CHROOTDIR : $CHROOTDIR"
+ echo " CHROOT : $CHROOT"
+ echo " COPY : $COPY"
+ echo " root path : $rootdir"
+ echo " copy path : $copydir"
+ echo ''
+ echo 'If the chroot, or copy does not exist, it will be created'
+ echo 'automatically.'
echo ''
echo 'This command will make the following configuration changes in'
echo 'the chroot:'
@@ -44,81 +65,104 @@ usage() {
echo " - overwrite \`/etc/pacman.d/mirrorlist'"
echo " - set \`CacheDir' in \`/etc/pacman.conf'"
echo ''
+ echo 'Creating a copy, deleting a copy, or syncing a copy can be fairly'
+ echo 'slow; but are very fast if $CHROOTDIR is on a btrfs partition.'
+ echo ''
echo 'Options:'
- echo ' Settings:'
- echo " -n <CHROOT> Use this chroot instead of \`$CHROOT'"
- echo " -l <COPY> Use this chroot copy instead \`$CHROOTCOPY'"
+ echo ' -n <CHROOT> Name of the chroot to use'
+ echo ' -l <COPY> Name of, or absolute path to, the copy to use'
echo ' -N Disable networking in the chroot'
+ echo ' -C <file> Location of pacman config file'
+ echo ' -M <file> Location of makepkg config file'
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 <FILE> Install the package FILE into the chroot'
- echo ' -i <PKG> Install the package PKG from repos into the chroot'
- echo ' -m Make sure the chroot exists; do nothing else'
- echo ' -r <CMD> Run CMD in the chroot'
- echo " -s Sync the copy with the \`root' copy"
- echo ' -u Update the chroot'
- echo ' -h Show this message'
+ echo 'Commands:'
+ echo ' Create/copy/delete:'
+ echo ' noop|make Do not do anything, but still creates the'
+ echo ' chroot copy if it does not exist'
+ echo " sync Sync the copy with the clean ('root') copy"
+ echo " delete delete the chroot copy"
+ echo ' Dealing with packages:'
+ echo ' install-file FILES... Like `pacman -U FILES...`'
+ echo ' install-name NAMES... Like `pacman -S NAMES...`'
+ echo ' update Like `pacman -Syu`'
+ echo ' clean-pkgs Remove all "exta" packages from the chroot copy'
+ echo ' Other:'
+ echo ' run CMD... Run CMD in the chroot copy'
+ echo ' enter Enter an interactive shell in the chroot copy'
+ echo ' clean-repo Clean /repo in the chroot copy'
+ echo ' help Show this message' # usage
}
+# Globals: $CHROOTDIR, $CHROOT, $COPY, $rootdir and $copydir
main() {
- CHROOTCOPY=$LIBREUSER
- [[ $CHROOTCOPY != root ]] || CHROOTCOPY=copy
+ COPY=$LIBREUSER
+ [[ $COPY != root ]] || COPY=copy
+
+ # defaults
+ rootdir="${CHROOTDIR}/${CHROOT}/root"
+ copydir="${CHROOTDIR}/${CHROOT}/${COPY}"
local mode=enter
- local archroot_args=(-f)
- local ARG=''
- while getopts 'n:l:NCcI:i:mr:suh' arg; do
+ local archroot_args=() # not local
+ while getopts 'n:l:NC:M:' 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;;
+ 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");;
+ *) usage; return 1;;
esac
done
shift $(($OPTIND - 1))
- if [[ $# > 0 ]]; then
+ if [[ $# < 1 ]]; then
+ error "Must specify a command"
usage
- exit 1
+ return 1
fi
+ mode=$1
+ shift
- # not local
rootdir="${CHROOTDIR}/${CHROOT}/root"
- copydir="${CHROOTDIR}/${CHROOT}/${CHROOTCOPY}"
+ if [[ ${COPY:0:1} = / ]]; then
+ copydir=$COPY
+ else
+ copydir="${CHROOTDIR}/${CHROOT}/${COPY}"
+ fi
########################################################################
+ if [[ $mode == help ]]; then
+ usage
+ return 0
+ fi
+
if (( EUID )); then
- error "This script must be run as root."
- exit 1
+ error "This program must be run as root."
+ return 1
fi
+ 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" \
"Waiting for existing lock on \`$copydir' to be released"
if [[ ! -d $rootdir ]]; then
- libremkchroot "$CHROOT"
+ archroot "${archroot_args[@]}" -m "$rootdir"
fi
- if [[ ! -d $copydir ]] && [[ $mode != sync ]]; then
- chroot_sync
+ if [[ ! -d $copydir ]] || [[ $mode == sync ]]; then
+ normshell chroot_sync "$CHROOTDIR/$CHROOT" "$COPY"
fi
- mkdir -p $copydir/etc/libretools.d
+ mkdir -p "$copydir/etc/libretools.d"
{
if [[ -n ${CHROOTEXTRAPKG[@]:-} ]]; then
printf 'CHROOTEXTRAPKG=('
@@ -127,37 +171,53 @@ main() {
else
printf 'CHROOTEXTRAPKG=()\n'
fi
- } > $copydir/etc/libretools.d/chroot.conf
+ } > "$copydir"/etc/libretools.d/chroot.conf
+
+ if [[ $mode != delete ]]; then
+ # "touch" the chroot first
+ # this will
+ # - overwrite \`/etc/pacman.d/mirrorlist'"
+ # - set \`CacheDir' in \`/etc/pacman.conf'"
+ # - apply -C or -M flags
+ archroot "${archroot_args[@]}" -r "$copydir" true
+ fi
########################################################################
- trap cleanup EXIT
case "$mode" in
- clean_repo)
+ # Creat/copy/delete
+ noop|make|sync) :;;
+ delete)
+ if [[ -d $copydir ]]; then
+ normshell chroot_delete "$copydir"
+ fi
+ ;;
+
+ # Dealing with packages
+ install-file) normshell chroot_install_pkgs "$copydir" "$@";;
+ install-name) archroot -r "$copydir" pacman -Sy "$@";;
+ clean-pkgs)
+ trap "rm -f '$copydir'/clean '$copydir'/chrootexec" EXIT
+ 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 -r "$copydir" /chrootexec
+ ;;
+
+ # Other
+ run) archroot -r "$copydir" "$@";;
+ enter) archroot -r "$copydir" bash;;
+ 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"
+ *)
+ error "Unrecognized command: \`$mode'"
+ return 1
;;
- install_pkg) archroot "${archroot_args[@]}" "${copydir}" -i $ARG ;;
- noop) :;;
- run) archroot "${archroot_args[@]}" "${copydir}" -r "$ARG" ;;
- sync) chroot_sync;;
- update) archroot "${archroot_args[@]}" "${copydir}" -u ;;
- enter) archroot "${archroot_args[@]}" "${copydir}" -r bash ;;
esac
}