forked from kiss-community/kiss
c6c851b645
If the chroot is exited with nonzero status, kiss-chroot runs `die chroot failed`. Then, die runs `exit 1` which causes the trap to execute. However, in this scope, "$@" is "chroot failed", so the trap evaluates $1 to be "chroot" rather than the mountpoint given to the kiss-chroot script. Then, the trap tries to unmount "chroot/dev" etc rather than the true mountpoint. This patch uses double quotes rather than single when setting the trap, so that $1 is expanded then and the mountpoint is stored for when the trap is called.
95 lines
2.4 KiB
Bash
Executable File
95 lines
2.4 KiB
Bash
Executable File
#!/bin/sh
|
|
# Enter a kiss chroot
|
|
|
|
log() {
|
|
printf '\033[32m->\033[m %s.\n' "$*"
|
|
}
|
|
|
|
die() {
|
|
log "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
run() {
|
|
printf '%s\n' "$*"
|
|
"$@" || return "${_ret:=0}"
|
|
}
|
|
|
|
clean() {
|
|
log Unmounting host paths; {
|
|
run umount "$1/dev/shm" 2>/dev/null
|
|
run umount "$1/dev/pts"
|
|
run umount "$1/dev"
|
|
run umount "$1/proc"
|
|
run umount "$1/run"
|
|
run umount "$1/sys/firmware/efi/efivars" 2>/dev/null
|
|
run umount "$1/sys"
|
|
run umount "$1/tmp"
|
|
run umount "$1/etc/resolv.conf"
|
|
}
|
|
}
|
|
|
|
mounted() {
|
|
# This is a pure shell mountpoint implementation. We're dealing
|
|
# with basic (and fixed/known) input so this doesn't need to
|
|
# handle more complex cases.
|
|
[ -e "$1" ] || return 1
|
|
[ -e /proc/mounts ] || return 1
|
|
|
|
while read -r _ target _; do
|
|
[ "$target" = "$1" ] && return 0
|
|
done < /proc/mounts
|
|
|
|
return 1
|
|
}
|
|
|
|
mmount() {
|
|
dest=$1
|
|
shift
|
|
mounted "$dest" || run mount "$@" "$dest"
|
|
}
|
|
|
|
main() {
|
|
# Ensure input does not end in '/'.
|
|
set -- "${1%"${1##*[!/]}"}"
|
|
|
|
[ "$1" ] || die Need a path to the chroot
|
|
[ -d "$1" ] || die Given path does not exist
|
|
[ "$(id -u)" = 0 ] || die Script needs to be run as root
|
|
|
|
# Intended behaviour.
|
|
# shellcheck disable=SC2064
|
|
trap "clean ${1%"${1##*[!/]}"}" EXIT INT
|
|
|
|
log Mounting host paths; {
|
|
mmount "$1/dev" -o bind /dev
|
|
mmount "$1/dev/pts" -o bind /dev/pts
|
|
mmount "$1/dev/shm" -t tmpfs shmfs 2>/dev/null
|
|
mmount "$1/proc" -t proc proc
|
|
mmount "$1/run" -t tmpfs tmpfs
|
|
mmount "$1/sys" -t sysfs sys
|
|
mmount "$1/sys/firmware/efi/efivars" -t efivarfs efivarfs 2>/dev/null
|
|
mmount "$1/tmp" -o mode=1777,nosuid,nodev -t tmpfs tmpfs
|
|
|
|
touch "$1/etc/resolv.conf"
|
|
mmount "$1/etc/resolv.conf" -o bind /etc/resolv.conf
|
|
}
|
|
|
|
log Entering chroot; {
|
|
_ret=1
|
|
|
|
run chroot "$1" /usr/bin/env -i \
|
|
HOME=/root \
|
|
TERM="$TERM" \
|
|
SHELL=/bin/sh \
|
|
USER=root \
|
|
LOGNAME=root \
|
|
CFLAGS="${CFLAGS:--march=x86-64 -mtune=generic -pipe -O2}" \
|
|
CXXFLAGS="${CXXFLAGS:--march=x86-64 -mtune=generic -pipe -O2}" \
|
|
MAKEFLAGS="${MAKEFLAGS:--j$(nproc 2>/dev/null || echo 1)}" \
|
|
/bin/sh -l
|
|
} || die chroot failed
|
|
}
|
|
|
|
main "$1"
|