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-all-issue-assignees:true
operations-per-run:300
close-issue-reason:'not_planned'
remove_stale:# trigger "stale" removal immediately when stale issues are commented on
if:github.event_name == 'issue_comment'
remove_stale:
# 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
# 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")
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."
# Check current branch. If it is master, then reset to the latest available tag.
# In case extra commits have been added after tagging/release (i.e in case of metadata updates/README.MD tweaks)
curBranch=$(git rev-parse --abbrev-ref HEAD)
@ -458,7 +460,7 @@ update_repo() {
# Data in the repositories is public anyway so we can make it readable by everyone (+r to keep executable permission if already set by git)
chmod -R a+rX "${directory}"
# Move back into the original directory
popd&>/dev/null ||return1
popd&>/dev/null ||return1
return0
}
@ -478,13 +480,19 @@ getGitFiles() {
# Show that we're checking it
printf"%b %b %s\\n""${OVER}""${TICK}""${str}"
# Update the repo, returning an error message on failure
update_repo "${directory}"||{printf"\\n %b: Could not update local repository. Contact support.%b\\n""${COL_LIGHT_RED}""${COL_NC}";exit 1;}
update_repo "${directory}"||{
printf"\\n %b: Could not update local repository. Contact support.%b\\n""${COL_LIGHT_RED}""${COL_NC}"
exit1
}
# If it's not a .git repo,
else
# Show an error
printf"%b %b %s\\n""${OVER}""${CROSS}""${str}"
# Attempt to make the repository, showing an error on failure
make_repo "${directory}""${remoteRepo}"||{printf"\\n %bError: Could not update local repository. Contact support.%b\\n""${COL_LIGHT_RED}""${COL_NC}";exit 1;}
make_repo "${directory}""${remoteRepo}"||{
printf"\\n %bError: Could not update local repository. Contact support.%b\\n""${COL_LIGHT_RED}""${COL_NC}"
exit1
}
fi
echo""
# Success via one of the two branches, as the commands would exit if they failed.
@ -496,19 +504,19 @@ resetRepo() {
# Use named variables for arguments
localdirectory="${1}"
# Move into the directory
pushd"${directory}"&>/dev/null ||return1
pushd"${directory}"&>/dev/null ||return1
# Store the message in a variable
str="Resetting repository within ${1}..."
# Show the message
printf" %b %s...""${INFO}""${str}"
# Use git to remove the local changes
git reset --hard &>/dev/null ||return$?
git reset --hard &>/dev/null ||return$?
# Data in the repositories is public anyway so we can make it readable by everyone (+r to keep executable permission if already set by git)
chmod -R a+rX "${directory}"
# And show the status
printf"%b %b %s\\n""${OVER}""${TICK}""${str}"
# Return to where we came from
popd&>/dev/null ||return1
popd&>/dev/null ||return1
# Function succeeded, as "git reset" would have triggered a return earlier if it failed
return0
}
@ -530,7 +538,7 @@ find_IPv4_information() {
# the variable with just the first field.
printf -v IPv4bare "$(printf${route#*src })"
if ! valid_ip "${IPv4bare}";then
if ! valid_ip "${IPv4bare}";then
IPv4bare="127.0.0.1"
fi
@ -566,7 +574,7 @@ welcomeDialogs() {
--yesno "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.\\n\\n\
\\Zb\\Z1IMPORTANT:\\Zn If you have not already done so, you must ensure that this device has a static IP.\\n\\n\
Depending on your operating system, there are many ways to achieve this, through DHCP reservation, or by manually assigning one.\\n\\n\
Please continue when the static addressing has been configured."\
Please continue when the static addressing has been configured."\
printf" This check can be skipped by setting the environment variable %bPIHOLE_SELINUX%b to %btrue%b\\n""${COL_LIGHT_RED}""${COL_NC}""${COL_LIGHT_RED}""${COL_NC}"
printf" e.g: export PIHOLE_SELINUX=true\\n"
printf" By setting this variable to true you acknowledge there may be issues with Pi-hole during or after the install\\n"
# Else if the password exists from previous setup, we'll load it later
pwstring="unchanged"
else
@ -1629,7 +1632,6 @@ displayFinalMessage() {
# Store a message in a variable and display it
additional="View the web interface at http://pi.hole/admin:${WEBPORT} or http://${IPV4_ADDRESS%/*}:${WEBPORT}/admin\\n\\nYour Admin Webpage login password is ${pwstring}"
# Final completion message to user
dialog --no-shadow --keep-tite \
--title "Installation Complete!"\
@ -1662,7 +1664,7 @@ update_dialogs() {
--title "Existing Install Detected!"\
--menu "\\n\\nWe have detected an existing install.\
\\n\\nPlease choose from the following options:\
\\n($strAdd)"\
\\n($strAdd)"\
"${r}""${c}"2\
"${opt1a}""${opt1b}"\
"${opt2a}""${opt2b}")||result=$?
@ -1690,12 +1692,19 @@ update_dialogs() {
}
check_download_exists(){
# Check if the download exists and we can reach the server
status=$(curl --head --silent "https://ftl.pi-hole.net/${1}"| head -n 1)
if grep -q "404"<<<"$status";then
return1
else
# Check the status code
if grep -q "200"<<<"$status";then
return0
elif grep -q "404"<<<"$status";then
return1
fi
# Other error or no status code at all, e.g., no Internet, server not
# available/reachable, ...
return2
}
fully_fetch_repo(){
@ -1720,7 +1729,7 @@ get_available_branches() {
cd"${directory}"||return1
# Get reachable remote branches, but store STDERR as STDOUT variable
# Special case: This is a 32 bit OS, installed on a 64 bit machine
# -> change machine processor to download the 32 bit executable
@ -1960,16 +1985,14 @@ get_binary_name() {
}
FTLcheckUpdate(){
#In the next section we check to see if FTL is already installed (in case of pihole -r).
#If the installed version matches the latest version, then check the installed sha1sum of the binary vs the remote sha1sum. If they do not match, then download
printf" %b Checking for existing FTL binary...\\n""${INFO}"
# In the next section we check to see if FTL is already installed (in case of pihole -r).
# If the installed version matches the latest version, then check the installed sha1sum of the binary vs the remote sha1sum. If they do not match, then download
local ftlLoc
ftlLoc=$(command -v pihole-FTL 2>/dev/null)
local ftlBranch
if[[ -f "/etc/pihole/ftlbranch"]];then
if[[ -f "/etc/pihole/ftlbranch"]];then
ftlBranch=$(</etc/pihole/ftlbranch)
else
ftlBranch="master"
@ -1982,14 +2005,24 @@ FTLcheckUpdate() {
local localSha1
if[[ ! "${ftlBranch}"=="master"]];then
#Check whether or not the binary for this FTL branch actually exists. If not, then there is no update!
#Check whether or not the binary for this FTL branch actually exists. If not, then there is no update!
local path
path="${ftlBranch}/${binary}"
# shellcheck disable=SC1090
if ! check_download_exists "$path";then
check_download_exists "$path"
localret=$?
if[$ret -ne 0];then
if[[$ret -eq 1]];then
printf" %b Branch \"%s\" is not available.\\n""${INFO}""${ftlBranch}"
printf" %b Use %bpihole checkout ftl [branchname]%b to switch to a valid branch.\\n""${INFO}""${COL_LIGHT_GREEN}""${COL_NC}"
return2
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}"
if ! pihole-FTL sqlite3 "${gravityDBfile}" <"${gravityDBschema}";then
if ! pihole-FTL sqlite3 -ni "${gravityDBfile}" <"${gravityDBschema}";then
echo -e "${CROSS} Unable to create ${gravityDBfile}"
return1
fi
@ -80,7 +75,7 @@ gravity_build_tree() {
echo -ne "${INFO}${str}..."
# 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="$?"
if[["${status}" -ne 0]];then
@ -119,7 +114,7 @@ gravity_swap_databases() {
# Update timestamp when the gravity table was last updated successfully
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="$?"
if[["${status}" -ne 0]];then
@ -164,7 +159,7 @@ database_table_from_file() {
# Get MAX(id) from domainlist when INSERTing into this table
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;")"
# Move source file to backup directory, create directory if not existing
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}"
# Delete tmpFile
rm "${tmpFile}" >/dev/null 2>&1||\
rm "${tmpFile}" >/dev/null 2>&1||
echo -e "${CROSS} Unable to remove ${tmpFile}"
}
# Check if a column with name ${2} exists in gravity table with name ${1}
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
return0# Bash 0 is success
fi
@ -226,10 +220,10 @@ gravity_column_exists() {
database_adlist_number(){
# Only try to set number of domains when this field exists in the gravity database
if ! gravity_column_exists "adlist""number";then
return;
return
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="$?"
if[["${status}" -ne 0]];then
@ -242,10 +236,10 @@ database_adlist_number() {
database_adlist_status(){
# Only try to set the status when this field exists in the gravity database
if ! gravity_column_exists "adlist""status";then
return;
return
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="$?"
if[["${status}" -ne 0]];then
@ -299,15 +293,10 @@ migrate_to_database() {
# Determine if DNS resolution is available before proceeding
gravity_CheckDNSResolutionAvailable(){
locallookupDomain="pi.hole"
# Determine if $localList does not exist, and ensure it is not empty