mirror of
https://github.com/pi-hole/pi-hole
synced 2025-01-03 04:30:55 +00:00
Merge branch 'development-v6' into new/migrate_dnsmasq_conf
This commit is contained in:
commit
ed1a6278b7
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@ -29,12 +29,12 @@ jobs:
|
|||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
-
|
-
|
||||||
name: Initialize CodeQL
|
name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: 'python'
|
languages: 'python'
|
||||||
-
|
-
|
||||||
name: Autobuild
|
name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v2
|
uses: github/codeql-action/autobuild@v3
|
||||||
-
|
-
|
||||||
name: Perform CodeQL Analysis
|
name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
|
13
.github/workflows/stale.yml
vendored
13
.github/workflows/stale.yml
vendored
@ -17,20 +17,23 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v8.0.0
|
- uses: actions/stale@v9.0.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
days-before-stale: 30
|
days-before-stale: 30
|
||||||
days-before-close: 5
|
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-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: $stale_label
|
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'
|
||||||
exempt-all-issue-assignees: true
|
exempt-all-issue-assignees: true
|
||||||
operations-per-run: 300
|
operations-per-run: 300
|
||||||
close-issue-reason: 'not_planned'
|
close-issue-reason: 'not_planned'
|
||||||
|
|
||||||
remove_stale: # trigger "stale" removal immediately when stale issues are commented on
|
remove_stale:
|
||||||
if: github.event_name == 'issue_comment'
|
# trigger "stale" removal immediately when stale issues are commented on
|
||||||
|
# we need to explicitly check that the trigger does not run on comment on a PR as
|
||||||
|
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment-on-issues-only-or-pull-requests-only
|
||||||
|
if: ${{ !github.event.issue.pull_request && github.event_name != 'schedule' }}
|
||||||
permissions:
|
permissions:
|
||||||
contents: read # for actions/checkout
|
contents: read # for actions/checkout
|
||||||
issues: write # to edit issues label
|
issues: write # to edit issues label
|
||||||
@ -39,7 +42,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v4.1.1
|
||||||
- name: Remove 'stale' label
|
- name: Remove 'stale' label
|
||||||
run: gh issue edit ${{ github.event.issue.number }} --remove-label $stale_label
|
run: gh issue edit ${{ github.event.issue.number }} --remove-label ${{ env.stale_label }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
2
.github/workflows/stale_pr.yml
vendored
2
.github/workflows/stale_pr.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v8.0.0
|
- uses: actions/stale@v9.0.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# Do not automatically mark PR/issue as stale
|
# Do not automatically mark PR/issue as stale
|
||||||
|
7
.github/workflows/test.yml
vendored
7
.github/workflows/test.yml
vendored
@ -64,9 +64,8 @@ jobs:
|
|||||||
ubuntu_23,
|
ubuntu_23,
|
||||||
centos_8,
|
centos_8,
|
||||||
centos_9,
|
centos_9,
|
||||||
fedora_36,
|
fedora_38,
|
||||||
fedora_37,
|
fedora_39,
|
||||||
fedora_38,
|
|
||||||
]
|
]
|
||||||
env:
|
env:
|
||||||
DISTRO: ${{matrix.distro}}
|
DISTRO: ${{matrix.distro}}
|
||||||
@ -75,7 +74,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Set up Python 3.10
|
- name: Set up Python 3.10
|
||||||
uses: actions/setup-python@v4.7.1
|
uses: actions/setup-python@v5.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
|
|
||||||
|
@ -21,20 +21,60 @@
|
|||||||
TestAPIAvailability() {
|
TestAPIAvailability() {
|
||||||
|
|
||||||
# as we are running locally, we can get the port value from FTL directly
|
# as we are running locally, we can get the port value from FTL directly
|
||||||
PORT="$(pihole-FTL --config webserver.port)"
|
local chaos_api_list availabilityResonse
|
||||||
PORT="${PORT%%,*}"
|
|
||||||
|
|
||||||
availabilityResonse=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${PORT}/api/auth")
|
# Query the API URLs from FTL using CHAOS TXT local.api.ftl
|
||||||
|
# The result is a space-separated enumeration of full URLs
|
||||||
|
# e.g., "http://localhost:80/api/" "https://localhost:443/api/"
|
||||||
|
chaos_api_list="$(dig +short chaos txt local.api.ftl @127.0.0.1)"
|
||||||
|
|
||||||
# test if http status code was 200 (OK) or 401 (authentication required)
|
# If the query was not successful, the variable is empty
|
||||||
if [ ! "${availabilityResonse}" = 200 ] && [ ! "${availabilityResonse}" = 401 ]; then
|
if [ -z "${chaos_api_list}" ]; then
|
||||||
echo "API not available at: http://localhost:${PORT}/api"
|
echo "API not available. Please check connectivity"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Iterate over space-separated list of URLs
|
||||||
|
while [ -n "${chaos_api_list}" ]; do
|
||||||
|
# Get the first URL
|
||||||
|
API_URL="${chaos_api_list%% *}"
|
||||||
|
# Strip leading and trailing quotes
|
||||||
|
API_URL="${API_URL%\"}"
|
||||||
|
API_URL="${API_URL#\"}"
|
||||||
|
|
||||||
|
# Test if the API is available at this URL
|
||||||
|
availabilityResonse=$(curl -skS -o /dev/null -w "%{http_code}" "${API_URL}auth")
|
||||||
|
|
||||||
|
# Test if http status code was 200 (OK) or 401 (authentication required)
|
||||||
|
if [ ! "${availabilityResonse}" = 200 ] && [ ! "${availabilityResonse}" = 401 ]; then
|
||||||
|
# API is not available at this port/protocol combination
|
||||||
|
API_PORT=""
|
||||||
|
else
|
||||||
|
# API is available at this URL combination
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove the first URL from the list
|
||||||
|
local last_api_list
|
||||||
|
last_api_list="${chaos_api_list}"
|
||||||
|
chaos_api_list="${chaos_api_list#* }"
|
||||||
|
|
||||||
|
# If the list did not change, we are at the last element
|
||||||
|
if [ "${last_api_list}" = "${chaos_api_list}" ]; then
|
||||||
|
# Remove the last element
|
||||||
|
chaos_api_list=""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# if API_PORT is empty, no working API port was found
|
||||||
|
if [ -n "${API_PORT}" ]; then
|
||||||
|
echo "API not available at: ${API_URL}"
|
||||||
echo "Exiting."
|
echo "Exiting."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
Authenthication() {
|
Authentication() {
|
||||||
# Try to authenticate
|
# Try to authenticate
|
||||||
LoginAPI
|
LoginAPI
|
||||||
|
|
||||||
@ -54,28 +94,27 @@ Authenthication() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LoginAPI() {
|
LoginAPI() {
|
||||||
sessionResponse="$(curl --silent -X POST "http://localhost:${PORT}/api/auth" --user-agent "Pi-hole cli " --data "{\"password\":\"${password}\"}" )"
|
sessionResponse="$(curl -skS -X POST "${API_URL}auth" --user-agent "Pi-hole cli " --data "{\"password\":\"${password}\"}" )"
|
||||||
|
|
||||||
if [ -z "${sessionResponse}" ]; then
|
if [ -z "${sessionResponse}" ]; then
|
||||||
echo "No response from FTL server. Please check connectivity"
|
echo "No response from FTL server. Please check connectivity"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# obtain validity and session ID from session response
|
# obtain validity and session ID from session response
|
||||||
validSession=$(echo "${sessionResponse}"| jq .session.valid 2>/dev/null)
|
validSession=$(echo "${sessionResponse}"| jq .session.valid 2>/dev/null)
|
||||||
SID=$(echo "${sessionResponse}"| jq --raw-output .session.sid 2>/dev/null)
|
SID=$(echo "${sessionResponse}"| jq --raw-output .session.sid 2>/dev/null)
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteSession() {
|
DeleteSession() {
|
||||||
# if a valid Session exists (no password required or successful authenthication) and
|
# if a valid Session exists (no password required or successful Authentication) and
|
||||||
# SID is not null (successful authenthication only), delete the session
|
# SID is not null (successful Authentication only), delete the session
|
||||||
if [ "${validSession}" = true ] && [ ! "${SID}" = null ]; then
|
if [ "${validSession}" = true ] && [ ! "${SID}" = null ]; then
|
||||||
# Try to delete the session. Omit the output, but get the http status code
|
# Try to delete the session. Omit the output, but get the http status code
|
||||||
deleteResponse=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE "http://localhost:${PORT}/api/auth" -H "Accept: application/json" -H "sid: ${SID}")
|
deleteResponse=$(curl -skS -o /dev/null -w "%{http_code}" -X DELETE "${API_URL}auth" -H "Accept: application/json" -H "sid: ${SID}")
|
||||||
|
|
||||||
case "${deleteResponse}" in
|
case "${deleteResponse}" in
|
||||||
"200") printf "%b" "A session that was not created cannot be deleted (e.g., empty API password).\n";;
|
"204") printf "%b" "Session successfully deleted.\n";;
|
||||||
"401") printf "%b" "Logout attempt without a valid session. Unauthorized!\n";;
|
"401") printf "%b" "Logout attempt without a valid session. Unauthorized!\n";;
|
||||||
"410") printf "%b" "Session successfully deleted.\n";;
|
|
||||||
esac;
|
esac;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -84,7 +123,7 @@ DeleteSession() {
|
|||||||
GetFTLData() {
|
GetFTLData() {
|
||||||
local data response status
|
local data response status
|
||||||
# get the data from querying the API as well as the http status code
|
# get the data from querying the API as well as the http status code
|
||||||
response=$(curl -s -w "%{http_code}" -X GET "http://localhost:${PORT}/api$1" -H "Accept: application/json" -H "sid: ${SID}" )
|
response=$(curl -skS -w "%{http_code}" -X GET "${API_URL}$1" -H "Accept: application/json" -H "sid: ${SID}" )
|
||||||
|
|
||||||
# status are the last 3 characters
|
# status are the last 3 characters
|
||||||
status=$(printf %s "${response#"${response%???}"}")
|
status=$(printf %s "${response#"${response%???}"}")
|
||||||
@ -93,7 +132,7 @@ GetFTLData() {
|
|||||||
|
|
||||||
if [ "${status}" = 200 ]; then
|
if [ "${status}" = 200 ]; then
|
||||||
# response OK
|
# response OK
|
||||||
echo "${data}"
|
printf %s "${data}"
|
||||||
elif [ "${status}" = 000 ]; then
|
elif [ "${status}" = 000 ]; then
|
||||||
# connection lost
|
# connection lost
|
||||||
echo "000"
|
echo "000"
|
||||||
|
@ -18,14 +18,19 @@ upgrade_gravityDB(){
|
|||||||
piholeDir="${2}"
|
piholeDir="${2}"
|
||||||
auditFile="${piholeDir}/auditlog.list"
|
auditFile="${piholeDir}/auditlog.list"
|
||||||
|
|
||||||
|
# Exit early if the database does not exist (e.g. in CI tests)
|
||||||
|
if [[ ! -f "${database}" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
# Get database version
|
# Get database version
|
||||||
version="$(pihole-FTL sqlite3 "${database}" "SELECT \"value\" FROM \"info\" WHERE \"property\" = 'version';")"
|
version="$(pihole-FTL sqlite3 -ni "${database}" "SELECT \"value\" FROM \"info\" WHERE \"property\" = 'version';")"
|
||||||
|
|
||||||
if [[ "$version" == "1" ]]; then
|
if [[ "$version" == "1" ]]; then
|
||||||
# This migration script upgrades the gravity.db file by
|
# This migration script upgrades the gravity.db file by
|
||||||
# adding the domain_audit table
|
# adding the domain_audit table
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 1 to 2"
|
echo -e " ${INFO} Upgrading gravity database from version 1 to 2"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/1_to_2.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/1_to_2.sql"
|
||||||
version=2
|
version=2
|
||||||
|
|
||||||
# Store audit domains in database table
|
# Store audit domains in database table
|
||||||
@ -40,28 +45,28 @@ upgrade_gravityDB(){
|
|||||||
# renaming the regex table to regex_blacklist, and
|
# renaming the regex table to regex_blacklist, and
|
||||||
# creating a new regex_whitelist table + corresponding linking table and views
|
# creating a new regex_whitelist table + corresponding linking table and views
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 2 to 3"
|
echo -e " ${INFO} Upgrading gravity database from version 2 to 3"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/2_to_3.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/2_to_3.sql"
|
||||||
version=3
|
version=3
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "3" ]]; then
|
if [[ "$version" == "3" ]]; then
|
||||||
# This migration script unifies the formally separated domain
|
# This migration script unifies the formally separated domain
|
||||||
# lists into a single table with a UNIQUE domain constraint
|
# lists into a single table with a UNIQUE domain constraint
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 3 to 4"
|
echo -e " ${INFO} Upgrading gravity database from version 3 to 4"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/3_to_4.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/3_to_4.sql"
|
||||||
version=4
|
version=4
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "4" ]]; then
|
if [[ "$version" == "4" ]]; then
|
||||||
# This migration script upgrades the gravity and list views
|
# This migration script upgrades the gravity and list views
|
||||||
# implementing necessary changes for per-client blocking
|
# implementing necessary changes for per-client blocking
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 4 to 5"
|
echo -e " ${INFO} Upgrading gravity database from version 4 to 5"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/4_to_5.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/4_to_5.sql"
|
||||||
version=5
|
version=5
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "5" ]]; then
|
if [[ "$version" == "5" ]]; then
|
||||||
# This migration script upgrades the adlist view
|
# This migration script upgrades the adlist view
|
||||||
# to return an ID used in gravity.sh
|
# to return an ID used in gravity.sh
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 5 to 6"
|
echo -e " ${INFO} Upgrading gravity database from version 5 to 6"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/5_to_6.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/5_to_6.sql"
|
||||||
version=6
|
version=6
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "6" ]]; then
|
if [[ "$version" == "6" ]]; then
|
||||||
@ -69,7 +74,7 @@ upgrade_gravityDB(){
|
|||||||
# which is automatically associated to all clients not
|
# which is automatically associated to all clients not
|
||||||
# having their own group assignments
|
# having their own group assignments
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 6 to 7"
|
echo -e " ${INFO} Upgrading gravity database from version 6 to 7"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/6_to_7.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/6_to_7.sql"
|
||||||
version=7
|
version=7
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "7" ]]; then
|
if [[ "$version" == "7" ]]; then
|
||||||
@ -77,21 +82,21 @@ upgrade_gravityDB(){
|
|||||||
# to ensure uniqueness on the group name
|
# to ensure uniqueness on the group name
|
||||||
# We also add date_added and date_modified columns
|
# We also add date_added and date_modified columns
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 7 to 8"
|
echo -e " ${INFO} Upgrading gravity database from version 7 to 8"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/7_to_8.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/7_to_8.sql"
|
||||||
version=8
|
version=8
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "8" ]]; then
|
if [[ "$version" == "8" ]]; then
|
||||||
# This migration fixes some issues that were introduced
|
# This migration fixes some issues that were introduced
|
||||||
# in the previous migration script.
|
# in the previous migration script.
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 8 to 9"
|
echo -e " ${INFO} Upgrading gravity database from version 8 to 9"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/8_to_9.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/8_to_9.sql"
|
||||||
version=9
|
version=9
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "9" ]]; then
|
if [[ "$version" == "9" ]]; then
|
||||||
# This migration drops unused tables and creates triggers to remove
|
# This migration drops unused tables and creates triggers to remove
|
||||||
# obsolete groups assignments when the linked items are deleted
|
# obsolete groups assignments when the linked items are deleted
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 9 to 10"
|
echo -e " ${INFO} Upgrading gravity database from version 9 to 10"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/9_to_10.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/9_to_10.sql"
|
||||||
version=10
|
version=10
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "10" ]]; then
|
if [[ "$version" == "10" ]]; then
|
||||||
@ -101,44 +106,57 @@ upgrade_gravityDB(){
|
|||||||
# to keep the copying process generic (needs the same columns in both the
|
# to keep the copying process generic (needs the same columns in both the
|
||||||
# source and the destination databases).
|
# source and the destination databases).
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 10 to 11"
|
echo -e " ${INFO} Upgrading gravity database from version 10 to 11"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/10_to_11.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/10_to_11.sql"
|
||||||
version=11
|
version=11
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "11" ]]; then
|
if [[ "$version" == "11" ]]; then
|
||||||
# Rename group 0 from "Unassociated" to "Default"
|
# Rename group 0 from "Unassociated" to "Default"
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 11 to 12"
|
echo -e " ${INFO} Upgrading gravity database from version 11 to 12"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/11_to_12.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/11_to_12.sql"
|
||||||
version=12
|
version=12
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "12" ]]; then
|
if [[ "$version" == "12" ]]; then
|
||||||
# Add column date_updated to adlist table
|
# Add column date_updated to adlist table
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 12 to 13"
|
echo -e " ${INFO} Upgrading gravity database from version 12 to 13"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/12_to_13.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/12_to_13.sql"
|
||||||
version=13
|
version=13
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "13" ]]; then
|
if [[ "$version" == "13" ]]; then
|
||||||
# Add columns number and status to adlist table
|
# Add columns number and status to adlist table
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 13 to 14"
|
echo -e " ${INFO} Upgrading gravity database from version 13 to 14"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/13_to_14.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/13_to_14.sql"
|
||||||
version=14
|
version=14
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "14" ]]; then
|
if [[ "$version" == "14" ]]; then
|
||||||
# Changes the vw_adlist created in 5_to_6
|
# Changes the vw_adlist created in 5_to_6
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 14 to 15"
|
echo -e " ${INFO} Upgrading gravity database from version 14 to 15"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/14_to_15.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/14_to_15.sql"
|
||||||
version=15
|
version=15
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "15" ]]; then
|
if [[ "$version" == "15" ]]; then
|
||||||
# Add column abp_entries to adlist table
|
# Add column abp_entries to adlist table
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 15 to 16"
|
echo -e " ${INFO} Upgrading gravity database from version 15 to 16"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/15_to_16.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/15_to_16.sql"
|
||||||
version=16
|
version=16
|
||||||
fi
|
fi
|
||||||
if [[ "$version" == "16" ]]; then
|
if [[ "$version" == "16" ]]; then
|
||||||
# Add antigravity table
|
# Add antigravity table
|
||||||
# Add column type to adlist table (to support adlist types)
|
# Add column type to adlist table (to support adlist types)
|
||||||
echo -e " ${INFO} Upgrading gravity database from version 16 to 17"
|
echo -e " ${INFO} Upgrading gravity database from version 16 to 17"
|
||||||
pihole-FTL sqlite3 "${database}" < "${scriptPath}/16_to_17.sql"
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/16_to_17.sql"
|
||||||
version=17
|
version=17
|
||||||
fi
|
fi
|
||||||
|
if [[ "$version" == "17" ]]; then
|
||||||
|
# Add adlist.id to vw_gravity and vw_antigravity
|
||||||
|
echo -e " ${INFO} Upgrading gravity database from version 17 to 18"
|
||||||
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/17_to_18.sql"
|
||||||
|
version=18
|
||||||
|
fi
|
||||||
|
if [[ "$version" == "18" ]]; then
|
||||||
|
# Modify DELETE triggers to delete BEFORE instead of AFTER to prevent
|
||||||
|
# foreign key constraint violations
|
||||||
|
echo -e " ${INFO} Upgrading gravity database from version 18 to 19"
|
||||||
|
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/18_to_19.sql"
|
||||||
|
version=19
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
25
advanced/Scripts/database_migration/gravity/17_to_18.sql
Normal file
25
advanced/Scripts/database_migration/gravity/17_to_18.sql
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.timeout 30000
|
||||||
|
|
||||||
|
PRAGMA FOREIGN_KEYS=OFF;
|
||||||
|
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
DROP VIEW vw_gravity;
|
||||||
|
CREATE VIEW vw_gravity AS SELECT domain, adlist.id AS adlist_id, adlist_by_group.group_id AS group_id
|
||||||
|
FROM gravity
|
||||||
|
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = gravity.adlist_id
|
||||||
|
LEFT JOIN adlist ON adlist.id = gravity.adlist_id
|
||||||
|
LEFT JOIN "group" ON "group".id = adlist_by_group.group_id
|
||||||
|
WHERE adlist.enabled = 1 AND (adlist_by_group.group_id IS NULL OR "group".enabled = 1);
|
||||||
|
|
||||||
|
DROP VIEW vw_antigravity;
|
||||||
|
CREATE VIEW vw_antigravity AS SELECT domain, adlist.id AS adlist_id, adlist_by_group.group_id AS group_id
|
||||||
|
FROM antigravity
|
||||||
|
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = antigravity.adlist_id
|
||||||
|
LEFT JOIN adlist ON adlist.id = antigravity.adlist_id
|
||||||
|
LEFT JOIN "group" ON "group".id = adlist_by_group.group_id
|
||||||
|
WHERE adlist.enabled = 1 AND (adlist_by_group.group_id IS NULL OR "group".enabled = 1) AND adlist.type = 1;
|
||||||
|
|
||||||
|
UPDATE info SET value = 18 WHERE property = 'version';
|
||||||
|
|
||||||
|
COMMIT;
|
27
advanced/Scripts/database_migration/gravity/18_to_19.sql
Normal file
27
advanced/Scripts/database_migration/gravity/18_to_19.sql
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
.timeout 30000
|
||||||
|
|
||||||
|
PRAGMA FOREIGN_KEYS=OFF;
|
||||||
|
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
DROP TRIGGER tr_domainlist_delete;
|
||||||
|
CREATE TRIGGER tr_domainlist_delete BEFORE DELETE ON domainlist
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM domainlist_by_group WHERE domainlist_id = OLD.id;
|
||||||
|
END;
|
||||||
|
|
||||||
|
DROP TRIGGER tr_adlist_delete;
|
||||||
|
CREATE TRIGGER tr_adlist_delete BEFORE DELETE ON adlist
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM adlist_by_group WHERE adlist_id = OLD.id;
|
||||||
|
END;
|
||||||
|
|
||||||
|
DROP TRIGGER tr_client_delete;
|
||||||
|
CREATE TRIGGER tr_client_delete BEFORE DELETE ON client
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM client_by_group WHERE client_id = OLD.id;
|
||||||
|
END;
|
||||||
|
|
||||||
|
UPDATE info SET value = 19 WHERE property = 'version';
|
||||||
|
|
||||||
|
COMMIT;
|
@ -150,18 +150,18 @@ AddDomain() {
|
|||||||
domain="$1"
|
domain="$1"
|
||||||
|
|
||||||
# Is the domain in the list we want to add it to?
|
# Is the domain in the list we want to add it to?
|
||||||
num="$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT COUNT(*) FROM domainlist WHERE domain = '${domain}';")"
|
num="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT COUNT(*) FROM domainlist WHERE domain = '${domain}';")"
|
||||||
requestedListname="$(GetListnameFromTypeId "${typeId}")"
|
requestedListname="$(GetListnameFromTypeId "${typeId}")"
|
||||||
|
|
||||||
if [[ "${num}" -ne 0 ]]; then
|
if [[ "${num}" -ne 0 ]]; then
|
||||||
existingTypeId="$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT type FROM domainlist WHERE domain = '${domain}';")"
|
existingTypeId="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT type FROM domainlist WHERE domain = '${domain}';")"
|
||||||
if [[ "${existingTypeId}" == "${typeId}" ]]; then
|
if [[ "${existingTypeId}" == "${typeId}" ]]; then
|
||||||
if [[ "${verbose}" == true ]]; then
|
if [[ "${verbose}" == true ]]; then
|
||||||
echo -e " ${INFO} ${1} already exists in ${requestedListname}, no need to add!"
|
echo -e " ${INFO} ${1} already exists in ${requestedListname}, no need to add!"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
existingListname="$(GetListnameFromTypeId "${existingTypeId}")"
|
existingListname="$(GetListnameFromTypeId "${existingTypeId}")"
|
||||||
pihole-FTL sqlite3 "${gravityDBfile}" "UPDATE domainlist SET type = ${typeId} WHERE domain='${domain}';"
|
pihole-FTL sqlite3 -ni "${gravityDBfile}" "UPDATE domainlist SET type = ${typeId} WHERE domain='${domain}';"
|
||||||
if [[ "${verbose}" == true ]]; then
|
if [[ "${verbose}" == true ]]; then
|
||||||
echo -e " ${INFO} ${1} already exists in ${existingListname}, it has been moved to ${requestedListname}!"
|
echo -e " ${INFO} ${1} already exists in ${existingListname}, it has been moved to ${requestedListname}!"
|
||||||
fi
|
fi
|
||||||
@ -177,10 +177,10 @@ AddDomain() {
|
|||||||
# Insert only the domain here. The enabled and date_added fields will be filled
|
# Insert only the domain here. The enabled and date_added fields will be filled
|
||||||
# with their default values (enabled = true, date_added = current timestamp)
|
# with their default values (enabled = true, date_added = current timestamp)
|
||||||
if [[ -z "${comment}" ]]; then
|
if [[ -z "${comment}" ]]; then
|
||||||
pihole-FTL sqlite3 "${gravityDBfile}" "INSERT INTO domainlist (domain,type) VALUES ('${domain}',${typeId});"
|
pihole-FTL sqlite3 -ni "${gravityDBfile}" "INSERT INTO domainlist (domain,type) VALUES ('${domain}',${typeId});"
|
||||||
else
|
else
|
||||||
# also add comment when variable has been set through the "--comment" option
|
# also add comment when variable has been set through the "--comment" option
|
||||||
pihole-FTL sqlite3 "${gravityDBfile}" "INSERT INTO domainlist (domain,type,comment) VALUES ('${domain}',${typeId},'${comment}');"
|
pihole-FTL sqlite3 -ni "${gravityDBfile}" "INSERT INTO domainlist (domain,type,comment) VALUES ('${domain}',${typeId},'${comment}');"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ RemoveDomain() {
|
|||||||
domain="$1"
|
domain="$1"
|
||||||
|
|
||||||
# Is the domain in the list we want to remove it from?
|
# Is the domain in the list we want to remove it from?
|
||||||
num="$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT COUNT(*) FROM domainlist WHERE domain = '${domain}' AND type = ${typeId};")"
|
num="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT COUNT(*) FROM domainlist WHERE domain = '${domain}' AND type = ${typeId};")"
|
||||||
|
|
||||||
requestedListname="$(GetListnameFromTypeId "${typeId}")"
|
requestedListname="$(GetListnameFromTypeId "${typeId}")"
|
||||||
|
|
||||||
@ -206,14 +206,14 @@ RemoveDomain() {
|
|||||||
fi
|
fi
|
||||||
reload=true
|
reload=true
|
||||||
# Remove it from the current list
|
# Remove it from the current list
|
||||||
pihole-FTL sqlite3 "${gravityDBfile}" "DELETE FROM domainlist WHERE domain = '${domain}' AND type = ${typeId};"
|
pihole-FTL sqlite3 -ni "${gravityDBfile}" "DELETE FROM domainlist WHERE domain = '${domain}' AND type = ${typeId};"
|
||||||
}
|
}
|
||||||
|
|
||||||
Displaylist() {
|
Displaylist() {
|
||||||
local count num_pipes domain enabled status nicedate requestedListname
|
local count num_pipes domain enabled status nicedate requestedListname
|
||||||
|
|
||||||
requestedListname="$(GetListnameFromTypeId "${typeId}")"
|
requestedListname="$(GetListnameFromTypeId "${typeId}")"
|
||||||
data="$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT domain,enabled,date_modified FROM domainlist WHERE type = ${typeId};" 2> /dev/null)"
|
data="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT domain,enabled,date_modified FROM domainlist WHERE type = ${typeId};" 2> /dev/null)"
|
||||||
|
|
||||||
if [[ -z $data ]]; then
|
if [[ -z $data ]]; then
|
||||||
echo -e "Not showing empty list"
|
echo -e "Not showing empty list"
|
||||||
@ -251,10 +251,10 @@ Displaylist() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NukeList() {
|
NukeList() {
|
||||||
count=$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT COUNT(1) FROM domainlist WHERE type = ${typeId};")
|
count=$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT COUNT(1) FROM domainlist WHERE type = ${typeId};")
|
||||||
listname="$(GetListnameFromTypeId "${typeId}")"
|
listname="$(GetListnameFromTypeId "${typeId}")"
|
||||||
if [ "$count" -gt 0 ];then
|
if [ "$count" -gt 0 ];then
|
||||||
pihole-FTL sqlite3 "${gravityDBfile}" "DELETE FROM domainlist WHERE type = ${typeId};"
|
pihole-FTL sqlite3 -ni "${gravityDBfile}" "DELETE FROM domainlist WHERE type = ${typeId};"
|
||||||
echo " ${TICK} Removed ${count} domain(s) from the ${listname}"
|
echo " ${TICK} Removed ${count} domain(s) from the ${listname}"
|
||||||
else
|
else
|
||||||
echo " ${INFO} ${listname} already empty. Nothing to do!"
|
echo " ${INFO} ${listname} already empty. Nothing to do!"
|
||||||
|
@ -39,7 +39,7 @@ flushARP(){
|
|||||||
# Truncate network_addresses table in pihole-FTL.db
|
# Truncate network_addresses table in pihole-FTL.db
|
||||||
# This needs to be done before we can truncate the network table due to
|
# This needs to be done before we can truncate the network table due to
|
||||||
# foreign key constraints
|
# foreign key constraints
|
||||||
if ! output=$(pihole-FTL sqlite3 "${DBFILE}" "DELETE FROM network_addresses" 2>&1); then
|
if ! output=$(pihole-FTL sqlite3 -ni "${DBFILE}" "DELETE FROM network_addresses" 2>&1); then
|
||||||
echo -e "${OVER} ${CROSS} Failed to truncate network_addresses table"
|
echo -e "${OVER} ${CROSS} Failed to truncate network_addresses table"
|
||||||
echo " Database location: ${DBFILE}"
|
echo " Database location: ${DBFILE}"
|
||||||
echo " Output: ${output}"
|
echo " Output: ${output}"
|
||||||
@ -47,7 +47,7 @@ flushARP(){
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Truncate network table in pihole-FTL.db
|
# Truncate network table in pihole-FTL.db
|
||||||
if ! output=$(pihole-FTL sqlite3 "${DBFILE}" "DELETE FROM network" 2>&1); then
|
if ! output=$(pihole-FTL sqlite3 -ni "${DBFILE}" "DELETE FROM network" 2>&1); then
|
||||||
echo -e "${OVER} ${CROSS} Failed to truncate network table"
|
echo -e "${OVER} ${CROSS} Failed to truncate network table"
|
||||||
echo " Database location: ${DBFILE}"
|
echo " Database location: ${DBFILE}"
|
||||||
echo " Output: ${output}"
|
echo " Output: ${output}"
|
||||||
|
@ -164,7 +164,9 @@ checkout() {
|
|||||||
path="${2}/${binary}"
|
path="${2}/${binary}"
|
||||||
oldbranch="$(pihole-FTL -b)"
|
oldbranch="$(pihole-FTL -b)"
|
||||||
|
|
||||||
if check_download_exists "$path"; then
|
check_download_exists "$path"
|
||||||
|
local ret=$?
|
||||||
|
if [ $ret -eq 0 ]; then
|
||||||
echo " ${TICK} Branch ${2} exists"
|
echo " ${TICK} Branch ${2} exists"
|
||||||
echo "${2}" > /etc/pihole/ftlbranch
|
echo "${2}" > /etc/pihole/ftlbranch
|
||||||
chmod 644 /etc/pihole/ftlbranch
|
chmod 644 /etc/pihole/ftlbranch
|
||||||
@ -175,11 +177,19 @@ checkout() {
|
|||||||
# Update local and remote versions via updatechecker
|
# Update local and remote versions via updatechecker
|
||||||
/opt/pihole/updatecheck.sh
|
/opt/pihole/updatecheck.sh
|
||||||
else
|
else
|
||||||
echo " ${CROSS} Requested branch \"${2}\" is not available"
|
if [[ $ret -eq 1 ]]; then
|
||||||
ftlbranches=( $(git ls-remote https://github.com/pi-hole/ftl | grep 'heads' | sed 's/refs\/heads\///;s/ //g' | awk '{print $2}') )
|
echo " ${CROSS} Requested branch \"${2}\" is not available"
|
||||||
echo -e " ${INFO} Available branches for FTL are:"
|
ftlbranches=( $(git ls-remote https://github.com/pi-hole/ftl | grep 'heads' | sed 's/refs\/heads\///;s/ //g' | awk '{print $2}') )
|
||||||
for e in "${ftlbranches[@]}"; do echo " - $e"; done
|
echo -e " ${INFO} Available branches for FTL are:"
|
||||||
exit 1
|
for e in "${ftlbranches[@]}"; do echo " - $e"; done
|
||||||
|
exit 1
|
||||||
|
elif [[ $ret -eq 2 ]]; then
|
||||||
|
printf " %b Unable to download from ftl.pi-hole.net. Please check your Internet connection and try again later.\\n" "${CROSS}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
printf " %b Unknown error. Please contact Pi-hole Support\\n" "${CROSS}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -49,7 +49,6 @@ FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://docs.pi-hole.net/main/prerequisite
|
|||||||
FAQ_HARDWARE_REQUIREMENTS_PORTS="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/#ports${COL_NC}"
|
FAQ_HARDWARE_REQUIREMENTS_PORTS="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/#ports${COL_NC}"
|
||||||
FAQ_HARDWARE_REQUIREMENTS_FIREWALLD="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/#firewalld${COL_NC}"
|
FAQ_HARDWARE_REQUIREMENTS_FIREWALLD="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/#firewalld${COL_NC}"
|
||||||
FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/t/why-is-a-default-gateway-important-for-pi-hole/3546${COL_NC}"
|
FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/t/why-is-a-default-gateway-important-for-pi-hole/3546${COL_NC}"
|
||||||
FAQ_FTL_COMPATIBILITY="${COL_CYAN}https://github.com/pi-hole/FTL#compatibility-list${COL_NC}"
|
|
||||||
|
|
||||||
# Other URLs we may use
|
# Other URLs we may use
|
||||||
FORUMS_URL="${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
|
FORUMS_URL="${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
|
||||||
@ -75,41 +74,21 @@ PIHOLE_CRON_FILE="${CRON_D_DIRECTORY}/pihole"
|
|||||||
|
|
||||||
PIHOLE_INSTALL_LOG_FILE="${PIHOLE_DIRECTORY}/install.log"
|
PIHOLE_INSTALL_LOG_FILE="${PIHOLE_DIRECTORY}/install.log"
|
||||||
PIHOLE_RAW_BLOCKLIST_FILES="${PIHOLE_DIRECTORY}/list.*"
|
PIHOLE_RAW_BLOCKLIST_FILES="${PIHOLE_DIRECTORY}/list.*"
|
||||||
PIHOLE_LOCAL_HOSTS_FILE="${PIHOLE_DIRECTORY}/local.list"
|
|
||||||
PIHOLE_LOGROTATE_FILE="${PIHOLE_DIRECTORY}/logrotate"
|
PIHOLE_LOGROTATE_FILE="${PIHOLE_DIRECTORY}/logrotate"
|
||||||
PIHOLE_FTL_CONF_FILE="${PIHOLE_DIRECTORY}/pihole.toml"
|
PIHOLE_FTL_CONF_FILE="${PIHOLE_DIRECTORY}/pihole.toml"
|
||||||
PIHOLE_CUSTOM_HOSTS_FILE="${PIHOLE_DIRECTORY}/custom.list"
|
|
||||||
PIHOLE_VERSIONS_FILE="${PIHOLE_DIRECTORY}/versions"
|
PIHOLE_VERSIONS_FILE="${PIHOLE_DIRECTORY}/versions"
|
||||||
|
|
||||||
# Read the value of an FTL config key. The value is printed to stdout.
|
# Read the value of an FTL config key. The value is printed to stdout.
|
||||||
#
|
|
||||||
# Args:
|
|
||||||
# 1. The key to read
|
|
||||||
# 2. The default if the setting or config does not exist
|
|
||||||
get_ftl_conf_value() {
|
get_ftl_conf_value() {
|
||||||
local key=$1
|
local key=$1
|
||||||
local default=$2
|
|
||||||
local value
|
|
||||||
|
|
||||||
# Obtain key=... setting from pihole-FTL.conf
|
# Obtain setting from FTL directly
|
||||||
if [[ -e "$PIHOLE_FTL_CONF_FILE" ]]; then
|
pihole-FTL --config "${key}"
|
||||||
# Constructed to return nothing when
|
|
||||||
# a) the setting is not present in the config file, or
|
|
||||||
# b) the setting is commented out (e.g. "#DBFILE=...")
|
|
||||||
value="$(sed -n -e "s/^\\s*$key=\\s*//p" ${PIHOLE_FTL_CONF_FILE})"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test for missing value. Use default value in this case.
|
|
||||||
if [[ -z "$value" ]]; then
|
|
||||||
value="$default"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$value"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PIHOLE_GRAVITY_DB_FILE="$(get_ftl_conf_value "GRAVITYDB" "${PIHOLE_DIRECTORY}/gravity.db")"
|
PIHOLE_GRAVITY_DB_FILE="$(get_ftl_conf_value "files.gravity")"
|
||||||
|
|
||||||
PIHOLE_FTL_DB_FILE="$(get_ftl_conf_value "DBFILE" "${PIHOLE_DIRECTORY}/pihole-FTL.db")"
|
PIHOLE_FTL_DB_FILE="$(get_ftl_conf_value "files.database")"
|
||||||
|
|
||||||
PIHOLE_COMMAND="${BIN_DIRECTORY}/pihole"
|
PIHOLE_COMMAND="${BIN_DIRECTORY}/pihole"
|
||||||
PIHOLE_COLTABLE_FILE="${BIN_DIRECTORY}/COL_TABLE"
|
PIHOLE_COLTABLE_FILE="${BIN_DIRECTORY}/COL_TABLE"
|
||||||
@ -119,10 +98,8 @@ FTL_PID="${RUN_DIRECTORY}/pihole-FTL.pid"
|
|||||||
PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log"
|
PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log"
|
||||||
PIHOLE_LOG_GZIPS="${LOG_DIRECTORY}/pihole.log.[0-9].*"
|
PIHOLE_LOG_GZIPS="${LOG_DIRECTORY}/pihole.log.[0-9].*"
|
||||||
PIHOLE_DEBUG_LOG="${LOG_DIRECTORY}/pihole_debug.log"
|
PIHOLE_DEBUG_LOG="${LOG_DIRECTORY}/pihole_debug.log"
|
||||||
PIHOLE_FTL_LOG="$(get_ftl_conf_value "LOGFILE" "${LOG_DIRECTORY}/FTL.log")"
|
PIHOLE_FTL_LOG="$(get_ftl_conf_value "files.log.ftl")"
|
||||||
|
PIHOLE_WEBSERVER_LOG="$(get_ftl_conf_value "files.log.webserver")"
|
||||||
# PIHOLE_WEB_SERVER_ACCESS_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/access-pihole.log" #TODO: FTL Error log?
|
|
||||||
# PIHOLE_WEB_SERVER_ERROR_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/error-pihole.log" #TODO: FTL Error log?
|
|
||||||
|
|
||||||
RESOLVCONF="${ETC}/resolv.conf"
|
RESOLVCONF="${ETC}/resolv.conf"
|
||||||
DNSMASQ_CONF="${ETC}/dnsmasq.conf"
|
DNSMASQ_CONF="${ETC}/dnsmasq.conf"
|
||||||
@ -132,8 +109,6 @@ PIHOLE_PROCESSES=( "pihole-FTL" )
|
|||||||
|
|
||||||
# Store the required directories in an array so it can be parsed through
|
# Store the required directories in an array so it can be parsed through
|
||||||
REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
|
REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
|
||||||
# "${WEB_SERVER_CONFIG_FILE}"
|
|
||||||
# "${WEB_SERVER_CUSTOM_CONFIG_FILE}"
|
|
||||||
"${PIHOLE_INSTALL_LOG_FILE}"
|
"${PIHOLE_INSTALL_LOG_FILE}"
|
||||||
"${PIHOLE_RAW_BLOCKLIST_FILES}"
|
"${PIHOLE_RAW_BLOCKLIST_FILES}"
|
||||||
"${PIHOLE_LOCAL_HOSTS_FILE}"
|
"${PIHOLE_LOCAL_HOSTS_FILE}"
|
||||||
@ -146,11 +121,9 @@ REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
|
|||||||
"${PIHOLE_LOG_GZIPS}"
|
"${PIHOLE_LOG_GZIPS}"
|
||||||
"${PIHOLE_DEBUG_LOG}"
|
"${PIHOLE_DEBUG_LOG}"
|
||||||
"${PIHOLE_FTL_LOG}"
|
"${PIHOLE_FTL_LOG}"
|
||||||
"${PIHOLE_WEB_SERVER_ACCESS_LOG_FILE}"
|
"${PIHOLE_WEBSERVER_LOG}"
|
||||||
"${PIHOLE_WEB_SERVER_ERROR_LOG_FILE}"
|
|
||||||
"${RESOLVCONF}"
|
"${RESOLVCONF}"
|
||||||
"${DNSMASQ_CONF}"
|
"${DNSMASQ_CONF}"
|
||||||
"${PIHOLE_CUSTOM_HOSTS_FILE}"
|
|
||||||
"${PIHOLE_VERSIONS_FILE}")
|
"${PIHOLE_VERSIONS_FILE}")
|
||||||
|
|
||||||
DISCLAIMER="This process collects information from your Pi-hole, and optionally uploads it to a unique and random directory on tricorder.pi-hole.net.
|
DISCLAIMER="This process collects information from your Pi-hole, and optionally uploads it to a unique and random directory on tricorder.pi-hole.net.
|
||||||
@ -544,18 +517,6 @@ disk_usage() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_pihole_toml() {
|
|
||||||
echo_current_diagnostic "Pi-hole configuration"
|
|
||||||
# If the file exists,
|
|
||||||
if [[ -r "${PIHOLE_FTL_CONF_FILE}" ]]; then
|
|
||||||
# parse it
|
|
||||||
parse_file "${PIHOLE_FTL_CONF_FILE}"
|
|
||||||
else
|
|
||||||
# If not, show an error
|
|
||||||
log_write "${CROSS} ${COL_RED}Could not read ${PIHOLE_FTL_CONF_FILE}.${COL_NC}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_locale() {
|
parse_locale() {
|
||||||
local pihole_locale
|
local pihole_locale
|
||||||
echo_current_diagnostic "Locale"
|
echo_current_diagnostic "Locale"
|
||||||
@ -585,17 +546,24 @@ ping_gateway() {
|
|||||||
ping_ipv4_or_ipv6 "${protocol}"
|
ping_ipv4_or_ipv6 "${protocol}"
|
||||||
# Check if we are using IPv4 or IPv6
|
# Check if we are using IPv4 or IPv6
|
||||||
# Find the default gateways using IPv4 or IPv6
|
# Find the default gateways using IPv4 or IPv6
|
||||||
local gateway
|
local gateway gateway_addr gateway_iface
|
||||||
|
|
||||||
log_write "${INFO} Default IPv${protocol} gateway(s):"
|
log_write "${INFO} Default IPv${protocol} gateway(s):"
|
||||||
|
|
||||||
while IFS= read -r gateway; do
|
while IFS= read -r gateway; do
|
||||||
log_write " ${gateway}"
|
log_write " $(cut -d ' ' -f 3 <<< "${gateway}")%$(cut -d ' ' -f 5 <<< "${gateway}")"
|
||||||
done < <(ip -"${protocol}" route | grep default | cut -d ' ' -f 3)
|
done < <(ip -"${protocol}" route | grep default)
|
||||||
|
|
||||||
gateway=$(ip -"${protocol}" route | grep default | cut -d ' ' -f 3 | head -n 1)
|
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 there was at least one gateway
|
||||||
if [ -n "${gateway}" ]; then
|
if [ -n "${gateway_addr}" ]; then
|
||||||
|
# Append the interface to the gateway address if it is a link-local address
|
||||||
|
if [[ "${gateway_addr}" =~ ^fe80 ]]; then
|
||||||
|
gateway="${gateway_addr}%${gateway_iface}"
|
||||||
|
else
|
||||||
|
gateway="${gateway_addr}"
|
||||||
|
fi
|
||||||
# Let the user know we will ping the gateway for a response
|
# Let the user know we will ping the gateway for a response
|
||||||
log_write " * Pinging first gateway ${gateway}..."
|
log_write " * Pinging first gateway ${gateway}..."
|
||||||
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
|
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
|
||||||
@ -654,10 +622,8 @@ compare_port_to_service_assigned() {
|
|||||||
|
|
||||||
check_required_ports() {
|
check_required_ports() {
|
||||||
echo_current_diagnostic "Ports in use"
|
echo_current_diagnostic "Ports in use"
|
||||||
# Since Pi-hole needs 53 and 4711, check what they are being used by
|
# Since Pi-hole needs various ports, check what they are being used by
|
||||||
# so we can detect any issues
|
# so we can detect any issues
|
||||||
local resolver="pihole-FTL"
|
|
||||||
local web_server="pihole-FTL"
|
|
||||||
local ftl="pihole-FTL"
|
local ftl="pihole-FTL"
|
||||||
# Create an array for these ports in use
|
# Create an array for these ports in use
|
||||||
ports_in_use=()
|
ports_in_use=()
|
||||||
@ -666,6 +632,15 @@ check_required_ports() {
|
|||||||
ports_in_use+=( "$line" )
|
ports_in_use+=( "$line" )
|
||||||
done < <( ss --listening --numeric --tcp --udp --processes --no-header )
|
done < <( ss --listening --numeric --tcp --udp --processes --no-header )
|
||||||
|
|
||||||
|
local ports_configured
|
||||||
|
# Get all configured ports
|
||||||
|
ports_configured="$(pihole-FTL --config "webserver.port")"
|
||||||
|
# Remove all non-didgits, split into an array at ","
|
||||||
|
ports_configured="${ports_configured//[!0-9,]/}"
|
||||||
|
mapfile -d "," -t ports_configured < <(echo "${ports_configured}")
|
||||||
|
# Add port 53
|
||||||
|
ports_configured+=("53")
|
||||||
|
|
||||||
# Now that we have the values stored,
|
# Now that we have the values stored,
|
||||||
for i in "${!ports_in_use[@]}"; do
|
for i in "${!ports_in_use[@]}"; do
|
||||||
# loop through them and assign some local variables
|
# loop through them and assign some local variables
|
||||||
@ -676,17 +651,13 @@ check_required_ports() {
|
|||||||
local port_number
|
local port_number
|
||||||
port_number="$(echo "${ports_in_use[$i]}" | awk '{print $5}')" # | awk '{gsub(/^.*:/,"",$5);print $5}')
|
port_number="$(echo "${ports_in_use[$i]}" | awk '{print $5}')" # | awk '{gsub(/^.*:/,"",$5);print $5}')
|
||||||
|
|
||||||
# Use a case statement to determine if the right services are using the right ports
|
# Check if the right services are using the right ports
|
||||||
case "$(echo "${port_number}" | rev | cut -d: -f1 | rev)" in
|
if [[ ${ports_configured[*]} =~ $(echo "${port_number}" | rev | cut -d: -f1 | rev) ]]; then
|
||||||
53) compare_port_to_service_assigned "${resolver}" "${service_name}" "${protocol_type}:${port_number}"
|
compare_port_to_service_assigned "${ftl}" "${service_name}" "${protocol_type}:${port_number}"
|
||||||
;;
|
else
|
||||||
80) compare_port_to_service_assigned "${web_server}" "${service_name}" "${protocol_type}:${port_number}"
|
|
||||||
;;
|
|
||||||
4711) compare_port_to_service_assigned "${ftl}" "${service_name}" "${protocol_type}:${port_number}"
|
|
||||||
;;
|
|
||||||
# If it's not a default port that Pi-hole needs, just print it out for the user to see
|
# If it's not a default port that Pi-hole needs, just print it out for the user to see
|
||||||
*) log_write " ${protocol_type}:${port_number} is in use by ${service_name:=<unknown>}";
|
log_write " ${protocol_type}:${port_number} is in use by ${service_name:=<unknown>}";
|
||||||
esac
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,7 +724,7 @@ dig_at() {
|
|||||||
# This helps emulate queries to different domains that a user might query
|
# This helps emulate queries to different domains that a user might query
|
||||||
# It will also give extra assurance that Pi-hole is correctly resolving and blocking domains
|
# It will also give extra assurance that Pi-hole is correctly resolving and blocking domains
|
||||||
local random_url
|
local random_url
|
||||||
random_url=$(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT domain FROM vw_gravity WHERE domain not like '||%^' ORDER BY RANDOM() LIMIT 1")
|
random_url=$(pihole-FTL sqlite3 -ni "${PIHOLE_GRAVITY_DB_FILE}" "SELECT domain FROM vw_gravity WHERE domain not like '||%^' ORDER BY RANDOM() LIMIT 1")
|
||||||
# Fallback if no non-ABP style domains were found
|
# Fallback if no non-ABP style domains were found
|
||||||
if [ -z "${random_url}" ]; then
|
if [ -z "${random_url}" ]; then
|
||||||
random_url="flurry.com"
|
random_url="flurry.com"
|
||||||
@ -792,24 +763,29 @@ dig_at() {
|
|||||||
# Removes CIDR and everything thereafter (e.g., scope properties)
|
# Removes CIDR and everything thereafter (e.g., scope properties)
|
||||||
addresses="$(ip address show dev "${iface}" | sed "/${sed_selector} /!d;s/^.*${sed_selector} //g;s/\/.*$//g;")"
|
addresses="$(ip address show dev "${iface}" | sed "/${sed_selector} /!d;s/^.*${sed_selector} //g;s/\/.*$//g;")"
|
||||||
if [ -n "${addresses}" ]; then
|
if [ -n "${addresses}" ]; then
|
||||||
while IFS= read -r local_address ; do
|
while IFS= read -r local_address ; do
|
||||||
|
# If ${local_address} is an IPv6 link-local address, append the interface name to it
|
||||||
|
if [[ "${local_address}" =~ ^fe80 ]]; then
|
||||||
|
local_address="${local_address}%${iface}"
|
||||||
|
fi
|
||||||
|
|
||||||
# Check if Pi-hole can use itself to block a domain
|
# 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}")"; then
|
if local_dig="$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @"${local_address}" "${record_type}")"; then
|
||||||
# If it can, show success
|
# If it can, show success
|
||||||
if [[ "${local_dig}" == *"status: NOERROR"* ]]; then
|
if [[ "${local_dig}" == *"status: NOERROR"* ]]; then
|
||||||
local_dig="NOERROR"
|
local_dig="NOERROR"
|
||||||
elif [[ "${local_dig}" == *"status: NXDOMAIN"* ]]; then
|
elif [[ "${local_dig}" == *"status: NXDOMAIN"* ]]; then
|
||||||
local_dig="NXDOMAIN"
|
local_dig="NXDOMAIN"
|
||||||
else
|
else
|
||||||
# Extract the first entry in the answer section from dig's output,
|
# Extract the first entry in the answer section from dig's output,
|
||||||
# replacing any multiple spaces and tabs with a single space
|
# replacing any multiple spaces and tabs with a single space
|
||||||
local_dig="$(echo "${local_dig}" | grep -A1 "ANSWER SECTION" | grep -v "ANSWER SECTION" | tr -s " \t" " ")"
|
local_dig="$(echo "${local_dig}" | grep -A1 "ANSWER SECTION" | grep -v "ANSWER SECTION" | tr -s " \t" " ")"
|
||||||
fi
|
fi
|
||||||
log_write "${TICK} ${random_url} ${COL_GREEN}is ${local_dig}${COL_NC} on ${COL_CYAN}${iface}${COL_NC} (${COL_CYAN}${local_address}${COL_NC})"
|
log_write "${TICK} ${random_url} ${COL_GREEN}is ${local_dig}${COL_NC} on ${COL_CYAN}${iface}${COL_NC} (${COL_CYAN}${local_address}${COL_NC})"
|
||||||
else
|
else
|
||||||
# Otherwise, show a failure
|
# Otherwise, show a failure
|
||||||
log_write "${CROSS} ${COL_RED}Failed to resolve${COL_NC} ${random_url} on ${COL_RED}${iface}${COL_NC} (${COL_RED}${local_address}${COL_NC})"
|
log_write "${CROSS} ${COL_RED}Failed to resolve${COL_NC} ${random_url} on ${COL_RED}${iface}${COL_NC} (${COL_RED}${local_address}${COL_NC})"
|
||||||
fi
|
fi
|
||||||
done <<< "${addresses}"
|
done <<< "${addresses}"
|
||||||
else
|
else
|
||||||
log_write "${TICK} No IPv${protocol} address available on ${COL_CYAN}${iface}${COL_NC}"
|
log_write "${TICK} No IPv${protocol} address available on ${COL_CYAN}${iface}${COL_NC}"
|
||||||
@ -995,12 +971,6 @@ list_files_in_dir() {
|
|||||||
if [[ "${dir_to_parse}" == "${SHM_DIRECTORY}" ]]; then
|
if [[ "${dir_to_parse}" == "${SHM_DIRECTORY}" ]]; then
|
||||||
# SHM file - we do not want to see the content, but we want to see the files and their sizes
|
# SHM file - we do not want to see the content, but we want to see the files and their sizes
|
||||||
log_write "$(ls -lh "${dir_to_parse}/")"
|
log_write "$(ls -lh "${dir_to_parse}/")"
|
||||||
elif [[ "${dir_to_parse}" == "${WEB_SERVER_CONFIG_DIRECTORY_FEDORA}" ]]; then
|
|
||||||
# we want to see all files files in /etc/lighttpd/conf.d
|
|
||||||
log_write "$(ls -lh "${dir_to_parse}/" 2> /dev/null )"
|
|
||||||
elif [[ "${dir_to_parse}" == "${WEB_SERVER_CONFIG_DIRECTORY_DEBIAN}" ]]; then
|
|
||||||
# we want to see all files files in /etc/lighttpd/conf.d
|
|
||||||
log_write "$(ls -lh "${dir_to_parse}/"/ 2> /dev/null )"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Store the files found in an array
|
# Store the files found in an array
|
||||||
@ -1014,7 +984,6 @@ list_files_in_dir() {
|
|||||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_RAW_BLOCKLIST_FILES}" ]] || \
|
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_RAW_BLOCKLIST_FILES}" ]] || \
|
||||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_INSTALL_LOG_FILE}" ]] || \
|
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_INSTALL_LOG_FILE}" ]] || \
|
||||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG}" ]] || \
|
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG}" ]] || \
|
||||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_WEB_SERVER_ACCESS_LOG_FILE}" ]] || \
|
|
||||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG_GZIPS}" ]]; then
|
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG_GZIPS}" ]]; then
|
||||||
:
|
:
|
||||||
elif [[ "${dir_to_parse}" == "${DNSMASQ_D_DIRECTORY}" ]]; then
|
elif [[ "${dir_to_parse}" == "${DNSMASQ_D_DIRECTORY}" ]]; then
|
||||||
@ -1029,8 +998,8 @@ list_files_in_dir() {
|
|||||||
log_write "\\n${COL_GREEN}$(ls -lhd "${dir_to_parse}"/"${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)
|
# 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 "${dir_to_parse}/${each_file}" in
|
case "${dir_to_parse}/${each_file}" in
|
||||||
# If it's Web server error log, give the first and last 25 lines
|
# If it's Web server log, give the first and last 25 lines
|
||||||
"${PIHOLE_WEB_SERVER_ERROR_LOG_FILE}") head_tail_log "${dir_to_parse}/${each_file}" 25
|
"${PIHOLE_WEBSERVER_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 25
|
||||||
;;
|
;;
|
||||||
# Same for the FTL log
|
# Same for the FTL log
|
||||||
"${PIHOLE_FTL_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 35
|
"${PIHOLE_FTL_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 35
|
||||||
@ -1061,11 +1030,7 @@ show_content_of_pihole_files() {
|
|||||||
# Show the content of the files in each of Pi-hole's folders
|
# Show the content of the files in each of Pi-hole's folders
|
||||||
show_content_of_files_in_dir "${PIHOLE_DIRECTORY}"
|
show_content_of_files_in_dir "${PIHOLE_DIRECTORY}"
|
||||||
show_content_of_files_in_dir "${DNSMASQ_D_DIRECTORY}"
|
show_content_of_files_in_dir "${DNSMASQ_D_DIRECTORY}"
|
||||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY}"
|
|
||||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY_FEDORA}"
|
|
||||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY_DEBIAN}"
|
|
||||||
show_content_of_files_in_dir "${CRON_D_DIRECTORY}"
|
show_content_of_files_in_dir "${CRON_D_DIRECTORY}"
|
||||||
show_content_of_files_in_dir "${WEB_SERVER_LOG_DIRECTORY}"
|
|
||||||
show_content_of_files_in_dir "${LOG_DIRECTORY}"
|
show_content_of_files_in_dir "${LOG_DIRECTORY}"
|
||||||
show_content_of_files_in_dir "${SHM_DIRECTORY}"
|
show_content_of_files_in_dir "${SHM_DIRECTORY}"
|
||||||
show_content_of_files_in_dir "${ETC}"
|
show_content_of_files_in_dir "${ETC}"
|
||||||
@ -1110,7 +1075,7 @@ show_db_entries() {
|
|||||||
IFS=$'\r\n'
|
IFS=$'\r\n'
|
||||||
local entries=()
|
local entries=()
|
||||||
mapfile -t entries < <(\
|
mapfile -t entries < <(\
|
||||||
pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" \
|
pihole-FTL sqlite3 -ni "${PIHOLE_GRAVITY_DB_FILE}" \
|
||||||
-cmd ".headers on" \
|
-cmd ".headers on" \
|
||||||
-cmd ".mode column" \
|
-cmd ".mode column" \
|
||||||
-cmd ".width ${widths}" \
|
-cmd ".width ${widths}" \
|
||||||
@ -1135,7 +1100,7 @@ show_FTL_db_entries() {
|
|||||||
IFS=$'\r\n'
|
IFS=$'\r\n'
|
||||||
local entries=()
|
local entries=()
|
||||||
mapfile -t entries < <(\
|
mapfile -t entries < <(\
|
||||||
pihole-FTL sqlite3 "${PIHOLE_FTL_DB_FILE}" \
|
pihole-FTL sqlite3 -ni "${PIHOLE_FTL_DB_FILE}" \
|
||||||
-cmd ".headers on" \
|
-cmd ".headers on" \
|
||||||
-cmd ".mode column" \
|
-cmd ".mode column" \
|
||||||
-cmd ".width ${widths}" \
|
-cmd ".width ${widths}" \
|
||||||
@ -1201,7 +1166,7 @@ analyze_gravity_list() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
show_db_entries "Info table" "SELECT property,value FROM info" "20 40"
|
show_db_entries "Info table" "SELECT property,value FROM info" "20 40"
|
||||||
gravity_updated_raw="$(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT value FROM info where property = 'updated'")"
|
gravity_updated_raw="$(pihole-FTL sqlite3 -ni "${PIHOLE_GRAVITY_DB_FILE}" "SELECT value FROM info where property = 'updated'")"
|
||||||
gravity_updated="$(date -d @"${gravity_updated_raw}")"
|
gravity_updated="$(date -d @"${gravity_updated_raw}")"
|
||||||
log_write " Last gravity run finished at: ${COL_CYAN}${gravity_updated}${COL_NC}"
|
log_write " Last gravity run finished at: ${COL_CYAN}${gravity_updated}${COL_NC}"
|
||||||
log_write ""
|
log_write ""
|
||||||
@ -1209,7 +1174,7 @@ analyze_gravity_list() {
|
|||||||
OLD_IFS="$IFS"
|
OLD_IFS="$IFS"
|
||||||
IFS=$'\r\n'
|
IFS=$'\r\n'
|
||||||
local gravity_sample=()
|
local gravity_sample=()
|
||||||
mapfile -t gravity_sample < <(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT domain FROM vw_gravity LIMIT 10")
|
mapfile -t gravity_sample < <(pihole-FTL sqlite3 -ni "${PIHOLE_GRAVITY_DB_FILE}" "SELECT domain FROM vw_gravity LIMIT 10")
|
||||||
log_write " ${COL_CYAN}----- First 10 Gravity Domains -----${COL_NC}"
|
log_write " ${COL_CYAN}----- First 10 Gravity Domains -----${COL_NC}"
|
||||||
|
|
||||||
for line in "${gravity_sample[@]}"; do
|
for line in "${gravity_sample[@]}"; do
|
||||||
@ -1241,7 +1206,7 @@ database_integrity_check(){
|
|||||||
|
|
||||||
log_write "${INFO} Checking foreign key constraints of ${database} ... (this can take several minutes)"
|
log_write "${INFO} Checking foreign key constraints of ${database} ... (this can take several minutes)"
|
||||||
unset result
|
unset result
|
||||||
result="$(pihole-FTL sqlite3 "${database}" -cmd ".headers on" -cmd ".mode column" "PRAGMA foreign_key_check" 2>&1 & spinner)"
|
result="$(pihole-FTL sqlite3 -ni "${database}" -cmd ".headers on" -cmd ".mode column" "PRAGMA foreign_key_check" 2>&1 & spinner)"
|
||||||
if [[ -z ${result} ]]; then
|
if [[ -z ${result} ]]; then
|
||||||
log_write "${TICK} No foreign key errors in ${database}"
|
log_write "${TICK} No foreign key errors in ${database}"
|
||||||
else
|
else
|
||||||
@ -1302,10 +1267,10 @@ spinner(){
|
|||||||
analyze_pihole_log() {
|
analyze_pihole_log() {
|
||||||
echo_current_diagnostic "Pi-hole log"
|
echo_current_diagnostic "Pi-hole log"
|
||||||
local pihole_log_permissions
|
local pihole_log_permissions
|
||||||
local logging_enabled
|
local queryLogging
|
||||||
|
|
||||||
logging_enabled=$(grep -c "^log-queries" /etc/dnsmasq.d/01-pihole.conf)
|
queryLogging="$(get_ftl_conf_value "dns.queryLogging")"
|
||||||
if [[ "${logging_enabled}" == "0" ]]; then
|
if [[ "${queryLogging}" == "false" ]]; then
|
||||||
# Inform user that logging has been disabled and pihole.log does not contain queries
|
# Inform user that logging has been disabled and pihole.log does not contain queries
|
||||||
log_write "${INFO} Query logging is disabled"
|
log_write "${INFO} Query logging is disabled"
|
||||||
log_write ""
|
log_write ""
|
||||||
@ -1402,10 +1367,6 @@ upload_to_tricorder() {
|
|||||||
# Run through all the functions we made
|
# Run through all the functions we made
|
||||||
make_temporary_log
|
make_temporary_log
|
||||||
initialize_debug
|
initialize_debug
|
||||||
# TODO: Address the reliance on setupVars.conf here. Should debug read pihole.toml directly, or rely on pihole-FTL --config?
|
|
||||||
# setupVars.conf needs to be sourced before the networking so the values are
|
|
||||||
# available to the other functions
|
|
||||||
source_setup_variables
|
|
||||||
check_component_versions
|
check_component_versions
|
||||||
# check_critical_program_versions
|
# check_critical_program_versions
|
||||||
diagnose_operating_system
|
diagnose_operating_system
|
||||||
@ -1419,7 +1380,6 @@ check_name_resolution
|
|||||||
check_dhcp_servers
|
check_dhcp_servers
|
||||||
process_status
|
process_status
|
||||||
ftl_full_status
|
ftl_full_status
|
||||||
parse_pihole_toml
|
|
||||||
analyze_ftl_db
|
analyze_ftl_db
|
||||||
analyze_gravity_list
|
analyze_gravity_list
|
||||||
show_groups
|
show_groups
|
||||||
|
@ -63,7 +63,7 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# Delete most recent 24 hours from FTL's database, leave even older data intact (don't wipe out all history)
|
# Delete most recent 24 hours from FTL's database, leave even older data intact (don't wipe out all history)
|
||||||
deleted=$(pihole-FTL sqlite3 "${DBFILE}" "DELETE FROM query_storage WHERE timestamp >= strftime('%s','now')-86400; select changes() from query_storage limit 1")
|
deleted=$(pihole-FTL sqlite3 -ni "${DBFILE}" "DELETE FROM query_storage WHERE timestamp >= strftime('%s','now')-86400; select changes() from query_storage limit 1")
|
||||||
|
|
||||||
# Restart pihole-FTL to force reloading history
|
# Restart pihole-FTL to force reloading history
|
||||||
sudo pihole restartdns
|
sudo pihole restartdns
|
||||||
|
@ -27,7 +27,7 @@ colfile="/opt/pihole/COL_TABLE"
|
|||||||
# Source api functions
|
# Source api functions
|
||||||
. "${PI_HOLE_INSTALL_DIR}/api.sh"
|
. "${PI_HOLE_INSTALL_DIR}/api.sh"
|
||||||
|
|
||||||
Help(){
|
Help() {
|
||||||
echo "Usage: pihole -q [option] <domain>
|
echo "Usage: pihole -q [option] <domain>
|
||||||
Example: 'pihole -q --partial domain.com'
|
Example: 'pihole -q --partial domain.com'
|
||||||
Query the adlists for a specified domain
|
Query the adlists for a specified domain
|
||||||
@ -36,29 +36,28 @@ Options:
|
|||||||
--partial Search the adlists for partially matching domains
|
--partial Search the adlists for partially matching domains
|
||||||
--all Return all query matches within the adlists
|
--all Return all query matches within the adlists
|
||||||
-h, --help Show this help dialog"
|
-h, --help Show this help dialog"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GenerateOutput() {
|
||||||
GenerateOutput(){
|
|
||||||
local data gravity_data lists_data num_gravity num_lists search_type_str
|
local data gravity_data lists_data num_gravity num_lists search_type_str
|
||||||
local gravity_data_csv lists_data_csv line current_domain
|
local gravity_data_csv lists_data_csv line current_domain
|
||||||
data="${1}"
|
data="${1}"
|
||||||
|
|
||||||
# construct a new json for the list results where each object contains the domain and the related type
|
# construct a new json for the list results where each object contains the domain and the related type
|
||||||
lists_data=$(echo "${data}" | jq '.search.domains | [.[] | {domain: .domain, type: .type}]')
|
lists_data=$(printf %s "${data}" | jq '.search.domains | [.[] | {domain: .domain, type: .type}]')
|
||||||
|
|
||||||
# construct a new json for the gravity results where each object contains the adlist URL and the related domains
|
# construct a new json for the gravity results where each object contains the adlist URL and the related domains
|
||||||
gravity_data=$(echo "${data}" | jq '.search.gravity | group_by(.address) | map({ address: (.[0].address), domains: [.[] | .domain] })')
|
gravity_data=$(printf %s "${data}" | jq '.search.gravity | group_by(.address) | map({ address: (.[0].address), domains: [.[] | .domain] })')
|
||||||
|
|
||||||
# number of objects in each json
|
# number of objects in each json
|
||||||
num_gravity=$(echo "${gravity_data}" | jq length )
|
num_gravity=$(printf %s "${gravity_data}" | jq length)
|
||||||
num_lists=$(echo "${lists_data}" | jq length )
|
num_lists=$(printf %s "${lists_data}" | jq length)
|
||||||
|
|
||||||
if [ "${partial}" = true ]; then
|
if [ "${partial}" = true ]; then
|
||||||
search_type_str="partially"
|
search_type_str="partially"
|
||||||
else
|
else
|
||||||
search_type_str="exactly"
|
search_type_str="exactly"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Results from allow/deny list
|
# Results from allow/deny list
|
||||||
@ -66,7 +65,7 @@ GenerateOutput(){
|
|||||||
if [ "${num_lists}" -gt 0 ]; then
|
if [ "${num_lists}" -gt 0 ]; then
|
||||||
# Convert the data to a csv, each line is a "domain,type" string
|
# Convert the data to a csv, each line is a "domain,type" string
|
||||||
# not using jq's @csv here as it quotes each value individually
|
# not using jq's @csv here as it quotes each value individually
|
||||||
lists_data_csv=$(echo "${lists_data}" | jq --raw-output '.[] | [.domain, .type] | join(",")' )
|
lists_data_csv=$(printf %s "${lists_data}" | jq --raw-output '.[] | [.domain, .type] | join(",")')
|
||||||
|
|
||||||
# Generate output for each csv line, separating line in a domain and type substring at the ','
|
# Generate output for each csv line, separating line in a domain and type substring at the ','
|
||||||
echo "${lists_data_csv}" | while read -r line; do
|
echo "${lists_data_csv}" | while read -r line; do
|
||||||
@ -79,7 +78,7 @@ GenerateOutput(){
|
|||||||
if [ "${num_gravity}" -gt 0 ]; then
|
if [ "${num_gravity}" -gt 0 ]; then
|
||||||
# Convert the data to a csv, each line is a "URL,domain,domain,...." string
|
# Convert the data to a csv, each line is a "URL,domain,domain,...." string
|
||||||
# not using jq's @csv here as it quotes each value individually
|
# not using jq's @csv here as it quotes each value individually
|
||||||
gravity_data_csv=$(echo "${gravity_data}" | jq --raw-output '.[] | [.address, .domains[]] | join(",")' )
|
gravity_data_csv=$(printf %s "${gravity_data}" | jq --raw-output '.[] | [.address, .domains[]] | join(",")')
|
||||||
|
|
||||||
# Generate line-by-line output for each csv line
|
# Generate line-by-line output for each csv line
|
||||||
echo "${gravity_data_csv}" | while read -r line; do
|
echo "${gravity_data_csv}" | while read -r line; do
|
||||||
@ -90,7 +89,7 @@ GenerateOutput(){
|
|||||||
# cut off URL, leaving "domain,domain,...."
|
# cut off URL, leaving "domain,domain,...."
|
||||||
line=${line#*,}
|
line=${line#*,}
|
||||||
# print each domain and remove it from the string until nothing is left
|
# print each domain and remove it from the string until nothing is left
|
||||||
while [ ${#line} -gt 0 ]; do
|
while [ ${#line} -gt 0 ]; do
|
||||||
current_domain=${line%%,*}
|
current_domain=${line%%,*}
|
||||||
printf ' - %s\n' "${COL_GREEN}${current_domain}${COL_NC}"
|
printf ' - %s\n' "${COL_GREEN}${current_domain}${COL_NC}"
|
||||||
# we need to remove the current_domain and the comma in two steps because
|
# we need to remove the current_domain and the comma in two steps because
|
||||||
@ -103,17 +102,17 @@ GenerateOutput(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
Main(){
|
Main() {
|
||||||
local data
|
local data
|
||||||
|
|
||||||
if [ -z "${domain}" ]; then
|
if [ -z "${domain}" ]; then
|
||||||
echo "No domain specified"; exit 1
|
echo "No domain specified"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
# domains are lowercased and converted to punycode by FTL since
|
# domains are lowercased and converted to punycode by FTL since
|
||||||
# https://github.com/pi-hole/FTL/pull/1715
|
# https://github.com/pi-hole/FTL/pull/1715
|
||||||
# no need to do it here
|
# no need to do it here
|
||||||
|
|
||||||
|
|
||||||
# Test if the authentication endpoint is available
|
# Test if the authentication endpoint is available
|
||||||
TestAPIAvailability
|
TestAPIAvailability
|
||||||
|
|
||||||
@ -121,14 +120,14 @@ Main(){
|
|||||||
# or b) for the /search endpoint (webserver.api.searchAPIauth) no authentication is required.
|
# or b) for the /search endpoint (webserver.api.searchAPIauth) no authentication is required.
|
||||||
# Therefore, we try to query directly without authentication but do authenticat if 401 is returned
|
# Therefore, we try to query directly without authentication but do authenticat if 401 is returned
|
||||||
|
|
||||||
data=$(GetFTLData "/search/${domain}?N=${max_results}&partial=${partial}")
|
data=$(GetFTLData "search/${domain}?N=${max_results}&partial=${partial}")
|
||||||
|
|
||||||
if [ "${data}" = 401 ]; then
|
if [ "${data}" = 401 ]; then
|
||||||
# Unauthenticated, so authenticate with the FTL server required
|
# Unauthenticated, so authenticate with the FTL server required
|
||||||
Authenthication
|
Authentication
|
||||||
|
|
||||||
# send query again
|
# send query again
|
||||||
data=$(GetFTLData "/search/${domain}?N=${max_results}&partial=${partial}")
|
data=$(GetFTLData "search/${domain}?N=${max_results}&partial=${partial}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GenerateOutput "${data}"
|
GenerateOutput "${data}"
|
||||||
@ -137,13 +136,13 @@ Main(){
|
|||||||
|
|
||||||
# Process all options (if present)
|
# Process all options (if present)
|
||||||
while [ "$#" -gt 0 ]; do
|
while [ "$#" -gt 0 ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"-h" | "--help" ) Help;;
|
"-h" | "--help") Help ;;
|
||||||
"--partial" ) partial="true";;
|
"--partial") partial="true" ;;
|
||||||
"--all" ) max_results=10000;; # hard-coded FTL limit
|
"--all") max_results=10000 ;; # hard-coded FTL limit
|
||||||
* ) domain=$1;;
|
*) domain=$1 ;;
|
||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
Main "${domain}"
|
Main "${domain}"
|
||||||
|
@ -144,7 +144,7 @@ main() {
|
|||||||
local binary
|
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)
|
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
|
if FTLcheckUpdate "${binary}"; then
|
||||||
FTL_update=true
|
FTL_update=true
|
||||||
echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}update available${COL_NC}"
|
echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}update available${COL_NC}"
|
||||||
else
|
else
|
||||||
@ -155,8 +155,13 @@ main() {
|
|||||||
2)
|
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_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."
|
||||||
;;
|
;;
|
||||||
|
3)
|
||||||
|
echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_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_LIGHT_RED}Something has gone wrong, contact support${COL_NC}"
|
||||||
|
exit 1
|
||||||
esac
|
esac
|
||||||
FTL_update=false
|
FTL_update=false
|
||||||
fi
|
fi
|
||||||
|
@ -10,27 +10,31 @@
|
|||||||
|
|
||||||
function get_local_branch() {
|
function get_local_branch() {
|
||||||
# Return active branch
|
# Return active branch
|
||||||
cd "${1}" 2> /dev/null || return 1
|
cd "${1}" 2>/dev/null || return 1
|
||||||
git rev-parse --abbrev-ref HEAD || return 1
|
git rev-parse --abbrev-ref HEAD || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_local_version() {
|
function get_local_version() {
|
||||||
# Return active version
|
# Return active version
|
||||||
cd "${1}" 2> /dev/null || return 1
|
cd "${1}" 2>/dev/null || return 1
|
||||||
git describe --tags --always 2> /dev/null || return 1
|
git describe --tags --always 2>/dev/null || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_local_hash() {
|
function get_local_hash() {
|
||||||
cd "${1}" 2> /dev/null || return 1
|
cd "${1}" 2>/dev/null || return 1
|
||||||
git rev-parse --short=8 HEAD || return 1
|
git rev-parse --short=8 HEAD || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_remote_version() {
|
function get_remote_version() {
|
||||||
curl -s "https://api.github.com/repos/pi-hole/${1}/releases/latest" 2> /dev/null | jq --raw-output .tag_name || return 1
|
# if ${2} is = "master" we need to use the "latest" endpoint, otherwise, we simply return null
|
||||||
|
if [[ "${2}" == "master" ]]; then
|
||||||
|
curl -s "https://api.github.com/repos/pi-hole/${1}/releases/latest" 2>/dev/null | jq --raw-output .tag_name || return 1
|
||||||
|
else
|
||||||
|
echo "null"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_remote_hash() {
|
||||||
function get_remote_hash(){
|
|
||||||
git ls-remote "https://github.com/pi-hole/${1}" --tags "${2}" | awk '{print substr($0, 1,8);}' || return 1
|
git ls-remote "https://github.com/pi-hole/${1}" --tags "${2}" | awk '{print substr($0, 1,8);}' || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,16 +56,15 @@ chmod 644 "${VERSION_FILE}"
|
|||||||
DOCKER_TAG=$(cat /pihole.docker.tag 2>/dev/null)
|
DOCKER_TAG=$(cat /pihole.docker.tag 2>/dev/null)
|
||||||
regex='^([0-9]+\.){1,2}(\*|[0-9]+)(-.*)?$|(^nightly$)|(^dev.*$)'
|
regex='^([0-9]+\.){1,2}(\*|[0-9]+)(-.*)?$|(^nightly$)|(^dev.*$)'
|
||||||
if [[ ! "${DOCKER_TAG}" =~ $regex ]]; then
|
if [[ ! "${DOCKER_TAG}" =~ $regex ]]; then
|
||||||
# DOCKER_TAG does not match the pattern (see https://regex101.com/r/RsENuz/1), so unset it.
|
# DOCKER_TAG does not match the pattern (see https://regex101.com/r/RsENuz/1), so unset it.
|
||||||
unset DOCKER_TAG
|
unset DOCKER_TAG
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# used in cronjob
|
# used in cronjob
|
||||||
if [[ "$1" == "reboot" ]]; then
|
if [[ "$1" == "reboot" ]]; then
|
||||||
sleep 30
|
sleep 30
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# get Core versions
|
# get Core versions
|
||||||
|
|
||||||
CORE_VERSION="$(get_local_version /etc/.pihole)"
|
CORE_VERSION="$(get_local_version /etc/.pihole)"
|
||||||
@ -73,13 +76,12 @@ addOrEditKeyValPair "${VERSION_FILE}" "CORE_BRANCH" "${CORE_BRANCH}"
|
|||||||
CORE_HASH="$(get_local_hash /etc/.pihole)"
|
CORE_HASH="$(get_local_hash /etc/.pihole)"
|
||||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_HASH" "${CORE_HASH}"
|
addOrEditKeyValPair "${VERSION_FILE}" "CORE_HASH" "${CORE_HASH}"
|
||||||
|
|
||||||
GITHUB_CORE_VERSION="$(get_remote_version pi-hole)"
|
GITHUB_CORE_VERSION="$(get_remote_version pi-hole "${CORE_BRANCH}")"
|
||||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
|
||||||
|
|
||||||
GITHUB_CORE_HASH="$(get_remote_hash pi-hole "${CORE_BRANCH}")"
|
GITHUB_CORE_HASH="$(get_remote_hash pi-hole "${CORE_BRANCH}")"
|
||||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_HASH" "${GITHUB_CORE_HASH}"
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_HASH" "${GITHUB_CORE_HASH}"
|
||||||
|
|
||||||
|
|
||||||
# get Web versions
|
# get Web versions
|
||||||
|
|
||||||
WEB_VERSION="$(get_local_version /var/www/html/admin)"
|
WEB_VERSION="$(get_local_version /var/www/html/admin)"
|
||||||
@ -91,7 +93,7 @@ addOrEditKeyValPair "${VERSION_FILE}" "WEB_BRANCH" "${WEB_BRANCH}"
|
|||||||
WEB_HASH="$(get_local_hash /var/www/html/admin)"
|
WEB_HASH="$(get_local_hash /var/www/html/admin)"
|
||||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_HASH" "${WEB_HASH}"
|
addOrEditKeyValPair "${VERSION_FILE}" "WEB_HASH" "${WEB_HASH}"
|
||||||
|
|
||||||
GITHUB_WEB_VERSION="$(get_remote_version web)"
|
GITHUB_WEB_VERSION="$(get_remote_version web "${WEB_BRANCH}")"
|
||||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
|
||||||
|
|
||||||
GITHUB_WEB_HASH="$(get_remote_hash web "${WEB_BRANCH}")"
|
GITHUB_WEB_HASH="$(get_remote_hash web "${WEB_BRANCH}")"
|
||||||
@ -108,13 +110,12 @@ addOrEditKeyValPair "${VERSION_FILE}" "FTL_BRANCH" "${FTL_BRANCH}"
|
|||||||
FTL_HASH="$(pihole-FTL --hash)"
|
FTL_HASH="$(pihole-FTL --hash)"
|
||||||
addOrEditKeyValPair "${VERSION_FILE}" "FTL_HASH" "${FTL_HASH}"
|
addOrEditKeyValPair "${VERSION_FILE}" "FTL_HASH" "${FTL_HASH}"
|
||||||
|
|
||||||
GITHUB_FTL_VERSION="$(get_remote_version FTL)"
|
GITHUB_FTL_VERSION="$(get_remote_version FTL "${FTL_BRANCH}")"
|
||||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}"
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}"
|
||||||
|
|
||||||
GITHUB_FTL_HASH="$(get_remote_hash FTL "${FTL_BRANCH}")"
|
GITHUB_FTL_HASH="$(get_remote_hash FTL "${FTL_BRANCH}")"
|
||||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_HASH" "${GITHUB_FTL_HASH}"
|
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_HASH" "${GITHUB_FTL_HASH}"
|
||||||
|
|
||||||
|
|
||||||
# get Docker versions
|
# get Docker versions
|
||||||
|
|
||||||
if [[ "${DOCKER_TAG}" ]]; then
|
if [[ "${DOCKER_TAG}" ]]; then
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
# This file is copyright under the latest version of the EUPL.
|
# This file is copyright under the latest version of the EUPL.
|
||||||
# Please see LICENSE file for your rights under this license.
|
# Please see LICENSE file for your rights under this license.
|
||||||
|
|
||||||
|
# Ignore warning about `local` being undefinded in POSIX
|
||||||
|
# shellcheck disable=SC3043
|
||||||
|
# https://github.com/koalaman/shellcheck/wiki/SC3043#exceptions
|
||||||
|
|
||||||
# Source the versions file poupulated by updatechecker.sh
|
# Source the versions file poupulated by updatechecker.sh
|
||||||
cachedVersions="/etc/pihole/versions"
|
cachedVersions="/etc/pihole/versions"
|
||||||
|
|
||||||
@ -21,118 +25,34 @@ else
|
|||||||
. "$cachedVersions"
|
. "$cachedVersions"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
getLocalVersion() {
|
main() {
|
||||||
case ${1} in
|
local details
|
||||||
"Pi-hole" ) echo "${CORE_VERSION:=N/A}";;
|
details=false
|
||||||
"web" ) echo "${WEB_VERSION:=N/A}";;
|
|
||||||
"FTL" ) echo "${FTL_VERSION:=N/A}";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
getLocalHash() {
|
# Automatically show detailed information if
|
||||||
case ${1} in
|
# at least one of the components is not on master branch
|
||||||
"Pi-hole" ) echo "${CORE_HASH:=N/A}";;
|
if [ ! "${CORE_BRANCH}" = "master" ] || [ ! "${WEB_BRANCH}" = "master" ] || [ ! "${FTL_BRANCH}" = "master" ]; then
|
||||||
"web" ) echo "${WEB_HASH:=N/A}";;
|
details=true
|
||||||
"FTL" ) echo "${FTL_HASH:=N/A}";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
getRemoteHash(){
|
|
||||||
case ${1} in
|
|
||||||
"Pi-hole" ) echo "${GITHUB_CORE_HASH:=N/A}";;
|
|
||||||
"web" ) echo "${GITHUB_WEB_HASH:=N/A}";;
|
|
||||||
"FTL" ) echo "${GITHUB_FTL_HASH:=N/A}";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
getRemoteVersion(){
|
|
||||||
case ${1} in
|
|
||||||
"Pi-hole" ) echo "${GITHUB_CORE_VERSION:=N/A}";;
|
|
||||||
"web" ) echo "${GITHUB_WEB_VERSION:=N/A}";;
|
|
||||||
"FTL" ) echo "${GITHUB_FTL_VERSION:=N/A}";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
getLocalBranch(){
|
|
||||||
case ${1} in
|
|
||||||
"Pi-hole" ) echo "${CORE_BRANCH:=N/A}";;
|
|
||||||
"web" ) echo "${WEB_BRANCH:=N/A}";;
|
|
||||||
"FTL" ) echo "${FTL_BRANCH:=N/A}";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
versionOutput() {
|
|
||||||
|
|
||||||
[ "$2" = "-c" ] || [ "$2" = "--current" ] || [ -z "$2" ] && current=$(getLocalVersion "${1}") && branch=$(getLocalBranch "${1}")
|
|
||||||
[ "$2" = "-l" ] || [ "$2" = "--latest" ] || [ -z "$2" ] && latest=$(getRemoteVersion "${1}")
|
|
||||||
if [ "$2" = "--hash" ]; then
|
|
||||||
[ "$3" = "-c" ] || [ "$3" = "--current" ] || [ -z "$3" ] && curHash=$(getLocalHash "${1}") && branch=$(getLocalBranch "${1}")
|
|
||||||
[ "$3" = "-l" ] || [ "$3" = "--latest" ] || [ -z "$3" ] && latHash=$(getRemoteHash "${1}") && branch=$(getLocalBranch "${1}")
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# We do not want to show the branch name when we are on master,
|
if [ "${details}" = true ]; then
|
||||||
# blank out the variable in this case
|
echo "Core"
|
||||||
if [ "$branch" = "master" ]; then
|
echo " Version is ${CORE_VERSION:=N/A} (Latest: ${GITHUB_CORE_VERSION:=N/A})"
|
||||||
branch=""
|
echo " Branch is ${CORE_BRANCH:=N/A}"
|
||||||
|
echo " Hash is ${CORE_HASH:=N/A} (Latest: ${GITHUB_CORE_HASH:=N/A})"
|
||||||
|
echo "Web"
|
||||||
|
echo " Version is ${WEB_VERSION:=N/A} (Latest: ${GITHUB_WEB_VERSION:=N/A})"
|
||||||
|
echo " Branch is ${WEB_BRANCH:=N/A}"
|
||||||
|
echo " Hash is ${WEB_HASH:=N/A} (Latest: ${GITHUB_WEB_HASH:=N/A})"
|
||||||
|
echo "FTL"
|
||||||
|
echo " Version is ${FTL_VERSION:=N/A} (Latest: ${GITHUB_FTL_VERSION:=N/A})"
|
||||||
|
echo " Branch is ${FTL_BRANCH:=N/A}"
|
||||||
|
echo " Hash is ${FTL_HASH:=N/A} (Latest: ${GITHUB_FTL_HASH:=N/A})"
|
||||||
else
|
else
|
||||||
branch="$branch "
|
echo "Core version is ${CORE_VERSION:=N/A} (Latest: ${GITHUB_CORE_VERSION:=N/A})"
|
||||||
|
echo "Web version is ${WEB_VERSION:=N/A} (Latest: ${GITHUB_WEB_VERSION:=N/A})"
|
||||||
|
echo "FTL version is ${FTL_VERSION:=N/A} (Latest: ${GITHUB_FTL_VERSION:=N/A})"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$current" ] && [ -n "$latest" ]; then
|
|
||||||
output="${1} version is $branch$current (Latest: $latest)"
|
|
||||||
elif [ -n "$current" ] && [ -z "$latest" ]; then
|
|
||||||
output="Current ${1} version is $branch$current"
|
|
||||||
elif [ -z "$current" ] && [ -n "$latest" ]; then
|
|
||||||
output="Latest ${1} version is $latest"
|
|
||||||
elif [ -n "$curHash" ] && [ -n "$latHash" ]; then
|
|
||||||
output="Local ${1} hash is $curHash (Remote: $latHash)"
|
|
||||||
elif [ -n "$curHash" ] && [ -z "$latHash" ]; then
|
|
||||||
output="Current local ${1} hash is $curHash"
|
|
||||||
elif [ -z "$curHash" ] && [ -n "$latHash" ]; then
|
|
||||||
output="Latest remote ${1} hash is $latHash"
|
|
||||||
elif [ -z "$curHash" ] && [ -z "$latHash" ]; then
|
|
||||||
output="Hashes for ${1} not available"
|
|
||||||
else
|
|
||||||
errorOutput
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -n "$output" ] && echo " $output"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errorOutput() {
|
main
|
||||||
echo " Invalid Option! Try 'pihole -v --help' for more information."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultOutput() {
|
|
||||||
versionOutput "Pi-hole" "$@"
|
|
||||||
versionOutput "web" "$@"
|
|
||||||
versionOutput "FTL" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
helpFunc() {
|
|
||||||
echo "Usage: pihole -v [repo | option] [option]
|
|
||||||
Example: 'pihole -v -p -l'
|
|
||||||
Show Pi-hole, Admin Console & FTL versions
|
|
||||||
|
|
||||||
Repositories:
|
|
||||||
-p, --pihole Only retrieve info regarding Pi-hole repository
|
|
||||||
-a, --admin Only retrieve info regarding web repository
|
|
||||||
-f, --ftl Only retrieve info regarding FTL repository
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-c, --current Return the current version
|
|
||||||
-l, --latest Return the latest version
|
|
||||||
--hash Return the GitHub hash from your local repositories
|
|
||||||
-h, --help Show this help dialog"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
case "${1}" in
|
|
||||||
"-p" | "--pihole" ) shift; versionOutput "Pi-hole" "$@";;
|
|
||||||
"-a" | "--admin" ) shift; versionOutput "web" "$@";;
|
|
||||||
"-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
|
|
||||||
"-h" | "--help" ) helpFunc;;
|
|
||||||
* ) defaultOutput "$@";;
|
|
||||||
esac
|
|
||||||
|
@ -65,7 +65,7 @@ CREATE TABLE info
|
|||||||
value TEXT NOT NULL
|
value TEXT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO "info" VALUES('version','17');
|
INSERT INTO "info" VALUES('version','18');
|
||||||
|
|
||||||
CREATE TABLE domain_audit
|
CREATE TABLE domain_audit
|
||||||
(
|
(
|
||||||
@ -144,14 +144,14 @@ CREATE VIEW vw_regex_blacklist AS SELECT domain, domainlist.id AS id, domainlist
|
|||||||
AND domainlist.type = 3
|
AND domainlist.type = 3
|
||||||
ORDER BY domainlist.id;
|
ORDER BY domainlist.id;
|
||||||
|
|
||||||
CREATE VIEW vw_gravity AS SELECT domain, adlist_by_group.group_id AS group_id
|
CREATE VIEW vw_gravity AS SELECT domain, adlist.id AS adlist_id, adlist_by_group.group_id AS group_id
|
||||||
FROM gravity
|
FROM gravity
|
||||||
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = gravity.adlist_id
|
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = gravity.adlist_id
|
||||||
LEFT JOIN adlist ON adlist.id = gravity.adlist_id
|
LEFT JOIN adlist ON adlist.id = gravity.adlist_id
|
||||||
LEFT JOIN "group" ON "group".id = adlist_by_group.group_id
|
LEFT JOIN "group" ON "group".id = adlist_by_group.group_id
|
||||||
WHERE adlist.enabled = 1 AND (adlist_by_group.group_id IS NULL OR "group".enabled = 1);
|
WHERE adlist.enabled = 1 AND (adlist_by_group.group_id IS NULL OR "group".enabled = 1);
|
||||||
|
|
||||||
CREATE VIEW vw_antigravity AS SELECT domain, adlist_by_group.group_id AS group_id
|
CREATE VIEW vw_antigravity AS SELECT domain, adlist.id AS adlist_id, adlist_by_group.group_id AS group_id
|
||||||
FROM antigravity
|
FROM antigravity
|
||||||
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = antigravity.adlist_id
|
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = antigravity.adlist_id
|
||||||
LEFT JOIN adlist ON adlist.id = antigravity.adlist_id
|
LEFT JOIN adlist ON adlist.id = antigravity.adlist_id
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# Pi-hole: A black hole for Internet advertisements
|
|
||||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
||||||
# Network-wide ad blocking via your own hardware.
|
|
||||||
#
|
|
||||||
# Allows the WebUI to use Pi-hole commands
|
|
||||||
#
|
|
||||||
# This file is copyright under the latest version of the EUPL.
|
|
||||||
# Please see LICENSE file for your rights under this license.
|
|
||||||
#
|
|
@ -1,5 +1,5 @@
|
|||||||
_pihole() {
|
_pihole() {
|
||||||
local cur prev opts opts_admin opts_checkout opts_debug opts_interface opts_logging opts_privacy opts_query opts_update opts_version
|
local cur prev opts opts_checkout opts_debug opts_logging opts_query opts_update opts_version
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
@ -7,17 +7,13 @@ _pihole() {
|
|||||||
|
|
||||||
case "${prev}" in
|
case "${prev}" in
|
||||||
"pihole")
|
"pihole")
|
||||||
opts="admin blacklist checkout debug disable enable flush help logging query reconfigure regex restartdns status tail uninstall updateGravity updatePihole version wildcard whitelist arpflush"
|
opts="blacklist checkout debug disable enable flush help logging query reconfigure regex restartdns status tail uninstall updateGravity updatePihole version wildcard whitelist arpflush"
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"whitelist"|"blacklist"|"wildcard"|"regex")
|
"whitelist"|"blacklist"|"wildcard"|"regex")
|
||||||
opts_lists="\--delmode \--noreload \--quiet \--list \--nuke"
|
opts_lists="\--delmode \--noreload \--quiet \--list \--nuke"
|
||||||
COMPREPLY=( $(compgen -W "${opts_lists}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_lists}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"admin")
|
|
||||||
opts_admin="celsius fahrenheit interface kelvin password privacylevel"
|
|
||||||
COMPREPLY=( $(compgen -W "${opts_admin}" -- ${cur}) )
|
|
||||||
;;
|
|
||||||
"checkout")
|
"checkout")
|
||||||
opts_checkout="core ftl web master dev"
|
opts_checkout="core ftl web master dev"
|
||||||
COMPREPLY=( $(compgen -W "${opts_checkout}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_checkout}" -- ${cur}) )
|
||||||
@ -31,33 +27,13 @@ _pihole() {
|
|||||||
COMPREPLY=( $(compgen -W "${opts_logging}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_logging}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"query")
|
"query")
|
||||||
opts_query="-adlist -all -exact"
|
opts_query="--partial --all"
|
||||||
COMPREPLY=( $(compgen -W "${opts_query}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_query}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"updatePihole"|"-up")
|
"updatePihole"|"-up")
|
||||||
opts_update="--check-only"
|
opts_update="--check-only"
|
||||||
COMPREPLY=( $(compgen -W "${opts_update}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts_update}" -- ${cur}) )
|
||||||
;;
|
;;
|
||||||
"version")
|
|
||||||
opts_version="\--admin \--current \--ftl \--hash \--latest \--pihole"
|
|
||||||
COMPREPLY=( $(compgen -W "${opts_version}" -- ${cur}) )
|
|
||||||
;;
|
|
||||||
"interface")
|
|
||||||
if ( [[ "$prev2" == "admin" ]] || [[ "$prev2" == "-a" ]] ); then
|
|
||||||
opts_interface="$(cat /proc/net/dev | cut -d: -s -f1)"
|
|
||||||
COMPREPLY=( $(compgen -W "${opts_interface}" -- ${cur}) )
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"privacylevel")
|
|
||||||
if ( [[ "$prev2" == "admin" ]] || [[ "$prev2" == "-a" ]] ); then
|
|
||||||
opts_privacy="0 1 2 3"
|
|
||||||
COMPREPLY=( $(compgen -W "${opts_privacy}" -- ${cur}) )
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"core"|"admin"|"ftl")
|
"core"|"admin"|"ftl")
|
||||||
if [[ "$prev2" == "checkout" ]]; then
|
if [[ "$prev2" == "checkout" ]]; then
|
||||||
opts_checkout="master dev"
|
opts_checkout="master dev"
|
||||||
|
File diff suppressed because it is too large
Load Diff
259
gravity.sh
259
gravity.sh
@ -36,21 +36,16 @@ blacklistFile="${piholeDir}/blacklist.txt"
|
|||||||
regexFile="${piholeDir}/regex.list"
|
regexFile="${piholeDir}/regex.list"
|
||||||
adListFile="${piholeDir}/adlists.list"
|
adListFile="${piholeDir}/adlists.list"
|
||||||
|
|
||||||
localList="${piholeDir}/local.list"
|
|
||||||
VPNList="/etc/openvpn/ipp.txt"
|
|
||||||
|
|
||||||
piholeGitDir="/etc/.pihole"
|
piholeGitDir="/etc/.pihole"
|
||||||
GRAVITYDB=$(getFTLConfigValue files.gravity)
|
GRAVITYDB=$(getFTLConfigValue files.gravity)
|
||||||
|
GRAVITY_TMPDIR=$(getFTLConfigValue files.gravity_tmp)
|
||||||
gravityDBschema="${piholeGitDir}/advanced/Templates/gravity.db.sql"
|
gravityDBschema="${piholeGitDir}/advanced/Templates/gravity.db.sql"
|
||||||
gravityDBcopy="${piholeGitDir}/advanced/Templates/gravity_copy.sql"
|
gravityDBcopy="${piholeGitDir}/advanced/Templates/gravity_copy.sql"
|
||||||
|
|
||||||
domainsExtension="domains"
|
domainsExtension="domains"
|
||||||
curl_connect_timeout=10
|
curl_connect_timeout=10
|
||||||
|
|
||||||
|
# Check gravity temp directory
|
||||||
# Set up tmp dir variable in case it's not configured
|
|
||||||
: "${GRAVITY_TMPDIR:=/tmp}"
|
|
||||||
|
|
||||||
if [ ! -d "${GRAVITY_TMPDIR}" ] || [ ! -w "${GRAVITY_TMPDIR}" ]; then
|
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_LIGHT_RED}Gravity temporary directory does not exist or is not a writeable directory, falling back to /tmp. ${COL_NC}"
|
||||||
GRAVITY_TMPDIR="/tmp"
|
GRAVITY_TMPDIR="/tmp"
|
||||||
@ -65,7 +60,7 @@ gravityOLDfile="${gravityDIR}/gravity_old.db"
|
|||||||
|
|
||||||
# Generate new SQLite3 file from schema template
|
# Generate new SQLite3 file from schema template
|
||||||
generate_gravity_database() {
|
generate_gravity_database() {
|
||||||
if ! pihole-FTL sqlite3 "${gravityDBfile}" < "${gravityDBschema}"; then
|
if ! pihole-FTL sqlite3 -ni "${gravityDBfile}" <"${gravityDBschema}"; then
|
||||||
echo -e " ${CROSS} Unable to create ${gravityDBfile}"
|
echo -e " ${CROSS} Unable to create ${gravityDBfile}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -80,7 +75,7 @@ gravity_build_tree() {
|
|||||||
echo -ne " ${INFO} ${str}..."
|
echo -ne " ${INFO} ${str}..."
|
||||||
|
|
||||||
# The index is intentionally not UNIQUE as poor quality adlists may contain domains more than once
|
# The index is intentionally not UNIQUE as poor quality adlists may contain domains more than once
|
||||||
output=$( { pihole-FTL sqlite3 "${gravityTEMPfile}" "CREATE INDEX idx_gravity ON gravity (domain, adlist_id);"; } 2>&1 )
|
output=$({ pihole-FTL sqlite3 -ni "${gravityTEMPfile}" "CREATE INDEX idx_gravity ON gravity (domain, adlist_id);"; } 2>&1)
|
||||||
status="$?"
|
status="$?"
|
||||||
|
|
||||||
if [[ "${status}" -ne 0 ]]; then
|
if [[ "${status}" -ne 0 ]]; then
|
||||||
@ -119,7 +114,7 @@ gravity_swap_databases() {
|
|||||||
|
|
||||||
# Update timestamp when the gravity table was last updated successfully
|
# Update timestamp when the gravity table was last updated successfully
|
||||||
update_gravity_timestamp() {
|
update_gravity_timestamp() {
|
||||||
output=$( { printf ".timeout 30000\\nINSERT OR REPLACE INTO info (property,value) values ('updated',cast(strftime('%%s', 'now') as int));" | pihole-FTL sqlite3 "${gravityTEMPfile}"; } 2>&1 )
|
output=$({ printf ".timeout 30000\\nINSERT OR REPLACE INTO info (property,value) values ('updated',cast(strftime('%%s', 'now') as int));" | pihole-FTL sqlite3 -ni "${gravityTEMPfile}"; } 2>&1)
|
||||||
status="$?"
|
status="$?"
|
||||||
|
|
||||||
if [[ "${status}" -ne 0 ]]; then
|
if [[ "${status}" -ne 0 ]]; then
|
||||||
@ -164,7 +159,7 @@ database_table_from_file() {
|
|||||||
|
|
||||||
# Get MAX(id) from domainlist when INSERTing into this table
|
# Get MAX(id) from domainlist when INSERTing into this table
|
||||||
if [[ "${table}" == "domainlist" ]]; then
|
if [[ "${table}" == "domainlist" ]]; then
|
||||||
rowid="$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT MAX(id) FROM domainlist;")"
|
rowid="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT MAX(id) FROM domainlist;")"
|
||||||
if [[ -z "$rowid" ]]; then
|
if [[ -z "$rowid" ]]; then
|
||||||
rowid=0
|
rowid=0
|
||||||
fi
|
fi
|
||||||
@ -173,19 +168,18 @@ database_table_from_file() {
|
|||||||
|
|
||||||
# Loop over all domains in ${src} file
|
# Loop over all domains in ${src} file
|
||||||
# Read file line by line
|
# Read file line by line
|
||||||
grep -v '^ *#' < "${src}" | while IFS= read -r domain
|
grep -v '^ *#' <"${src}" | while IFS= read -r domain; do
|
||||||
do
|
|
||||||
# Only add non-empty lines
|
# Only add non-empty lines
|
||||||
if [[ -n "${domain}" ]]; then
|
if [[ -n "${domain}" ]]; then
|
||||||
if [[ "${table}" == "domain_audit" ]]; then
|
if [[ "${table}" == "domain_audit" ]]; then
|
||||||
# domain_audit table format (no enable or modified fields)
|
# domain_audit table format (no enable or modified fields)
|
||||||
echo "${rowid},\"${domain}\",${timestamp}" >> "${tmpFile}"
|
echo "${rowid},\"${domain}\",${timestamp}" >>"${tmpFile}"
|
||||||
elif [[ "${table}" == "adlist" ]]; then
|
elif [[ "${table}" == "adlist" ]]; then
|
||||||
# Adlist table format
|
# Adlist table format
|
||||||
echo "${rowid},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${src}\",,0,0,0,0,0" >> "${tmpFile}"
|
echo "${rowid},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${src}\",,0,0,0,0,0" >>"${tmpFile}"
|
||||||
else
|
else
|
||||||
# White-, black-, and regexlist table format
|
# White-, black-, and regexlist table format
|
||||||
echo "${rowid},${list_type},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${src}\"" >> "${tmpFile}"
|
echo "${rowid},${list_type},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${src}\"" >>"${tmpFile}"
|
||||||
fi
|
fi
|
||||||
rowid+=1
|
rowid+=1
|
||||||
fi
|
fi
|
||||||
@ -194,7 +188,7 @@ database_table_from_file() {
|
|||||||
# Store domains in database table specified by ${table}
|
# Store domains in database table specified by ${table}
|
||||||
# Use printf as .mode and .import need to be on separate lines
|
# Use printf as .mode and .import need to be on separate lines
|
||||||
# see https://unix.stackexchange.com/a/445615/83260
|
# see https://unix.stackexchange.com/a/445615/83260
|
||||||
output=$( { printf ".timeout 30000\\n.mode csv\\n.import \"%s\" %s\\n" "${tmpFile}" "${table}" | pihole-FTL sqlite3 "${gravityDBfile}"; } 2>&1 )
|
output=$({ printf ".timeout 30000\\n.mode csv\\n.import \"%s\" %s\\n" "${tmpFile}" "${table}" | pihole-FTL sqlite3 -ni "${gravityDBfile}"; } 2>&1)
|
||||||
status="$?"
|
status="$?"
|
||||||
|
|
||||||
if [[ "${status}" -ne 0 ]]; then
|
if [[ "${status}" -ne 0 ]]; then
|
||||||
@ -204,17 +198,17 @@ database_table_from_file() {
|
|||||||
|
|
||||||
# Move source file to backup directory, create directory if not existing
|
# Move source file to backup directory, create directory if not existing
|
||||||
mkdir -p "${backup_path}"
|
mkdir -p "${backup_path}"
|
||||||
mv "${src}" "${backup_file}" 2> /dev/null || \
|
mv "${src}" "${backup_file}" 2>/dev/null ||
|
||||||
echo -e " ${CROSS} Unable to backup ${src} to ${backup_path}"
|
echo -e " ${CROSS} Unable to backup ${src} to ${backup_path}"
|
||||||
|
|
||||||
# Delete tmpFile
|
# Delete tmpFile
|
||||||
rm "${tmpFile}" > /dev/null 2>&1 || \
|
rm "${tmpFile}" >/dev/null 2>&1 ||
|
||||||
echo -e " ${CROSS} Unable to remove ${tmpFile}"
|
echo -e " ${CROSS} Unable to remove ${tmpFile}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if a column with name ${2} exists in gravity table with name ${1}
|
# Check if a column with name ${2} exists in gravity table with name ${1}
|
||||||
gravity_column_exists() {
|
gravity_column_exists() {
|
||||||
output=$( { printf ".timeout 30000\\nSELECT EXISTS(SELECT * FROM pragma_table_info('%s') WHERE name='%s');\\n" "${1}" "${2}" | pihole-FTL sqlite3 "${gravityTEMPfile}"; } 2>&1 )
|
output=$({ printf ".timeout 30000\\nSELECT EXISTS(SELECT * FROM pragma_table_info('%s') WHERE name='%s');\\n" "${1}" "${2}" | pihole-FTL sqlite3 -ni "${gravityTEMPfile}"; } 2>&1)
|
||||||
if [[ "${output}" == "1" ]]; then
|
if [[ "${output}" == "1" ]]; then
|
||||||
return 0 # Bash 0 is success
|
return 0 # Bash 0 is success
|
||||||
fi
|
fi
|
||||||
@ -226,10 +220,10 @@ gravity_column_exists() {
|
|||||||
database_adlist_number() {
|
database_adlist_number() {
|
||||||
# Only try to set number of domains when this field exists in the gravity database
|
# Only try to set number of domains when this field exists in the gravity database
|
||||||
if ! gravity_column_exists "adlist" "number"; then
|
if ! gravity_column_exists "adlist" "number"; then
|
||||||
return;
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET number = %i, invalid_domains = %i WHERE id = %i;\\n" "${2}" "${3}" "${1}" | pihole-FTL sqlite3 "${gravityTEMPfile}"; } 2>&1 )
|
output=$({ printf ".timeout 30000\\nUPDATE adlist SET number = %i, invalid_domains = %i WHERE id = %i;\\n" "${2}" "${3}" "${1}" | pihole-FTL sqlite3 -ni "${gravityTEMPfile}"; } 2>&1)
|
||||||
status="$?"
|
status="$?"
|
||||||
|
|
||||||
if [[ "${status}" -ne 0 ]]; then
|
if [[ "${status}" -ne 0 ]]; then
|
||||||
@ -242,10 +236,10 @@ database_adlist_number() {
|
|||||||
database_adlist_status() {
|
database_adlist_status() {
|
||||||
# Only try to set the status when this field exists in the gravity database
|
# Only try to set the status when this field exists in the gravity database
|
||||||
if ! gravity_column_exists "adlist" "status"; then
|
if ! gravity_column_exists "adlist" "status"; then
|
||||||
return;
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET status = %i WHERE id = %i;\\n" "${2}" "${1}" | pihole-FTL sqlite3 "${gravityTEMPfile}"; } 2>&1 )
|
output=$({ printf ".timeout 30000\\nUPDATE adlist SET status = %i WHERE id = %i;\\n" "${2}" "${1}" | pihole-FTL sqlite3 -ni "${gravityTEMPfile}"; } 2>&1)
|
||||||
status="$?"
|
status="$?"
|
||||||
|
|
||||||
if [[ "${status}" -ne 0 ]]; then
|
if [[ "${status}" -ne 0 ]]; then
|
||||||
@ -299,15 +293,10 @@ migrate_to_database() {
|
|||||||
|
|
||||||
# Determine if DNS resolution is available before proceeding
|
# Determine if DNS resolution is available before proceeding
|
||||||
gravity_CheckDNSResolutionAvailable() {
|
gravity_CheckDNSResolutionAvailable() {
|
||||||
local lookupDomain="pi.hole"
|
local lookupDomain="raw.githubusercontent.com"
|
||||||
|
|
||||||
# Determine if $localList does not exist, and ensure it is not empty
|
|
||||||
if [[ ! -e "${localList}" ]] || [[ -s "${localList}" ]]; then
|
|
||||||
lookupDomain="raw.githubusercontent.com"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Determine if $lookupDomain is resolvable
|
# Determine if $lookupDomain is resolvable
|
||||||
if timeout 4 getent hosts "${lookupDomain}" &> /dev/null; then
|
if timeout 4 getent hosts "${lookupDomain}" &>/dev/null; then
|
||||||
# Print confirmation of resolvability if it had previously failed
|
# Print confirmation of resolvability if it had previously failed
|
||||||
if [[ -n "${secs:-}" ]]; then
|
if [[ -n "${secs:-}" ]]; then
|
||||||
echo -e "${OVER} ${TICK} DNS resolution is now available\\n"
|
echo -e "${OVER} ${TICK} DNS resolution is now available\\n"
|
||||||
@ -321,7 +310,7 @@ gravity_CheckDNSResolutionAvailable() {
|
|||||||
# If the /etc/resolv.conf contains resolvers other than 127.0.0.1 then the local dnsmasq will not be queried and pi.hole is NXDOMAIN.
|
# If the /etc/resolv.conf contains resolvers other than 127.0.0.1 then the local dnsmasq will not be queried and pi.hole is NXDOMAIN.
|
||||||
# This means that even though name resolution is working, the getent hosts check fails and the holddown timer keeps ticking and eventually fails
|
# This means that even though name resolution is working, the getent hosts check fails and the holddown timer keeps ticking and eventually fails
|
||||||
# So we check the output of the last command and if it failed, attempt to use dig +short as a fallback
|
# So we check the output of the last command and if it failed, attempt to use dig +short as a fallback
|
||||||
if timeout 4 dig +short "${lookupDomain}" &> /dev/null; then
|
if timeout 4 dig +short "${lookupDomain}" &>/dev/null; then
|
||||||
if [[ -n "${secs:-}" ]]; then
|
if [[ -n "${secs:-}" ]]; then
|
||||||
echo -e "${OVER} ${TICK} DNS resolution is now available\\n"
|
echo -e "${OVER} ${TICK} DNS resolution is now available\\n"
|
||||||
fi
|
fi
|
||||||
@ -332,7 +321,7 @@ gravity_CheckDNSResolutionAvailable() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Determine error output message
|
# Determine error output message
|
||||||
if pgrep pihole-FTL &> /dev/null; then
|
if pgrep pihole-FTL &>/dev/null; then
|
||||||
echo -e " ${CROSS} DNS resolution is currently unavailable"
|
echo -e " ${CROSS} DNS resolution is currently unavailable"
|
||||||
else
|
else
|
||||||
echo -e " ${CROSS} DNS service is not running"
|
echo -e " ${CROSS} DNS service is not running"
|
||||||
@ -342,7 +331,7 @@ gravity_CheckDNSResolutionAvailable() {
|
|||||||
# Ensure DNS server is given time to be resolvable
|
# Ensure DNS server is given time to be resolvable
|
||||||
secs="120"
|
secs="120"
|
||||||
echo -ne " ${INFO} Time until retry: ${secs}"
|
echo -ne " ${INFO} Time until retry: ${secs}"
|
||||||
until timeout 1 getent hosts "${lookupDomain}" &> /dev/null; do
|
until timeout 1 getent hosts "${lookupDomain}" &>/dev/null; do
|
||||||
[[ "${secs:-}" -eq 0 ]] && break
|
[[ "${secs:-}" -eq 0 ]] && break
|
||||||
echo -ne "${OVER} ${INFO} Time until retry: ${secs}"
|
echo -ne "${OVER} ${INFO} Time until retry: ${secs}"
|
||||||
: $((secs--))
|
: $((secs--))
|
||||||
@ -363,19 +352,19 @@ gravity_DownloadBlocklists() {
|
|||||||
|
|
||||||
# Retrieve source URLs from gravity database
|
# Retrieve source URLs from gravity database
|
||||||
# We source only enabled adlists, SQLite3 stores boolean values as 0 (false) or 1 (true)
|
# We source only enabled adlists, SQLite3 stores boolean values as 0 (false) or 1 (true)
|
||||||
mapfile -t sources <<< "$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT address FROM vw_adlist;" 2> /dev/null)"
|
mapfile -t sources <<<"$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT address FROM vw_adlist;" 2>/dev/null)"
|
||||||
mapfile -t sourceIDs <<< "$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT id FROM vw_adlist;" 2> /dev/null)"
|
mapfile -t sourceIDs <<<"$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT id FROM vw_adlist;" 2>/dev/null)"
|
||||||
mapfile -t sourceTypes <<< "$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT type FROM vw_adlist;" 2> /dev/null)"
|
mapfile -t sourceTypes <<<"$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT type FROM vw_adlist;" 2>/dev/null)"
|
||||||
|
|
||||||
# Parse source domains from $sources
|
# Parse source domains from $sources
|
||||||
mapfile -t sourceDomains <<< "$(
|
mapfile -t sourceDomains <<<"$(
|
||||||
# Logic: Split by folder/port
|
# Logic: Split by folder/port
|
||||||
awk -F '[/:]' '{
|
awk -F '[/:]' '{
|
||||||
# Remove URL protocol & optional username:password@
|
# Remove URL protocol & optional username:password@
|
||||||
gsub(/(.*:\/\/|.*:.*@)/, "", $0)
|
gsub(/(.*:\/\/|.*:.*@)/, "", $0)
|
||||||
if(length($1)>0){print $1}
|
if(length($1)>0){print $1}
|
||||||
else {print "local"}
|
else {print "local"}
|
||||||
}' <<< "$(printf '%s\n' "${sources[@]}")" 2> /dev/null
|
}' <<<"$(printf '%s\n' "${sources[@]}")" 2>/dev/null
|
||||||
)"
|
)"
|
||||||
|
|
||||||
local str="Pulling blocklist source list into range"
|
local str="Pulling blocklist source list into range"
|
||||||
@ -393,8 +382,8 @@ gravity_DownloadBlocklists() {
|
|||||||
# Prepare new gravity database
|
# Prepare new gravity database
|
||||||
str="Preparing new gravity database"
|
str="Preparing new gravity database"
|
||||||
echo -ne " ${INFO} ${str}..."
|
echo -ne " ${INFO} ${str}..."
|
||||||
rm "${gravityTEMPfile}" > /dev/null 2>&1
|
rm "${gravityTEMPfile}" >/dev/null 2>&1
|
||||||
output=$( { pihole-FTL sqlite3 "${gravityTEMPfile}" < "${gravityDBschema}"; } 2>&1 )
|
output=$({ pihole-FTL sqlite3 -ni "${gravityTEMPfile}" <"${gravityDBschema}"; } 2>&1)
|
||||||
status="$?"
|
status="$?"
|
||||||
|
|
||||||
if [[ "${status}" -ne 0 ]]; then
|
if [[ "${status}" -ne 0 ]]; then
|
||||||
@ -414,7 +403,7 @@ gravity_DownloadBlocklists() {
|
|||||||
copyGravity="${copyGravity//"${gravityDBfile_default}"/"${gravityDBfile}"}"
|
copyGravity="${copyGravity//"${gravityDBfile_default}"/"${gravityDBfile}"}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
output=$( { pihole-FTL sqlite3 "${gravityTEMPfile}" <<< "${copyGravity}"; } 2>&1 )
|
output=$({ pihole-FTL sqlite3 -ni "${gravityTEMPfile}" <<<"${copyGravity}"; } 2>&1)
|
||||||
status="$?"
|
status="$?"
|
||||||
|
|
||||||
if [[ "${status}" -ne 0 ]]; then
|
if [[ "${status}" -ne 0 ]]; then
|
||||||
@ -459,7 +448,7 @@ gravity_DownloadBlocklists() {
|
|||||||
|
|
||||||
# this will remove first @ that is after schema and before domain
|
# this will remove first @ that is after schema and before domain
|
||||||
# \1 is optional schema, \2 is userinfo
|
# \1 is optional schema, \2 is userinfo
|
||||||
check_url="$( sed -re 's#([^:/]*://)?([^/]+)@#\1\2#' <<< "$url" )"
|
check_url="$(sed -re 's#([^:/]*://)?([^/]+)@#\1\2#' <<<"$url")"
|
||||||
|
|
||||||
if [[ "${check_url}" =~ ${regex} ]]; then
|
if [[ "${check_url}" =~ ${regex} ]]; then
|
||||||
echo -e " ${CROSS} Invalid Target"
|
echo -e " ${CROSS} Invalid Target"
|
||||||
@ -479,7 +468,7 @@ compareLists() {
|
|||||||
if [[ -s "${target}.sha1" ]]; then
|
if [[ -s "${target}.sha1" ]]; then
|
||||||
if ! sha1sum --check --status --strict "${target}.sha1"; then
|
if ! sha1sum --check --status --strict "${target}.sha1"; then
|
||||||
# The list changed upstream, we need to update the checksum
|
# The list changed upstream, we need to update the checksum
|
||||||
sha1sum "${target}" > "${target}.sha1"
|
sha1sum "${target}" >"${target}.sha1"
|
||||||
echo " ${INFO} List has been updated"
|
echo " ${INFO} List has been updated"
|
||||||
database_adlist_status "${adlistID}" "1"
|
database_adlist_status "${adlistID}" "1"
|
||||||
else
|
else
|
||||||
@ -488,7 +477,7 @@ compareLists() {
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# No checksum available, create one for comparing on the next run
|
# No checksum available, create one for comparing on the next run
|
||||||
sha1sum "${target}" > "${target}.sha1"
|
sha1sum "${target}" >"${target}.sha1"
|
||||||
# We assume here it was changed upstream
|
# We assume here it was changed upstream
|
||||||
database_adlist_status "${adlistID}" "1"
|
database_adlist_status "${adlistID}" "1"
|
||||||
fi
|
fi
|
||||||
@ -517,25 +506,29 @@ gravity_DownloadBlocklistFromUrl() {
|
|||||||
echo -ne " ${INFO} ${str} Pending..."
|
echo -ne " ${INFO} ${str} Pending..."
|
||||||
blocked=false
|
blocked=false
|
||||||
case $(getFTLConfigValue dns.blocking.mode) in
|
case $(getFTLConfigValue dns.blocking.mode) in
|
||||||
"IP-NODATA-AAAA"|"IP")
|
"IP-NODATA-AAAA" | "IP")
|
||||||
# Get IP address of this domain
|
# Get IP address of this domain
|
||||||
ip="$(dig "${domain}" +short)"
|
ip="$(dig "${domain}" +short)"
|
||||||
# Check if this IP matches any IP of the system
|
# Check if this IP matches any IP of the system
|
||||||
if [[ -n "${ip}" && $(grep -Ec "inet(|6) ${ip}" <<< "$(ip a)") -gt 0 ]]; then
|
if [[ -n "${ip}" && $(grep -Ec "inet(|6) ${ip}" <<<"$(ip a)") -gt 0 ]]; then
|
||||||
blocked=true
|
blocked=true
|
||||||
fi;;
|
fi
|
||||||
"NXDOMAIN")
|
;;
|
||||||
if [[ $(dig "${domain}" | grep "NXDOMAIN" -c) -ge 1 ]]; then
|
"NXDOMAIN")
|
||||||
blocked=true
|
if [[ $(dig "${domain}" | grep "NXDOMAIN" -c) -ge 1 ]]; then
|
||||||
fi;;
|
blocked=true
|
||||||
"NODATA")
|
fi
|
||||||
if [[ $(dig "${domain}" | grep "NOERROR" -c) -ge 1 ]] && [[ -z $(dig +short "${domain}") ]]; then
|
;;
|
||||||
blocked=true
|
"NODATA")
|
||||||
fi;;
|
if [[ $(dig "${domain}" | grep "NOERROR" -c) -ge 1 ]] && [[ -z $(dig +short "${domain}") ]]; then
|
||||||
"NULL"|*)
|
blocked=true
|
||||||
if [[ $(dig "${domain}" +short | grep "0.0.0.0" -c) -ge 1 ]]; then
|
fi
|
||||||
blocked=true
|
;;
|
||||||
fi;;
|
"NULL" | *)
|
||||||
|
if [[ $(dig "${domain}" +short | grep "0.0.0.0" -c) -ge 1 ]]; then
|
||||||
|
blocked=true
|
||||||
|
fi
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ "${blocked}" == true ]]; then
|
if [[ "${blocked}" == true ]]; then
|
||||||
@ -547,43 +540,53 @@ gravity_DownloadBlocklistFromUrl() {
|
|||||||
fi
|
fi
|
||||||
ip=$(dig "@${ip_addr}" -p "${port}" +short "${domain}" | tail -1)
|
ip=$(dig "@${ip_addr}" -p "${port}" +short "${domain}" | tail -1)
|
||||||
if [[ $(echo "${url}" | awk -F '://' '{print $1}') = "https" ]]; then
|
if [[ $(echo "${url}" | awk -F '://' '{print $1}') = "https" ]]; then
|
||||||
port=443;
|
port=443
|
||||||
else port=80
|
else
|
||||||
|
port=80
|
||||||
fi
|
fi
|
||||||
bad_list=$(pihole -q -adlist "${domain}" | head -n1 | awk -F 'Match found in ' '{print $2}')
|
bad_list=$(pihole -q -adlist "${domain}" | head -n1 | awk -F 'Match found in ' '{print $2}')
|
||||||
echo -e "${OVER} ${CROSS} ${str} ${domain} is blocked by ${bad_list%:}. Using DNS on ${PIHOLE_DNS_1} to download ${url}";
|
echo -e "${OVER} ${CROSS} ${str} ${domain} is blocked by ${bad_list%:}. Using DNS on ${PIHOLE_DNS_1} to download ${url}"
|
||||||
echo -ne " ${INFO} ${str} Pending..."
|
echo -ne " ${INFO} ${str} Pending..."
|
||||||
cmd_ext="--resolve $domain:$port:$ip"
|
cmd_ext="--resolve $domain:$port:$ip"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2> /dev/null)
|
httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2>/dev/null)
|
||||||
|
|
||||||
case $url in
|
case $url in
|
||||||
# Did we "download" a local file?
|
# Did we "download" a local file?
|
||||||
"file"*)
|
"file"*)
|
||||||
if [[ -s "${listCurlBuffer}" ]]; then
|
if [[ -s "${listCurlBuffer}" ]]; then
|
||||||
echo -e "${OVER} ${TICK} ${str} Retrieval successful"; success=true
|
echo -e "${OVER} ${TICK} ${str} Retrieval successful"
|
||||||
else
|
success=true
|
||||||
echo -e "${OVER} ${CROSS} ${str} Not found / empty list"
|
else
|
||||||
fi;;
|
echo -e "${OVER} ${CROSS} ${str} Not found / empty list"
|
||||||
# Did we "download" a remote file?
|
fi
|
||||||
*)
|
;;
|
||||||
# Determine "Status:" output based on HTTP response
|
# Did we "download" a remote file?
|
||||||
case "${httpCode}" in
|
*)
|
||||||
"200") echo -e "${OVER} ${TICK} ${str} Retrieval successful"; success=true;;
|
# Determine "Status:" output based on HTTP response
|
||||||
"304") echo -e "${OVER} ${TICK} ${str} No changes detected"; success=true;;
|
case "${httpCode}" in
|
||||||
"000") echo -e "${OVER} ${CROSS} ${str} Connection Refused";;
|
"200")
|
||||||
"403") echo -e "${OVER} ${CROSS} ${str} Forbidden";;
|
echo -e "${OVER} ${TICK} ${str} Retrieval successful"
|
||||||
"404") echo -e "${OVER} ${CROSS} ${str} Not found";;
|
success=true
|
||||||
"408") echo -e "${OVER} ${CROSS} ${str} Time-out";;
|
;;
|
||||||
"451") echo -e "${OVER} ${CROSS} ${str} Unavailable For Legal Reasons";;
|
"304")
|
||||||
"500") echo -e "${OVER} ${CROSS} ${str} Internal Server Error";;
|
echo -e "${OVER} ${TICK} ${str} No changes detected"
|
||||||
"504") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Gateway)";;
|
success=true
|
||||||
"521") echo -e "${OVER} ${CROSS} ${str} Web Server Is Down (Cloudflare)";;
|
;;
|
||||||
"522") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Cloudflare)";;
|
"000") echo -e "${OVER} ${CROSS} ${str} Connection Refused" ;;
|
||||||
* ) echo -e "${OVER} ${CROSS} ${str} ${url} (${httpCode})";;
|
"403") echo -e "${OVER} ${CROSS} ${str} Forbidden" ;;
|
||||||
esac;;
|
"404") echo -e "${OVER} ${CROSS} ${str} Not found" ;;
|
||||||
|
"408") echo -e "${OVER} ${CROSS} ${str} Time-out" ;;
|
||||||
|
"451") echo -e "${OVER} ${CROSS} ${str} Unavailable For Legal Reasons" ;;
|
||||||
|
"500") echo -e "${OVER} ${CROSS} ${str} Internal Server Error" ;;
|
||||||
|
"504") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Gateway)" ;;
|
||||||
|
"521") echo -e "${OVER} ${CROSS} ${str} Web Server Is Down (Cloudflare)" ;;
|
||||||
|
"522") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Cloudflare)" ;;
|
||||||
|
*) echo -e "${OVER} ${CROSS} ${str} ${url} (${httpCode})" ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
local done="false"
|
local done="false"
|
||||||
@ -637,7 +640,7 @@ gravity_ParseFileIntoDomains() {
|
|||||||
# This helps with that and makes it easier to read
|
# This helps with that and makes it easier to read
|
||||||
# It also helps with debugging so each stage of the script can be researched more in depth
|
# It also helps with debugging so each stage of the script can be researched more in depth
|
||||||
# 1) Convert all characters to lowercase
|
# 1) Convert all characters to lowercase
|
||||||
tr '[:upper:]' '[:lower:]' < "${src}" > "${destination}"
|
tr '[:upper:]' '[:lower:]' <"${src}" >"${destination}"
|
||||||
|
|
||||||
# 2) Remove carriage returns
|
# 2) Remove carriage returns
|
||||||
# 3) Remove lines starting with ! (ABP Comments)
|
# 3) Remove lines starting with ! (ABP Comments)
|
||||||
@ -647,7 +650,7 @@ gravity_ParseFileIntoDomains() {
|
|||||||
# 7) Remove leading tabs, spaces, etc. (Also removes leading IP addresses)
|
# 7) Remove leading tabs, spaces, etc. (Also removes leading IP addresses)
|
||||||
# 8) Remove empty lines
|
# 8) Remove empty lines
|
||||||
|
|
||||||
sed -i -r \
|
sed -i -r \
|
||||||
-e 's/\r$//' \
|
-e 's/\r$//' \
|
||||||
-e 's/\s*!.*//g' \
|
-e 's/\s*!.*//g' \
|
||||||
-e 's/\s*\[.*//g' \
|
-e 's/\s*\[.*//g' \
|
||||||
@ -664,12 +667,12 @@ gravity_Table_Count() {
|
|||||||
local table="${1}"
|
local table="${1}"
|
||||||
local str="${2}"
|
local str="${2}"
|
||||||
local num
|
local num
|
||||||
num="$(pihole-FTL sqlite3 "${gravityTEMPfile}" "SELECT COUNT(*) FROM ${table};")"
|
num="$(pihole-FTL sqlite3 -ni "${gravityTEMPfile}" "SELECT COUNT(*) FROM ${table};")"
|
||||||
if [[ "${table}" == "gravity" ]]; then
|
if [[ "${table}" == "gravity" ]]; then
|
||||||
local unique
|
local unique
|
||||||
unique="$(pihole-FTL sqlite3 "${gravityTEMPfile}" "SELECT COUNT(*) FROM (SELECT DISTINCT domain FROM ${table});")"
|
unique="$(pihole-FTL sqlite3 -ni "${gravityTEMPfile}" "SELECT COUNT(*) FROM (SELECT DISTINCT domain FROM ${table});")"
|
||||||
echo -e " ${INFO} Number of ${str}: ${num} (${COL_BOLD}${unique} unique domains${COL_NC})"
|
echo -e " ${INFO} Number of ${str}: ${num} (${COL_BOLD}${unique} unique domains${COL_NC})"
|
||||||
pihole-FTL sqlite3 "${gravityTEMPfile}" "INSERT OR REPLACE INTO info (property,value) VALUES ('gravity_count',${unique});"
|
pihole-FTL sqlite3 -ni "${gravityTEMPfile}" "INSERT OR REPLACE INTO info (property,value) VALUES ('gravity_count',${unique});"
|
||||||
else
|
else
|
||||||
echo -e " ${INFO} Number of ${str}: ${num}"
|
echo -e " ${INFO} Number of ${str}: ${num}"
|
||||||
fi
|
fi
|
||||||
@ -686,18 +689,6 @@ gravity_ShowCount() {
|
|||||||
gravity_Table_Count "vw_regex_whitelist" "regex allowed filters"
|
gravity_Table_Count "vw_regex_whitelist" "regex allowed filters"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create "localhost" entries into hosts format
|
|
||||||
gravity_generateLocalList() {
|
|
||||||
# Empty $localList if it already exists, otherwise, create it
|
|
||||||
echo "### Do not modify this file, it will be overwritten by pihole -g" > "${localList}"
|
|
||||||
chmod 644 "${localList}"
|
|
||||||
|
|
||||||
# Add additional LAN hosts provided by OpenVPN (if available)
|
|
||||||
if [[ -f "${VPNList}" ]]; then
|
|
||||||
awk -F, '{printf $2"\t"$1".vpn\n"}' "${VPNList}" >> "${localList}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trap Ctrl-C
|
# Trap Ctrl-C
|
||||||
gravity_Trap() {
|
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_LIGHT_RED}User-abort detected${COL_NC}"; gravity_Cleanup "error"; }' INT
|
||||||
@ -711,12 +702,12 @@ gravity_Cleanup() {
|
|||||||
echo -ne " ${INFO} ${str}..."
|
echo -ne " ${INFO} ${str}..."
|
||||||
|
|
||||||
# Delete tmp content generated by Gravity
|
# Delete tmp content generated by Gravity
|
||||||
rm ${piholeDir}/pihole.*.txt 2> /dev/null
|
rm ${piholeDir}/pihole.*.txt 2>/dev/null
|
||||||
rm ${piholeDir}/*.tmp 2> /dev/null
|
rm ${piholeDir}/*.tmp 2>/dev/null
|
||||||
# listCurlBuffer location
|
# listCurlBuffer location
|
||||||
rm "${GRAVITY_TMPDIR}"/*.phgpb 2> /dev/null
|
rm "${GRAVITY_TMPDIR}"/*.phgpb 2>/dev/null
|
||||||
# invalid_domains location
|
# invalid_domains location
|
||||||
rm "${GRAVITY_TMPDIR}"/*.ph-non-domains 2> /dev/null
|
rm "${GRAVITY_TMPDIR}"/*.ph-non-domains 2>/dev/null
|
||||||
|
|
||||||
# Ensure this function only runs when gravity_SetDownloadOptions() has completed
|
# Ensure this function only runs when gravity_SetDownloadOptions() has completed
|
||||||
if [[ "${gravity_Blackbody:-}" == true ]]; then
|
if [[ "${gravity_Blackbody:-}" == true ]]; then
|
||||||
@ -724,7 +715,7 @@ gravity_Cleanup() {
|
|||||||
for file in "${piholeDir}"/*."${domainsExtension}"; do
|
for file in "${piholeDir}"/*."${domainsExtension}"; do
|
||||||
# If list is not in active array, then remove it
|
# If list is not in active array, then remove it
|
||||||
if [[ ! "${activeDomains[*]}" == *"${file}"* ]]; then
|
if [[ ! "${activeDomains[*]}" == *"${file}"* ]]; then
|
||||||
rm -f "${file}" 2> /dev/null || \
|
rm -f "${file}" 2>/dev/null ||
|
||||||
echo -e " ${CROSS} Failed to remove ${file##*/}"
|
echo -e " ${CROSS} Failed to remove ${file##*/}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@ -750,7 +741,7 @@ database_recovery() {
|
|||||||
local str="Checking integrity of existing gravity database (this can take a while)"
|
local str="Checking integrity of existing gravity database (this can take a while)"
|
||||||
local option="${1}"
|
local option="${1}"
|
||||||
echo -ne " ${INFO} ${str}..."
|
echo -ne " ${INFO} ${str}..."
|
||||||
result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA integrity_check" 2>&1)"
|
result="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "PRAGMA integrity_check" 2>&1)"
|
||||||
|
|
||||||
if [[ ${result} = "ok" ]]; then
|
if [[ ${result} = "ok" ]]; then
|
||||||
echo -e "${OVER} ${TICK} ${str} - no errors found"
|
echo -e "${OVER} ${TICK} ${str} - no errors found"
|
||||||
@ -758,7 +749,7 @@ database_recovery() {
|
|||||||
str="Checking foreign keys of existing gravity database (this can take a while)"
|
str="Checking foreign keys of existing gravity database (this can take a while)"
|
||||||
echo -ne " ${INFO} ${str}..."
|
echo -ne " ${INFO} ${str}..."
|
||||||
unset result
|
unset result
|
||||||
result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA foreign_key_check" 2>&1)"
|
result="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "PRAGMA foreign_key_check" 2>&1)"
|
||||||
if [[ -z ${result} ]]; then
|
if [[ -z ${result} ]]; then
|
||||||
echo -e "${OVER} ${TICK} ${str} - no errors found"
|
echo -e "${OVER} ${TICK} ${str} - no errors found"
|
||||||
if [[ "${option}" != "force" ]]; then
|
if [[ "${option}" != "force" ]]; then
|
||||||
@ -766,18 +757,18 @@ database_recovery() {
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -e "${OVER} ${CROSS} ${str} - errors found:"
|
echo -e "${OVER} ${CROSS} ${str} - errors found:"
|
||||||
while IFS= read -r line ; do echo " - $line"; done <<< "$result"
|
while IFS= read -r line; do echo " - $line"; done <<<"$result"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -e "${OVER} ${CROSS} ${str} - errors found:"
|
echo -e "${OVER} ${CROSS} ${str} - errors found:"
|
||||||
while IFS= read -r line ; do echo " - $line"; done <<< "$result"
|
while IFS= read -r line; do echo " - $line"; done <<<"$result"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
str="Trying to recover existing gravity database"
|
str="Trying to recover existing gravity database"
|
||||||
echo -ne " ${INFO} ${str}..."
|
echo -ne " ${INFO} ${str}..."
|
||||||
# We have to remove any possibly existing recovery database or this will fail
|
# We have to remove any possibly existing recovery database or this will fail
|
||||||
rm -f "${gravityDBfile}.recovered" > /dev/null 2>&1
|
rm -f "${gravityDBfile}.recovered" >/dev/null 2>&1
|
||||||
if result="$(pihole-FTL sqlite3 "${gravityDBfile}" ".recover" | pihole-FTL sqlite3 "${gravityDBfile}.recovered" 2>&1)"; then
|
if result="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" ".recover" | pihole-FTL sqlite3 -ni "${gravityDBfile}.recovered" 2>&1)"; then
|
||||||
echo -e "${OVER} ${TICK} ${str} - success"
|
echo -e "${OVER} ${TICK} ${str} - success"
|
||||||
mv "${gravityDBfile}" "${gravityDBfile}.old"
|
mv "${gravityDBfile}" "${gravityDBfile}.old"
|
||||||
mv "${gravityDBfile}.recovered" "${gravityDBfile}"
|
mv "${gravityDBfile}.recovered" "${gravityDBfile}"
|
||||||
@ -785,7 +776,7 @@ database_recovery() {
|
|||||||
echo -ne " ${INFO} The old ${gravityDBfile} has been moved to ${gravityDBfile}.old"
|
echo -ne " ${INFO} The old ${gravityDBfile} has been moved to ${gravityDBfile}.old"
|
||||||
else
|
else
|
||||||
echo -e "${OVER} ${CROSS} ${str} - the following errors happened:"
|
echo -e "${OVER} ${CROSS} ${str} - the following errors happened:"
|
||||||
while IFS= read -r line ; do echo " - $line"; done <<< "$result"
|
while IFS= read -r line; do echo " - $line"; done <<<"$result"
|
||||||
echo -e " ${CROSS} Recovery failed. Try \"pihole -r recreate\" instead."
|
echo -e " ${CROSS} Recovery failed. Try \"pihole -r recreate\" instead."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@ -804,9 +795,10 @@ Options:
|
|||||||
|
|
||||||
repairSelector() {
|
repairSelector() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"recover") recover_database=true;;
|
"recover") recover_database=true ;;
|
||||||
"recreate") recreate_database=true;;
|
"recreate") recreate_database=true ;;
|
||||||
*) echo "Usage: pihole -g -r {recover,recreate}
|
*)
|
||||||
|
echo "Usage: pihole -g -r {recover,recreate}
|
||||||
Attempt to repair gravity database
|
Attempt to repair gravity database
|
||||||
|
|
||||||
Available options:
|
Available options:
|
||||||
@ -825,15 +817,17 @@ Available options:
|
|||||||
and create a new file from scratch. If you still
|
and create a new file from scratch. If you still
|
||||||
have the migration backup created when migrating
|
have the migration backup created when migrating
|
||||||
to Pi-hole v5.0, Pi-hole will import these files."
|
to Pi-hole v5.0, Pi-hole will import these files."
|
||||||
exit 0;;
|
exit 0
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
for var in "$@"; do
|
for var in "$@"; do
|
||||||
case "${var}" in
|
case "${var}" in
|
||||||
"-f" | "--force" ) forceDelete=true;;
|
"-f" | "--force" ) forceDelete=true;;
|
||||||
"-r" | "--repair" ) repairSelector "$3";;
|
"-r" | "--repair" ) repairSelector "$3";;
|
||||||
"-h" | "--help" ) helpFunc;;
|
"-u" | "--upgrade" ) upgrade_gravityDB "${gravityDBfile}" "${piholeDir}"; exit 0;;
|
||||||
|
"-h" | "--help" ) helpFunc;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -849,9 +843,9 @@ if [[ "${recreate_database:-}" == true ]]; then
|
|||||||
str="Recreating gravity database from migration backup"
|
str="Recreating gravity database from migration backup"
|
||||||
echo -ne "${INFO} ${str}..."
|
echo -ne "${INFO} ${str}..."
|
||||||
rm "${gravityDBfile}"
|
rm "${gravityDBfile}"
|
||||||
pushd "${piholeDir}" > /dev/null || exit
|
pushd "${piholeDir}" >/dev/null || exit
|
||||||
cp migration_backup/* .
|
cp migration_backup/* .
|
||||||
popd > /dev/null || exit
|
popd >/dev/null || exit
|
||||||
echo -e "${OVER} ${TICK} ${str}"
|
echo -e "${OVER} ${TICK} ${str}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -869,7 +863,7 @@ if [[ "${forceDelete:-}" == true ]]; then
|
|||||||
str="Deleting existing list cache"
|
str="Deleting existing list cache"
|
||||||
echo -ne "${INFO} ${str}..."
|
echo -ne "${INFO} ${str}..."
|
||||||
|
|
||||||
rm /etc/pihole/list.* 2> /dev/null || true
|
rm /etc/pihole/list.* 2>/dev/null || true
|
||||||
echo -e "${OVER} ${TICK} ${str}"
|
echo -e "${OVER} ${TICK} ${str}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -884,9 +878,6 @@ if ! gravity_DownloadBlocklists; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create local.list
|
|
||||||
gravity_generateLocalList
|
|
||||||
|
|
||||||
# Update gravity timestamp
|
# Update gravity timestamp
|
||||||
update_gravity_timestamp
|
update_gravity_timestamp
|
||||||
|
|
||||||
|
6
pihole
6
pihole
@ -140,8 +140,7 @@ uninstallFunc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
versionFunc() {
|
versionFunc() {
|
||||||
shift
|
exec "${PI_HOLE_SCRIPT_DIR}"/version.sh
|
||||||
exec "${PI_HOLE_SCRIPT_DIR}"/version.sh "$@"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restartDNS() {
|
restartDNS() {
|
||||||
@ -508,7 +507,6 @@ Options:
|
|||||||
-up, updatePihole Update Pi-hole subsystems
|
-up, updatePihole Update Pi-hole subsystems
|
||||||
Add '--check-only' to exit script before update is performed.
|
Add '--check-only' to exit script before update is performed.
|
||||||
-v, version Show installed versions of Pi-hole, Web Interface & FTL
|
-v, version Show installed versions of Pi-hole, Web Interface & FTL
|
||||||
Add '-h' for more info on version usage
|
|
||||||
uninstall Uninstall Pi-hole from your system
|
uninstall Uninstall Pi-hole from your system
|
||||||
status Display the running status of Pi-hole subsystems
|
status Display the running status of Pi-hole subsystems
|
||||||
enable Enable Pi-hole subsystems
|
enable Enable Pi-hole subsystems
|
||||||
@ -531,7 +529,7 @@ fi
|
|||||||
need_root=1
|
need_root=1
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
"-h" | "help" | "--help" ) helpFunc;;
|
"-h" | "help" | "--help" ) helpFunc;;
|
||||||
"-v" | "version" ) versionFunc "$@";;
|
"-v" | "version" ) versionFunc;;
|
||||||
"-c" | "chronometer" ) chronometerFunc "$@";;
|
"-c" | "chronometer" ) chronometerFunc "$@";;
|
||||||
"-q" | "query" ) queryFunc "$@";;
|
"-q" | "query" ) queryFunc "$@";;
|
||||||
"status" ) statusFunc "$2";;
|
"status" ) statusFunc "$2";;
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
FROM fedora:37
|
|
||||||
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 $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
|
|
||||||
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
|
|
||||||
|
|
||||||
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
|
|
@ -1,4 +1,4 @@
|
|||||||
FROM fedora:36
|
FROM fedora:39
|
||||||
RUN dnf install -y git initscripts
|
RUN dnf install -y git initscripts
|
||||||
|
|
||||||
ENV GITDIR /etc/.pihole
|
ENV GITDIR /etc/.pihole
|
@ -1,6 +1,6 @@
|
|||||||
pyyaml == 6.0.1
|
pyyaml == 6.0.1
|
||||||
pytest == 7.4.3
|
pytest == 8.0.0
|
||||||
pytest-xdist == 3.3.1
|
pytest-xdist == 3.5.0
|
||||||
pytest-testinfra == 9.0.0
|
pytest-testinfra == 10.0.0
|
||||||
tox == 4.11.3
|
tox == 4.12.1
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ from .conftest import (
|
|||||||
run_script,
|
run_script,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
FTL_BRANCH = "development-v6"
|
||||||
|
|
||||||
|
|
||||||
def test_supported_package_manager(host):
|
def test_supported_package_manager(host):
|
||||||
"""
|
"""
|
||||||
@ -80,11 +82,7 @@ def test_installPihole_fresh_install_readableFiles(host):
|
|||||||
host.run("command -v dnf > /dev/null && dnf install -y man")
|
host.run("command -v dnf > /dev/null && dnf install -y man")
|
||||||
host.run("command -v yum > /dev/null && yum install -y man")
|
host.run("command -v yum > /dev/null && yum install -y man")
|
||||||
# Workaround to get FTLv6 installed until it reaches master branch
|
# Workaround to get FTLv6 installed until it reaches master branch
|
||||||
host.run(
|
host.run('echo "' + FTL_BRANCH + '" > /etc/pihole/ftlbranch')
|
||||||
"""
|
|
||||||
echo "development-v6" > /etc/pihole/ftlbranch
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
install = host.run(
|
install = host.run(
|
||||||
"""
|
"""
|
||||||
export TERM=xterm
|
export TERM=xterm
|
||||||
@ -174,10 +172,6 @@ def test_installPihole_fresh_install_readableFiles(host):
|
|||||||
)
|
)
|
||||||
actual_rc = host.run(check_man).rc
|
actual_rc = host.run(check_man).rc
|
||||||
assert exit_status_success == actual_rc
|
assert exit_status_success == actual_rc
|
||||||
# check not readable sudoers file
|
|
||||||
check_sudo = test_cmd.format("r", "/etc/sudoers.d/pihole", piholeuser)
|
|
||||||
actual_rc = host.run(check_sudo).rc
|
|
||||||
assert exit_status_success != actual_rc
|
|
||||||
# check not readable cron file
|
# check not readable cron file
|
||||||
check_sudo = test_cmd.format("x", "/etc/cron.d/", piholeuser)
|
check_sudo = test_cmd.format("x", "/etc/cron.d/", piholeuser)
|
||||||
actual_rc = host.run(check_sudo).rc
|
actual_rc = host.run(check_sudo).rc
|
||||||
@ -235,45 +229,35 @@ def test_update_package_cache_failure_no_errors(host):
|
|||||||
assert "Error: Unable to update package cache." in updateCache.stdout
|
assert "Error: Unable to update package cache." in updateCache.stdout
|
||||||
|
|
||||||
|
|
||||||
def test_FTL_detect_aarch64_no_errors(host):
|
@pytest.mark.parametrize(
|
||||||
|
"arch,detected_string,supported",
|
||||||
|
[
|
||||||
|
("aarch64", "AArch64 (64 Bit ARM)", True),
|
||||||
|
("armv6", "ARMv6", True),
|
||||||
|
("armv7l", "ARMv7 (or newer)", True),
|
||||||
|
("armv7", "ARMv7 (or newer)", True),
|
||||||
|
("armv8a", "ARMv7 (or newer)", True),
|
||||||
|
("x86_64", "x86_64", True),
|
||||||
|
("riscv64", "riscv64", True),
|
||||||
|
("mips", "mips", False),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_FTL_detect_no_errors(host, arch, detected_string, supported):
|
||||||
"""
|
"""
|
||||||
confirms only aarch64 package is downloaded for FTL engine
|
confirms only correct package is downloaded for FTL engine
|
||||||
"""
|
"""
|
||||||
# mock uname to return aarch64 platform
|
# mock uname to return passed platform
|
||||||
mock_command("uname", {"-m": ("aarch64", "0")}, host)
|
mock_command("uname", {"-m": (arch, "0")}, host)
|
||||||
detectPlatform = host.run(
|
# mock readelf to respond with passed CPU architecture
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
create_pihole_user
|
|
||||||
funcOutput=$(get_binary_name)
|
|
||||||
binary="pihole-FTL${funcOutput##*pihole-FTL}"
|
|
||||||
theRest="${funcOutput%pihole-FTL*}"
|
|
||||||
FTLdetect "${binary}" "${theRest}"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
expected_stdout = info_box + " FTL Checks..."
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + " Detected AArch64 (64 Bit ARM) architecture"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + " Downloading and Installing FTL"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_FTL_detect_armv6_no_errors(host):
|
|
||||||
"""
|
|
||||||
confirms only armv6 package is downloaded for FTL engine
|
|
||||||
"""
|
|
||||||
# mock uname to return armv6 platform
|
|
||||||
mock_command("uname", {"-m": ("armv6", "0")}, host)
|
|
||||||
# mock readelf to respond with armv6l CPU architecture
|
|
||||||
mock_command_2(
|
mock_command_2(
|
||||||
"readelf",
|
"readelf",
|
||||||
{
|
{
|
||||||
"-A /bin/sh": ("Tag_CPU_arch: armv6", "0"),
|
"-A /bin/sh": ("Tag_CPU_arch: " + arch, "0"),
|
||||||
"-A /usr/bin/sh": ("Tag_CPU_arch: armv6", "0"),
|
"-A /usr/bin/sh": ("Tag_CPU_arch: " + arch, "0"),
|
||||||
},
|
},
|
||||||
host,
|
host,
|
||||||
)
|
)
|
||||||
|
host.run('echo "' + FTL_BRANCH + '" > /etc/pihole/ftlbranch')
|
||||||
detectPlatform = host.run(
|
detectPlatform = host.run(
|
||||||
"""
|
"""
|
||||||
source /opt/pihole/basic-install.sh
|
source /opt/pihole/basic-install.sh
|
||||||
@ -284,188 +268,30 @@ def test_FTL_detect_armv6_no_errors(host):
|
|||||||
FTLdetect "${binary}" "${theRest}"
|
FTLdetect "${binary}" "${theRest}"
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
expected_stdout = info_box + " FTL Checks..."
|
if supported:
|
||||||
assert expected_stdout in detectPlatform.stdout
|
expected_stdout = info_box + " FTL Checks..."
|
||||||
expected_stdout = tick_box + " Detected ARMv6 architecture"
|
assert expected_stdout in detectPlatform.stdout
|
||||||
assert expected_stdout in detectPlatform.stdout
|
expected_stdout = tick_box + " Detected " + detected_string + " architecture"
|
||||||
expected_stdout = tick_box + " Downloading and Installing FTL"
|
assert expected_stdout in detectPlatform.stdout
|
||||||
assert expected_stdout in detectPlatform.stdout
|
expected_stdout = tick_box + " Downloading and Installing FTL"
|
||||||
|
assert expected_stdout in detectPlatform.stdout
|
||||||
|
else:
|
||||||
def test_FTL_detect_armv7l_no_errors(host):
|
expected_stdout = (
|
||||||
"""
|
"Not able to detect architecture (unknown: " + detected_string + ")"
|
||||||
confirms only armv7l package is downloaded for FTL engine
|
)
|
||||||
"""
|
assert expected_stdout in detectPlatform.stdout
|
||||||
# mock uname to return armv7l platform
|
|
||||||
mock_command("uname", {"-m": ("armv7l", "0")}, host)
|
|
||||||
# mock readelf to respond with armv7l CPU architecture
|
|
||||||
mock_command_2(
|
|
||||||
"readelf",
|
|
||||||
{
|
|
||||||
"-A /bin/sh": ("Tag_CPU_arch: armv7l", "0"),
|
|
||||||
"-A /usr/bin/sh": ("Tag_CPU_arch: armv7l", "0"),
|
|
||||||
},
|
|
||||||
host,
|
|
||||||
)
|
|
||||||
detectPlatform = host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
create_pihole_user
|
|
||||||
funcOutput=$(get_binary_name)
|
|
||||||
binary="pihole-FTL${funcOutput##*pihole-FTL}"
|
|
||||||
theRest="${funcOutput%pihole-FTL*}"
|
|
||||||
FTLdetect "${binary}" "${theRest}"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
expected_stdout = info_box + " FTL Checks..."
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + (" Detected ARMv7 (or newer) architecture")
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + " Downloading and Installing FTL"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_FTL_detect_armv7_no_errors(host):
|
|
||||||
"""
|
|
||||||
confirms only armv7 package is downloaded for FTL engine
|
|
||||||
"""
|
|
||||||
# mock uname to return armv7 platform
|
|
||||||
mock_command("uname", {"-m": ("armv7", "0")}, host)
|
|
||||||
# mock readelf to respond with armv7 CPU architecture
|
|
||||||
mock_command_2(
|
|
||||||
"readelf",
|
|
||||||
{
|
|
||||||
"-A /bin/sh": ("Tag_CPU_arch: armv7", "0"),
|
|
||||||
"-A /usr/bin/sh": ("Tag_CPU_arch: armv7", "0"),
|
|
||||||
},
|
|
||||||
host,
|
|
||||||
)
|
|
||||||
detectPlatform = host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
create_pihole_user
|
|
||||||
funcOutput=$(get_binary_name)
|
|
||||||
binary="pihole-FTL${funcOutput##*pihole-FTL}"
|
|
||||||
theRest="${funcOutput%pihole-FTL*}"
|
|
||||||
FTLdetect "${binary}" "${theRest}"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
expected_stdout = info_box + " FTL Checks..."
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + (" Detected ARMv7 (or newer) architecture")
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + " Downloading and Installing FTL"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_FTL_detect_armv8a_no_errors(host):
|
|
||||||
"""
|
|
||||||
confirms only armv8a package is downloaded for FTL engine
|
|
||||||
"""
|
|
||||||
# mock uname to return armv8a platform
|
|
||||||
mock_command("uname", {"-m": ("armv8a", "0")}, host)
|
|
||||||
# mock readelf to respond with armv8a CPU architecture
|
|
||||||
mock_command_2(
|
|
||||||
"readelf",
|
|
||||||
{
|
|
||||||
"-A /bin/sh": ("Tag_CPU_arch: armv8a", "0"),
|
|
||||||
"-A /usr/bin/sh": ("Tag_CPU_arch: armv8a", "0"),
|
|
||||||
},
|
|
||||||
host,
|
|
||||||
)
|
|
||||||
detectPlatform = host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
create_pihole_user
|
|
||||||
funcOutput=$(get_binary_name)
|
|
||||||
binary="pihole-FTL${funcOutput##*pihole-FTL}"
|
|
||||||
theRest="${funcOutput%pihole-FTL*}"
|
|
||||||
FTLdetect "${binary}" "${theRest}"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
expected_stdout = info_box + " FTL Checks..."
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + " Detected ARMv7 (or newer) architecture (armv8a)"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + " Downloading and Installing FTL"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_FTL_detect_x86_64_no_errors(host):
|
|
||||||
"""
|
|
||||||
confirms only x86_64 package is downloaded for FTL engine
|
|
||||||
"""
|
|
||||||
detectPlatform = host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
create_pihole_user
|
|
||||||
funcOutput=$(get_binary_name)
|
|
||||||
binary="pihole-FTL${funcOutput##*pihole-FTL}"
|
|
||||||
theRest="${funcOutput%pihole-FTL*}"
|
|
||||||
FTLdetect "${binary}" "${theRest}"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
expected_stdout = info_box + " FTL Checks..."
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + " Detected x86_64 architecture"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
expected_stdout = tick_box + " Downloading and Installing FTL"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_FTL_detect_unknown_no_errors(host):
|
|
||||||
"""confirms only generic package is downloaded for FTL engine"""
|
|
||||||
# mock uname to return generic platform
|
|
||||||
mock_command("uname", {"-m": ("mips", "0")}, host)
|
|
||||||
detectPlatform = host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
create_pihole_user
|
|
||||||
funcOutput=$(get_binary_name)
|
|
||||||
binary="pihole-FTL${funcOutput##*pihole-FTL}"
|
|
||||||
theRest="${funcOutput%pihole-FTL*}"
|
|
||||||
FTLdetect "${binary}" "${theRest}"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
expected_stdout = "Not able to detect architecture (unknown: mips)"
|
|
||||||
assert expected_stdout in detectPlatform.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_FTL_download_aarch64_no_errors(host):
|
|
||||||
"""
|
|
||||||
confirms only aarch64 package is downloaded for FTL engine
|
|
||||||
"""
|
|
||||||
# mock dialog answers and ensure installer dependencies
|
|
||||||
mock_command("dialog", {"*": ("", "0")}, host)
|
|
||||||
host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
install_dependent_packages ${INSTALLER_DEPS[@]}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
download_binary = host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
create_pihole_user
|
|
||||||
FTLinstall "pihole-FTL-aarch64-linux-gnu"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
expected_stdout = tick_box + " Downloading and Installing FTL"
|
|
||||||
assert expected_stdout in download_binary.stdout
|
|
||||||
assert "error" not in download_binary.stdout.lower()
|
|
||||||
|
|
||||||
|
|
||||||
def test_FTL_development_binary_installed_and_responsive_no_errors(host):
|
def test_FTL_development_binary_installed_and_responsive_no_errors(host):
|
||||||
"""
|
"""
|
||||||
confirms FTL development binary is copied and functional in installed location
|
confirms FTL development binary is copied and functional in installed location
|
||||||
"""
|
"""
|
||||||
|
host.run('echo "' + FTL_BRANCH + '" > /etc/pihole/ftlbranch')
|
||||||
host.run(
|
host.run(
|
||||||
"""
|
"""
|
||||||
source /opt/pihole/basic-install.sh
|
source /opt/pihole/basic-install.sh
|
||||||
create_pihole_user
|
create_pihole_user
|
||||||
funcOutput=$(get_binary_name)
|
funcOutput=$(get_binary_name)
|
||||||
echo "development" > /etc/pihole/ftlbranch
|
|
||||||
binary="pihole-FTL${funcOutput##*pihole-FTL}"
|
binary="pihole-FTL${funcOutput##*pihole-FTL}"
|
||||||
theRest="${funcOutput%pihole-FTL*}"
|
theRest="${funcOutput%pihole-FTL*}"
|
||||||
FTLdetect "${binary}" "${theRest}"
|
FTLdetect "${binary}" "${theRest}"
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
[tox]
|
|
||||||
envlist = py3
|
|
||||||
|
|
||||||
[testenv:py3]
|
|
||||||
allowlist_externals = docker
|
|
||||||
deps = -rrequirements.txt
|
|
||||||
commands = docker buildx build --load --progress plain -f _fedora_36.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
|
|
@ -4,5 +4,5 @@ envlist = py3
|
|||||||
[testenv]
|
[testenv]
|
||||||
allowlist_externals = docker
|
allowlist_externals = docker
|
||||||
deps = -rrequirements.txt
|
deps = -rrequirements.txt
|
||||||
commands = docker buildx build --load --progress plain -f _fedora_37.Dockerfile -t pytest_pihole:test_container ../
|
commands = docker buildx build --load --progress plain -f _fedora_39.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
|
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py
|
Loading…
Reference in New Issue
Block a user