-
-
Save tai/f0baa03b5d61609e2cb6fa601574b377 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| usage() { | |
| local p=${0##*/} | |
| cat <<EOF 1>&2 | |
| $p - Run command in alternative environment | |
| Usage: [VE_BACKEND=(proot|bwrap|unshare|chroot)] $p <env> cmd args... | |
| Example: | |
| $ eval \$(ve completion) | |
| $ $p /n/hc xeyes | |
| $ $p hc xeyes | |
| $ VE_BACKEND=bwrap $p hc | |
| NOTE: | |
| - UTS hostname is kept same as host env to satisfy X auth. | |
| - File owner/groups may be different from host env. | |
| - Backend: proot is easier to use, but bwrap is more stable | |
| EOF | |
| exit 0 | |
| } | |
| gencomp() { | |
| local p=${0##*/} | |
| cat <<EOF | |
| _ve_helper() { | |
| local cur="\${COMP_WORDS[COMP_CWORD]}"; | |
| if [ \${COMP_CWORD} -eq 1 ] ; then | |
| COMPREPLY=(\$(compgen -W "\$(/bin/ls -1 /n)" "\$cur")); | |
| else | |
| COMPREPLY=(\$(compgen -o default -A file "\$cur")); | |
| fi | |
| }; | |
| complete -F _ve_helper $p | |
| EOF | |
| exit 0 | |
| } | |
| do_mark() { | |
| local key=$1 | |
| sudo mkdir -p $veroot/.ve/refs/$key | |
| } | |
| do_unmark() { | |
| local key=$1 | |
| sudo rmdir -p --ignore-fail-on-non-empty $veroot/.ve/refs/$key | |
| ! test -d $veroot/.ve/refs | |
| } | |
| do_bind() { | |
| local veroot=$1 | |
| test -e $veroot/proc/cpuinfo || sudo mount -t proc none $veroot/proc | |
| test -e $veroot/sys/kernel || sudo mount -t sysfs none $veroot/sys | |
| test -e $veroot/dev/usb || sudo mount -t devtmpfs none $veroot/dev | |
| for i in c d f t; do | |
| # skip if already mounted | |
| test $(sudo stat -c %m $veroot/$i) = "$veroot/$i" && continue | |
| $DEBUG sudo mount --rbind /$i $veroot/$i | |
| done | |
| } | |
| do_unbind() { | |
| local veroot=$1 | |
| for i in c d f t dev sys proc; do | |
| # skip if already unmounted | |
| test $(sudo stat -c %m $veroot/$i) = "$veroot/$i" || continue | |
| $DEBUG sudo umount -lf $veroot/$i | |
| done | |
| } | |
| do_unshare() { | |
| local ve=$1 veroot=$2; shift 2 | |
| # prepare bind mounts | |
| local key=$$ | |
| do_mark $key && do_bind $veroot | |
| # NOTE: | |
| # - Hostname is still parent hostname | |
| # - May have an issue with file owner/groups | |
| $DEBUG unshare -u -c -w $PWD -R $veroot "$@" | |
| do_unmark $key && do_unbind $veroot | |
| } | |
| do_chroot() { | |
| local ve=$1 veroot=$2; shift 2 | |
| # prepare bind mounts | |
| local key=$$ | |
| do_mark $key && do_bind $veroot | |
| # NOTE: | |
| # - Hostname is still parent hostname | |
| # - PWD is always / | |
| $DEBUG sudo -E chroot --userspec=$USER $veroot "$@" | |
| do_unmark $key && do_unbind $veroot | |
| } | |
| do_bwrap() { | |
| local ve=$1 veroot=$2; shift 2 | |
| # NOTE: | |
| # - May have an issue with file owner/groups | |
| # - Hostname is still parent hostname - needed to satisfy X auth | |
| $DEBUG bwrap --bind $veroot / --bind /c /c --bind /d /d --bind /f /f --bind /t /t \ | |
| --dev-bind /dev /dev --proc /proc --bind /sys /sys --chdir $PWD -- "$@" | |
| } | |
| do_proot() { | |
| local ve=$1 veroot=$2; shift 2 | |
| # NOTE: | |
| # - Hostname is still parent hostname - needed to satisfy X auth | |
| local qemu= | |
| if file -L $veroot/bin/sh | egrep -qv '(80386|x86-64)'; then | |
| for i in $veroot/usr/bin/qemu-*-static; do | |
| test -f $i && qemu="-q ${i##*/}" | |
| done | |
| fi | |
| $DEBUG proot $qemu -r $veroot -b /c -b /d -b /f -b /t -b /dev -b /sys -b /proc "$@" | |
| } | |
| run() { | |
| local ve=$1; shift | |
| local veroot=$ve | |
| # <env> can either be rootfs path or name | |
| test -d "$veroot" || veroot="/n/$ve" | |
| # Run a shell if no command is given | |
| local fallback= | |
| if [ $# -eq 0 ]; then | |
| fallback="$SHELL -l" | |
| fi | |
| do_${VE_BACKEND:=proot} $ve $veroot "$@" $fallback | |
| } | |
| test "$1" = "completion" && gencomp | |
| test $# -gt 0 || usage | |
| run "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment