summaryrefslogtreecommitdiff
path: root/src/chroot-tools/librechroot
diff options
context:
space:
mode:
Diffstat (limited to 'src/chroot-tools/librechroot')
-rwxr-xr-xsrc/chroot-tools/librechroot128
1 files changed, 86 insertions, 42 deletions
diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot
index e82b18c..e5ca1f7 100755
--- a/src/chroot-tools/librechroot
+++ b/src/chroot-tools/librechroot
@@ -25,18 +25,26 @@
# - the commands=() array
# - the case statement in main()
-. $(librelib conf.sh)
+. $(librelib conf)
load_files chroot
. libremessages
-. $(librelib makechrootpkg)
+
+shopt -s nullglob
+umask 0022
+
+readonly _arch_nspawn=$(librelib chroot/arch-nspawn)
+readonly _mkarchroot=$(librelib chroot/mkarchroot)
+readonly _makechrootpkg=$(librelib chroot/makechrootpkg.sh)
# Because the makechrootpkg.sh library functions don't work with -euE
-normshell() (
+_makechrootpkg() (
set +euE
+ . "$_makechrootpkg"
"$@"
)
+# Usage: make_empty_repo $copydir
make_empty_repo() {
local copydir=$1
mkdir -p "${copydir}/repo"
@@ -44,8 +52,21 @@ make_empty_repo() {
ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db"
}
+# Usage: chroot_add_to_local_repo $copydir $pkgfiles...
+chroot_add_to_local_repo() {
+ local copydir=$1; shift
+ mkdir -p "$copydir/repo"
+ local pkgfile
+ for pkgfile in "$@"; do
+ cp "$pkgfile" "$copydir/repo"
+ pushd "$copydir/repo" >/dev/null
+ repo-add repo.db.tar.gz "${pkgfile##*/}"
+ popd >/dev/null
+ done
+}
+
usage() {
- calculate_directories
+ eval "$(calculate_directories)"
print "Usage: %s [OPTIONS] COMMAND [ARGS...]" "${0##*/}"
print 'Interacts with an archroot (arch chroot).'
echo
@@ -99,6 +120,8 @@ usage() {
flag '-N' 'Disable networking in the chroot'
flag "-C <$(_ FILE)>" 'Copy this file to `$copydir/etc/pacman.conf`'
flag "-M <$(_ FILE)>" 'Copy this file to `$copydir/etc/makepkg.conf`'
+ flag "-w <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read/write'
+ flag "-r <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read-only'
echo
print 'Commands:'
print ' Create/copy/delete:'
@@ -120,7 +143,7 @@ usage() {
flag 'clean-repo' 'Clean /repo in the chroot copy'
flag 'help' 'Show this message'
}
-commands=(
+readonly commands=(
noop make sync delete
install-file install-name update clean-pkgs
run enter clean-repo help
@@ -130,6 +153,7 @@ commands=(
calculate_directories() {
# Don't assume that CHROOTDIR or CHROOT are set,
# but assume that COPY is set.
+ local rootdir copydir
if [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then
rootdir="${CHROOTDIR}/${CHROOT}/root"
@@ -144,6 +168,18 @@ calculate_directories() {
else
copydir=''
fi
+
+ declare -p rootdir
+ declare -p copydir
+}
+
+arch_nspawn_flags=()
+sysd_nspawn_flags=()
+arch-nspawn() {
+ local copydir=$1; shift
+ set +u # if an array is empty, it counts as unbound
+ "$_arch_nspawn" "${arch_nspawn_flags[@]}" "$copydir" "${sysd_nspawn_flags[@]}" -- "$@"
+ set -u
}
# Globals: $CHROOTDIR, $CHROOT, $COPY, $rootdir and $copydir
@@ -152,19 +188,14 @@ main() {
[[ $COPY != root ]] || COPY=copy
local mode=enter
- local archroot_args=()
- while getopts 'n:l:NC:M:' arg; do
- case $arg in
+ while getopts 'n:l:NC:M:w:r:' opt; do
+ case $opt 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");;
+ N) sysd_nspawn_flags+=(--private-network);;
+ C|M) arch_nspawn_flags+=(-$opt "$OPTARG");;
+ w) sysd_nspawn_flags+=("--bind=$OPTARG");;
+ r) sysd_nspawn_flags+=("--bind-ro=$OPTARG");;
*) usage >/dev/stderr; return 1;;
esac
done
@@ -188,7 +219,12 @@ main() {
fi
check_vars chroot CHROOTDIR CHROOT
- calculate_directories
+ eval "$(calculate_directories)"
+
+ readonly LIBREUSER LIBREHOME
+ readonly CHROOTDIR CHROOT COPY
+ readonly rootdir copydir
+ readonly mode
########################################################################
@@ -200,29 +236,27 @@ main() {
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" \
+ # Note that '9' is the same FD number as in mkarchroot et al.
+ lock 9 "$copydir.lock" \
"Waiting for existing lock on chroot copy to be released: [%s]" "$COPY"
if [[ ! -d $rootdir ]]; then
msg "Creating 'root' copy for chroot [%s]" "$CHROOT"
- set +u # if archroot_args is empty, it counts as unbound
- archroot "${archroot_args[@]}" -m "$rootdir" base-devel
+ set +u # if an array is empty, it counts as unbound
+ "$_mkarchroot" "${arch_nspawn_flags[@]}" "$rootdir" base-devel
set -u
make_empty_repo "$rootdir"
fi
if [[ ! -d $copydir ]] || [[ $mode == sync ]]; then
msg "Syncing copy [%s] with root copy" "$COPY"
- normshell chroot_sync "$CHROOTDIR/$CHROOT" "$COPY"
+ _makechrootpkg sync_chroot "$CHROOTDIR/$CHROOT" "$COPY"
fi
mkdir -p "$copydir/etc/libretools.d"
{
- if [[ -n ${CHROOTEXTRAPKG[@]:-} ]]; then
- printf 'CHROOTEXTRAPKG=('
- printf "'%s' " "${CHROOTEXTRAPKG[@]}"
- printf ')\n'
+ if [[ -n ${CHROOTEXTRAPKG[*]:-} ]]; then
+ declare -p CHROOTEXTRAPKG | sed -r 's/declare( -.)* //'
else
printf 'CHROOTEXTRAPKG=()\n'
fi
@@ -234,9 +268,8 @@ main() {
# - 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
+ arch-nspawn "$copydir" true
+ arch_nspawn_flags=() # XXX dirty hack, don't apply -C or -M again
fi
########################################################################
@@ -246,30 +279,41 @@ main() {
noop|make|sync) :;;
delete)
if [[ -d $copydir ]]; then
- normshell chroot_delete "$copydir"
+ _makechrootpkg delete_chroot "$copydir" "$COPY"
fi
;;
# Dealing with packages
install-file)
- normshell chroot_install_pkgs "$copydir" "$@"
- normshell chroot_add_to_local_repo "$copydir" "$@"
+ _makechrootpkg install_packages "$copydir" "$@"
+ chroot_add_to_local_repo "$copydir" "$@"
+ ;;
+ install-name)
+ arch-nspawn "$copydir" pacman -Sy "$@"
+ ;;
+ update)
+ arch-nspawn "$copydir" pacman -Syu --noconfirm
;;
- install-name) archroot -r "$copydir" pacman -Sy "$@";;
- update) archroot -u "$copydir";;
clean-pkgs)
- trap "rm -f '$copydir'/clean '$copydir'/chrootexec" EXIT
- cp -a "$(which chcleanup)" "$copydir/clean"
- echo '#!/bin/bash' > "$copydir/chrootexec"
- echo 'mkdir -p /build' >> "$copydir/chrootexec"
- echo 'cd /build; /clean' >> "$copydir/chrootexec"
+ trap "rm -f '$copydir'/bin/chcleanup '$copydir'/chrootexec" EXIT
+ install -m755 "$(librelib chroot/chcleanup)" "$copydir/bin/chcleanup"
+ printf '%s\n' \
+ '#!/bin/bash' \
+ 'mkdir -p /build' \
+ 'cd /build' \
+ '/bin/chcleanup' \
+ > "$copydir/chrootexec"
chmod 755 "$copydir/chrootexec"
- archroot -r "$copydir" /chrootexec
+ arch-nspawn "$copydir" /chrootexec
;;
# Other
- run) archroot -r "$copydir" "$@";;
- enter) archroot -r "$copydir" bash;;
+ run)
+ arch-nspawn "$copydir" "$@"
+ ;;
+ enter)
+ arch-nspawn "$copydir" bash
+ ;;
clean-repo)
rm -rf "${copydir}"/repo/*
make_empty_repo "$copydir"