Advertisement
s243a

sandbox_s243a_debug12.sh

Jan 27th, 2020
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 24.95 KB | None | 0 0
  1. #!/bin/bash
  2. # James Budiono 2011, 2013, 2015
  3. # puppy test/compilation sandbox
  4. # this version uses tmpfs instead of an rw image,
  5. # and you can also choose which SFS to use
  6. # run this from terminal.
  7. # version 4 - replace sed with awk - more powerful and more correct, will handle all oddball cases
  8. #           where loop-N and pup_ro-N numbers don't match
  9. # version 5 - add compatibility when running with pup_rw=tmpfs (step 2.a)
  10. # version 6 - (2012) adapted to be more flexible - for Fatdog64 600
  11. # version 7 - (2012) cleanup mounts if if we are killed
  12. # version 8 - (2013) re-launch in terminal if we aren't in terminal
  13. # version 9 - (2013) enable running multiple sandboxes
  14. # version 10 - (2015) use pid/mount namespaces if available
  15. #
  16. # 0. directory locations
  17. #. $BOOTSTATE_PATH # AUFS_ROOT_ID
  18. #XTERM="defaultterm"
  19. #
  20. # All options below were added by s243a:
  21. #
  22. # -o, --output-file
  23. #    Just write layer paths to an output file but don't mount the sandbox.
  24. # --no-exit
  25. #   if an output file is specified (i.e. -o or --output-file) layer paths are just written to a file and the program exits unless the no-exit flag is specified.
  26. # f, --input-file
  27. #   read layer paths from a file rather than reading existing layers
  28. # m,--pmedia
  29. #   determines pupmodes. Refer to puppy boot parmaters
  30. # d, --pdrv
  31. #   this is the particiaion where the puppy files are located. The default is /mnt/home
  32. # s, psubdir
  33. #   this is the sub directory where the puppy files are located
  34. # c, --clear-env
  35. #   deletes enviornental variabls
  36. # --env-prefix
  37. #   enviornental variable prefix
  38. # b --boot-config
  39. #   path to boot config (e.g. /etc/rc.d/BOOTCONFIG
  40. # --disto-specs
  41. #   path to distro specs (e.g. /etc/DISTRO_SPECS; e.g. /initrd/distro-specs)
  42. # L, --layer
  43. #   a subgke kater
  44. #  e, --extra-sfs
  45. #   a list of extra sfs files (space seperated)
  46. #  u, --union-record
  47. # --xterm
  48. # --sandbox
  49. # -initrd
  50. # --save
  51. # --noexit
  52. # --psave
  53. # --pupmode
  54.  
  55. #I thought some assoitive arrays might be useful but I'm not using them yet.
  56. #declare -A KEYs_by_MNT_PT
  57. #declare -A KEYs_by_FILE_PATH
  58. #declare -A KEYs_by_trimmed_MNT_PT
  59. #declare -A KEYs_by_trimmed_FILE_PATH
  60. #declare -A MNT_PTs
  61. #declare -A FILE_PATHs
  62. #declare -A ON_status
  63. MAX_STR_LEN=50
  64.  
  65.  
  66. XTERM=${XTERM:-urxvt}
  67. SANDBOX_ROOT=${SANDBOX_ROOT:-/mnt/sb}
  68. declare -a options="$(getopt -o f:,o:,m:,d:,s:,b:,e: --long input-file:output-file:,pmedia:,pdrv:,psubdir:,boot-config:,distro-specs:,extra-sfs:,maybe-aufs,maybe-psubdir:,no-exit::,--psave:,--pupmode -- "$@")"
  69. declare -a options2
  70. declare -a LAYER_SOURCES
  71. LAYER_SOURCE=none
  72. function find_save(){
  73.   for prefix in '${DISTRO_FILE_PREFIX}save' '.*save'; do
  74.     for dir in "$PDRV/${PSUBDIR}" "PDRV";  do
  75.        
  76.       ONE_SAVE="$(ls $dir -1 | grep -m "${prefix}save")"
  77.       if [ -z "$ONE_SAVE" ]; then
  78.          continue
  79.       else
  80.          SAVE_FILE="$ONE_SAVE"
  81.          FULL_SAVE_PATH="$dir"/ONE_SAVE
  82.          break
  83.       fi
  84.     done
  85.    done
  86.    echo "PSAVE"mount_items
  87. }
  88. function find_bk_folders(){
  89.   for a_PDRV in "$PDRV" sr0 sr1; do #Consider adding /mnt/home here
  90.     for a_psubdir in "${PSUBDIR}" "";  do
  91.       MT_PT_of_Folder="$(mount_fn2 "$PDRV" "${PSUBDIR}")"
  92.       #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L981
  93.       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)"
  94.       [ ! -z "#BKFOLDERS" ] && break  
  95.     done
  96.   done
  97. }
  98. function mount_items(){
  99.   local Moun_Point
  100.   local File_PATH #Might be a directory
  101.   local AWK_PRG="$(cat << EOF
  102. #Some info on FPAT:
  103. # https://stackoverflow.com/questions/6619619/awk-consider-double-quoted-string-as-one-token-and-ignore-space-in-between
  104. #
  105. #Field 4 is the mount point
  106. #Field 1 is also the mount point but maybe be trimmed in the future
  107. #Field 6 is the path to the file being mounted
  108. #Field 7 is the mount device but it may be blank
  109. #Field 8 is the uuid but might be blank
  110. function get_mp(dev){
  111.  #cmd="cat /proc/mounts | grep \"$(realpath " dev ")\""
  112.  cmd="cat /proc/mounts | grep " dev "
  113.   while ((cmd | getline )){
  114.     if ( index($1,dev)>0 ){
  115.       return $2
  116.       break
  117.     }
  118.   }
  119. }
  120. function get_dev(mp){
  121.   #cmd="cat /proc/mounts | grep \"$(realpath " dev ")\""
  122.   cmd="cat /proc/mounts | grep " dev "
  123.  while ((cmd | getline )){
  124.    #this could potentially return a false positive
  125.    if ( index($2,mp)>0 ){
  126.      return $1
  127.      break
  128.    }
  129.  }
  130. }
  131. function get__dev_mnt_pt(f6,f7,f8,    mp,dev){
  132.  if (length(f8)>0){ #f8 is the uuid or label
  133.    blkid_line(f8)
  134.    dev=BLKID_REC["DEV"]
  135.    dev_mp=get_mp(dev)
  136.    if (length(dev_mp)==0){
  137.      dev_mp=dev
  138.      sub(/^[/](dev)[/](.*)/,"mnt",dev_mp)
  139.    }
  140.  }
  141.  if (length(dev)==0){ #f
  142.    if (length(f7)>0){ #f7 is the mount device but it may be blank
  143.      dev_mp=get_mp(f7) #This only checks existing mounts
  144.      if (length(dev_mp)==0){ #If the mount isn't existing then try to infer it from the path
  145.        dev_mp=f7
  146.        sub(/^[/]dev/,"[/]mnt",dev_mp)
  147.      }
  148.      
  149.    }
  150.    else { #is the path to the file being mounted
  151.      dev_mp=gensub(/^([/][^/]*[/][^/]*)/.*/,"\\1","",f6)
  152.    }
  153.  }
  154.  return dev_mp
  155. }
  156.  
  157. function get__dev_path(f6,f7,f8,    mp,dev){
  158.  if (length(f8)>0){ #Field 8 is the uuid or label but might be blank
  159.    blkid_line(f8)
  160.    dev=BLKID_REC["DEV"]
  161.  }
  162.  if (length(dev)==0){ #Field 7 is the mount device but it may be blank
  163.    length(f7)>0) return f7
  164.  else { #Field 6 is the path to the file being mounted
  165.    dev_name=gensub(/^[/][^/]*[/]([^/]*)/.*/,"\\1","",f6)
  166.    dev="/dev/" dev_name
  167.  }
  168.  return dev
  169. }
  170. function blkid_line(s,   i,field,field_val,cmd){
  171.  delete BLKID_REC
  172.  cmd="blkid | grep " s
  173.  while ((cmd | getline )){
  174.    BLKID_REC["DEV"]=$1
  175.    array_size
  176.    for (i = 2; 2<=NF; i++){
  177.      field_val=gensub(/^[^=]*=[\"]([^\"]*)[\"]$/,"\\1",1,$i)
  178.      field=sub(/=.*$/,"",$i)
  179.      BLKID_REC[field]=field_val
  180.    }
  181.    break
  182.  }
  183. }
  184.  
  185. #s can be any regX to filter the blkid output
  186. #s is usually the device (e.g. /dev/sda or sda)
  187. function get__uuid(s,uuid){
  188.  if (length(uuid)==0){
  189.    blkid_line(s)
  190.    return BLKID_REC["UUID"]
  191.  }
  192.  else {
  193.    return uuid
  194.  }
  195. }
  196. function get_dev(s,dev){
  197.  blkid_line(s)
  198.  return BLKID_REC["DEV"]
  199. }
  200. BEGIN{
  201.     FPAT = "([^ ]+)|(\"[^\"]+\")"
  202.    
  203. }
  204. {
  205.    if (FIELD_NUM>NF || length($FIELD_NUM) == 0 || NF==7){
  206.      switch(FIELD_NUM){
  207.      case 7: #PDRV mount point      
  208.        print get__dev_mnt_pt($6,$7,$8)
  209.        break
  210.      case 8: #UUID
  211.        dev_mnt_pt=get__dev_mnt_pt($6,$7,$8)
  212.        print get__uuid(dev_mnt_pt,$8)
  213.        break
  214.         }
  215.    } else {
  216.       print $FIELD_NUM
  217.     }
  218. }
  219. )"
  220.   while IFS"" read -r p || [ -n "$p" ]; do #https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash
  221.      File_PATH="$(echo "$1" | awk -v FIELD_NUM=6 "$AWK_PRG")"
  222.      Moun_Point="$(echo "$1" | awk -v FIELD_NUM=1 "$AWK_PRG")"
  223.      PDRV_MNT="$(echo "$1" | awk -v FIELD_NUM=7 "$AWK_PRG")"
  224.      PDRV_UUID="$(echo "$1" | awk -v FIELD_NUM=8 "$AWK_PRG")"
  225.      
  226.      [ -z "$PDRV_MNT" ] &&
  227.      mount_fn2 "PDRV" "$File_PATH" "$Moun_Point"
  228.   done <"$1"
  229. }
  230. function mount_fn2(){
  231.   local a_dev
  232.   local a_mp
  233.   if [ ! -b /dev/$1 ]; then
  234.     a_dev="$(blkid | grep -m1 $1 | cut -d ":" -f1)"
  235.     a_mp="${bla//\/dev/\/mnt}"
  236.     mount "$a_dev" "$a_mp"
  237.     $1="$a_mp"
  238.   fi
  239.   if [ -d "$1/$2" ]; then
  240.     #Make sure the directory isn't empty
  241.     if [ ! -z "$(ls -A "$1/$2")" ]; then
  242.       echo "$1/$2"
  243.     fi
  244.   elif [ -f "$1/$2" ]; then
  245.     echo "$(mount_fn "$1/$2")"
  246.   fi
  247. }
  248. function mount_fn(){
  249.   local MNT_PT=''
  250.     FULL_PATH=$(realpath "$1")
  251.     key=$(md5sum < <( echo "$FULL_PATH" ) | cut -f1 -d' ')
  252.     key=${key:0:5}
  253.     FNAME="$(echo "${FULL_PATH}__${key}" | sed 's#/#+#g' | sed 's#\.#+#g')"
  254.    
  255.     if [ ! -z "$2" ]; then
  256.       MNT_PT="$(cat /proc/mounts | grep "$2" | grep -m1 $FNAME | cut -d ' ' -f2 )"              
  257.       [ -z "$MNT_PT" ] && MNT_PT="$(cat /proc/mounts | grep -m1 "$2" | cut -d ' ' -f2 )"
  258.       [ -z "$MNT_PT" ] && MNT_PT="$(cat /proc/mounts | grep -m1 $FNAME | cut -d ' ' -f2 )"            
  259.    else
  260.        MNT_PT="$(cat /proc/mounts | grep -m1 $FNAME | cut -d ' ' -f2)"  
  261.        #if [ -f "$MNT_PT" ];
  262.    fi
  263.     if [ -z "${MNT_PT}" ]; then  
  264.       #case "FNAME" in
  265.       #*.iso)
  266.       #   DIR_PATH=/media; ;;
  267.       #*)
  268.         DIR_PATH=/mnt #; ;;
  269.       #esac
  270.       #if [ -z "$2" ]; then
  271.        # MNT_PT="$2"
  272.       #fi
  273.       #[ -z "$MNT_PT" ] && MNT_PT="${DIR_PATH}/$FNAME"
  274.       LN=${#FNAME}
  275.       start="$((LN-MAX_STR_LEN-4))"
  276.       if [ "$start" -lt 0 ]; then
  277.         start=0
  278.       fi
  279.       FNAME=${FNAME:$start}
  280.       MNT_PT="${DIR_PATH}/$FNAME"
  281.      
  282.       mkdir -p "${MNT_PT}"
  283.       mount $FULL_PATH "${MNT_PT}"    
  284.       MNT_PT="$(cat /proc/mounts | grep -m1 $FNAME | cut -d ' ' -f2 )"          
  285.    fi
  286.   echo  "${MNT_PT}"
  287. }
  288. function mk_initrd_dir(){
  289.   mkdir -p "$FAKEROOT"/initrd
  290.   if [ -z "$PUPMODE" ] ; then
  291.     if [ -z "$PMEDIA" ]; then
  292.       #if [ "$PUPMODE" = 5 ] ; then
  293.       #  #aufs layers:              RW (top)      RO1             RO2              PUPMODE
  294.       #  #First boot (or pfix=ram): tmpfs                         pup_xxx.sfs      5
  295.       PUPMODE=5 #MAYBE PUPMODE=2 would be better
  296.     elif [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = 'usbhd' ]; then
  297.       find_save
  298.       if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
  299.         #aufs layers:               RW (top)      RO1             RO2              PUPMODE
  300.         #Normal running puppy:      pup_save.3fs                  pup_xxx.sfs      12      
  301.         PUPMODE=12
  302.       else
  303.         echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
  304.         PUMPMODE=2
  305.         #TODO, prompt to either search for save file/folder or alternatively create it.
  306.       fi
  307.     elif [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]; then
  308.       find_save
  309.       #aufs layers:                 RW (top)      RO1             RO2              PUPMODE
  310.       #ditto, but flash drive:      tmpfs         pup_save.3fs    pup_xxx.sfs      13
  311.       if [ -f "$SAVE_PATH" ] || [ -d "$SAVE_PATH" ]; then
  312.         #aufs layers:               RW (top)      RO1             RO2              PUPMODE
  313.         #ditto, but flash drive:    tmpfs         pup_save.3fs    pup_xxx.sfs      13
  314.         PUPMODE=13
  315.       else
  316.         echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
  317.         PUPMODE=5
  318.       fi
  319.     elif [ "$PMEDIA" =  usbcd ] || [ "$PMEDIA" =  idecd ] || [ "$PMEDIA" =  satacd ] ; then
  320.       find_bk_folders
  321.       if [ ! -z "$BKFOLDERS" ]; then
  322.         PUPMODE=77  #MULTI-Session CD
  323.       else #First Boot
  324.         find_save
  325.         if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
  326.           PUPMODE=13      
  327.         else
  328.           PUPMODE=5
  329.         fi
  330.       fi
  331.       #aufs layers:            RW (top)      RO1             RO2              PUPMODE
  332.       #Multisession cd/dvd:       tmpfs         folders         pup_xxx.sfs      77
  333.     else #[PUPMODE=2 -> full install
  334.       PUPMODE=2
  335.     fi
  336.     if [ "$PUPMODE" = 2 ]; then #Full install
  337.       echo "Full install has no initrd"
  338.     else
  339.       mkdir -p "$FAKEROOT/initrd"
  340.       cd $FAKEROOT/initrd
  341.       if [ "$PUPMODE" = 12 ]; then # Usually [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = usbhd ]
  342.         ln -s mnt/dev_save/"${SAVE_PATH}" pup_rw
  343.       elif [ "$PUPMODE" = 13 ] || [ "$PUPMODE" = 5 ] || [ "$PUPMODE" = 77 ]; then
  344.         ln -s mnt/tmpfs/pup_rw pup_rw
  345.         if [ "$PUPMODE" = 13 ]; then  # Usually [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]
  346.           ln -s "mnt/tmpfs/dev_save/${SAVE_PATH}" pup_ro1
  347.         elif [ "$PUPMODE" = 77 ]; then
  348.           ln -s mnt/tmpfs/pup_ro1/"${SAVE_PATH}" pup_ro1  #Usually [ "$PMEDIA" =  usbcd ] || [ "$PMEDIA" =  idecd ] || [ "$PMEDIA" =  satacd ]
  349.         fi
  350.       fi
  351.     fi
  352.   fi
  353. }
  354.  
  355. eval set --"$options"
  356. while [ $# -gt 0 ]; do
  357.   case "$1" in
  358.   -f|--input-file)
  359.      INPUT_FILE=$2
  360.     LAYER_SOURCE=INPUT_FILE
  361.     LAYER_SOURCES+=( input-file )
  362.     shift 2; ;;      
  363.   -o|--output-file) OUTPUT_FILE=$2; shift 2; ;;
  364.   --no-exit)
  365.     if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  366.       NO_EXIT="$2"
  367.       shift 2
  368.     else
  369.       NO_EXIT=true
  370.       shift 1
  371.     fi; ;;
  372.   -p|--env-prefix) ENV_PREFIX=$2; shift 2; ;;
  373.   -m|--pmedia) PMEDIA=$2; shift 2; ;;
  374.   -d| --pdrv) PDRV=$2; shift 2; ;;
  375.   -s|--psubdir) PSUBDIR=$2;
  376.     LAYER_SOURCE=psubdir  
  377.     LAYER_SOURCES+=( psubdir )
  378.     shift 2; ;;
  379.     --maybe-psubdir) PSUBDIR=$2;
  380.     LAYER_SOURCE=maybe-psubdir  
  381.     LAYER_SOURCES+=( maybe-psubdir )
  382.     shift 2; ;;    
  383.   --distro-specs)
  384.      DISTRO_SPECS=$2;
  385.      . "$DISTRO_SPECS"
  386.      shift 2
  387.      ;;
  388.    --boot-config)
  389.        DISTRO_SPECS=$2;
  390.      . "$BOOTCONFIG"
  391.      shift 2
  392.      ;;
  393.    --union-record)  
  394.      LASTUNIONRECORD="$2";
  395.      LAYER_SOURCES+=( union-record )
  396.      shift 2; ;;
  397.    -e|--extra-sfs)
  398.      EXTRASFSLIST="$2";
  399.      LAYER_SOURCES+=( extrasfs )
  400.      shift 2; ;;
  401.   --maybe-aufs)
  402.     LAYER_SOURCE=maybe-aufs  
  403.     LAYER_SOURCES+=( maybe-aufs )
  404.     shift 1; ;;
  405.   --psave)
  406.     PSAVE=$2
  407.     shift 2
  408.     ;;
  409.   --pupmode)
  410.     PUPMODE=$2
  411.     shift 2
  412.     ;;
  413.   --)
  414.     shift 1
  415.     options2+=( "$@" )
  416.     break; ;;
  417.   *)
  418.      options2+=( "$1" )
  419.      shift 1; ;;
  420.   esac
  421. done
  422.  
  423. #set -- "${options2[@]}"
  424. if [ "$LAYER_SOURCE" = none ] && [ ! -z "$PDRV" ]; then
  425.   PDRV=${PDRV:-/mnt/home}
  426.   for rec in $LASTUNIONRECORD; do
  427.     if [ -f "$PDRV/$rec" ]; then
  428.       items+="\"$PDRV/$rec\" \"$rec\""$'\n'
  429.     fi
  430.   done
  431.   if [ -z "$items" ]; then
  432.     [ -z "$DISTRO_PUPPYSFS" ] && DISTRO_PUPPYSFS=$(ls -1 $PDRV | grep -i -m1 puppy_.*\.sfs$)
  433.     [ -z "$DISTRO_ZDRVSFS" ] && DISTRO_ZDRVSFS=$(ls -1 $PDRV | grep -i -m1 zdrv.*\.sfs$)
  434.     [ -z "$DISTRO_FDRVSFS" ] && DISTRO_FDRVSFS=$(ls -1 $PDRV | grep -i -m1 fdrv.*\.sfs$)
  435.     [ -z "$DISTRO_ADRVSFS" ] && DISTRO_ADRVSFS=$(ls -1 $PDRV | grep -i -m1 adrv.*\.sfs$)    
  436.     [ -z "$DISTRO_YDRVSFS" ] && DISTRO_YDRVSFS=$(ls -1 $PDRV | grep -i -m1 ydrv.*\.sfs$)    
  437.     for rec in "$DISTRO_PUPPYSFS" "$DISTRO_ZDRVSFS" "$DISTRO_FDRVSFS" "$DISTRO_ADRVSFS" "$DISTRO_YDRVSFS"; do
  438.       [ -z "$rec" ] && continue
  439.       items+="$PDRV/$rec" "$rec"$'\n'  
  440.     done
  441.   fi
  442.   if [ ! -z "$items" ]; then  
  443.     for rec in $EXTRASFSLIST; do
  444.       if [ -f "$PDRV/$rec" ]; then
  445.         items+="\"$PDRV/$rec\" \"$rec\" "on"\""$'\n'
  446.       fi
  447.     done
  448.   fi
  449. fi
  450. if [ -z "$items" ] && [ "$LAYER_SOURCE" = none ] ; then
  451.     LAYER_SOURCE=aufs  
  452.     LAYER_SOURCES+=( aufs )
  453. fi
  454. [ -z "$PDRV" ] && PDRV="$(realpath /mnt/home)"
  455. if [ "$(cat /proc/mounts | grep -c "$PDRV")" = 0 ]; then
  456.   PDRV_DEV="$(blkid | grep -m1 "$PDRV" | cut -d ':' -f1)"
  457.   PDRV="$(echo "$PDRV_DEV" | sed 's#^/dev/#/mnt/#')"
  458.   mount "$PDRV_DEV" "$PDRVV"
  459. fi  
  460.  
  461.  
  462. FAKEROOT=$SANDBOX_ROOT/fakeroot   # mounted chroot location of sandbox - ie, the fake root
  463. SANDBOX_TMPFS=$SANDBOX_ROOT/sandbox # mounted rw location of tmpfs used for sandbox
  464. DEV_SAVE=$SANDBOX_ROOT/dev_save
  465. mkdir -p "$DEV_SAVE"
  466.  
  467. SANDBOX_ID=
  468. TMPFILE=$(mktemp -p /tmp)
  469. # use namespaces if available
  470. #[ -e /proc/1/ns/pid ] && [ -e /proc/1/ns/mnt ] && type unshare >/dev/null && USE_NS=1
  471.  
  472.  
  473.  
  474.  
  475. # umount all if we are accidentally killed
  476. trap 'umountall' 1
  477. umountall() {
  478.   {
  479.   umount -l $FAKEROOT/$SANDBOX_TMPFS
  480.   if [ PUPMODE = 2 ]; then #Full Install
  481.       umount -l $FAKEROOT/tmp
  482.     else
  483.       umount -l $FAKEROOT/initrd/mnt/tmpfs
  484.     fi
  485.   for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
  486.     layer="$(eval 'echo $'$layer_name)"
  487.     if [ ! -z "$layer" ] ; then
  488.       umount -l "$FAKEROOT/initrd/$layer_name"
  489.     fi
  490.   done    
  491.   umount -l $FAKEROOT/proc
  492.   umount -l $FAKEROOT/sys
  493.   umount -l $FAKEROOT/dev
  494.  
  495.   umount -l $FAKEROOT
  496.   umount -l $SANDBOX_TMPFS
  497.   rmdir $FAKEROOT
  498.   #if  [ PUPMODE = 2 ] || PUPMODE = 5 ]; then
  499.     rmdir $SANDBOX_TMPFS
  500.   #fi
  501.   } 2> /dev/null
  502. }
  503.  
  504. # 0.1 must be root
  505. if [ $(id -u) -ne 0 ]; then
  506.   echo "You must be root to use sandbox."
  507.   exit
  508. fi
  509.  
  510. # 0.2 cannot launch sandbox within sandbox
  511. if [ "$AUFS_ROOT_ID" != "" ] ; then
  512.   grep -q $SANDBOX_ROOT /sys/fs/aufs/$AUFS_ROOT_ID/br0 &&
  513.     echo "Cannot launch sandbox within sandbox." && exit
  514. fi
  515.  
  516. # 0.3 help
  517. case "$1" in
  518.   --help|-h)
  519.   echo "Usage: ${0##*/}"
  520.   echo "Starts an in-memory (throwaway) sandbox. Type 'exit' to leave."
  521.   exit
  522. esac
  523.  
  524. # 0.4 if not running from terminal but in Xorg, then launch via terminal
  525. ! [ -t 0 ] && [ -n "$DISPLAY" ] && exec $XTERM -e "$0" "$@"
  526. ! [ -t 0 ] && exit
  527. # 1. get aufs system-id for the root filesystem
  528. if [ -z "$AUFS_ROOT_ID" ] ; then
  529.   AUFS_ROOT_ID=$(
  530.     awk '{ if ($2 == "/" && $3 == "aufs") { match($4,/si=[0-9a-f]*/); print "si_" substr($4,RSTART+3,RLENGTH-3) } }' /proc/mounts
  531.   )
  532. fi
  533. function get_items(){
  534.     local out
  535.     OUTFILE=/tmp/get_items_out
  536.     rm "$OUTFILE"
  537.    
  538.     out+="$(
  539.  { echo ==mount==; cat /proc/mounts;
  540.    echo ==losetup==; losetup-FULL -a;
  541.    echo ==branches==;
  542.      if [ $# -eq 0 ]; then
  543.        ls -v /sys/fs/aufs/$AUFS_ROOT_ID/br[0-9]* | xargs sed 's/=.*//';
  544.      else
  545.        if [ "$1" = "-f" ]; then
  546.          cat "$2";
  547.        elif [ "$1" = "-s" ]; then
  548.          cat <<<"$2";
  549.        fi;
  550.      fi; } | \
  551.    awk -v PDRV="$PDRV" -v MAX_STR_LEN="$MAX_STR_LEN" -v OUTFILE="$OUTFILE" \
  552. -f /usr/bin/sandbox.awk
  553. )"
  554.   echo "$out"
  555. }
  556.  
  557. if [ -z "$items" ]; then
  558.  
  559.   for item_source in "${LAYER_SOURCES[@]}"; do
  560.   # 2. get branches, then map branches to mount types or loop devices
  561.     case "$item_source" in
  562.     input-file)
  563.     mount_items "$INPUT_FILE"
  564.   items+="$(get_items -f "$INPUT_FILE")"; ;;
  565.     union-record)
  566.        new_items=''
  567.        for rec in $LASTUNIONRECORD; do
  568.         if [ -f "$rec" ]; then
  569.           MNT_PT="$(mount_fm "$rec" )"
  570.           new_items+="\"$MNT_PT\" \"$rec\" \"on\""$'\n'
  571.         elif [ -f "$PDRV/$rec" ]; then
  572.           MNT_PT="$(mount_fm "$PDRV/$rec" )"
  573.           new_items+="\"$MNT_PT\", \"$PDRV/$rec\", \"on\""$'\n'
  574.         fi
  575.       done
  576.       items+="$(get_items -f <<<"$new_items")"
  577.       ;;
  578.     extra-sfs)
  579.        new_items=''
  580.        for rec in $EXTRASFSLIST; do
  581.        if [ -f "$rec" ]; then
  582.           MNT_PT="$(mount_fm "$rec" )"
  583.           new_items+="\"$MNT_PT\" \"$rec\" \"on\""$'\n'
  584.         elif [ -f "$PDRV/$rec" ]; then
  585.           MNT_PT="$(mount_fm "$PDRV/$rec" )"
  586.           new_items+="\"$MNT_PT\" \"$PDRV/$rec\" \"on\""$'\n'
  587.         fi
  588.       done
  589.       ;;
  590.     layer=*)
  591.       item_path="$(echo ${litem_source#*=})"
  592.       if [ -f "$item_path" ]; then
  593.         MNT_PT="$(mount_fm "$item_path" )"
  594.       elif [ -d "$item_path" ]; then  
  595.         MNT_PT="$item_path" #This isn't really a mount poing
  596.       elif [ ! -d  "$item_path" ]; then
  597.         echo "Warning  cannot mount $item_path"
  598.         continue
  599.       fi
  600.       items+="\"$MNT_PT\" \"$item_path\" \"on\""$'\n'
  601.       ;;
  602.     psubdir|maybe-psubdir)
  603.       if [ "$item_source" = "maybe-psubdir" ]; then
  604.          [ ! -z "$items" ] && continue
  605.       fi
  606.       [ -z "$DISTRO_PUPPYSFS" ] && DISTRO_PUPPYSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'puppy_.*\.sfs$')"
  607.       [ -z "$DISTRO_ZDRVSFS" ] && DISTRO_ZDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'zdrv.*\.sfs$')"
  608.       [ -z "$DISTRO_FDRVSFS" ] && DISTRO_FDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'fdrv.*\.sfs$')"
  609.       [ -z "$DISTRO_ADRVSFS" ] && DISTRO_ADRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'adrv.*\.sfs$')"    
  610.       [ -z "$DISTRO_YDRVSFS" ] && DISTRO_YDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'ydrv.*\.sfs$')"  
  611.       new_items=""
  612.       for rec in "$DISTRO_PUPPYSFS" "$DISTRO_ZDRVSFS" "$DISTRO_FDRVSFS" "$DISTRO_ADRVSFS" "$DISTRO_YDRVSFS";  do
  613.         #MNT_PATH="${rec}"
  614.         [ -z "$rec" ] && continue
  615.         #[ ! -z "${PSUBDIR}" ] && MNT_PATH=${PSUBDIR}/${MNT_PATH}
  616.         MNT_PATH="${PDRV}/${PSUBDIR}/$rec"
  617.         MNT_PT="$(mount_fn "$MNT_PATH")"
  618.         new_items+="\"${MNT_PT}\" \"$rec\" \"on\""$'\n'
  619.        
  620.       done
  621.       export new_items="$new_items"
  622.       echo "$new_items"
  623.       items+="$(get_items -s "$new_items")"
  624.       ;;      
  625.     aufs)
  626.       items+="$(get_items)" ; ;;  
  627.     maybe-aufs)
  628.        [  -z "$items" ] && items+="$(get_items)"; ;;  
  629.   esac
  630.   items="$(echo "$items" | sed -n '/^\s*\(on\)\?\s*$/! p' | sed -n '/^Error: Expected on/! p' | sed -n '/^Use --help on/! p')"
  631.   done
  632. fi
  633. # 3. Ask user to choose the SFS
  634.  
  635. dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \
  636.   --checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE
  637. chosen="$(cat $TMPFILE)"
  638.  
  639. clear
  640. if [ -z "$chosen" ]; then
  641.   echo "Cancelled or no SFS is chosen - exiting."
  642.   exit 1
  643. fi
  644.  
  645.  
  646. # 4. convert chosen SFS to robranches
  647. robranches=""
  648. for a in $(cat $TMPFILE) ; do
  649.     #a="$(echo "$a" | sed 's/,$//')" # | sed 's/^'//' | sed 's/'$//' )"
  650.     a="$(echo "$a" | sed 's/"//g')" # | sed 's/^'//' | sed 's/'$//' )"
  651.   robranches=$robranches:$a=ro
  652.   sed -i "\#^$a # {s/ off / on /}" /tmp/get_items_out
  653. done
  654. if [ ! -z "$OUTPUT_FILE" ]; then
  655.   cp "/tmp/get_items_out" "$OUTPUT_FILE"
  656.   if [ ! "$NO_EXIT" = true ]; then
  657.     exit 0
  658.   fi
  659. fi
  660. rm $TMPFILE
  661.  
  662. #if [ PUPMODE = 2 ] || PUPMODE = 5 ]; then
  663.   # 0.5 is this the first sandbox? If not, then create another name for mountpoints
  664.   if grep -q $FAKEROOT /proc/mounts; then
  665.   FAKEROOT=$(mktemp -d -p $SANDBOX_ROOT ${FAKEROOT##*/}.XXXXXXX)
  666.   SANDBOX_ID=".${FAKEROOT##*.}"
  667.   SANDBOX_TMPFS=$SANDBOX_ROOT/${SANDBOX_TMPFS##*/}${SANDBOX_ID}
  668.   rmdir $FAKEROOT
  669.   fi
  670.   # 5. make the mountpoints if not exist  yet
  671.   mkdir -p $FAKEROOT $SANDBOX_TMPFS
  672. #else
  673. #  SANDBOX_TMPFS="$SAVE_MP_FULL_PATH"
  674. #fi
  675.  
  676.  
  677.  
  678. mk_initrd_dir
  679.  
  680.  
  681. # 6. do the magic - mount the tmpfs first, and then the rest with aufs
  682. if mount -t tmpfs none $SANDBOX_TMPFS; then
  683.   if mount -t aufs -o "udba=reval,diropq=w,br:$SANDBOX_TMPFS=rw$robranches" aufs $FAKEROOT; then
  684.     # 5. record our new aufs-root-id so tools don't hack real filesystem  
  685.     SANDBOX_AUFS_ID=$(grep $FAKEROOT /proc/mounts | sed 's/.*si=/si_/; s/ .*//') #'
  686.     sed -i -e '/AUFS_ROOT_ID/ d' $FAKEROOT/etc/BOOTSTATE 2> /dev/null
  687.     echo AUFS_ROOT_ID=$SANDBOX_AUFS_ID >> $FAKEROOT/etc/BOOTSTATE
  688.    
  689.     # 7. sandbox is ready, now just need to mount other supports - pts, proc, sysfs, usb and tmp
  690.     mkdir -p $FAKEROOT/dev $FAKEROOT/sys $FAKEROOT/proc $FAKEROOT/tmp
  691.     mkdir -p  "$DEV_SAVE/${PSUBDIR}"
  692.     mount -o bind  "PDRV/${PSUBDIR}" "$DEV_SAVE/${PSUBDIR}" #TODO: ONLY do this if we aren't going to mount all of mnt/dev_save
  693.     mount -o bind  "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/initrd/mnt/dev_save"
  694.     #Maybe optionally do this based on some input paramater:
  695.     #Also pull these layers from an array
  696.     for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
  697.         layer="$(eval 'echo $'$layer_name)"
  698.       if [ ! -z "$layer" ] ; then
  699.         mount -o bind  "$layer" "$FAKEROOT/initrd/$layer_name"
  700.       fi
  701.     done
  702.     mount -o rbind /dev $FAKEROOT/dev
  703.     mount -t sysfs none $FAKEROOT/sys
  704.     mount -t proc none $FAKEROOT/proc
  705.     if [ PUPMODE = 2 ]; then #Full Install
  706.       tmp_des=$FAKEROOT/tmp
  707.       tmp_source=/tmp
  708.     else
  709.         mkdir -p $FAKEROOT/initrd/mnt/tmpfs
  710.       tmp_des=$FAKEROOT/initrd/mnt/tmpfs
  711.       tmp_source=/initrd/mnt/tmpfs
  712.       cd $FAKEROOT
  713.       rm tmp
  714.       ln -s initrd/mnt/tmpfs tmp
  715.     fi
  716.     mount -o bind $tmp_source $tmp_des
  717.     mkdir -p $FAKEROOT/$SANDBOX_TMPFS
  718.     mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS # so we can access it within sandbox
  719.    
  720.     # 8. optional copy, to enable running sandbox-ed xwin
  721.     cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null
  722.    
  723.     # 9. make sure we identify ourself as in sandbox - and we're good to go!
  724.     echo -e '\nexport PS1="sandbox'${SANDBOX_ID}'# "' >> $FAKEROOT/etc/shinit #fatdog 600
  725.     sed -i -e '/^PS1/ s/^.*$/PS1="sandbox'${SANDBOX_ID}'# "/' $FAKEROOT/etc/profile # earlier fatdog
  726.    
  727.     if [ -d "$FULL_SAVE_PATH" ]; then #TODO verify that this works with a save file
  728.       if [ $PUPMODE -eq 13 ] && [ $PUPMODE -eq 77 ]; then
  729.         #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
  730.         #and copy_folders()  https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L482
  731.           #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1091
  732.           mount -o remount,prepend:"$FULL_SAVE_PATH"=rw,mod:"$SANDBOX_TMPFS"=ro,del:"$SANDBOX_TMPFS" "$FAKEROOT"
  733.           #mount -o remount,add:1:"$FULL_SAVE_PATH"=ro+wh "$FAKEROOT"
  734.       fi
  735.     fi
  736.     echo "Starting sandbox now."
  737.     if [ $USE_NS ]; then
  738.       unshare -f -p --mount-proc=$FAKEROOT/proc chroot $FAKEROOT
  739.     else
  740.       chroot $FAKEROOT
  741.     fi
  742.  
  743.     # 10. done - clean up everything
  744.     umountall
  745.     echo "Leaving sandbox."
  746.   else
  747.     echo "Unable to mount aufs br:$SANDBOX_TMPFS=rw$robranches"
  748.     umount -l $SANDBOX_TMPFS    
  749.   fi
  750. else
  751.   echo "unable to mount tmpfs."
  752. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement