#!/bin/sh
#(c) Copyright Barry Kauler 04 February 2017, barryk.org
#Licence: GPL v3 (/usr/share/doc/legal)
#170225 snapshot, create configuration-$DATE, new version configuration-<version>.
#170524 remove 'session.sfs', this concept no longer used. various fixes.
#170525 make 'session.sfs' an optional technique. reconstitute session.sfs.
#170525 some exclusions from snapshot. 170527 fixes.
#170528 fixes. new "Current status" frame. /mnt/home now /mnt/wkg/home.
#170816 set a max. depth to number of versions.
#170924 PUPSTATE has SESSIONSFSflag (see 'init' script in initrd.q) 0=no session.sfs
#171218 fix backSNAP.
#171226 was getting checkboxes "Release 0.6.4" and "Snapshot 0.6.4" -- remove latter.
#171226 log all snapshots in one file.
#171226 log all rollbacks in mnt/${WKG_DEV}/${WKG_DIR}repository/rollback-log
#180428 fixed containers snapshot-comments, container rollback.
#180602 boot-partition was not unmounted.
#180606 fixed buglet. need path root/.XLOADED for mksquashfs
#180624 erase container .session: aufs top-level .wh* dirs/files. confirmation dlg.
#180904 $KERNELNAME (vmlinuz or kernel8.img). see also 3buildeasydistro, easy-remaster, initrd (init, rollback).
#181006 fixed display of snapshot-comments file.
#181017 handle .sessionSKEL when erase container.
#181028 rename 'repository' folder to 'releases'.
#181121 handle .session/.control
#181122 q*.sfs renamed to easy*.sfs
#181123 /.* should be /.[a-zA-Z]*
#181130 'initrd.q' renamed to 'initrd'
#190715 if boot-partition read-only, cannot change version. 190721 fix.
#190829 /home symlink.
#191022 change default save-depth from 3 to 5
#200205 Esmourguit : gettexted Erase (ligne 290), Rollback and Snapshot (lignes 123, 295) and lines 188, 255, 271, 314, 329
#200319 increase allowed DEPTH_MAX from 5 to 7.
#200729 when rollback, do not rollback initrd, as older scripts may be broken.
#200813 erase session, offer to save some things. code extracted to script erase-exceptions.
#200829 copy easy.sfs when rollback. 200830 fix.

export TEXTDOMAIN=version-control
export OUTPUT_CHARSET=UTF-8

. /etc/DISTRO_SPECS
. /etc/rc.d/PUPSTATE #170924 has SESSIONSFSflag (see 'init' script in initrd) 0=no session.sfs

DATE="$(date +%Y%m%d%H%M)"
mkdir -p /tmp/easy_version_control

test_cont_mntd_func() {
 MNTDFLAG="$(mount | grep "containers/${EC_NAME}/container")"
 if [ "$MNTDFLAG" ];then
  pupdialog --background '#FF8080' --backtitle "$(gettext 'ERROR: container') ${EC_NAME}" --msgbox "$(gettext 'You cannot perform a session erase, snapshot, or rollback, when a container is in use.')" 0 0
  return 1
 fi
 return 0
}

if [ "$BOOT_FS" == "iso9660" ];then #190715 190721
 VERS="$DISTRO_VERSION"
else
 #170525 have coreutils 'sort', but this is cool...
 #busybox sort does not have that option (sort in coreutils has '-V'), so improvise...
 VERS="$(ls -l /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-* | rev | cut -f 1 -d '-' | rev)"
fi
#refer: http://stackoverflow.com/questions/4493205/unix-sort-of-version-numbers
#sortedVERS="$(echo "$VERS" | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n)" #lowest to highest.
revsortedVERS="$(echo "$VERS" | busybox sort -t. -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr)" #highest to lowest.

#170525
if grep -qw aufs /proc/filesystems; then
 LAYERFS='aufs'
 RO='=ro'
else
 LAYERFS='overlay'
 RO=''
fi

#170816  180606 change depth from 2 to 3. 191022 change default to 5
DEPTH_DEF="5"
if [ ! -s /var/local/version-history-depth ];then
 echo -n '5' > /var/local/version-history-depth
else
 DEPTH_DEF="$(cat /var/local/version-history-depth)"
fi

#180904
KERNELNAME=vmlinuz
[ -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/kernel8.img ] && KERNELNAME="kernel8.img" #rpi3

#171226 log all snapshots in one file...
touch /mnt/${WKG_DEV}/${WKG_DIR}releases/rollback-log
echo -e 'SNAPSHOT LOG\n************' > /tmp/easy_version_control/all-snapshots
touch /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/snapshot-comments
for aSSC in $(find /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-* -maxdepth 1 -type f -name snapshot-comments)
do
 [ "$aSSC" == "" ] && continue
 aVER="$(echo -n "$aSSC" | cut -f 5 -d '/' | cut -f 2 -d '-')"
 echo -e "\n${aVER}" >> /tmp/easy_version_control/all-snapshots
 dashchars="$(echo -n "$aVER" | tr '[0-9.]' '-')"
 echo "$dashchars" >> /tmp/easy_version_control/all-snapshots
 cat $aSSC  >> /tmp/easy_version_control/all-snapshots
done
echo -e "\n\nROLLBACK LOG\n************" >> /tmp/easy_version_control/all-snapshots
if [ -s /mnt/${WKG_DEV}/${WKG_DIR}releases/rollback-log ];then
 cat /mnt/${WKG_DEV}/${WKG_DIR}releases/rollback-log >> /tmp/easy_version_control/all-snapshots
else
 echo -e "\n-nothing yet-" >> /tmp/easy_version_control/all-snapshots
fi

#find all earlier versions and snapshots...
#170218 actions to ensure only one checkbox is ticked --any simpler way to do this?
BACKXML=""; REFRESHXML=""
rm -f /tmp/easy_version_control/chkbx-*
if [ "$BOOT_FS" == "iso9660" ];then #190715 190721
 RELEASES="${DISTRO_VERSION}" #190721 fix.
else
 RELEASES="$(find /mnt/${WKG_DEV}/${WKG_DIR}releases -maxdepth 1 -type d -name 'easy-*' | rev | cut -f 1 -d '/' | rev | cut -f 2 -d '-' | sort -t. -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr)" #version sort, highest to lowest
fi
HI_REL="$(echo "$RELEASES" | head -n 1)"
for aVER in `echo "$RELEASES" | tr '\n' ' '`
do
 ZaVER="$(echo -n "$aVER" | tr '.' 'Z')" #cannot have . in label.
 SNAPXML=""
 for aSNAPDATE in $(find /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${aVER} -maxdepth 1 -type f -name 'rw-*' | rev | cut -f 1 -d '/' | cut -f 2- -d '.' | rev | cut -f 2 -d '-' | grep -v '\.' | tr '\n' ' ') #170525 171226
 do
  echo "false" > /tmp/easy_version_control/chkbx-RW_${ZaVER}_${aSNAPDATE}
  REFRESHXML="${REFRESHXML}<action>refresh:RW_${ZaVER}_${aSNAPDATE}</action>"
  SNAPXML="${SNAPXML}
  <checkbox>
    <input file>/tmp/easy_version_control/chkbx-RW_${ZaVER}_${aSNAPDATE}</input>
    <label>Snapshot ${aSNAPDATE}</label>
    <variable>RW_${ZaVER}_${aSNAPDATE}</variable>
    <action>if true ls -1 /tmp/easy_version_control/chkbx-* | xargs -I SUB sed -i 's%.*%false%' SUB </action>
    <action>if true echo true > /tmp/easy_version_control/chkbx-RW_${ZaVER}_${aSNAPDATE} </action>
    REFRESHACTIONHERE
  </checkbox>"
 done
 echo "false" > /tmp/easy_version_control/chkbx-EASYVC_${ZaVER}
 REFRESHXML="${REFRESHXML}<action>refresh:EASYVC_${ZaVER}</action>"
 BACKXML="${BACKXML}
 <frame Easy ${aVER}>
   <vbox>
     <checkbox>
       <input file>/tmp/easy_version_control/chkbx-EASYVC_${ZaVER}</input>
       <label>Release ${aVER}</label>
       <variable>EASYVC_${ZaVER}</variable>
       <action>if true ls -1 /tmp/easy_version_control/chkbx-* | xargs -I SUB sed -i 's%.*%false%' SUB </action>
       <action>if true echo true > /tmp/easy_version_control/chkbx-EASYVC_${ZaVER} </action>
       REFRESHACTIONHERE
     </checkbox>
     ${SNAPXML}
   </vbox>
 </frame>"
done
PTN="s%REFRESHACTIONHERE%${REFRESHXML}%"
BACKXML2="$(echo "$BACKXML" | sed -e "$PTN")"

if [ "$BOOT_FS" == "iso9660" ];then #190715 190721
 RO_NOTICE="<text><label>$(gettext 'NOTICE: As the boot partition is read-only, cannot rollback to a different version. However, you can bootup an older or newer version to achieve the version change, for example boot an older CD.')</label></text>"
else
 RO_NOTICE=""
fi

HI_CON=''
CONTAINERS="$(ls -1 /mnt/${WKG_DEV}/${WKG_DIR}containers)"
if [ "$CONTAINERS" ];then
 HI_CON="$(echo "$CONTAINERS" | head -n 1)"
 DEF_CON="<default>${HI_CON}</default>"
fi
#script to return list of snapshots in a container:  180428 fix...
cat > /tmp/easy_version_control/ec-ver-snaps <<EOF
#!/bin/sh
#passed param is name of a container. else default to HI_CON
. /etc/rc.d/PUPSTATE
 EC_NAME="\$1"
 [ ! "\$EC_NAME" ] && EC_NAME="${HI_CON}"
 EC_SNAPS="\$(ls -1 /mnt/\${WKG_DEV}/\${WKG_DIR}containers/\${EC_NAME}/rw-*.sfs 2>/dev/null | rev | cut -f 1 -d '-' | cut -f 2- -d '.' | rev)"
 if [ "\$EC_SNAPS" ];then
  echo "\$EC_SNAPS"
 else
  echo '-empty-'
 fi
EOF
chmod 755 /tmp/easy_version_control/ec-ver-snaps

M_close="$(gettext 'Close')"

M_help1="$(gettext 'Easy Linux keeps a record of everything. The user may take a snapshot of the current work at any time, and there will be upgrades to later versions. All snapshots and old versions are saved in the <i>releases</i> folder.')

$(gettext 'Easy Linux also supports containers, which are in the <i>containers</i> folder. Snapshots of current work in each container may also be saved, in this case inside the appropriate container folder.')

<b>$(gettext 'Warning')</b>
$(gettext 'Note that although it is nice to keep all of the history in the releases, this can get out of hand if memory storage is limited. A Flash stick of 8GB for example, may seem like a lot, but can quickly fill.')
$(gettext 'The <i>Depth</i> parameter sets a maximum limit to number of versions recorded. Older versions are deleted from the releases folder.')

<b>$(gettext 'Technical notes')</b>
$(gettext 'Location of releases folder:') /mnt/${WKG_DEV}/${WKG_DIR}releases
$(gettext 'Location of containers folder:') /mnt/${WKG_DEV}/${WKG_DIR}containers
$(gettext '<i>Depth</i> is stored in /var/local/version-history-depth')"
export DLG_HELP1="<window resizable=\"false\" title=\"$(gettext 'Help: Easy Version Control')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_help1}\"</label><variable>DLG_HELP1</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP1</action></button></hbox></vbox></window>"

M_help2="$(gettext 'Easy Linux runs on a layered filesystem. This has one or more read-only layers on the bottom, including <i>easy.sfs</i> that has the entire Easy Linux files.
The top layer is read-write, and this has all of the changes you have made, such as new files and installed packages.')
$(gettext 'It is this read-write (rw) layer that will be saved.')

$(gettext 'Note that the purpose of taking a snapshot, is that it can be rolled back to at any future date.')

<b>$(gettext 'Some reasons for taking a snapshot')</b>
<b>$(gettext '1.')</b> $(gettext 'You have setup theming and network. Later on, you want to get rid of whatever you have done, and go back to this original state.')
<b>$(gettext '2.')</b> $(gettext 'You have added the devx.sfs as a read-only layer. Take a snapshot before compiling and installing source packages, then later can remove them all by rolling back to the snapshot.')

<b>$(gettext 'Technical notes')</b>
$(gettext 'The rw layer is located at:')
/mnt/${WKG_DEV}/${WKG_DIR}.session
$(gettext 'The snapshot will be saved as:')
/mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/rw-${DATE}.sfs"
export DLG_HELP2="<window resizable=\"false\" title=\"$(gettext 'Help: take snapshot')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_help2}\"</label><variable>DLG_HELP2</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP2</action></button></hbox></vbox></window>"

if [ $SESSIONSFSflag -eq 1 ];then #170525
 M_help3b="$(gettext 'Files found inside each easy-<i>version</i> folder are:') ${KERNELNAME}, initrd, easy.sfs, session.sfs, $(gettext 'and any extra SFS files that are desired to be loaded.')"
 M_help3c="
session.sfs: $(gettext 'Merge of session.sfs and rw layer of previous version')"
 M_help4b="$(gettext 'Easy Linux runs on a layered filesystem, with read-only (ro) layers <i>easy.sfs</i> and <i>session.sfs</i>, and a read-write (rw) layer on top.')"
 M_help4c="
$(gettext 'Note that session.sfs is the merge of session.sfs and the rw-layer from the previous version of Easy Linux.')
"
else
 M_help3b="$(gettext 'Files found inside each easy-<i>version</i> folder are:') ${KERNELNAME}, initrd, easy.sfs, $(gettext 'and any extra SFS files that are desired to be loaded.')"
 M_help3c=""
 M_help4b="$(gettext 'Easy Linux runs on a layered filesystem, with read-only (ro) layer <i>easy.sfs</i>, and a read-write (rw) layer on top.')"
 M_help4c=""
fi

M_help3="$(gettext 'Previous versions (releases) of Easy Linux, if any, as well as any snapshots taken by the user, are saved in the <i>releases</i> folder.')

$(gettext 'The reason for keeping all of this history in the releases folder, is that the user can roll back to any earlier version and/or snapshot.')
$(gettext 'Reasons for doing this are varied. Sometimes, a later version proves to be troublesome, therefore it is a simple matter to rollback, until the problems with the later version are sorted out.')
$(gettext 'Snapshots are also useful, as they capture the state of the system when the user has it setup in a particular desired way, which can be rolled back to if there is a mess created later on.')

$(gettext 'As version upgrades occur, the amount of storage occupied by older versions may get excessive, hence the <i>Depth</i> parameter sets a maximum depth for the history. Older versions are deleted.')

<b>$(gettext 'WARNING')</b>
$(gettext 'Rolling back to versions from January 2019 to December 22, 2019, is broken. That is, versions prior to 1.3 in the Pyro series and 2.2 in the Buster series. Rolling back and forward to any snapshot in the same version is OK. From 1.3 and 2.2 onwards, all of rollback should work.')

<b>$(gettext 'Technical notes')</b>
$(gettext 'Location of releases:') /mnt/${WKG_DEV}/${WKG_DIR}releases
$(gettext 'Folders within the repository are named easy-<i>version</i>, where <i>version</i> is the release number.')
$(gettext 'The current easy-<i>version</i> folder:') easy-${DISTRO_VERSION}
$(gettext '<i>Depth</i> is stored in /var/local/version-history-depth')
${M_help3b}
$(gettext 'If there are any snapshots, they are named:') rw-<i>date</i>.sfs
${KERNELNAME}:  $(gettext 'This is the Linux kernel')
initrd:      $(gettext 'This runs at bootup')
easy.sfs:    $(gettext 'This has all of Easy Linux')${M_help3c}"
export DLG_HELP3="<window resizable=\"false\" title=\"$(gettext 'Help: Rollback')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\" width-chars=\"60\"><label>\"${M_help3}\"</label><variable>DLG_HELP3</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP3</action></button></hbox></vbox></window>"

M_help4="${M_help4b}
$(gettext 'It is this rw layer that will be erased.')
${M_help4c}
$(gettext 'The rw layer has all changes made by the user. Theming, network setup, installed packages, etc, are all in this rw layer.')
$(gettext 'Note however, anything installed to /home is outside the rw layer, and will not be erased.')

$(gettext 'NOTE: if you click the Erase button, there will be another window offering to preserve some things, such as browser, audio or video profiles.')

<b>$(gettext 'Technical notes')</b>
$(gettext 'Location of rw folder:') /mnt/${WKG_DEV}/${WKG_DIR}.session
$(gettext 'It is the content of this folder that will be erased.')
$(gettext '/home is a symlink to:') /mnt/${WKG_DEV}/${WKG_DIR}home
$(gettext '/mnt/wkg/home is a symlink to:') /mnt/${WKG_DEV}/${WKG_DIR}home
$(gettext 'This will not be erased. This is where user personal files are kept, such as downloads, photos, videos.')"
export DLG_HELP4="<window resizable=\"false\" title=\"$(gettext 'Help: Erase session')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_help4}\"</label><variable>DLG_HELP4</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP4</action></button></hbox></vbox></window>"

M_help5="$(gettext 'A container is a copy of Easy Linux, to run applications isolated from the main Easy Linux and other containers.')

$(gettext 'This is done for two main reasons, security, and/or to provide a working environment that does not compromise the main Easy Linux. An example of the latter would be compiling and testing source packages.')

$(gettext 'A container is not really a copy, it just seems that way. It is built upon a layered filesystem, with <i>easy.sfs</i> and other read-only layers that are shared with the main Easy Linux and other containers.')

$(gettext 'Each container has its own read-write layer, and this may be erased, or a snapshot taken. If there is a previous snapshot, then it can be rolled-back to.')

<b>$(gettext 'Technical notes')</b>
$(gettext 'Location of containers:') /mnt/${WKG_DEV}/${WKG_DIR}containers"
export DLG_HELP5="<window resizable=\"false\" title=\"$(gettext 'Help: Containers')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_help5}\"</label><variable>DLG_HELP5</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP5</action></button></hbox></vbox></window>"


export EVC_DIALOG="<window title=\"$(gettext 'Easy Version Control')\" icon-name=\"gtk-about\" window_position=\"1\">
 <vbox>
  <text><label>$(gettext 'Here you may choose to take a snapshot of the session, or roll back to an earlier snapshot or version')</label></text>

  <hbox>
    <vbox>
      <frame $(gettext 'Current status')>
        <text><label>$(gettext 'Version:') ${DISTRO_VERSION}</label></text>
      </frame>
    </vbox>
    <vbox>
      <frame $(gettext 'Session')>
       <hbox>
         <text><label>$(gettext 'Erase the working session:')</label></text>
         <vbox><button><label>$(gettext 'Erase')</label><action type=\"exit\">erase</action></button></vbox>
         <vbox><button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP4</action></button></vbox>
       </hbox>
       <hbox>
         <text><label>$(gettext 'Save the working session:')</label></text>
         <vbox><button><label>$(gettext 'Snapshot')</label><action type=\"exit\">snapshot</action></button></vbox>
         <vbox><button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP2</action></button></vbox>
       </hbox>
      </frame>
    </vbox>
  </hbox>

  <frame $(gettext 'Rollback')>
   <hbox>
    ${BACKXML2}
    ${RO_NOTICE}
    <text space-expand=\"true\"><label>\" \"</label></text>
   </hbox>
   <hbox>
     <text><label>$(gettext 'Depth:')</label></text>
     <comboboxtext><variable>DEPTH_MAX</variable><default>${DEPTH_DEF}</default><item>1</item><item>2</item><item>3</item><item>4</item><item>5</item><item>6</item><item>7</item></comboboxtext>
     <text><label>\"  \"</label></text>
     <button><label>$(gettext 'Rollback')</label><action type=\"exit\">rollback</action></button>
     <button tooltip-text=\"$(gettext 'Snapshot comments')\"><input file>/usr/local/lib/X11/mini-icons/mini-Document.xpm</input><action>defaulttextviewer /tmp/easy_version_control/all-snapshots & </action></button>
     <text><label>\"  \"</label></text>
     <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP3</action></button>
   </hbox>
  </frame>
  
  <frame $(gettext 'Containers')>
    <text><label>$(gettext 'Take a snapshot or erase the working session, or rollback to an earlier snapshot, in a container')</label></text>
    <hbox>
      <comboboxtext><variable>EC_NAME</variable>${DEF_CON}<input>ls -1 /mnt/${WKG_DEV}/${WKG_DIR}containers</input><action>refresh:EC_SNAP</action></comboboxtext>
      <button><label>$(gettext 'Erase')</label><action type=\"exit\">ec_erase</action></button>
      <button><label>$(gettext 'Snapshot')</label><action type=\"exit\">ec_snapshot</action></button>
      <text><label>\"  \"</label></text>
      <comboboxtext><variable>EC_SNAP</variable><input>/tmp/easy_version_control/ec-ver-snaps \${EC_NAME} </input></comboboxtext>
      <button><label>$(gettext 'Rollback')</label><action type=\"exit\">ec_rollback</action></button>
      <button tooltip-text=\"$(gettext 'Snapshot comments')\"><input file>/usr/local/lib/X11/mini-icons/mini-Document.xpm</input><action>defaulttextviewer /mnt/${WKG_DEV}/${WKG_DIR}containers/\${EC_NAME}/snapshot-comments & </action></button>
      <text><label>\"  \"</label></text>
      <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP5</action></button>
    </hbox>
  </frame>
  
  <hbox>
   <hbox><button cancel></button></hbox>
   <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP1</action></button>
  </hbox>
 </vbox>
 </window>"

echo "$EVC_DIALOG" > evc.log
RETVARS="$(gtkdialog --program=EVC_DIALOG)"
eval "$RETVARS"

#EXITNOW=1
#[ "$EXIT" == "erase" ] && EXITNOW=0
#[ "$EXIT" == "snapshot" ] && EXITNOW=0
#[ "$EXIT" == "rollback" ] && EXITNOW=0
#[ "$EXIT" == "ec_erase" ] && EXITNOW=0
#[ "$EXIT" == "ec_snapshot" ] && EXITNOW=0
#[ "$EXIT" == "ec_rollback" ] && EXITNOW=0
#[ $EXITNOW -eq 1 ] && exit

if [ "$DEPTH_MAX" != "$DEPTH_DEF" ];then
 echo -n "$DEPTH_MAX" > /var/local/version-history-depth
fi

if [ "$EXIT" == "erase" ];then
 ###NOTICE### cannot do it now, done in initramfs.
 #rm -rf /mnt/${WKG_DEV}/${WKG_DIR}.session/*
 
 #200813 ask about exceptions...
 /usr/local/easy_version/erase-exceptions
 if [ $? -eq 0 ];then 
  echo -n ",erase" > /.rollback.flg #init in initramfs will read this.
  pupdialog --background '#40FF40' --backtitle "$(gettext 'Erase almost completed')" --msgbox "$(gettext 'The rw layer will be erased. However, as this is currently in use, a reboot is required to take effect.')" 0 0
 else
  [ -f /.rollback.flg ] && rm -f /.rollback.flg
  pupdialog --background '#FF8080' --backtitle "$(gettext 'Erase aborted')" --msgbox "$(gettext 'Confirming, you decided not to erase the working session.')" 0 0
 fi
 
fi

if [ "$EXIT" == "snapshot" ];then
 #170525 some exclusions from snapshot... 180606 need path root/.XLOADED  181121 exclude .control
 echo -e 'dev\nmnt\nproc\nrun\nsys\ntmp\nvar\n.fsckme.flg\nlost+found\nroot/.XLOADED\n.control' > /tmp/easy_version_control/snapshot-exclusions1
 urxvt -bg '#09A0FF' -e mksquashfs /mnt/${WKG_DEV}/${WKG_DIR}.session /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/rw-${DATE}.sfs -ef /tmp/easy_version_control/snapshot-exclusions1 -no-exports
 cp -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/configuration /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/configuration-${DATE} #170225
 sync
# popup "background=#40FF10 level=top terminate=ok|<big>$(gettext 'Snapshot created!')</big>
#$(gettext 'Snapshot file:') /mnt/${WKG_DEV}/${WKG_DIR}releases/rw-${DATE}.sfs"
 echo -n "${DATE} " >> /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/snapshot-comments
 pupdialog --background '#40FF40' --backtitle "$(gettext 'Snapshot created')"  --inputbox "$(gettext 'Snapshot file:') /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/rw-${DATE}.sfs
$(gettext 'Please type a short one-line comment about this snapshot:')" 0 0 2> /tmp/easy_version_control/comment
 cat /tmp/easy_version_control/comment >> /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${DISTRO_VERSION}/snapshot-comments #170527
 exit
fi

#170525
reconstitute_sessionsfs_func() {
 localBackVer="$1"
 ROLAYERS=""
 if [ ! -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${localBackVer}/session.sfs ];then
  for APREVER in $revsortedVERS
  do
   [ "$APREVER" == "" ] && continue #precaution
   if vercmp ${APREVER} gt ${localBackVer}; then continue; fi
   if [ -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${localBackVer}/session.sfs ];then
    mkdir -p /tmp/easy_version_control/sessionsfs
    busybox mount -t squashfs -o loop,noatime /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${APREVER}/session.sfs /tmp/easy_version_control/sessionsfs
    ROLAYERS="${ROLAYERS}:/tmp/easy_version_control/sessionsfs${RO}"
    break
   else
    mkdir -p /tmp/easy_version_control/${APREVER}
    busybox mount -t squashfs -o loop,noatime /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${APREVER}/rw-${APREVER}.sfs /tmp/easy_version_control/${APREVER}
    ROLAYERS="${ROLAYERS}:/tmp/easy_version_control/${APREVER}${RO}"
   fi
  done
 fi
 if [ "$ROLAYERS" ];then
  xROLAYERS="$(echo -n "$ROLAYERS" | sed -e 's%^:%%')"
  mkdir -p /tmp/easy_version_control/tempwork
  mkdir -p /tmp/easy_version_control/rwlayer
  mkdir -p /tmp/easy_version_control/mntpt
  if [ "$LAYERFS" == "aufs" ];then
   mount -t aufs -o br=/tmp/easy_version_control/rwlayer=rw${ROLAYERS} aufs /tmp/easy_version_control/mntpt
  else
   mount -t overlay -o lowerdir=${xROLAYERS},upperdir=/tmp/easy_version_control/rwlayer,workdir=/tmp/easy_version_control/tempwork overlay /tmp/easy_version_control/mntpt
  fi
  urxvt -bg '#09A0FF' -e mksquashfs /tmp/easy_version_control/mntpt /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${localBackVer}/session.sfs #>/dev/null
  sync
  for AMNTD in `echo -n "$xROLAYERS" | tr ':' '\n' | cut -f 1 -d '=' | tr '\n' ' '`
  do
   busybox umount $AMNTD
  done
 fi
}

if [ "$EXIT" == "rollback" ];then
 backEASYver="$(echo "$RETVARS" | grep '^EASYVC_' | grep '"true"' | cut -f 2 -d '_' | cut -f 1 -d '=' | tr 'Z' '.')"
 if [ "$backEASYver" ];then
  #roll back to this version
  if [ "${DISTRO_VERSION}" != "${backEASYver}" ];then #200829 precaution.
   UMNTFLG=0
   if [ "$(mount | grep "/mnt/${BOOT_DEV} ")" == "" ];then
    mkdir -p /mnt/${BOOT_DEV}
    mount -t ${BOOT_FS} /dev/${BOOT_DEV} /mnt/${BOOT_DEV}
    UMNTFLG=1
   fi
   ###NOTICE### do not copy .session as in layer fs. init will do it.
   cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backEASYver}/${KERNELNAME} /mnt/${BOOT_DEV}/${BOOT_DIR} #200829 -a
   #cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backEASYver}/initrd /mnt/${BOOT_DEV}/${BOOT_DIR} #200729 do not change this file.
   #200829 copy easy.sfs now, so that INIT_DISTRO_VERSION will be correct in init script in initrd, note /sbin/rollback in initrd will copy it again...
   cp -L -p -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backEASYver}/easy.sfs /mnt/${BOOT_DEV}/${BOOT_DIR} #200830 -p
   cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backEASYver}/configuration-${backEASYver} /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backEASYver}/configuration #170225 200829
   sync
   if [ $SESSIONSFSflag -eq 1 ];then
    #170525 if no session.sfs in previous easy- folder, reconstitute it...
    reconstitute_sessionsfs_func ${backEASYver}
    echo -n "${backEASYver},erase" > /.rollback.flg #init in initramfs will read this. 170526 170529
   else
    echo -n "${backEASYver},${backEASYver}" > /.rollback.flg #init in initramfs will read this. 170526
   fi
   sync
   [ $UMNTFLG -eq 1 ] && busybox umount /mnt/${BOOT_DEV} #180602
  fi
  echo -e "\nDate: ${DATE}\n------------------\n$(gettext 'Current version:') ${DISTRO_VERSION}\n$(gettext 'Rolled-back version:') ${backEASYver}" >> /mnt/${WKG_DEV}/${WKG_DIR}releases/rollback-log #171226
  pupdialog --background '#40FF40' --backtitle "$(gettext 'Rollback almost completed')" --msgbox "$(gettext 'Current version:') ${DISTRO_VERSION}
$(gettext 'Rolled-back version:') ${backEASYver}
$(gettext 'This requires a reboot to take effect')" 0 0
 else
  backSNAP="$(echo "$RETVARS" | grep '^RW_' | grep '"true"' | cut -f 2,3 -d '_' | cut -f 1 -d '=' | tr 'Z' '.')"
  if [ "$backSNAP" ];then
   backVER="$(echo -n "$backSNAP" | cut -f 1 -d '_')"
   backDATE="$(echo -n "$backSNAP" | cut -f 2 -d '_')"
   UMNTFLG=0
   if [ "$backVER" != "$DISTRO_VERSION" ];then
    if [ "$(mount | grep "/mnt/${BOOT_DEV} ")" == "" ];then
     mkdir -p /mnt/${BOOT_DEV}
     mount -t ${BOOT_FS} /dev/${BOOT_DEV} /mnt/${BOOT_DEV}
     UMNTFLG=1
    fi
    cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backVER}/${KERNELNAME} /mnt/${BOOT_DEV}/${BOOT_DIR} #200829
    #cp -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backVER}/initrd /mnt/${BOOT_DEV}/${BOOT_DIR} #200729 do not change this file.
    cp -L -p -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backVER}/easy.sfs /mnt/${BOOT_DEV}/${BOOT_DIR} #200830 -p
    if [ $SESSIONSFSflag -eq 1 ];then
     #170525 if no session.sfs in previous easy- folder, reconstitute it...
     reconstitute_sessionsfs_func ${backVER}
    fi
    sync
   fi
   cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backVER}/configuration-${backDATE} /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${backVER}/configuration #200829
   ###NOTICE### do not copy .session as in layer fs. init will do it.
   sync
   #busybox umount /tmp/evc-snap-mnt
   [ $UMNTFLG -eq 1 ] && busybox umount /mnt/${BOOT_DEV}
   if [ "$backVER" == "$DISTRO_VERSION" ];then
    echo -e "\nDate: ${DATE}\n------------------\n$(gettext 'Version:') ${DISTRO_VERSION}\n$(gettext 'Rolled-back to snapshot:') rw-${backDATE}.sfs" >> /mnt/${WKG_DEV}/${WKG_DIR}releases/rollback-log #171226
    echo -n ",${backDATE}" > /.rollback.flg #init in initramfs will read this.
    MSGdone="$(gettext 'Rolled-back to snapshot:') rw-${backDATE}.sfs
$(gettext 'This will be copied to:') /mnt/${WKG_DEV}/${WKG_DIR}.session
$(gettext 'This requires a reboot to take effect.')"
   else
    echo -e "\nDate: ${DATE}\n------------------\n$(gettext 'Rolled-back to version:') ${backVER}\n$(gettext 'Rolled-back to snapshot:') ${backDATE}" >> /mnt/${WKG_DEV}/${WKG_DIR}releases/rollback-log #171226
    echo -n "${backVER},${backDATE}" > /.rollback.flg #init in initramfs will read this.
    MSGdone="$(gettext 'Rolled-back to version:') ${backVER}
$(gettext 'Rolled-back to snapshot:') ${backDATE}
$(gettext 'This will be copied to:') /mnt/${WKG_DEV}/${WKG_DIR}.session
$(gettext 'This requires a reboot to take effect.')"
   fi
   pupdialog --background '#40FF40' --backtitle "$(gettext 'Rollback almost completed')" --msgbox "${MSGdone}" 0 0
  fi
 fi
fi

if [ "$EXIT" == "ec_erase" ];then
 test_cont_mntd_func #test if container in use.
 if [ $? -ne 0 ];then
  if [ "$EC_NAME" == "desk" ];then #181017
   pupdialog --background '#FF8080' --backtitle "$(gettext 'ERROR: Container') ${EC_NAME}" --msgbox "$(gettext 'Sorry the container is currently in use. The read-write layer cannot be erased. It is required to restart the X server or reboot (see the Shutdown menu) to stop the desk container. Aborting.')" 0 0
  else
   pupdialog --background '#FF8080' --backtitle "$(gettext 'ERROR: Container') ${EC_NAME}" --msgbox "$(gettext 'Sorry the container is currently in use. The read-write layer cannot be erased. Aborting.')" 0 0
  fi
  exit
 fi
 rm -rf /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/*
 #181121 consider SKEL may have .control folder...
 rm -rf /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/.[a-z]* 2>/dev/null #180624 aufs top-level .wh* dirs/files. 181121 avoid deleting .control  181123
 [ -d /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.sessionSKEL ] && cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.sessionSKEL/* /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/ #181017
 [ -d /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.sessionSKEL/.control ] && cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.sessionSKEL/.control /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/
 pupdialog --background '#40FF40' --backtitle "$(gettext 'Container:') ${EC_NAME}" --msgbox "$(gettext 'The container read-write layer has been erased.')" 0 0
fi

if [ "$EXIT" == "ec_snapshot" ];then
 test_cont_mntd_func #test if container in use.
 [ $? -ne 0 ] && exit
 #170525 some exclusions from snapshot... 180606 need path root/.XLOADED 181121 exclude .control
 echo -e 'dev\nmnt\nproc\nrun\nsys\ntmp\nvar\n.fsckme.flg\nlost+found\nroot/.XLOADED\n.control' > /tmp/easy_version_control/snapshot-exclusions1
 urxvt -bg '#09A0FF' -e mksquashfs /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/rw-${DATE}.sfs -ef /tmp/easy_version_control/snapshot-exclusions1 -no-exports
 cp -f /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/configuration /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/configuration-${DATE}
 sync
 echo -n "${DATE} " >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/snapshot-comments
 pupdialog --background '#40FF40' --backtitle "$(gettext 'Snapshot created')"  --inputbox "$(gettext 'Snapshot file:') /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/rw-${DATE}.sfs
$(gettext 'Please type a short one-line comment about this snapshot:')" 0 0 2> /tmp/easy_version_control/comment
 cat /tmp/easy_version_control/comment >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/snapshot-comments #170527 180428
fi

if [ "$EXIT" == "ec_rollback" ];then
 test_cont_mntd_func #test if container in use.
 [ $? -ne 0 ] && exit
 mkdir -p /tmp/easy_version_control/tmpmnt
 busybox mount -t squashfs -o loop,noatime /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/rw-${EC_SNAP}.sfs /tmp/easy_version_control/tmpmnt
 rm -rf /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/*
 #181121 consider SKEL may have .control folder...
 rm -rf /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/.[a-z]* 2>/dev/null #180624 aufs top-level .wh* dirs/files. 181121 avoid deleting .control  181123
 [ -d /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.sessionSKEL ] && cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.sessionSKEL/* /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/ #181017
 [ -d /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.sessionSKEL/.control ] && cp -a -f /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.sessionSKEL/.control /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/
 cp -a -f /tmp/easy_version_control/tmpmnt/* /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/.session/
 [ -f /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/configuration-${EC_SNAP} ] && cp -f /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/configuration-${EC_SNAP} /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_NAME}/configuration
 sync
 busybox umount /tmp/easy_version_control/tmpmnt
fi

###end###
