Merge pull request #2743 from haguenau/fix/shellcheck-install-script

Clean up basic install script
This commit is contained in:
Mark Drobnak 2019-05-16 23:22:01 -04:00 committed by GitHub
commit c8d32e0dd3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -118,7 +118,7 @@ done
# If the color table file exists, # If the color table file exists,
if [[ -f "${coltable}" ]]; then if [[ -f "${coltable}" ]]; then
# source it # source it
source ${coltable} source "${coltable}"
# Otherwise, # Otherwise,
else else
# Set these values so the installer can still run in color # Set these values so the installer can still run in color
@ -182,14 +182,14 @@ if is_command apt-get ; then
# A variable to store the command used to update the package cache # A variable to store the command used to update the package cache
UPDATE_PKG_CACHE="${PKG_MANAGER} update" UPDATE_PKG_CACHE="${PKG_MANAGER} update"
# An array for something... # An array for something...
PKG_INSTALL=(${PKG_MANAGER} --yes --no-install-recommends install) PKG_INSTALL=("${PKG_MANAGER}" --yes --no-install-recommends install)
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE # grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true" PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
# Some distros vary slightly so these fixes for dependencies may apply # Some distros vary slightly so these fixes for dependencies may apply
# on Ubuntu 18.04.1 LTS we need to add the universe repository to gain access to dialog and dhcpcd5 # on Ubuntu 18.04.1 LTS we need to add the universe repository to gain access to dialog and dhcpcd5
APT_SOURCES="/etc/apt/sources.list" APT_SOURCES="/etc/apt/sources.list"
if awk 'BEGIN{a=1;b=0}/bionic main/{a=0}/bionic.*universe/{b=1}END{exit a + b}' ${APT_SOURCES}; then if awk 'BEGIN{a=1;b=0}/bionic main/{a=0}/bionic.*universe/{b=1}END{exit a + b}' ${APT_SOURCES}; then
if ! whiptail --defaultno --title "Dependencies Require Update to Allowed Repositories" --yesno "Would you like to enable 'universe' repository?\\n\\nThis repository is required by the following packages:\\n\\n- dhcpcd5\\n- dialog" ${r} ${c}; then if ! whiptail --defaultno --title "Dependencies Require Update to Allowed Repositories" --yesno "Would you like to enable 'universe' repository?\\n\\nThis repository is required by the following packages:\\n\\n- dhcpcd5\\n- dialog" "${r}" "${c}"; then
printf " %b Aborting installation: dependencies could not be installed.\\n" "${CROSS}" printf " %b Aborting installation: dependencies could not be installed.\\n" "${CROSS}"
exit # exit the installer exit # exit the installer
else else
@ -201,7 +201,7 @@ if is_command apt-get ; then
fi fi
fi fi
# Debian 7 doesn't have iproute2 so if the dry run install is successful, # Debian 7 doesn't have iproute2 so if the dry run install is successful,
if ${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1; then if "${PKG_MANAGER}" install --dry-run iproute2 > /dev/null 2>&1; then
# we can install it # we can install it
iproute_pkg="iproute2" iproute_pkg="iproute2"
# Otherwise, # Otherwise,
@ -222,7 +222,7 @@ if is_command apt-get ; then
# Check if installed php is v 7.0, or newer to determine packages to install # Check if installed php is v 7.0, or newer to determine packages to install
if [[ "$phpInsNewer" != true ]]; then if [[ "$phpInsNewer" != true ]]; then
# Prefer the php metapackage if it's there # Prefer the php metapackage if it's there
if ${PKG_MANAGER} install --dry-run php > /dev/null 2>&1; then if "${PKG_MANAGER}" install --dry-run php > /dev/null 2>&1; then
phpVer="php" phpVer="php"
# fall back on the php5 packages # fall back on the php5 packages
else else
@ -233,19 +233,19 @@ if is_command apt-get ; then
phpVer="php$phpInsMajor.$phpInsMinor" phpVer="php$phpInsMajor.$phpInsMinor"
fi fi
# We also need the correct version for `php-sqlite` (which differs across distros) # We also need the correct version for `php-sqlite` (which differs across distros)
if ${PKG_MANAGER} install --dry-run ${phpVer}-sqlite3 > /dev/null 2>&1; then if "${PKG_MANAGER}" install --dry-run "${phpVer}-sqlite3" > /dev/null 2>&1; then
phpSqlite="sqlite3" phpSqlite="sqlite3"
else else
phpSqlite="sqlite" phpSqlite="sqlite"
fi fi
# Since our install script is so large, we need several other programs to successfully get a machine provisioned # Since our install script is so large, we need several other programs to successfully get a machine provisioned
# These programs are stored in an array so they can be looped through later # These programs are stored in an array so they can be looped through later
INSTALLER_DEPS=(apt-utils dialog debconf dhcpcd5 git ${iproute_pkg} whiptail) INSTALLER_DEPS=(apt-utils dialog debconf dhcpcd5 git "${iproute_pkg}" whiptail)
# Pi-hole itself has several dependencies that also need to be installed # Pi-hole itself has several dependencies that also need to be installed
PIHOLE_DEPS=(cron curl dnsutils iputils-ping lsof netcat psmisc sudo unzip wget idn2 sqlite3 libcap2-bin dns-root-data resolvconf libcap2) PIHOLE_DEPS=(cron curl dnsutils iputils-ping lsof netcat psmisc sudo unzip wget idn2 sqlite3 libcap2-bin dns-root-data resolvconf libcap2)
# The Web dashboard has some that also need to be installed # The Web dashboard has some that also need to be installed
# It's useful to separate the two since our repos are also setup as "Core" code and "Web" code # It's useful to separate the two since our repos are also setup as "Core" code and "Web" code
PIHOLE_WEB_DEPS=(lighttpd ${phpVer}-common ${phpVer}-cgi ${phpVer}-${phpSqlite}) PIHOLE_WEB_DEPS=(lighttpd "${phpVer}-common" "${phpVer}-cgi" "${phpVer}-${phpSqlite}")
# The Web server user, # The Web server user,
LIGHTTPD_USER="www-data" LIGHTTPD_USER="www-data"
# group, # group,
@ -281,7 +281,7 @@ elif is_command rpm ; then
# Fedora and family update cache on every PKG_INSTALL call, no need for a separate update. # Fedora and family update cache on every PKG_INSTALL call, no need for a separate update.
UPDATE_PKG_CACHE=":" UPDATE_PKG_CACHE=":"
PKG_INSTALL=(${PKG_MANAGER} install -y) PKG_INSTALL=("${PKG_MANAGER}" install -y)
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l" PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(dialog git iproute newt procps-ng which) INSTALLER_DEPS=(dialog git iproute newt procps-ng which)
PIHOLE_DEPS=(bind-utils cronie curl findutils nmap-ncat sudo unzip wget libidn2 psmisc sqlite libcap) PIHOLE_DEPS=(bind-utils cronie curl findutils nmap-ncat sudo unzip wget libidn2 psmisc sqlite libcap)
@ -319,7 +319,7 @@ elif is_command rpm ; then
# The default php on CentOS 7.x is 5.4 which is EOL # 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 # Check if the version of PHP available via installed repositories is >= to PHP 7
AVAILABLE_PHP_VERSION=$(${PKG_MANAGER} info php | grep -i version | grep -o '[0-9]\+' | head -1) AVAILABLE_PHP_VERSION=$("${PKG_MANAGER}" info php | grep -i version | grep -o '[0-9]\+' | head -1)
if [[ $AVAILABLE_PHP_VERSION -ge $SUPPORTED_CENTOS_PHP_VERSION ]]; then if [[ $AVAILABLE_PHP_VERSION -ge $SUPPORTED_CENTOS_PHP_VERSION ]]; then
# Since PHP 7 is available by default, install via default PHP package names # Since PHP 7 is available by default, install via default PHP package names
: # do nothing as PHP is current : # do nothing as PHP is current
@ -329,7 +329,7 @@ elif is_command rpm ; then
rpm -q ${REMI_PKG} &> /dev/null || rc=$? rpm -q ${REMI_PKG} &> /dev/null || rc=$?
if [[ $rc -ne 0 ]]; then if [[ $rc -ne 0 ]]; then
# The PHP version available via default repositories is older than version 7 # 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 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 # 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}" printf " %b User opt-out of PHP 7 upgrade on CentOS. Deprecated PHP may be in use.\\n" "${INFO}"
: # continue with unsupported php version : # continue with unsupported php version
@ -352,7 +352,7 @@ elif is_command rpm ; then
fi fi
else else
# Warn user of unsupported version of Fedora or CentOS # 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 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}" printf " %b Aborting installation due to unsupported RPM based distribution\\n" "${CROSS}"
exit # exit the installer exit # exit the installer
else else
@ -543,15 +543,15 @@ get_available_interfaces() {
# A function for displaying the dialogs the user sees when first running the installer # A function for displaying the dialogs the user sees when first running the installer
welcomeDialogs() { welcomeDialogs() {
# Display the welcome dialog using an appropriately sized window via the calculation conducted earlier in the script # 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} whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\\n\\nThis installer will transform your device into a network-wide ad blocker!" "${r}" "${c}"
# Request that users donate if they enjoy the software since we all work on it in our free time # 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: http://pi-hole.net/donate" ${r} ${c} whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\\n\\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" "${r}" "${c}"
# Explain the need for a static address # Explain the need for a static address
whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly. whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c} In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." "${r}" "${c}"
} }
# We need to make sure there is enough space before installing, so there is a function to check this # We need to make sure there is enough space before installing, so there is a function to check this
@ -638,7 +638,7 @@ chooseInterface() {
# Feed the available interfaces into this while loop # Feed the available interfaces into this while loop
done <<< "${availableInterfaces}" done <<< "${availableInterfaces}"
# The whiptail command that will be run, stored in a variable # The whiptail command that will be run, stored in a variable
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount}) chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" "${r}" "${c}" "${interfaceCount}")
# Now run the command using the interfaces saved into the array # Now run the command using the interfaces saved into the array
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) || \ chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) || \
# If the user chooses Cancel, exit # If the user chooses Cancel, exit
@ -719,7 +719,7 @@ useIPv6dialog() {
# If the IPV6_ADDRESS contains a value # If the IPV6_ADDRESS contains a value
if [[ ! -z "${IPV6_ADDRESS}" ]]; then if [[ ! -z "${IPV6_ADDRESS}" ]]; then
# Display that IPv6 is supported and will be used # Display that IPv6 is supported and will be used
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c} whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." "${r}" "${c}"
fi fi
} }
@ -729,7 +729,7 @@ use4andor6() {
local useIPv4 local useIPv4
local useIPv6 local useIPv6
# Let use select IPv4 and/or IPv6 via a checklist # Let use select IPv4 and/or IPv6 via a checklist
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2) cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" "${r}" "${c}" 2)
# In an array, show the options available: # In an array, show the options available:
# IPv4 (on by default) # IPv4 (on by default)
options=(IPv4 "Block ads over IPv4" on options=(IPv4 "Block ads over IPv4" on
@ -778,11 +778,11 @@ getStaticIPv4Settings() {
# This is useful for users that are using DHCP reservations; then we can just use the information gathered via our functions # This is useful for users that are using DHCP reservations; then we can just use the information gathered via our functions
if whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address? if whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: ${IPV4_ADDRESS} IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}; then Gateway: ${IPv4gw}" "${r}" "${c}"; then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. # 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. 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. 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} 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 # Nothing else to do since the variables are already set above
else else
# Otherwise, we need to ask the user to input their desired settings. # Otherwise, we need to ask the user to input their desired settings.
@ -791,13 +791,13 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
until [[ "${ipSettingsCorrect}" = True ]]; do until [[ "${ipSettingsCorrect}" = True ]]; do
# Ask for the IPv4 address # 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) || \ 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) || \
# Cancelling IPv4 settings window # Cancelling IPv4 settings window
{ ipSettingsCorrect=False; echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; } { 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}" printf " %b Your static IPv4 address: %s\\n" "${INFO}" "${IPV4_ADDRESS}"
# Ask for the gateway # 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) || \ 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) || \
# Cancelling gateway settings window # Cancelling gateway settings window
{ ipSettingsCorrect=False; echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; } { 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}" printf " %b Your static IPv4 gateway: %s\\n" "${INFO}" "${IPv4gw}"
@ -805,7 +805,7 @@ 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 # 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? if whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: ${IPV4_ADDRESS} IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}; then Gateway: ${IPv4gw}" "${r}" "${c}"; then
# After that's done, the loop ends and we move on # After that's done, the loop ends and we move on
ipSettingsCorrect=True ipSettingsCorrect=True
else else
@ -933,7 +933,7 @@ valid_ip() {
# and set the new one to a dot (period) # and set the new one to a dot (period)
IFS='.' IFS='.'
# Put the IP into an array # Put the IP into an array
ip=(${ip}) ip=("${ip}")
# Restore the IFS to what it was # Restore the IFS to what it was
IFS=${OIFS} IFS=${OIFS}
## Evaluate each octet by checking if it's less than or equal to 255 (the max for each octet) ## Evaluate each octet by checking if it's less than or equal to 255 (the max for each octet)
@ -943,7 +943,7 @@ valid_ip() {
stat=$? stat=$?
fi fi
# Return the exit code # Return the exit code
return ${stat} return "${stat}"
} }
# A function to choose the upstream DNS provider(s) # A function to choose the upstream DNS provider(s)
@ -973,7 +973,7 @@ setDNS() {
# Restore the IFS to what it was # Restore the IFS to what it was
IFS=${OIFS} IFS=${OIFS}
# In a whiptail dialog, show the options # 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 \ DNSchoices=$(whiptail --separate-output --menu "Select Upstream DNS Provider. To use your own, select Custom." "${r}" "${c}" 7 \
"${DNSChooseOptions[@]}" 2>&1 >/dev/tty) || \ "${DNSChooseOptions[@]}" 2>&1 >/dev/tty) || \
# exit if Cancel is selected # exit if Cancel is selected
{ printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; }
@ -1003,7 +1003,7 @@ setDNS() {
fi fi
# Dialog for the user to enter custom upstream servers # Dialog for 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.\\n\\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3) || \ piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), separated by a comma.\\n\\nFor example '8.8.8.8, 8.8.4.4'" "${r}" "${c}" "${prePopulate}" 3>&1 1>&2 2>&3) || \
{ printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; }
# Clean user input and replace whitespace with comma. # Clean user input and replace whitespace with comma.
piholeDNS=$(sed 's/[, \t]\+/,/g' <<< "${piholeDNS}") piholeDNS=$(sed 's/[, \t]\+/,/g' <<< "${piholeDNS}")
@ -1036,7 +1036,7 @@ setDNS() {
# Otherwise, # Otherwise,
else else
# Show the settings # Show the settings
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 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
# and break from the loop since the servers are valid # and break from the loop since the servers are valid
DNSSettingsCorrect=True DNSSettingsCorrect=True
# Otherwise, # Otherwise,
@ -1127,7 +1127,7 @@ setAdminFlag() {
local WebChoices local WebChoices
# Similar to the logging function, ask what the user wants # 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) WebToggleCommand=(whiptail --separate-output --radiolist "Do you wish to install the web admin interface?" "${r}" "${c}" 6)
# with the default being enabled # with the default being enabled
WebChooseOptions=("On (Recommended)" "" on WebChooseOptions=("On (Recommended)" "" on
Off "" off) Off "" off)
@ -1248,11 +1248,11 @@ version_check_dnsmasq() {
printf " it is from a previous Pi-hole install.\\n" printf " it is from a previous Pi-hole install.\\n"
printf " %b Backing up dnsmasq.conf to dnsmasq.conf.orig..." "${INFO}" printf " %b Backing up dnsmasq.conf to dnsmasq.conf.orig..." "${INFO}"
# so backup the original file # so backup the original file
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig} mv -f "${dnsmasq_conf}" "${dnsmasq_conf_orig}"
printf "%b %b Backing up dnsmasq.conf to dnsmasq.conf.orig...\\n" "${OVER}" "${TICK}" printf "%b %b Backing up dnsmasq.conf to dnsmasq.conf.orig...\\n" "${OVER}" "${TICK}"
printf " %b Restoring default dnsmasq.conf..." "${INFO}" printf " %b Restoring default dnsmasq.conf..." "${INFO}"
# and replace it with the default # and replace it with the default
install -D -m 644 -T ${dnsmasq_original_config} ${dnsmasq_conf} install -D -m 644 -T "${dnsmasq_original_config}" "${dnsmasq_conf}"
printf "%b %b Restoring default dnsmasq.conf...\\n" "${OVER}" "${TICK}" printf "%b %b Restoring default dnsmasq.conf...\\n" "${OVER}" "${TICK}"
# Otherwise, # Otherwise,
else else
@ -1263,7 +1263,7 @@ version_check_dnsmasq() {
# If a file cannot be found, # If a file cannot be found,
printf " %b No dnsmasq.conf found... restoring default dnsmasq.conf..." "${INFO}" printf " %b No dnsmasq.conf found... restoring default dnsmasq.conf..." "${INFO}"
# restore the default one # restore the default one
install -D -m 644 -T ${dnsmasq_original_config} ${dnsmasq_conf} install -D -m 644 -T "${dnsmasq_original_config}" "${dnsmasq_conf}"
printf "%b %b No dnsmasq.conf found... restoring default dnsmasq.conf...\\n" "${OVER}" "${TICK}" printf "%b %b No dnsmasq.conf found... restoring default dnsmasq.conf...\\n" "${OVER}" "${TICK}"
fi fi
@ -1273,37 +1273,37 @@ version_check_dnsmasq() {
install -d -m 755 "/etc/dnsmasq.d" install -d -m 755 "/etc/dnsmasq.d"
fi fi
# Copy the new Pi-hole DNS config file into the dnsmasq.d directory # Copy the new Pi-hole DNS config file into the dnsmasq.d directory
install -D -m 644 -T ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location} install -D -m 644 -T "${dnsmasq_pihole_01_snippet}" "${dnsmasq_pihole_01_location}"
printf "%b %b Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf\\n" "${OVER}" "${TICK}" printf "%b %b Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf\\n" "${OVER}" "${TICK}"
# Replace our placeholder values with the GLOBAL DNS variables that we populated earlier # Replace our placeholder values with the GLOBAL DNS variables that we populated earlier
# First, swap in the interface to listen on # First, swap in the interface to listen on
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location} sed -i "s/@INT@/$PIHOLE_INTERFACE/" "${dnsmasq_pihole_01_location}"
if [[ "${PIHOLE_DNS_1}" != "" ]]; then if [[ "${PIHOLE_DNS_1}" != "" ]]; then
# Then swap in the primary DNS server # Then swap in the primary DNS server
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location} sed -i "s/@DNS1@/$PIHOLE_DNS_1/" "${dnsmasq_pihole_01_location}"
else else
# #
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location} sed -i '/^server=@DNS1@/d' "${dnsmasq_pihole_01_location}"
fi fi
if [[ "${PIHOLE_DNS_2}" != "" ]]; then if [[ "${PIHOLE_DNS_2}" != "" ]]; then
# Then swap in the primary DNS server # Then swap in the primary DNS server
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location} sed -i "s/@DNS2@/$PIHOLE_DNS_2/" "${dnsmasq_pihole_01_location}"
else else
# #
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location} sed -i '/^server=@DNS2@/d' "${dnsmasq_pihole_01_location}"
fi fi
# #
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf} sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' "${dnsmasq_conf}"
# If the user does not want to enable logging, # If the user does not want to enable logging,
if [[ "${QUERY_LOGGING}" == false ]] ; then if [[ "${QUERY_LOGGING}" == false ]] ; then
# Disable it by commenting out the directive in the DNS config file # Disable it by commenting out the directive in the DNS config file
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location} sed -i 's/^log-queries/#log-queries/' "${dnsmasq_pihole_01_location}"
# Otherwise, # Otherwise,
else else
# enable it by uncommenting the directive in the DNS config file # enable it by uncommenting the directive in the DNS config file
sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location} sed -i 's/^#log-queries/log-queries/' "${dnsmasq_pihole_01_location}"
fi fi
} }
@ -1616,7 +1616,6 @@ install_dependent_packages() {
# Install packages passed in via argument array # Install packages passed in via argument array
# No spinner - conflicts with set -e # No spinner - conflicts with set -e
declare -a argArray1=("${!1}")
declare -a installArray declare -a installArray
# Debian based package install - debconf will download the entire package list # Debian based package install - debconf will download the entire package list
@ -1626,7 +1625,7 @@ install_dependent_packages() {
# installed by us, and remove only the installed packages, and not the entire list. # installed by us, and remove only the installed packages, and not the entire list.
if is_command debconf-apt-progress ; then if is_command debconf-apt-progress ; then
# For each package, # For each package,
for i in "${argArray1[@]}"; do for i in "$@"; do
printf " %b Checking for %s..." "${INFO}" "${i}" printf " %b Checking for %s..." "${INFO}" "${i}"
if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep "ok installed" &> /dev/null; then if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep "ok installed" &> /dev/null; then
printf "%b %b Checking for %s\\n" "${OVER}" "${TICK}" "${i}" printf "%b %b Checking for %s\\n" "${OVER}" "${TICK}" "${i}"
@ -1645,9 +1644,9 @@ install_dependent_packages() {
fi fi
# Install Fedora/CentOS packages # Install Fedora/CentOS packages
for i in "${argArray1[@]}"; do for i in "$@"; do
printf " %b Checking for %s..." "${INFO}" "${i}" printf " %b Checking for %s..." "${INFO}" "${i}"
if ${PKG_MANAGER} -q list installed "${i}" &> /dev/null; then if "${PKG_MANAGER}" -q list installed "${i}" &> /dev/null; then
printf "%b %b Checking for %s" "${OVER}" "${TICK}" "${i}" printf "%b %b Checking for %s" "${OVER}" "${TICK}" "${i}"
else else
printf "%b %b Checking for %s (will be installed)" "${OVER}" "${INFO}" "${i}" printf "%b %b Checking for %s (will be installed)" "${OVER}" "${INFO}" "${i}"
@ -1765,7 +1764,7 @@ configureFirewall() {
# If a firewall is running, # If a firewall is running,
if firewall-cmd --state &> /dev/null; then if firewall-cmd --state &> /dev/null; then
# ask if the user wants to install Pi-hole's default firewall rules # ask if the user wants to install Pi-hole's default firewall rules
whiptail --title "Firewall in use" --yesno "We have detected a running firewall\\n\\nPi-hole currently requires HTTP and DNS port access.\\n\\n\\n\\nInstall Pi-hole default firewall rules?" ${r} ${c} || \ whiptail --title "Firewall in use" --yesno "We have detected a running firewall\\n\\nPi-hole currently requires HTTP and DNS port access.\\n\\n\\n\\nInstall Pi-hole default firewall rules?" "${r}" "${c}" || \
{ printf " %b Not installing firewall rulesets.\\n" "${INFO}"; return 0; } { printf " %b Not installing firewall rulesets.\\n" "${INFO}"; return 0; }
printf " %b Configuring FirewallD for httpd and pihole-FTL\\n" "${TICK}" printf " %b Configuring FirewallD for httpd and pihole-FTL\\n" "${TICK}"
# Allow HTTP and DNS traffic # Allow HTTP and DNS traffic
@ -1778,7 +1777,7 @@ configureFirewall() {
# If chain Policy is not ACCEPT or last Rule is not ACCEPT # If chain Policy is not ACCEPT or last Rule is not ACCEPT
# then check and insert our Rules above the DROP/REJECT Rule. # then check and insert our Rules above the DROP/REJECT Rule.
if iptables -S INPUT | head -n1 | grep -qv '^-P.*ACCEPT$' || iptables -S INPUT | tail -n1 | grep -qv '^-\(A\|P\).*ACCEPT$'; then if iptables -S INPUT | head -n1 | grep -qv '^-P.*ACCEPT$' || iptables -S INPUT | tail -n1 | grep -qv '^-\(A\|P\).*ACCEPT$'; then
whiptail --title "Firewall in use" --yesno "We have detected a running firewall\\n\\nPi-hole currently requires HTTP and DNS port access.\\n\\n\\n\\nInstall Pi-hole default firewall rules?" ${r} ${c} || \ whiptail --title "Firewall in use" --yesno "We have detected a running firewall\\n\\nPi-hole currently requires HTTP and DNS port access.\\n\\n\\n\\nInstall Pi-hole default firewall rules?" "${r}" "${c}" || \
{ printf " %b Not installing firewall rulesets.\\n" "${INFO}"; return 0; } { printf " %b Not installing firewall rulesets.\\n" "${INFO}"; return 0; }
printf " %b Installing new IPTables firewall rulesets\\n" "${TICK}" printf " %b Installing new IPTables firewall rulesets\\n" "${TICK}"
# Check chain first, otherwise a new rule will duplicate old ones # Check chain first, otherwise a new rule will duplicate old ones
@ -1872,21 +1871,21 @@ installLogrotate() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break. # At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here. # Refactoring of install script has changed the name of a couple of variables. Sort them out here.
accountForRefactor() { accountForRefactor() {
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars} sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' "${setupVars}"
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars} sed -i 's/IPv4_address/IPV4_ADDRESS/g' "${setupVars}"
sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars} sed -i 's/IPv4addr/IPV4_ADDRESS/g' "${setupVars}"
sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars} sed -i 's/IPv6_address/IPV6_ADDRESS/g' "${setupVars}"
sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars} sed -i 's/piholeIPv6/IPV6_ADDRESS/g' "${setupVars}"
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars} sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' "${setupVars}"
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars} sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' "${setupVars}"
sed -i 's/^INSTALL_WEB=/INSTALL_WEB_INTERFACE=/' ${setupVars} sed -i 's/^INSTALL_WEB=/INSTALL_WEB_INTERFACE=/' "${setupVars}"
# Add 'INSTALL_WEB_SERVER', if its not been applied already: https://github.com/pi-hole/pi-hole/pull/2115 # Add 'INSTALL_WEB_SERVER', if its not been applied already: https://github.com/pi-hole/pi-hole/pull/2115
if ! grep -q '^INSTALL_WEB_SERVER=' ${setupVars}; then if ! grep -q '^INSTALL_WEB_SERVER=' ${setupVars}; then
local webserver_installed=false local webserver_installed=false
if grep -q '^INSTALL_WEB_INTERFACE=true' ${setupVars}; then if grep -q '^INSTALL_WEB_INTERFACE=true' ${setupVars}; then
webserver_installed=true webserver_installed=true
fi fi
echo -e "INSTALL_WEB_SERVER=$webserver_installed" >> ${setupVars} echo -e "INSTALL_WEB_SERVER=$webserver_installed" >> "${setupVars}"
fi fi
} }
@ -1968,7 +1967,7 @@ checkSelinux() {
# If it's enforcing, # If it's enforcing,
if [[ "${enforceMode}" == "Enforcing" ]]; then if [[ "${enforceMode}" == "Enforcing" ]]; then
# Explain Pi-hole does not support it yet # Explain Pi-hole does not support it yet
whiptail --defaultno --title "SELinux Enforcing Detected" --yesno "SELinux is being ENFORCED on your system! \\n\\nPi-hole currently does not support SELinux, but you may still continue with the installation.\\n\\nNote: Web Admin will not be fully functional unless you set your policies correctly\\n\\nContinue installing Pi-hole?" ${r} ${c} || \ whiptail --defaultno --title "SELinux Enforcing Detected" --yesno "SELinux is being ENFORCED on your system! \\n\\nPi-hole currently does not support SELinux, but you may still continue with the installation.\\n\\nNote: Web Admin will not be fully functional unless you set your policies correctly\\n\\nContinue installing Pi-hole?" "${r}" "${c}" || \
{ printf "\\n %bSELinux Enforcing detected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } { printf "\\n %bSELinux Enforcing detected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; }
printf " %b Continuing installation with SELinux Enforcing\\n" "${INFO}" printf " %b Continuing installation with SELinux Enforcing\\n" "${INFO}"
printf " %b Please refer to official SELinux documentation to create a custom policy\\n" "${INFO}" printf " %b Please refer to official SELinux documentation to create a custom policy\\n" "${INFO}"
@ -2007,7 +2006,7 @@ If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole. The install log is in /etc/pihole.
${additional}" ${r} ${c} ${additional}" "${r}" "${c}"
} }
update_dialogs() { update_dialogs() {
@ -2028,7 +2027,7 @@ update_dialogs() {
opt2b="This will reset your Pi-hole and allow you to enter new settings." opt2b="This will reset your Pi-hole and allow you to enter new settings."
# Display the information to the user # 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=$(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 \
"${opt1a}" "${opt1b}" \ "${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3) || \ "${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3) || \
{ printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; } { printf " %bCancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"; exit 1; }
@ -2525,7 +2524,7 @@ main() {
notify_package_updates_available notify_package_updates_available
# Install packages used by this installation script # Install packages used by this installation script
install_dependent_packages INSTALLER_DEPS[@] install_dependent_packages "${INSTALLER_DEPS[@]}"
# Check if SELinux is Enforcing # Check if SELinux is Enforcing
checkSelinux checkSelinux
@ -2556,7 +2555,7 @@ main() {
installDefaultBlocklists installDefaultBlocklists
# Source ${setupVars} to use predefined user variables in the functions # Source ${setupVars} to use predefined user variables in the functions
source ${setupVars} source "${setupVars}"
# Get the privacy level if it exists (default is 0) # Get the privacy level if it exists (default is 0)
if [[ -f "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then if [[ -f "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then
@ -2576,7 +2575,7 @@ main() {
dep_install_list+=("${PIHOLE_WEB_DEPS[@]}") dep_install_list+=("${PIHOLE_WEB_DEPS[@]}")
fi fi
install_dependent_packages dep_install_list[@] install_dependent_packages "${dep_install_list[@]}"
unset dep_install_list unset dep_install_list
# On some systems, lighttpd is not enabled on first install. We need to enable it here if the user # On some systems, lighttpd is not enabled on first install. We need to enable it here if the user
@ -2613,7 +2612,7 @@ main() {
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8) pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
# shellcheck disable=SC1091 # shellcheck disable=SC1091
. /opt/pihole/webpage.sh . /opt/pihole/webpage.sh
echo "WEBPASSWORD=$(HashPassword ${pw})" >> ${setupVars} echo "WEBPASSWORD=$(HashPassword "${pw}")" >> "${setupVars}"
fi fi
fi fi