kiss/contrib/kiss-chroot

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"