#!/bin/bash do { #//////////////////////////////////// # DietPi-Globals # #//////////////////////////////////// # Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com # #//////////////////////////////////// # # Info: # - Allows export of shared DietPi global variables/funcs into current bash session, and other scripts # # Excluded scripts, which do NOT load these globals # - dietpi-ramlog # - dietpi-ramdisk # - dietpi.txt (and all other .txt .ini or config files) # #//////////////////////////////////// #----------------------------------------------------------------------------------- # Core var's, functions, environment. Used at start of all scripts. #----------------------------------------------------------------------------------- #Prevent incorrect parsing with non-english locales. setvar LANG = 'en_GB.UTF-8' #Ensure we are in users home dir: https://github.com/Fourdee/DietPi/issues/905#issuecomment-298223705 cd $HOME #To be exported by the originating script (eg: dietpi-software) # - Used in: # G_ERROR_ (info) setvar G_PROGRAM_NAME = '''' #User input? (eg: interactive shell available via STDIN check) # Effects: # - G_ERROR_HANDLER whiptail display # NB: You can export G_USER_INPUTS=0 to force non-interactive (eg: .bashrc) Must run 'unset G_USER_INPUTS' after to return to auto detection. if test -z $G_USER_INPUTS { setvar G_USER_INPUTS = '0' if [[ -t 0 ]] { #checked: # - OK | systemD = non-STDIN # - OK | Cron = non-STDIN #shopt login_shell # == [[ $- == *i* ]] #.bashrc dietpi/login exec is not interactive... #[ -t 0 ]# .bashrc dietpi/login exec is interactive... #set -i in .bashrc is not available... setvar G_USER_INPUTS = '1' } } #DEBUG: # echo $G_USER_INPUTS # shopt login_shell # sleep 1 #DEBUG: # - DietPi Scripts, moved from /etc/bash.bashrc alias sudo='sudo ' # https://github.com/Fourdee/DietPi/issues/424 alias dietpi-process_tool='/DietPi/dietpi/dietpi-process_tool' alias dietpi-letsencrypt='/DietPi/dietpi/dietpi-letsencrypt' alias dietpi-autostart='/DietPi/dietpi/dietpi-autostart' alias dietpi-cron='/DietPi/dietpi/dietpi-cron' alias dietpi-launcher='/DietPi/dietpi/dietpi-launcher' alias dietpi-cleaner='/DietPi/dietpi/dietpi-cleaner' alias dietpi-morsecode='/DietPi/dietpi/dietpi-morsecode' alias dietpi-sync='/DietPi/dietpi/dietpi-sync' alias dietpi-backup='/DietPi/dietpi/dietpi-backup' alias dietpi-bugreport='/DietPi/dietpi/dietpi-bugreport' alias dietpi-services='/DietPi/dietpi/dietpi-services' alias dietpi-config='/DietPi/dietpi/dietpi-config' alias dietpi-software='/DietPi/dietpi/dietpi-software' alias dietpi-update='/DietPi/dietpi/dietpi-update' alias dietpi-drive_manager='/DietPi/dietpi/dietpi-drive_manager' alias emulationstation='/opt/retropie/supplementary/emulationstation/emulationstation' alias cpu='/DietPi/dietpi/dietpi-cpuinfo' alias dietpi-logclear='/DietPi/dietpi/dietpi-logclear' # - Optional DietPi software aliases/functions test -f /usr/local/games/opentyrian/run && alias opentyrian='/usr/local/games/opentyrian/run' test -f /DietPi/dietpi/misc/dietpi-justboom && alias dietpi-justboom='/DietPi/dietpi/misc/dietpi-justboom' test -f "$G_FP_DIETPI_USERDATA"/dxx-rebirth/run.sh && alias dxx-rebirth="$G_FP_DIETPI_USERDATA/dxx-rebirth/run.sh" test -f /usr/share/applications/kodi.desktop && alias startkodi='/DietPi/dietpi/misc/start_kodi' test -f /etc/systemd/system/dietpi-cloudshell.service && alias dietpi-cloudshell='/DietPi/dietpi/dietpi-cloudshell' # occ/ncc need to be global function, as aliases are not accessible from non-interactive scripts: test -f /var/www/owncloud/occ && proc occ { sudo -u www-data php /var/www/owncloud/occ @ARGV; } test -f /var/www/nextcloud/occ && proc ncc { sudo -u www-data php /var/www/nextcloud/occ @ARGV; } # - Treesize # $1 = Optional input directory (eg: G_TREESIZE /etc/apt) proc G_TREESIZE { du -k --max-depth=1 $1 | sort -nr | awk ' BEGIN { split("KB,MB,GB,TB", Units, ","); } { u = 1; while ($1 >= 1024) { $1 = $1 / 1024; u += 1; } $1 = sprintf("%.1f %s", $1, Units[u]); print $0; } ' } # DietPi-Notify # $1: # -2=process animation # - $2 = text # -1=autodetect_fail_ok # - $2 = EXIT_CODE # 0=OK # - $2 = text # 1=failed # - $2 = text # 2=info # - $2 = text # 3=DietPi banner style # - $2 = txt program name # - $3 = txt mode proc G_DIETPI-NOTIFY { local ainput_string=("$@") #header_line="\e[38;5;154m─────────────────────────────────────────────────────\e[0m" local header_line="\e[90m─────────────────────────────────────────────────────\e[0m" local status_text_ok="\e[32m OK \e[0m" local status_text_error="\e[31mFAILED\e[0m" local status_text_info="\e[0m INFO \e[0m" local bracket_string_l="\e[90m[\e[0m" local bracket_string_r="\e[90m]\e[0m" #Funcs proc Print_Process_Animation { local bright_dot="\e[1;93m.\e[0m" local dimmed_dot="\e[2;33m.\e[0m" local aprocess_string=( #\u23F9 "$bright_dot " "$dimmed_dot$bright_dot " " $dimmed_dot$bright_dot " " $dimmed_dot$bright_dot " " $dimmed_dot$bright_dot " " $dimmed_dot$bright_dot" " $bright_dot$dimmed_dot" " $bright_dot$dimmed_dot " " $bright_dot$dimmed_dot " " $bright_dot$dimmed_dot " "$bright_dot$dimmed_dot " ) for (( i=0; i<=${#aprocess_string[@]}; i++ )); do (( i == 11 )) && i=1 [ -f /tmp/dietpi-process.pid ] && echo -ne "\r$bracket_string_l${aprocess_string[i]}$bracket_string_r " || break sleep 0.15 done } proc Clean_Process_Animation { if test -f /tmp/dietpi-process.pid { kill $( /dev/null rm /tmp/dietpi-process.pid &> /dev/null || sudo rm /tmp/dietpi-process.pid &> /dev/null # In case, the output took more than one line, clean from cursor (animation position) until end of terminal. tput ed } echo -ne "\r\e[K" } proc Print_Process { echo -ne "\r\e[9C" } proc Print_Ok { Clean_Process_Animation echo -ne "$bracket_string_l$status_text_ok$bracket_string_r " } proc Print_Failed { Clean_Process_Animation echo -ne "$bracket_string_l$status_text_error$bracket_string_r " } proc Print_Info { Clean_Process_Animation echo -ne "$bracket_string_l$status_text_info$bracket_string_r " } # - Print all input string on same line # - $1 = start printing from word number $1 proc Print_Input_String { local i=0 for (( i=$1;i<${#ainput_string[@]} ;i++)) do echo -ne "${ainput_string[$i]}" done } #-------------------------------------------------------------------------------------- # Main Loop #-------------------------------------------------------------------------------------- #Exit code, print OK or Failed #$2 = exit code # - Use this at end of DietPi scripts, EG: G_DIETPI-NOTIFY -1 ${EXIT_CODE:=0} if (( $1 == -1 )) { if test $2 = "0" { setvar ainput_string = ''(" Completed") Print_Ok Print_Input_String 2 echo '' } else { setvar ainput_string = ''(" An issue has occured") Print_Failed Print_Input_String 2 echo '' } #-------------------------------------------------------------------------------------- #Status Processing #$@ = txt desc } elif (( $1 == -2 )) { Print_Process Print_Input_String 1 # Calculate the amount of output lines and in case move cursor up for correct animation and to allow cleaning the whole output. local string="$[join(ARGV)]" local lines=0 { tput cuu1 (( lines-- )) } test ! -f /tmp/dietpi-process.pid && touch /tmp/dietpi-process.pid && shell { Print_Process_Animation & echo $! > /tmp/dietpi-process.pid } #Status Ok #$@ = txt desc } elif (( $1 == 0 )) { Print_Ok Print_Input_String 1 echo '' #Status failed #$@ = txt desc } elif (( $1 == 1 )) { Print_Failed Print_Input_String 1 echo '' #Status Info #$@ = txt desc } elif (( $1 == 2 )) { Print_Info echo -ne "\e[90m" Print_Input_String 1 echo -e "\e[0m" #DietPi banner style #$2 = txt program name #$3 = txt mode } elif (( $1 == 3 )) { echo -e "\n \e[38;5;154m$2\e[0m" echo -e $header_line echo -e " \e[90mMode: \e[0m$(Print_Input_String 2)\n" } #----------------------------------------------------------------------------------- # Unset also internal functions, otherwise they are accessible from terminal. unset Print_Process_Animation unset Clean_Process_Animation unset Print_Process unset Print_Ok unset Print_Failed unset Print_Info unset Print_Input_String #----------------------------------------------------------------------------------- } setvar G_CHECK_ROOT_USER_VERIFIED = ${G_CHECK_ROOT_USER_VERIFIED:=0} #only check once for each session proc G_CHECK_ROOT_USER { if (( ! $G_CHECK_ROOT_USER_VERIFIED )) { G_DIETPI-NOTIFY -2 'Checking for (elevated) root access' if (( $UID != 0 )) { G_DIETPI-NOTIFY 1 'Root privileges required. Please run the command with "sudo"\n' exit 1 } else { G_DIETPI-NOTIFY 0 'Root access verified.' export G_CHECK_ROOT_USER_VERIFIED=1 } } } setvar G_CHECK_ROOTFS_RW_VERIFIED = ${G_CHECK_ROOTFS_RW_VERIFIED:=0} #only check once for each session proc G_CHECK_ROOTFS_RW { if (( ! $G_CHECK_ROOTFS_RW_VERIFIED )) { #RootFS RW check /DietPi/dietpi/dietpi-drive_manager 3 if (( $? != 0 )) { G_DIETPI-NOTIFY 1 'RootFS is currently Read Only, unable to continue.\n' exit 1 } else { export G_CHECK_ROOTFS_RW_VERIFIED=1 } } } #----------------------------------------------------------------------------------- # DietPi Error Handler # https://github.com/Fourdee/DietPi/issues/1311#issuecomment-353716344 #----------------------------------------------------------------------------------- setvar G_ERROR_HANDLER_EXITCODE = '''' #input value to use with G_ERROR_HANDLER setvar G_ERROR_HANDLER_COMMAND = '''' #eg: G_AGI: moooooooo # For export: On error, following entries will be used setvar G_ERROR_HANDLER_ONERROR_EXIT = '1' #Do we exit the program when the error occurs? 0=no 1=yes setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = '''' #FP to logfile, if available #Runs automatically after G_ERROR_HANDLER to reset vars to default proc G_ERROR_HANDLER_RESET { #unset originating program unset G_ERROR_HANDLER_EXITCODE unset G_ERROR_HANDLER_COMMAND unset G_ERROR_HANDLER_ONERROR_EXIT unset G_ERROR_HANDLER_ONERROR_FPLOGFILE setvar G_ERROR_HANDLER_EXITCODE = '''' setvar G_ERROR_HANDLER_COMMAND = '''' setvar G_ERROR_HANDLER_ONERROR_EXIT = '1' setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = '''' } #Handles exit code errors, as defined by G_ERROR_HANDLER_xxxx settings # Usage: # export G_ERROR_HANDLER_COMMAND='Doing something usefull with Owncloud' # export G_ERROR_HANDLER_ONERROR_EXIT=0 # Don't exit program on error, continue # export G_ERROR_HANDLER_ONERROR_FPLOGFILE=/var/log/mylogfile # to print if error occurs # occ --doing-something-useful # export G_ERROR_HANDLER_EXITCODE=$? # G_ERROR_HANDLER proc G_ERROR_HANDLER { #Ok if (( $G_ERROR_HANDLER_EXITCODE == 0 )) { G_DIETPI-NOTIFY 0 $G_ERROR_HANDLER_COMMAND #Error } else { local print_hw_info="VERSION:v$(sed -n 1p /DietPi/dietpi/.version).$(sed -n 2p /DietPi/dietpi/.version) | HW_MODEL:$G_HW_MODEL | HW_ARCH:$G_HW_ARCH | DISTRO:$G_DISTRO" local print_exitcode_info="exit_code = $G_ERROR_HANDLER_EXITCODE" local print_logfile_info="Log file contents:\n$(tail -50 $G_ERROR_HANDLER_ONERROR_FPLOGFILE)" local print_report_to_dietpi_info='If problems persist, please report this to DietPi for investigation, including a screenshot of this error! (https://github.com/Fourdee/DietPi/issues).' local print_unable_to_continue='Unable to continue, the program will now terminate.' echo '' if test -n $G_PROGRAM_NAME { G_DIETPI-NOTIFY 1 "$G_PROGRAM_NAME: $G_ERROR_HANDLER_COMMAND" } else { G_DIETPI-NOTIFY 1 $G_ERROR_HANDLER_COMMAND } G_DIETPI-NOTIFY 2 $print_exitcode_info G_DIETPI-NOTIFY 2 $print_hw_info # - On Error: Display logfile FP, if set if test -n $G_ERROR_HANDLER_ONERROR_FPLOGFILE { G_DIETPI-NOTIFY 2 $print_logfile_info } # Display "please report to dietpi", if its one of our programs if test -n $G_PROGRAM_NAME { G_DIETPI-NOTIFY 2 $print_report_to_dietpi_info } # - On Error: Display whip version? if (( $G_USER_INPUTS )) { local whip_msg=() if test -n $G_PROGRAM_NAME { setvar whip_msg = ""$G_PROGRAM_NAME: $G_ERROR_HANDLER_COMMAND"" } else { setvar whip_msg = "$G_ERROR_HANDLER_COMMAND" } setvar whip_msg = ''\n'' setvar whip_msg = "" - $print_exitcode_info"" setvar whip_msg = ''\n'' setvar whip_msg = "" - $print_hw_info"" setvar whip_msg = ''\n\n'' # Display optional logfile? if test -n $G_ERROR_HANDLER_ONERROR_FPLOGFILE { setvar whip_msg = "$print_logfile_info" setvar whip_msg = ''\n\n'' } # Display "please report to dietpi", if its one of our programs if test -n $G_PROGRAM_NAME { setvar whip_msg = "$print_report_to_dietpi_info" } if (( $G_ERROR_HANDLER_ONERROR_EXIT )) { setvar whip_msg = ''\n\n'' setvar whip_msg = "$print_unable_to_continue" } whiptail --title 'DietPi Error Handler:' --msgbox $whip_msg --scrolltext 22 85 } # - On Error: Kill current script, excluding the shell. if (( $G_ERROR_HANDLER_ONERROR_EXIT )) { # - Github printout: echo -e " \e[41m -------------------------------------------------------------------- - DietPi has encounted an error, and, is unable to continue - - Please create a ticket: https://github.com/Fourdee/DietPi/issues - - Copy and paste the BLUE lines below, into the ticket - -------------------------------------------------------------------- \e[0m \e[44m #### Required Information: - DietPi Version | v$(sed -n 1p /DietPi/dietpi/.version).$(sed -n 2p /DietPi/dietpi/.version) - SBC Device | $G_HW_MODEL_DESCRIPTION (index=$G_HW_MODEL) - Distro | $G_DISTRO_NAME (index=$G_DISTRO) - Command | $G_ERROR_HANDLER_COMMAND - Error Handler | G_ERROR_HANDLER #### Additional Information (if applicable): - Software title | $G_PROGRAM_NAME #### Expected behaviour: #### Actual behaviour: #### Steps to reproduce: #### Additional logs: \`\`\` $print_logfile_info \`\`\` \e[0m \e[41m--------------------------------------------------------------------\e[0m " G_DIETPI-NOTIFY 1 $print_unable_to_continue # - Reset for next run G_ERROR_HANDLER_RESET kill -INT $$ } } return $G_ERROR_HANDLER_EXITCODE # - Reset for next run G_ERROR_HANDLER_RESET } #Run a command and send the output through the error handler. This has the same effect as running G_ERROR_HANDLER afterwards, however, allows for command used info, and log output/view when an error occurs #NB: This command does not support inputs with redirects. For file creation, use G_FILE_EXISTS afterwards to check it exists: https://github.com/Fourdee/DietPi/issues/1311#issuecomment-354541417 # $@ = input command # eg: # G_RUN_CMD mkdir /never/gonna/work proc G_RUN_CMD { setvar G_ERROR_HANDLER_COMMAND = "@ARGV" G_DIETPI-NOTIFY -2 "Running command: $G_ERROR_HANDLER_COMMAND" $G_ERROR_HANDLER_COMMAND &> /tmp/G_ERROR_HANDLER_COMMAND setvar G_ERROR_HANDLER_EXITCODE = ""$? setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = ''/tmp/G_ERROR_HANDLER_COMMAND'' G_ERROR_HANDLER rm /tmp/G_ERROR_HANDLER_COMMAND &> /dev/null } #Checks if a file/folder exists # Automatically passed through G_ERROR_HANDLER proc G_FILE_EXISTS { setvar G_ERROR_HANDLER_COMMAND = "@ARGV" setvar G_ERROR_HANDLER_EXITCODE = '0' G_DIETPI-NOTIFY -2 "Checking for existance: $G_ERROR_HANDLER_COMMAND" local string='' if test -f $G_ERROR_HANDLER_COMMAND { setvar string = ""File exists"" } elif test -d $G_ERROR_HANDLER_COMMAND { setvar string = ""Folder exists"" } else { setvar string = ""File/folder does not exist"" setvar G_ERROR_HANDLER_EXITCODE = '1' } setvar string = "" | $G_ERROR_HANDLER_COMMAND"" echo -e $string > /tmp/G_ERROR_HANDLER_COMMAND setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = ''/tmp/G_ERROR_HANDLER_COMMAND'' setvar G_ERROR_HANDLER_COMMAND = "$string" G_ERROR_HANDLER rm /tmp/G_ERROR_HANDLER_COMMAND &> /dev/null } #----------------------------------------------------------------------------------- # DietPi First-Run Stage #----------------------------------------------------------------------------------- # -2 = PREP_SYSTEM/Unknown | -1 = first boot | 0 = run dietpi-software at login | 1 = completed setvar G_DIETPI_INSTALL_STAGE = '-2' if test -f /DietPi/dietpi/.install_stage { setvar G_DIETPI_INSTALL_STAGE = $(cat /DietPi/dietpi/.install_stage) } #----------------------------------------------------------------------------------- # Hardware Details #----------------------------------------------------------------------------------- setvar G_HW_MODEL = ${G_HW_MODEL:-0} setvar G_HW_MODEL_DESCRIPTION = ${G_HW_MODEL_DESCRIPTION:-NULL} setvar G_HW_ARCH = ${G_HW_ARCH:-0} setvar G_HW_CPU_CORES = ${G_HW_CPU_CORES:-1} setvar G_HW_CPUID = ${G_HW_CPUID:-0} setvar G_DISTRO = ${G_DISTRO:-0} setvar G_DISTRO_NAME = ${G_DISTRO_NAME:-NULL} # - Update # NB: dietpi-boot service launches dietpi-obtain_hw_model to create the following file if test -f /DietPi/dietpi/.hw_model { setvar G_HW_MODEL = $(sed -n 1p /DietPi/dietpi/.hw_model) setvar G_HW_MODEL_DESCRIPTION = $(sed -n 2p /DietPi/dietpi/.hw_model) setvar G_HW_ARCH = $(sed -n 6p /DietPi/dietpi/.hw_model) setvar G_HW_CPU_CORES = $(nproc --all) setvar G_HW_CPUID = $(sed -n 9p /DietPi/dietpi/.hw_model) setvar G_DISTRO = $(sed -n 3p /DietPi/dietpi/.hw_model) setvar G_DISTRO_NAME = ''jessie'' if (( $G_DISTRO == 4 )) { setvar G_DISTRO_NAME = ''stretch'' } elif (( $G_DISTRO == 5 )) { setvar G_DISTRO_NAME = ''buster'' } } #Returns current CPU temp 'C proc G_OBTAIN_CPU_TEMP { # - Array to store possible locations for temp read. setvar afp_temperature = ''( #'/sys/class/thermal/thermal_zone1/temp' #sparky/Asus, will break other SBC temp readouts as most have 2 zones, needs a special case '/sys/class/thermal/thermal_zone0/temp' '/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input' '/sys/class/hwmon/hwmon0/device/temp_label' ) for ((i=0; i<${#afp_temperature[@]}; i++)) do if [ -f "${afp_temperature[$i]}" ]; then # Sparky/asus, special case: if (( $G_HW_MODEL == 70 || $G_HW_MODEL == 52 )); then cpu_temp_current=$(cat /sys/class/thermal/thermal_zone1/temp) else cpu_temp_current=$(cat ${afp_temperature[$i]}) fi # - Boards that provide 2 digit output # Pine # NanoPi M2 # NanoPi M3 # H3 3.x # H2+ 3.x if (( $G_HW_MODEL == 40 || $G_HW_MODEL == 61 || $G_HW_MODEL == 62 || ( $G_HW_CPUID == 1 && $(uname -r | grep -ci -m1 '^3.') ) || ( $G_HW_MODEL == 32 && $(uname -r | grep -ci -m1 '^3.') ) )); then echo -e "Do nothing" &> /dev/null else cpu_temp_current=$( echo -e "$cpu_temp_current" | awk '{print $1/1000}' | xargs printf "%0.0f" ) fi break fi done unset afp_temperature echo $cpu_temp_current } #Returns current CPU usage % proc G_OBTAIN_CPU_USAGE { # - PS (inaccurate, but fast??) local cpu_usage=0 local fp_temp='/tmp/.cpu_usage_cpuinfo' ps -axo %cpu | sed '1d' | sed 's/ //' > "$fp_temp" while read line { setvar cpu_usage = $( echo "scale=1;$cpu_usage + $line" | bc -l ) } < "$fp_temp" # - ps returns usage of each core, so we devide the total by #n cores setvar cpu_usage = $(echo "scale=1;$cpu_usage / $(nproc --all)" | bc -l ) echo $cpu_usage } #----------------------------------------------------------------------------------- # DietPi specific directories #----------------------------------------------------------------------------------- # - Default DietPi userdata location. This must NEVER change. setvar G_FP_DIETPI_USERDATA = ''/mnt/dietpi_userdata'' # - Current DietPi userdata location (actual, follows symlink of G_FP_DIETPI_USERDATA, if not on rootFS) #G_FP_DIETPI_USERDATA_CURRENT=$(readlink -f $G_FP_DIETPI_USERDATA) #FP_DIETPI_VAR_LIB='/var/lib/dietpi' #FP_DIETPI_VAR_TMP='/var/tmp/dietpi' #----------------------------------------------------------------------------------- # URL Connection test #----------------------------------------------------------------------------------- # $@ = URL # NB: automatically error handled (G_ERROR_HANDLER) # Prompts user to configure network if $G_USER_INPUTS=1 proc G_CHECK_URL { local string="$[join(ARGV)]" local timeout=10 local retry_max=5 local error_connection_failed=0 setvar G_ERROR_HANDLER_EXITCODE = '0' setvar G_ERROR_HANDLER_COMMAND = ""Connection test: $string"" setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = ''/tmp/G_CHECK_URL'' while true { #Allow user choice to configure network on failure if (( $G_USER_INPUTS )) { setvar G_ERROR_HANDLER_ONERROR_EXIT = '0' if (( $error_connection_failed )) { #Ask to check settings, whiptail --title "URL Connection Test Failed" --yesno "DietPi was unable to establish a connection:\n - $string\n\nIf problems persist, the URL may be offline/unreachable.\n\nWould you like to configure network settings and try again?" --yes-button "Ok" --no-button "Exit" --defaultno --backtitle $G_PROGRAM_NAME 15 80 setvar CHOICE = ""$? #run dietpi config if (( $CHOICE == 0 )) { whiptail --title "Launching DietPi-Config" --msgbox "DietPi-Config will now be started.\nUse the Network Options menu to change and test your network settings.\n\nWhen completed, exit DietPi-Config to resume." --backtitle "Launching DietPi-Config" 14 60 /DietPi/dietpi/dietpi-config 8 1 #User aborted, exit now with current error information } else { setvar G_ERROR_HANDLER_ONERROR_EXIT = '1' setvar G_ERROR_HANDLER_EXITCODE = '1' setvar G_USER_INPUTS = '0' #disable whiptail info G_ERROR_HANDLER #break #handled by G_ERROR_HANDLER script kill } } #Force exit on failure to end loop (overrides any export G_ERROR_HANDLER_ONERROR_EXIT in this session) } else { setvar G_ERROR_HANDLER_ONERROR_EXIT = '1' } for ((i=1; i<=$retry_max; i++)) do G_DIETPI-NOTIFY -2 "($i/$retry_max) Testing connection to $string, please wait..." wget --spider --timeout=$timeout --tries=1 "$string" &> /tmp/G_CHECK_URL G_ERROR_HANDLER_EXITCODE=$? # Valid if (( $G_ERROR_HANDLER_EXITCODE == 0 )); then break # Retry else sleep 2 error_connection_failed=1 G_DIETPI-NOTIFY -2 "Failed connection attempt ($i/$retry_max), retrying..." fi done #--no-check-certificate #https://github.com/Fourdee/DietPi/issues/352#issuecomment-221013166 G_ERROR_HANDLER if (( $G_ERROR_HANDLER_EXITCODE == 0 )) { break } } rm /tmp/G_CHECK_URL return $G_ERROR_HANDLER_EXITCODE } #----------------------------------------------------------------------------------- # APT #----------------------------------------------------------------------------------- setvar G_FP_LOG_APT = ''/var/tmp/dietpi/logs/dietpi-software_apt.log'' #Support for apt-fast: https://github.com/Fourdee/DietPi/issues/698 # APT_BINARY='apt-get' # if [ -f /usr/bin/apt-fast ]; then # APT_BINARY='apt-fast' # fi #apt-get install # NB: automatically error handled (G_ERROR_HANDLER) proc G_AGI { local string="$[join(ARGV)]" local force_options='' if (( $G_DISTRO >= 4 )) { setvar force_options = ''--allow-downgrades --allow-remove-essential --allow-change-held-packages --allow-unauthenticated'' } else { setvar force_options = ''--force-yes'' } setvar G_ERROR_HANDLER_EXITCODE = '0' setvar G_ERROR_HANDLER_COMMAND = ""G_AGI: $string"" setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = "$G_FP_LOG_APT" #-qq can add a slight period of appearing nothing is happening, lets inform user G_DIETPI-NOTIFY 2 "APT installation for: $string, please wait...'" DEBIAN_FRONTEND=noninteractive' apt-get install -y -qq $force_options $string 2>&1 | tee $G_FP_LOG_APT setvar G_ERROR_HANDLER_EXITCODE = ${PIPESTATUS[0]} G_ERROR_HANDLER return $G_ERROR_HANDLER_EXITCODE } #apt-get purge # NB: automatically error handled (G_ERROR_HANDLER) proc G_AGP { local string="$[join(ARGV)]" local options='' if (( $G_DISTRO >= 4 )) { setvar options = '' --allow-change-held-packages'' } setvar G_ERROR_HANDLER_EXITCODE = '0' setvar G_ERROR_HANDLER_COMMAND = ""G_AGP: $string"" setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = "$G_FP_LOG_APT" G_DIETPI-NOTIFY 2 "APT removal for: $string, please wait...'" DEBIAN_FRONTEND=noninteractive' apt-get purge -y $string $options 2>&1 | tee $G_FP_LOG_APT setvar G_ERROR_HANDLER_EXITCODE = ${PIPESTATUS[0]} G_ERROR_HANDLER return $G_ERROR_HANDLER_EXITCODE } #apt-get autoremove # NB: automatically error handled (G_ERROR_HANDLER) proc G_AGA { setvar G_ERROR_HANDLER_EXITCODE = '0' setvar G_ERROR_HANDLER_COMMAND = ""G_AGA"" setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = "$G_FP_LOG_APT" G_DIETPI-NOTIFY 2 "APT autoremove + purge, please wait...'" DEBIAN_FRONTEND=noninteractive' apt-get autoremove --purge -y 2>&1 | tee $G_FP_LOG_APT setvar G_ERROR_HANDLER_EXITCODE = ${PIPESTATUS[0]} G_ERROR_HANDLER return $G_ERROR_HANDLER_EXITCODE } #apt-get install -f # NB: automatically error handled (G_ERROR_HANDLER) proc G_AGF { setvar G_ERROR_HANDLER_EXITCODE = '0' setvar G_ERROR_HANDLER_COMMAND = ""G_AGF"" setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = "$G_FP_LOG_APT" G_DIETPI-NOTIFY 2 "APT fix, please wait...'" DEBIAN_FRONTEND=noninteractive' apt-get install -f -y 2>&1 | tee $G_FP_LOG_APT setvar G_ERROR_HANDLER_EXITCODE = ${PIPESTATUS[0]} G_ERROR_HANDLER return $G_ERROR_HANDLER_EXITCODE } #apt-get update # NB: automatically error handled (G_ERROR_HANDLER) proc G_AGUP { setvar G_ERROR_HANDLER_EXITCODE = '0' setvar G_ERROR_HANDLER_COMMAND = ""G_AGUP"" setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = "$G_FP_LOG_APT" G_DIETPI-NOTIFY 2 "APT update, please wait...'" DEBIAN_FRONTEND=noninteractive' apt-get clean 2>&1 | tee $G_FP_LOG_APT' DEBIAN_FRONTEND=noninteractive' apt-get update 2>&1 | tee -a $G_FP_LOG_APT setvar G_ERROR_HANDLER_EXITCODE = ${PIPESTATUS[0]} G_ERROR_HANDLER return $G_ERROR_HANDLER_EXITCODE } #apt-get upgrade # NB: automatically error handled (G_ERROR_HANDLER) proc G_AGUG { setvar G_ERROR_HANDLER_EXITCODE = '0' setvar G_ERROR_HANDLER_COMMAND = ""G_AGUG"" setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = "$G_FP_LOG_APT" G_DIETPI-NOTIFY 2 "APT upgrade, please wait...'" DEBIAN_FRONTEND=noninteractive' apt-get upgrade -y 2>&1 | tee $G_FP_LOG_APT setvar G_ERROR_HANDLER_EXITCODE = ${PIPESTATUS[0]} G_ERROR_HANDLER return $G_ERROR_HANDLER_EXITCODE } #apt-get dist-upgrade # NB: automatically error handled (G_ERROR_HANDLER) proc G_AGDUG { setvar G_ERROR_HANDLER_EXITCODE = '0' setvar G_ERROR_HANDLER_COMMAND = ""G_AGDUG"" setvar G_ERROR_HANDLER_ONERROR_FPLOGFILE = "$G_FP_LOG_APT" if (( $G_DISTRO >= 4 )) { setvar force_options = ''--allow-downgrades --allow-remove-essential --allow-change-held-packages --allow-unauthenticated'' } else { setvar force_options = ''--force-yes'' } G_DIETPI-NOTIFY 2 "APT dist-upgrade, please wait...'" DEBIAN_FRONTEND=noninteractive' apt-get dist-upgrade -y 2>&1 | tee $G_FP_LOG_APT setvar G_ERROR_HANDLER_EXITCODE = ${PIPESTATUS[0]} G_ERROR_HANDLER return $G_ERROR_HANDLER_EXITCODE } #Checks for required APT packages, installs if needed. # $@ = list of required packages # NB: automatically error handled (G_ERROR_HANDLER) proc G_AG_CHECK_INSTALL_PREREQ { local fp_temp='/tmp/.G_AG_CHECK_INSTALL_PREREQ' local exit_code=0 local string=( "$@" ) local packages_to_install='' G_DIETPI-NOTIFY 2 "Checking for pre-req APT packages: ${string[*]}" dpkg --get-selections > "$fp_temp" for i in "${string[@]}" { if (( ! $(grep -ci -m1 "^$i[[:space:]]" "$fp_temp") )) { G_DIETPI-NOTIFY 2 "($i) | Not found, flagged for installation" setvar packages_to_install = "" $i"" } } if test -n $packages_to_install { G_DIETPI-NOTIFY -2 "Installing pre-req APT packages" G_AGI $packages_to_install setvar exit_code = ""$? } else { G_DIETPI-NOTIFY 2 "Pre-req APT packages are installed" } #G_AGI now handles the error rm $fp_temp return $exit_code } #----------------------------------------------------------------------------------- # HW specific #----------------------------------------------------------------------------------- #rpi-update # - Holds APT packages # - Skips backup proc G_RPI_UPDATE { if (( $G_HW_MODEL < 10 )) { G_AG_CHECK_INSTALL_PREREQ rpi-update export SKIP_BACKUP=1 G_RUN_CMD rpi-update apt-mark hold raspberrypi-bootloader raspberrypi-kernel libraspberrypi-bin } } #----------------------------------------------------------------------------------- #G_DIETPI-NOTIFY 2 'DietPi-Globals loaded\n' #----------------------------------------------------------------------------------- }