diff --git a/.github/workflows/dietpi-software.bash b/.github/workflows/dietpi-software.bash index 8dd83980c0..0c3383578a 100644 --- a/.github/workflows/dietpi-software.bash +++ b/.github/workflows/dietpi-software.bash @@ -204,7 +204,7 @@ Process_Software() 167) (( $arch < 3 )) || aSERVICES[i]='raspotify';; # 32-bit ARM fails with: "arm-binfmt-P: /usr/bin/librespot: Unable to find a guest_base to satisfy all guest address mapping requirements" #169) aSERVICES[i]='voice-recognizer';; "RuntimeError: This module can only be run on a Raspberry Pi!" 170) aCOMMANDS[i]='unrar -V';; - #171) aSERVICES[i]='frps frpc' aTCP[i]='7000 7400 7500';; Interactive install with service and ports depending on server/client/both choice + 171) aSERVICES[i]='frps frpc' aTCP[i]='7000 7400 7500';; 172) aSERVICES[i]='wg-quick@wg0' aUDP[i]='51820';; 174) aCOMMANDS[i]='gimp -v';; 176) aSERVICES[i]='mycroft';; diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index c2e229892e..e377c9b8f2 100755 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -1509,7 +1509,6 @@ Available commands: aSOFTWARE_DESC[$software_id]='reverse proxy' aSOFTWARE_CATX[$software_id]=16 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/advanced_networking/#frp' - aSOFTWARE_INTERACTIVE[$software_id]=1 # Home Automation #-------------------------------------------------------------------------------- @@ -6538,18 +6537,16 @@ _EOF_ G_EXEC cd frp_* - local choice_required= - while : - do - G_WHIP_MENU_ARRAY=( - 'Server' ': Use this machine as a server, with a public IP' - 'Client' ': Use this machine as a client, without a public IP' - 'Both' ': Run the reverse proxy only on this machine' - ) + # Mode choice + G_WHIP_MENU_ARRAY=( + 'Server' ': Use this machine as a server, with a public IP' + 'Client' ': Use this machine as a client, without a public IP' + 'Both' ': Run the reverse proxy only on this machine' + ) - G_WHIP_MENU "${choice_required}Please choose how you are going to run frp." && break - choice_required='[ERROR] A choice is required to finish the frp install.\n\n' - done + G_WHIP_NOCANCEL=1 + G_WHIP_DEFAULT_ITEM='Both' + G_WHIP_MENU 'Please choose how you are going to run frp:' local mode=$G_WHIP_RETURNED_VALUE G_EXEC mkdir -p /etc/frp @@ -6577,6 +6574,18 @@ RestartSec=5s [Install] WantedBy=multi-user.target _EOF_ + # Pre-v9.9: Inform about config file migration + if [[ -f '/etc/frp/frps.ini' ]] + then + G_WHIP_MSG '[WARNING] New toml config file will be generated +\nfrp deprecated the ini format for its config files, hence /etc/frp/frps.toml will be generated and used from now on. +\nAn automated conversion is not possible and hence need to be done manually, if you did changes. A backup of the ini config it kept in place: +- /etc/frp/frps.ini.bak +\nA full overview of all config keys can be found here: +- https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml' + G_EXEC mv /etc/frp/frps.ini{,.bak} + fi + # Pre-create config file to turn on dashboard token=$(openssl rand -hex 15) [[ -f '/etc/frp/frps.toml' ]] || cat << _EOF_ > /etc/frp/frps.toml @@ -6617,22 +6626,39 @@ RestartSec=5s [Install] WantedBy=multi-user.target _EOF_ - local server_addr='127.0.0.1' server_port=7000 - if [[ $G_WHIP_RETURNED_VALUE == 'Client' ]] + # Pre-v9.9: Inform about config file migration + if [[ -f '/etc/frp/frpc.ini' ]] then - G_WHIP_DEFAULT_ITEM="$server_addr:$server_port" - G_WHIP_INPUTBOX_REGEX='^[0-9.:]+$' - G_WHIP_INPUTBOX_REGEX_TEXT='be a valid IP address, optionally with appended network port number, like "192.168.1.100:7000"' - G_WHIP_INPUTBOX 'Please enter the IP address of your frp server, optionally including port (default 7000):' - server_addr=${G_WHIP_RETURNED_VALUE%:*} - [[ $G_WHIP_RETURNED_VALUE =~ : ]] && server_port=${G_WHIP_RETURNED_VALUE##*:} - - G_WHIP_INPUTBOX 'Please enter the authentication token of your frp server:' - token=$G_WHIP_RETURNED_VALUE + G_WHIP_MSG '[WARNING] New toml config file will be generated +\nfrp deprecated the ini format for its config files, hence /etc/frp/frpc.toml will be generated and used from now on. +\nAn automated conversion is not possible and hence need to be done manually, if you did changes. A backup of the ini config it kept in place: +- /etc/frp/frpc.ini.bak +\nA full overview of all config keys can be found here: +- https://github.com/fatedier/frp/blob/dev/conf/frpc_full_example.toml' + G_EXEC mv /etc/frp/frpc.ini{,.bak} fi # Pre-create config file to turn on admin UI - [[ -f '/etc/frp/frpc.toml' ]] || cat << _EOF_ > /etc/frp/frpc.toml + if [[ ! -f '/etc/frp/frpc.toml' ]] + then + local server_addr='127.0.0.1' server_port=7000 + if [[ $G_WHIP_RETURNED_VALUE == 'Client' ]] + then + G_WHIP_NOCANCEL=1 + G_WHIP_DEFAULT_ITEM="$server_addr:$server_port" + G_WHIP_INPUTBOX_REGEX='^[0-9.:]+$' + G_WHIP_INPUTBOX_REGEX_TEXT='be a valid IP address, optionally with appended network port number, like "192.168.1.100:7000"' + G_WHIP_INPUTBOX 'Please enter the IP address of your frp server, optionally including port (default 7000):' + server_addr=${G_WHIP_RETURNED_VALUE%:*} + [[ $G_WHIP_RETURNED_VALUE =~ : ]] && server_port=${G_WHIP_RETURNED_VALUE##*:} + + G_WHIP_NOCANCEL=1 + G_WHIP_INPUTBOX_REGEX='*' + G_WHIP_INPUTBOX 'Please enter the authentication token of your frp server:' + token=$G_WHIP_RETURNED_VALUE + fi + + cat << _EOF_ > /etc/frp/frpc.toml serverAddr = "$server_addr" serverPort = $server_port @@ -6644,6 +6670,8 @@ webServer.password = "$GLOBAL_PW" auth.method = "token" auth.token = "$token" _EOF_ + fi + G_EXEC chmod 0660 /etc/frp/frpc.toml G_EXEC chown root:frp /etc/frp/frpc.toml aENABLE_SERVICES+=('frpc') diff --git a/dietpi/func/dietpi-globals b/dietpi/func/dietpi-globals index 36a6efd12c..4136e15a8e 100644 --- a/dietpi/func/dietpi-globals +++ b/dietpi/func/dietpi-globals @@ -483,8 +483,8 @@ $grey───────────────────────── local whip_chars_text=$(( $WHIP_SIZE_X - 4 )) # Due to internal margins, the available width is 4 characters smaller WHIP_SCROLLTEXT= # Add "--scrolltext" automatically if text height exceeds max available - Process_Line(){ - + Process_Line() + { local split line=$1 # Split line by "\n" newline escape sequences, the only one which is interpreted by whiptail, in a strict way: "\\n" still creates a newline, hence the sequence cannot be escaped! @@ -504,27 +504,25 @@ $grey───────────────────────── (( whip_lines_text += 1 + ( ${#line} - 1 ) / $whip_chars_text )) # Stop counting if required size exceeds screen already (( $whip_lines_text <= $WHIP_SIZE_Y )) || return 1 - } # - WHIP_MESSAGE - if [[ $WHIP_ERROR$WHIP_MESSAGE ]]; then - + if [[ $WHIP_ERROR$WHIP_MESSAGE ]] + then while read -r line; do Process_Line "$line" || break; done <<< "$WHIP_ERROR$WHIP_MESSAGE" # - WHIP_TEXTFILE - elif [[ $WHIP_TEXTFILE ]]; then - + elif [[ $WHIP_TEXTFILE ]] + then while read -r line; do Process_Line "$line" || break; done < "$WHIP_TEXTFILE" - fi unset -f Process_Line # Process menu and checklist # - G_WHIP_MENU - if [[ $input_mode == 2 ]]; then - + if [[ $input_mode == 2 ]] + then # Requires 1 additional line for text ((whip_lines_text++)) @@ -554,8 +552,8 @@ $grey───────────────────────── done # - G_WHIP_CHECKLIST - elif [[ $input_mode == 3 ]]; then - + elif [[ $input_mode == 3 ]] + then # Lines required for checklist: ( ${#array} + 2 ) to round up single+double array entries WHIP_SIZE_Z=$(( ( ${#G_WHIP_CHECKLIST_ARRAY[@]} + 2 ) / 3 )) @@ -580,44 +578,37 @@ $grey───────────────────────── G_WHIP_CHECKLIST_ARRAY[$i]+='●' done - fi # Adjust sizes to fit content # - G_WHIP_MENU/G_WHIP_CHECKLIST needs to hold text + selection field (WHIP_SIZE_Z) - if [[ $input_mode == [23] ]]; then - + if [[ $input_mode == [23] ]] + then # If required lines would exceed screen, reduce WHIP_SIZE_Z - if (( $whip_lines_text + $WHIP_SIZE_Z > $WHIP_SIZE_Y )); then - + if (( $whip_lines_text + $WHIP_SIZE_Z > $WHIP_SIZE_Y )) + then WHIP_SIZE_Z=$(( $WHIP_SIZE_Y - $whip_lines_text )) # Assure at least 2 lines to have the selection field scroll bar identifiable - if (( $WHIP_SIZE_Z < 2 )); then - + if (( $WHIP_SIZE_Z < 2 )) + then WHIP_SIZE_Z=2 # Since text is partly hidden now, add text scroll ability and info to backtitle WHIP_SCROLLTEXT='--scrolltext' WHIP_BACKTITLE+=' | Use up/down buttons to scroll text' - fi # else reduce WHIP_SIZE_Y to hold all content else - WHIP_SIZE_Y=$(( $whip_lines_text + $WHIP_SIZE_Z )) - fi # - Everything else needs to hold text only - elif (( $whip_lines_text > $WHIP_SIZE_Y )); then - + elif (( $whip_lines_text > $WHIP_SIZE_Y )) + then WHIP_SCROLLTEXT='--scrolltext' WHIP_BACKTITLE+=' | Use up/down buttons to scroll text' - else - WHIP_SIZE_Y=$whip_lines_text - fi } @@ -627,17 +618,14 @@ $grey───────────────────────── { local WHIP_MESSAGE=$* - if [[ $G_INTERACTIVE == 1 ]]; then - + if [[ $G_INTERACTIVE == 1 ]] + then local WHIP_ERROR WHIP_BACKTITLE WHIP_SCROLLTEXT WHIP_SIZE_X WHIP_SIZE_Y G_WHIP_INIT # shellcheck disable=SC2086 whiptail ${G_PROGRAM_NAME:+--title "$G_PROGRAM_NAME"} --backtitle "$WHIP_BACKTITLE" --msgbox "$WHIP_MESSAGE" --ok-button "$G_WHIP_BUTTON_OK_TEXT" $WHIP_SCROLLTEXT "$WHIP_SIZE_Y" "$WHIP_SIZE_X" - else - G_DIETPI-NOTIFY 2 "$WHIP_MESSAGE" - fi G_WHIP_DESTROY @@ -650,30 +638,26 @@ $grey───────────────────────── { local result=0 - if [[ $G_INTERACTIVE == 1 ]]; then - + if [[ $G_INTERACTIVE == 1 ]] + then local WHIP_ERROR WHIP_MESSAGE WHIP_BACKTITLE WHIP_SCROLLTEXT WHIP_SIZE_X WHIP_SIZE_Y WHIP_TEXTFILE=$1 header='File viewer' [[ $log == 1 ]] && header='Log viewer' - if [[ -f $WHIP_TEXTFILE ]]; then - + if [[ -f $WHIP_TEXTFILE ]] + then G_WHIP_INIT # shellcheck disable=SC2086 whiptail --title "${G_PROGRAM_NAME:+$G_PROGRAM_NAME | }$header" --backtitle "$WHIP_BACKTITLE" --textbox "$WHIP_TEXTFILE" --ok-button "$G_WHIP_BUTTON_OK_TEXT" $WHIP_SCROLLTEXT "$WHIP_SIZE_Y" "$WHIP_SIZE_X" - else - result=1 WHIP_ERROR="[FAILED] File does not exist: $WHIP_TEXTFILE" G_WHIP_INIT # shellcheck disable=SC2086 whiptail --title "${G_PROGRAM_NAME:+$G_PROGRAM_NAME | }$header" --backtitle "$WHIP_BACKTITLE" --msgbox "$WHIP_ERROR" --ok-button "$G_WHIP_BUTTON_OK_TEXT" $WHIP_SCROLLTEXT "$WHIP_SIZE_Y" "$WHIP_SIZE_X" - fi - fi G_WHIP_DESTROY - return "$result" + return "${result:-1}" } # G_WHIP_YESNO "message" @@ -684,18 +668,17 @@ $grey───────────────────────── local result=1 default_no='--defaultno' [[ ${G_WHIP_DEFAULT_ITEM,,} == 'yes' || ${G_WHIP_DEFAULT_ITEM,,} == 'ok' ]] && result=0 default_no= - if [[ $G_INTERACTIVE == 1 ]]; then - + if [[ $G_INTERACTIVE == 1 ]] + then local WHIP_ERROR WHIP_BACKTITLE WHIP_SCROLLTEXT WHIP_SIZE_X WHIP_SIZE_Y WHIP_MESSAGE=$* G_WHIP_INIT # shellcheck disable=SC2086 whiptail ${G_PROGRAM_NAME:+--title "$G_PROGRAM_NAME"} --backtitle "$WHIP_BACKTITLE" --yesno "$WHIP_MESSAGE" --yes-button "$G_WHIP_BUTTON_OK_TEXT" --no-button "$G_WHIP_BUTTON_CANCEL_TEXT" "$default_no" $WHIP_SCROLLTEXT "$WHIP_SIZE_Y" "$WHIP_SIZE_X" result=$? - fi G_WHIP_DESTROY - return "$result" + return "${result:-1}" } # G_WHIP_INPUTBOX "message" @@ -707,26 +690,27 @@ $grey───────────────────────── local result=1 unset -v G_WHIP_RETURNED_VALUE # in case left from last G_WHIP - if [[ $G_INTERACTIVE == 1 ]]; then - + if [[ $G_INTERACTIVE == 1 ]] + then local WHIP_ERROR WHIP_BACKTITLE WHIP_SCROLLTEXT WHIP_SIZE_X WHIP_SIZE_Y WHIP_MESSAGE=$* NOCANCEL=() + G_WHIP_INPUTBOX_REGEX=${G_WHIP_INPUTBOX_REGEX:-'.'} + G_WHIP_INPUTBOX_REGEX_TEXT=${G_WHIP_INPUTBOX_REGEX_TEXT:-'not be empty'} [[ $G_WHIP_NOCANCEL == 1 ]] && NOCANCEL=('--nocancel') while : do G_WHIP_INIT - G_WHIP_INPUTBOX_REGEX=${G_WHIP_INPUTBOX_REGEX:-'.'} - G_WHIP_INPUTBOX_REGEX_TEXT=${G_WHIP_INPUTBOX_REGEX_TEXT:-'not be empty'} # shellcheck disable=SC2086 G_WHIP_RETURNED_VALUE=$(whiptail ${G_PROGRAM_NAME:+--title "$G_PROGRAM_NAME"} --backtitle "$WHIP_BACKTITLE" --inputbox "$WHIP_ERROR$WHIP_MESSAGE" --ok-button "$G_WHIP_BUTTON_OK_TEXT" --cancel-button "$G_WHIP_BUTTON_CANCEL_TEXT" "${NOCANCEL[@]}" $WHIP_SCROLLTEXT "$WHIP_SIZE_Y" "$WHIP_SIZE_X" "$G_WHIP_DEFAULT_ITEM" 3>&1 1>&2 2>&3-; echo $? > /tmp/.G_WHIP_INPUTBOX_RESULT) read -r result < /tmp/.G_WHIP_INPUTBOX_RESULT; rm -f /tmp/.G_WHIP_INPUTBOX_RESULT [[ $result == 0 && ! $G_WHIP_RETURNED_VALUE =~ $G_WHIP_INPUTBOX_REGEX ]] && { WHIP_ERROR="[FAILED] Input must $G_WHIP_INPUTBOX_REGEX_TEXT, please try again ...\n\n"; continue; } break done - + else + G_WHIP_RETURNED_VALUE=$G_WHIP_DEFAULT_ITEM fi G_WHIP_DESTROY - return "$result" + return "${result:-1}" } # G_WHIP_PASSWORD "message" @@ -738,8 +722,8 @@ $grey───────────────────────── local return_value=1 unset -v result # in case left from last call - if [[ $G_INTERACTIVE == 1 ]]; then - + if [[ $G_INTERACTIVE == 1 ]] + then local WHIP_ERROR WHIP_BACKTITLE WHIP_SCROLLTEXT WHIP_SIZE_X WHIP_SIZE_Y WHIP_MESSAGE=$* while : do @@ -753,11 +737,10 @@ $grey───────────────────────── return_value=0 break done - fi G_WHIP_DESTROY - return "$return_value" + return "${return_value:-1}" } # G_WHIP_MENU "message" @@ -768,19 +751,24 @@ $grey───────────────────────── local result=1 unset -v G_WHIP_RETURNED_VALUE # in case left from last call - [[ $G_INTERACTIVE == 1 ]] && until [[ $G_WHIP_RETURNED_VALUE ]] # Stay in menu if empty option was selected (separator line) - do + if [[ $G_INTERACTIVE == 1 ]] + then local WHIP_ERROR WHIP_BACKTITLE WHIP_SCROLLTEXT WHIP_SIZE_X WHIP_SIZE_Y WHIP_SIZE_Z WHIP_MESSAGE=$* NOCANCEL=() [[ $G_WHIP_NOCANCEL == 1 ]] && NOCANCEL=('--nocancel') - G_WHIP_INIT 2 - # shellcheck disable=SC2086 - G_WHIP_RETURNED_VALUE=$(whiptail ${G_PROGRAM_NAME:+--title "$G_PROGRAM_NAME"} --backtitle "$WHIP_BACKTITLE" --menu "$WHIP_MESSAGE" --ok-button "$G_WHIP_BUTTON_OK_TEXT" --cancel-button "$G_WHIP_BUTTON_CANCEL_TEXT" "${NOCANCEL[@]}" --default-item "$G_WHIP_DEFAULT_ITEM" $WHIP_SCROLLTEXT "$WHIP_SIZE_Y" "$WHIP_SIZE_X" "$WHIP_SIZE_Z" -- "${G_WHIP_MENU_ARRAY[@]}" 3>&1 1>&2 2>&3-; echo $? > /tmp/.WHIP_MENU_RESULT) - read -r result < /tmp/.WHIP_MENU_RESULT; rm -f /tmp/.WHIP_MENU_RESULT - [[ ${result:=1} == 0 ]] || break # Exit loop in case of cancel button selection or error or if .WHIP_MENU_RESULT could not be created - done + until [[ $G_WHIP_RETURNED_VALUE ]] # Stay in menu if empty option was selected (separator line) + do + G_WHIP_INIT 2 + # shellcheck disable=SC2086 + G_WHIP_RETURNED_VALUE=$(whiptail ${G_PROGRAM_NAME:+--title "$G_PROGRAM_NAME"} --backtitle "$WHIP_BACKTITLE" --menu "$WHIP_MESSAGE" --ok-button "$G_WHIP_BUTTON_OK_TEXT" --cancel-button "$G_WHIP_BUTTON_CANCEL_TEXT" "${NOCANCEL[@]}" --default-item "$G_WHIP_DEFAULT_ITEM" $WHIP_SCROLLTEXT "$WHIP_SIZE_Y" "$WHIP_SIZE_X" "$WHIP_SIZE_Z" -- "${G_WHIP_MENU_ARRAY[@]}" 3>&1 1>&2 2>&3-; echo $? > /tmp/.WHIP_MENU_RESULT) + read -r result < /tmp/.WHIP_MENU_RESULT; rm -f /tmp/.WHIP_MENU_RESULT + [[ ${result:=1} == 0 ]] || break # Exit loop in case of cancel button selection or error or if .WHIP_MENU_RESULT could not be created + done + else + G_WHIP_RETURNED_VALUE=$G_WHIP_DEFAULT_ITEM + fi G_WHIP_DESTROY - return "$result" + return "${result:-1}" } # G_WHIP_CHECKLIST "message" @@ -800,6 +788,8 @@ $grey───────────────────────── G_WHIP_RETURNED_VALUE=$(whiptail ${G_PROGRAM_NAME:+--title "$G_PROGRAM_NAME"} --backtitle "$WHIP_BACKTITLE | Use spacebar to toggle selection" --checklist "$WHIP_MESSAGE" --separate-output --ok-button "$G_WHIP_BUTTON_OK_TEXT" --cancel-button "$G_WHIP_BUTTON_CANCEL_TEXT" "${NOCANCEL[@]}" --default-item "$G_WHIP_DEFAULT_ITEM" $WHIP_SCROLLTEXT "$WHIP_SIZE_Y" "$WHIP_SIZE_X" "$WHIP_SIZE_Z" -- "${G_WHIP_CHECKLIST_ARRAY[@]}" 3>&1 1>&2 2>&3-; echo $? > /tmp/.WHIP_CHECKLIST_RESULT) G_WHIP_RETURNED_VALUE=$(echo -e "$G_WHIP_RETURNED_VALUE" | tr '\n' ' ') read -r result < /tmp/.WHIP_CHECKLIST_RESULT; rm -f /tmp/.WHIP_CHECKLIST_RESULT + else + G_WHIP_RETURNED_VALUE=$G_WHIP_DEFAULT_ITEM fi G_WHIP_DESTROY