#!/bin/sh # -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*- prog=$( basename $0 .bash ) ROLE=base # export PATH=$PATH:/usr/local/bin . /usr/local/bin/usr_local_tput.bash # MUST be silent error () { retval=$1 ; shift; ERROR $prog $* >&2 ; exit $retval ; } usage () { echo "USAGE: $prog chroot-dir [command args] -" $* >&2 ; exit 1 ; } warn () { : ; } info () { : ; } debug () { : ; } # must be run as root [ "$( id -u )" -ne "0" ] && error 1 "must be run as root" [ -x /bin/chroot ] && EXE=/bin/chroot [ -x /usr/sbin/chroot ] && EXE=/usr/sbin/chroot # debian setcap CAP_SYS_PTRACE=+ep $EXE if [ "$#" -eq "0" ] ; then usage "give an absolute directory name as argument" fi LARGS="" CMD="" while true; do case "$1" in '-'*) LARGS="$1" shift ;; *) break ;; esac done [ -z "$LARGS" ] && LARGS="--userspec=0:0" root=$1 shift if [ ! -d "$root" ] ; then error 1 "directory not found - $root" fi # unix partition [ -d $root/lost+found ] || WARN "No $root/lost+found" # linux partition [ -e $root/usr/src/ ] || WARN "No $root/usr/src" # check for /dev/loop devices - up to 255 on android [ -e /dev/loop1 ] || \ ( cd /dev && \ for i in 0 1 2 3 4 5 6 7 ; do [ -e loop$i ] && continue mknod loop$i b 7 $i chmod 660 loop$i chgrp disk loop$i done ) cd $root || error 6 "Can't cd to $root" # sbin/boostrap_chroot.bash for file in .bashrc .bash_profile .bash_logout .emacs ; do [ -f $root/root/$file ] && continue cp -p /root/$file $root/root/ done for file in tmp usr/tmp var/tmp ; do [ -d $file ] && continue mkdir $file || error 8 " missing directory $file" chmod 1777 $file done # df /var/tmp | grep -q sd.12 || mount /var/tmp for file in proc sys dev dev/pts dev/shm usr ; do [ -d $file ] && continue mkdir $file || error 9 "Cant mkdir $file" chmod 755 $file done if false ; then [ -e proc/self ] || mount -o bind /proc $root/proc || error 10 # https://forums.gentoo.org/viewtopic-t-1061422-start-0.html [ -e dev/null ] || mount -o bind /dev $root/dev || error 11 # what happens to dev/shm ? its own memory? # required for ansible and firefox df -a | grep -q $root/dev/shm || mount -t tmpfs -o noexec,size=5% tmpfs $root/dev/shm || error 12 [ -e dev/pts/ptmx ] || \ mount -t devpts -o rw,relatime,gid=5,mode=620,ptmxmode=000 devpts $root/dev/pts || error 13 else # https://wiki.gentoo.org/wiki/Chroot [ -e dev/loop0 ] || \ { mount --rbind /dev $root/dev ; mount --make-rslave $root/dev ; } \ || error 10 mount --rbind /dev $root/dev [ -e proc/self ] || mount -t proc /proc $root/proc \ || error 11 mount -t proc /proc [ -e sys/block ] || \ { mount --rbind /sys $root/sys ; mount --make-rslave $root/sys ; } \ || error 12 --rbind /sys $root/sys df -a | grep -q $root/dev/shm || \ mount -t tmpfs -o noexec,size=5% tmpfs $root/dev/shm || error 14 $root/dev/shm df -a | grep -q $root/tmp || mount --rbind /tmp $root/tmp \ || error 13 mount --rbind /tmp $root/tmp # https://wiki.gentoo.org/wiki/Project:X86/Chroot_Guide [ -e dev/pts/ptmx ] || \ mount -o bind /dev/pts $root/dev/pts || error 14 mount -o bind /dev/pts $root/dev/pts fi # user if [ -d $root/$HOME -a -f ~/.Xauthority ] ; then cp ~/.Xauthority $root/$HOME cp ~/.xauth* $root/$HOME fi base=$( basename $root ) [ -e ./start.rc ] || cat > ./start.rc << EOF # env-update && . /etc/profile export PS1='\${tty}\\u@${base}:\\W\\$ ' EOF [ -z "$DISPLAY" ] || grep -q DISPLAY ./start.rc || \ echo export DISPLAY=\"$DISPLAY\" >> ./start.rc # openpty failed: 'out of pty devices' # root@Flati:11# d /dev/pts/ # total 6 # 2 ./ 4 ../ # You'll also want to copy over resolv.conf in order to have proper DNS name # resolution from inside the chroot: cp -L /etc/resolv.conf etc || error 16 "Cant cp -L /etc/resolv.conf" EARGS="CHROOT=$root PATH=/usr/sbin:/usr/bin:/sbin:/bin" #? set these to root or derive them? what about -l? EELTS="$EELTS TERM DISPLAY HOME LANG LC_ALL" [ -z "$LC_COLLATE" ] && EELTS="$EELTS LC_COLLATE" || EARGS="$EARGS LC_COLLATE=C" . /usr/local/bin/proxy_export.bash >/dev/null EELTS="$EELTS http_proxy https_proxy socks_proxy no_proxy" for elt in $EELTS ; do EARGS="$EARGS $( env|grep ^${elt}= )" done # mesg: ttyname failed: Success tty=$( tty 2>/dev/null ) [ $? -eq 0 -a -n "$tty" ] && EARGS="$EARGS TTY=$tty" # was /bin/bash -l [ "$#" -eq 0 ] && set -- /bin/bash -i -l # Now you can chroot into your new system. Use env before chroot to ensure that no # environment variables from the installation media are used by your new system: #? PATH=$PATH # info chroot $LARGS $root /usr/bin/env -i $EARGS "$@" exec $EXE $LARGS $root /usr/bin/env -i $EARGS "$@"