#!/bin/bash
#-t --tmpfs path to temporary save file
#-r --root Parent directory to the new rootfs. Only applied to options which are to the right of this option.
#-f --fake-root This is the location where the fake (or new) rootfs will be mounted.
#-n --new-root See: -f --fake-root
# This is a subdirectory of the -r|--root option when the -r --root option is applied to the left of this argument
unset SANDBOX_ID
unset rwbranch
unset FAKEROOT
unset SANDBOX_TMPFS
unset FAKEROOT_dir
unset SANDBOX_IMG
FAKEROOT_SET=false
#SANDBOX_ROOT=/mnt/sb
unset SANDBOX_ROOT
# [ -z "$TMPFILE" ] && TMPFILE=$(mktemp -p /tmp)
TMPFILE=$(mktemp -p /tmp)
trap 'umountall' 1
function log(){
local logfile="${2}"
local trace="$3"
#[ -z "$logfile" ] && LOGFILE
#[ -z "$trace" ] && trace=TRACE
if [ ! -z "$LOGFILE" ]; then
case "$1" in
init)
[ "$TRACE" = true ] && set -x
[ ! -z "$LOGFILE" ] && rm "$LOGFILE"
exec 6>&1 # Link file descriptor #6 with stdout.
#exec &1> >(tee -a "$LOGFILE")
#exec &2> >(tee -a "$LOGFILE")
exec &> >(tee -a "$LOGFILE")
;;
start)
[ "$TRACE" = true ] && set -x
#exec &1> >(tee -a "$LOGFILE")
#exec &2> >(tee -a "$LOGFILE")
exec &> >(tee -a "$LOGFILE")
;;
stop)
#https://stackoverflow.com/questions/21106465/restoring-stdout-and-stderr-to-default-value
[ "$TRACE" = true ] && set +x
exec 1>&6 #See https://tldp.org/LDP/abs/html/x17974.html
#exec 6>&- # Restore stdout and close file descriptor #6.
exec &2> /dev/stderr
;;
esac
fi
}
declare -a del_rules_filter
declare -a del_rules_action
declare -a umount_rules_filter
declare -a umount_rules_action
safe_delete(){
unset safe_delete_result
POLICY="" #Default action if no rule is found
if [ ! -z "$(cat /proc/mounts | grep -F "$(ls -1d $1 | sed 's:/$::')" - )" ] ||
[ ! -z "$(cat /proc/mounts | grep -F "$(ls -1d $1 | xargs realpath )" - )" ] ; then
#It is not safe to delete a mounted directory
safe_delete_result=1 #This is in case one doesn't want to use the return status right away
return 1
else
PATH_TO_DEL="$(realpath -m $1)"
[ -d "$PATH_TO_DEL" ] && "PATH_TO_DEL=$PATH_TO_DEL/"
for a_rule_key in "${!del_rules_filter[@]}"; do
rule_i="${a_rull_key[$a_rule_key]}"
if [ ! -z "$(echo $PATH_TO_DEL | grep "$rule_i")" ] ||
[[ "$PATH_TO_DEL" = $rule_i ]]; then
action="${del_rules_action[$a_rule_key]}"
case $action in
DELETE)
safe_delete_result=0 #This is in case one doesn't want to use the return status right away
return 0
break #This is probably redundant
;;
KEEP)
safe_delete_result=1 #This is in case one doesn't want to use the return status right away
return 1
break #This is probably redundant
;;
POLICY_KEEP)
POLICY=KEEP
;;
POLICY_DELETE)
POLICY=DELETE
;;
esac
fi
done
if [ -z ${safe_delete_result+x} ]; then #If we don't have a result yet set result based on policy
case "$POLICY" in
KEEP)
safe_delete_result=1
return 1; ;;
DELETE)
safe_delete_result=0
return 0; ;;
*)
echo "No Delete policy set, so keeping file/dir $1"
safe_delete_result=1
return 1
esac
fi
fi
}
safe_umount(){
unset safe_umount_result
POLICY="" #Default action if no rule is found
PATH_TO_UMOUNT="$(realpath -m $1)"
[ -d "$PATH_TO_UMOUNT" ] && PATH_TO_UMOUNT="$PATH_TO_UMOUNT/" #TODO, this should always be true so add error if it is not.
for a_rule_key in "${!umount_rules_filter[@]}"; do
rule_i="${a_rull_key[$a_rule_key]}"
if [ ! -z "$(echo $1 | grep "$rule_i")" ] ||
[[ "$PATH_TO_UMOUNT" = $rule_i ]]; then
action="${umount_rules_action[$a_rule_key]}"
case $action in
DELETE)
safe_umount_result=0 #This is in case one doesn't want to use the return status right away
return 0
break #This is probably redundant
;;
UMOUNT)
safe_umount_result=1 #This is in case one doesn't want to use the return status right away
return 1
break #This is probably redundant
;;
POLICY_KEEP)
POLICY=KEEP
;;
POLICY_UMOUNT)
POLICY=UMOUNT
;;
esac
fi
done
if [ -z ${safe_umount_result+x} ]; then #If we don't have a result yet set result based on policy
case "$POLICY" in
KEEP)
safe_umount_result=1
return 1; ;;
UMOUNT)
safe_umount_result=0
return 0; ;;
*)
echo "No Delete policy set, so keeping file/dir $1"
safe_umount_result=1
return 1
esac
fi
}
umountall() {
{
log start
set -x
#R_FR=$(realpath -m "$FAKEROOT")
#[ ${#R_FR} -lt 2 ] && exit
safe_umount $SANDBOX_TMPFS
[ $safe_umount_result -eq 0 ] && umount -l $SANDBOX_TMPFS
if [ PUPMODE = 2 ]; then #Full Install
safe_umount $FAKEROOT/tmp
umount -l $FAKEROOT/tmp
else
safe_umount $FAKEROOT/initrd/mnt/tmpfs
[ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT/initrd/mnt/tmpfs
fi
for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
layer="$(eval 'echo $'$layer_name)"
if [ ! -z "$layer" ] ; then
safe_umount "$FAKEROOT/initrd/$layer_name"
[ $safe_umount_result -eq 0 ] && umount -l "$FAKEROOT/initrd/$layer_name"
fi
done
for aFolder in /proc /sys /dev ""; do
safe_umount $FAKEROOT"/$aFolder"
[ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT$aFolder
done
if [ -z "$RW_LAYER" ]; then
safe_umount "$SANDBOX_TMPFS"
[ $safe_umount_result -eq 0 ] && umount -l $SANDBOX_TMPFS
safe_delete "$SANDBOX_TMPFS"
[ $safe_delete_result -eq 0 ] && rmdir $SANDBOX_TMPFS
fi
safe_delete $FAKEROOT
[ $safe_delete_result -eq 0 ] && rmdir $FAKEROOT
} # 2> /dev/null
}
function choose_save(){
# location not specified - then ask
log stop
dialog --backtitle "rw image sandbox" --title "choose rw image" \
--extra-button --extra-label "Create" --ok-label "Locate" \
--yesno "You didn't specify the location of the rw image file. Do you want to locate existing file, or do you want to create a new one?" 0 0
chosen=$?
log start
case $chosen in
0) # ok - locate
log stop
dialog --backtitle "rw image sandbox" --title "Specify location of existing rw image" --fselect `pwd` 8 60 2> $TMPFILE
savebranch=`cat $TMPFILE`
log start
rm $TMPFILE
if [ -n "$savebranch" ]; then
if [ -d "$savebranch" ]; then
case "$savebranch" in
"/mnt"|"/mnt/"|"/mnt/home"|"/mnt/home/"|"/")
log stop
echo "warning chose the following savebranch $savebranch"
read -p "Press enter to continue"
log start
set_sandbox_img ""
;;
esac
SANDBOX_IMG=$savebranch
elif [ ! -f "$savebranch" ]; then
echo "$savebranch doesn't exist - exiting."
echo "will use tmpfs instead"
log stop
read -p "Press enter to continue"
log start
savebranch=""
else
set_sandbox_img ""
fi
else
echo "You didn't specify any file or you pressed cancel. Exiting."
exit
fi
;;
3) # create
echo "create"
log stop
dialog --backtitle "save image sandbox" --title "Specify name and path of new the file" --fselect `pwd` 8 60 2> $TMPFILE
savebranch=`cat $TMPFILE`
log start
rm $TMPFILE
if [ -n "$savebranch" ]; then
if [ -f "$savebranch" ]; then
echo "$savebranch already exist - exiting."
exit
else
# get the size
log stop
dialog --title "Create new save image" --inputbox "Specify size (in megabytes)" 0 40 100 2> $TMPFILE
size=`cat $TMPFILE`
log start
rm $TMPFILE
if [ -n "$size" ]; then
if dd if=/dev/zero of="$savebranch" bs=1 count=0 seek="$size"M; then
if ! mke2fs -F "$savebranch"; then
echo "I fail to make an ext2 filesystem at $savebranch, exiting."
exit
fi
else
echo "I fail to create a ${size}M file at $savebranch,, exiting."
exit
fi
else
echo "You didn't specify the size or your press cancel. Exiting."
exit
fi
fi
else
echo "You didn't specify any file or you pressed cancel. Exiting."
exit
fi
;;
1 | 255) # 1 is cancel, 255 is Escape
;&
*) # invalid input - treat as cancel
echo "Cancelled - exiting."
exit
;;
esac
}
function find_save(){
if [ ! -z "SANDBOX_IMG" ]; then
FULL_SAVE_PATH=$SANDBOX_IMG
else
for prefix in '${DISTRO_FILE_PREFIX}save' '.*save'; do
for dir in "$PDRV/${PSUBDIR}" "PDRV"; do
ONE_SAVE="$(ls $dir -1 | grep -m "${prefix}save")"
if [ -z "$ONE_SAVE" ]; then
continue
else
SAVE_FILE="$ONE_SAVE"
FULL_SAVE_PATH="$dir"/ONE_SAVE
break
fi
done
done
echo "PSAVE"mount_items
fi
}
function find_bk_folders(){
for a_PDRV in "$PDRV" sr0 sr1; do #Consider adding /mnt/home here
for a_psubdir in "${PSUBDIR}" ""; do
MT_PT_of_Folder="$(mount_fn2 "$PDRV" "${PSUBDIR}")"
#https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L981
BKFOLDERS="$(find $MT_PT_of_Folder -maxdepth 1 -xdev -type d -name '20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]' | sed -e s%^${SAVE_MP}/%% | sort -r)"
[ ! -z "#BKFOLDERS" ] && break
done
done
}
function mk_initrd_dir(){
mkdir -p "$FAKEROOT"/initrd
if [ -z "$PUPMODE" ] ; then
if [ -z "$PMEDIA" ]; then
#if [ "$PUPMODE" = 5 ] ; then
# #aufs layers: RW (top) RO1 RO2 PUPMODE
# #First boot (or pfix=ram): tmpfs pup_xxx.sfs 5
PUPMODE=5 #MAYBE PUPMODE=2 would be better
elif [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = 'usbhd' ]; then
find_save
if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
#aufs layers: RW (top) RO1 RO2 PUPMODE
#Normal running puppy: pup_save.3fs pup_xxx.sfs 12
PUPMODE=12
else
echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
PUMPMODE=2
#TODO, prompt to either search for save file/folder or alternatively create it.
fi
elif [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]; then
find_save
#aufs layers: RW (top) RO1 RO2 PUPMODE
#ditto, but flash drive: tmpfs pup_save.3fs pup_xxx.sfs 13
if [ -f "$SAVE_PATH" ] || [ -d "$SAVE_PATH" ]; then
#aufs layers: RW (top) RO1 RO2 PUPMODE
#ditto, but flash drive: tmpfs pup_save.3fs pup_xxx.sfs 13
PUPMODE=13
else
echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
PUPMODE=5
fi
elif [ "$PMEDIA" = usbcd ] || [ "$PMEDIA" = idecd ] || [ "$PMEDIA" = satacd ] ; then
find_bk_folders
if [ ! -z "$BKFOLDERS" ]; then
PUPMODE=77 #MULTI-Session CD
else #First Boot
find_save
if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
PUPMODE=13
else
PUPMODE=5
fi
fi
#aufs layers: RW (top) RO1 RO2 PUPMODE
#Multisession cd/dvd: tmpfs folders pup_xxx.sfs 77
else #[PUPMODE=2 -> full install
PUPMODE=2
fi
if [ "$PUPMODE" = 2 ] && [ 1 -ne 1 ]; then #Full install
echo "Full install has no initrd"
else
mkdir -p "$FAKEROOT/initrd"
cd $FAKEROOT/initrd
if [ "$PUPMODE" = 12 ]; then # Usually [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = usbhd ]
ln -s mnt/dev_save/"${SAVE_PATH}" pup_rw
elif [ "$PUPMODE" = 13 ] || [ "$PUPMODE" = 5 ] || [ "$PUPMODE" = 77 ]; then
ln -s mnt/tmpfs/pup_rw pup_rw
if [ "$PUPMODE" = 13 ]; then # Usually [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]
ln -s "mnt/tmpfs/dev_save/${SAVE_PATH}" pup_ro1
elif [ "$PUPMODE" = 77 ]; then
ln -s mnt/tmpfs/pup_ro1/"${SAVE_PATH}" pup_ro1 #Usually [ "$PMEDIA" = usbcd ] || [ "$PMEDIA" = idecd ] || [ "$PMEDIA" = satacd ]
fi
fi
mkdir -p "$FAKEROOT/initrd/mnt/dev_save"
mount -o bind /mnt/home "$FAKEROOT/initrd/mnt/dev_save"
mkdir $FAKEROOT/mnt
cd $FAKEROOT/mnt
ln -s ../initrd/mnt/dev_save
cd $FAKEROOT
mount -o bind $SANDBOX_IMG initrd/mnt/tmpfs/pup_rw #not sure if this applies to all pupmodes.
fi
fi
}
function set_fakeroot(){
unset CLEANUP_SANDBOX_ROOT
# if SANDBOX_ROOT is set to null then set it in this function
# if FAKEROOT is null then this implies "/"
if [ -z ${FAKEROOT+x} ] && [ $FAKEROOT_SET = false ]; then
FAKEROOT=fakeroot
CLEANUP_SANDBOX_ROOT=yes
fi
if [ ! -z ${SANDBOX_ROOT+x} ] || [ ${#FAKEROOT} -gt 1 ]; then
if [ "${CLEANUP_SANDBOX_ROOT}" = yes ]; then
SANDBOX_ROOT=/mnt/sb
else
FAKEROOT_SET
fi
if [ ${#SANDBOX_ROOT} -gt 1 ] && [ $FAKEROOT_SET = false ]; then
FAKEROOT=$SANDBOX_ROOT/$FAKEROOT
FAKEROOT_SET=true
elif [ ! -z ${FAKEROOT+x} ]; then
FAKEROOT_SET=true
fi
FAKEROOT_dir="${FAKEROOT%/*}"
[ -z "${SANDBOX_ROOT}" ] && SANDBOX_ROOT=${FAKEROOT_dir}
if grep -q $FAKEROOT /proc/mounts; then
if [ ! "$SANDBOX_ROOT" = /mnt/sb ]; then
log stop
dialog --backtitle "rename root" --title "already mounted" \
--extra-button --extra-label "Rename" --ok-label "Keep" \
--yesno "FAKEROOTI is already a mount point. Rename Root?" 0 0
chosen=$?
log start
case "#chosen" in
1)
RENAME_ROOT=yes; ;;
0)
RENAME_ROOT=no; ;;
esac
else
RENAME_ROOT=yes
fi
if [ "${RENAME_ROOT}" = yes ]; then
FAKEROOT=$(mktemp -d -p ${FAKEROOT%/*}/ ${FAKEROOT##*/}.XXXXXXX)
SANDBOX_ID=".${FAKEROOT##*.}"
if [ -z "$SANDBOX_IMG" ]; then
[ -z "$savebranch" ] && choose_save
savebranch="$(realpath -m $savebranch)"
if [ -d "$savebranch" ]; then
#TODO: verify this works if savebranch is a mounted directory.
SANDBOX_IMG="$savebranch"
else
[ ! -z "$savebranch" ] && loop=$(losetup-FULL -a | grep "$savebranch" | sed "s/:.*$//" )
if [ ! -z "$loop" ]; then
SANDBOX_IMG=$(cat /proc/mounts | grep $loop | cut -d " " -f2)
fi
if [ -z "$SANDBOX_IMG" ] ; then
SANDBOX_IMG=$FAKEROOT_dir/sandbox_img${SANDBOX_ID}
mkdir -p $SANDBOX_IMG
fi
fi
rmdir $FAKEROOT
else
log stop
echo "Warning chose to remount over existing mount! $FAKEROOT"
echo "ctrl-c to quote"
read -p "Press enter to continue"
log start
fi
fi
else
echo "This is our first sandbox"
fi
else
echo "Warning sandbox root not defined"
#[ -z "$FAKEROOT" ] && FAKEROOT=/
fi
if [ $CLEANUP_SANDBOX_ROOT = yes ]; then
if [ ${#del_rules_filter} -eq 0 ]; then
del_rules_filter+=( $SANDBOX_ROOT"/*" )
del_rules_filter+=( POLICY_DELETE )
fi
if [ ${#umount_rules_filter} -eq 0 ]; then
umount_rules_filter+=( $SANDBOX_ROOT"/*" )
umount_rules_filter+=( POLICY_UMOUNT )
fi
fi
mkdir -p "$SANDBOX_ROOT"
mkdir -p "$FAKEROOT"
}
function set_sandbox_img(){
[ -z ${FAKEROOT_dir+x} ] && set_fakeroot
if [ ! -z ${SANDBOX_IMG+x} ] && [ -z "${SANDBOX_IMG}" ] || [ ! -z ${1+x} ]; then
SANDBOX_IMG=sandbox_img
SANDBOX_IMG=${SANDBOX_IMG}${SANDBOX_ID}
[ ! -z "$FAKEROOT_dir" ] && SANDBOX_IMG=$FAKEROOT_dir/$SANDBOX_IMG
elif [ -z "${FAKEROOT_dir}" ] ; then
SANDBOX_IMG=$FAKEROOT_dir/$SANDBOX_IMG
fi
}
function set_sandbox_tmpfs(){
[ -z ${FAKEROOT_dir+x} ] && set_fakeroot
if [ ! -z ${SANDBOX_TMPFS+x} ] && [ -z "${SANDBOX_TMPFS}" ]; then
SANDBOX_TMPFS=sandbox_tmpfs
SANDBOX_TMPFS=${SANDBOX_TMPFS}${SANDBOX_ID}
[ -z "$FAKEROOT_dir" ] && SANDBOX_TMPFS=$FAKEROOT_dir/$SANDBOX_TMPFS
elif [ -z "${FAKEROOT_dir}" ] ; then
SANDBOX_TMPFS=$FAKEROOT_dir/$SANDBOX_TMPFS
fi
}
declare -a options="$(getopt -o t::,r::,s:,d:,l: --long input-file:tmpfs::,root::,save:,pupmode::,pmedia:,pdrv:,psubdir:,distro-specs:,logfile:,trace: -- "$@")"
eval set --"$options"
while [ $# -gt 0 ]; do
case "$1" in
-t|--tmpfs)
if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
SANDBOX_TMPFS="$2"
set_sandbox_tmpfs
shift 2
else
SANDBOX_TMPFS="" #Later we use [ -z ${SANDBOX_TMPFS+x} ] to check that this is set
set_sandbox_tmpfs
shift 1
fi; ;;
-r|--root)
if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
SANDBOX_ROOT="$2"
shift 2
else
SANDBOX_ROOT="" #Later we use [ -z ${SANDBOX_ROOT+x} ] to check that this is set
shift 1
fi; ;;
-f|-n|--fake-root|--new-root)
if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
FAKEROOT="$2"
set_fakeroot
shift 2
else
FAKEROOT="" #Later we use [ -z ${FAKEROOT+x} ] to check that this is set
set_fakeroot
shift 1
fi; ;;
-s|--save) #$SANDBOX_IMG
#if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
if [ -d "$2" ]; then
SANDBOX_IMG=$2
savebranch=$2
else [ -f "$2" ]
#mnt_sb_immage
#mount -o loop "$rwbranch" $SANDBOX_IMG;
savebranch=$1
loop=$(losetup-FULL -a | grep "$savebranch" | sed "s/:.*$//")
if [ ! -z "$loop" ]; then
SANDBOX_IMG=$(/proc/mounts | grep $loop | cut -d " " -f2)
else
SANDBOX_IMG=""
set_sandbox_img
fi
shift 2;
fi; ;;
--pupmode)
if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
PUPMODE=$2
shift 2
else
PUPMODE=2
shift
fi
;;
--pmedia) PMEDIA=$2; shift 2; ;;
-d| --pdrv) PDRV=$2; shift 2; ;;
--psubdir) PSUBDIR=$2;
shift 2; ;;
--distro-specs)
DISTRO_SPECS=$2;
. "$DISTRO_SPECS"
shift 2
;;
-l|--logfile)
LOGFILE=$2
[ -z "$TRACE" ] && TRACE=true
shift 2
log init
;;
-t|--trace)
TRACE=$2
if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
TRACE="$2"
shift 2
else
TRACE=true
shift 1
fi
log init
;;
--)
shift 1
options2+=( "$@" )
break; ;;
*)
options2+=( "$1" )
shift 1; ;;
esac
done
if [ -z ${SANDBOX_ROOT+x} ] && [ -z ${FAKEROOT+x} ]; then
SANDBOX_ROOT="" #Later this will change to SANDBOX_ROOT=/mnt/sb
set_fakeroot
[ -z $SANDBOX_IMG ] && set_sandbox_img
fi
#SANDBOX_TMPFS=$SANDBOX_ROOT/sandbox # mounted rw location of
#SANDBOX_TMPFS=$SANDBOX_ROOT/initrd/mnt/tmpfs/pup_rw
#tmpfs used for sandbox
#SANDBOX_ID=
TMPFILE=$(mktemp -p /tmp)
# use namespaces if available
#[ -e /proc/1/ns/pid ] && [ -e /proc/1/ns/mnt ] && type unshare >/dev/null && USE_NS=1
# umount all if we are accidentally killed
#trap 'umountall' 1
#s243a don't unmount on error
# 0.1 must be root
if [ $(id -u) -ne 0 ]; then
echo "You must be root to use sandbox."
exit
fi
## 0.2 cannot launch sandbox within sandbox
#if [ "$AUFS_ROOT_ID" != "" ] ; then
# grep -q $SANDBOX_ROOT /sys/fs/aufs/$AUFS_ROOT_ID/br0 &&
# echo "Cannot launch sandbox within sandbox." && exit
#fi
# s243a we are remounting everything rather then creating a sandbox.
# 0.3 help
case "$1" in
--help|-h)
echo "Usage: ${0##*/}"
echo "Starts an in-memory (throwaway) sandbox. Type 'exit' to leave."
exit
esac
## 0.4 if not running from terminal but in Xorg, then launch via terminal
#! [ -t 0 ] && [ -n "$DISPLAY" ] && exec $XTERM -e "$0" "$@"
#! [ -t 0 ] && exit
## 0.5 is this the first sandbox? If not, then create another name for mountpoints
#if grep -q $FAKEROOT /proc/mounts; then
# FAKEROOT=$(mktemp -d -p $SANDBOX_ROOT ${FAKEROOT##*/}.XXXXXXX)
# SANDBOX_ID=".${FAKEROOT##*.}"
# SANDBOX_TMPFS=$SANDBOX_ROOT/${SANDBOX_TMPFS##*/}${SANDBOX_ID}
# rmdir $FAKEROOT
#fi
# 1. get aufs system-id for the root filesystem
if [ -z "$AUFS_ROOT_ID" ] ; then
AUFS_ROOT_ID=$(
awk '{ if ($2 == "/" && $3 == "aufs") { match($4,/si=[0-9a-f]*/); print "si_" substr($4,RSTART+3,RLENGTH-3) } }' /proc/mounts
)
fi
# 2. get branches, then map branches to mount types or loop devices
items=$(
{ echo ==mount==; cat /proc/mounts;
echo ==losetup==; losetup-FULL -a;
echo ==branches==; ls -v /sys/fs/aufs/$AUFS_ROOT_ID/br[0-9]* | xargs sed 's/=.*//'; } | \
awk '
/==mount==/ { mode=1 }
/==losetup==/ { mode=2 }
/==branches==/ { mode=3 }
{
if (mode == 1) {
# get list of mount points, types, and devices - index is $3 (mount points)
mountdev[$2]=$1
mounttypes[$2]=$3
} else if (mode == 2) {
# get list of loop devices and files - index is $1 (loop devs)
sub(/:/,"",$1)
sub(/.*\//,"",$3); sub(/)/,"",$3)
loopdev[$1]=$3
} else if (mode == 3) {
# map mount types to loop files if mount devices is a loop
for (m in mountdev) {
if ( loopdev[mountdev[m]] != "" ) mounttypes[m]=loopdev[mountdev[m]]
}
# for (m in mountdev) print m " on " mountdev[m] " type " mounttypes[m]
mode=4
} else if (mode==4) {
# print the branches and its mappings
if ($0 in mounttypes){
print $0, mounttypes[$0], "on"
}
else {
MNT_PATH=$0
sub(/^.*[\/]/,"")
print MNT_PATH, $0, "on"
}
}
}
'
)
# '
# 3. Ask user to choose the SFS
log stop
dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \
--checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE
chosen="$(cat $TMPFILE)"
log start
clear
if [ -z "$chosen" ]; then
echo "Cancelled or no SFS is chosen - exiting."
exit 1
fi
# 4. convert chosen SFS to robranches
robranches=""
for a in $(cat $TMPFILE) ; do
robranches=$robranches:$a=ro
done
rm $TMPFILE
# 5. get location of rw image
[ -z ${savebranch+x} ] && choose_save
mkdir -p $SANDBOX_IMG
[ ${#SANDBOX_IMG} -gt 1 ] || echo "Pathlenth too short SANDBOX_IMG='$SANDBOX_IMG'"
if [ ! -z "$savebranch" ]; then
if [ -f "$savebranch" ]; then
loop=$(losetup-FULL -a | grep "$savebranch" | sed "s/:.*$//" )
if [ ! -z "$loop" ]; then
SANDBOX_IMG=$(cat /proc/mounts | grep $loop | cut -d " " -f2)
else
mount -o loop "$savebranch" $SANDBOX_IMG
fi
fi
fi
#[ ${#SANDBOX_IMG} -gt 1 ] || echo "Pathlenth too short SANDBOX_IMG='$SANDBOX_IMG'"
#if [ -z "$rwdir" ] ; then #savebranch
if [ ! -z "$PUPMODE" ]; then
if [ $PUPMODE -ne 5 ] && [ $PUPMODE -ne 13 ] && [ $PUPMODE -ne 77 ]; then
if [ -z ${SANDBOX_TMPFS+x} ]; then
SANDBOX_TMPFS="" #Later we use [ -z ${SANDBOX_TMPFS+x} ] to check that this is set
fi
fi
fi
#fi
# # 4. make the mountpoints if not exist yet
# if [ ! -z "$SANDBOX_IMG" ]; then
# mkdir -p $SANDBOX_IMG
# mount -o loop "$savebranch" $SANDBOX_IMG || {
# echo "Failed to mount '$savebranch' at '$SANDBOX_IMG'"
# exit
# }
#fi
if [ ! -z "$SANDBOX_ROOT" ]; then
DEV_SAVE=$SANDBOX_ROOT/dev_save
mkdir -p "$DEV_SAVE"
if [ -z "$PDRV" ]; then
if [[ "$SANDBOX_IMG" = *"/mnt/"* ]]; then
PSUBDIR=${SANDBOX_IMG#/mnt/*/}
PDRV=${SANDBOX_IMG%"/$PSUBDIR"}
PDRV_real=$(cat /proc/mounts | grep $(realpath $PDRV) | cut -d " " -f1)
PSUBDIR_i=${PSUBDIR}
PDRV_i=${PDRV}
PDRV_real_i=${PDRV_real}
while (true); do
if [[ PDRV_real_i = /dev/loop* ]]; then
PDRV_real_i=$(losetup-FULL -a | grep "$(basename PDRV_real)")
PDRV_real_i=${PDRV_real#*(}
PDRV_real_i=${PDRV_real%)}
PSUBDIR_i=${PDRV_real_i#/mnt/*/}
PDRV_real=$PSUBDIR_i/$PDRV_real
PDRV_real_i=${SANDBOX_IMG%"/$PSUBDIR_i"}
PDRV_real_i=$(cat /proc/mounts | grep $(realpath $PDRV_real_i) | cut -d " " -f1)
elif [[ PDRV_real_i = /dev/* ]]; then
PDRV_real=$(blkid | grep $PDRV_real)
break
else
echo "could not identify PDRV_real"
break
fi
done
fi
fi
fi
#if [ -z $PDRV ]; then
# case "$(uname -a)"
#fi
[ -z $PDRV ] && PDRV=/mnt/home
if [ -z "$SANDBOX_IMG" ] || [ ! -z ${SANDBOX_TMPFS+x} ]; then
if [ -z "$SANDBOX_TMPFS" ] ; then
#SANDBOX_TMPFS=$SANDBOX_ROOT/sandbox
set_sandbox_tmpfs
#if grep -q $SANDBOX_TMPFS /proc/mounts; then
# #FAKEROOT=$(mktemp -d -p $SANDBOX_ROOT ${FAKEROOT##*/}.XXXXXXX)
# #SANDBOX_ID=".${FAKEROOT##*.}"
# SANDBOX_TMPFS=$SANDBOX_ROOT/${SANDBOX_ID/}${SANDBOX_ID}
# mkdir -p -f SANDBOX_TMPFS
# mount -t tmpfs none $SANDBOX_TMPFS; #We could exit if this fails but we don't need to becuase we can still write to SANDBOX_TMPFS even if it isn't tmpfs.
# rmdir $FAKEROOT
#fi
fi
if [ ! -z "${SANDBOX_TMPFS}" ] && [ ! -z "$(grep -q ${SANDBOX_TMPFS} /proc/mounts)" ]; then
mount -t tmpfs none $SANDBOX_TMPFS;
fi
elif [ ! -z "${SANDBOX_TMPFS}" ]; then
if [ ! -z "${SANDBOX_TMPFS}" ] && [ ! -z "$(grep -q ${SANDBOX_TMPFS} /proc/mounts)" ]; then
mount -t tmpfs none $SANDBOX_TMPFS;
fi
fi
if [ -z "$SANDBOX_TMPFS" ]; then
SANDBOX_TMPFS=$SANDBOX_IMG
else
if [ $robranches ~= ** ]; then
robranches=$SANDBOX_IMG=rr:$robranches
fi
fi
mkdir -p $FAKEROOT
#mk_initrd_dir
# 5. do the magic - mount the rw image first, and then the rest with aufs
#if mount -o loop "$rwbranch" $SANDBOX_IMG; then
if [ ${#FAKEROOT} -gt 1 ] && ! grep -q $FAKEROOT /proc/mounts; then
echo "mount -t aufs -o \"br:$SANDBOX_TMPFS=rw$robranches\" aufs ${FAKEROOT}"
echo "About to mount FAKEROOT at $FAKEROOT"
read -p "Press enter to continue"
mount -t aufs -o "br:$SANDBOX_TMPFS=rw$robranches" aufs ${FAKEROOT}
# 5. record our new aufs-root-id so tools don't hack real filesystem
SANDBOX_AUFS_ID=$(grep $FAKEROOT /proc/mounts | sed 's/.*si=/si_/; s/ .*//') #'
sed -i -e '/AUFS_ROOT_ID/ d' $FAKEROOT/etc/BOOTSTATE 2> /dev/null
echo AUFS_ROOT_ID=$SANDBOX_AUFS_ID >> $FAKEROOT/etc/BOOTSTATE
# 7. sandbox is ready, now just need to mount other supports - pts, proc, sysfs, usb and tmp
mkdir -p $FAKEROOT/dev $FAKEROOT/sys $FAKEROOT/proc $FAKEROOT/tmp
mkdir -p "$DEV_SAVE/${PSUBDIR}"
mount -o bind "$PDRV/${PSUBDIR}" "$DEV_SAVE/${PSUBDIR}"
#mount -o bind "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/initrd/mnt/dev_save"
mount -o bind "$DEV_SAVE" "$FAKEROOT/initrd/mnt/dev_save"
#Maybe optionally do this based on some input paramater:
#Also pull these layers from an array
for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
layer="$(eval 'echo $'$layer_name)"
if [ ! -z "$layer" ] ; then
mount -o bind "$layer" "$FAKEROOT/initrd/$layer_name"
fi
done
case "$(uname -a)" in
*fatdog*)
mkdir -p "$FAKEROOT/aufs"
#mount -o bind "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/aufs/dev_save"
mkdir -p "$FAKEROOT/aufs/dev_save"
mount -o bind /mnt/home "$FAKEROOT/aufs/dev_save"
cd $FAKEROOT
#mkdir -p mnt/home
cd mnt
ln -s home ../aufs/dev_save
pup_save="$SANDBOX_IMG"
mount -o bind "$pup_save" "$FAKEROOT/aufs/pup_save"
base_sfs=/aufs/pup_ro
mount -o bind "$base_sfs" "$FAKEROOT/aufs/pup_ro"
if [ "$SANDBOX_TMPFS" != "$SANDBOX_IMG" ]; then
pup_rw="$SANDBOX_TMPFS"
mount -o bind "$pup_rw" "$FAKEROOT/aufs/pup_rw"
fi
;;
*) #assume this is puppy
mk_initrd_dir
#mkdir -p "$FAKEROOT/initrd/mnt/dev_save"
#mount -o bind /mnt/home "$FAKEROOT/initrd/mnt/dev_save"
#mkdir $FAKEROOT/mnt
#cd $FAKEROOT/mnt
#ln -s ../initrd/mnt/dev_save
;;
esac
mkdir -p $FAKEROOT/mnt/home
mount -o rbind /dev $FAKEROOT/dev
mount -t sysfs none $FAKEROOT/sys
mount -t proc none $FAKEROOT/proc
if [ PUPMODE = 2 ] || [[ "$(uname -a)" = *fatdog* ]]; then #Full Install #Maybe don't base this on PUPMODE
tmp_des=$FAKEROOT/tmp
tmp_source=/tmp
else
#case "$(uname -a)" in
#*fadog*)
#
#*) #assume this is puppy
mkdir -p $FAKEROOT/initrd/mnt/tmpfs
tmp_des=$FAKEROOT/initrd/mnt/tmpfs
tmp_source=/initrd/mnt/tmpfs
cd $FAKEROOT
rm tmp
ln -s initrd/mnt/tmpfs tmp
fi
mount -o bind $tmp_source $tmp_des
cd $FAKEROOT
case "$(uname -a)" in
*fatdog*)
mkdir -p $FAKEROOT/aufs
mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS
;;
*) #assume this is puppy
mk_initrd_dir
#ln -s initrd/mnt/tmpfs tmp
#mkdir -p $FAKEROOT/$SANDBOX_TMPFS
#mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS # so we can access it within sandbox
;;
esac
# #mkdir -p $FAKEROOT/$SANDBOX_TMPFS
# mkdir -p $FAKEROOT/$SANDBOX_IMG
# mount -o bind $SANDBOX_IMG $FAKEROOT/$SANDBOX_IMG # so we can access it within sandbox
cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null
# 8. optional copy, to enable running sandbox-ed xwin
cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null
# 9. make sure we identify ourself as in sandbox - and we're good to go!
echo -e '\nexport PS1="sandbox'${SANDBOX_ID}'# "' >> $FAKEROOT/etc/shinit #fatdog 600
sed -i -e '/^PS1/ s/^.*$/PS1="sandbox'${SANDBOX_ID}'# "/' $FAKEROOT/etc/profile # earlier fatdog
if [ -d "$FULL_SAVE_PATH" ]; then #TODO verify that this works with a save file
if [ $PUPMODE -eq 13 ] && [ $PUPMODE -eq 77 ]; then
#TODO: when PUPMODE=77 (multisession cd) we need to copy folders. See: https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1084
#and copy_folders() https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L482
#https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1091
mount -o remount,prepend:"$FULL_SAVE_PATH"=rw,mod:"$SANDBOX_TMPFS"=ro,del:"$SANDBOX_TMPFS" "$FAKEROOT"
#mount -o remount,add:1:"$FULL_SAVE_PATH"=ro+wh "$FAKEROOT"
fi
fi
echo "Starting sandbox now."
log stop
if [ $USE_NS ]; then
unshare -f -p --mount-proc=$FAKEROOT/proc chroot $FAKEROOT
else
chroot $FAKEROOT
fi
log start
# 8. done - clean up everything
umountall
echo "Leaving sandbox."
elif [ "${FAKEROOT:-/}" = "/" ]; then
#[ -z "$FAKEROOT" ] && $FAKEROOT="/"
echo "mount -t aufs -o \"remount,br:$SANDBOX_TMPFS=rw$robranches\" aufs ${FAKEROOT:-/}"
echo "Warning! about to remount rootfs at $FAKEROOT"
read -p "Press enter to continue"
trap - 1 #Clear traps
trap
mount -t aufs -o "br:$SANDBOX_TMPFS=rw$robranches" aufs ${FAKEROOT:-/};
mkdir -p /dev /sys /proc /tmp #These probably already exist
[[ "`mountpoint /dev`" != *"is a mountpoint"* ]] && mount -t devtmpfs devtmpfs /dev
mkdir -p /initrd/mnt/tmpfs
[[ "`mountpoint /initrd/mnt/tmpfs`" != *"is a mountpoint"* ]] && mount -t tmpfs none /initrd/mnt/tmpfs
mkdir -p /initrd/mnt/tmpfs/tmp
if [[ "`mountpoint /tmp`" != *"is a mountpoint"* ]]; then
if [[ "`mountpoint /initrd/mnt/tmpfs`" != *"is a mountpoint"* ]]; then
mount -o bind /initrd/mnt/tmpfs/tmp /tmp
else
mount -t tmpfs none /tmp
fi
fi
else
echo "not implemented for FAKEROOT=${FAKEROOT:-/}}"
exit
fi
#else
# echo "Unable to mount aufs br:$SANDBOX_IMG=rw$robranches"
# umount -l $SANDBOX_IMG
#fi
#else
# echo "unable to mount rw image: $rwbranch"
#fi