From bf57a786e6c80efd19573b626febdb928dd583b3 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sat, 18 Jun 2022 17:17:10 -0700 Subject: [PATCH 01/11] Convert whiptail to dialog. Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 660 ++++++++++++++++++----------- 1 file changed, 421 insertions(+), 239 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 3f5c972f..b1202d75 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -2,7 +2,7 @@ # shellcheck disable=SC1090 # Pi-hole: A black hole for Internet advertisements -# (c) 2017-2021 Pi-hole, LLC (https://pi-hole.net) +# (c) Pi-hole (https://pi-hole.net) # Network-wide ad blocking via your own hardware. # # Installs and Updates Pi-hole @@ -32,6 +32,14 @@ export PATH+=':/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' # Local variables will be in lowercase and will exist only within functions # It's still a work in progress, so you may see some variance in this guideline until it is complete +# Dialog result codes +# dialog code values can be set by environment variables, we only override if +# the env var is not set or empty. +: "${DIALOG_OK:=0}" +: "${DIALOG_CANCEL:=1}" +: "${DIALOG_ESC:=255}" + + # List of supported DNS servers DNS_SERVERS=$(cat << EOM Google (ECS, DNSSEC);8.8.8.8;8.8.4.4;2001:4860:4860:0:0:0:0:8888;2001:4860:4860:0:0:0:0:8844 @@ -93,7 +101,7 @@ if [ -z "${USER}" ]; then USER="$(id -un)" fi -# whiptail dialog dimensions: 20 rows and 70 chars width assures to fit on small screens and is known to hold all content. +# dialog dimensions: 20 rows and 70 chars width assures to fit on small screens and is known to hold all content. r=20 c=70 @@ -317,7 +325,7 @@ package_manager_detect() { # Packages required to perform the os_check (stored as an array) OS_CHECK_DEPS=(grep dnsutils) # Packages required to run this install script (stored as an array) - INSTALLER_DEPS=(git iproute2 whiptail ca-certificates) + INSTALLER_DEPS=(git iproute2 dialog ca-certificates) # Packages required to run Pi-hole (stored as an array) PIHOLE_DEPS=(cron curl iputils-ping psmisc sudo unzip idn2 libcap2-bin dns-root-data libcap2 netcat-openbsd procps) # Packages required for the Web admin interface (stored as an array) @@ -419,32 +427,74 @@ select_rpm_php(){ rpm -q ${REMI_PKG} &> /dev/null || rc=$? if [[ $rc -ne 0 ]]; then # The PHP version available via default repositories is older than version 7 - if ! whiptail --defaultno --title "PHP 7 Update (recommended)" --yesno "PHP 7.x is recommended for both security and language features.\\nWould you like to install PHP7 via Remi's RPM repository?\\n\\nSee: https://rpms.remirepo.net for more information" "${r}" "${c}"; then - # User decided to NOT update PHP from REMI, attempt to install the default available PHP version - printf " %b User opt-out of PHP 7 upgrade on CentOS. Deprecated PHP may be in use.\\n" "${INFO}" - : # continue with unsupported php version - else - printf " %b Enabling Remi's RPM repository (https://rpms.remirepo.net)\\n" "${INFO}" - "${PKG_INSTALL[@]}" "https://rpms.remirepo.net/enterprise/${REMI_PKG}-$(rpm -E '%{rhel}').rpm" &> /dev/null - # enable the PHP 7 repository via yum-config-manager (provided by yum-utils) - "${PKG_INSTALL[@]}" "yum-utils" &> /dev/null - yum-config-manager --enable ${REMI_REPO} &> /dev/null - printf " %b Remi's RPM repository has been enabled for PHP7\\n" "${TICK}" - # trigger an install/update of PHP to ensure previous version of PHP is updated from REMI - if "${PKG_INSTALL[@]}" "php-cli" &> /dev/null; then - printf " %b PHP7 installed/updated via Remi's RPM repository\\n" "${TICK}" - else - printf " %b There was a problem updating to PHP7 via Remi's RPM repository\\n" "${CROSS}" + dialog --no-shadow --clear \ + --title "PHP 7 Update (recommended)" \ + --defaultno \ + --yesno "PHP 7.x is recommended for both security and language features. \ + \\nWould you like to install PHP7 via Remi's RPM repository? \ + \\n\\nSee: https://rpms.remirepo.net for more information" \ + "${r}" "${c}" + + result=$? + case ${result} in + # User chose to install PHP 7 via Remi's RPM repository + "${DIALOG_OK}") + printf " %b Enabling Remi's RPM repository (https://rpms.remirepo.net)\\n" "${INFO}" + "${PKG_INSTALL[@]}" "https://rpms.remirepo.net/enterprise/${REMI_PKG}-$(rpm -E '%{rhel}').rpm" &> /dev/null + # enable the PHP 7 repository via yum-config-manager (provided by yum-utils) + "${PKG_INSTALL[@]}" "yum-utils" &> /dev/null + yum-config-manager --enable ${REMI_REPO} &> /dev/null + printf " %b Remi's RPM repository has been enabled for PHP7\\n" "${TICK}" + # trigger an install/update of PHP to ensure previous version of PHP is updated from REMI + if "${PKG_INSTALL[@]}" "php-cli" &> /dev/null; then + printf " %b PHP7 installed/updated via Remi's RPM repository\\n" "${TICK}" + else + printf " %b There was a problem updating to PHP7 via Remi's RPM repository\\n" "${CROSS}" + exit 1 + fi + ;; + + # User chose not to install PHP 7 via Remi's RPM repository + "${DIALOG_CANCEL}") + # User decided to NOT update PHP from REMI, attempt to install the default available PHP version + printf " %b User opt-out of PHP 7 upgrade on CentOS. Deprecated PHP may be in use.\\n" "${INFO}" + ;; + + # User closed the dialog window + "${DIALOG_ESC}") + printf " %b Escape pressed, exiting installer at Remi dialog window\\n" "${CROSS}" exit 1 - fi - fi - fi # Warn user of unsupported version of Fedora or CentOS - if ! whiptail --defaultno --title "Unsupported RPM based distribution" --yesno "Would you like to continue installation on an unsupported RPM based distribution?\\n\\nPlease ensure the following packages have been installed manually:\\n\\n- lighttpd\\n- lighttpd-fastcgi\\n- PHP version 7+" "${r}" "${c}"; then - printf " %b Aborting installation due to unsupported RPM based distribution\\n" "${CROSS}" - exit - else - printf " %b Continuing installation with unsupported RPM based distribution\\n" "${INFO}" + ;; + esac fi + + # Warn user of unsupported version of Fedora or CentOS + dialog --no-shadow --clear \ + --title "Unsupported RPM based distribution" \ + --defaultno \ + --no-button "Exit" \ + --yes-button "Continue" \ + --yesno "Would you like to continue installation on an unsupported RPM based distribution? \ + \\n\\nPlease ensure the following packages have been installed manually: \ + \\n\\n- lighttpd\\n- lighttpd-fastcgi\\n- PHP version 7+" \ + "${r}" "${c}" + + result=$? + case ${result} in + # User chose to continue installation on an unsupported RPM based distribution + "${DIALOG_OK}") + printf " %b User opted to continue installation on an unsupported RPM based distribution.\\n" "${INFO}" + ;; + # User chose not to continue installation on an unsupported RPM based distribution + "${DIALOG_CANCEL}") + printf " %b User opted not to continue installation on an unsupported RPM based distribution.\\n" "${INFO}" + exit 1 + ;; + "${DIALOG_ESC}") + printf " %b Escape pressed, exiting installer at unsupported RPM based distribution dialog window\\n" "${CROSS}" + exit 1 + ;; + esac fi fi } @@ -636,40 +686,46 @@ get_available_interfaces() { # A function for displaying the dialogs the user sees when first running the installer welcomeDialogs() { # Display the welcome dialog using an appropriately sized window via the calculation conducted earlier in the script - whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\\n\\nThis installer will transform your device into a network-wide ad blocker!" "${r}" "${c}" + dialog --no-shadow --clear \ + --backtitle "Welcome" \ + --title "Pi-hole Automated Installer" \ + --msgbox "\\n\\nThis installer will transform your device into a network-wide ad blocker!" \ + "${r}" "${c}" \ + --and-widget \ + --backtitle "Support Pi-hole" \ + --title "Open Source Software" \ + --msgbox "\\n\\nThe Pi-hole is free, but powered by your donations: https://pi-hole.net/donate/" \ + "${r}" "${c}" \ + --and-widget \ + --colors \ + --backtitle "Initiating network interface" \ + --title "Static IP Needed" \ + --no-button "Exit" --yes-button "Continue" \ + --defaultno \ + --yesno "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.\\n\\n \ + \\Zb\\Z1IMPORTANT:\\Zn If you have not already done so, you must ensure that this device has a static IP.\\n \ + Depending on your operating system, there are many ways to achieve this, through DHCP reservation, or by manually assigning one.\\n\\n \ + Please continue when the static addressing has been configured." \ + "${r}" "${c}" - # Request that users donate if they enjoy the software since we all work on it in our free time - whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\\n\\nThe Pi-hole is free, but powered by your donations: https://pi-hole.net/donate/" "${r}" "${c}" - - # Explain the need for a static address - if whiptail --defaultno --backtitle "Initiating network interface" --title "Static IP Needed" --yesno "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly. - -IMPORTANT: If you have not already done so, you must ensure that this device has a static IP. Either through DHCP reservation, or by manually assigning one. Depending on your operating system, there are many ways to achieve this. - -Choose yes to indicate that you have understood this message, and wish to continue" "${r}" "${c}"; then - #Nothing to do, continue - echo - else - printf " %b Installer exited at static IP message.\\n" "${INFO}" - exit 1 - fi + result=$? + case "${result}" in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %b Installer exited at static IP message.\\n" "${INFO}" + exit 1 + ;; + esac } # A function that lets the user pick an interface to use with Pi-hole chooseInterface() { - # Turn the available interfaces into an array so it can be used with a whiptail dialog - local interfacesArray=() + # Turn the available interfaces into a string so it can be used with dialog + local interfacesList # Number of available interfaces local interfaceCount - # Whiptail variable storage - local chooseInterfaceCmd - # Temporary Whiptail options storage - local chooseInterfaceOptions - # Loop sentinel variable - local firstLoop=1 - # Find out how many interfaces are available to choose from - interfaceCount=$(wc -l <<< "${availableInterfaces}") + # POSIX compliant way to get the number of elements in an array + interfaceCount=$(printf "%s\n" "${availableInterfaces}" | wc -l) # If there is one interface, if [[ "${interfaceCount}" -eq 1 ]]; then @@ -677,33 +733,32 @@ chooseInterface() { PIHOLE_INTERFACE="${availableInterfaces}" # Otherwise, else + # Set status for the first entry to be selected + status="ON" + # While reading through the available interfaces - while read -r line; do - # Use a variable to set the option as OFF to begin with - mode="OFF" - # If it's the first loop, - if [[ "${firstLoop}" -eq 1 ]]; then - # set this as the interface to use (ON) - firstLoop=0 - mode="ON" - fi - # Put all these interfaces into an array - interfacesArray+=("${line}" "available" "${mode}") - # Feed the available interfaces into this while loop - done <<< "${availableInterfaces}" - # The whiptail command that will be run, stored in a variable - chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to toggle selection)" "${r}" "${c}" 6) - # Now run the command using the interfaces saved into the array - chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) || \ - # If the user chooses Cancel, exit - { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } - # For each interface - for desiredInterface in ${chooseInterfaceOptions}; do - # Set the one the user selected as the interface to use - PIHOLE_INTERFACE=${desiredInterface} - # and show this information to the user - printf " %b Using interface: %s\\n" "${INFO}" "${PIHOLE_INTERFACE}" + for interface in ${availableInterfaces}; do + # Put all these interfaces into a string + interfacesList="${interfacesList}${interface} available ${status} " + # All further interfaces are deselected + status="OFF" done + # shellcheck disable=SC2086 + # Disable check for double quote here as we are passing a string with spaces + PIHOLE_INTERFACE=$(dialog --no-shadow --clear --output-fd 1 \ + --radiolist "Choose An Interface (press space to toggle selection)" \ + ${r} ${c} "${interfaceCount}" ${interfacesList}) + + result=$? + case ${result} in + "${DIALOG_CANCEL}"|"${DIALOG_ESC}") + # Show an error message and exit + printf " %b %s\\n" "${CROSS}" "No interface selected, exiting installer" + exit 1 + ;; + esac + + printf " %b Using interface: %s\\n" "${INFO}" "${PIHOLE_INTERFACE}" fi } @@ -789,57 +844,102 @@ getStaticIPv4Settings() { local ipSettingsCorrect local DHCPChoice # Ask if the user wants to use DHCP settings as their static IP - # This is useful for users that are using DHCP reservations; then we can just use the information gathered via our functions - DHCPChoice=$(whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --menu --separate-output "Do you want to use your current network settings as a static address? \\n - IP address: ${IPV4_ADDRESS} \\n - Gateway: ${IPv4gw} \\n" "${r}" "${c}" 3\ - "Yes" "Set static IP using current values" \ - "No" "Set static IP using custom values" \ - "Skip" "I will set a static IP later, or have already done so" 3>&2 2>&1 1>&3) || \ - { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } + # This is useful for users that are using DHCP reservations; we can use the information gathered + DHCPChoice=$(dialog --no-shadow --clear --output-fd 1 \ + --backtitle "Calibrating network interface" \ + --title "Static IP Address" \ + --menu "Do you want to use your current network settings as a static address?\\n \ + IP address: ${IPV4_ADDRESS}\\n \ + Gateway: ${IPv4gw}\\n" \ + "${r}" "${c}" 3 \ + "Yes" "Set static IP using current values" \ + "No" "Set static IP using custom values" \ + "Skip" "I will set a static IP later, or have already done so") - case ${DHCPChoice} in - "Yes") - # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. - whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that. - If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want. - It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." "${r}" "${c}" - # Nothing else to do since the variables are already set above - setDHCPCD - ;; + result=$? + case ${result} in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac - "No") - # Otherwise, we need to ask the user to input their desired settings. - # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP) - # Start a loop to let the user enter their information with the chance to go back and edit it if necessary - until [[ "${ipSettingsCorrect}" = True ]]; do + case ${DHCPChoice} in + "Skip") + return + ;; + "Yes") + # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. + dialog --no-shadow --clear \ + --backtitle "IP information" \ + --title "FYI: IP Conflict" \ + --msgbox "\\nIt is possible your router could still try to assign this IP to a device, which would cause a conflict. \ + But in most cases the router is smart enough to not do that. \ + If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want. \ + It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." \ + "${r}" "${c}" - # Ask for the IPv4 address - IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" "${r}" "${c}" "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3) || \ - # Canceling IPv4 settings window - { ipSettingsCorrect=False; echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; } - printf " %b Your static IPv4 address: %s\\n" "${INFO}" "${IPV4_ADDRESS}" + result=$? + case ${result} in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac + ;; - # Ask for the gateway - IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" "${r}" "${c}" "${IPv4gw}" 3>&1 1>&2 2>&3) || \ - # Canceling gateway settings window - { ipSettingsCorrect=False; echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; } - printf " %b Your static IPv4 gateway: %s\\n" "${INFO}" "${IPv4gw}" + "No") + # Otherwise, we need to ask the user to input their desired settings. + # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP) + # Start a loop to let the user enter their information with the chance to go back and edit it if necessary + ipSettingsCorrect=false + until [[ "${ipSettingsCorrect}" = True ]]; do - # Give the user a chance to review their settings before moving on - if whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct? - IP address: ${IPV4_ADDRESS} - Gateway: ${IPv4gw}" "${r}" "${c}"; then + # Ask for the IPv4 address + _staticIPv4Temp=$(dialog --no-shadow --clear --output-fd 1 \ + --backtitle "Calibrating network interface" \ + --title "IPv4 Address" \ + --form "\\nEnter your desired IPv4 address" \ + "${r}" "${c}" 0 \ + "IPv4 Address:" 1 1 "${IPV4_ADDRESS}" 1 15 19 0 \ + "IPv4 Gateway:" 2 1 "${IPv4gw}" 2 15 19 0) + + result=$? + case ${result} in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac + + IPV4_ADDRESS=${_staticIPv4Temp%$'\n'*} + IPv4gw=${_staticIPv4Temp#*$'\n'} + + # Give the user a chance to review their settings before moving on + dialog --no-shadow --clear \ + --backtitle "Calibrating network interface" \ + --title "Static IP Address" \ + --defaultno \ + --yesno "Are these settings correct? + IP address: ${IPV4_ADDRESS} + Gateway: ${IPv4gw}" \ + "${r}" "${c}" + + result=$? + case ${result} in + "${DIALOG_OK}") # After that's done, the loop ends and we move on ipSettingsCorrect=True - else - # If the settings are wrong, the loop continues - ipSettingsCorrect=False - fi + ;; + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac done - setDHCPCD - ;; - esac + ;; + esac + setDHCPCD } # Configure networking via dhcpcd @@ -929,11 +1029,18 @@ setDNS() { DNSChooseOptions[DNSServerCount]="" # Restore the IFS to what it was IFS=${OIFS} - # In a whiptail dialog, show the options - DNSchoices=$(whiptail --separate-output --menu "Select Upstream DNS Provider. To use your own, select Custom." "${r}" "${c}" 7 \ - "${DNSChooseOptions[@]}" 2>&1 >/dev/tty) || \ - # Exit if the user selects "Cancel" - { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } + # In a dialog, show the options + DNSchoices=$(dialog --no-shadow --clear --output-fd 1 \ + --menu "Select Upstream DNS Provider. To use your own, select Custom." "${r}" "${c}" 7 \ + "${DNSChooseOptions[@]}") + + result=$? + case ${result} in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac # Depending on the user's choice, set the GLOBAL variables to the IP of the respective provider if [[ "${DNSchoices}" == "Custom" ]] @@ -947,7 +1054,7 @@ setDNS() { # If the first and second upstream servers do not exist, do not prepopulate an IP address prePopulate="" else - # Otherwise, prepopulate the whiptail dialogue with the appropriate DNS value(s) + # Otherwise, prepopulate the dialogue with the appropriate DNS value(s) prePopulate=", ${PIHOLE_DNS_2}" fi elif [[ "${PIHOLE_DNS_1}" ]] && [[ ! "${PIHOLE_DNS_2}" ]]; then @@ -957,8 +1064,21 @@ setDNS() { fi # Prompt the user to enter custom upstream servers - piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), separated by a comma. If you want to specify a port other than 53, separate it with a hash.\\n\\nFor example '8.8.8.8, 8.8.4.4' or '127.0.0.1#5335'" "${r}" "${c}" "${prePopulate}" 3>&1 1>&2 2>&3) || \ - { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } + piholeDNS=$(dialog --no-shadow --clear --output-fd 1 \ + --backtitle "Specify Upstream DNS Provider(s)" \ + --inputbox "Enter your desired upstream DNS provider(s), separated by a comma. \ + If you want to specify a port other than 53, separate it with a hash. \ + \\n\\nFor example '8.8.8.8, 8.8.4.4' or '127.0.0.1#5335'" \ + "${r}" "${c}" "${prePopulate}") + + result=$? + case ${result} in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac + # Clean user input and replace whitespace with comma. piholeDNS=$(sed 's/[, \t]\+/,/g' <<< "${piholeDNS}") @@ -977,7 +1097,21 @@ setDNS() { # If either of the DNS servers are invalid, if [[ "${PIHOLE_DNS_1}" == "${strInvalid}" ]] || [[ "${PIHOLE_DNS_2}" == "${strInvalid}" ]]; then # explain this to the user, - whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\\n\\n DNS Server 1: $PIHOLE_DNS_1\\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c} + dialog --no-shadow --clear \ + --title "Invalid IP Address(es)" \ + --backtitle "Invalid IP" \ + --msgbox "\\nOne or both of the entered IP addresses were invalid. Please try again. \ + \\n\\nInvalid IPs: ${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}" \ + "${r}" "${c}" + + result=$? + case ${result} in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac + # set the variables back to nothing, if [[ "${PIHOLE_DNS_1}" == "${strInvalid}" ]]; then PIHOLE_DNS_1="" @@ -988,12 +1122,25 @@ setDNS() { # and continue the loop. DNSSettingsCorrect=False else - # Otherwise, show the DNS setting to the user, and break the loop if they confirm them. - if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\\n DNS Server 1: $PIHOLE_DNS_1\\n DNS Server 2: ${PIHOLE_DNS_2}" "${r}" "${c}"); then - DNSSettingsCorrect=True - else - DNSSettingsCorrect=False - fi + dialog --no-shadow --clear \ + --backtitle "Specify Upstream DNS Provider(s)" \ + --title "Upstream DNS Provider(s)" \ + --yesno "Are these settings correct?\\n\\tDNS Server 1:\\t${PIHOLE_DNS_1}\\n\\tDNS Server 2:\\t${PIHOLE_DNS_2}" \ + "${r}" "${c}" + + result=$? + case ${result} in + "${DIALOG_OK}") + DNSSettingsCorrect=True + ;; + "${DIALOG_CANCEL}") + DNSSettingsCorrect=False + ;; + "${DIALOG_ESC}") + printf " %bEscape pressed, exiting installer at DNS Settings%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac fi done else @@ -1023,106 +1170,122 @@ setDNS() { # Allow the user to enable/disable logging setLogging() { - # Local, named variables - local LogToggleCommand - local LogChooseOptions - local LogChoices + # Ask the user if they want to enable logging + dialog --no-shadow --clear \ + --backtitle "Pihole Installation" \ + --title "Enable Logging" \ + --yesno "\\n\\nWould you like to enable query logging?" \ + "${r}" "${c}" - # Ask if the user wants to log queries - LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?" "${r}" "${c}" 6) - # The default selection is on - LogChooseOptions=("On (Recommended)" "" on - Off "" off) - # Get the user's choice - LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" && exit 1) - case ${LogChoices} in - # If it's on, - "On (Recommended)") - printf " %b Logging On.\\n" "${INFO}" - # set the GLOBAL variable setting to true + result=$? + case ${result} in + "${DIALOG_OK}") + # If they chose yes, + printf " %b Query Logging on.\\n" "${INFO}" QUERY_LOGGING=true ;; - # Otherwise, it's off, - Off) - printf " %b Logging Off.\\n" "${INFO}" - # set the GLOBAL variable setting to false + "${DIALOG_CANCEL}") + # If they chose no, + printf " %b Query Logging off.\\n" "${INFO}" QUERY_LOGGING=false ;; + "${DIALOG_ESC}") + # User pressed + printf " %bEscape pressed, exiting installer at Query Logging choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; esac } # Allow the user to set their FTL privacy level setPrivacyLevel() { - local LevelCommand - local LevelOptions + PRIVACY_LEVEL=$(dialog --no-shadow --clear --output-fd 1 \ + --radiolist "Select a privacy mode for FTL. https://docs.pi-hole.net/ftldns/privacylevels/" \ + "${r}" "${c}" 6 \ + # The default selection is level 0 + "0" "Show everything" on \ + "1" "Hide domains" off \ + "2" "Hide domains and clients" off \ + "3" "Anonymous mode" off) - LevelCommand=(whiptail --separate-output --radiolist "Select a privacy mode for FTL. https://docs.pi-hole.net/ftldns/privacylevels/" "${r}" "${c}" 6) - - # The default selection is level 0 - LevelOptions=( - "0" "Show everything" on - "1" "Hide domains" off - "2" "Hide domains and clients" off - "3" "Anonymous mode" off - ) - - # Get the user's choice - PRIVACY_LEVEL=$("${LevelCommand[@]}" "${LevelOptions[@]}" 2>&1 >/dev/tty) || (echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}" && exit 1) - - printf " %b Privacy level %d" "${INFO}" "${PRIVACY_LEVEL}" + result=$? + case ${result} in + "${DIALOG_OK}") + printf " %b Using privacy level: %s\\n" "${INFO}" "${PRIVACY_LEVEL}" + ;; + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %b Cancelled privacy level selection.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac } # Function to ask the user if they want to install the dashboard setAdminFlag() { - # Local, named variables - local WebToggleCommand - local WebChooseOptions - local WebChoices - # Similar to the logging function, ask what the user wants - WebToggleCommand=(whiptail --separate-output --radiolist "Do you wish to install the web admin interface?" "${r}" "${c}" 6) - # with the default being enabled - WebChooseOptions=("On (Recommended)" "" on - Off "" off) - WebChoices=$("${WebToggleCommand[@]}" "${WebChooseOptions[@]}" 2>&1 >/dev/tty) || (printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" && exit 1) - # Depending on their choice - case ${WebChoices} in - "On (Recommended)") - printf " %b Web Interface On\\n" "${INFO}" - # Set it to true + dialog --no-shadow --clear \ + --backtitle "Pihole Installation" \ + --title "Admin Web Interface" \ + --yesno "\\n\\nDo you want to install the Admin Web Interface?" \ + "${r}" "${c}" + + result=$? + case ${result} in + "${DIALOG_OK}") + # If they chose yes, + printf " %b Installing Admin Web Interface\\n" "${INFO}" + # Set the flag to install the web interface INSTALL_WEB_INTERFACE=true ;; - Off) - printf " %b Web Interface Off\\n" "${INFO}" - # or false + "${DIALOG_CANCEL}") + # If they chose no, + printf " %b Not installing Admin Web Interface\\n" "${INFO}" + # Set the flag to not install the web interface INSTALL_WEB_INTERFACE=false - # Deselect the web server as well, since it is obsolete then INSTALL_WEB_SERVER=false ;; + "${DIALOG_ESC}") + # User pressed + printf " %bEscape pressed, exiting installer at Admin Web Interface choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; esac # If the user wants to install the Web admin interface (i.e. it has not been deselected above) - if [[ "${INSTALL_WEB_SERVER}" == true ]]; then + if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then # Get list of required PHP modules, excluding base package (common) and handler (cgi) local i php_modules for i in "${PIHOLE_WEB_DEPS[@]}"; do [[ $i == 'php'* && $i != *'-common' && $i != *'-cgi' ]] && php_modules+=" ${i#*-}"; done - WebToggleCommand=(whiptail --separate-output --radiolist "Do you wish to install the web server (lighttpd) and required PHP modules?\\n\\nNB: If you disable this, and, do not have an existing web server and required PHP modules (${php_modules# }) installed, the web interface will not function. Additionally the web server user needs to be member of the \"pihole\" group for full functionality." "${r}" "${c}" 6) - # Enable as default and recommended option - WebChooseOptions=("On (Recommended)" "" on - Off "" off) - WebChoices=$("${WebToggleCommand[@]}" "${WebChooseOptions[@]}" 2>&1 >/dev/tty) || (printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" && exit 1) - # Depending on their choice - case ${WebChoices} in - "On (Recommended)") - printf " %b Web Server On\\n" "${INFO}" - # set it to true, as clearly seen below. + dialog --no-shadow --clear \ + --backtitle "Pi-hole Installation" \ + --title "Web Server" \ + --yesno "\\n\\nA web server is required for the Admin Web Interface. \ + \\n\\nDo you want to install lighttpd and the required PHP modules? \ + \\n\\nNB: If you disable this, and, do not have an existing web server \ + and required PHP modules (${php_modules# }) installed, the web interface \ + will not function. Additionally the web server user needs to be member of \ + the \"pihole\" group for full functionality." \ + "${r}" "${c}" + + result=$? + case ${result} in + "${DIALOG_OK}") + # If they chose yes, + printf " %b Installing lighttpd\\n" "${INFO}" + # Set the flag to install the web server INSTALL_WEB_SERVER=true ;; - Off) - printf " %b Web Server Off\\n" "${INFO}" - # or false + "${DIALOG_CANCEL}") + # If they chose no, + printf " %b Not installing lighttpd\\n" "${INFO}" + # Set the flag to not install the web server INSTALL_WEB_SERVER=false ;; + "${DIALOG_ESC}") + # User pressed + printf " %bEscape pressed, exiting installer at web server choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; esac fi } @@ -1133,18 +1296,33 @@ chooseBlocklists() { if [[ -f "${adlistFile}" ]]; then mv "${adlistFile}" "${adlistFile}.old" fi - # Let user select (or not) blocklists via a checklist - cmd=(whiptail --separate-output --checklist "Pi-hole relies on third party lists in order to block ads.\\n\\nYou can use the suggestion below, and/or add your own after installation\\n\\nTo deselect the suggested list, use spacebar" "${r}" "${c}" 5) - # In an array, show the options available (all off by default): - options=(StevenBlack "StevenBlack's Unified Hosts List" on) + # Let user select (or not) blocklists + dialog --no-shadow --clear \ + --backtitle "Pi-hole Installation" \ + --title "Blocklists" \ + --yesno "\\nPi-hole relies on third party lists in order to block ads. \ + \\n\\nYou can use the suggestion below, and/or add your own after installation. \ + \\n\\nSelect 'Yes' to include: \ + \\n\\nStevenBlack's Unified Hosts List" \ + "${r}" "${c}" - # In a variable, show the choices available; exit if Cancel is selected - choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty) || { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; rm "${adlistFile}" ;exit 1; } - # Add all selected choices to the lists file - for choice in ${choices} - do - appendToListsFile "${choice}" - done + result=$? + case ${result} in + "${DIALOG_OK}") + # If they chose yes, + printf " %b Installing StevenBlack's Unified Hosts List\\n" "${INFO}" + echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >> "${adlistFile}" + ;; + "${DIALOG_CANCEL}") + # If they chose no, + printf " %b Not installing StevenBlack's Unified Hosts List\\n" "${INFO}" + ;; + "${DIALOG_ESC}") + # User pressed + printf " %bEscape pressed, exiting installer at blocklist choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac # Create an empty adList file with appropriate permissions. if [ ! -f "${adlistFile}" ]; then install -m 644 /dev/null "${adlistFile}" @@ -1153,14 +1331,6 @@ chooseBlocklists() { fi } -# Accept a string parameter, it must be one of the default lists -# This function saves duplication between chooseBlocklists and installDefaultBlocklists -appendToListsFile() { - case $1 in - StevenBlack ) echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >> "${adlistFile}";; - esac -} - # Used only in unattended setup # If there is already the adListFile, we keep it, else we create it using all default lists installDefaultBlocklists() { @@ -1169,7 +1339,7 @@ installDefaultBlocklists() { if [[ -f "${adlistFile}" ]]; then return; fi - appendToListsFile StevenBlack + echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >> "${adlistFile}" } # Check if /etc/dnsmasq.conf is from pi-hole. If so replace with an original and install new in .d directory @@ -1940,14 +2110,14 @@ Your Admin Webpage login password is ${pwstring}" fi # Final completion message to user - whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using: - -IPv4: ${IPV4_ADDRESS%/*} -IPv6: ${IPV6_ADDRESS:-"Not Configured"} - -If you have not done so already, the above IP should be set to static. - -${additional}" "${r}" "${c}" + dialog --no-shadow --clear \ + --title "Installation Complete!" \ + --msgbox "Configure your devices to use the Pi-hole as their DNS server using: \ + \\n\\nIPv4: ${IPV4_ADDRESS%/*} \ + \\nIPv6: ${IPV6_ADDRESS:-"Not Configured"} \ + \\nIf you have not done so already, the above IP should be set to static. \ + \\n${additional}" + "${r}" "${c}" } update_dialogs() { @@ -1967,20 +2137,32 @@ update_dialogs() { opt2b="Resets Pi-hole and allows re-selecting settings." # Display the information to the user - UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\\n\\nWe have detected an existing install.\\n\\nPlease choose from the following options: \\n($strAdd)" "${r}" "${c}" 2 \ + UpdateCmd=$(dialog --no-shadow --clear --output-fd 1 \ + --title "Existing Install Detected!" \ + --menu "\\n\\nWe have detected an existing install. \ + \\n\\nPlease choose from the following options: \ + \\n($strAdd)" \ + "${r}" "${c}" 2 \ "${opt1a}" "${opt1b}" \ - "${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3) || \ - { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } + "${opt2a}" "${opt2b}") + + result=$? + case ${result} in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + exit 1 + ;; + esac # Set the variable based on if the user chooses case ${UpdateCmd} in # repair, or - ${opt1a}) + "${opt1a}") printf " %b %s option selected\\n" "${INFO}" "${opt1a}" useUpdateVars=true ;; # reconfigure, - ${opt2a}) + "${opt2a}") printf " %b %s option selected\\n" "${INFO}" "${opt2a}" useUpdateVars=false ;; @@ -2478,7 +2660,7 @@ main() { if [[ -f "${setupVars}" ]]; then # if it's running unattended, if [[ "${runUnattended}" == true ]]; then - printf " %b Performing unattended setup, no whiptail dialogs will be displayed\\n" "${INFO}" + printf " %b Performing unattended setup, no dialogs will be displayed\\n" "${INFO}" # Use the setup variables useUpdateVars=true # also disable debconf-apt-progress dialogs From 1ed5ff306d21392f9da6566e5601110cb590e085 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sat, 2 Jul 2022 12:36:16 -0700 Subject: [PATCH 02/11] Align dialog texts. Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 78 +++++++++++++++--------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index b1202d75..f0a33967 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -101,7 +101,7 @@ if [ -z "${USER}" ]; then USER="$(id -un)" fi -# dialog dimensions: 20 rows and 70 chars width assures to fit on small screens and is known to hold all content. +# dialog dimensions: Let dialog handle appropriate sizing. r=20 c=70 @@ -430,9 +430,9 @@ select_rpm_php(){ dialog --no-shadow --clear \ --title "PHP 7 Update (recommended)" \ --defaultno \ - --yesno "PHP 7.x is recommended for both security and language features. \ - \\nWould you like to install PHP7 via Remi's RPM repository? \ - \\n\\nSee: https://rpms.remirepo.net for more information" \ + --yesno "PHP 7.x is recommended for both security and language features.\ +\\n\\nWould you like to install PHP7 via Remi's RPM repository?\ +\\n\\nSee: https://rpms.remirepo.net for more information"\ "${r}" "${c}" result=$? @@ -474,9 +474,9 @@ select_rpm_php(){ --defaultno \ --no-button "Exit" \ --yes-button "Continue" \ - --yesno "Would you like to continue installation on an unsupported RPM based distribution? \ - \\n\\nPlease ensure the following packages have been installed manually: \ - \\n\\n- lighttpd\\n- lighttpd-fastcgi\\n- PHP version 7+" \ + --yesno "Would you like to continue installation on an unsupported RPM based distribution?\ +\\n\\nPlease ensure the following packages have been installed manually:\ +\\n\\n- lighttpd\\n- lighttpd-fastcgi\\n- PHP version 7+"\ "${r}" "${c}" result=$? @@ -702,10 +702,10 @@ welcomeDialogs() { --title "Static IP Needed" \ --no-button "Exit" --yes-button "Continue" \ --defaultno \ - --yesno "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.\\n\\n \ - \\Zb\\Z1IMPORTANT:\\Zn If you have not already done so, you must ensure that this device has a static IP.\\n \ - Depending on your operating system, there are many ways to achieve this, through DHCP reservation, or by manually assigning one.\\n\\n \ - Please continue when the static addressing has been configured." \ + --yesno "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.\\n\\n\ +\\Zb\\Z1IMPORTANT:\\Zn If you have not already done so, you must ensure that this device has a static IP.\\n\\n\ +Depending on your operating system, there are many ways to achieve this, through DHCP reservation, or by manually assigning one.\\n\\n\ +Please continue when the static addressing has been configured."\ "${r}" "${c}" result=$? @@ -873,10 +873,10 @@ getStaticIPv4Settings() { dialog --no-shadow --clear \ --backtitle "IP information" \ --title "FYI: IP Conflict" \ - --msgbox "\\nIt is possible your router could still try to assign this IP to a device, which would cause a conflict. \ - But in most cases the router is smart enough to not do that. \ - If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want. \ - It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." \ + --msgbox "\\nIt is possible your router could still try to assign this IP to a device, which would cause a conflict\ +But in most cases the router is smart enough to not do that.\ +If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.\ +It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address."\ "${r}" "${c}" result=$? @@ -1066,9 +1066,9 @@ setDNS() { # Prompt the user to enter custom upstream servers piholeDNS=$(dialog --no-shadow --clear --output-fd 1 \ --backtitle "Specify Upstream DNS Provider(s)" \ - --inputbox "Enter your desired upstream DNS provider(s), separated by a comma. \ - If you want to specify a port other than 53, separate it with a hash. \ - \\n\\nFor example '8.8.8.8, 8.8.4.4' or '127.0.0.1#5335'" \ + --inputbox "Enter your desired upstream DNS provider(s), separated by a comma.\ +If you want to specify a port other than 53, separate it with a hash.\ +\\n\\nFor example '8.8.8.8, 8.8.4.4' or '127.0.0.1#5335'"\ "${r}" "${c}" "${prePopulate}") result=$? @@ -1100,8 +1100,8 @@ setDNS() { dialog --no-shadow --clear \ --title "Invalid IP Address(es)" \ --backtitle "Invalid IP" \ - --msgbox "\\nOne or both of the entered IP addresses were invalid. Please try again. \ - \\n\\nInvalid IPs: ${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}" \ + --msgbox "\\nOne or both of the entered IP addresses were invalid. Please try again.\ +\\n\\nInvalid IPs: ${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}" \ "${r}" "${c}" result=$? @@ -1199,10 +1199,10 @@ setLogging() { # Allow the user to set their FTL privacy level setPrivacyLevel() { + # The default selection is level 0 PRIVACY_LEVEL=$(dialog --no-shadow --clear --output-fd 1 \ --radiolist "Select a privacy mode for FTL. https://docs.pi-hole.net/ftldns/privacylevels/" \ "${r}" "${c}" 6 \ - # The default selection is level 0 "0" "Show everything" on \ "1" "Hide domains" off \ "2" "Hide domains and clients" off \ @@ -1259,12 +1259,12 @@ setAdminFlag() { dialog --no-shadow --clear \ --backtitle "Pi-hole Installation" \ --title "Web Server" \ - --yesno "\\n\\nA web server is required for the Admin Web Interface. \ - \\n\\nDo you want to install lighttpd and the required PHP modules? \ - \\n\\nNB: If you disable this, and, do not have an existing web server \ - and required PHP modules (${php_modules# }) installed, the web interface \ - will not function. Additionally the web server user needs to be member of \ - the \"pihole\" group for full functionality." \ + --yesno "\\n\\nA web server is required for the Admin Web Interface.\ +\\n\\nDo you want to install lighttpd and the required PHP modules?\ +\\n\\nNB: If you disable this, and, do not have an existing web server\ +and required PHP modules (${php_modules# }) installed, the web interface\ +will not function. Additionally the web server user needs to be member of\ +the \"pihole\" group for full functionality." \ "${r}" "${c}" result=$? @@ -1300,10 +1300,10 @@ chooseBlocklists() { dialog --no-shadow --clear \ --backtitle "Pi-hole Installation" \ --title "Blocklists" \ - --yesno "\\nPi-hole relies on third party lists in order to block ads. \ - \\n\\nYou can use the suggestion below, and/or add your own after installation. \ - \\n\\nSelect 'Yes' to include: \ - \\n\\nStevenBlack's Unified Hosts List" \ + --yesno "\\nPi-hole relies on third party lists in order to block ads.\ +\\n\\nYou can use the suggestion below, and/or add your own after installation.\ +\\n\\nSelect 'Yes' to include:\ +\\n\\nStevenBlack's Unified Hosts List" \ "${r}" "${c}" result=$? @@ -2112,11 +2112,11 @@ Your Admin Webpage login password is ${pwstring}" # Final completion message to user dialog --no-shadow --clear \ --title "Installation Complete!" \ - --msgbox "Configure your devices to use the Pi-hole as their DNS server using: \ - \\n\\nIPv4: ${IPV4_ADDRESS%/*} \ - \\nIPv6: ${IPV6_ADDRESS:-"Not Configured"} \ - \\nIf you have not done so already, the above IP should be set to static. \ - \\n${additional}" + --msgbox "Configure your devices to use the Pi-hole as their DNS server using:\ +\\n\\nIPv4: ${IPV4_ADDRESS%/*}\ +\\nIPv6: ${IPV6_ADDRESS:-"Not Configured"}\ +\\nIf you have not done so already, the above IP should be set to static.\ +\\n${additional}" "${r}" "${c}" } @@ -2139,9 +2139,9 @@ update_dialogs() { # Display the information to the user UpdateCmd=$(dialog --no-shadow --clear --output-fd 1 \ --title "Existing Install Detected!" \ - --menu "\\n\\nWe have detected an existing install. \ - \\n\\nPlease choose from the following options: \ - \\n($strAdd)" \ + --menu "\\n\\nWe have detected an existing install.\ +\\n\\nPlease choose from the following options:\ +\\n($strAdd)"\ "${r}" "${c}" 2 \ "${opt1a}" "${opt1b}" \ "${opt2a}" "${opt2b}") From a650641da48410744e7bfb77f6d92437a9787282 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sat, 2 Jul 2022 12:51:03 -0700 Subject: [PATCH 03/11] Change tests to mock dialog Signed-off-by: Dan Schaper --- test/test_any_automated_install.py | 18 +++++++++--------- test/test_centos_7_support.py | 8 ++++---- test/test_centos_8_support.py | 8 ++++---- test/test_centos_common_support.py | 8 ++++---- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/test_any_automated_install.py b/test/test_any_automated_install.py index f42feef0..61849f54 100644 --- a/test/test_any_automated_install.py +++ b/test/test_any_automated_install.py @@ -152,8 +152,8 @@ def test_installPihole_fresh_install_readableFiles(host): ''' confirms all necessary files are readable by pihole user ''' - # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*': ('', '0')}, host) + # dialog returns Cancel for user prompt + mock_command('dialog', {'*': ('', '0')}, host) # mock git pull mock_command_passthrough('git', {'pull': ('', '0')}, host) # mock systemctl to not start lighttpd and FTL @@ -393,8 +393,8 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): "127.0.0.1", # "pi.hole" ] - # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*': ('', '0')}, host) + # dialog returns Cancel for user prompt + mock_command('dialog', {'*': ('', '0')}, host) # mock git pull mock_command_passthrough('git', {'pull': ('', '0')}, host) @@ -870,8 +870,8 @@ def test_FTL_download_aarch64_no_errors(host): ''' confirms only aarch64 package is downloaded for FTL engine ''' - # mock whiptail answers and ensure installer dependencies - mock_command('whiptail', {'*': ('', '0')}, host) + # mock dialog answers and ensure installer dependencies + mock_command('dialog', {'*': ('', '0')}, host) host.run(''' source /opt/pihole/basic-install.sh package_manager_detect @@ -1100,7 +1100,7 @@ def test_os_check_passes(host): def test_package_manager_has_installer_deps(host): ''' Confirms OS is able to install the required packages for the installer''' - mock_command('whiptail', {'*': ('', '0')}, host) + mock_command('dialog', {'*': ('', '0')}, host) output = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect @@ -1113,7 +1113,7 @@ def test_package_manager_has_installer_deps(host): def test_package_manager_has_pihole_deps(host): ''' Confirms OS is able to install the required packages for Pi-hole ''' - mock_command('whiptail', {'*': ('', '0')}, host) + mock_command('dialog', {'*': ('', '0')}, host) output = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect @@ -1127,7 +1127,7 @@ def test_package_manager_has_pihole_deps(host): def test_package_manager_has_web_deps(host): ''' Confirms OS is able to install the required packages for web ''' - mock_command('whiptail', {'*': ('', '0')}, host) + mock_command('dialog', {'*': ('', '0')}, host) output = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect diff --git a/test/test_centos_7_support.py b/test/test_centos_7_support.py index f72740a6..c7e75813 100644 --- a/test/test_centos_7_support.py +++ b/test/test_centos_7_support.py @@ -26,8 +26,8 @@ def test_php_upgrade_user_optout_centos_eq_7(host): confirms installer behavior when user opt-out of installing PHP7 from REMI (php not currently installed) ''' - # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*': ('', '1')}, host) + # dialog returns Cancel for user prompt + mock_command('dialog', {'*': ('', '1')}, host) package_manager_detect = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect @@ -45,8 +45,8 @@ def test_php_upgrade_user_optin_centos_eq_7(host): confirms installer behavior when user opt-in to installing PHP7 from REMI (php not currently installed) ''' - # Whiptail dialog returns Continue for user prompt - mock_command('whiptail', {'*': ('', '0')}, host) + # dialog returns Continue for user prompt + mock_command('dialog', {'*': ('', '0')}, host) package_manager_detect = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect diff --git a/test/test_centos_8_support.py b/test/test_centos_8_support.py index 464055b4..9adbe841 100644 --- a/test/test_centos_8_support.py +++ b/test/test_centos_8_support.py @@ -29,8 +29,8 @@ def test_php_upgrade_user_optout_skipped_centos_gte_8(host): latest CentOS (should trigger on CentOS7 only) (php not currently installed) ''' - # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*': ('', '1')}, host) + # dialog dialog returns Cancel for user prompt + mock_command('dialog', {'*': ('', '1')}, host) package_manager_detect = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect @@ -50,8 +50,8 @@ def test_php_upgrade_user_optin_skipped_centos_gte_8(host): latest CentOS (should trigger on CentOS7 only) (php not currently installed) ''' - # Whiptail dialog returns Continue for user prompt - mock_command('whiptail', {'*': ('', '0')}, host) + # dialog dialog returns Continue for user prompt + mock_command('dialog', {'*': ('', '0')}, host) package_manager_detect = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect diff --git a/test/test_centos_common_support.py b/test/test_centos_common_support.py index 80ca2a85..ac408e92 100644 --- a/test/test_centos_common_support.py +++ b/test/test_centos_common_support.py @@ -76,8 +76,8 @@ def test_php_version_lt_7_detected_upgrade_user_optout_centos(host): default_centos_php_version = php_package.version.split('.')[0] if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended pytest.skip("Test deprecated . Detected default PHP version >= 7") - # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*': ('', '1')}, host) + # dialog returns Cancel for user prompt + mock_command('dialog', {'*': ('', '1')}, host) package_manager_detect = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect @@ -101,8 +101,8 @@ def test_php_version_lt_7_detected_upgrade_user_optin_centos(host): default_centos_php_version = php_package.version.split('.')[0] if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended pytest.skip("Test deprecated . Detected default PHP version >= 7") - # Whiptail dialog returns Continue for user prompt - mock_command('whiptail', {'*': ('', '0')}, host) + # dialog returns Continue for user prompt + mock_command('dialog', {'*': ('', '0')}, host) package_manager_detect = host.run(''' source /opt/pihole/basic-install.sh package_manager_detect From 2845c72bde1aa741534d4cf7234203e39d52aff1 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sat, 2 Jul 2022 17:13:33 -0700 Subject: [PATCH 04/11] Add testing dependencies for CentOS7 and dialog Signed-off-by: Dan Schaper --- test/_centos_7.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/_centos_7.Dockerfile b/test/_centos_7.Dockerfile index 355f4fdb..95422525 100644 --- a/test/_centos_7.Dockerfile +++ b/test/_centos_7.Dockerfile @@ -1,5 +1,5 @@ FROM centos:7 -RUN yum install -y git +RUN yum install -y dialog git python3 ENV GITDIR /etc/.pihole ENV SCRIPTDIR /opt/pihole From 44667b5ffb70ff72d3cdf4e3a3dcdde84427605f Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Mon, 4 Jul 2022 12:35:08 -0700 Subject: [PATCH 05/11] Add dialog to RPM installer requirements. Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index f0a33967..0e023215 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -292,6 +292,9 @@ test_dpkg_lock() { # Compatibility package_manager_detect() { + # TODO - pull common packages for both distributions out into a common variable, then add + # the distro-specific ones below. + # First check to see if apt-get is installed. if is_command apt-get ; then # Set some global variables here @@ -355,7 +358,7 @@ package_manager_detect() { PKG_INSTALL=("${PKG_MANAGER}" install -y) PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l" OS_CHECK_DEPS=(grep bind-utils) - INSTALLER_DEPS=(git iproute newt procps-ng which chkconfig ca-certificates) + INSTALLER_DEPS=(git dialog iproute newt procps-ng which chkconfig ca-certificates) PIHOLE_DEPS=(cronie curl findutils sudo unzip libidn2 psmisc libcap nmap-ncat) PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php-common php-cli php-pdo php-xml php-json php-intl) LIGHTTPD_USER="lighttpd" From 72fcdb128a788adcfa74940611480d11d75cc6fa Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Mon, 4 Jul 2022 14:00:16 -0700 Subject: [PATCH 06/11] Rework cenos7 functions Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 157 +++++++++++++++-------------- 1 file changed, 80 insertions(+), 77 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 0e023215..0cb01206 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -356,7 +356,8 @@ package_manager_detect() { # These variable names match the ones for apt-get. See above for an explanation of what they are for. PKG_INSTALL=("${PKG_MANAGER}" install -y) - PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l" + # CentOS package manager returns 100 when there are packages to update so we need to || true to prevent the script from exiting. + PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l || true" OS_CHECK_DEPS=(grep bind-utils) INSTALLER_DEPS=(git dialog iproute newt procps-ng which chkconfig ca-certificates) PIHOLE_DEPS=(cronie curl findutils sudo unzip libidn2 psmisc libcap nmap-ncat) @@ -407,16 +408,21 @@ select_rpm_php(){ PIHOLE_WEB_DEPS=("${CENTOS7_PIHOLE_WEB_DEPS[@]}") unset CENTOS7_PIHOLE_WEB_DEPS fi - # CentOS requires the EPEL repository to gain access to Fedora packages - if [[ CURRENT_CENTOS_VERSION -eq 7 ]]; then - EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm" - elif [[ CURRENT_CENTOS_VERSION -eq 8 ]]; then - EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm" + + if rpm -qa | grep -qi 'epel'; then + printf " %b EPEL repository already installed\\n" "${TICK}" + else + # CentOS requires the EPEL repository to gain access to Fedora packages + if [[ CURRENT_CENTOS_VERSION -eq 7 ]]; then + EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm" + elif [[ CURRENT_CENTOS_VERSION -eq 8 ]]; then + EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm" + fi + printf " %b Enabling EPEL package repository (https://fedoraproject.org/wiki/EPEL)\\n" "${INFO}" + "${PKG_INSTALL[@]}" ${EPEL_PKG} + printf " %b Installed %s\\n" "${TICK}" "${EPEL_PKG}" fi - printf " %b Enabling EPEL package repository (https://fedoraproject.org/wiki/EPEL)\\n" "${INFO}" - "${PKG_INSTALL[@]}" ${EPEL_PKG} &> /dev/null - printf " %b Installed %s\\n" "${TICK}" "${EPEL_PKG}" # The default php on CentOS 7.x is 5.4 which is EOL # Check if the version of PHP available via installed repositories is >= to PHP 7 @@ -424,38 +430,44 @@ select_rpm_php(){ if [[ $AVAILABLE_PHP_VERSION -ge $SUPPORTED_CENTOS_PHP_VERSION ]]; then # Since PHP 7 is available by default, install via default PHP package names : # do nothing as PHP is current + printf "PHP 7 is installed" else REMI_PKG="remi-release" REMI_REPO="remi-php72" - rpm -q ${REMI_PKG} &> /dev/null || rc=$? - if [[ $rc -ne 0 ]]; then - # The PHP version available via default repositories is older than version 7 - dialog --no-shadow --clear \ - --title "PHP 7 Update (recommended)" \ - --defaultno \ - --yesno "PHP 7.x is recommended for both security and language features.\ + REMI_REPO_URL="https://rpms.remirepo.net/enterprise/${REMI_PKG}-$(rpm -E '%{rhel}').rpm" + + # The PHP version available via default repositories is older than version 7 + dialog --no-shadow --keep-tite \ + --title "PHP 7 Update (recommended)" \ + --defaultno \ + --yesno "PHP 7.x is recommended for both security and language features.\ \\n\\nWould you like to install PHP7 via Remi's RPM repository?\ \\n\\nSee: https://rpms.remirepo.net for more information"\ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? - case ${result} in - # User chose to install PHP 7 via Remi's RPM repository - "${DIALOG_OK}") + case ${result} in + "${DIALOG_OK}" ) + printf " %b Installing PHP 7 via Remi's RPM repository\\n" "${INFO}" + "${PKG_INSTALL[@]}" "yum-utils" &> /dev/null + if rpm -q ${REMI_PKG} &> /dev/null; then + printf " %b Remi's RPM repository is already installed\\n" "${TICK}" + else printf " %b Enabling Remi's RPM repository (https://rpms.remirepo.net)\\n" "${INFO}" - "${PKG_INSTALL[@]}" "https://rpms.remirepo.net/enterprise/${REMI_PKG}-$(rpm -E '%{rhel}').rpm" &> /dev/null - # enable the PHP 7 repository via yum-config-manager (provided by yum-utils) - "${PKG_INSTALL[@]}" "yum-utils" &> /dev/null - yum-config-manager --enable ${REMI_REPO} &> /dev/null + yum -y install "${REMI_REPO_URL}" + printf " %b Installed %s from %s\\n" "${TICK}" "${REMI_PKG}" "${REMI_REPO_URL}" printf " %b Remi's RPM repository has been enabled for PHP7\\n" "${TICK}" - # trigger an install/update of PHP to ensure previous version of PHP is updated from REMI - if "${PKG_INSTALL[@]}" "php-cli" &> /dev/null; then - printf " %b PHP7 installed/updated via Remi's RPM repository\\n" "${TICK}" - else - printf " %b There was a problem updating to PHP7 via Remi's RPM repository\\n" "${CROSS}" - exit 1 - fi - ;; + fi + yum-config-manager --disable 'remi-php*' + yum-config-manager --enable "${REMI_REPO}" + + # trigger an install/update of PHP to ensure previous version of PHP is updated from REMI + if "${PKG_INSTALL[@]}" "php-cli" &> /dev/null; then + printf " %b PHP7 installed/updated via Remi's RPM repository\\n" "${TICK}" + else + printf " %b There was a problem updating to PHP7 via Remi's RPM repository\\n" "${CROSS}" + exit 1 + fi + ;; # User chose not to install PHP 7 via Remi's RPM repository "${DIALOG_CANCEL}") @@ -471,8 +483,9 @@ select_rpm_php(){ esac fi + else # Warn user of unsupported version of Fedora or CentOS - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --title "Unsupported RPM based distribution" \ --defaultno \ --no-button "Exit" \ @@ -480,9 +493,8 @@ select_rpm_php(){ --yesno "Would you like to continue installation on an unsupported RPM based distribution?\ \\n\\nPlease ensure the following packages have been installed manually:\ \\n\\n- lighttpd\\n- lighttpd-fastcgi\\n- PHP version 7+"\ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in # User chose to continue installation on an unsupported RPM based distribution "${DIALOG_OK}") @@ -498,7 +510,6 @@ select_rpm_php(){ exit 1 ;; esac - fi fi } @@ -689,17 +700,17 @@ get_available_interfaces() { # A function for displaying the dialogs the user sees when first running the installer welcomeDialogs() { # Display the welcome dialog using an appropriately sized window via the calculation conducted earlier in the script - dialog --no-shadow --clear \ + dialog --no-shadow --clear --keep-tite \ --backtitle "Welcome" \ --title "Pi-hole Automated Installer" \ --msgbox "\\n\\nThis installer will transform your device into a network-wide ad blocker!" \ "${r}" "${c}" \ - --and-widget \ + --and-widget --clear \ --backtitle "Support Pi-hole" \ --title "Open Source Software" \ --msgbox "\\n\\nThe Pi-hole is free, but powered by your donations: https://pi-hole.net/donate/" \ "${r}" "${c}" \ - --and-widget \ + --and-widget --clear \ --colors \ --backtitle "Initiating network interface" \ --title "Static IP Needed" \ @@ -709,9 +720,8 @@ welcomeDialogs() { \\Zb\\Z1IMPORTANT:\\Zn If you have not already done so, you must ensure that this device has a static IP.\\n\\n\ Depending on your operating system, there are many ways to achieve this, through DHCP reservation, or by manually assigning one.\\n\\n\ Please continue when the static addressing has been configured."\ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result="$?" - result=$? case "${result}" in "${DIALOG_CANCEL}" | "${DIALOG_ESC}") printf " %b Installer exited at static IP message.\\n" "${INFO}" @@ -748,7 +758,7 @@ chooseInterface() { done # shellcheck disable=SC2086 # Disable check for double quote here as we are passing a string with spaces - PIHOLE_INTERFACE=$(dialog --no-shadow --clear --output-fd 1 \ + PIHOLE_INTERFACE=$(dialog --no-shadow --keep-tite --output-fd 1 \ --radiolist "Choose An Interface (press space to toggle selection)" \ ${r} ${c} "${interfaceCount}" ${interfacesList}) @@ -848,7 +858,7 @@ getStaticIPv4Settings() { local DHCPChoice # Ask if the user wants to use DHCP settings as their static IP # This is useful for users that are using DHCP reservations; we can use the information gathered - DHCPChoice=$(dialog --no-shadow --clear --output-fd 1 \ + DHCPChoice=$(dialog --no-shadow --keep-tite --output-fd 1 \ --backtitle "Calibrating network interface" \ --title "Static IP Address" \ --menu "Do you want to use your current network settings as a static address?\\n \ @@ -873,16 +883,15 @@ getStaticIPv4Settings() { ;; "Yes") # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --backtitle "IP information" \ --title "FYI: IP Conflict" \ --msgbox "\\nIt is possible your router could still try to assign this IP to a device, which would cause a conflict\ But in most cases the router is smart enough to not do that.\ If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.\ It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address."\ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in "${DIALOG_CANCEL}" | "${DIALOG_ESC}") printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" @@ -899,7 +908,7 @@ It is also possible to use a DHCP reservation, but if you are going to do that, until [[ "${ipSettingsCorrect}" = True ]]; do # Ask for the IPv4 address - _staticIPv4Temp=$(dialog --no-shadow --clear --output-fd 1 \ + _staticIPv4Temp=$(dialog --no-shadow --keep-tite --output-fd 1 \ --backtitle "Calibrating network interface" \ --title "IPv4 Address" \ --form "\\nEnter your desired IPv4 address" \ @@ -919,16 +928,15 @@ It is also possible to use a DHCP reservation, but if you are going to do that, IPv4gw=${_staticIPv4Temp#*$'\n'} # Give the user a chance to review their settings before moving on - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --backtitle "Calibrating network interface" \ --title "Static IP Address" \ --defaultno \ --yesno "Are these settings correct? IP address: ${IPV4_ADDRESS} Gateway: ${IPv4gw}" \ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in "${DIALOG_OK}") # After that's done, the loop ends and we move on @@ -1033,7 +1041,7 @@ setDNS() { # Restore the IFS to what it was IFS=${OIFS} # In a dialog, show the options - DNSchoices=$(dialog --no-shadow --clear --output-fd 1 \ + DNSchoices=$(dialog --no-shadow --keep-tite --output-fd 1 \ --menu "Select Upstream DNS Provider. To use your own, select Custom." "${r}" "${c}" 7 \ "${DNSChooseOptions[@]}") @@ -1067,7 +1075,7 @@ setDNS() { fi # Prompt the user to enter custom upstream servers - piholeDNS=$(dialog --no-shadow --clear --output-fd 1 \ + piholeDNS=$(dialog --no-shadow --keep-tite --output-fd 1 \ --backtitle "Specify Upstream DNS Provider(s)" \ --inputbox "Enter your desired upstream DNS provider(s), separated by a comma.\ If you want to specify a port other than 53, separate it with a hash.\ @@ -1100,14 +1108,13 @@ If you want to specify a port other than 53, separate it with a hash.\ # If either of the DNS servers are invalid, if [[ "${PIHOLE_DNS_1}" == "${strInvalid}" ]] || [[ "${PIHOLE_DNS_2}" == "${strInvalid}" ]]; then # explain this to the user, - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --title "Invalid IP Address(es)" \ --backtitle "Invalid IP" \ --msgbox "\\nOne or both of the entered IP addresses were invalid. Please try again.\ \\n\\nInvalid IPs: ${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}" \ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in "${DIALOG_CANCEL}" | "${DIALOG_ESC}") printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" @@ -1125,13 +1132,12 @@ If you want to specify a port other than 53, separate it with a hash.\ # and continue the loop. DNSSettingsCorrect=False else - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --backtitle "Specify Upstream DNS Provider(s)" \ --title "Upstream DNS Provider(s)" \ --yesno "Are these settings correct?\\n\\tDNS Server 1:\\t${PIHOLE_DNS_1}\\n\\tDNS Server 2:\\t${PIHOLE_DNS_2}" \ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in "${DIALOG_OK}") DNSSettingsCorrect=True @@ -1174,13 +1180,12 @@ If you want to specify a port other than 53, separate it with a hash.\ # Allow the user to enable/disable logging setLogging() { # Ask the user if they want to enable logging - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --backtitle "Pihole Installation" \ --title "Enable Logging" \ --yesno "\\n\\nWould you like to enable query logging?" \ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in "${DIALOG_OK}") # If they chose yes, @@ -1203,7 +1208,7 @@ setLogging() { # Allow the user to set their FTL privacy level setPrivacyLevel() { # The default selection is level 0 - PRIVACY_LEVEL=$(dialog --no-shadow --clear --output-fd 1 \ + PRIVACY_LEVEL=$(dialog --no-shadow --keep-tite --output-fd 1 \ --radiolist "Select a privacy mode for FTL. https://docs.pi-hole.net/ftldns/privacylevels/" \ "${r}" "${c}" 6 \ "0" "Show everything" on \ @@ -1226,13 +1231,12 @@ setPrivacyLevel() { # Function to ask the user if they want to install the dashboard setAdminFlag() { # Similar to the logging function, ask what the user wants - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --backtitle "Pihole Installation" \ --title "Admin Web Interface" \ --yesno "\\n\\nDo you want to install the Admin Web Interface?" \ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in "${DIALOG_OK}") # If they chose yes, @@ -1259,7 +1263,7 @@ setAdminFlag() { # Get list of required PHP modules, excluding base package (common) and handler (cgi) local i php_modules for i in "${PIHOLE_WEB_DEPS[@]}"; do [[ $i == 'php'* && $i != *'-common' && $i != *'-cgi' ]] && php_modules+=" ${i#*-}"; done - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --backtitle "Pi-hole Installation" \ --title "Web Server" \ --yesno "\\n\\nA web server is required for the Admin Web Interface.\ @@ -1268,9 +1272,8 @@ setAdminFlag() { and required PHP modules (${php_modules# }) installed, the web interface\ will not function. Additionally the web server user needs to be member of\ the \"pihole\" group for full functionality." \ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in "${DIALOG_OK}") # If they chose yes, @@ -1300,16 +1303,15 @@ chooseBlocklists() { mv "${adlistFile}" "${adlistFile}.old" fi # Let user select (or not) blocklists - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --backtitle "Pi-hole Installation" \ --title "Blocklists" \ --yesno "\\nPi-hole relies on third party lists in order to block ads.\ \\n\\nYou can use the suggestion below, and/or add your own after installation.\ \\n\\nSelect 'Yes' to include:\ \\n\\nStevenBlack's Unified Hosts List" \ - "${r}" "${c}" + "${r}" "${c}" && result=0 || result=$? - result=$? case ${result} in "${DIALOG_OK}") # If they chose yes, @@ -2113,7 +2115,7 @@ Your Admin Webpage login password is ${pwstring}" fi # Final completion message to user - dialog --no-shadow --clear \ + dialog --no-shadow --keep-tite \ --title "Installation Complete!" \ --msgbox "Configure your devices to use the Pi-hole as their DNS server using:\ \\n\\nIPv4: ${IPV4_ADDRESS%/*}\ @@ -2140,14 +2142,14 @@ update_dialogs() { opt2b="Resets Pi-hole and allows re-selecting settings." # Display the information to the user - UpdateCmd=$(dialog --no-shadow --clear --output-fd 1 \ + UpdateCmd=$(dialog --no-shadow --keep-tite --output-fd 1 \ --title "Existing Install Detected!" \ --menu "\\n\\nWe have detected an existing install.\ \\n\\nPlease choose from the following options:\ \\n($strAdd)"\ "${r}" "${c}" 2 \ "${opt1a}" "${opt1b}" \ - "${opt2a}" "${opt2b}") + "${opt2a}" "${opt2b}" || true) result=$? case ${result} in @@ -2634,6 +2636,9 @@ main() { fi fi + # Check if SELinux is Enforcing and exit before doing anything else + checkSelinux + # Check for supported package managers so that we may install dependencies package_manager_detect @@ -2656,8 +2661,6 @@ main() { select_rpm_php fi - # Check if SELinux is Enforcing - checkSelinux # If the setup variable file exists, if [[ -f "${setupVars}" ]]; then From a39c470f2dd5881856e081abf297237510142e6a Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Tue, 5 Jul 2022 00:06:12 -0700 Subject: [PATCH 07/11] Requested changes. Co-authored-by: MichaIng Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 0cb01206..0728900e 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -1268,9 +1268,9 @@ setAdminFlag() { --title "Web Server" \ --yesno "\\n\\nA web server is required for the Admin Web Interface.\ \\n\\nDo you want to install lighttpd and the required PHP modules?\ -\\n\\nNB: If you disable this, and, do not have an existing web server\ -and required PHP modules (${php_modules# }) installed, the web interface\ -will not function. Additionally the web server user needs to be member of\ +\\n\\nNB: If you disable this, and, do not have an existing web server \ +and required PHP modules (${php_modules# }) installed, the web interface \ +will not function. Additionally the web server user needs to be member of \ the \"pihole\" group for full functionality." \ "${r}" "${c}" && result=0 || result=$? From 39cb1029e9ae804cd1912fc1a84048814e5ab830 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Tue, 5 Jul 2022 14:23:59 -0700 Subject: [PATCH 08/11] Clarify button labels Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 33 ++++++++++++------------------ 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 0728900e..c3ff87cf 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -759,6 +759,7 @@ chooseInterface() { # shellcheck disable=SC2086 # Disable check for double quote here as we are passing a string with spaces PIHOLE_INTERFACE=$(dialog --no-shadow --keep-tite --output-fd 1 \ + --cancel-label "Exit" --ok-label "Select" \ --radiolist "Choose An Interface (press space to toggle selection)" \ ${r} ${c} "${interfaceCount}" ${interfacesList}) @@ -859,6 +860,7 @@ getStaticIPv4Settings() { # Ask if the user wants to use DHCP settings as their static IP # This is useful for users that are using DHCP reservations; we can use the information gathered DHCPChoice=$(dialog --no-shadow --keep-tite --output-fd 1 \ + --cancel-label "Exit" --ok-label "Continue" \ --backtitle "Calibrating network interface" \ --title "Static IP Address" \ --menu "Do you want to use your current network settings as a static address?\\n \ @@ -884,6 +886,7 @@ getStaticIPv4Settings() { "Yes") # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. dialog --no-shadow --keep-tite \ + --cancel-label "Exit" \ --backtitle "IP information" \ --title "FYI: IP Conflict" \ --msgbox "\\nIt is possible your router could still try to assign this IP to a device, which would cause a conflict\ @@ -909,6 +912,8 @@ It is also possible to use a DHCP reservation, but if you are going to do that, # Ask for the IPv4 address _staticIPv4Temp=$(dialog --no-shadow --keep-tite --output-fd 1 \ + --cancer-label "Exit" \ + --ok-label "Continue" \ --backtitle "Calibrating network interface" \ --title "IPv4 Address" \ --form "\\nEnter your desired IPv4 address" \ @@ -929,24 +934,14 @@ It is also possible to use a DHCP reservation, but if you are going to do that, # Give the user a chance to review their settings before moving on dialog --no-shadow --keep-tite \ + --no-label "Edit IP" \ --backtitle "Calibrating network interface" \ --title "Static IP Address" \ --defaultno \ --yesno "Are these settings correct? IP address: ${IPV4_ADDRESS} Gateway: ${IPv4gw}" \ - "${r}" "${c}" && result=0 || result=$? - - case ${result} in - "${DIALOG_OK}") - # After that's done, the loop ends and we move on - ipSettingsCorrect=True - ;; - "${DIALOG_CANCEL}" | "${DIALOG_ESC}") - printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" - exit 1 - ;; - esac + "${r}" "${c}" && ipSettingsCorrect=True done ;; esac @@ -1042,6 +1037,7 @@ setDNS() { IFS=${OIFS} # In a dialog, show the options DNSchoices=$(dialog --no-shadow --keep-tite --output-fd 1 \ + --cancel-label "Exit" \ --menu "Select Upstream DNS Provider. To use your own, select Custom." "${r}" "${c}" 7 \ "${DNSChooseOptions[@]}") @@ -1076,6 +1072,7 @@ setDNS() { # Prompt the user to enter custom upstream servers piholeDNS=$(dialog --no-shadow --keep-tite --output-fd 1 \ + --cancel-label "Exit" \ --backtitle "Specify Upstream DNS Provider(s)" \ --inputbox "Enter your desired upstream DNS provider(s), separated by a comma.\ If you want to specify a port other than 53, separate it with a hash.\ @@ -1113,14 +1110,7 @@ If you want to specify a port other than 53, separate it with a hash.\ --backtitle "Invalid IP" \ --msgbox "\\nOne or both of the entered IP addresses were invalid. Please try again.\ \\n\\nInvalid IPs: ${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}" \ - "${r}" "${c}" && result=0 || result=$? - - case ${result} in - "${DIALOG_CANCEL}" | "${DIALOG_ESC}") - printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" - exit 1 - ;; - esac + "${r}" "${c}" # set the variables back to nothing, if [[ "${PIHOLE_DNS_1}" == "${strInvalid}" ]]; then @@ -1209,6 +1199,8 @@ setLogging() { setPrivacyLevel() { # The default selection is level 0 PRIVACY_LEVEL=$(dialog --no-shadow --keep-tite --output-fd 1 \ + --cancel-label "Exit" \ + --ok-label "Continue" \ --radiolist "Select a privacy mode for FTL. https://docs.pi-hole.net/ftldns/privacylevels/" \ "${r}" "${c}" 6 \ "0" "Show everything" on \ @@ -2143,6 +2135,7 @@ update_dialogs() { # Display the information to the user UpdateCmd=$(dialog --no-shadow --keep-tite --output-fd 1 \ + --cancel-label Exit \ --title "Existing Install Detected!" \ --menu "\\n\\nWe have detected an existing install.\ \\n\\nPlease choose from the following options:\ From ad70ece73e541f576cf5cbdc8f36778f3a4185a4 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 5 Jul 2022 23:10:40 -0300 Subject: [PATCH 09/11] Fixing dialog line breaks Signed-off-by: RD WebDesign --- automated install/basic-install.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index c3ff87cf..18c4a068 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -2101,9 +2101,7 @@ displayFinalMessage() { # If the user wants to install the dashboard, if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then # Store a message in a variable and display it - additional="View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin - -Your Admin Webpage login password is ${pwstring}" + additional="View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin\\n\\nYour Admin Webpage login password is ${pwstring}" fi # Final completion message to user @@ -2113,8 +2111,7 @@ Your Admin Webpage login password is ${pwstring}" \\n\\nIPv4: ${IPV4_ADDRESS%/*}\ \\nIPv6: ${IPV6_ADDRESS:-"Not Configured"}\ \\nIf you have not done so already, the above IP should be set to static.\ -\\n${additional}" - "${r}" "${c}" +\\n${additional}" "${r}" "${c}" } update_dialogs() { From 46f991f578ade00749ed0acd76a62f50fb0f588b Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Tue, 5 Jul 2022 20:11:00 -0700 Subject: [PATCH 10/11] Apply suggestions from code review Co-authored-by: yubiuser Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 18c4a068..47749c5f 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -1179,12 +1179,12 @@ setLogging() { case ${result} in "${DIALOG_OK}") # If they chose yes, - printf " %b Query Logging on.\\n" "${INFO}" + printf " %b Query Logging on.\\n" "${INFO}" QUERY_LOGGING=true ;; "${DIALOG_CANCEL}") # If they chose no, - printf " %b Query Logging off.\\n" "${INFO}" + printf " %b Query Logging off.\\n" "${INFO}" QUERY_LOGGING=false ;; "${DIALOG_ESC}") @@ -1232,13 +1232,13 @@ setAdminFlag() { case ${result} in "${DIALOG_OK}") # If they chose yes, - printf " %b Installing Admin Web Interface\\n" "${INFO}" + printf " %b Installing Admin Web Interface\\n" "${INFO}" # Set the flag to install the web interface INSTALL_WEB_INTERFACE=true ;; "${DIALOG_CANCEL}") # If they chose no, - printf " %b Not installing Admin Web Interface\\n" "${INFO}" + printf " %b Not installing Admin Web Interface\\n" "${INFO}" # Set the flag to not install the web interface INSTALL_WEB_INTERFACE=false INSTALL_WEB_SERVER=false @@ -1269,13 +1269,13 @@ the \"pihole\" group for full functionality." \ case ${result} in "${DIALOG_OK}") # If they chose yes, - printf " %b Installing lighttpd\\n" "${INFO}" + printf " %b Installing lighttpd\\n" "${INFO}" # Set the flag to install the web server INSTALL_WEB_SERVER=true ;; "${DIALOG_CANCEL}") # If they chose no, - printf " %b Not installing lighttpd\\n" "${INFO}" + printf " %b Not installing lighttpd\\n" "${INFO}" # Set the flag to not install the web server INSTALL_WEB_SERVER=false ;; @@ -1307,12 +1307,12 @@ chooseBlocklists() { case ${result} in "${DIALOG_OK}") # If they chose yes, - printf " %b Installing StevenBlack's Unified Hosts List\\n" "${INFO}" + printf " %b Installing StevenBlack's Unified Hosts List\\n" "${INFO}" echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >> "${adlistFile}" ;; "${DIALOG_CANCEL}") # If they chose no, - printf " %b Not installing StevenBlack's Unified Hosts List\\n" "${INFO}" + printf " %b Not installing StevenBlack's Unified Hosts List\\n" "${INFO}" ;; "${DIALOG_ESC}") # User pressed From cfbc731eab83f8ad351f644b07902f00d33c712f Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Tue, 5 Jul 2022 20:25:27 -0700 Subject: [PATCH 11/11] Apply suggestions from code review Co-authored-by: yubiuser Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 47749c5f..3e18f8de 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -1136,7 +1136,7 @@ If you want to specify a port other than 53, separate it with a hash.\ DNSSettingsCorrect=False ;; "${DIALOG_ESC}") - printf " %bEscape pressed, exiting installer at DNS Settings%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b Escape pressed, exiting installer at DNS Settings%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" exit 1 ;; esac @@ -1189,7 +1189,7 @@ setLogging() { ;; "${DIALOG_ESC}") # User pressed - printf " %bEscape pressed, exiting installer at Query Logging choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b Escape pressed, exiting installer at Query Logging choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" exit 1 ;; esac @@ -1245,7 +1245,7 @@ setAdminFlag() { ;; "${DIALOG_ESC}") # User pressed - printf " %bEscape pressed, exiting installer at Admin Web Interface choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b Escape pressed, exiting installer at Admin Web Interface choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" exit 1 ;; esac @@ -1281,7 +1281,7 @@ the \"pihole\" group for full functionality." \ ;; "${DIALOG_ESC}") # User pressed - printf " %bEscape pressed, exiting installer at web server choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b Escape pressed, exiting installer at web server choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" exit 1 ;; esac @@ -1316,7 +1316,7 @@ chooseBlocklists() { ;; "${DIALOG_ESC}") # User pressed - printf " %bEscape pressed, exiting installer at blocklist choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b Escape pressed, exiting installer at blocklist choice.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" exit 1 ;; esac