From 4609f908601bf0076cd55b8351755672a7dc6512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 25 Feb 2025 14:24:59 +0100 Subject: [PATCH 01/21] Show an warning dialoge before performing an update 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 | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index 9ea63b4c..07db152e 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -97,6 +97,50 @@ GitCheckUpdateAvail() { fi } +updateWarnDialog() { + # Display the warning dialog + + local core_str web_str ftl_str + + if [[ "${core_update}" == true ]]; then + core_str="Core: \\Zb\\Z1update available\\Zn" + else + core_str="Core: \\Zb\\Z4up to date\\Zn" + fi + if [[ "${web_update}" == true ]]; then + web_str="Web Interface: \\Zb\\Z1update available\\Zn" + else + web_str="Web Interface: \\Zb\\Z4up to date\\Zn" + fi + if [[ "${FTL_update}" == true ]]; then + ftl_str="FTL: \\Zb\\Z1update available\\Zn" + else + ftl_str="FTL: \\Zb\\Z4up to date\\Zn" + fi + # shellcheck disable=SC2154 # Variables "${r}" "${c}" are defined in the main script + dialog --no-shadow --clear --keep-tite \ + --colors \ + --backtitle "Updating Pi-hole" \ + --title "Warning" \ + --no-button "Exit" --yes-button "Continue" \ + --defaultno \ + --yesno "\\nThe following Pi-hole components are going to be updated.\\n\\n\\n\ + $core_str\\n\ + $web_str\\n\ + $ftl_str\\n\\n\\n\ +\\Zb\\Z1IMPORTANT:\\Zn Make a (teleporter) backup of your system!\\n\\n\ +Updates can come with significant changes. Please read the changelog carefully.\\n\\n\\n\ +Please confirm you want to start the update process." \ + "${r}" "${c}" && result=0 || result="$?" + + case "${result}" in + "${DIALOG_CANCEL}" | "${DIALOG_ESC}") + printf " %b User canceled the update process.\\n" "${INFO}" + exit 1 + ;; + esac +} + main() { local basicError="\\n ${COL_LIGHT_RED}Unable to complete update, please contact Pi-hole Support${COL_NC}" local core_update @@ -198,6 +242,11 @@ main() { exit 0 fi + # if there is any update, show the warning dialog and ask for confirmation + if [[ "${core_update}" == true || "${web_update}" == true || "${FTL_update}" == true ]]; then + updateWarnDialog + fi + if [[ "${core_update}" == true ]]; then echo "" echo -e " ${INFO} Pi-hole core files out of date, updating local repo." From 43ee7247183a369e963a5c8bb0b6b9190c1521f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 26 Feb 2025 13:30:46 +0100 Subject: [PATCH 02/21] Improve alignment and add link to blog post 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 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index 07db152e..efdcd9d6 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -108,14 +108,14 @@ updateWarnDialog() { core_str="Core: \\Zb\\Z4up to date\\Zn" fi if [[ "${web_update}" == true ]]; then - web_str="Web Interface: \\Zb\\Z1update available\\Zn" + web_str="Web: \\Zb\\Z1update available\\Zn" else - web_str="Web Interface: \\Zb\\Z4up to date\\Zn" + web_str="Web: \\Zb\\Z4up to date\\Zn" fi if [[ "${FTL_update}" == true ]]; then - ftl_str="FTL: \\Zb\\Z1update available\\Zn" + ftl_str="FTL: \\Zb\\Z1update available\\Zn" else - ftl_str="FTL: \\Zb\\Z4up to date\\Zn" + ftl_str="FTL: \\Zb\\Z4up to date\\Zn" fi # shellcheck disable=SC2154 # Variables "${r}" "${c}" are defined in the main script dialog --no-shadow --clear --keep-tite \ @@ -129,7 +129,7 @@ updateWarnDialog() { $web_str\\n\ $ftl_str\\n\\n\\n\ \\Zb\\Z1IMPORTANT:\\Zn Make a (teleporter) backup of your system!\\n\\n\ -Updates can come with significant changes. Please read the changelog carefully.\\n\\n\\n\ +Updates can come with significant changes. Please read the changelog at https://pi-hole.net/blog carefully.\\n\\n\\n\ Please confirm you want to start the update process." \ "${r}" "${c}" && result=0 || result="$?" From 1a3a23a8677a1c063d0855888f6bf22fb7536890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 26 May 2025 21:38:26 +0200 Subject: [PATCH 03/21] Give FTL 120 seconds to shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Templates/pihole-FTL.service | 4 ++-- advanced/Templates/pihole-FTL.systemd | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/advanced/Templates/pihole-FTL.service b/advanced/Templates/pihole-FTL.service index 7c7e9962..9cdad7a0 100644 --- a/advanced/Templates/pihole-FTL.service +++ b/advanced/Templates/pihole-FTL.service @@ -57,9 +57,9 @@ start() { stop() { if is_running; then kill "${FTL_PID}" - # Give FTL 60 seconds to gracefully stop + # Give FTL 120 seconds to gracefully stop i=1 - while [ "${i}" -le 60 ]; do + while [ "${i}" -le 120 ]; do if ! is_running; then break fi diff --git a/advanced/Templates/pihole-FTL.systemd b/advanced/Templates/pihole-FTL.systemd index fcbb8d8d..0f0e8245 100644 --- a/advanced/Templates/pihole-FTL.systemd +++ b/advanced/Templates/pihole-FTL.systemd @@ -28,7 +28,7 @@ ExecReload=/bin/kill -HUP $MAINPID ExecStopPost=/opt/pihole/pihole-FTL-poststop.sh # Use graceful shutdown with a reasonable timeout -TimeoutStopSec=60s +TimeoutStopSec=120s # Make /usr, /boot, /etc and possibly some more folders read-only... ProtectSystem=full From 082d74eeb1f6eaee9edcda6f79695e714451c077 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Fri, 6 Jun 2025 06:44:17 +0200 Subject: [PATCH 04/21] Install ARMv7 binary even when we detect a 64bit (aarch64) CPU but the operating system is 32bit. See FTL#2494 for reference Signed-off-by: DL6ER --- automated install/basic-install.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 279dc1d1..fcacf96d 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -1849,9 +1849,18 @@ get_binary_name() { # If the machine is aarch64 (armv8) if [[ "${machine}" == "aarch64" ]]; then - # If AArch64 is found (e.g., BCM2711 in Raspberry Pi 4) - printf "%b %b Detected AArch64 (64 Bit ARM) architecture\\n" "${OVER}" "${TICK}" - l_binary="pihole-FTL-arm64" + if [[ "$(getconf LONG_BIT)" == "64" ]]; then + # If the OS is 64 bit, we use the arm64 binary + printf "%b %b Detected AArch64 (64 Bit ARM) architecture\\n" "${OVER}" "${TICK}" + l_binary="pihole-FTL-arm64" + else + # If the OS is 32 bit, we use the armv7 binary (aarch64 is actually armv8) + # Even though the machine is 64 bit capable, this makes debugging + # very hard as 32bit tools like gdb, etc. cannot analyze the 64 bit + # binary. See FTL issue #2494 for such an example. + printf "%b %b Detected AArch64 (64 Bit ARM) architecture with 32 bit OS\\n" "${OVER}" "${TICK}" + l_binary="pihole-FTL-armv7" + fi elif [[ "${machine}" == "arm"* ]]; then # ARM 32 bit # Get supported processor from other binaries installed on the system From 3f7f6f02948eb37751dcd7b29eca953ff2bc2804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 27 Feb 2025 12:00:25 +0100 Subject: [PATCH 05/21] Allow uses to skip binary check and installing FTL in case the use a self-compiled binary 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 | 34 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 86e74730..8a81deac 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -156,6 +156,7 @@ EOM # The runUnattended flag is one example of this repair=false runUnattended=false +PIHOLE_SKIP_FTL_CHECK=false # Check arguments for the undocumented flags for var in "$@"; do case "$var" in @@ -2224,12 +2225,16 @@ main() { # Check if there is a usable FTL binary available on this architecture - do # this early on as FTL is a hard dependency for Pi-hole - local funcOutput - funcOutput=$(get_binary_name) #Store output of get_binary_name here - # Abort early if this processor is not supported (get_binary_name returns empty string) - if [[ "${funcOutput}" == "" ]]; then - printf " %b Upgrade/install aborted\\n" "${CROSS}" "${DISTRO_NAME}" - exit 1 + # Allow the user to skip this check if they are using a self-compiled FTL binary from an unsupported architecture + if [ ! "${PIHOLE_SKIP_FTL_CHECK}" = true ]; then + # Get the binary name for the current architecture + local funcOutput + funcOutput=$(get_binary_name) #Store output of get_binary_name here + # Abort early if this processor is not supported (get_binary_name returns empty string) + if [[ "${funcOutput}" == "" ]]; then + printf " %b Upgrade/install aborted\\n" "${CROSS}" "${DISTRO_NAME}" + exit 1 + fi fi if [[ "${fresh_install}" == false ]]; then @@ -2271,13 +2276,16 @@ main() { create_pihole_user # Download and install FTL - local binary - binary="pihole-FTL${funcOutput##*pihole-FTL}" #binary name will be the last line of the output of get_binary_name (it always begins with pihole-FTL) - local theRest - theRest="${funcOutput%pihole-FTL*}" # Print the rest of get_binary_name's output to display (cut out from first instance of "pihole-FTL") - if ! FTLdetect "${binary}" "${theRest}"; then - printf " %b FTL Engine not installed\\n" "${CROSS}" - exit 1 + # Allow the user to skip this check if they are using a self-compiled FTL binary from an unsupported architecture + if [ ! "${PIHOLE_SKIP_FTL_CHECK}" = true ]; then + local binary + binary="pihole-FTL${funcOutput##*pihole-FTL}" #binary name will be the last line of the output of get_binary_name (it always begins with pihole-FTL) + local theRest + theRest="${funcOutput%pihole-FTL*}" # Print the rest of get_binary_name's output to display (cut out from first instance of "pihole-FTL") + if ! FTLdetect "${binary}" "${theRest}"; then + printf " %b FTL Engine not installed\\n" "${CROSS}" + exit 1 + fi fi # Install and log everything to a file From f67a8e51108e2c83019230688bfb141009524747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 3 Mar 2025 22:02:25 +0100 Subject: [PATCH 06/21] Only set PIHOLE_SKIP_FTL_CHECK if not already set by env variable 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, 3 insertions(+), 1 deletion(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 8a81deac..50123739 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -156,7 +156,9 @@ EOM # The runUnattended flag is one example of this repair=false runUnattended=false -PIHOLE_SKIP_FTL_CHECK=false +if [ -z "$PIHOLE_SKIP_FTL_CHECK" ]; then + PIHOLE_SKIP_FTL_CHECK=false +fi # Check arguments for the undocumented flags for var in "$@"; do case "$var" in From f3e04117f6fc1cb01a23adc1933cfde17df6c708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 3 Mar 2025 22:19:32 +0100 Subject: [PATCH 07/21] Let users know we skipped the FTL checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: davygravy Signed-off-by: Christian König --- automated install/basic-install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 50123739..4d475399 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -2228,7 +2228,7 @@ main() { # Check if there is a usable FTL binary available on this architecture - do # this early on as FTL is a hard dependency for Pi-hole # Allow the user to skip this check if they are using a self-compiled FTL binary from an unsupported architecture - if [ ! "${PIHOLE_SKIP_FTL_CHECK}" = true ]; then + if [ "${PIHOLE_SKIP_FTL_CHECK}" != true ]; then # Get the binary name for the current architecture local funcOutput funcOutput=$(get_binary_name) #Store output of get_binary_name here @@ -2237,6 +2237,8 @@ main() { printf " %b Upgrade/install aborted\\n" "${CROSS}" "${DISTRO_NAME}" exit 1 fi + else + printf " %b %bPIHOLE_SKIP_FTL_CHECK env variable set to true - skipping architecture check%b\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}" fi if [[ "${fresh_install}" == false ]]; then @@ -2279,7 +2281,7 @@ main() { # Download and install FTL # Allow the user to skip this check if they are using a self-compiled FTL binary from an unsupported architecture - if [ ! "${PIHOLE_SKIP_FTL_CHECK}" = true ]; then + if [ "${PIHOLE_SKIP_FTL_CHECK}" != true ]; then local binary binary="pihole-FTL${funcOutput##*pihole-FTL}" #binary name will be the last line of the output of get_binary_name (it always begins with pihole-FTL) local theRest @@ -2288,6 +2290,8 @@ main() { printf " %b FTL Engine not installed\\n" "${CROSS}" exit 1 fi + else + printf " %b %bPIHOLE_SKIP_FTL_CHECK env variable set to true - skipping FTL binary installation%b\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}" fi # Install and log everything to a file From 463086ef23e7e4c0fd1d7b182e15a913565a1700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 8 Mar 2025 14:38:00 +0100 Subject: [PATCH 08/21] Skip FTL update check if $PIHOLE_SKIP_FTL_CHECK is set to true 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 | 52 +++++++++++++++++------------- automated install/basic-install.sh | 4 +-- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index 4e0d973e..eb9e7829 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -149,31 +149,37 @@ main() { echo -e " ${INFO} Web Interface:\\t${COL_GREEN}up to date${COL_NC}" fi - local funcOutput - funcOutput=$(get_binary_name) #Store output of get_binary_name here - local binary - binary="pihole-FTL${funcOutput##*pihole-FTL}" #binary name will be the last line of the output of get_binary_name (it always begins with pihole-FTL) + # Allow the user to skip this check if they are using a self-compiled FTL binary from an unsupported architecture + if [ "${PIHOLE_SKIP_FTL_CHECK}" != true ]; then + local funcOutput + funcOutput=$(get_binary_name) #Store output of get_binary_name here + local binary + binary="pihole-FTL${funcOutput##*pihole-FTL}" #binary name will be the last line of the output of get_binary_name (it always begins with pihole-FTL) - if FTLcheckUpdate "${binary}" &>/dev/null; then - FTL_update=true - echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}update available${COL_NC}" + if FTLcheckUpdate "${binary}" &>/dev/null; then + FTL_update=true + echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}update available${COL_NC}" + else + case $? in + 1) + echo -e " ${INFO} FTL:\\t\\t${COL_GREEN}up to date${COL_NC}" + ;; + 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}" + exit 1 + ;; + *) + echo -e " ${INFO} FTL:\\t\\t${COL_RED}Something has gone wrong, contact support${COL_NC}" + exit 1 + esac + FTL_update=false + fi else - case $? in - 1) - echo -e " ${INFO} FTL:\\t\\t${COL_GREEN}up to date${COL_NC}" - ;; - 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}" - exit 1 - ;; - *) - echo -e " ${INFO} FTL:\\t\\t${COL_RED}Something has gone wrong, contact support${COL_NC}" - exit 1 - esac + echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}PIHOLE_SKIP_FTL_CHECK env variable set to true - update check skipped${COL_NC}" FTL_update=false fi diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 4d475399..0ab163ae 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -2238,7 +2238,7 @@ main() { exit 1 fi else - printf " %b %bPIHOLE_SKIP_FTL_CHECK env variable set to true - skipping architecture check%b\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}" + printf " %b %bPIHOLE_SKIP_FTL_CHECK env variable set to true - skipping architecture check%b\\n" "${INFO}" "${COL_YELLOW}" "${COL_NC}" fi if [[ "${fresh_install}" == false ]]; then @@ -2291,7 +2291,7 @@ main() { exit 1 fi else - printf " %b %bPIHOLE_SKIP_FTL_CHECK env variable set to true - skipping FTL binary installation%b\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}" + printf " %b %bPIHOLE_SKIP_FTL_CHECK env variable set to true - skipping FTL binary installation%b\\n" "${INFO}" "${COL_YELLOW}" "${COL_NC}" fi # Install and log everything to a file From 95021fce5866003015e63ce9f2b529a18e0aedf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 16 Jul 2025 21:00:05 +0200 Subject: [PATCH 09/21] Fix permission for *.etag files after gravity run 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, 4 insertions(+) diff --git a/gravity.sh b/gravity.sh index fd5d45de..da5aecfa 100755 --- a/gravity.sh +++ b/gravity.sh @@ -808,6 +808,10 @@ gravity_DownloadBlocklistFromUrl() { fix_owner_permissions "${saveLocation}" # Compare lists if they are identical compareLists "${adlistID}" "${saveLocation}" + # Set permissions for the *.etag file + if [[ -f "${saveLocation}.etag" ]]; then + fix_owner_permissions "${saveLocation}.etag" + fi # Add domains to database table file pihole-FTL "${gravity_type}" parseList "${saveLocation}" "${gravityTEMPfile}" "${adlistID}" done="true" From a8db4def9a42e564b61591f3e04e05cbb30edd5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Jul 2025 11:54:12 +0200 Subject: [PATCH 10/21] Use flag --skipFTL instead of env var PIHOLE_SKIP_FTL_CHECK 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 | 26 ++++++++++++++++++++------ automated install/basic-install.sh | 13 ++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index eb9e7829..67ac9693 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -150,7 +150,7 @@ main() { fi # Allow the user to skip this check if they are using a self-compiled FTL binary from an unsupported architecture - if [ "${PIHOLE_SKIP_FTL_CHECK}" != true ]; then + if [ "${skipFTL}" != true ]; then local funcOutput funcOutput=$(get_binary_name) #Store output of get_binary_name here local binary @@ -179,7 +179,7 @@ main() { FTL_update=false fi else - echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}PIHOLE_SKIP_FTL_CHECK env variable set to true - update check skipped${COL_NC}" + echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}--skipFTL set - update check skipped${COL_NC}" FTL_update=false fi @@ -228,7 +228,14 @@ main() { fi if [[ "${FTL_update}" == true || "${core_update}" == true ]]; then - ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --repair --unattended || \ + local addionalFlag + + if [[ ${skipFTL} == true ]]; then + addionalFlag="--skipFTL" + else + addionalFlag="" + fi + ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --repair --unattended ${addionalFlag} || \ echo -e "${basicError}" && exit 1 fi @@ -248,8 +255,15 @@ main() { exit 0 } -if [[ "$1" == "--check-only" ]]; then - CHECK_ONLY=true -fi +CHECK_ONLY=false +skipFTL=false + +# Check arguments +for var in "$@"; do + case "$var" in + "--check-only") CHECK_ONLY=true ;; + "--skipFTL") skipFTL=true ;; + esac +done main diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 0ab163ae..296730b0 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -156,14 +156,13 @@ EOM # The runUnattended flag is one example of this repair=false runUnattended=false -if [ -z "$PIHOLE_SKIP_FTL_CHECK" ]; then - PIHOLE_SKIP_FTL_CHECK=false -fi +skipFTL=false # Check arguments for the undocumented flags for var in "$@"; do case "$var" in "--repair") repair=true ;; "--unattended") runUnattended=true ;; + "--skipFTL") skipFTL=true ;; esac done @@ -2228,7 +2227,7 @@ main() { # Check if there is a usable FTL binary available on this architecture - do # this early on as FTL is a hard dependency for Pi-hole # Allow the user to skip this check if they are using a self-compiled FTL binary from an unsupported architecture - if [ "${PIHOLE_SKIP_FTL_CHECK}" != true ]; then + if [ "${skipFTL}" != true ]; then # Get the binary name for the current architecture local funcOutput funcOutput=$(get_binary_name) #Store output of get_binary_name here @@ -2238,7 +2237,7 @@ main() { exit 1 fi else - printf " %b %bPIHOLE_SKIP_FTL_CHECK env variable set to true - skipping architecture check%b\\n" "${INFO}" "${COL_YELLOW}" "${COL_NC}" + printf " %b %b--skipFTL set - skipping architecture check%b\\n" "${INFO}" "${COL_YELLOW}" "${COL_NC}" fi if [[ "${fresh_install}" == false ]]; then @@ -2281,7 +2280,7 @@ main() { # Download and install FTL # Allow the user to skip this check if they are using a self-compiled FTL binary from an unsupported architecture - if [ "${PIHOLE_SKIP_FTL_CHECK}" != true ]; then + if [ "${skipFTL}" != true ]; then local binary binary="pihole-FTL${funcOutput##*pihole-FTL}" #binary name will be the last line of the output of get_binary_name (it always begins with pihole-FTL) local theRest @@ -2291,7 +2290,7 @@ main() { exit 1 fi else - printf " %b %bPIHOLE_SKIP_FTL_CHECK env variable set to true - skipping FTL binary installation%b\\n" "${INFO}" "${COL_YELLOW}" "${COL_NC}" + printf " %b %b--skipFTL set - skipping FTL binary installation%b\\n" "${INFO}" "${COL_YELLOW}" "${COL_NC}" fi # Install and log everything to a file From a9e3d3b72841a63bef3e3f6df08d57b91807d4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Jul 2025 12:07:33 +0200 Subject: [PATCH 11/21] Use --skipFTL flag also for pihole repair and checkout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/piholeCheckout.sh | 18 +++++++++++++++++- pihole | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh index a6df46f2..deb07172 100755 --- a/advanced/Scripts/piholeCheckout.sh +++ b/advanced/Scripts/piholeCheckout.sh @@ -41,6 +41,22 @@ warning1() { } checkout() { + + local skipFTL additionalFlag + skipFTL=false + # Check arguments + for var in "$@"; do + case "$var" in + "--skipFTL") skipFTL=true ;; + esac + done + + if [ "${skipFTL}" == true ]; then + additionalFlag="--skipFTL" + else + additionalFlag="" + fi + local corebranches local webbranches @@ -235,7 +251,7 @@ checkout() { # Force updating everything if [[ ! "${1}" == "web" && ! "${1}" == "ftl" ]]; then echo -e " ${INFO} Running installer to upgrade your installation" - if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then + if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended ${additionalFlag}; then exit 0 else echo -e " ${COL_RED} Error: Unable to complete update, please contact support${COL_NC}" diff --git a/pihole b/pihole index c1566ed7..5c3377d3 100755 --- a/pihole +++ b/pihole @@ -115,7 +115,22 @@ repairPiholeFunc() { if [ -n "${DOCKER_VERSION}" ]; then unsupportedFunc else - /etc/.pihole/automated\ install/basic-install.sh --repair + local skipFTL additionalFlag + skipFTL=false + # Check arguments + for var in "$@"; do + case "$var" in + "--skipFTL") skipFTL=true ;; + esac + done + + if [ "${skipFTL}" == true ]; then + additionalFlag="--skipFTL" + else + additionalFlag="" + fi + + /etc/.pihole/automated\ install/basic-install.sh --repair ${additionalFlag} exit 0; fi } @@ -589,7 +604,7 @@ case "${1}" in "-d" | "debug" ) debugFunc "$@";; "-f" | "flush" ) flushFunc "$@";; "-up" | "updatePihole" ) updatePiholeFunc "$@";; - "-r" | "repair" ) repairPiholeFunc;; + "-r" | "repair" ) repairPiholeFunc "$@";; "-g" | "updateGravity" ) updateGravityFunc "$@";; "-l" | "logging" ) piholeLogging "$@";; "uninstall" ) uninstallFunc;; From 5ed52554d741061a6bb81cea477e4b9dbd340a5f Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Mon, 11 Aug 2025 14:51:59 +0100 Subject: [PATCH 12/21] Move unattended check to the top of the script - exit early if `/etc/pihole/pihole.toml` file is not found, Signed-off-by: Adam Warner --- automated install/basic-install.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index daacb9a3..35975844 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -167,6 +167,17 @@ for var in "$@"; do esac done +if [[ "${runUnattended}" == true ]]; then + # In order to run an unattended setup, a pre-seeded /etc/pihole/pihole.toml must exist + if [[ ! -f "${PI_HOLE_CONFIG_DIR}/pihole.toml" ]]; then + printf " %b Error: \"%s\" not found. Cannot run unattended setup\\n" "${CROSS}" "${PI_HOLE_CONFIG_DIR}/pihole.toml" + exit 1 + fi + printf " %b Performing unattended setup, no dialogs will be displayed\\n" "${INFO}" + # also disable debconf-apt-progress dialogs + export DEBIAN_FRONTEND="noninteractive" +fi + # If the color table file exists, if [[ -f "${coltable}" ]]; then # source it @@ -2242,15 +2253,6 @@ main() { exit 1 fi - 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}" - # also disable debconf-apt-progress dialogs - export DEBIAN_FRONTEND="noninteractive" - fi - fi - if [[ "${fresh_install}" == true ]]; then # Display welcome dialogs welcomeDialogs From a734733a87c731eb3ef77b3bd66336e087daaef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 18 Aug 2025 20:09:04 +0200 Subject: [PATCH 13/21] Disable log flush on docker container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- pihole | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pihole b/pihole index 5af46fa6..e6257b64 100755 --- a/pihole +++ b/pihole @@ -92,8 +92,12 @@ debugFunc() { } flushFunc() { - "${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh "$@" - exit 0 + if [ -n "${DOCKER_VERSION}" ]; then + unsupportedFunc + else + "${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh "$@" + exit 0 + fi } # Deprecated function, should be removed in the future From 12342682b425a9181d153673cc1d8c073efb91f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 21 Oct 2025 20:29:19 +0200 Subject: [PATCH 14/21] Separate log flush from log rotate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/piholeLogFlush.sh | 78 +++++++---------------------- advanced/Scripts/piholeLogRotate.sh | 72 ++++++++++++++++++++++++++ advanced/Templates/pihole.cron | 2 +- automated install/basic-install.sh | 2 +- manpages/pihole.8 | 15 +++++- pihole | 15 +++++- 6 files changed, 118 insertions(+), 66 deletions(-) create mode 100755 advanced/Scripts/piholeLogRotate.sh diff --git a/advanced/Scripts/piholeLogFlush.sh b/advanced/Scripts/piholeLogFlush.sh index ac28aed9..10b4f320 100755 --- a/advanced/Scripts/piholeLogFlush.sh +++ b/advanced/Scripts/piholeLogFlush.sh @@ -17,11 +17,6 @@ utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh" # shellcheck source="./advanced/Scripts/utils.sh" source "${utilsfile}" -# In case we're running at the same time as a system logrotate, use a -# separate logrotate state file to prevent stepping on each other's -# toes. -STATEFILE="/var/lib/logrotate/pihole" - # Determine database location DBFILE=$(getFTLConfigValue "files.database") if [ -z "$DBFILE" ]; then @@ -42,25 +37,6 @@ if [ -z "$WEBFILE" ]; then WEBFILE="/var/log/pihole/webserver.log" fi -# Helper function to handle log rotation for a single file -rotate_log() { - # This function copies x.log over to x.log.1 - # and then empties x.log - # Note that moving the file is not an option, as - # dnsmasq would happily continue writing into the - # moved file (it will have the same file handler) - local logfile="$1" - if [[ "$*" != *"quiet"* ]]; then - echo -ne " ${INFO} Rotating ${logfile} ..." - fi - cp -p "${logfile}" "${logfile}.1" - echo " " > "${logfile}" - chmod 640 "${logfile}" - if [[ "$*" != *"quiet"* ]]; then - echo -e "${OVER} ${TICK} Rotated ${logfile} ..." - fi -} - # Helper function to handle log flushing for a single file flush_log() { local logfile="$1" @@ -78,41 +54,23 @@ flush_log() { fi } -if [[ "$*" == *"once"* ]]; then - # Nightly logrotation - if command -v /usr/sbin/logrotate >/dev/null; then - # Logrotate once +# Manual flushing +flush_log "${LOGFILE}" +flush_log "${FTLFILE}" +flush_log "${WEBFILE}" - if [[ "$*" != *"quiet"* ]]; then - echo -ne " ${INFO} Running logrotate ..." - fi - mkdir -p "${STATEFILE%/*}" - /usr/sbin/logrotate --force --state "${STATEFILE}" /etc/pihole/logrotate - else - # Handle rotation for each log file - rotate_log "${LOGFILE}" - rotate_log "${FTLFILE}" - rotate_log "${WEBFILE}" - fi -else - # Manual flushing - flush_log "${LOGFILE}" - flush_log "${FTLFILE}" - flush_log "${WEBFILE}" - - if [[ "$*" != *"quiet"* ]]; then - echo -ne " ${INFO} Flushing database, DNS resolution temporarily unavailable ..." - fi - - # Stop FTL to make sure it doesn't write to the database while we're deleting data - service pihole-FTL stop - - # Delete most recent 24 hours from FTL's database, leave even older data intact (don't wipe out all history) - deleted=$(pihole-FTL sqlite3 -ni "${DBFILE}" "DELETE FROM query_storage WHERE timestamp >= strftime('%s','now')-86400; select changes() from query_storage limit 1") - - # Restart FTL - service pihole-FTL restart - if [[ "$*" != *"quiet"* ]]; then - echo -e "${OVER} ${TICK} Deleted ${deleted} queries from long-term query database" - fi +if [[ "$*" != *"quiet"* ]]; then + echo -ne " ${INFO} Flushing database, DNS resolution temporarily unavailable ..." +fi + +# Stop FTL to make sure it doesn't write to the database while we're deleting data +service pihole-FTL stop + +# Delete most recent 24 hours from FTL's database, leave even older data intact (don't wipe out all history) +deleted=$(pihole-FTL sqlite3 -ni "${DBFILE}" "DELETE FROM query_storage WHERE timestamp >= strftime('%s','now')-86400; select changes() from query_storage limit 1") + +# Restart FTL +service pihole-FTL restart +if [[ "$*" != *"quiet"* ]]; then + echo -e "${OVER} ${TICK} Deleted ${deleted} queries from long-term query database" fi diff --git a/advanced/Scripts/piholeLogRotate.sh b/advanced/Scripts/piholeLogRotate.sh new file mode 100755 index 00000000..b7de90ee --- /dev/null +++ b/advanced/Scripts/piholeLogRotate.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# Pi-hole: A black hole for Internet advertisements +# (c) 2025 Pi-hole, LLC (https://pi-hole.net) +# Network-wide ad blocking via your own hardware. +# +# Rotate Pi-hole's log file +# +# This file is copyright under the latest version of the EUPL. +# Please see LICENSE file for your rights under this license. + +colfile="/opt/pihole/COL_TABLE" +# shellcheck source="./advanced/Scripts/COL_TABLE" +source ${colfile} + +readonly PI_HOLE_SCRIPT_DIR="/opt/pihole" +utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh" +# shellcheck source="./advanced/Scripts/utils.sh" +source "${utilsfile}" + +# In case we're running at the same time as a system logrotate, use a +# separate logrotate state file to prevent stepping on each other's +# toes. +STATEFILE="/var/lib/logrotate/pihole" + + +# Determine log file location +LOGFILE=$(getFTLConfigValue "files.log.dnsmasq") +if [ -z "$LOGFILE" ]; then + LOGFILE="/var/log/pihole/pihole.log" +fi +FTLFILE=$(getFTLConfigValue "files.log.ftl") +if [ -z "$FTLFILE" ]; then + FTLFILE="/var/log/pihole/FTL.log" +fi +WEBFILE=$(getFTLConfigValue "files.log.webserver") +if [ -z "$WEBFILE" ]; then + WEBFILE="/var/log/pihole/webserver.log" +fi + +# Helper function to handle log rotation for a single file +rotate_log() { + # This function copies x.log over to x.log.1 + # and then empties x.log + # Note that moving the file is not an option, as + # dnsmasq would happily continue writing into the + # moved file (it will have the same file handler) + local logfile="$1" + if [[ "$*" != *"quiet"* ]]; then + echo -ne " ${INFO} Rotating ${logfile} ..." + fi + cp -p "${logfile}" "${logfile}.1" + echo " " > "${logfile}" + chmod 640 "${logfile}" + if [[ "$*" != *"quiet"* ]]; then + echo -e "${OVER} ${TICK} Rotated ${logfile} ..." + fi +} + +# Nightly logrotation +if command -v /usr/sbin/logrotate >/dev/null; then + # Logrotate once + if [[ "$*" != *"quiet"* ]]; then + echo -ne " ${INFO} Running logrotate ..." + fi + mkdir -p "${STATEFILE%/*}" + /usr/sbin/logrotate --force --state "${STATEFILE}" /etc/pihole/logrotate +else + # Handle rotation for each log file + rotate_log "${LOGFILE}" + rotate_log "${FTLFILE}" + rotate_log "${WEBFILE}" +fi diff --git a/advanced/Templates/pihole.cron b/advanced/Templates/pihole.cron index c62d31ab..3b71cbff 100644 --- a/advanced/Templates/pihole.cron +++ b/advanced/Templates/pihole.cron @@ -24,7 +24,7 @@ # The flush script will use logrotate if available # parameter "once": logrotate only once (default is twice) # parameter "quiet": don't print messages -00 00 * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole flush once quiet +00 00 * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole logrotate quiet @reboot root /usr/sbin/logrotate --state /var/lib/logrotate/pihole /etc/pihole/logrotate diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index a4c04158..65464b9e 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -84,7 +84,7 @@ webInterfaceDir="${webroot}/admin" piholeGitUrl="https://github.com/pi-hole/pi-hole.git" PI_HOLE_LOCAL_REPO="/etc/.pihole" # List of pihole scripts, stored in an array -PI_HOLE_FILES=(list piholeDebug piholeLogFlush setupLCD update version gravity uninstall webpage) +PI_HOLE_FILES=(list piholeDebug piholeLogFlush piholeLogRotate setupLCD update version gravity uninstall webpage) # This directory is where the Pi-hole scripts will be installed PI_HOLE_INSTALL_DIR="/opt/pihole" PI_HOLE_CONFIG_DIR="/etc/pihole" diff --git a/manpages/pihole.8 b/manpages/pihole.8 index ac3146ba..191691ee 100644 --- a/manpages/pihole.8 +++ b/manpages/pihole.8 @@ -100,9 +100,12 @@ Available commands and options: -c Include a Pi-hole database integrity check .br -\fB-f, flush\fR +\fB-f, flush\fR [quite] .br - Flush the Pi-hole log + Flush the Pi-hole log and last 24h from the query database +.br + + quite Suppress output .br \fB-r, repair\fR @@ -242,6 +245,14 @@ Available commands and options: verbose Show authentication and status messages .br +\fBlogrotate\fR [quite] +.br + Rotate Pi-hole's log files +.br + + quite Suppress output +.br + .SH "EXAMPLE" Some usage examples diff --git a/pihole b/pihole index e6257b64..4fe09418 100755 --- a/pihole +++ b/pihole @@ -92,6 +92,7 @@ debugFunc() { } flushFunc() { + # unsupported in docker because it requires restarting FTL if [ -n "${DOCKER_VERSION}" ]; then unsupportedFunc else @@ -109,6 +110,11 @@ arpFunc() { exit 0 } +logrotateFunc() { + "${PI_HOLE_SCRIPT_DIR}"/piholeLogRotate.sh "$@" + exit 0 +} + networkFlush() { shift "${PI_HOLE_SCRIPT_DIR}"/piholeNetworkFlush.sh "$@" @@ -506,7 +512,8 @@ Debugging Options: -d, debug Start a debugging session Add '-c' or '--check-database' to include a Pi-hole database integrity check Add '-a' to automatically upload the log to tricorder.pi-hole.net - -f, flush Flush the Pi-hole log + -f, flush Flush the Pi-hole logs and last 24h from the query database + Add 'quiet' to suppress output messages -r, repair Repair Pi-hole subsystems -t, tail [arg] View the live output of the Pi-hole log. Add an optional argument to filter the log @@ -539,7 +546,9 @@ Options: checkout Switch Pi-hole subsystems to a different GitHub branch Add '-h' for more info on checkout usage networkflush Flush information stored in Pi-hole's network tables - Add '--arp' to additionally flush the ARP table "; + Add '--arp' to additionally flush the ARP table + logrotate Rotate Pi-hole's log files + Add 'quiet' to suppress output messages"; exit 0 } @@ -582,6 +591,7 @@ case "${1}" in "arpflush" ) need_root=true;; # Deprecated, use networkflush instead "networkflush" ) need_root=true;; "-t" | "tail" ) need_root=true;; + "logrotate" ) need_root=true;; * ) helpFunc;; esac @@ -617,5 +627,6 @@ case "${1}" in "arpflush" ) arpFunc "$@";; # Deprecated, use networkflush instead "networkflush" ) networkFlush "$@";; "-t" | "tail" ) tailFunc "$2";; + "logrotate" ) logrotateFunc "$@";; * ) helpFunc;; esac From b2e56662c0d4cf4393fff58f181b8c3167745155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 22 Oct 2025 20:25:42 +0200 Subject: [PATCH 15/21] Loose requirements for local file access for gravity Signed-off-by: yubiuser --- gravity.sh | 53 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/gravity.sh b/gravity.sh index 5720ca41..1e394811 100755 --- a/gravity.sh +++ b/gravity.sh @@ -612,7 +612,7 @@ compareLists() { gravity_DownloadBlocklistFromUrl() { local url="${1}" adlistID="${2}" saveLocation="${3}" compression="${4}" gravity_type="${5}" domain="${6}" local listCurlBuffer str httpCode success="" ip customUpstreamResolver="" - local file_path permissions ip_addr port blocked=false download=true + local file_path 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=() @@ -721,29 +721,40 @@ gravity_DownloadBlocklistFromUrl() { fi fi - # If we are going to "download" a local file, we first check if the target - # file has a+r permission. We explicitly check for all+read because we want - # to make sure that the file is readable by everyone and not just the user - # running the script. - if [[ $url == "file://"* ]]; then + # If we "download" a local file (file://), verify read access before using it. + # When running as root (e.g., via pihole -g), check that the 'pihole' user can read the file + # to match the effective runtime user of FTL; otherwise, check the current user's read access + # (e.g., in Docker or when invoked by a non-root user). The target must + # resolve to a regular file and be readable by the evaluated user. + if [[ "${url}" == "file://"* ]]; then # Get the file path - file_path=$(echo "$url" | cut -d'/' -f3-) + file_path=$(echo "${url}" | cut -d'/' -f3-) # Check if the file exists and is a regular file (i.e. not a socket, fifo, tty, block). Might still be a symlink. - if [[ ! -f $file_path ]]; then - # Output that the file does not exist - echo -e "${OVER} ${CROSS} ${file_path} does not exist" - download=false - else - # Check if the file or a file referenced by the symlink has a+r permissions - permissions=$(stat -L -c "%a" "$file_path") - if [[ $permissions == *4 || $permissions == *5 || $permissions == *6 || $permissions == *7 ]]; then - # Output that we are using the local file - echo -e "${OVER} ${INFO} Using local file ${file_path}" - else - # Output that the file does not have the correct permissions - echo -e "${OVER} ${CROSS} Cannot read file (file needs to have a+r permission)" + if [[ ! -f ${file_path} ]]; then + # Output that the file does not exist + echo -e "${OVER} ${CROSS} ${file_path} does not exist" download=false - fi + else + if [ "$(id -un)" == "root" ]; then + # If we are root, we need to check if the pihole user has read permission + # otherwise, we might read files that the pihole user should not be able to read + if sudo -u pihole test -r "${file_path}"; then + echo -e "${OVER} ${INFO} Using local file ${file_path}" + else + echo -e "${OVER} ${CROSS} Cannot read file (user 'pihole' lacks read permission)" + download=false + fi + else + # If we are not root, we just check if the current user has read permission + if [[ -r "${file_path}" ]]; then + # Output that we are using the local file + echo -e "${OVER} ${INFO} Using local file ${file_path}" + else + # Output that the file is not readable by the current user + echo -e "${OVER} ${CROSS} Cannot read file (current user '$(id -un)' lacks read permission)" + download=false + fi + fi fi fi From 11344c39f5bbc960bb343f7e95a45d0d0090c7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 23 Oct 2025 22:09:55 +0200 Subject: [PATCH 16/21] Prevent URLs like file:/./ to circumvent permission check 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 1e394811..8f1005a0 100755 --- a/gravity.sh +++ b/gravity.sh @@ -726,7 +726,7 @@ gravity_DownloadBlocklistFromUrl() { # to match the effective runtime user of FTL; otherwise, check the current user's read access # (e.g., in Docker or when invoked by a non-root user). The target must # resolve to a regular file and be readable by the evaluated user. - if [[ "${url}" == "file://"* ]]; then + if [[ "${url}" == "file:/"* ]]; then # Get the file path file_path=$(echo "${url}" | cut -d'/' -f3-) # Check if the file exists and is a regular file (i.e. not a socket, fifo, tty, block). Might still be a symlink. From 527895a377b60877d21b9d3ef3d1a4e3738e3c82 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Fri, 24 Oct 2025 21:07:12 +0200 Subject: [PATCH 17/21] Fix indentation Co-authored-by: RD WebDesign Signed-off-by: yubiuser --- gravity.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gravity.sh b/gravity.sh index 8f1005a0..28fa5ead 100755 --- a/gravity.sh +++ b/gravity.sh @@ -736,9 +736,9 @@ gravity_DownloadBlocklistFromUrl() { download=false else if [ "$(id -un)" == "root" ]; then - # If we are root, we need to check if the pihole user has read permission - # otherwise, we might read files that the pihole user should not be able to read - if sudo -u pihole test -r "${file_path}"; then + # If we are root, we need to check if the pihole user has read permission + # otherwise, we might read files that the pihole user should not be able to read + if sudo -u pihole test -r "${file_path}"; then echo -e "${OVER} ${INFO} Using local file ${file_path}" else echo -e "${OVER} ${CROSS} Cannot read file (user 'pihole' lacks read permission)" From 7df117876faebeb38353cdd859513ce9a6e60798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 3 Nov 2025 22:23:12 +0100 Subject: [PATCH 18/21] Replace sudo with doas on alpine 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 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 0b186472..8dc4ae96 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -155,7 +155,7 @@ EOM ) # List of required packages on APK based systems -PIHOLE_META_VERSION_APK=0.1 +PIHOLE_META_VERSION_APK=0.2 PIHOLE_META_DEPS_APK=( bash bash-completion @@ -165,6 +165,8 @@ PIHOLE_META_DEPS_APK=( cronie curl dialog + doas # sudo replacement + doas-sudo-shim git grep iproute2-minimal # piholeARPTable.sh @@ -178,7 +180,6 @@ PIHOLE_META_DEPS_APK=( procps-ng psmisc shadow - sudo tzdata unzip wget From d765ce768f0769b2d21e6ee80201c322020c720a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 16 Feb 2026 20:09:58 +0100 Subject: [PATCH 19/21] Wipe version file before creating a new one Signed-off-by: yubiuser --- advanced/Scripts/updatecheck.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/advanced/Scripts/updatecheck.sh b/advanced/Scripts/updatecheck.sh index 44f21419..a54e5c9e 100755 --- a/advanced/Scripts/updatecheck.sh +++ b/advanced/Scripts/updatecheck.sh @@ -50,8 +50,12 @@ rm -f "/etc/pihole/GitHubVersions" rm -f "/etc/pihole/localbranches" rm -f "/etc/pihole/localversions" -# Create new versions file if it does not exist VERSION_FILE="/etc/pihole/versions" + +# Remove the version file if it exists +rm -f "${VERSION_FILE}" + +# Create new versions file touch "${VERSION_FILE}" chmod 644 "${VERSION_FILE}" From ac370146286b39a8d09ffa40a93a66c5942cae94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 18 Feb 2026 09:22:11 +0100 Subject: [PATCH 20/21] Truncate version file instead of removing and creating freshly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/updatecheck.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/advanced/Scripts/updatecheck.sh b/advanced/Scripts/updatecheck.sh index a54e5c9e..23abf7a6 100755 --- a/advanced/Scripts/updatecheck.sh +++ b/advanced/Scripts/updatecheck.sh @@ -52,11 +52,8 @@ rm -f "/etc/pihole/localversions" VERSION_FILE="/etc/pihole/versions" -# Remove the version file if it exists -rm -f "${VERSION_FILE}" - -# Create new versions file -touch "${VERSION_FILE}" +# Truncates the file to zero length if it exists to clear it up, otherwise creates an empty file. +truncate -s 0 "${VERSION_FILE}" chmod 644 "${VERSION_FILE}" # if /pihole.docker.tag file exists, we will use it's value later in this script From 4125bcccdcf3de01a59157ff5a8aef59d4765161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 18 Feb 2026 09:25:10 +0100 Subject: [PATCH 21/21] Files should be created before calling addOrEditKeyValPair MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/utils.sh | 3 --- test/test_any_utils.py | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/advanced/Scripts/utils.sh b/advanced/Scripts/utils.sh index d000a6db..51f5db36 100755 --- a/advanced/Scripts/utils.sh +++ b/advanced/Scripts/utils.sh @@ -30,9 +30,6 @@ addOrEditKeyValPair() { local key="${2}" local value="${3}" - # touch file to prevent grep error if file does not exist yet - touch "${file}" - if grep -q "^${key}=" "${file}"; then # Key already exists in file, modify the value sed -i "/^${key}=/c\\${key}=${value}" "${file}" diff --git a/test/test_any_utils.py b/test/test_any_utils.py index 43e637f3..e4646572 100644 --- a/test/test_any_utils.py +++ b/test/test_any_utils.py @@ -2,6 +2,7 @@ def test_key_val_replacement_works(host): """Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file""" host.run(""" source /opt/pihole/utils.sh + touch ./testoutput addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1" addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2" addOrEditKeyValPair "./testoutput" "KEY_ONE" "value3"