summaryrefslogtreecommitdiff
path: root/src/chroot-tools/librechroot
diff options
context:
space:
mode:
Diffstat (limited to 'src/chroot-tools/librechroot')
-rwxr-xr-xsrc/chroot-tools/librechroot119
1 files changed, 101 insertions, 18 deletions
diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot
index d53448a..1c9700c 100755
--- a/src/chroot-tools/librechroot
+++ b/src/chroot-tools/librechroot
@@ -27,35 +27,107 @@
cmd=${0##*/}
-clean_chroot() { # Clean packages with pacman
- msg "Cleaning chroot with pacman: ${chroot_path}"
+lock_open_write() {
+ local fd=$1
+ local path=$2
+ local msg=$3
+
+ # Only reopen the FD if it wasn't handed to us
+ if [[ $(readlink -f /dev/fd/$fd) != "${path}.lock" ]]; then
+ exec $fd>"${path}.lock"
+ fi
+
+ if ! flock -n $fd; then
+ stat_busy "$msg"
+ flock $fd
+ stat_done
+ fi
+}
+
+lock_open_read() {
+ local fd=$1
+ local path=$2
+ local msg=$3
+
+ # Only reopen the FD if it wasn't handed to us
+ if [[ $(readlink -f /dev/fd/$fd) != "${path}.lock" ]]; then
+ exec $fd>"${path}.lock"
+ fi
- cp -a "$(dirname $0)/chcleanup" "${chroot_path}/clean"
- mkarchroot -r "cd /build; /clean" "${chroot_path}"
+ if ! flock -sn $fd; then
+ stat_busy "$msg"
+ flock -s $fd
+ stat_done
+ fi
+}
- #mkarchroot "${chroot_path}" base base-devel sudo "${CHROOTEXTRAPKG[@]}"
+lock_close() {
+ local fd=$1
+ exec $fd>&-
+}
+
+clean_pacman() {
+ msg "Cleaning chroot with pacman: ${copydir}"
+
+ cp -a "$(dirname $0)/chcleanup" "${copydir}/clean"
+ mkarchroot -r "cd /build; /clean" "${copydir}"
+
+ #mkarchroot "${copydir}" base base-devel sudo "${CHROOTEXTRAPKG[@]}"
}
clean_repo() {
- msg "Cleaning repo for chroot: ${chroot_path}"
+ msg "Cleaning repo for chroot: ${copydir}"
+
+ if [ -d "${copydir}/repo" ]; then
+ find "${copydir}/repo/" -mindepth 1 -delete
+ else
+ mkdir -p "${copydir}/repo"
+ fi
+ bsdtar -czf "${copydir}/repo/repo.db.tar.gz" -T /dev/null
+ ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db"
+}
+
+##
+# This function is almost verbatim from makechrootpkg
+##
+sync() {
+ if [[ $CHROOTCOPY = root ]]; then
+ error "Cannot sync the root copy with itself"
+ exit 1
+ fi
+
+ # Note that '9' is the same FD number as in mkarchroot
+ lock_open_write 9 "$copydir" "Locking chroot copy '$copy'"
+ lock_open_read 8 "$rootdir" "Locking clean chroot"
- if [ -d "${chroot_path}/repo" ]; then
- find "${chroot_path}/repo/" -mindepth 1 -delete
+ 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
- mkdir -p "${chroot_path}/repo"
+ use_rsync=true
fi
- bsdtar -czf "${chroot_path}/repo/repo.db.tar.gz" -T /dev/null
- ln -s "repo.db.tar.gz" "${chroot_path}/repo/repo.db"
+
+ if $use_rsync; then
+ mkdir -p "$copydir"
+ rsync -a --delete -q -W -x "$CHROOTDIR/$CHROOT/root/" "$copydir"
+ fi
+ stat_done
+
+ lock_close 8
+ lock_close 9
}
update() {
- msg "Updating chroot: ${chroot_path}"
- mkarchroot -u "${chroot_path}"
+ msg "Updating chroot: ${copydir}"
+ mkarchroot -u "${copydir}"
}
enter() {
- msg "Entering chroot: ${chroot_path}"
- mkarchroot -r "bash" "${chroot_path}"
+ msg "Entering chroot: ${copydir}"
+ mkarchroot -r "bash" "${copydir}"
}
usage() {
@@ -72,6 +144,7 @@ usage() {
echo ' Modes:'
echo ' -h Show this message'
echo ' -c Clean the chroot using pacman'
+ echo " -C Clean the chroot by syncing it with 'root' copy"
echo ' -r Clean /repo in the chroot'
echo ' -u Update the chroot'
}
@@ -88,7 +161,8 @@ main() {
d) CHROOTDIR=$OPTARG;;
l) CHROOTCOPY=$OPTARG;;
- c) mode=clean_chroot;;
+ c) mode=clean_pacman;;
+ C) mode=sync;;
r) mode=clean_repo;;
u) mode=update;;
@@ -104,15 +178,24 @@ main() {
esac
# not local
- chroot_path="${CHROOTDIR}/${CHROOT}/${CHROOTCOPY}"
+ rootdir="${CHROOTDIR}/${CHROOT}/root"
+ copydir="${CHROOTDIR}/${CHROOT}/${CHROOTCOPY}"
if (( EUID )); then
error "This script must be run as root."
exit 1
fi
+ if [[ ! -d $rootdir ]]; then
+ libremkchroot -d "$CHROOTDIR" "$CHROOT"
+ fi
+
+ if [[ ! -d $copydir ]] && [[ $mode != sync ]]; then
+ sync
+ fi
+
case "$mode" in
- clean_chroot) clean_chroot; exit $?;;
+ clean_pacman) clean_pacman; exit $?;;
clean_repo) clean_repo; exit $?;;
update) update; exit $?;;
enter) enter; exit $?;;