Compare commits

..

2 Commits

Author SHA1 Message Date
Christian König 12342682b4 Separate log flush from log rotate
CodeQL / Analyze (pull_request) Has been cancelled
Test Supported Distributions / smoke-tests (pull_request) Has been cancelled
Test Supported Distributions / distro-test (alpine_3_21) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (alpine_3_22) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (centos_10) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (centos_9) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (debian_11) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (debian_12) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (debian_13) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (fedora_40) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (fedora_41) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (fedora_42) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (ubuntu_20) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (ubuntu_22) (pull_request) Has been cancelled
Test Supported Distributions / distro-test (ubuntu_24) (pull_request) Has been cancelled
Signed-off-by: Christian König <github@yubiuser.dev>
2025-10-21 20:47:53 +02:00
Christian König a734733a87 Disable log flush on docker container
Signed-off-by: Christian König <github@yubiuser.dev>
2025-10-21 20:41:18 +02:00
17 changed files with 204 additions and 174 deletions
+4 -4
View File
@@ -25,16 +25,16 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
# Initializes the CodeQL tools for scanning.
-
name: Initialize CodeQL
uses: github/codeql-action/init@e12f0178983d466f2f6028f5cc7a6d786fd97f4b #v4.31.4
uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 #v4.30.9
with:
languages: 'python'
-
name: Autobuild
uses: github/codeql-action/autobuild@e12f0178983d466f2f6028f5cc7a6d786fd97f4b #v4.31.4
uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 #v4.30.9
-
name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@e12f0178983d466f2f6028f5cc7a6d786fd97f4b #v4.31.4
uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 #v4.30.9
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
- name: Remove 'stale' label
run: gh issue edit ${{ github.event.issue.number }} --remove-label ${{ env.stale_label }}
env:
+1 -1
View File
@@ -33,7 +33,7 @@ jobs:
name: Syncing branches
steps:
- name: Checkout
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
- name: Opening pull request
run: gh pr create -B development -H master --title 'Sync master back into development' --body 'Created by Github action' --label 'internal'
env:
+5 -6
View File
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
with:
fetch-depth: 0 # Differential ShellCheck requires full git history
@@ -38,18 +38,18 @@ jobs:
- name: Spell-Checking
uses: codespell-project/actions-codespell@8f01853be192eb0f849a5c7d721450e7a467c579 #v2.2
uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 #v2.1
with:
ignore_words_file: .codespellignore
- name: Get editorconfig-checker
uses: editorconfig-checker/action-editorconfig-checker@4b6cd6190d435e7e084fb35e36a096e98506f7b9 #v2.1.0
uses: editorconfig-checker/action-editorconfig-checker@5ecdd656fe347c26f76b1b435b90e1d74fb5e787 # tag v2. is really out of date
- name: Run editorconfig-checker
run: editorconfig-checker
- name: Check python code formatting with black
uses: psf/black@05f0a8ce1f71fbb36e1e032d3b518c7b945089a2 #25.11.0
uses: psf/black@af0ba72a73598c76189d6dd1b21d8532255d5942 #25.9.0
with:
src: "./test"
options: "--check --diff --color"
@@ -74,7 +74,6 @@ jobs:
fedora_40,
fedora_41,
fedora_42,
fedora_43,
alpine_3_21,
alpine_3_22,
]
@@ -82,7 +81,7 @@ jobs:
DISTRO: ${{matrix.distro}}
steps:
- name: Checkout repository
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
- name: Set up Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #v6.0.0
+57 -46
View File
@@ -593,21 +593,18 @@ check_required_ports() {
# Add port 53
ports_configured+=("53")
local protocol_type port_number service_name
# Now that we have the values stored,
for i in "${!ports_in_use[@]}"; do
# loop through them and assign some local variables
read -r protocol_type port_number service_name <<< "$(
awk '{
p=$1; n=$5; s=$7
gsub(/users:\(\("/,"",s)
gsub(/".*/,"",s)
print p, n, s
}' <<< "${ports_in_use[$i]}"
)"
local service_name
service_name=$(echo "${ports_in_use[$i]}" | awk '{gsub(/users:\(\("/,"",$7);gsub(/".*/,"",$7);print $7}')
local protocol_type
protocol_type=$(echo "${ports_in_use[$i]}" | awk '{print $1}')
local port_number
port_number="$(echo "${ports_in_use[$i]}" | awk '{print $5}')" # | awk '{gsub(/^.*:/,"",$5);print $5}')
# Check if the right services are using the right ports
if [[ ${ports_configured[*]} =~ ${port_number##*:} ]]; then
if [[ ${ports_configured[*]} =~ $(echo "${port_number}" | rev | cut -d: -f1 | rev) ]]; then
compare_port_to_service_assigned "${ftl}" "${service_name}" "${protocol_type}:${port_number}"
else
# If it's not a default port that Pi-hole needs, just print it out for the user to see
@@ -725,7 +722,7 @@ dig_at() {
fi
# Check if Pi-hole can use itself to block a domain
if local_dig="$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @"${local_address}" "${record_type}" -p "$(get_ftl_conf_value "dns.port")")"; then
if local_dig="$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @"${local_address}" "${record_type}")"; then
# If it can, show success
if [[ "${local_dig}" == *"status: NOERROR"* ]]; then
local_dig="NOERROR"
@@ -819,27 +816,42 @@ ftl_full_status(){
make_array_from_file() {
local filename="${1}"
# If the file is a directory do nothing since it cannot be parsed
[[ -d "${filename}" ]] && return
# The second argument can put a limit on how many line should be read from the file
# Since some of the files are so large, this is helpful to limit the output
local limit=${2}
# A local iterator for testing if we are at the limit above
local i=0
# If the file is a directory
if [[ -d "${filename}" ]]; then
# do nothing since it cannot be parsed
:
else
# Otherwise, read the file line by line
while IFS= read -r line;do
# Otherwise, strip out comments and blank lines
new_line=$(echo "${line}" | sed -e 's/^\s*#.*$//' -e '/^$/d')
# If the line still has content (a non-zero value)
if [[ -n "${new_line}" ]]; then
# Process the file, strip out comments and blank lines
local processed
processed=$(sed -e 's/^\s*#.*$//' -e '/^$/d' "${filename}")
# If the string contains "### CHANGED", highlight this part in red
if [[ "${new_line}" == *"### CHANGED"* ]]; then
new_line="${new_line//### CHANGED/${COL_RED}### CHANGED${COL_NC}}"
fi
while IFS= read -r line; do
# If the string contains "### CHANGED", highlight this part in red
log_write " ${line//### CHANGED/${COL_RED}### CHANGED${COL_NC}}"
((i++))
# if the limit of lines we want to see is exceeded do nothing
[[ -n ${limit} && $i -eq ${limit} ]] && break
done <<< "$processed"
# Finally, write this line to the log
log_write " ${new_line}"
fi
# Increment the iterator +1
i=$((i+1))
# but if the limit of lines we want to see is exceeded
if [[ -z ${limit} ]]; then
# do nothing
:
elif [[ $i -eq ${limit} ]]; then
break
fi
done < "${filename}"
fi
}
parse_file() {
@@ -912,38 +924,38 @@ list_files_in_dir() {
fi
# Store the files found in an array
local files_found=("${dir_to_parse}"/*)
mapfile -t files_found < <(ls "${dir_to_parse}")
# For each file in the array,
for each_file in "${files_found[@]}"; do
if [[ -d "${each_file}" ]]; then
if [[ -d "${dir_to_parse}/${each_file}" ]]; then
# If it's a directory, do nothing
:
elif [[ "${each_file}" == "${PIHOLE_DEBUG_LOG}" ]] || \
[[ "${each_file}" == "${PIHOLE_RAW_BLOCKLIST_FILES}" ]] || \
[[ "${each_file}" == "${PIHOLE_INSTALL_LOG_FILE}" ]] || \
[[ "${each_file}" == "${PIHOLE_LOG}" ]] || \
[[ "${each_file}" == "${PIHOLE_LOG_GZIPS}" ]]; then
elif [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_DEBUG_LOG}" ]] || \
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_RAW_BLOCKLIST_FILES}" ]] || \
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_INSTALL_LOG_FILE}" ]] || \
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG}" ]] || \
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG_GZIPS}" ]]; then
:
elif [[ "${dir_to_parse}" == "${DNSMASQ_D_DIRECTORY}" ]]; then
# in case of the dnsmasq directory include all files in the debug output
log_write "\\n${COL_GREEN}$(ls -lhd "${each_file}")${COL_NC}"
make_array_from_file "${each_file}"
log_write "\\n${COL_GREEN}$(ls -lhd "${dir_to_parse}"/"${each_file}")${COL_NC}"
make_array_from_file "${dir_to_parse}/${each_file}"
else
# Then, parse the file's content into an array so each line can be analyzed if need be
for i in "${!REQUIRED_FILES[@]}"; do
if [[ "${each_file}" == "${REQUIRED_FILES[$i]}" ]]; then
if [[ "${dir_to_parse}/${each_file}" == "${REQUIRED_FILES[$i]}" ]]; then
# display the filename
log_write "\\n${COL_GREEN}$(ls -lhd "${each_file}")${COL_NC}"
log_write "\\n${COL_GREEN}$(ls -lhd "${dir_to_parse}"/"${each_file}")${COL_NC}"
# Check if the file we want to view has a limit (because sometimes we just need a little bit of info from the file, not the entire thing)
case "${each_file}" in
case "${dir_to_parse}/${each_file}" in
# If it's Web server log, give the first and last 25 lines
"${PIHOLE_WEBSERVER_LOG}") head_tail_log "${each_file}" 25
"${PIHOLE_WEBSERVER_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 25
;;
# Same for the FTL log
"${PIHOLE_FTL_LOG}") head_tail_log "${each_file}" 35
"${PIHOLE_FTL_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 35
;;
# parse the file into an array in case we ever need to analyze it line-by-line
*) make_array_from_file "${each_file}";
*) make_array_from_file "${dir_to_parse}/${each_file}";
esac
else
# Otherwise, do nothing since it's not a file needed for Pi-hole so we don't care about it
@@ -979,7 +991,6 @@ head_tail_log() {
local filename="${1}"
# The number of lines to use for head and tail
local qty="${2}"
local filebasename="${filename##*/}"
local head_line
local tail_line
# Put the current Internal Field Separator into another variable so it can be restored later
@@ -988,14 +999,14 @@ head_tail_log() {
IFS=$'\r\n'
local log_head=()
mapfile -t log_head < <(head -n "${qty}" "${filename}")
log_write " ${COL_CYAN}-----head of ${filebasename}------${COL_NC}"
log_write " ${COL_CYAN}-----head of $(basename "${filename}")------${COL_NC}"
for head_line in "${log_head[@]}"; do
log_write " ${head_line}"
done
log_write ""
local log_tail=()
mapfile -t log_tail < <(tail -n "${qty}" "${filename}")
log_write " ${COL_CYAN}-----tail of ${filebasename}------${COL_NC}"
log_write " ${COL_CYAN}-----tail of $(basename "${filename}")------${COL_NC}"
for tail_line in "${log_tail[@]}"; do
log_write " ${tail_line}"
done
@@ -1069,15 +1080,15 @@ check_dhcp_servers() {
}
show_groups() {
show_db_entries "Groups" "SELECT id,CASE enabled WHEN '0' THEN ' no' WHEN '1' THEN ' yes' ELSE enabled END enabled,name,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,description FROM \"group\"" "4 7 50 19 19 50"
show_db_entries "Groups" "SELECT id,CASE enabled WHEN '0' THEN ' 0' WHEN '1' THEN ' 1' ELSE enabled END enabled,name,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,description FROM \"group\"" "4 7 50 19 19 50"
}
show_adlists() {
show_db_entries "Adlists" "SELECT id,CASE enabled WHEN '0' THEN ' no' WHEN '1' THEN ' yes' ELSE enabled END enabled,GROUP_CONCAT(adlist_by_group.group_id) group_ids, CASE type WHEN '0' THEN 'Block' WHEN '1' THEN 'Allow' ELSE type END type, address,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM adlist LEFT JOIN adlist_by_group ON adlist.id = adlist_by_group.adlist_id GROUP BY id;" "5 7 12 5 100 19 19 50"
show_db_entries "Adlists" "SELECT id,CASE enabled WHEN '0' THEN ' 0' WHEN '1' THEN ' 1' ELSE enabled END enabled,GROUP_CONCAT(adlist_by_group.group_id) group_ids,address,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM adlist LEFT JOIN adlist_by_group ON adlist.id = adlist_by_group.adlist_id GROUP BY id;" "5 7 12 100 19 19 50"
}
show_domainlist() {
show_db_entries "Domainlist" "SELECT id,CASE type WHEN '0' THEN 'exact-allow' WHEN '1' THEN 'exact-deny' WHEN '2' THEN 'regex-allow' WHEN '3' THEN 'regex-deny' ELSE type END type,CASE enabled WHEN '0' THEN ' no' WHEN '1' THEN ' yes' ELSE enabled END enabled,GROUP_CONCAT(domainlist_by_group.group_id) group_ids,domain,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM domainlist LEFT JOIN domainlist_by_group ON domainlist.id = domainlist_by_group.domainlist_id GROUP BY id;" "5 11 7 12 100 19 19 50"
show_db_entries "Domainlist (0/1 = exact allow-/denylist, 2/3 = regex allow-/denylist)" "SELECT id,CASE type WHEN '0' THEN '0 ' WHEN '1' THEN ' 1 ' WHEN '2' THEN ' 2 ' WHEN '3' THEN ' 3' ELSE type END type,CASE enabled WHEN '0' THEN ' 0' WHEN '1' THEN ' 1' ELSE enabled END enabled,GROUP_CONCAT(domainlist_by_group.group_id) group_ids,domain,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM domainlist LEFT JOIN domainlist_by_group ON domainlist.id = domainlist_by_group.domainlist_id GROUP BY id;" "5 4 7 12 100 19 19 50"
}
show_clients() {
+18 -60
View File
@@ -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
+72
View File
@@ -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
+3 -11
View File
@@ -8,20 +8,12 @@ utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
# Get file paths
FTL_PID_FILE="$(getFTLConfigValue files.pid)"
FTL_LOG_FILE="$(getFTLConfigValue files.log.ftl)"
PIHOLE_LOG_FILE="$(getFTLConfigValue files.log.dnsmasq)"
WEBSERVER_LOG_FILE="$(getFTLConfigValue files.log.webserver)"
FTL_PID_FILE="${FTL_PID_FILE:-/run/pihole-FTL.pid}"
FTL_LOG_FILE="${FTL_LOG_FILE:-/var/log/pihole/FTL.log}"
PIHOLE_LOG_FILE="${PIHOLE_LOG_FILE:-/var/log/pihole/pihole.log}"
WEBSERVER_LOG_FILE="${WEBSERVER_LOG_FILE:-/var/log/pihole/webserver.log}"
# Ensure that permissions are set so that pihole-FTL can edit all necessary files
mkdir -p /var/log/pihole
chown -R pihole:pihole /etc/pihole/ /var/log/pihole/
# allow all users read version file (and use pihole -v)
touch /etc/pihole/versions
chmod 0644 /etc/pihole/versions
# allow pihole to access subdirs in /etc/pihole (sets execution bit on dirs)
@@ -36,7 +28,7 @@ chown root:root /etc/pihole/logrotate
# Touch files to ensure they exist (create if non-existing, preserve if existing)
[ -f "${FTL_PID_FILE}" ] || install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}"
[ -f "${FTL_LOG_FILE}" ] || install -m 640 -o pihole -g pihole /dev/null "${FTL_LOG_FILE}"
[ -f "${PIHOLE_LOG_FILE}" ] || install -m 640 -o pihole -g pihole /dev/null "${PIHOLE_LOG_FILE}"
[ -f "${WEBSERVER_LOG_FILE}" ] || install -m 640 -o pihole -g pihole /dev/null "${WEBSERVER_LOG_FILE}"
[ -f /var/log/pihole/FTL.log ] || install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/FTL.log
[ -f /var/log/pihole/pihole.log ] || install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/pihole.log
[ -f /var/log/pihole/webserver.log ] || install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/webserver.log
[ -f /etc/pihole/dhcp.leases ] || install -m 644 -o pihole -g pihole /dev/null /etc/pihole/dhcp.leases
+1 -1
View File
@@ -13,7 +13,7 @@ extra_started_commands="reload"
respawn_max=5
respawn_period=60
capabilities="^CAP_NET_BIND_SERVICE,^CAP_NET_RAW,^CAP_NET_ADMIN,^CAP_SYS_NICE,^CAP_IPC_LOCK,^CAP_CHOWN,^CAP_SYS_TIME"
capabilities="^CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN,CAP_SYS_TIME"
depend() {
want net
+3 -3
View File
@@ -17,15 +17,15 @@ StartLimitIntervalSec=60s
[Service]
User=pihole
PermissionsStartOnly=true
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_NICE CAP_IPC_LOCK CAP_CHOWN CAP_SYS_TIME
# Run prestart with elevated permissions
ExecStartPre=+/opt/pihole/pihole-FTL-prestart.sh
ExecStartPre=/opt/pihole/pihole-FTL-prestart.sh
ExecStart=/usr/bin/pihole-FTL -f
Restart=on-failure
RestartSec=5s
ExecReload=/bin/kill -HUP $MAINPID
ExecStopPost=+/opt/pihole/pihole-FTL-poststop.sh
ExecStopPost=/opt/pihole/pihole-FTL-poststop.sh
# Use graceful shutdown with a reasonable timeout
TimeoutStopSec=60s
+1 -1
View File
@@ -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
+4 -5
View File
@@ -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"
@@ -116,11 +116,11 @@ c=70
PIHOLE_META_PACKAGE_CONTROL_APT=$(
cat <<EOM
Package: pihole-meta
Version: 0.6
Version: 0.5
Maintainer: Pi-hole team <adblock@pi-hole.net>
Architecture: all
Description: Pi-hole dependency meta package
Depends: awk,bash-completion,binutils,ca-certificates,cron|cron-daemon,curl,dialog,bind9-dnsutils|dnsutils,dns-root-data,git,grep,iproute2,iputils-ping,jq,libcap2,libcap2-bin,lshw,procps,psmisc,sudo,unzip
Depends: awk,bash-completion,binutils,ca-certificates,cron|cron-daemon,curl,dialog,dnsutils,dns-root-data,git,grep,iproute2,iputils-ping,jq,libcap2,libcap2-bin,lshw,procps,psmisc,sudo,unzip
Section: contrib/metapackages
Priority: optional
EOM
@@ -694,11 +694,10 @@ chooseInterface() {
status="OFF"
done
# Disable check for double quote here as we are passing a string with spaces
# shellcheck disable=SC2086
PIHOLE_INTERFACE=$(dialog --no-shadow --keep-tite --output-fd 1 \
--cancel-label "Exit" --ok-label "Select" \
--radiolist "Choose An Interface (press space to toggle selection)" \
${r} ${c} "${interfaceCount}" ${interfacesList})
${r} ${c} "${interfaceCount}" "${interfacesList}")
result=$?
case ${result} in
+13 -2
View File
@@ -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
+19 -4
View File
@@ -92,8 +92,13 @@ debugFunc() {
}
flushFunc() {
"${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh "$@"
exit 0
# unsupported in docker because it requires restarting FTL
if [ -n "${DOCKER_VERSION}" ]; then
unsupportedFunc
else
"${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh "$@"
exit 0
fi
}
# Deprecated function, should be removed in the future
@@ -105,6 +110,11 @@ arpFunc() {
exit 0
}
logrotateFunc() {
"${PI_HOLE_SCRIPT_DIR}"/piholeLogRotate.sh "$@"
exit 0
}
networkFlush() {
shift
"${PI_HOLE_SCRIPT_DIR}"/piholeNetworkFlush.sh "$@"
@@ -502,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
@@ -535,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
}
@@ -578,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
@@ -613,5 +627,6 @@ case "${1}" in
"arpflush" ) arpFunc "$@";; # Deprecated, use networkflush instead
"networkflush" ) networkFlush "$@";;
"-t" | "tail" ) tailFunc "$2";;
"logrotate" ) logrotateFunc "$@";;
* ) helpFunc;;
esac
-17
View File
@@ -1,17 +0,0 @@
FROM fedora:43
RUN dnf install -y git initscripts
ENV GITDIR=/etc/.pihole
ENV SCRIPTDIR=/opt/pihole
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
ADD . $GITDIR
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $GITDIR/advanced/Scripts/COL_TABLE $SCRIPTDIR/
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV SKIP_INSTALL=true
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
+2 -2
View File
@@ -1,6 +1,6 @@
pyyaml == 6.0.3
pytest == 9.0.1
pytest == 8.4.2
pytest-xdist == 3.8.0
pytest-testinfra == 10.2.2
tox == 4.32.0
tox == 4.31.0
pytest-clarity == 1.0.1
-10
View File
@@ -1,10 +0,0 @@
[tox]
envlist = py3
[testenv]
allowlist_externals = docker
deps = -rrequirements.txt
setenv =
COLUMNS=120
commands = docker buildx build --load --progress plain -f _fedora_43.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py