From 6fc5bf83f49a637316e4c69a5d0947443426efb5 Mon Sep 17 00:00:00 2001 From: Michael Woolweaver Date: Wed, 9 Apr 2025 12:25:24 -0500 Subject: [PATCH 01/32] don't mute SC2086 Signed-off-by: Michael Woolweaver --- gravity.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/gravity.sh b/gravity.sh index 514289d0..8ccd9a5b 100755 --- a/gravity.sh +++ b/gravity.sh @@ -601,7 +601,7 @@ compareLists() { # Download specified URL and perform checks on HTTP status and file content gravity_DownloadBlocklistFromUrl() { local url="${1}" adlistID="${2}" saveLocation="${3}" target="${4}" compression="${5}" gravity_type="${6}" domain="${7}" - local modifiedOptions="" listCurlBuffer str httpCode success="" ip cmd_ext + local modifiedOptions=() listCurlBuffer str httpCode success="" ip cmd_ext local file_path permissions ip_addr port blocked=false download=true # Create temp file to store content on disk instead of RAM @@ -619,14 +619,14 @@ gravity_DownloadBlocklistFromUrl() { # Save HTTP ETag to the specified file. An ETag is a caching related header, # usually returned in a response. If no ETag is sent by the server, an empty # file is created and can later be used consistently. - modifiedOptions="--etag-save ${saveLocation}.etag" + modifiedOptions=("${modifiedOptions[@]}" --etag-save "${saveLocation}".etag) if [[ -f "${saveLocation}.etag" ]]; then # This option makes a conditional HTTP request for the specific ETag read # from the given file by sending a custom If-None-Match header using the # stored ETag. This way, the server will only send the file if it has # changed since the last request. - modifiedOptions="${modifiedOptions} --etag-compare ${saveLocation}.etag" + modifiedOptions=("${modifiedOptions[@]}" --etag-compare "${saveLocation}".etag) fi fi @@ -639,7 +639,7 @@ gravity_DownloadBlocklistFromUrl() { # Interstingly, this option is not supported by raw.githubusercontent.com # URLs, however, it is still supported by many older web servers which may # not support the HTTP ETag method so we keep it as a fallback. - modifiedOptions="${modifiedOptions} -z ${saveLocation}" + modifiedOptions=("${modifiedOptions[@]}" -z "${saveLocation}") fi fi @@ -743,9 +743,7 @@ gravity_DownloadBlocklistFromUrl() { fi if [[ "${download}" == true ]]; then - # See https://github.com/pi-hole/pi-hole/issues/6159 for justification of the below disable directive - # shellcheck disable=SC2086 - httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression} ${cmd_ext} ${modifiedOptions} -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2>/dev/null) + httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression} ${cmd_ext} "${modifiedOptions[@]}" -w "%{http_code}" ${url} -o ${listCurlBuffer} 2>/dev/null) fi case $url in From 89c4248315700004e249e119ebf851e7e464ee40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 22 Apr 2025 21:57:47 +0200 Subject: [PATCH 02/32] Use quotes for all substitutions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- gravity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gravity.sh b/gravity.sh index 8ccd9a5b..403b1bd7 100755 --- a/gravity.sh +++ b/gravity.sh @@ -743,7 +743,7 @@ gravity_DownloadBlocklistFromUrl() { fi if [[ "${download}" == true ]]; then - httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression} ${cmd_ext} "${modifiedOptions[@]}" -w "%{http_code}" ${url} -o ${listCurlBuffer} 2>/dev/null) + httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L "${compression}" "${cmd_ext}" "${modifiedOptions[@]}" -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2>/dev/null) fi case $url in From 774037834b769b9d37477424f5cbc810c7e6cc25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 22 Apr 2025 22:01:21 +0200 Subject: [PATCH 03/32] Rename cmd_ext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- gravity.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gravity.sh b/gravity.sh index 403b1bd7..384ee4ea 100755 --- a/gravity.sh +++ b/gravity.sh @@ -601,7 +601,7 @@ compareLists() { # Download specified URL and perform checks on HTTP status and file content gravity_DownloadBlocklistFromUrl() { local url="${1}" adlistID="${2}" saveLocation="${3}" target="${4}" compression="${5}" gravity_type="${6}" domain="${7}" - local modifiedOptions=() listCurlBuffer str httpCode success="" ip cmd_ext + local modifiedOptions=() listCurlBuffer str httpCode success="" ip customUpstreamResolver local file_path permissions ip_addr port blocked=false download=true # Create temp file to store content on disk instead of RAM @@ -705,7 +705,7 @@ gravity_DownloadBlocklistFromUrl() { fi echo -e "${OVER} ${CROSS} ${str} ${domain} is blocked by one of your lists. Using DNS server ${upstream} instead" echo -ne " ${INFO} ${str} Pending..." - cmd_ext="--resolve $domain:$port:$ip" + customUpstreamResolver="--resolve $domain:$port:$ip" fi fi @@ -743,7 +743,7 @@ gravity_DownloadBlocklistFromUrl() { fi if [[ "${download}" == true ]]; then - httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L "${compression}" "${cmd_ext}" "${modifiedOptions[@]}" -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2>/dev/null) + httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L "${compression}" "${customUpstreamResolver}" "${modifiedOptions[@]}" -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2>/dev/null) fi case $url in From 76e41aeefaacf54a7fc23a0581d5ab8293e77a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 22 Apr 2025 22:03:54 +0200 Subject: [PATCH 04/32] Add small note about modifiedOptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- gravity.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gravity.sh b/gravity.sh index 384ee4ea..d91d3166 100755 --- a/gravity.sh +++ b/gravity.sh @@ -601,8 +601,10 @@ compareLists() { # Download specified URL and perform checks on HTTP status and file content gravity_DownloadBlocklistFromUrl() { local url="${1}" adlistID="${2}" saveLocation="${3}" target="${4}" compression="${5}" gravity_type="${6}" domain="${7}" - local modifiedOptions=() listCurlBuffer str httpCode success="" ip customUpstreamResolver + local listCurlBuffer str httpCode success="" ip customUpstreamResolver local file_path permissions ip_addr port blocked=false download=true + # modifiedOptions is an array to store all the options used to check if the adlist has been changed upstream + local modifiedOptions=() # Create temp file to store content on disk instead of RAM # We don't use '--suffix' here because not all implementations of mktemp support it, e.g. on Alpine From 13d76abff7212965da856bfcf042675a9a0ee5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 22 Apr 2025 22:38:07 +0200 Subject: [PATCH 05/32] Set customUpstreamResolver empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- gravity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gravity.sh b/gravity.sh index d91d3166..4ce532fc 100755 --- a/gravity.sh +++ b/gravity.sh @@ -601,7 +601,7 @@ compareLists() { # Download specified URL and perform checks on HTTP status and file content gravity_DownloadBlocklistFromUrl() { local url="${1}" adlistID="${2}" saveLocation="${3}" target="${4}" compression="${5}" gravity_type="${6}" domain="${7}" - local listCurlBuffer str httpCode success="" ip customUpstreamResolver + local listCurlBuffer str httpCode success="" ip customUpstreamResolver="" local file_path permissions ip_addr port blocked=false download=true # modifiedOptions is an array to store all the options used to check if the adlist has been changed upstream local modifiedOptions=() From 7a641f4c35b29f82e7d706b14e9260734fd8d842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 22 Apr 2025 22:52:33 +0200 Subject: [PATCH 06/32] Use paramteter expansion to prevent adding literal '' if parameter is empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- gravity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gravity.sh b/gravity.sh index 4ce532fc..19458c16 100755 --- a/gravity.sh +++ b/gravity.sh @@ -745,7 +745,7 @@ gravity_DownloadBlocklistFromUrl() { fi if [[ "${download}" == true ]]; then - httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L "${compression}" "${customUpstreamResolver}" "${modifiedOptions[@]}" -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2>/dev/null) + httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression:+${compression}} ${customUpstreamResolver:+${customUpstreamResolver}} "${modifiedOptions[@]}" -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2>/dev/null) fi case $url in From a590b774314b37cde3a297e2bc7869534c169aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 5 Apr 2025 22:33:30 +0200 Subject: [PATCH 07/32] Link to documentation on how to add local user to pihole group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- automated install/basic-install.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 9e0246f0..b1956449 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -2481,6 +2481,8 @@ main() { printf " %b View the web interface at http://pi.hole:${WEBPORT}/admin or http://%s/admin\\n\\n" "${INFO}" "${IPV4_ADDRESS%/*}:${WEBPORT}" printf " %b Web Interface password: %b%s%b\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${pw}" "${COL_NC}" printf " %b This can be changed using 'pihole setpassword'\\n\\n" "${INFO}" + printf " %b To allow your user to use all CLI functions without authentication, refer to\\n" "${INFO}" + printf " our documentation at: https://docs.pi-hole.net/main/post-install/\\n\\n" # Final dialog message to the user dialog --no-shadow --keep-tite \ @@ -2489,7 +2491,11 @@ main() { \\n\\nIPv4: ${IPV4_ADDRESS%/*}\ \\nIPv6: ${IPV6_ADDRESS:-"Not Configured"}\ \\nIf you have not done so already, the above IP should be set to static.\ -\\nView the web interface at http://pi.hole/admin:${WEBPORT} or http://${IPV4_ADDRESS%/*}:${WEBPORT}/admin\\n\\nYour Admin Webpage login password is ${pw}" "${r}" "${c}" +\\nView the web interface at http://pi.hole/admin:${WEBPORT} or http://${IPV4_ADDRESS%/*}:${WEBPORT}/admin\\n\\nYour Admin Webpage login password is ${pw}\ +\\n +\\n +\\nTo allow your user to use all CLI functions without authentication,\ +\\nrefer to https://docs.pi-hole.net/main/post-install/" "${r}" "${c}" INSTALL_TYPE="Installation" else From 6130b800e3e02ba3f8a4c7997fc67861f0efdb6e Mon Sep 17 00:00:00 2001 From: deHakkelaar Date: Mon, 2 Jun 2025 03:59:36 +0200 Subject: [PATCH 08/32] basic-install.sh listing interfaces Following up on below one: https://github.com/pi-hole/pi-hole/pull/6236 And below poor attempt: https://github.com/pi-hole/pi-hole/pull/6256 Signed-off-by: deHakkelaar --- automated install/basic-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 279dc1d1..dfecda9c 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -577,7 +577,7 @@ Do you wish to continue with an IPv6-only installation?\\n\\n" \ # Get available interfaces that are UP get_available_interfaces() { # There may be more than one so it's all stored in a variable - availableInterfaces=$(ip --oneline link show up | awk '{print $2}' | grep -v "^lo" | cut -d':' -f1 | cut -d'@' -f1) + availableInterfaces=$(ip --oneline link show up | awk -F ': |@' '!/<.*LOOPBACK.*>/ {print $2}') } # A function for displaying the dialogs the user sees when first running the installer From ea61755881b9c3b4c7776ab265079f3695c9cd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 5 Jun 2025 12:50:10 +0200 Subject: [PATCH 09/32] Only update the package cache on fresh installations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/update.sh | 1 + automated install/basic-install.sh | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index 51c1b1a1..d9412f8a 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -114,6 +114,7 @@ main() { # Install packages used by this installation script (necessary if users have removed e.g. git from their systems) + check_fresh_install package_manager_detect build_dependency_package install_dependent_packages diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 279dc1d1..cbad9eac 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -231,6 +231,13 @@ is_command() { command -v "${check_command}" >/dev/null 2>&1 } +check_fresh_install() { + # in case of an update (can be a v5 -> v6 or v6 -> v6 update) or repair + if [[ -f "${PI_HOLE_V6_CONFIG}" ]] || [[ -f "/etc/pihole/setupVars.conf" ]]; then + fresh_install=false + fi +} + # Compatibility package_manager_detect() { @@ -247,8 +254,10 @@ package_manager_detect() { PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true" # The command we will use to remove packages (used in the uninstaller) PKG_REMOVE="${PKG_MANAGER} -y remove --purge" - # Update package cache - update_package_cache || exit 1 + # Update package cache only on fresh installs + if [[ "${fresh_install}" == true ]]; then + update_package_cache || exit 1 + fi # If apt-get is not found, check for rpm. elif is_command rpm; then @@ -2193,6 +2202,9 @@ main() { # Check for availability of either the "service" or "systemctl" commands check_service_command + # Check if this is a fresh install or an update/repair + check_fresh_install + # Check for supported package managers so that we may install dependencies package_manager_detect @@ -2216,10 +2228,7 @@ main() { exit 1 fi - # in case of an update (can be a v5 -> v6 or v6 -> v6 update) or repair - if [[ -f "${PI_HOLE_V6_CONFIG}" ]] || [[ -f "/etc/pihole/setupVars.conf" ]]; then - # retain settings - fresh_install=false + if [[ "${fresh_install}" == false ]]; then # if it's running unattended, if [[ "${runUnattended}" == true ]]; then printf " %b Performing unattended setup, no dialogs will be displayed\\n" "${INFO}" From 93ecfb9504c7f353ebf8dd83b23a8c89c9bbdc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 5 Jun 2025 13:09:03 +0200 Subject: [PATCH 10/32] We test a fresh installaton, so don't pretend this is not a fresh installation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- test/test_any_automated_install.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_any_automated_install.py b/test/test_any_automated_install.py index 0fa0453a..eb1f72e4 100644 --- a/test/test_any_automated_install.py +++ b/test/test_any_automated_install.py @@ -89,10 +89,8 @@ def test_installPihole_fresh_install_readableFiles(host): export DEBIAN_FRONTEND=noninteractive umask 0027 runUnattended=true - fresh_install=false source /opt/pihole/basic-install.sh > /dev/null runUnattended=true - fresh_install=false main /opt/pihole/pihole-FTL-prestart.sh """ From 5ff4f000d5e8e9c853bd18b96ae1237868243978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 5 Jun 2025 14:16:27 +0200 Subject: [PATCH 11/32] Add 'never-stale' to the exempt issue labels of the stale workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index a0dd9a31..34ffb64e 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -24,7 +24,7 @@ jobs: days-before-close: 5 stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Please comment or update this issue or it will be closed in 5 days.' stale-issue-label: '${{ env.stale_label }}' - exempt-issue-labels: 'Internal, Fixed in next release, Bug: Confirmed, Documentation Needed' + exempt-issue-labels: 'Internal, Fixed in next release, Bug: Confirmed, Documentation Needed, never-stale' exempt-all-issue-assignees: true operations-per-run: 300 close-issue-reason: 'not_planned' From d16c049768463a978137340812d782a0120acb43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 5 Jun 2025 14:43:38 +0200 Subject: [PATCH 12/32] Set PI_HOLE_SCRIPT_DIR in api.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/api.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/advanced/Scripts/api.sh b/advanced/Scripts/api.sh index 613a8d86..e5eacd41 100755 --- a/advanced/Scripts/api.sh +++ b/advanced/Scripts/api.sh @@ -22,7 +22,8 @@ TestAPIAvailability() { local chaos_api_list authResponse authStatus authData apiAvailable DNSport # as we are running locally, we can get the port value from FTL directly - readonly utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh" + PI_HOLE_SCRIPT_DIR="/opt/pihole" + utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh" # shellcheck source=./advanced/Scripts/utils.sh . "${utilsfile}" From 3933cb0575f1004ed585bcf090e4c2f52dc78936 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 7 Jun 2025 10:01:39 +0000 Subject: [PATCH 13/32] Bump pytest from 8.3.5 to 8.4.0 in /test Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.5 to 8.4.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.5...8.4.0) --- updated-dependencies: - dependency-name: pytest dependency-version: 8.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- test/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements.txt b/test/requirements.txt index b273c351..8e45a6d0 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,5 +1,5 @@ pyyaml == 6.0.2 -pytest == 8.3.5 +pytest == 8.4.0 pytest-xdist == 3.6.1 pytest-testinfra == 10.2.2 tox == 4.26.0 From 2c1032090d7afff4effe1661981ba8947250c890 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 7 Jun 2025 10:07:56 +0000 Subject: [PATCH 14/32] Bump pytest-xdist from 3.6.1 to 3.7.0 in /test Bumps [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) from 3.6.1 to 3.7.0. - [Release notes](https://github.com/pytest-dev/pytest-xdist/releases) - [Changelog](https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-xdist/compare/v3.6.1...v3.7.0) --- updated-dependencies: - dependency-name: pytest-xdist dependency-version: 3.7.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- test/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements.txt b/test/requirements.txt index 8e45a6d0..d2e4344a 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,6 +1,6 @@ pyyaml == 6.0.2 pytest == 8.4.0 -pytest-xdist == 3.6.1 +pytest-xdist == 3.7.0 pytest-testinfra == 10.2.2 tox == 4.26.0 pytest-clarity == 1.0.1 From b39c9956e844d82a17ac2ba51c421977d443901a Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Sat, 7 Jun 2025 18:27:46 +0300 Subject: [PATCH 15/32] Dependabot: group updates Signed-off-by: XhmikosR --- .github/dependabot.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index af9b74db..4ecfe617 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,6 +8,11 @@ updates: time: "10:00" open-pull-requests-limit: 10 target-branch: development + versioning-strategy: increase + groups: + github-actions: + patterns: + - "*" - package-ecosystem: pip directory: "/test" schedule: @@ -16,3 +21,8 @@ updates: time: "10:00" open-pull-requests-limit: 10 target-branch: development + versioning-strategy: increase + groups: + github-actions: + patterns: + - "*" From 5777497f52c3c87da870e9282bf21e30ffcf5133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sun, 8 Jun 2025 21:25:43 +0200 Subject: [PATCH 16/32] Separate package manager detection and cache update functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/update.sh | 1 - automated install/basic-install.sh | 9 +++++---- test/test_any_automated_install.py | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index d9412f8a..51c1b1a1 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -114,7 +114,6 @@ main() { # Install packages used by this installation script (necessary if users have removed e.g. git from their systems) - check_fresh_install package_manager_detect build_dependency_package install_dependent_packages diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index cbad9eac..99b11d5c 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -254,10 +254,6 @@ package_manager_detect() { PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true" # The command we will use to remove packages (used in the uninstaller) PKG_REMOVE="${PKG_MANAGER} -y remove --purge" - # Update package cache only on fresh installs - if [[ "${fresh_install}" == true ]]; then - update_package_cache || exit 1 - fi # If apt-get is not found, check for rpm. elif is_command rpm; then @@ -2208,6 +2204,11 @@ main() { # Check for supported package managers so that we may install dependencies package_manager_detect + # Update package cache only on fresh installs and apt based systems + if [[ "${fresh_install}" == true ]] && is_command apt-get; then + update_package_cache || exit 1 + fi + # Notify user of package availability notify_package_updates_available diff --git a/test/test_any_automated_install.py b/test/test_any_automated_install.py index eb1f72e4..cf4b454d 100644 --- a/test/test_any_automated_install.py +++ b/test/test_any_automated_install.py @@ -471,6 +471,7 @@ def test_package_manager_has_pihole_deps(host): """ source /opt/pihole/basic-install.sh package_manager_detect + update_package_cache build_dependency_package install_dependent_packages """ @@ -487,6 +488,7 @@ def test_meta_package_uninstall(host): """ source /opt/pihole/basic-install.sh package_manager_detect + update_package_cache build_dependency_package install_dependent_packages """ From 7a16024020d975b3e0490621e4cc6832b4151111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sun, 8 Jun 2025 21:31:56 +0200 Subject: [PATCH 17/32] Run package update everytime before building the meta package when invoking from the install script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- automated install/basic-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 99b11d5c..c18e6c0d 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -2204,8 +2204,8 @@ main() { # Check for supported package managers so that we may install dependencies package_manager_detect - # Update package cache only on fresh installs and apt based systems - if [[ "${fresh_install}" == true ]] && is_command apt-get; then + # Update package cache only on apt based systems + if is_command apt-get; then update_package_cache || exit 1 fi From c19e907c0c5c26604b30dbd7d56752e26a407476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 9 Jun 2025 19:06:15 +0200 Subject: [PATCH 18/32] Fix dependabot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- .github/dependabot.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4ecfe617..7a5d2064 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,9 +8,8 @@ updates: time: "10:00" open-pull-requests-limit: 10 target-branch: development - versioning-strategy: increase groups: - github-actions: + github-actions-dependencies: patterns: - "*" - package-ecosystem: pip @@ -21,8 +20,7 @@ updates: time: "10:00" open-pull-requests-limit: 10 target-branch: development - versioning-strategy: increase groups: - github-actions: + python-dependencies: patterns: - "*" From 04d9d32444d57ee29388d21b63a276d88e1f31c1 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 17 Jun 2025 20:19:13 -0300 Subject: [PATCH 19/32] Remove test for port 4711 Signed-off-by: RD WebDesign --- advanced/Scripts/piholeDebug.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index 741ff2f4..2f82186f 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -388,14 +388,6 @@ check_firewalld() { else log_write "${CROSS} ${COL_RED} Local Interface Not Detected${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" fi - # check FTL custom zone port: 4711 - local firewalld_ftl_zone_ports - firewalld_ftl_zone_ports=$(firewall-cmd --zone=ftl --list-ports) - if [[ "${firewalld_ftl_zone_ports}" =~ "4711/tcp" ]]; then - log_write "${TICK} ${COL_GREEN} FTL Port 4711/tcp Detected${COL_NC}"; - else - log_write "${CROSS} ${COL_RED} FTL Port 4711/tcp Not Detected${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" - fi else log_write "${CROSS} ${COL_RED}FTL Custom Zone Not Detected${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" fi From 405053692a8ae62c18fde18baa7b19211cb86036 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 17 Jun 2025 21:32:49 -0300 Subject: [PATCH 20/32] Add HTTPS and NTP services to firewalld test Signed-off-by: RD WebDesign --- advanced/Scripts/piholeDebug.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index 2f82186f..7f12a2ab 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -367,7 +367,7 @@ check_firewalld() { # test common required service ports local firewalld_enabled_services firewalld_enabled_services=$(firewall-cmd --list-services) - local firewalld_expected_services=("http" "dns" "dhcp" "dhcpv6") + local firewalld_expected_services=("http" "https" "dns" "dhcp" "dhcpv6" "ntp") for i in "${firewalld_expected_services[@]}"; do if [[ "${firewalld_enabled_services}" =~ ${i} ]]; then log_write "${TICK} ${COL_GREEN} Allow Service: ${i}${COL_NC}"; From 700c892dff37b9dab8d20b9c4965367eed513285 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Jun 2025 10:10:43 +0000 Subject: [PATCH 21/32] Bump tox from 4.26.0 to 4.27.0 in /test Bumps [tox](https://github.com/tox-dev/tox) from 4.26.0 to 4.27.0. - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.26.0...4.27.0) --- updated-dependencies: - dependency-name: tox dependency-version: 4.27.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- test/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements.txt b/test/requirements.txt index d2e4344a..821e505e 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -2,5 +2,5 @@ pyyaml == 6.0.2 pytest == 8.4.0 pytest-xdist == 3.7.0 pytest-testinfra == 10.2.2 -tox == 4.26.0 +tox == 4.27.0 pytest-clarity == 1.0.1 From 0bc06ed204cb4fc6b831c060b608b59acbbb4d82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Jun 2025 10:10:47 +0000 Subject: [PATCH 22/32] Bump pytest from 8.4.0 to 8.4.1 in /test Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.4.0 to 8.4.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.4.0...8.4.1) --- updated-dependencies: - dependency-name: pytest dependency-version: 8.4.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- test/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements.txt b/test/requirements.txt index d2e4344a..43b1af15 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,5 +1,5 @@ pyyaml == 6.0.2 -pytest == 8.4.0 +pytest == 8.4.1 pytest-xdist == 3.7.0 pytest-testinfra == 10.2.2 tox == 4.26.0 From 830c4bc049bcd7e81727dec8d2d91303e1f9d705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 21 Jun 2025 22:40:43 +0200 Subject: [PATCH 23/32] Do not skipp root check for pihole user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- pihole | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pihole b/pihole index 1dfab754..1dee25e5 100755 --- a/pihole +++ b/pihole @@ -570,9 +570,9 @@ if [[ -z ${USER} ]]; then USER=$(whoami) fi -# Check if the current user is neither root nor pihole and if the command +# Check if the current user is not root and if the command # requires root. If so, exit with an error message. -if [[ $EUID -ne 0 && ${USER} != "pihole" && need_root -eq 1 ]];then +if [[ $EUID -ne 0 && need_root -eq 1 ]];then echo -e " ${CROSS} The Pi-hole command requires root privileges, try:" echo -e " ${COL_GREEN}sudo pihole $*${COL_NC}" exit 1 From a48665c7bba428e3e204c9f1bed5d2b8c244336c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 24 Jun 2025 18:51:01 +0200 Subject: [PATCH 24/32] Remove deprecated and unused colors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/COL_TABLE | 20 +------- advanced/Scripts/piholeCheckout.sh | 10 ++-- advanced/Scripts/update.sh | 26 +++++----- automated install/basic-install.sh | 82 +++++++++++++++--------------- automated install/uninstall.sh | 10 ++-- gravity.sh | 8 +-- pihole | 4 +- 7 files changed, 71 insertions(+), 89 deletions(-) diff --git a/advanced/Scripts/COL_TABLE b/advanced/Scripts/COL_TABLE index f9a014fc..0c6981c1 100644 --- a/advanced/Scripts/COL_TABLE +++ b/advanced/Scripts/COL_TABLE @@ -1,11 +1,11 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 # Disable warning about unused variables + # Determine if terminal is capable of showing colors if [ -t 1 ] && [ "$(tput colors)" -ge 8 ]; then # Bold and underline may not show up on all clients # If something MUST be emphasized, use both COL_BOLD='' - COL_ULINE='' - COL_NC='' COL_GRAY='' COL_RED='' @@ -17,8 +17,6 @@ if [ -t 1 ] && [ "$(tput colors)" -ge 8 ]; then else # Provide empty variables for `set -u` COL_BOLD="" - COL_ULINE="" - COL_NC="" COL_GRAY="" COL_RED="" @@ -29,22 +27,8 @@ else COL_CYAN="" fi -# Deprecated variables -COL_WHITE="${COL_BOLD}" -COL_BLACK="${COL_NC}" -COL_LIGHT_BLUE="${COL_BLUE}" -COL_LIGHT_GREEN="${COL_GREEN}" -COL_LIGHT_CYAN="${COL_CYAN}" -COL_LIGHT_RED="${COL_RED}" -COL_URG_RED="${COL_RED}${COL_BOLD}${COL_ULINE}" -COL_LIGHT_PURPLE="${COL_PURPLE}" -COL_BROWN="${COL_YELLOW}" -COL_LIGHT_GRAY="${COL_GRAY}" -COL_DARK_GRAY="${COL_GRAY}" - TICK="[${COL_GREEN}✓${COL_NC}]" CROSS="[${COL_RED}✗${COL_NC}]" INFO="[i]" QST="[?]" -DONE="${COL_GREEN} done!${COL_NC}" OVER="\\r" diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh index beaac5f1..a6df46f2 100755 --- a/advanced/Scripts/piholeCheckout.sh +++ b/advanced/Scripts/piholeCheckout.sh @@ -26,7 +26,7 @@ source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" warning1() { echo " Please note that changing branches severely alters your Pi-hole subsystems" echo " Features that work on the master branch, may not on a development branch" - echo -e " ${COL_LIGHT_RED}This feature is NOT supported unless a Pi-hole developer explicitly asks!${COL_NC}" + echo -e " ${COL_RED}This feature is NOT supported unless a Pi-hole developer explicitly asks!${COL_NC}" read -r -p " Have you read and understood this? [y/N] " response case "${response}" in [yY][eE][sS]|[yY]) @@ -55,19 +55,19 @@ checkout() { # This is unlikely if ! is_repo "${PI_HOLE_FILES_DIR}" ; then - echo -e " ${COL_LIGHT_RED}Error: Core Pi-hole repo is missing from system!" + echo -e " ${COL_RED}Error: Core Pi-hole repo is missing from system!" echo -e " Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}" exit 1; fi if ! is_repo "${webInterfaceDir}" ; then - echo -e " ${COL_LIGHT_RED}Error: Web Admin repo is missing from system!" + echo -e " ${COL_RED}Error: Web Admin repo is missing from system!" echo -e " Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}" exit 1; fi if [[ -z "${1}" ]]; then - echo -e " ${COL_LIGHT_RED}Invalid option${COL_NC}" + echo -e " ${COL_RED}Invalid option${COL_NC}" echo -e " Try 'pihole checkout --help' for more information." exit 1 fi @@ -238,7 +238,7 @@ checkout() { if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then exit 0 else - echo -e " ${COL_LIGHT_RED} Error: Unable to complete update, please contact support${COL_NC}" + echo -e " ${COL_RED} Error: Unable to complete update, please contact support${COL_NC}" exit 1 fi fi diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index 51c1b1a1..5fb7de18 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -47,7 +47,7 @@ GitCheckUpdateAvail() { # Fetch latest changes in this repo if ! git fetch --quiet origin ; then - echo -e "\\n ${COL_LIGHT_RED}Error: Unable to update local repository. Contact Pi-hole Support.${COL_NC}" + echo -e "\\n ${COL_RED}Error: Unable to update local repository. Contact Pi-hole Support.${COL_NC}" exit 1 fi @@ -76,13 +76,13 @@ GitCheckUpdateAvail() { if [[ "${#LOCAL}" == 0 ]]; then - echo -e "\\n ${COL_LIGHT_RED}Error: Local revision could not be obtained, please contact Pi-hole Support" + echo -e "\\n ${COL_RED}Error: Local revision could not be obtained, please contact Pi-hole Support" echo -e " Additional debugging output:${COL_NC}" git status exit 1 fi if [[ "${#REMOTE}" == 0 ]]; then - echo -e "\\n ${COL_LIGHT_RED}Error: Remote revision could not be obtained, please contact Pi-hole Support" + echo -e "\\n ${COL_RED}Error: Remote revision could not be obtained, please contact Pi-hole Support" echo -e " Additional debugging output:${COL_NC}" git status exit 1 @@ -103,7 +103,7 @@ GitCheckUpdateAvail() { } main() { - local basicError="\\n ${COL_LIGHT_RED}Unable to complete update, please contact Pi-hole Support${COL_NC}" + local basicError="\\n ${COL_RED}Unable to complete update, please contact Pi-hole Support${COL_NC}" local core_update local web_update local FTL_update @@ -120,7 +120,7 @@ main() { # This is unlikely if ! is_repo "${PI_HOLE_FILES_DIR}" ; then - echo -e "\\n ${COL_LIGHT_RED}Error: Core Pi-hole repo is missing from system!" + echo -e "\\n ${COL_RED}Error: Core Pi-hole repo is missing from system!" echo -e " Please re-run install script from https://pi-hole.net${COL_NC}" exit 1; fi @@ -132,11 +132,11 @@ main() { echo -e " ${INFO} Pi-hole Core:\\t${COL_YELLOW}update available${COL_NC}" else core_update=false - echo -e " ${INFO} Pi-hole Core:\\t${COL_LIGHT_GREEN}up to date${COL_NC}" + echo -e " ${INFO} Pi-hole Core:\\t${COL_GREEN}up to date${COL_NC}" fi if ! is_repo "${ADMIN_INTERFACE_DIR}" ; then - echo -e "\\n ${COL_LIGHT_RED}Error: Web Admin repo is missing from system!" + echo -e "\\n ${COL_RED}Error: Web Admin repo is missing from system!" echo -e " Please re-run install script from https://pi-hole.net${COL_NC}" exit 1; fi @@ -146,7 +146,7 @@ main() { echo -e " ${INFO} Web Interface:\\t${COL_YELLOW}update available${COL_NC}" else web_update=false - echo -e " ${INFO} Web Interface:\\t${COL_LIGHT_GREEN}up to date${COL_NC}" + echo -e " ${INFO} Web Interface:\\t${COL_GREEN}up to date${COL_NC}" fi local funcOutput @@ -160,17 +160,17 @@ main() { else case $? in 1) - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_GREEN}up to date${COL_NC}" + echo -e " ${INFO} FTL:\\t\\t${COL_GREEN}up to date${COL_NC}" ;; 2) - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Branch is not available.${COL_NC}\\n\\t\\t\\tUse ${COL_LIGHT_GREEN}pihole checkout ftl [branchname]${COL_NC} to switch to a valid branch." + echo -e " ${INFO} FTL:\\t\\t${COL_RED}Branch is not available.${COL_NC}\\n\\t\\t\\tUse ${COL_GREEN}pihole checkout ftl [branchname]${COL_NC} to switch to a valid branch." ;; 3) - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Something has gone wrong, cannot reach download server${COL_NC}" + echo -e " ${INFO} FTL:\\t\\t${COL_RED}Something has gone wrong, cannot reach download server${COL_NC}" exit 1 ;; *) - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Something has gone wrong, contact support${COL_NC}" + echo -e " ${INFO} FTL:\\t\\t${COL_RED}Something has gone wrong, contact support${COL_NC}" exit 1 esac FTL_update=false @@ -187,7 +187,7 @@ main() { if [[ ! "${ftlBranch}" == "master" && ! "${ftlBranch}" == "development" ]]; then # Notify user that they are on a custom branch which might mean they they are lost # behind if a branch was merged to development and got abandoned - printf " %b %bWarning:%b You are using FTL from a custom branch (%s) and might be missing future releases.\\n" "${INFO}" "${COL_LIGHT_RED}" "${COL_NC}" "${ftlBranch}" + printf " %b %bWarning:%b You are using FTL from a custom branch (%s) and might be missing future releases.\\n" "${INFO}" "${COL_RED}" "${COL_NC}" "${ftlBranch}" fi if [[ "${core_update}" == false && "${web_update}" == false && "${FTL_update}" == false ]]; then diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index fca77f99..46bfffb9 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -173,13 +173,11 @@ if [[ -f "${coltable}" ]]; then else # Set these values so the installer can still run in color COL_NC='\e[0m' # No Color - COL_LIGHT_GREEN='\e[1;32m' - COL_LIGHT_RED='\e[1;31m' - TICK="[${COL_LIGHT_GREEN}✓${COL_NC}]" - CROSS="[${COL_LIGHT_RED}✗${COL_NC}]" + COL_GREEN='\e[1;32m' + COL_RED='\e[1;31m' + TICK="[${COL_GREEN}✓${COL_NC}]" + CROSS="[${COL_RED}✗${COL_NC}]" INFO="[i]" - # shellcheck disable=SC2034 - DONE="${COL_LIGHT_GREEN} done!${COL_NC}" OVER="\\r\\033[K" fi @@ -187,13 +185,13 @@ fi # This lets users know that it is a Pi-hole, LLC product show_ascii_berry() { echo -e " - ${COL_LIGHT_GREEN}.;;,. + ${COL_GREEN}.;;,. .ccccc:,. :cccclll:. ..,, :ccccclll. ;ooodc 'ccll:;ll .oooodc .;cll.;;looo:. - ${COL_LIGHT_RED}.. ','. + ${COL_RED}.. ','. .',,,,,,'. .',,,,,,,,,,. .',,,,,,,,,,,,.... @@ -215,7 +213,7 @@ abort() { # remove any leftover build directory that may exist rm -rf /tmp/pihole-meta_* - echo -e "\\n\\n ${COL_LIGHT_RED}Installation was interrupted${COL_NC}\\n" + echo -e "\\n\\n ${COL_RED}Installation was interrupted${COL_NC}\\n" echo -e "Pi-hole's dependencies might be already installed. If you want to remove them you can try to\\n" echo -e "a) run 'pihole uninstall' \\n" echo -e "b) Remove the meta-package 'pihole-meta' manually \\n" @@ -308,7 +306,7 @@ build_dependency_package(){ printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}" else printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" - printf "%b Error: Building pihole-meta.deb failed. %b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf "%b Error: Building pihole-meta.deb failed. %b\\n" "${COL_RED}" "${COL_NC}" return 1 fi @@ -341,7 +339,7 @@ build_dependency_package(){ printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}" else printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" - printf "%b Error: Building pihole-meta.rpm failed. %b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf "%b Error: Building pihole-meta.rpm failed. %b\\n" "${COL_RED}" "${COL_NC}" return 1 fi @@ -483,7 +481,7 @@ getGitFiles() { printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}" # Update the repo, returning an error message on failure update_repo "${directory}" || { - printf "\\n %b: Could not update local repository. Contact support.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf "\\n %b: Could not update local repository. Contact support.%b\\n" "${COL_RED}" "${COL_NC}" exit 1 } # If it's not a .git repo, @@ -492,7 +490,7 @@ getGitFiles() { printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" # Attempt to make the repository, showing an error on failure make_repo "${directory}" "${remoteRepo}" || { - printf "\\n %bError: Could not update local repository. Contact support.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf "\\n %bError: Could not update local repository. Contact support.%b\\n" "${COL_RED}" "${COL_NC}" exit 1 } fi @@ -807,7 +805,7 @@ setDNS() { result=$? case ${result} in "${DIALOG_CANCEL}" | "${DIALOG_ESC}") - printf " %b Cancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b Cancel was selected, exiting installer%b\\n" "${COL_RED}" "${COL_NC}" exit 1 ;; esac @@ -844,7 +842,7 @@ If you want to specify a port other than 53, separate it with a hash.\ result=$? case ${result} in "${DIALOG_CANCEL}" | "${DIALOG_ESC}") - printf " %b Cancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b Cancel was selected, exiting installer%b\\n" "${COL_RED}" "${COL_NC}" exit 1 ;; esac @@ -898,7 +896,7 @@ If you want to specify a port other than 53, separate it with a hash.\ DNSSettingsCorrect=False ;; "${DIALOG_ESC}") - printf " %b Escape 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_RED}" "${COL_NC}" exit 1 ;; esac @@ -949,7 +947,7 @@ setLogging() { ;; "${DIALOG_ESC}") # User pressed - printf " %b Escape 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_RED}" "${COL_NC}" exit 1 ;; esac @@ -974,7 +972,7 @@ setPrivacyLevel() { 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}" + printf " %b Cancelled privacy level selection.%b\\n" "${COL_RED}" "${COL_NC}" exit 1 ;; esac @@ -1008,7 +1006,7 @@ chooseBlocklists() { ;; "${DIALOG_ESC}") # User pressed - printf " %b Escape 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_RED}" "${COL_NC}" exit 1 ;; esac @@ -1134,7 +1132,7 @@ installScripts() { else # Otherwise, show an error and exit printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" - printf "\\t\\t%bError: Local repo %s not found, exiting installer%b\\n" "${COL_LIGHT_RED}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}" + printf "\\t\\t%bError: Local repo %s not found, exiting installer%b\\n" "${COL_RED}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}" return 1 fi } @@ -1149,7 +1147,7 @@ installConfigs() { # Install empty custom.list file if it does not exist if [[ ! -r "${PI_HOLE_CONFIG_DIR}/hosts/custom.list" ]]; then if ! install -D -T -o pihole -g pihole -m 660 /dev/null "${PI_HOLE_CONFIG_DIR}/hosts/custom.list" &>/dev/null; then - printf " %b Error: Unable to initialize configuration file %s/custom.list\\n" "${COL_LIGHT_RED}" "${PI_HOLE_CONFIG_DIR}/hosts" + printf " %b Error: Unable to initialize configuration file %s/custom.list\\n" "${COL_RED}" "${PI_HOLE_CONFIG_DIR}/hosts" return 1 fi fi @@ -1328,7 +1326,7 @@ update_package_cache() { UPDATE_PKG_CACHE="apt update" fi printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" - printf " %b Error: Unable to update package cache. Please try \"%s\"%b\\n" "${COL_LIGHT_RED}" "sudo ${UPDATE_PKG_CACHE}" "${COL_NC}" + printf " %b Error: Unable to update package cache. Please try \"%s\"%b\\n" "${COL_RED}" "sudo ${UPDATE_PKG_CACHE}" "${COL_NC}" return 1 fi } @@ -1346,7 +1344,7 @@ notify_package_updates_available() { printf "%b %b %s... up to date!\\n\\n" "${OVER}" "${TICK}" "${str}" else printf "%b %b %s... %s updates available\\n" "${OVER}" "${TICK}" "${str}" "${updatesToInstall}" - printf " %b %bIt is recommended to update your OS after installing the Pi-hole!%b\\n\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}" + printf " %b %bIt is recommended to update your OS after installing the Pi-hole!%b\\n\\n" "${INFO}" "${COL_GREEN}" "${COL_NC}" fi } @@ -1363,11 +1361,11 @@ install_dependent_packages() { rm /tmp/pihole-meta.deb else printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" - printf " %b Error: Unable to install Pi-hole dependency package.\\n" "${COL_LIGHT_RED}" + printf " %b Error: Unable to install Pi-hole dependency package.\\n" "${COL_RED}" return 1 fi else - printf " %b Error: Unable to find Pi-hole dependency package.\\n" "${COL_LIGHT_RED}" + printf " %b Error: Unable to find Pi-hole dependency package.\\n" "${COL_RED}" return 1 fi # Install Fedora/CentOS packages @@ -1378,11 +1376,11 @@ install_dependent_packages() { rm /tmp/pihole-meta.rpm else printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" - printf " %b Error: Unable to install Pi-hole dependency package.\\n" "${COL_LIGHT_RED}" + printf " %b Error: Unable to install Pi-hole dependency package.\\n" "${COL_RED}" return 1 fi else - printf " %b Error: Unable to find Pi-hole dependency package.\\n" "${COL_LIGHT_RED}" + printf " %b Error: Unable to find Pi-hole dependency package.\\n" "${COL_RED}" return 1 fi @@ -1611,13 +1609,13 @@ checkSelinux() { if [[ "${SELINUX_ENFORCING}" -eq 1 ]] && [[ -z "${PIHOLE_SELINUX}" ]]; then printf " Pi-hole does not provide an SELinux policy as the required changes modify the security of your system.\\n" printf " Please refer to https://wiki.centos.org/HowTos/SELinux if SELinux is required for your deployment.\\n" - printf " This check can be skipped by setting the environment variable %bPIHOLE_SELINUX%b to %btrue%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" "${COL_LIGHT_RED}" "${COL_NC}" + printf " This check can be skipped by setting the environment variable %bPIHOLE_SELINUX%b to %btrue%b\\n" "${COL_RED}" "${COL_NC}" "${COL_RED}" "${COL_NC}" printf " e.g: export PIHOLE_SELINUX=true\\n" printf " By setting this variable to true you acknowledge there may be issues with Pi-hole during or after the install\\n" - printf "\\n %bSELinux Enforcing detected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" + printf "\\n %bSELinux Enforcing detected, exiting installer%b\\n" "${COL_RED}" "${COL_NC}" exit 1 elif [[ "${SELINUX_ENFORCING}" -eq 1 ]] && [[ -n "${PIHOLE_SELINUX}" ]]; then - printf " %b %bSELinux Enforcing detected%b. PIHOLE_SELINUX env variable set - installer will continue\\n" "${INFO}" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b %bSELinux Enforcing detected%b. PIHOLE_SELINUX env variable set - installer will continue\\n" "${INFO}" "${COL_RED}" "${COL_NC}" fi } @@ -1715,13 +1713,13 @@ clone_or_reset_repos() { # Reset the Core repo resetRepo ${PI_HOLE_LOCAL_REPO} || { - printf " %b Unable to reset %s, exiting installer%b\\n" "${COL_LIGHT_RED}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}" + printf " %b Unable to reset %s, exiting installer%b\\n" "${COL_RED}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}" exit 1 } # Reset the Web repo resetRepo ${webInterfaceDir} || { - printf " %b Unable to reset %s, exiting installer%b\\n" "${COL_LIGHT_RED}" "${webInterfaceDir}" "${COL_NC}" + printf " %b Unable to reset %s, exiting installer%b\\n" "${COL_RED}" "${webInterfaceDir}" "${COL_NC}" exit 1 } # Otherwise, a fresh installation is happening @@ -1729,13 +1727,13 @@ clone_or_reset_repos() { # so get git files for Core getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || { - printf " %b Unable to clone %s into %s, unable to continue%b\\n" "${COL_LIGHT_RED}" "${piholeGitUrl}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}" + printf " %b Unable to clone %s into %s, unable to continue%b\\n" "${COL_RED}" "${piholeGitUrl}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}" exit 1 } # get the Web git files getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || { - printf " %b Unable to clone %s into ${webInterfaceDir}, exiting installer%b\\n" "${COL_LIGHT_RED}" "${webInterfaceGitUrl}" "${COL_NC}" + printf " %b Unable to clone %s into ${webInterfaceDir}, exiting installer%b\\n" "${COL_RED}" "${webInterfaceGitUrl}" "${COL_NC}" exit 1 } fi @@ -1811,7 +1809,7 @@ FTLinstall() { return 1 } printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" - printf " %b Error: Download of %s/%s failed (checksum error)%b\\n" "${COL_LIGHT_RED}" "${url}" "${binary}" "${COL_NC}" + printf " %b Error: Download of %s/%s failed (checksum error)%b\\n" "${COL_RED}" "${url}" "${binary}" "${COL_NC}" # Remove temp dir remove_dir "${tempdir}" @@ -1825,7 +1823,7 @@ FTLinstall() { } printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" # The URL could not be found - printf " %b Error: URL %s/%s not found%b\\n" "${COL_LIGHT_RED}" "${url}" "${binary}" "${COL_NC}" + printf " %b Error: URL %s/%s not found%b\\n" "${COL_RED}" "${url}" "${binary}" "${COL_NC}" # Remove temp dir remove_dir "${tempdir}" @@ -1902,7 +1900,7 @@ get_binary_name() { # Something else - we try to use 32bit executable and warn the user if [[ ! "${machine}" == "i686" ]]; then printf "%b %b %s...\\n" "${OVER}" "${CROSS}" "${str}" - printf " %b %bNot able to detect architecture (unknown: %s), trying x86 (32bit) executable%b\\n" "${INFO}" "${COL_LIGHT_RED}" "${machine}" "${COL_NC}" + printf " %b %bNot able to detect architecture (unknown: %s), trying x86 (32bit) executable%b\\n" "${INFO}" "${COL_RED}" "${machine}" "${COL_NC}" printf " %b Contact Pi-hole Support if you experience issues (e.g: FTL not running)\\n" "${INFO}" else printf "%b %b Detected 32bit (i686) architecture\\n" "${OVER}" "${TICK}" @@ -1945,7 +1943,7 @@ FTLcheckUpdate() { status=$? if [ "${status}" -eq 1 ]; then printf " %b Branch \"%s\" is not available.\\n" "${INFO}" "${ftlBranch}" - printf " %b Use %bpihole checkout ftl [branchname]%b to switch to a valid branch.\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}" + printf " %b Use %bpihole checkout ftl [branchname]%b to switch to a valid branch.\\n" "${INFO}" "${COL_GREEN}" "${COL_NC}" elif [ "${status}" -eq 2 ]; then printf " %b Unable to download from ftl.pi-hole.net. Please check your Internet connection and try again later.\\n" "${CROSS}" return 3 @@ -2158,7 +2156,7 @@ main() { else # Otherwise, they do not have enough privileges, so let the user know printf " %b %s\\n" "${INFO}" "${str}" - printf " %b %bScript called with non-root privileges%b\\n" "${INFO}" "${COL_LIGHT_RED}" "${COL_NC}" + printf " %b %bScript called with non-root privileges%b\\n" "${INFO}" "${COL_RED}" "${COL_NC}" printf " The Pi-hole requires elevated privileges to install and run\\n" printf " Please check the installer for any concerns regarding this requirement\\n" printf " Make sure to download this script from a trusted source\\n\\n" @@ -2182,7 +2180,7 @@ main() { # Otherwise, tell the user they need to run the script as root, and bail printf "%b %b Sudo utility check\\n" "${OVER}" "${CROSS}" printf " %b Sudo is needed for the Web Interface to run pihole commands\\n\\n" "${INFO}" - printf " %b %bPlease re-run this installer as root${COL_NC}\\n" "${INFO}" "${COL_LIGHT_RED}" + printf " %b %bPlease re-run this installer as root${COL_NC}\\n" "${INFO}" "${COL_RED}" exit 1 fi fi @@ -2367,7 +2365,7 @@ main() { printf " %b If you have not done so already, the above IP should be set to static.\\n" "${INFO}" printf " %b View the web interface at http://pi.hole:${WEBPORT}/admin or http://%s/admin\\n\\n" "${INFO}" "${IPV4_ADDRESS%/*}:${WEBPORT}" - printf " %b Web Interface password: %b%s%b\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${pw}" "${COL_NC}" + printf " %b Web Interface password: %b%s%b\\n" "${INFO}" "${COL_GREEN}" "${pw}" "${COL_NC}" printf " %b This can be changed using 'pihole setpassword'\\n\\n" "${INFO}" printf " %b To allow your user to use all CLI functions without authentication, refer to\\n" "${INFO}" printf " our documentation at: https://docs.pi-hole.net/main/post-install/\\n\\n" @@ -2392,7 +2390,7 @@ main() { # Display where the log file is printf "\\n %b The install log is located at: %s\\n" "${INFO}" "${installLogLoc}" - printf " %b %b%s complete! %b\\n" "${TICK}" "${COL_LIGHT_GREEN}" "${INSTALL_TYPE}" "${COL_NC}" + printf " %b %b%s complete! %b\\n" "${TICK}" "${COL_GREEN}" "${INSTALL_TYPE}" "${COL_NC}" if [[ "${INSTALL_TYPE}" == "Update" ]]; then printf "\\n" diff --git a/automated install/uninstall.sh b/automated install/uninstall.sh index a158e595..e8dec36a 100755 --- a/automated install/uninstall.sh +++ b/automated install/uninstall.sh @@ -17,10 +17,10 @@ ADMIN_INTERFACE_DIR=$(getFTLConfigValue "webserver.paths.webroot")$(getFTLConfig readonly ADMIN_INTERFACE_DIR while true; do - read -rp " ${QST} Are you sure you would like to remove ${COL_WHITE}Pi-hole${COL_NC}? [y/N] " answer + read -rp " ${QST} Are you sure you would like to remove ${COL_BOLD}Pi-hole${COL_NC}? [y/N] " answer case ${answer} in [Yy]* ) break;; - * ) echo -e "${OVER} ${COL_LIGHT_GREEN}Uninstall has been canceled${COL_NC}"; exit 0;; + * ) echo -e "${OVER} ${COL_GREEN}Uninstall has been canceled${COL_NC}"; exit 0;; esac done @@ -150,11 +150,11 @@ removePiholeFiles() { echo -e "\\n We're sorry to see you go, but thanks for checking out Pi-hole! If you need help, reach out to us on GitHub, Discourse, Reddit or Twitter - Reinstall at any time: ${COL_WHITE}curl -sSL https://install.pi-hole.net | bash${COL_NC} + Reinstall at any time: ${COL_BOLD}curl -sSL https://install.pi-hole.net | bash${COL_NC} - ${COL_LIGHT_RED}Please reset the DNS on your router/clients to restore internet connectivity${COL_NC} + ${COL_RED}Please reset the DNS on your router/clients to restore internet connectivity${COL_NC} ${INFO} Pi-hole's meta package has been removed, use the 'autoremove' function from your package manager to remove unused dependencies${COL_NC} - ${COL_LIGHT_GREEN}Uninstallation Complete! ${COL_NC}" + ${COL_GREEN}Uninstallation Complete! ${COL_NC}" } ######### SCRIPT ########### diff --git a/gravity.sh b/gravity.sh index 16e459c6..fcbce46b 100755 --- a/gravity.sh +++ b/gravity.sh @@ -50,7 +50,7 @@ etag_support=false # Check gravity temp directory if [ ! -d "${GRAVITY_TMPDIR}" ] || [ ! -w "${GRAVITY_TMPDIR}" ]; then - echo -e " ${COL_LIGHT_RED}Gravity temporary directory does not exist or is not a writeable directory, falling back to /tmp. ${COL_NC}" + echo -e " ${COL_RED}Gravity temporary directory does not exist or is not a writeable directory, falling back to /tmp. ${COL_NC}" GRAVITY_TMPDIR="/tmp" fi @@ -821,13 +821,13 @@ gravity_DownloadBlocklistFromUrl() { if [[ "${done}" != "true" ]]; then # Determine if cached list has read permission if [[ -r "${saveLocation}" ]]; then - echo -e " ${CROSS} List download failed: ${COL_LIGHT_GREEN}using previously cached list${COL_NC}" + echo -e " ${CROSS} List download failed: ${COL_GREEN}using previously cached list${COL_NC}" # Set list status to "download-failed/cached" database_adlist_status "${adlistID}" "3" # Add domains to database table file pihole-FTL "${gravity_type}" parseList "${saveLocation}" "${gravityTEMPfile}" "${adlistID}" else - echo -e " ${CROSS} List download failed: ${COL_LIGHT_RED}no cached list available${COL_NC}" + echo -e " ${CROSS} List download failed: ${COL_RED}no cached list available${COL_NC}" # Manually reset these two numbers because we do not call parseList here database_adlist_number "${adlistID}" 0 0 database_adlist_status "${adlistID}" "4" @@ -864,7 +864,7 @@ gravity_ShowCount() { # Trap Ctrl-C gravity_Trap() { - trap '{ echo -e "\\n\\n ${INFO} ${COL_LIGHT_RED}User-abort detected${COL_NC}"; gravity_Cleanup "error"; }' INT + trap '{ echo -e "\\n\\n ${INFO} ${COL_RED}User-abort detected${COL_NC}"; gravity_Cleanup "error"; }' INT } # Clean up after Gravity upon exit or cancellation diff --git a/pihole b/pihole index 1dfab754..fde9ae82 100755 --- a/pihole +++ b/pihole @@ -238,7 +238,7 @@ Time: fi if [[ ${error} == true ]];then - echo -e " ${COL_LIGHT_RED}Unknown format for blocking timer!${COL_NC}" + echo -e " ${COL_RED}Unknown format for blocking timer!${COL_NC}" echo -e " Try 'pihole disable --help' for more information." exit 1 fi @@ -293,7 +293,7 @@ Options: echo -e " ${INFO} Enabling logging..." local str="Logging has been enabled!" else - echo -e " ${COL_LIGHT_RED}Invalid option${COL_NC} + echo -e " ${COL_RED}Invalid option${COL_NC} Try 'pihole logging --help' for more information." exit 1 fi From daec6f8c02ef8871a84f8e1926d4f6cb9b19a525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 24 Jun 2025 19:03:24 +0200 Subject: [PATCH 25/32] Set color codes when FORCE_COLOR is true MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/COL_TABLE | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/advanced/Scripts/COL_TABLE b/advanced/Scripts/COL_TABLE index 0c6981c1..7d339c0e 100644 --- a/advanced/Scripts/COL_TABLE +++ b/advanced/Scripts/COL_TABLE @@ -2,7 +2,8 @@ # shellcheck disable=SC2034 # Disable warning about unused variables # Determine if terminal is capable of showing colors -if [ -t 1 ] && [ "$(tput colors)" -ge 8 ]; then +# When COL_TABLE is sourced via gravity invoked by FTL, FORCE_COLOR is set to true +if { [ -t 1 ] && [ "$(tput colors)" -ge 8 ]; } || [ "${FORCE_COLOR}" ]; then # Bold and underline may not show up on all clients # If something MUST be emphasized, use both COL_BOLD='' From 19d59434408f0d3ce2f86a0cb4c824468c16d3c6 Mon Sep 17 00:00:00 2001 From: Rob Gill Date: Wed, 25 Jun 2025 05:10:12 +1000 Subject: [PATCH 26/32] piholeDebug - Get default route robustly Determine address and interface of default route by preceeding 'via' and 'dev' fields in json output instead of plain text field position. Log if unable to determine default gateway Signed-off-by: Rob Gill --- advanced/Scripts/piholeDebug.sh | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index 741ff2f4..e4bd1191 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -497,16 +497,25 @@ ping_gateway() { ping_ipv4_or_ipv6 "${protocol}" # Check if we are using IPv4 or IPv6 # Find the default gateways using IPv4 or IPv6 - local gateway gateway_addr gateway_iface + local gateway gateway_addr gateway_iface default_route log_write "${INFO} Default IPv${protocol} gateway(s):" - while IFS= read -r gateway; do - log_write " $(cut -d ' ' -f 3 <<< "${gateway}")%$(cut -d ' ' -f 5 <<< "${gateway}")" - done < <(ip -"${protocol}" route | grep default) + while IFS= read -r default_route; do + gateway_addr=$(jq -r '.gateway' <<< "${default_route}") + gateway_iface=$(jq -r '.dev' <<< "${default_route}") + log_write " ${gateway_addr}%${gateway_iface}" + done < <(ip -j -"${protocol}" route | jq -c '.[] | select(.dst == "default")') + + # Find the first default route + default_route=$(ip -j -"${protocol}" route show default) + if echo "$default_route" | grep 'gateway' | grep -q 'dev'; then + gateway_addr=$(echo "$default_route" | jq -r -c '.[0].gateway') + gateway_iface=$(echo "$default_route" | jq -r -c '.[0].dev') + else + log_write " Unable to determine gateway address for IPv${protocol}" + fi - gateway_addr=$(ip -"${protocol}" route | grep default | cut -d ' ' -f 3 | head -n 1) - gateway_iface=$(ip -"${protocol}" route | grep default | cut -d ' ' -f 5 | head -n 1) # If there was at least one gateway if [ -n "${gateway_addr}" ]; then # Append the interface to the gateway address if it is a link-local address From 3a35e589f2ead2aa85c146c17f7246401248b602 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Thu, 26 Jun 2025 00:40:37 +0200 Subject: [PATCH 27/32] installer: exit if FTL update check fails The return code of `FTLdetect()` is used in the installer to know whether FTL has been installed or not. The function however returns an error only, if the download of FTL fails, not if checking for a latest version/update of FTL fails. This way, installs and rapairs can continue without or with ourdated FTL until `pihole-FTL migrate v6`, which hangs endlessly, if it is a v5 FTL. This commit handles the return code in `FTLdetect()`, and lets it return true only if FTL download succeeded, or if the update check succeeded and FTL is up-to-date. Else, it could neither be repaired, nor installed, and the error message should give a hint what went wrong, hence exit. `FTLdetect()` is not called by any other script, hence this change has no surprising effect elsewhere. Additionally, a syntax error in the `FTLcheckUpdate()` function itself is fixed, which masks the `check_download_exists()` return code, hence always leads to error code 4, if the FTL branch is not `master`. Signed-off-by: MichaIng --- automated install/basic-install.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 279dc1d1..afb9dc50 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -1940,8 +1940,8 @@ FTLcheckUpdate() { path="${ftlBranch}/${binary}" # Check whether or not the binary for this FTL branch actually exists. If not, then there is no update! + local status if ! check_download_exists "$path"; then - local status status=$? if [ "${status}" -eq 1 ]; then printf " %b Branch \"%s\" is not available.\\n" "${INFO}" "${ftlBranch}" @@ -2031,6 +2031,11 @@ FTLdetect() { if FTLcheckUpdate "${1}"; then FTLinstall "${1}" || return 1 + else + case $? in + 1) :;; # FTL is up-to-date + *) exit 1;; # 404 (2), other HTTP or curl error (3), unknown (4) + esac fi } From f24fc9573a9a77fb18b389262e70c92364b13781 Mon Sep 17 00:00:00 2001 From: Rob Gill Date: Sun, 29 Jun 2025 06:45:02 +1000 Subject: [PATCH 28/32] taillog Prevent grep interpeting search term as an option Adds '--' indicating end of options before the user provided search pattern. Signed-off-by: Rob Gill --- pihole | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole b/pihole index fde9ae82..7df4aefc 100755 --- a/pihole +++ b/pihole @@ -396,7 +396,7 @@ tailFunc() { # Color blocklist/denylist/wildcard entries as red # Color A/AAAA/DHCP strings as white # Color everything else as gray - tail -f $LOGFILE | grep --line-buffered "${1}" | sed -E \ + tail -f $LOGFILE | grep --line-buffered -- "${1}" | sed -E \ -e "s,($(date +'%b %d ')| dnsmasq\[[0-9]*\]),,g" \ -e "s,(.*(denied |gravity blocked ).*),${COL_RED}&${COL_NC}," \ -e "s,.*(query\\[A|DHCP).*,${COL_NC}&${COL_NC}," \ From 2f9fa80d7a9dc9d7452c0177b2a897ba0c11d455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 1 Jul 2025 13:34:55 +0200 Subject: [PATCH 29/32] Update python version used in test to 3.13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ac496406..c2e8f951 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -80,10 +80,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.2.2 - - name: Set up Python 3.10 + - name: Set up Python uses: actions/setup-python@v5.6.0 with: - python-version: "3.10" + python-version: "3.13" - name: Install wheel run: pip install wheel From c5c5116e530c2a61aadfc34d7b81d3adf0efe03d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Jul 2025 10:28:30 +0000 Subject: [PATCH 30/32] Bump pytest-xdist from 3.7.0 to 3.8.0 in /test Bumps [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) from 3.7.0 to 3.8.0. - [Release notes](https://github.com/pytest-dev/pytest-xdist/releases) - [Changelog](https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-xdist/compare/v3.7.0...v3.8.0) --- updated-dependencies: - dependency-name: pytest-xdist dependency-version: 3.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- test/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requirements.txt b/test/requirements.txt index 6553def2..92f78840 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,6 +1,6 @@ pyyaml == 6.0.2 pytest == 8.4.1 -pytest-xdist == 3.7.0 +pytest-xdist == 3.8.0 pytest-testinfra == 10.2.2 tox == 4.27.0 pytest-clarity == 1.0.1 From 6db6c68a4e95d63e92f79b4e3093384c8b2ef4f6 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Thu, 10 Jul 2025 21:34:35 +0200 Subject: [PATCH 31/32] update: abort if FTL branch does not exist Currently, if the FTL update check returns 404, hence the FTL branch does not seem to exist, an error message is printed, but the update continues, only the FTL update is skipped. This can lead to setups with v5 FTL and v6 core/web, failing at config migration, where FTL is invoked with a v6-only command. With this change, the update aborts immediately if the FTL branch is invalid, like it does in case of other FTL update check errors (other HTTP error codes than 404 or other curl errors). Hence it continues only if FTL is up-to-date already, or a new version from the given branch has been found. Signed-off-by: MichaIng --- advanced/Scripts/update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index 5fb7de18..4e0d973e 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -164,6 +164,7 @@ main() { ;; 2) echo -e " ${INFO} FTL:\\t\\t${COL_RED}Branch is not available.${COL_NC}\\n\\t\\t\\tUse ${COL_GREEN}pihole checkout ftl [branchname]${COL_NC} to switch to a valid branch." + exit 1 ;; 3) echo -e " ${INFO} FTL:\\t\\t${COL_RED}Something has gone wrong, cannot reach download server${COL_NC}" From 86bdae0076edf3a96a41ade11bc0675fa988e45a Mon Sep 17 00:00:00 2001 From: deHakkelaar Date: Sun, 13 Jul 2025 11:05:58 +0200 Subject: [PATCH 32/32] Update basic-install.sh Added comments --- automated install/basic-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index dfecda9c..3932fb59 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -577,6 +577,9 @@ Do you wish to continue with an IPv6-only installation?\\n\\n" \ # Get available interfaces that are UP get_available_interfaces() { # There may be more than one so it's all stored in a variable + # The ip command list all interfaces that are in the up state + # The awk command filters out any interfaces that have the LOOPBACK flag set + # while using the characters ": " or "@" as a field separator for awk availableInterfaces=$(ip --oneline link show up | awk -F ': |@' '!/<.*LOOPBACK.*>/ {print $2}') }