#!/bin/bash do { #//////////////////////////////////// # DietPi Backup # #//////////////////////////////////// # Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com # #//////////////////////////////////// # # Info: # - filename /DietPi/dietpi/dietpi-backup # - Allows for a complete system back and restore of the linux filesystem (/) # # Usage: # - /DietPi/dietpi/dietpi-backup -1 = Restore # - /DietPi/dietpi/dietpi-backup = Menu # - /DietPi/dietpi/dietpi-backup 1 = Backup # # $2 = optional directory location to use with backup/restore input: # - /DietPi/dietpi/dietpi-backup -1 /mnt/MyDirectoryTarget = Restore # - /DietPi/dietpi/dietpi-backup 1 /mnt/MyDirectoryTarget = Backup #//////////////////////////////////// #Grab Input setglobal INPUT = '0' if [[ $1 =~ ^-?[0-9]+$ ]] { setglobal INPUT = $1 } #Import DietPi-Globals --------------------------------------------------------------- source /DietPi/dietpi/func/dietpi-globals G_CHECK_ROOT_USER G_CHECK_ROOTFS_RW export G_PROGRAM_NAME='DietPi-Backup' #Import DietPi-Globals --------------------------------------------------------------- #///////////////////////////////////////////////////////////////////////////////////// # MENUS #///////////////////////////////////////////////////////////////////////////////////// setglobal WHIP_BACKTITLE = ''DietPi-Backup'' setglobal WHIP_TITLE = '''' setglobal MENU_LASTITEM = '''' setglobal CHOICE = '0' setglobal OPTION = '0' setglobal TARGETMENUID = '0' #TARGETMENUID=0 proc Menu_Main{ local backup_last_completed_system='System backup not found. Create one.' if test -f "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" { setglobal backup_last_completed_system = $[grep 'Completed' "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" | tail -1] } local backup_last_completed_userdata='User data backup not found (requires "Full" backup mode)' if test -f "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_USERDATA" { setglobal backup_last_completed_userdata = $[grep 'Completed' "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_USERDATA" | tail -1] } local text_backup_mode='System only' local text_start_mode_desc='system' if sh-expr ' $BACKUP_MODE == 1 ' { setglobal text_backup_mode = ''Full'' setglobal text_start_mode_desc = ''system and user data'' } setglobal WHIP_TITLE = ''DietPi-Backup'' setglobal OPTION = $[whiptail --title $WHIP_TITLE --menu "Current backup and restore location:\n - $FP_TARGET_BACKUP\n - $backup_last_completed_system\n - $backup_last_completed_userdata" --cancel-button "Exit" --default-item $MENU_LASTITEM --backtitle $WHIP_BACKTITLE 16 80 5 \ "Help" "What does DietPi-Backup do?" \ "Location" "Change where your backup will be saved and restored from." \ "Backup mode" ": $text_backup_mode" \ "Backup" "Create (or update) a backup of this system." \ "Restore" "Restore this system from a previous backup." !3 > !1 !1 > !2 !2 > !3] setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { setglobal MENU_LASTITEM = $OPTION match $OPTION { with Location setglobal TARGETMENUID = '1' with "Backup mode" setglobal OPTION = $[whiptail --title $WHIP_TITLE --menu "Please select a backup mode:\n\n - System only\nOnly the system is backed up and restored, this does not include your DietPi user data ($G_FP_DIETPI_USERDATA).\n\n - Full:\nSystem and user data ($G_FP_DIETPI_USERDATA) is backed up and restored.\n\nMore information on what DietPi user data is:\nhttp://dietpi.com/phpbb/viewtopic.php?f=8&t=478#p2087" --cancel-button "Exit" --default-item $BACKUP_MODE --backtitle $WHIP_BACKTITLE 20 80 2 \ "0" "System only" \ "1" "Full (includes user data)" !3 > !1 !1 > !2 !2 > !3] setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { setglobal BACKUP_MODE = $OPTION } with Help whiptail --title "DietPi-Backup Help" --msgbox "DietPi-Backup is a program that allows you to Backup and Restore your DietPi system.\n\nIf you have broken your system, or want to reset your system to an earlier date, this can all be done with DietPi-Backup.\n\nSimply choose a location where you want to save and restore your backups from, then, select Backup or Restore.\n\nMore information:\n - http://dietpi.com/phpbb/viewtopic.php?f=8&t=5&p=256#p255" --backtitle $WHIP_BACKTITLE 20 75 with Backup setglobal WHIP_TITLE = '' Start backup? '' whiptail --title $WHIP_TITLE --yesno "Your $text_start_mode_desc will be backed up to:\n$FP_TARGET_BACKUP\n\nDo you wish to continue?" --yes-button "Ok" --no-button "Back" --defaultno --backtitle $WHIP_BACKTITLE 11 65 setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { Run_Backup } with Restore setglobal WHIP_TITLE = '' Start restore? '' whiptail --title $WHIP_TITLE --yesno "Your $text_start_mode_desc will be restored from:\n$FP_TARGET_BACKUP\n\nDo you wish to continue?" --yes-button "Ok" --no-button "Back" --defaultno --backtitle $WHIP_BACKTITLE 11 65 setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { Run_Restore } } } else { Menu_Exit } } proc Menu_Exit{ setglobal WHIP_TITLE = '' Exit DietPi-Backup? '' whiptail --title $WHIP_TITLE --yesno $WHIP_TITLE --yes-button "Ok" --no-button "Back" --defaultno --backtitle $WHIP_BACKTITLE 10 50 setglobal CHOICE = $Status #Exit if sh-expr ' $CHOICE == 0 ' { setglobal TARGETMENUID = '-1' } } #TARGETMENUID=1 proc Menu_Set_Directory{ local current_directory="$FP_TARGET_BACKUP" setglobal WHIP_TITLE = ''Select your backup and restore location'' setglobal OPTION = $[whiptail --title $WHIP_TITLE --menu "Please select the location where your system backup will be saved, and restored from.\n\nYour current location:\n$FP_TARGET_BACKUP" --cancel-button "Back" --backtitle $WHIP_BACKTITLE 15 75 3 \ "Search" "Find previous backups in /mnt/*" \ "List" "Select from a list of available mounts/drives" \ "Manual" "Manually type a directory to use." !3 > !1 !1 > !2 !2 > !3] setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { match $OPTION { with Search local fp_search_results="/tmp/.dietpi-backup_search_results" echo -e "\n\nSearching /mnt/* for previous backups, please wait... \n \n" find /mnt -type f -name $BACKUP_STATS_FILENAME_SYSTEM > $fp_search_results #Do we have any results? if sh-expr ' $(cat "$fp_search_results" | wc -l) > 0 ' { readarray search_results_list < $fp_search_results #Create List for Whiptail local search_results_whiptail=() for ((i=0; i<${#search_results_list[@]}; i++)) do local last_backup_date=$( grep 'Completed' ${search_results_list[$i]} | tail -1 | sed 's/.*: //' ) # Date of last backup for this backup local backup_directory=$( echo -e ${search_results_list[$i]} | sed 's/\/'"$BACKUP_STATS_FILENAME_SYSTEM"'//g' ) # Backup directory (minus the backup file), that we can use for target backup directory. search_results_whiptail+=("$backup_directory" ": $last_backup_date") done setglobal OPTION = $[whiptail --title "Backups found." --menu "Please select a previous backup to use:" --cancel-button "Back" --backtitle $WHIP_BACKTITLE 12 70 3 $(search_results_whiptail[@]) !3 > !1 !1 > !2 !2 > !3] setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { setglobal FP_TARGET_BACKUP = $OPTION } #delete[] array unset search_results_list unset search_results_whiptail rm $fp_search_results &> /dev/null } else { whiptail --title "No results" --msgbox "No previous backups were found in /mnt/*" --backtitle $WHIP_BACKTITLE 10 60 } with Manual Input_User_Directory with List /DietPi/dietpi/dietpi-drive_manager 1 setglobal FP_TARGET_BACKUP = $[cat /tmp/dietpi-drive_manager_selmnt] if test $FP_TARGET_BACKUP = "/" { setglobal FP_TARGET_BACKUP = ''/mnt'' } setglobal FP_TARGET_BACKUP = ''/dietpi-backup'' } } else { #Return to main menu setglobal TARGETMENUID = '0' } Check_Supported_Directory_Location # - Not supported, reset directory target to previous if sh-expr ' $TARGET_DIRECTORY_SUPPORTED == 0 ' { setglobal FP_TARGET_BACKUP = $current_directory } } proc Input_User_Directory{ setglobal OPTION = $[whiptail --inputbox "Please enter the filepath to your directory. \neg: /mnt/dietpi-backup\n - Must be located inside /mnt/* \n - Must be symlink compatible filesystem (ext2/3/4)" 10 70 $FP_TARGET_BACKUP --title "Manual backup directory" --backtitle $WHIP_BACKTITLE !3 > !1 !1 > !2 !2 > !3] setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { setglobal FP_TARGET_BACKUP = $OPTION } } #///////////////////////////////////////////////////////////////////////////////////// # Errors #///////////////////////////////////////////////////////////////////////////////////// proc Error_Filesystem_Not_Supported{ G_DIETPI-NOTIFY 1 "Filesystem not supported in $FP_TARGET_BACKUP" if sh-expr ' $G_USER_INPUTS ' { whiptail --title "Error" --msgbox "$FP_TARGET_BACKUP Has a filesystem of: $TARGET_FILESYSTEM_TYPE, and is not supported.\n\nThe filesystem must be EXT2/3/4 for symlink compatibility." --backtitle $WHIP_BACKTITLE 11 70 } } proc Error_Not_Mnt_Directory{ G_DIETPI-NOTIFY 1 "Target directory is not inside /mnt ($FP_TARGET_BACKUP)" if sh-expr ' $G_USER_INPUTS ' { whiptail --title "Directory not supported" --msgbox "$FP_TARGET_BACKUP\n\nYour current location is not supported.\nThe location must be inside the /mnt/* directory.\n - eg: /mnt/dietpi-backup" --backtitle $WHIP_BACKTITLE 11 70 } } proc Error_DietpiUserdata_Directory{ G_DIETPI-NOTIFY 1 "Target directory can not be contained within DietPi user data location ($FP_TARGET_BACKUP)" if sh-expr ' $G_USER_INPUTS ' { whiptail --title "Directory not supported" --msgbox "$FP_TARGET_BACKUP\n\nYour current location is not supported.\nTarget directory can not be contained within DietPi user data location ($G_FP_DIETPI_USERDATA)" --backtitle $WHIP_BACKTITLE 13 70 } } proc Error_Rsync_Already_Running{ G_DIETPI-NOTIFY 1 "Another Rsync process is already running." echo -e "$RSYNC_MODE_TEXT failed: $[date +"%d-%m-%Y_%H%M]. Rsync is already running." >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" #Menu if sh-expr ' $G_USER_INPUTS ' { whiptail --title "$RSYNC_MODE_TEXT Error" --msgbox "A $RSYNC_MODE_TEXT could not be started as rsync is already running." --backtitle $WHIP_BACKTITLE 13 60 } } proc Error_Rsync_Failed{ G_DIETPI-NOTIFY 1 "$RSYNC_MODE_TEXT failed." #Menu if sh-expr ' $G_USER_INPUTS ' { whiptail --title "$RSYNC_MODE_TEXT failed" --msgbox "Your $RSYNC_MODE_TEXT has failed. Please see the Log file for more information:\n\n$LOGFILE" --backtitle $WHIP_BACKTITLE 12 60 } } #///////////////////////////////////////////////////////////////////////////////////// # Backup System #///////////////////////////////////////////////////////////////////////////////////// setglobal RSYNC_MODE_TEXT = '0' setglobal BACKUP_MODE = '1' #0=system only, 1=full (system and userdata) #LOGFILE setglobal LOGFILE = ''/var/log/dietpi-backup.log'' #Backup Filepaths setglobal FP_SOURCE_SYSTEM = ''/'' setglobal FP_TARGET_BACKUP = ''/mnt/dietpi-backup'' setglobal G_FP_DIETPI_USERDATA_ACTUAL = $[readlink -f /mnt/dietpi_userdata] #file applied to successful backups (stored in "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" setglobal BACKUP_STATS_FILENAME_SYSTEM = ''.dietpi-backup_system_stats'' setglobal BACKUP_STATS_FILENAME_USERDATA = ''.dietpi-backup_userdata_stats'' #Exclude/include file setglobal FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP = ''/tmp/.dietpi-backup_filter_inc_exc'' setglobal FP_EXCLUDE_USER = ''/DietPi/dietpi/.dietpi-backup_exclude'' setglobal FP_INCLUDE_USER = ''/DietPi/dietpi/.dietpi-backup_include'' #Supported filesystems setglobal TARGET_FILESYSTEM_TYPE = '0' setglobal TARGET_DIRECTORY_SUPPORTED = '0' setglobal aSUPPORTED_FILESYSTEMS = ''( 'ext4' 'ext3' 'ext2' 'nfs' 'nfs4' 'btrfs' ) #rsync options setglobal RSYNC_RUN_OPTIONS_SYSTEM_BACKUP = ""-alHpvP --delete --log-file=$LOGFILE --include-from=$FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP"" setglobal RSYNC_RUN_OPTIONS_USERDATA_BACKUP = ""-alHpvP --delete --log-file=$LOGFILE"" #Sucessful backup/restore states setglobal BACKUP_RESTORE_FAILED = '0' #Date format for logs proc Print_Date{ echo -e $[date +"%d-%m-%Y %H:%M] } proc Create_Filter_Include_Exclude{ #Include cat << """ > "$FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP" #INCLUDE #Global - Folders #+ /example/ """ > $FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP #INCLUDE #Global - Folders #+ /example/ _EOF_ # - Add users additional list if test -f $FP_INCLUDE_USER { echo -e "\n#User include file" >> $FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP while read -r line { echo -e "+ $line" >> $FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP } < "$FP_INCLUDE_USER" } #Exclude cat << """ >> "$FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP" #EXCLUDE #Global - Folders - $FP_TARGET_BACKUP/ - /mnt/ - /media/ - /dev/ - /proc/ - /sys/ - /tmp/ - /run/ #Apt package cache (.deb) - /var/cache/apt/archives/ #Manpages / Docs - /usr/share/man/ - /usr/share/doc/ #Global - Files - $LOGFILE - $FP_DIETPIBACKUP_SETTINGS - $BACKUP_STATS_FILENAME_SYSTEM - $BACKUP_STATS_FILENAME_USERDATA - /var/swap - fake-hwclock.data - *.tmp #MS Windows specific - Thumbs.db - desktop.ini """ >> $FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP #EXCLUDE #Global - Folders - $FP_TARGET_BACKUP/ - /mnt/ - /media/ - /dev/ - /proc/ - /sys/ - /tmp/ - /run/ #Apt package cache (.deb) - /var/cache/apt/archives/ #Manpages / Docs - /usr/share/man/ - /usr/share/doc/ #Global - Files - $LOGFILE - $FP_DIETPIBACKUP_SETTINGS - $BACKUP_STATS_FILENAME_SYSTEM - $BACKUP_STATS_FILENAME_USERDATA - /var/swap - fake-hwclock.data - *.tmp #MS Windows specific - Thumbs.db - desktop.ini _EOF_ #Add users additional list if test -f $FP_EXCLUDE_USER { echo -e "\n#User exclude file" >> $FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP while read -r line { echo -e "- $line" >> $FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP } < "$FP_EXCLUDE_USER" } #DEBUG cp $FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP /tmp/.dietpi-backup_inc_exc_list } proc Services_Stop{ /DietPi/dietpi/dietpi-services stop } proc Services_Start{ /DietPi/dietpi/dietpi-services start } proc Run_Backup{ setglobal RSYNC_MODE_TEXT = '"Backup'" G_DIETPI-NOTIFY 3 DietPi-Backup $RSYNC_MODE_TEXT #Check valid FS Check_Supported_Directory_Location #Filesystem supported if sh-expr ' $TARGET_DIRECTORY_SUPPORTED == 1 ' { #Generate target dir. mkdir -p $FP_TARGET_BACKUP #Error: Unable to create target folder. if test ! -d $FP_TARGET_BACKUP { if sh-expr ' $G_USER_INPUTS ' { whiptail --title "$RSYNC_MODE_TEXT failed." --msgbox "Unable to create $FP_TARGET_BACKUP" --backtitle $WHIP_BACKTITLE 10 60 } #Error: Rsync is already running } elif sh-expr ' $(ps aux | grep -ci -m1 "[r]sync") == 1 ' { Error_Rsync_Already_Running } else { #Start Backup echo -e "DietPi-Backup Log File. $[date +"%d-%m-%Y_%H%M]\n\n" > $LOGFILE #Generate Exclude/Include lists Create_Filter_Include_Exclude Services_Stop G_DIETPI-NOTIFY 2 "Backing up to: $FP_TARGET_BACKUP" setglobal BACKUP_RESTORE_FAILED = '0' while true { # - system setglobal RSYNC_MODE_TEXT = ''Backup (system)'' rsync $RSYNC_RUN_OPTIONS_SYSTEM_BACKUP $FP_SOURCE_SYSTEM "$FP_TARGET_BACKUP"/dietpi-backup_system/ if sh-expr ' $? == 0 ' { G_DIETPI-NOTIFY 0 "$RSYNC_MODE_TEXT Completed.\n" echo -e "$RSYNC_MODE_TEXT Completed : $[Print_Date]" >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" } else { G_DIETPI-NOTIFY 1 "$RSYNC_MODE_TEXT FAILED.\n" echo -e "$RSYNC_MODE_TEXT FAILED : $[Print_Date]" >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" setglobal BACKUP_RESTORE_FAILED = '1' break } # - userdata setglobal RSYNC_MODE_TEXT = ''Backup (user data)'' if sh-expr ' $BACKUP_MODE == 1 ' { rsync $RSYNC_RUN_OPTIONS_USERDATA_BACKUP "$G_FP_DIETPI_USERDATA_ACTUAL"/ "$FP_TARGET_BACKUP"/dietpi-backup_userdata/ if sh-expr ' $? == 0 ' { G_DIETPI-NOTIFY 0 "$RSYNC_MODE_TEXT Completed.\n" echo -e "$RSYNC_MODE_TEXT Completed : $[Print_Date]" >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_USERDATA" } else { G_DIETPI-NOTIFY 1 "$RSYNC_MODE_TEXT FAILED.\n" echo -e "$RSYNC_MODE_TEXT FAILED : $[Print_Date]" >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_USERDATA" setglobal BACKUP_RESTORE_FAILED = '1' break } } # - done break } if sh-expr ' $BACKUP_RESTORE_FAILED ' { Error_Rsync_Failed } else { if sh-expr ' $G_USER_INPUTS ' { setglobal RSYNC_MODE_TEXT = ''Backup'' whiptail --title "$RSYNC_MODE_TEXT completed" --msgbox "Your $RSYNC_MODE_TEXT was saved to:\n$FP_TARGET_BACKUP\n\nLog file: $LOGFILE" --backtitle $WHIP_BACKTITLE 11 60 } } Services_Start #return to main menu setglobal TARGETMENUID = '0' } } } proc Run_Restore{ setglobal RSYNC_MODE_TEXT = '"Restore'" G_DIETPI-NOTIFY 3 DietPi-Backup $RSYNC_MODE_TEXT #Check valid FS Check_Supported_Directory_Location #Filesystem supported if sh-expr ' $TARGET_DIRECTORY_SUPPORTED == 1 ' { #Error: Backup not found if test ! -f "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" { G_DIETPI-NOTIFY 2 "No Backup was found in $FP_TARGET_BACKUP" G_DIETPI-NOTIFY 1 "$RSYNC_MODE_TEXT Failed.\n" if sh-expr ' $G_USER_INPUTS ' { whiptail --title "$RSYNC_MODE_TEXT failed" --msgbox "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM does not exist\n\nHave you created a backup?" --backtitle $WHIP_BACKTITLE 11 70 } #Error: Rsync is already running } elif sh-expr ' $(ps aux | grep -ci -m1 "[r]sync") == 1 ' { Error_Rsync_Already_Running #Restore } else { #Generate Exclude/Include lists Create_Filter_Include_Exclude Services_Stop G_DIETPI-NOTIFY 2 "Restoring from: $FP_TARGET_BACKUP" setglobal BACKUP_RESTORE_FAILED = '0' while true { # - System setglobal RSYNC_MODE_TEXT = ''Restore (system)'' rsync $RSYNC_RUN_OPTIONS_SYSTEM_BACKUP "$FP_TARGET_BACKUP"/dietpi-backup_system/ $FP_SOURCE_SYSTEM if sh-expr ' $? == 0 ' { G_DIETPI-NOTIFY 0 "$RSYNC_MODE_TEXT Completed.\n" echo -e "$RSYNC_MODE_TEXT Completed : $[Print_Date]" >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" } else { G_DIETPI-NOTIFY 1 "$RSYNC_MODE_TEXT FAILED.\n" echo -e "$RSYNC_MODE_TEXT FAILED : $[Print_Date]" >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_SYSTEM" setglobal BACKUP_RESTORE_FAILED = '1' break } # - User data setglobal RSYNC_MODE_TEXT = ''Restore (user data)'' if sh-expr ' $BACKUP_MODE == 1 ' { # - Only restore userdata if a backup exists if test -f "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_USERDATA" { rsync $RSYNC_RUN_OPTIONS_USERDATA_BACKUP "$FP_TARGET_BACKUP"/dietpi-backup_userdata/ "$G_FP_DIETPI_USERDATA_ACTUAL"/ if sh-expr ' $? == 0 ' { G_DIETPI-NOTIFY 0 "$RSYNC_MODE_TEXT Completed.\n" echo -e "$RSYNC_MODE_TEXT Completed : $[Print_Date]" >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_USERDATA" } else { G_DIETPI-NOTIFY 1 "$RSYNC_MODE_TEXT FAILED.\n" echo -e "$RSYNC_MODE_TEXT FAILED : $[Print_Date]" >> "$FP_TARGET_BACKUP/$BACKUP_STATS_FILENAME_USERDATA" setglobal BACKUP_RESTORE_FAILED = '1' break } } else { G_DIETPI-NOTIFY 2 "$RSYNC_MODE_TEXT: No backup exists, skipping...\n" } } # - done break } if sh-expr ' $BACKUP_RESTORE_FAILED ' { Error_Rsync_Failed } else { if sh-expr ' $G_USER_INPUTS ' { setglobal RSYNC_MODE_TEXT = ''Restore'' whiptail --title "$RSYNC_MODE_TEXT completed" --msgbox "$RSYNC_MODE_TEXT completed from:\n$FP_TARGET_BACKUP\n\nLog file: $LOGFILE\n\nA Reboot is required." --backtitle $WHIP_BACKTITLE 13 60 } } Services_Start #return to main menu setglobal TARGETMENUID = '0' } } } proc Check_Install_PreReqs{ G_AG_CHECK_INSTALL_PREREQ rsync } proc Check_Supported_Directory_Location{ setglobal TARGET_DIRECTORY_SUPPORTED = '0' #Disallow dietpi_userdata location, due to includes in that location if [[ "$FP_TARGET_BACKUP" == "$G_FP_DIETPI_USERDATA"* ]] || [[ "$FP_TARGET_BACKUP" == "$G_FP_DIETPI_USERDATA_ACTUAL"* ]] { Error_DietpiUserdata_Directory #Check location contains /mnt/ } elif [[ "$FP_TARGET_BACKUP" == "/mnt/"* ]] { #Generate the target directory if it doesnt exist. So we can check what filesystem it will be. local directory_generated=0 if test ! -d $FP_TARGET_BACKUP { mkdir -p $FP_TARGET_BACKUP setglobal directory_generated = '1' } setglobal TARGET_FILESYSTEM_TYPE = $[ df -T $FP_TARGET_BACKUP | sed -n '2p' | awk '{print $2}] for ((i=0; i<${#aSUPPORTED_FILESYSTEMS[@]}; i++)) do if [ "$TARGET_FILESYSTEM_TYPE" = "${aSUPPORTED_FILESYSTEMS[$i]}" ]; then TARGET_DIRECTORY_SUPPORTED=1 break fi done #Delete directory if tested if sh-expr ' $directory_generated == 1 ' { rm -R $FP_TARGET_BACKUP } #Not ext2/3/4 if sh-expr ' $TARGET_DIRECTORY_SUPPORTED == 0 ' { Error_Filesystem_Not_Supported } #Not inside /mnt } else { Error_Not_Mnt_Directory } } #///////////////////////////////////////////////////////////////////////////////////// # Settings File #///////////////////////////////////////////////////////////////////////////////////// #Settings File setglobal FP_DIETPIBACKUP_SETTINGS = '"/DietPi/dietpi/.dietpi-backup_settings'" proc Write_Settings_File{ cat << """ > "$FP_DIETPIBACKUP_SETTINGS" FP_TARGET_BACKUP=$FP_TARGET_BACKUP BACKUP_MODE=$BACKUP_MODE """ > $FP_DIETPIBACKUP_SETTINGS FP_TARGET_BACKUP=$FP_TARGET_BACKUP BACKUP_MODE=$BACKUP_MODE _EOF_ } proc Read_Settings_File{ if test -f $FP_DIETPIBACKUP_SETTINGS { source "$FP_DIETPIBACKUP_SETTINGS" } } #///////////////////////////////////////////////////////////////////////////////////// # Main Loop #///////////////////////////////////////////////////////////////////////////////////// #pre-reqs, install if required. Check_Install_PreReqs #Read settings file Read_Settings_File # $2 Optional directory input. if test -n $2 { setglobal FP_TARGET_BACKUP = $2 } #----------------------------------------------------------------------------- #Run Backup if sh-expr ' $INPUT == 1 ' { Run_Backup #Run Restore } elif sh-expr ' $INPUT == -1 ' { Run_Restore #----------------------------------------------------------------------------- #Run menu } elif sh-expr ' $INPUT == 0 ' { while sh-expr ' $TARGETMENUID > -1 ' { clear if sh-expr ' $TARGETMENUID == 0 ' { Menu_Main } elif sh-expr ' $TARGETMENUID == 1 ' { Menu_Set_Directory } } #Save settings Write_Settings_File } #----------------------------------------------------------------------------------- #Cleaup left over tmp files rm $FP_FILTER_INCLUDE_EXCLUDE_SYSTEM_BACKUP &> /dev/null #----------------------------------------------------------------------------------- #delete[] array unset aSUPPORTED_FILESYSTEMS #----------------------------------------------------------------------------------- exit 0 #----------------------------------------------------------------------------------- }