summaryrefslogtreecommitdiff
path: root/src/chroot-tools/librechroot
diff options
context:
space:
mode:
Diffstat (limited to 'src/chroot-tools/librechroot')
-rwxr-xr-xsrc/chroot-tools/librechroot230
1 files changed, 230 insertions, 0 deletions
diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot
new file mode 100755
index 0000000..45aec10
--- /dev/null
+++ b/src/chroot-tools/librechroot
@@ -0,0 +1,230 @@
+#!/bin/bash -euE
+# librechroot
+
+# Copyright 2010 Nicolás Reynolds
+# Copyright 2011 Joshua Haase
+# Copyright 2012-2013 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 <http://www.gnu.org/licenses/>.
+
+. /usr/share/libretools/conf.sh
+load_conf_libretools_chroot
+
+. libremessages
+. /usr/share/devtools/makechrootpkg.sh
+
+# Because the makechrootpkg.sh library functions don't work with -euE
+normshell() (
+ set +euE
+ "$@"
+)
+
+cmd=${0##*/}
+usage() {
+ 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:'
+ echo " - overwrite \`/etc/libretools.d/chroot.conf'"
+ 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 ' -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 '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() {
+ COPY=$LIBREUSER
+ [[ $COPY != root ]] || COPY=copy
+
+ # defaults
+ rootdir="${CHROOTDIR}/${CHROOT}/root"
+ copydir="${CHROOTDIR}/${CHROOT}/${COPY}"
+
+ local mode=enter
+ local archroot_args=()
+ while getopts 'n:l:NC:M:' arg; do
+ case $arg in
+ n) CHROOT=$OPTARG;;
+ 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 [[ $# < 1 ]]; then
+ error "Must specify a command"
+ usage
+ return 1
+ fi
+ mode=$1
+ shift
+
+ rootdir="${CHROOTDIR}/${CHROOT}/root"
+ 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 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 chroot copy to be released: [$COPY]"
+
+ if [[ ! -d $rootdir ]]; then
+ msg "Creating 'root' copy for chroot [$CHROOT]"
+ set +u # if archroot_args is empty, it counts as unbound
+ archroot "${archroot_args[@]}" -m "$rootdir" base-devel
+ set -u
+ fi
+
+ if [[ ! -d $copydir ]] || [[ $mode == sync ]]; then
+ msg "Syncing copy [$COPY] with root copy"
+ normshell chroot_sync "$CHROOTDIR/$CHROOT" "$COPY"
+ fi
+
+ mkdir -p "$copydir/etc/libretools.d"
+ {
+ if [[ -n ${CHROOTEXTRAPKG[@]:-} ]]; then
+ printf 'CHROOTEXTRAPKG=('
+ printf "'%s' " "${CHROOTEXTRAPKG[@]}"
+ printf ')\n'
+ else
+ printf 'CHROOTEXTRAPKG=()\n'
+ fi
+ } > "$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
+ set +u # if archroot_args is empty, it counts as unbound
+ archroot "${archroot_args[@]}" -r "$copydir" true
+ set -u
+ fi
+
+ ########################################################################
+
+ case "$mode" in
+ # 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"
+ ;;
+ *)
+ error "Unrecognized command: \`$mode'"
+ return 1
+ ;;
+ esac
+}
+
+main "$@"