Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c86af0e59 | ||
|
|
ddaa1bf0d4 | ||
|
|
6b8ba3c15e | ||
|
|
7536c312ee | ||
|
|
a8b6eb9b70 | ||
|
|
67385b7ed4 | ||
|
|
64e61aac4a | ||
|
|
2fd5b944ad | ||
|
|
f91606bb17 | ||
|
|
122bc6b927 | ||
|
|
3491dbfd04 | ||
|
|
871067acd8 | ||
|
|
06cf7afbc2 | ||
|
|
01bf9ca42a | ||
|
|
c8c6533440 | ||
|
|
f1b15f7e92 | ||
|
|
e0c351f0e4 | ||
|
|
7957acf42f | ||
|
|
c3e8d76d63 | ||
|
|
128a3ab1be | ||
|
|
df3e9e5f51 | ||
|
|
c322458dcb | ||
|
|
21be1bd58e | ||
|
|
469a267150 | ||
|
|
090727b1d3 | ||
|
|
85ffbcf05e | ||
|
|
528abc9c97 | ||
|
|
8b98fd06ed | ||
|
|
bc6fb0c934 | ||
|
|
e773e3302c | ||
|
|
0cf59cf0fa | ||
|
|
bc471cb0bd | ||
|
|
429510e168 | ||
|
|
4c9401175c | ||
|
|
235673dac8 | ||
|
|
d737948f64 | ||
|
|
52283478c8 | ||
|
|
c84be5de61 | ||
|
|
d85982dc51 | ||
|
|
5c61f6cb65 | ||
|
|
4c0a94d2b9 | ||
|
|
5c090d25e1 | ||
|
|
89c0706abc | ||
|
|
e5695f862f | ||
|
|
e3db5fc601 | ||
|
|
9c51050283 | ||
|
|
17779bad94 | ||
|
|
fed58f03bf | ||
|
|
c5b3b8dd68 | ||
|
|
46986714d4 | ||
|
|
4f3debcb5b | ||
|
|
223ef72250 | ||
|
|
cf467db61d | ||
|
|
fae1d13892 | ||
|
|
4265bcb178 | ||
|
|
9471c69882 | ||
|
|
79c0b446e1 | ||
|
|
a478f2460b | ||
|
|
2dc599f266 | ||
|
|
d7f7ef9965 | ||
|
|
888e44e53d | ||
|
|
18d28533eb | ||
|
|
56527e5dd9 | ||
|
|
997a771dc8 | ||
|
|
77f0012f6b | ||
|
|
b7b5ffa8dd | ||
|
|
34b66002e9 | ||
|
|
71b560667b | ||
|
|
9dd51b79b5 | ||
|
|
7fd062c4d8 | ||
|
|
3731b65bd5 | ||
|
|
6057b134ae | ||
|
|
0749de3d1f | ||
|
|
d48c557134 | ||
|
|
a705fbca73 | ||
|
|
276c480f50 | ||
|
|
25ba68104b | ||
|
|
3d01e4d0cf | ||
|
|
1b0b0ca445 | ||
|
|
e1a2591c4d | ||
|
|
f8a12917e2 | ||
|
|
37b45d411d | ||
|
|
22ebf21487 | ||
|
|
bf5fffaca7 | ||
|
|
9debd22179 | ||
|
|
a8ce1354c8 | ||
|
|
0a780a959a | ||
|
|
951b4ed002 | ||
|
|
755ec8bf2f | ||
|
|
1c1407e083 | ||
|
|
9463c3c69f | ||
|
|
54bcf5626f | ||
|
|
ba8a50c829 | ||
|
|
bb57a9e616 | ||
|
|
4f4dfe3ac0 | ||
|
|
d4ce5b1c2a | ||
|
|
b6d1bd7335 | ||
|
|
17ec88d96f | ||
|
|
0df38cd64e | ||
|
|
0932c5c498 | ||
|
|
73ca4ebdbc | ||
|
|
da6596e516 | ||
|
|
00e51f32b5 | ||
|
|
f90fb8b946 | ||
|
|
2ff1fa1b85 | ||
|
|
230d6a435f | ||
|
|
53c0982c8b | ||
|
|
9b5ea13a33 | ||
|
|
c90d8284ef | ||
|
|
7ab9664255 | ||
|
|
3a22657645 | ||
|
|
4567f264b4 |
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout repository
|
||||
uses: actions/checkout@v3.0.2
|
||||
uses: actions/checkout@v3.1.0
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
-
|
||||
name: Initialize CodeQL
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5.2.0
|
||||
- uses: actions/stale@v6.0.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 30
|
||||
|
||||
2
.github/workflows/sync-back-to-dev.yml
vendored
2
.github/workflows/sync-back-to-dev.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
name: Syncing branches
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3.0.2
|
||||
uses: actions/checkout@v3.1.0
|
||||
- name: Opening pull request
|
||||
id: pull
|
||||
uses: tretuna/sync-branches@1.4.0
|
||||
|
||||
87
.github/workflows/test.yml
vendored
87
.github/workflows/test.yml
vendored
@@ -12,29 +12,33 @@ jobs:
|
||||
if: github.event.pull_request.draft == false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout repository
|
||||
uses: actions/checkout@v3.0.2
|
||||
-
|
||||
name: Check scripts in repository are executable
|
||||
run: |
|
||||
IFS=$'\n';
|
||||
for f in $(find . -name '*.sh'); do if [[ ! -x $f ]]; then echo "$f is not executable" && FAIL=1; fi ;done
|
||||
unset IFS;
|
||||
# If FAIL is 1 then we fail.
|
||||
[[ $FAIL == 1 ]] && exit 1 || echo "Scripts are executable!"
|
||||
-
|
||||
name: Spell-Checking
|
||||
uses: codespell-project/actions-codespell@master
|
||||
with:
|
||||
ignore_words_file: .codespellignore
|
||||
-
|
||||
name: Get editorconfig-checker
|
||||
uses: editorconfig-checker/action-editorconfig-checker@main # tag v1.0.0 is really out of date
|
||||
-
|
||||
name: Run editorconfig-checker
|
||||
run: editorconfig-checker
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.1.0
|
||||
|
||||
- name: Check scripts in repository are executable
|
||||
run: |
|
||||
IFS=$'\n';
|
||||
for f in $(find . -name '*.sh'); do if [[ ! -x $f ]]; then echo "$f is not executable" && FAIL=1; fi ;done
|
||||
unset IFS;
|
||||
# If FAIL is 1 then we fail.
|
||||
[[ $FAIL == 1 ]] && exit 1 || echo "Scripts are executable!"
|
||||
|
||||
- name: Spell-Checking
|
||||
uses: codespell-project/actions-codespell@master
|
||||
with:
|
||||
ignore_words_file: .codespellignore
|
||||
|
||||
- name: Get editorconfig-checker
|
||||
uses: editorconfig-checker/action-editorconfig-checker@main # tag v1.0.0 is really out of date
|
||||
|
||||
- name: Run editorconfig-checker
|
||||
run: editorconfig-checker
|
||||
|
||||
- name: Check python code formatting with black
|
||||
uses: psf/black@stable
|
||||
with:
|
||||
src: "./test"
|
||||
options: "--check --diff --color"
|
||||
|
||||
distro-test:
|
||||
if: github.event.pull_request.draft == false
|
||||
@@ -43,21 +47,30 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
distro: [debian_10, debian_11, ubuntu_20, ubuntu_22, centos_8, fedora_34]
|
||||
distro:
|
||||
[
|
||||
debian_10,
|
||||
debian_11,
|
||||
ubuntu_20,
|
||||
ubuntu_22,
|
||||
centos_8,
|
||||
centos_9,
|
||||
fedora_35,
|
||||
fedora_36,
|
||||
]
|
||||
env:
|
||||
DISTRO: ${{matrix.distro}}
|
||||
steps:
|
||||
-
|
||||
name: Checkout repository
|
||||
uses: actions/checkout@v3.0.2
|
||||
-
|
||||
name: Set up Python 3.10
|
||||
uses: actions/setup-python@v4.2.0
|
||||
with:
|
||||
python-version: '3.10'
|
||||
-
|
||||
name: Install dependencies
|
||||
run: pip install -r test/requirements.txt
|
||||
-
|
||||
name: Test with tox
|
||||
run: tox -c test/tox.${DISTRO}.ini
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.1.0
|
||||
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install -r test/requirements.txt
|
||||
|
||||
- name: Test with tox
|
||||
run: tox -c test/tox.${DISTRO}.ini
|
||||
|
||||
14
README.md
14
README.md
@@ -16,11 +16,11 @@
|
||||
|
||||
The Pi-hole® is a [DNS sinkhole](https://en.wikipedia.org/wiki/DNS_Sinkhole) that protects your devices from unwanted content without installing any client-side software.
|
||||
|
||||
- **Easy-to-install**: our versatile installer walks you through the process and takes less than ten minutes
|
||||
- **Easy-to-install**: our dialogs walk you through the simple installation process in less than ten minutes
|
||||
- **Resolute**: content is blocked in _non-browser locations_, such as ad-laden mobile apps and smart TVs
|
||||
- **Responsive**: seamlessly speeds up the feel of everyday browsing by caching DNS queries
|
||||
- **Lightweight**: runs smoothly with [minimal hardware and software requirements](https://docs.pi-hole.net/main/prerequisites/)
|
||||
- **Robust**: a command line interface that is quality assured for interoperability
|
||||
- **Robust**: a command-line interface that is quality assured for interoperability
|
||||
- **Insightful**: a beautiful responsive Web Interface dashboard to view and control your Pi-hole
|
||||
- **Versatile**: can optionally function as a [DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026), ensuring _all_ your devices are protected automatically
|
||||
- **Scalable**: [capable of handling hundreds of millions of queries](https://pi-hole.net/2017/05/24/how-much-traffic-can-pi-hole-handle/) when installed on server-grade hardware
|
||||
@@ -60,7 +60,7 @@ Please refer to the [Pi-hole docker repo](https://github.com/pi-hole/docker-pi-h
|
||||
|
||||
## [Post-install: Make your network take advantage of Pi-hole](https://docs.pi-hole.net/main/post-install/)
|
||||
|
||||
Once the installer has been run, you will need to [configure your router to have **DHCP clients use Pi-hole as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) which ensures that all devices connecting to your network will have content blocked without any further intervention.
|
||||
Once the installer has been run, you will need to [configure your router to have **DHCP clients use Pi-hole as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245). This router configuration will ensure that all devices connecting to your network will have content blocked without any further intervention.
|
||||
|
||||
If your router does not support setting the DNS server, you can [use Pi-hole's built-in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026); be sure to disable DHCP on your router first (if it has that feature available).
|
||||
|
||||
@@ -70,7 +70,7 @@ As a last resort, you can manually set each device to use Pi-hole as their DNS s
|
||||
|
||||
## Pi-hole is free but powered by your support
|
||||
|
||||
There are many reoccurring costs involved with maintaining free, open source, and privacy-respecting software; expenses which [our volunteer developers](https://github.com/orgs/pi-hole/people) pitch in to cover out-of-pocket. This is just one example of how strongly we feel about our software and the importance of keeping it maintained.
|
||||
There are many reoccurring costs involved with maintaining free, open-source, and privacy-respecting software; expenses which [our volunteer developers](https://github.com/orgs/pi-hole/people) pitch in to cover out-of-pocket. This is just one example of how strongly we feel about our software and the importance of keeping it maintained.
|
||||
|
||||
Make no mistake: **your support is absolutely vital to help keep us innovating!**
|
||||
|
||||
@@ -87,7 +87,7 @@ If you'd rather not donate (_which is okay!_), there are other ways you can help
|
||||
- [Hetzner Cloud](https://hetzner.cloud/?ref=7aceisRX3AzA) _affiliate link_
|
||||
- [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1) _affiliate link_
|
||||
- [Stickermule](https://www.stickermule.com/unlock?ref_id=9127301701&utm_medium=link&utm_source=invite) _earn a $10 credit after your first purchase_
|
||||
- [Amazon US](http://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_
|
||||
- [Amazon US](https://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_
|
||||
- Spreading the word about our software and how you have benefited from it
|
||||
|
||||
### Contributing via GitHub
|
||||
@@ -132,9 +132,9 @@ Some of the statistics you can integrate include:
|
||||
|
||||
Access the API via [`telnet`](https://github.com/pi-hole/FTL), the Web (`admin/api.php`) and Command Line (`pihole -c -j`). You can find out [more details over here](https://discourse.pi-hole.net/t/pi-hole-api/1863).
|
||||
|
||||
### The Command Line Interface
|
||||
### The Command-Line Interface
|
||||
|
||||
The [pihole](https://docs.pi-hole.net/core/pihole-command/) command has all the functionality necessary to fully administer the Pi-hole, without the need of the Web Interface. It's fast, user-friendly, and auditable by anyone with an understanding of `bash`.
|
||||
The [pihole](https://docs.pi-hole.net/core/pihole-command/) command has all the functionality necessary to fully administer the Pi-hole, without the need for the Web Interface. It's fast, user-friendly, and auditable by anyone with an understanding of `bash`.
|
||||
|
||||
Some notable features include:
|
||||
|
||||
|
||||
@@ -29,13 +29,6 @@ bogus-priv
|
||||
|
||||
no-resolv
|
||||
|
||||
server=@DNS1@
|
||||
server=@DNS2@
|
||||
|
||||
interface=@INT@
|
||||
|
||||
cache-size=@CACHE_SIZE@
|
||||
|
||||
log-queries
|
||||
log-facility=/var/log/pihole/pihole.log
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ LC_NUMERIC=C
|
||||
# Retrieve stats from FTL engine
|
||||
pihole-FTL() {
|
||||
local ftl_port LINE
|
||||
ftl_port=$(cat /run/pihole-FTL.port 2> /dev/null)
|
||||
# shellcheck disable=SC1091
|
||||
. /opt/pihole/utils.sh
|
||||
ftl_port=$(getFTLAPIPort)
|
||||
if [[ -n "$ftl_port" ]]; then
|
||||
# Open connection to FTL
|
||||
exec 3<>"/dev/tcp/127.0.0.1/$ftl_port"
|
||||
@@ -503,11 +505,11 @@ chronoFunc() {
|
||||
fi
|
||||
|
||||
printFunc " Pi-hole: " "$ph_status" "$ph_info"
|
||||
printFunc " Ads Today: " "$ads_percentage_today%" "$ads_info"
|
||||
printFunc " Blocked: " "$ads_percentage_today%" "$ads_info"
|
||||
printFunc "Local Qrys: " "$queries_cached_percentage%" "$dns_info"
|
||||
|
||||
printFunc " Blocked: " "$recent_blocked"
|
||||
printFunc "Top Advert: " "$top_ad"
|
||||
printFunc "Last Block: " "$recent_blocked"
|
||||
printFunc " Top Block: " "$top_ad"
|
||||
|
||||
# Provide more stats on screens with more lines
|
||||
if [[ "$scr_lines" -eq 17 ]]; then
|
||||
|
||||
@@ -164,6 +164,8 @@ checkout() {
|
||||
exit 1
|
||||
fi
|
||||
checkout_pull_branch "${webInterfaceDir}" "${2}"
|
||||
# Update local and remote versions via updatechecker
|
||||
/opt/pihole/updatecheck.sh
|
||||
elif [[ "${1}" == "ftl" ]] ; then
|
||||
local path
|
||||
local oldbranch
|
||||
@@ -178,6 +180,8 @@ checkout() {
|
||||
FTLinstall "${binary}"
|
||||
restart_service pihole-FTL
|
||||
enable_service pihole-FTL
|
||||
# Update local and remote versions via updatechecker
|
||||
/opt/pihole/updatecheck.sh
|
||||
else
|
||||
echo " ${CROSS} Requested branch \"${2}\" is not available"
|
||||
ftlbranches=( $(git ls-remote https://github.com/pi-hole/ftl | grep 'heads' | sed 's/refs\/heads\///;s/ //g' | awk '{print $2}') )
|
||||
|
||||
@@ -44,17 +44,12 @@ fi
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/pihole/versions
|
||||
|
||||
OBFUSCATED_PLACEHOLDER="<DOMAIN OBFUSCATED>"
|
||||
|
||||
# FAQ URLs for use in showing the debug log
|
||||
FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
|
||||
FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
|
||||
FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/${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_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}"
|
||||
FAQ_BAD_ADDRESS="${COL_CYAN}https://discourse.pi-hole.net/t/why-do-i-see-bad-address-at-in-pihole-log/3972${COL_NC}"
|
||||
|
||||
# Other URLs we may use
|
||||
FORUMS_URL="${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
|
||||
@@ -73,7 +68,6 @@ WEB_SERVER_LOG_DIRECTORY="/var/log/lighttpd"
|
||||
WEB_SERVER_CONFIG_DIRECTORY="/etc/lighttpd"
|
||||
HTML_DIRECTORY="/var/www/html"
|
||||
WEB_GIT_DIRECTORY="${HTML_DIRECTORY}/admin"
|
||||
#BLOCK_PAGE_DIRECTORY="${HTML_DIRECTORY}/pihole"
|
||||
SHM_DIRECTORY="/dev/shm"
|
||||
ETC="/etc"
|
||||
|
||||
@@ -91,6 +85,7 @@ PIHOLE_LOGROTATE_FILE="${PIHOLE_DIRECTORY}/logrotate"
|
||||
PIHOLE_SETUP_VARS_FILE="${PIHOLE_DIRECTORY}/setupVars.conf"
|
||||
PIHOLE_FTL_CONF_FILE="${PIHOLE_DIRECTORY}/pihole-FTL.conf"
|
||||
PIHOLE_CUSTOM_HOSTS_FILE="${PIHOLE_DIRECTORY}/custom.list"
|
||||
PIHOLE_VERSIONS_FILE="${PIHOLE_DIRECTORY}/versions"
|
||||
|
||||
# Read the value of an FTL config key. The value is printed to stdout.
|
||||
#
|
||||
@@ -126,7 +121,6 @@ PIHOLE_COMMAND="${BIN_DIRECTORY}/pihole"
|
||||
PIHOLE_COLTABLE_FILE="${BIN_DIRECTORY}/COL_TABLE"
|
||||
|
||||
FTL_PID="${RUN_DIRECTORY}/pihole-FTL.pid"
|
||||
FTL_PORT="${RUN_DIRECTORY}/pihole-FTL.port"
|
||||
|
||||
PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log"
|
||||
PIHOLE_LOG_GZIPS="${LOG_DIRECTORY}/pihole.log.[0-9].*"
|
||||
@@ -155,7 +149,6 @@ REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
|
||||
"${PIHOLE_COMMAND}"
|
||||
"${PIHOLE_COLTABLE_FILE}"
|
||||
"${FTL_PID}"
|
||||
"${FTL_PORT}"
|
||||
"${PIHOLE_LOG}"
|
||||
"${PIHOLE_LOG_GZIPS}"
|
||||
"${PIHOLE_DEBUG_LOG}"
|
||||
@@ -164,7 +157,8 @@ REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
|
||||
"${PIHOLE_WEB_SERVER_ERROR_LOG_FILE}"
|
||||
"${RESOLVCONF}"
|
||||
"${DNSMASQ_CONF}"
|
||||
"${PIHOLE_CUSTOM_HOSTS_FILE}")
|
||||
"${PIHOLE_CUSTOM_HOSTS_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.
|
||||
|
||||
@@ -242,15 +236,7 @@ compare_local_version_to_git_version() {
|
||||
local git_dir="${1}"
|
||||
# The named component of the project (Core or Web)
|
||||
local pihole_component="${2}"
|
||||
# If we are checking the Core versions,
|
||||
if [[ "${pihole_component}" == "Core" ]]; then
|
||||
# We need to search for "Pi-hole" when using pihole -v
|
||||
local search_term="Pi-hole"
|
||||
elif [[ "${pihole_component}" == "Web" ]]; then
|
||||
# We need to search for "AdminLTE" so store it in a variable as well
|
||||
#shellcheck disable=2034
|
||||
local search_term="AdminLTE"
|
||||
fi
|
||||
|
||||
# Display what we are checking
|
||||
echo_current_diagnostic "${pihole_component} version"
|
||||
# Store the error message in a variable in case we want to change and/or reuse it
|
||||
@@ -263,43 +249,35 @@ compare_local_version_to_git_version() {
|
||||
log_write "${COL_RED}Could not cd into ${git_dir}$COL_NC"
|
||||
if git status &> /dev/null; then
|
||||
# The current version the user is on
|
||||
local remote_version
|
||||
remote_version=$(git describe --tags --abbrev=0);
|
||||
local local_version
|
||||
local_version=$(git describe --tags --abbrev=0);
|
||||
# What branch they are on
|
||||
local remote_branch
|
||||
remote_branch=$(git rev-parse --abbrev-ref HEAD);
|
||||
local local_branch
|
||||
local_branch=$(git rev-parse --abbrev-ref HEAD);
|
||||
# The commit they are on
|
||||
local remote_commit
|
||||
remote_commit=$(git describe --long --dirty --tags --always)
|
||||
local local_commit
|
||||
local_commit=$(git describe --long --dirty --tags --always)
|
||||
# Status of the repo
|
||||
local local_status
|
||||
local_status=$(git status -s)
|
||||
# echo this information out to the user in a nice format
|
||||
# If the current version matches what pihole -v produces, the user is up-to-date
|
||||
if [[ "${remote_version}" == "$(pihole -v | awk '/${search_term}/ {print $6}' | cut -d ')' -f1)" ]]; then
|
||||
log_write "${TICK} ${pihole_component}: ${COL_GREEN}${remote_version}${COL_NC}"
|
||||
# If not,
|
||||
else
|
||||
# echo the current version in yellow, signifying it's something to take a look at, but not a critical error
|
||||
# Also add a URL to an FAQ
|
||||
log_write "${INFO} ${pihole_component}: ${COL_YELLOW}${remote_version:-Untagged}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
|
||||
fi
|
||||
log_write "${TICK} Version: ${local_version}"
|
||||
|
||||
# Print the repo upstreams
|
||||
remotes=$(git remote -v)
|
||||
log_write "${INFO} Remotes: ${remotes//$'\n'/'\n '}"
|
||||
|
||||
# If the repo is on the master branch, they are on the stable codebase
|
||||
if [[ "${remote_branch}" == "master" ]]; then
|
||||
if [[ "${local_branch}" == "master" ]]; then
|
||||
# so the color of the text is green
|
||||
log_write "${INFO} Branch: ${COL_GREEN}${remote_branch}${COL_NC}"
|
||||
log_write "${INFO} Branch: ${COL_GREEN}${local_branch}${COL_NC}"
|
||||
# If it is any other branch, they are in a development branch
|
||||
else
|
||||
# So show that in yellow, signifying it's something to take a look at, but not a critical error
|
||||
log_write "${INFO} Branch: ${COL_YELLOW}${remote_branch:-Detached}${COL_NC} (${FAQ_CHECKOUT_COMMAND})"
|
||||
log_write "${INFO} Branch: ${COL_YELLOW}${local_branch:-Detached}${COL_NC}"
|
||||
fi
|
||||
# echo the current commit
|
||||
log_write "${INFO} Commit: ${remote_commit}"
|
||||
log_write "${INFO} Commit: ${local_commit}"
|
||||
# if `local_status` is non-null, then the repo is not clean, display details here
|
||||
if [[ ${local_status} ]]; then
|
||||
# Replace new lines in the status with 12 spaces to make the output cleaner
|
||||
@@ -333,22 +311,15 @@ compare_local_version_to_git_version() {
|
||||
}
|
||||
|
||||
check_ftl_version() {
|
||||
local ftl_name="FTL"
|
||||
local FTL_VERSION FTL_COMMIT FTL_BRANCH
|
||||
echo_current_diagnostic "${ftl_name} version"
|
||||
echo_current_diagnostic "FTL version"
|
||||
# Use the built in command to check FTL's version
|
||||
FTL_VERSION=$(pihole-FTL -vv | grep -m 1 Version | awk '{printf $2}')
|
||||
FTL_BRANCH=$(pihole-FTL -vv | grep -m 1 Branch | awk '{printf $2}')
|
||||
FTL_COMMIT=$(pihole-FTL -vv | grep -m 1 Commit | awk '{printf $2}')
|
||||
|
||||
# Compare the current FTL version to the remote version
|
||||
if [[ "${FTL_VERSION}" == "$(pihole -v | awk '/FTL/ {print $6}' | cut -d ')' -f1)" ]]; then
|
||||
# If they are the same, FTL is up-to-date
|
||||
log_write "${TICK} ${ftl_name}: ${COL_GREEN}${FTL_VERSION}${COL_NC}"
|
||||
else
|
||||
# If not, show it in yellow, signifying there is an update
|
||||
log_write "${INFO} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
|
||||
fi
|
||||
|
||||
log_write "${TICK} Version: ${FTL_VERSION}"
|
||||
|
||||
# If they use the master branch, they are on the stable codebase
|
||||
if [[ "${FTL_BRANCH}" == "master" ]]; then
|
||||
@@ -357,7 +328,7 @@ check_ftl_version() {
|
||||
# If it is any other branch, they are in a development branch
|
||||
else
|
||||
# So show that in yellow, signifying it's something to take a look at, but not a critical error
|
||||
log_write "${INFO} Branch: ${COL_YELLOW}${FTL_BRANCH}${COL_NC} (${FAQ_CHECKOUT_COMMAND})"
|
||||
log_write "${INFO} Branch: ${COL_YELLOW}${FTL_BRANCH}${COL_NC}"
|
||||
fi
|
||||
|
||||
# echo the current commit
|
||||
@@ -678,15 +649,20 @@ ping_gateway() {
|
||||
local protocol="${1}"
|
||||
ping_ipv4_or_ipv6 "${protocol}"
|
||||
# Check if we are using IPv4 or IPv6
|
||||
# Find the default gateway using IPv4 or IPv6
|
||||
# Find the default gateways using IPv4 or IPv6
|
||||
local gateway
|
||||
gateway="$(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3)"
|
||||
|
||||
# If the gateway variable has a value (meaning a gateway was found),
|
||||
if [[ -n "${gateway}" ]]; then
|
||||
log_write "${INFO} Default IPv${protocol} gateway: ${gateway}"
|
||||
log_write "${INFO} Default IPv${protocol} gateway(s):"
|
||||
|
||||
while IFS= read -r gateway; do
|
||||
log_write " ${gateway}"
|
||||
done < <(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3)
|
||||
|
||||
gateway=$(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3 | head -n 1)
|
||||
# If there was at least one gateway
|
||||
if [ -n "${gateway}" ]; then
|
||||
# Let the user know we will ping the gateway for a response
|
||||
log_write " * Pinging ${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,
|
||||
# on the pihole interface, and tail the last three lines of the output
|
||||
# If pinging the gateway is not successful,
|
||||
@@ -949,10 +925,21 @@ process_status(){
|
||||
else
|
||||
# Otherwise, use the service command and mock the output of `systemctl is-active`
|
||||
local status_of_process
|
||||
if service "${i}" status | grep -E 'is\srunning' &> /dev/null; then
|
||||
status_of_process="active"
|
||||
|
||||
# If DOCKER_VERSION is set, the output is slightly different (s6 init system on Docker)
|
||||
if [ -n "${DOCKER_VERSION}" ]; then
|
||||
if service "${i}" status | grep -E '^up' &> /dev/null; then
|
||||
status_of_process="active"
|
||||
else
|
||||
status_of_process="inactive"
|
||||
fi
|
||||
else
|
||||
status_of_process="inactive"
|
||||
# non-Docker system
|
||||
if service "${i}" status | grep -E 'is\srunning' &> /dev/null; then
|
||||
status_of_process="active"
|
||||
else
|
||||
status_of_process="inactive"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# and print it out to the user
|
||||
@@ -1378,49 +1365,8 @@ spinner(){
|
||||
fi
|
||||
}
|
||||
|
||||
obfuscated_pihole_log() {
|
||||
local pihole_log=("$@")
|
||||
local line
|
||||
local error_to_check_for
|
||||
local line_to_obfuscate
|
||||
local obfuscated_line
|
||||
for line in "${pihole_log[@]}"; do
|
||||
# A common error in the pihole.log is when there is a non-hosts formatted file
|
||||
# that the DNS server is attempting to read. Since it's not formatted
|
||||
# correctly, there will be an entry for "bad address at line n"
|
||||
# So we can check for that here and highlight it in red so the user can see it easily
|
||||
error_to_check_for=$(echo "${line}" | grep 'bad address at')
|
||||
# Some users may not want to have the domains they visit sent to us
|
||||
# To that end, we check for lines in the log that would contain a domain name
|
||||
line_to_obfuscate=$(echo "${line}" | grep ': query\|: forwarded\|: reply')
|
||||
# If the variable contains a value, it found an error in the log
|
||||
if [[ -n ${error_to_check_for} ]]; then
|
||||
# So we can print it in red to make it visible to the user
|
||||
log_write " ${CROSS} ${COL_RED}${line}${COL_NC} (${FAQ_BAD_ADDRESS})"
|
||||
else
|
||||
# If the variable does not a value (the current default behavior), so do not obfuscate anything
|
||||
if [[ -z ${OBFUSCATE} ]]; then
|
||||
log_write " ${line}"
|
||||
# Otherwise, a flag was passed to this command to obfuscate domains in the log
|
||||
else
|
||||
# So first check if there are domains in the log that should be obfuscated
|
||||
if [[ -n ${line_to_obfuscate} ]]; then
|
||||
# If there are, we need to use awk to replace only the domain name (the 6th field in the log)
|
||||
# so we substitute the domain for the placeholder value
|
||||
obfuscated_line=$(echo "${line_to_obfuscate}" | awk -v placeholder="${OBFUSCATED_PLACEHOLDER}" '{sub($6,placeholder); print $0}')
|
||||
log_write " ${obfuscated_line}"
|
||||
else
|
||||
log_write " ${line}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
analyze_pihole_log() {
|
||||
echo_current_diagnostic "Pi-hole log"
|
||||
local pihole_log_head=()
|
||||
local pihole_log_tail=()
|
||||
local pihole_log_permissions
|
||||
local logging_enabled
|
||||
|
||||
@@ -1430,22 +1376,10 @@ analyze_pihole_log() {
|
||||
log_write "${INFO} Query logging is disabled"
|
||||
log_write ""
|
||||
fi
|
||||
# Put the current Internal Field Separator into another variable so it can be restored later
|
||||
OLD_IFS="$IFS"
|
||||
# Get the lines that are in the file(s) and store them in an array for parsing later
|
||||
IFS=$'\r\n'
|
||||
|
||||
pihole_log_permissions=$(ls -lhd "${PIHOLE_LOG}")
|
||||
log_write "${COL_GREEN}${pihole_log_permissions}${COL_NC}"
|
||||
mapfile -t pihole_log_head < <(head -n 20 ${PIHOLE_LOG})
|
||||
log_write " ${COL_CYAN}-----head of $(basename ${PIHOLE_LOG})------${COL_NC}"
|
||||
obfuscated_pihole_log "${pihole_log_head[@]}"
|
||||
log_write ""
|
||||
mapfile -t pihole_log_tail < <(tail -n 20 ${PIHOLE_LOG})
|
||||
log_write " ${COL_CYAN}-----tail of $(basename ${PIHOLE_LOG})------${COL_NC}"
|
||||
obfuscated_pihole_log "${pihole_log_tail[@]}"
|
||||
log_write ""
|
||||
# Set the IFS back to what it was
|
||||
IFS="$OLD_IFS"
|
||||
head_tail_log "${PIHOLE_LOG}" 20
|
||||
}
|
||||
|
||||
curl_to_tricorder() {
|
||||
|
||||
@@ -216,9 +216,8 @@ main() {
|
||||
fi
|
||||
|
||||
if [[ "${FTL_update}" == true || "${core_update}" == true || "${web_update}" == true ]]; then
|
||||
# Force an update of the updatechecker
|
||||
# Update local and remote versions via updatechecker
|
||||
/opt/pihole/updatecheck.sh
|
||||
/opt/pihole/updatecheck.sh x remote
|
||||
echo -e " ${INFO} Local version file information updated."
|
||||
fi
|
||||
|
||||
|
||||
@@ -15,16 +15,30 @@ function get_local_branch() {
|
||||
}
|
||||
|
||||
function get_local_version() {
|
||||
# Return active branch
|
||||
# Return active version
|
||||
cd "${1}" 2> /dev/null || return 1
|
||||
git describe --long --dirty --tags 2> /dev/null || return 1
|
||||
}
|
||||
|
||||
function get_local_hash() {
|
||||
cd "${1}" 2> /dev/null || return 1
|
||||
git rev-parse --short HEAD || return 1
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
function get_remote_hash(){
|
||||
git ls-remote "https://github.com/pi-hole/${1}" --tags "${2}" | awk '{print substr($0, 0,9);}' || return 1
|
||||
}
|
||||
|
||||
# Source the setupvars config file
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/pihole/setupVars.conf
|
||||
|
||||
# Source the utils file
|
||||
# Source the utils file for addOrEditKeyValPair()
|
||||
# shellcheck disable=SC1091
|
||||
. /opt/pihole/utils.sh
|
||||
|
||||
@@ -38,55 +52,82 @@ VERSION_FILE="/etc/pihole/versions"
|
||||
touch "${VERSION_FILE}"
|
||||
chmod 644 "${VERSION_FILE}"
|
||||
|
||||
if [[ "$2" == "remote" ]]; then
|
||||
# if /pihole.docker.tag file exists, we will use it's value later in this script
|
||||
DOCKER_TAG=$(cat /pihole.docker.tag 2>/dev/null)
|
||||
regex='^([0-9]+\.){1,2}(\*|[0-9]+)(-.*)?$|(^nightly$)|(^dev.*$)'
|
||||
if [[ ! "${DOCKER_TAG}" =~ $regex ]]; then
|
||||
# DOCKER_TAG does not match the pattern (see https://regex101.com/r/RsENuz/1), so unset it.
|
||||
unset DOCKER_TAG
|
||||
fi
|
||||
|
||||
if [[ "$3" == "reboot" ]]; then
|
||||
# used in cronjob
|
||||
if [[ "$1" == "reboot" ]]; then
|
||||
sleep 30
|
||||
fi
|
||||
fi
|
||||
|
||||
GITHUB_CORE_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
|
||||
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
GITHUB_WEB_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/AdminLTE/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
|
||||
fi
|
||||
# get Core versions
|
||||
|
||||
GITHUB_FTL_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}"
|
||||
CORE_VERSION="$(get_local_version /etc/.pihole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_VERSION" "${CORE_VERSION}"
|
||||
|
||||
if [[ "${PIHOLE_DOCKER_TAG}" ]]; then
|
||||
GITHUB_DOCKER_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/docker-pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_DOCKER_VERSION" "${GITHUB_DOCKER_VERSION}"
|
||||
fi
|
||||
CORE_BRANCH="$(get_local_branch /etc/.pihole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_BRANCH" "${CORE_BRANCH}"
|
||||
|
||||
else
|
||||
CORE_HASH="$(get_local_hash /etc/.pihole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_HASH" "${CORE_HASH}"
|
||||
|
||||
CORE_BRANCH="$(get_local_branch /etc/.pihole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_BRANCH" "${CORE_BRANCH}"
|
||||
GITHUB_CORE_VERSION="$(get_remote_version pi-hole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
|
||||
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_BRANCH" "${WEB_BRANCH}"
|
||||
fi
|
||||
GITHUB_CORE_HASH="$(get_remote_hash pi-hole "${CORE_BRANCH}")"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_HASH" "${GITHUB_CORE_HASH}"
|
||||
|
||||
FTL_BRANCH="$(pihole-FTL branch)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "FTL_BRANCH" "${FTL_BRANCH}"
|
||||
|
||||
CORE_VERSION="$(get_local_version /etc/.pihole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_VERSION" "${CORE_VERSION}"
|
||||
# get Web versions
|
||||
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
WEB_VERSION="$(get_local_version /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_VERSION" "${WEB_VERSION}"
|
||||
fi
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
|
||||
FTL_VERSION="$(pihole-FTL version)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "FTL_VERSION" "${FTL_VERSION}"
|
||||
WEB_VERSION="$(get_local_version /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_VERSION" "${WEB_VERSION}"
|
||||
|
||||
# PIHOLE_DOCKER_TAG is set as env variable only on docker installations
|
||||
if [[ "${PIHOLE_DOCKER_TAG}" ]]; then
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "DOCKER_VERSION" "${PIHOLE_DOCKER_TAG}"
|
||||
fi
|
||||
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_BRANCH" "${WEB_BRANCH}"
|
||||
|
||||
WEB_HASH="$(get_local_hash /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_HASH" "${WEB_HASH}"
|
||||
|
||||
GITHUB_WEB_VERSION="$(get_remote_version AdminLTE)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
|
||||
|
||||
GITHUB_WEB_HASH="$(get_remote_hash AdminLTE "${WEB_BRANCH}")"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_HASH" "${GITHUB_WEB_HASH}"
|
||||
|
||||
fi
|
||||
|
||||
# get FTL versions
|
||||
|
||||
FTL_VERSION="$(pihole-FTL version)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "FTL_VERSION" "${FTL_VERSION}"
|
||||
|
||||
FTL_BRANCH="$(pihole-FTL branch)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "FTL_BRANCH" "${FTL_BRANCH}"
|
||||
|
||||
FTL_HASH="$(pihole-FTL -v | cut -d "-" -f2)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "FTL_HASH" "${FTL_HASH}"
|
||||
|
||||
GITHUB_FTL_VERSION="$(get_remote_version FTL)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}"
|
||||
|
||||
GITHUB_FTL_HASH="$(get_remote_hash FTL "${FTL_BRANCH}")"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_HASH" "${GITHUB_FTL_HASH}"
|
||||
|
||||
|
||||
# get Docker versions
|
||||
|
||||
if [[ "${DOCKER_TAG}" ]]; then
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "DOCKER_VERSION" "${DOCKER_TAG}"
|
||||
|
||||
GITHUB_DOCKER_VERSION="$(get_remote_version docker-pi-hole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_DOCKER_VERSION" "${GITHUB_DOCKER_VERSION}"
|
||||
fi
|
||||
|
||||
@@ -31,9 +31,12 @@ addOrEditKeyValPair() {
|
||||
local key="${2}"
|
||||
local value="${3}"
|
||||
|
||||
# touch file to prevent grep error if file does not exist yet
|
||||
touch "${file}"
|
||||
|
||||
if grep -q "^${key}=" "${file}"; then
|
||||
# Key already exists in file, modify the value
|
||||
sed -i "/^${key}=/c\\${key}=${value}" "${file}"
|
||||
# Key already exists in file, modify the value
|
||||
sed -i "/^${key}=/c\\${key}=${value}" "${file}"
|
||||
else
|
||||
# Key does not already exist, add it and it's value
|
||||
echo "${key}=${value}" >> "${file}"
|
||||
@@ -51,9 +54,12 @@ addKey(){
|
||||
local file="${1}"
|
||||
local key="${2}"
|
||||
|
||||
# touch file to prevent grep error if file does not exist yet
|
||||
touch "${file}"
|
||||
|
||||
if ! grep -q "^${key}" "${file}"; then
|
||||
# Key does not exist, add it.
|
||||
echo "${key}" >> "${file}"
|
||||
# Key does not exist, add it.
|
||||
echo "${key}" >> "${file}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -70,47 +76,27 @@ removeKey() {
|
||||
sed -i "/^${key}/d" "${file}"
|
||||
}
|
||||
|
||||
#######################
|
||||
# returns path of FTL's port file
|
||||
#######################
|
||||
getFTLAPIPortFile() {
|
||||
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
|
||||
local DEFAULT_PORT_FILE="/run/pihole-FTL.port"
|
||||
local FTL_APIPORT_FILE
|
||||
|
||||
if [ -s "${FTLCONFFILE}" ]; then
|
||||
# if PORTFILE is not set in pihole-FTL.conf, use the default path
|
||||
FTL_APIPORT_FILE="$({ grep '^PORTFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PORT_FILE}"; } | cut -d'=' -f2-)"
|
||||
else
|
||||
# if there is no pihole-FTL.conf, use the default path
|
||||
FTL_APIPORT_FILE="${DEFAULT_PORT_FILE}"
|
||||
fi
|
||||
|
||||
echo "${FTL_APIPORT_FILE}"
|
||||
}
|
||||
|
||||
|
||||
#######################
|
||||
# returns FTL's current telnet API port based on the content of the pihole-FTL.port file
|
||||
#
|
||||
# Takes one argument: path to pihole-FTL.port
|
||||
# Example getFTLAPIPort "/run/pihole-FTL.port"
|
||||
#######################
|
||||
# returns FTL's current telnet API port based on the setting in /etc/pihole-FTL.conf
|
||||
########################
|
||||
getFTLAPIPort(){
|
||||
local PORTFILE="${1}"
|
||||
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
|
||||
local DEFAULT_FTL_PORT=4711
|
||||
local ftl_api_port
|
||||
|
||||
if [ -s "$PORTFILE" ]; then
|
||||
# -s: FILE exists and has a size greater than zero
|
||||
ftl_api_port=$(cat "${PORTFILE}")
|
||||
# Exploit prevention: unset the variable if there is malicious content
|
||||
# Verify that the value read from the file is numeric
|
||||
expr "$ftl_api_port" : "[^[:digit:]]" > /dev/null && unset ftl_api_port
|
||||
if [ -s "$FTLCONFFILE" ]; then
|
||||
# if FTLPORT is not set in pihole-FTL.conf, use the default port
|
||||
ftl_api_port="$({ grep '^FTLPORT=' "${FTLCONFFILE}" || echo "${DEFAULT_FTL_PORT}"; } | cut -d'=' -f2-)"
|
||||
# Exploit prevention: set the port to the default port if there is malicious (non-numeric)
|
||||
# content set in pihole-FTL.conf
|
||||
expr "${ftl_api_port}" : "[^[:digit:]]" > /dev/null && ftl_api_port="${DEFAULT_FTL_PORT}"
|
||||
else
|
||||
# if there is no pihole-FTL.conf, use the default port
|
||||
ftl_api_port="${DEFAULT_FTL_PORT}"
|
||||
fi
|
||||
|
||||
# echo the port found in the portfile or default to the default port
|
||||
echo "${ftl_api_port:=$DEFAULT_FTL_PORT}"
|
||||
echo "${ftl_api_port}"
|
||||
}
|
||||
|
||||
#######################
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
# 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.
|
||||
@@ -8,179 +8,95 @@
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
# Variables
|
||||
DEFAULT="-1"
|
||||
COREGITDIR="/etc/.pihole/"
|
||||
WEBGITDIR="/var/www/html/admin/"
|
||||
|
||||
# Source the setupvars config file
|
||||
# shellcheck disable=SC1091
|
||||
source /etc/pihole/setupVars.conf
|
||||
. /etc/pihole/setupVars.conf
|
||||
|
||||
# Source the versions file poupulated by updatechecker.sh
|
||||
cachedVersions="/etc/pihole/versions"
|
||||
|
||||
if [ -f ${cachedVersions} ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$cachedVersions"
|
||||
else
|
||||
echo "Could not find /etc/pihole/versions. Running update now."
|
||||
pihole updatechecker
|
||||
# shellcheck disable=SC1090
|
||||
. "$cachedVersions"
|
||||
fi
|
||||
|
||||
getLocalVersion() {
|
||||
# FTL requires a different method
|
||||
if [[ "$1" == "FTL" ]]; then
|
||||
pihole-FTL version
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Get the tagged version of the local repository
|
||||
local directory="${1}"
|
||||
local version
|
||||
|
||||
cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
|
||||
version=$(git describe --tags --always || echo "$DEFAULT")
|
||||
if [[ "${version}" =~ ^v ]]; then
|
||||
echo "${version}"
|
||||
elif [[ "${version}" == "${DEFAULT}" ]]; then
|
||||
echo "ERROR"
|
||||
return 1
|
||||
else
|
||||
echo "Untagged"
|
||||
fi
|
||||
return 0
|
||||
case ${1} in
|
||||
"Pi-hole" ) echo "${CORE_VERSION:=N/A}";;
|
||||
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${WEB_VERSION:=N/A}";;
|
||||
"FTL" ) echo "${FTL_VERSION:=N/A}";;
|
||||
esac
|
||||
}
|
||||
|
||||
getLocalHash() {
|
||||
# Local FTL hash does not exist on filesystem
|
||||
if [[ "$1" == "FTL" ]]; then
|
||||
echo "N/A"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Get the short hash of the local repository
|
||||
local directory="${1}"
|
||||
local hash
|
||||
|
||||
cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
|
||||
hash=$(git rev-parse --short HEAD || echo "$DEFAULT")
|
||||
if [[ "${hash}" == "${DEFAULT}" ]]; then
|
||||
echo "ERROR"
|
||||
return 1
|
||||
else
|
||||
echo "${hash}"
|
||||
fi
|
||||
return 0
|
||||
case ${1} in
|
||||
"Pi-hole" ) echo "${CORE_HASH:=N/A}";;
|
||||
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${WEB_HASH:=N/A}";;
|
||||
"FTL" ) echo "${FTL_HASH:=N/A}";;
|
||||
esac
|
||||
}
|
||||
|
||||
getRemoteHash(){
|
||||
# Remote FTL hash is not applicable
|
||||
if [[ "$1" == "FTL" ]]; then
|
||||
echo "N/A"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local daemon="${1}"
|
||||
local branch="${2}"
|
||||
|
||||
hash=$(git ls-remote --heads "https://github.com/pi-hole/${daemon}" | \
|
||||
awk -v bra="$branch" '$0~bra {print substr($0,0,8);exit}')
|
||||
if [[ -n "$hash" ]]; then
|
||||
echo "$hash"
|
||||
else
|
||||
echo "ERROR"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
case ${1} in
|
||||
"Pi-hole" ) echo "${GITHUB_CORE_HASH:=N/A}";;
|
||||
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${GITHUB_WEB_HASH:=N/A}";;
|
||||
"FTL" ) echo "${GITHUB_FTL_HASH:=N/A}";;
|
||||
esac
|
||||
}
|
||||
|
||||
getRemoteVersion(){
|
||||
# Get the version from the remote origin
|
||||
local daemon="${1}"
|
||||
local version
|
||||
local cachedVersions
|
||||
cachedVersions="/etc/pihole/versions"
|
||||
|
||||
#If the above file exists, then we can read from that. Prevents overuse of GitHub API
|
||||
if [[ -f "$cachedVersions" ]]; then
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
. "$cachedVersions"
|
||||
|
||||
case $daemon in
|
||||
"pi-hole" ) echo "${GITHUB_CORE_VERSION}";;
|
||||
"AdminLTE" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${GITHUB_WEB_VERSION}";;
|
||||
"FTL" ) echo "${GITHUB_FTL_VERSION}";;
|
||||
esac
|
||||
|
||||
return 0
|
||||
fi
|
||||
|
||||
version=$(curl --silent --fail "https://api.github.com/repos/pi-hole/${daemon}/releases/latest" | \
|
||||
awk -F: '$1 ~/tag_name/ { print $2 }' | \
|
||||
tr -cd '[[:alnum:]]._-')
|
||||
if [[ "${version}" =~ ^v ]]; then
|
||||
echo "${version}"
|
||||
else
|
||||
echo "ERROR"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
case ${1} in
|
||||
"Pi-hole" ) echo "${GITHUB_CORE_VERSION:=N/A}";;
|
||||
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${GITHUB_WEB_VERSION:=N/A}";;
|
||||
"FTL" ) echo "${GITHUB_FTL_VERSION:=N/A}";;
|
||||
esac
|
||||
}
|
||||
|
||||
getLocalBranch(){
|
||||
# Get the checked out branch of the local directory
|
||||
local directory="${1}"
|
||||
local branch
|
||||
|
||||
# Local FTL btranch is stored in /etc/pihole/ftlbranch
|
||||
if [[ "$1" == "FTL" ]]; then
|
||||
branch="$(pihole-FTL branch)"
|
||||
else
|
||||
cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
|
||||
branch=$(git rev-parse --abbrev-ref HEAD || echo "$DEFAULT")
|
||||
fi
|
||||
if [[ ! "${branch}" =~ ^v ]]; then
|
||||
if [[ "${branch}" == "master" ]]; then
|
||||
echo ""
|
||||
elif [[ "${branch}" == "HEAD" ]]; then
|
||||
echo "in detached HEAD state at "
|
||||
else
|
||||
echo "${branch} "
|
||||
fi
|
||||
else
|
||||
# Branch started in "v"
|
||||
echo "release "
|
||||
fi
|
||||
return 0
|
||||
case ${1} in
|
||||
"Pi-hole" ) echo "${CORE_BRANCH:=N/A}";;
|
||||
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${WEB_BRANCH:=N/A}";;
|
||||
"FTL" ) echo "${FTL_BRANCH:=N/A}";;
|
||||
esac
|
||||
}
|
||||
|
||||
versionOutput() {
|
||||
if [[ "$1" == "AdminLTE" && "${INSTALL_WEB_INTERFACE}" != true ]]; then
|
||||
if [ "$1" = "AdminLTE" ] && [ "${INSTALL_WEB_INTERFACE}" != true ]; then
|
||||
echo " WebAdmin not installed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
[[ "$1" == "pi-hole" ]] && GITDIR=$COREGITDIR
|
||||
[[ "$1" == "AdminLTE" ]] && GITDIR=$WEBGITDIR
|
||||
[[ "$1" == "FTL" ]] && GITDIR="FTL"
|
||||
|
||||
[[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR) && branch=$(getLocalBranch $GITDIR)
|
||||
[[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
|
||||
if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
|
||||
[[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR") && branch=$(getLocalBranch $GITDIR)
|
||||
[[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
|
||||
[ "$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
|
||||
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 [[ "$curHash" == "N/A" ]] || [[ "$latHash" == "N/A" ]]; then
|
||||
output="${1^} hash is not applicable"
|
||||
elif [[ -n "$curHash" ]] && [[ -n "$latHash" ]]; then
|
||||
output="${1^} hash is $curHash (Latest: $latHash)"
|
||||
elif [[ -n "$curHash" ]] && [[ -z "$latHash" ]]; then
|
||||
output="Current ${1^} hash is $curHash"
|
||||
elif [[ -z "$curHash" ]] && [[ -n "$latHash" ]]; then
|
||||
output="Latest ${1^} hash is $latHash"
|
||||
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 of branch $branch is $curHash (Remote: $latHash)"
|
||||
elif [ -n "$curHash" ] && [ -z "$latHash" ]; then
|
||||
output="Current local ${1} hash of branch $branch is $curHash"
|
||||
elif [ -z "$curHash" ] && [ -n "$latHash" ]; then
|
||||
output="Latest remote ${1} hash of branch $branch is $latHash"
|
||||
elif [ -z "$curHash" ] && [ -z "$latHash" ]; then
|
||||
output="Hashes for ${1} not available"
|
||||
else
|
||||
errorOutput
|
||||
return 1
|
||||
fi
|
||||
|
||||
[[ -n "$output" ]] && echo " $output"
|
||||
[ -n "$output" ] && echo " $output"
|
||||
}
|
||||
|
||||
errorOutput() {
|
||||
@@ -189,9 +105,9 @@ errorOutput() {
|
||||
}
|
||||
|
||||
defaultOutput() {
|
||||
versionOutput "pi-hole" "$@"
|
||||
versionOutput "Pi-hole" "$@"
|
||||
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
if [ "${INSTALL_WEB_INTERFACE}" = true ]; then
|
||||
versionOutput "AdminLTE" "$@"
|
||||
fi
|
||||
|
||||
@@ -217,7 +133,7 @@ Options:
|
||||
}
|
||||
|
||||
case "${1}" in
|
||||
"-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
|
||||
"-p" | "--pihole" ) shift; versionOutput "Pi-hole" "$@";;
|
||||
"-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
|
||||
"-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
|
||||
"-h" | "--help" ) helpFunc;;
|
||||
|
||||
@@ -393,13 +393,8 @@ ProcessDHCPSettings() {
|
||||
if [[ "${DHCP_LEASETIME}" == "0" ]]; then
|
||||
leasetime="infinite"
|
||||
elif [[ "${DHCP_LEASETIME}" == "" ]]; then
|
||||
leasetime="24"
|
||||
addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "${leasetime}"
|
||||
elif [[ "${DHCP_LEASETIME}" == "24h" ]]; then
|
||||
#Installation is affected by known bug, introduced in a previous version.
|
||||
#This will automatically clean up setupVars.conf and remove the unnecessary "h"
|
||||
leasetime="24"
|
||||
addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "${leasetime}"
|
||||
leasetime="24h"
|
||||
addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "24"
|
||||
else
|
||||
leasetime="${DHCP_LEASETIME}h"
|
||||
fi
|
||||
@@ -632,6 +627,14 @@ checkDomain()
|
||||
echo "${validDomain}"
|
||||
}
|
||||
|
||||
escapeDots()
|
||||
{
|
||||
# SC suggest bashism ${variable//search/replace}
|
||||
# shellcheck disable=SC2001
|
||||
escaped=$(echo "$1" | sed 's/\./\\./g')
|
||||
echo "${escaped}"
|
||||
}
|
||||
|
||||
addAudit()
|
||||
{
|
||||
shift # skip "-a"
|
||||
@@ -707,6 +710,7 @@ RemoveCustomDNSAddress() {
|
||||
validHost="$(checkDomain "${host}")"
|
||||
if [[ -n "${validHost}" ]]; then
|
||||
if valid_ip "${ip}" || valid_ip6 "${ip}" ; then
|
||||
validHost=$(escapeDots "${validHost}")
|
||||
sed -i "/^${ip} ${validHost}$/Id" "${dnscustomfile}"
|
||||
else
|
||||
echo -e " ${CROSS} Invalid IP has been passed"
|
||||
@@ -734,7 +738,12 @@ AddCustomCNAMERecord() {
|
||||
if [[ -n "${validDomain}" ]]; then
|
||||
validTarget="$(checkDomain "${target}")"
|
||||
if [[ -n "${validTarget}" ]]; then
|
||||
echo "cname=${validDomain},${validTarget}" >> "${dnscustomcnamefile}"
|
||||
if [ "${validDomain}" = "${validTarget}" ]; then
|
||||
echo " ${CROSS} Domain and target are the same. This would cause a DNS loop."
|
||||
exit 1
|
||||
else
|
||||
echo "cname=${validDomain},${validTarget}" >> "${dnscustomcnamefile}"
|
||||
fi
|
||||
else
|
||||
echo " ${CROSS} Invalid Target Passed!"
|
||||
exit 1
|
||||
@@ -760,7 +769,9 @@ RemoveCustomCNAMERecord() {
|
||||
if [[ -n "${validDomain}" ]]; then
|
||||
validTarget="$(checkDomain "${target}")"
|
||||
if [[ -n "${validTarget}" ]]; then
|
||||
sed -i "/cname=${validDomain},${validTarget}$/Id" "${dnscustomcnamefile}"
|
||||
validDomain=$(escapeDots "${validDomain}")
|
||||
validTarget=$(escapeDots "${validTarget}")
|
||||
sed -i "/^cname=${validDomain},${validTarget}$/Id" "${dnscustomcnamefile}"
|
||||
else
|
||||
echo " ${CROSS} Invalid Target Passed!"
|
||||
exit 1
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# Description: Enable service provided by pihole-FTL daemon
|
||||
### END INIT INFO
|
||||
|
||||
#source utils.sh for getFTLPIDFile(), getFTLPID (), getFTLAPIPortFile()
|
||||
#source utils.sh for getFTLPIDFile(), getFTLPID ()
|
||||
PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
. "${utilsfile}"
|
||||
@@ -31,7 +31,6 @@ start() {
|
||||
# Touch files to ensure they exist (create if non-existing, preserve if existing)
|
||||
mkdir -pm 0755 /run/pihole /var/log/pihole
|
||||
[ ! -f "${FTL_PID_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}"
|
||||
[ ! -f "${FTL_PORT_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PORT_FILE}"
|
||||
[ ! -f /var/log/pihole/FTL.log ] && install -m 644 -o pihole -g pihole /dev/null /var/log/pihole/FTL.log
|
||||
[ ! -f /var/log/pihole/pihole.log ] && install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/pihole.log
|
||||
[ ! -f /etc/pihole/dhcp.leases ] && install -m 644 -o pihole -g pihole /dev/null /etc/pihole/dhcp.leases
|
||||
@@ -91,7 +90,7 @@ stop() {
|
||||
echo "Not running"
|
||||
fi
|
||||
# Cleanup
|
||||
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}" "${FTL_PORT_FILE}"
|
||||
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}"
|
||||
echo
|
||||
}
|
||||
|
||||
@@ -111,7 +110,6 @@ status() {
|
||||
|
||||
# Get file paths
|
||||
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||
FTL_PORT_FILE="$(getFTLAPIPortFile)"
|
||||
|
||||
# Get FTL's current PID
|
||||
FTL_PID="$(getFTLPID ${FTL_PID_FILE})"
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
|
||||
@reboot root /usr/sbin/logrotate --state /var/lib/logrotate/pihole /etc/pihole/logrotate
|
||||
|
||||
# Pi-hole: Grab local version and branch every 10 minutes
|
||||
*/10 * * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker local
|
||||
|
||||
# Pi-hole: Grab remote version every 24 hours
|
||||
59 17 * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker remote
|
||||
@reboot root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker remote reboot
|
||||
# Pi-hole: Grab remote and local version every 24 hours
|
||||
59 17 * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker
|
||||
@reboot root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker reboot
|
||||
|
||||
@@ -29,7 +29,8 @@ if (!empty($_SERVER["FQDN"])) {
|
||||
if ($serverName === "pi.hole"
|
||||
|| (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) {
|
||||
// Redirect to Web Interface
|
||||
exit(header("Location: /admin"));
|
||||
header("Location: /admin");
|
||||
exit();
|
||||
} elseif (filter_var($serverName, FILTER_VALIDATE_IP) || in_array($serverName, $authorizedHosts)) {
|
||||
// When directly browsing via IP or authorized hostname
|
||||
// Render splash/landing page based off presence of $landPage file
|
||||
@@ -75,6 +76,6 @@ EOT;
|
||||
exit($splashPage);
|
||||
}
|
||||
|
||||
exit(header("HTTP/1.1 404 Not Found"));
|
||||
|
||||
header("HTTP/1.1 404 Not Found");
|
||||
exit();
|
||||
?>
|
||||
|
||||
@@ -83,6 +83,7 @@ PI_HOLE_INSTALL_DIR="/opt/pihole"
|
||||
PI_HOLE_CONFIG_DIR="/etc/pihole"
|
||||
PI_HOLE_BIN_DIR="/usr/local/bin"
|
||||
PI_HOLE_404_DIR="${webroot}/pihole"
|
||||
FTL_CONFIG_FILE="${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf"
|
||||
if [ -z "$useUpdateVars" ]; then
|
||||
useUpdateVars=false
|
||||
fi
|
||||
@@ -357,7 +358,7 @@ package_manager_detect() {
|
||||
# These variable names match the ones for apt-get. See above for an explanation of what they are for.
|
||||
PKG_INSTALL=("${PKG_MANAGER}" install -y)
|
||||
# CentOS package manager returns 100 when there are packages to update so we need to || true to prevent the script from exiting.
|
||||
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l || true"
|
||||
PKG_COUNT="${PKG_MANAGER} check-update | grep -E '(.i686|.x86|.noarch|.arm|.src)' | wc -l || true"
|
||||
OS_CHECK_DEPS=(grep bind-utils)
|
||||
INSTALLER_DEPS=(git dialog iproute newt procps-ng which chkconfig ca-certificates)
|
||||
PIHOLE_DEPS=(cronie curl findutils sudo unzip libidn2 psmisc libcap nmap-ncat jq)
|
||||
@@ -827,8 +828,11 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
|
||||
|
||||
# Configure networking via dhcpcd
|
||||
setDHCPCD() {
|
||||
# Check if the IP is already in the file
|
||||
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
|
||||
# Regex for matching a non-commented static ip address setting
|
||||
local regex="^[ \t]*static ip_address[ \t]*=[ \t]*${IPV4_ADDRESS}"
|
||||
|
||||
# Check if static IP is already set in file
|
||||
if grep -q "${regex}" /etc/dhcpcd.conf; then
|
||||
printf " %b Static IP already configured\\n" "${INFO}"
|
||||
# If it's not,
|
||||
else
|
||||
@@ -999,10 +1003,10 @@ If you want to specify a port other than 53, separate it with a hash.\
|
||||
# and continue the loop.
|
||||
DNSSettingsCorrect=False
|
||||
else
|
||||
dialog --no-shadow --keep-tite \
|
||||
dialog --no-shadow --no-collapse --keep-tite \
|
||||
--backtitle "Specify Upstream DNS Provider(s)" \
|
||||
--title "Upstream DNS Provider(s)" \
|
||||
--yesno "Are these settings correct?\\n\\tDNS Server 1:\\t${PIHOLE_DNS_1}\\n\\tDNS Server 2:\\t${PIHOLE_DNS_2}" \
|
||||
--yesno "Are these settings correct?\\n"$'\t'"DNS Server 1:"$'\t'"${PIHOLE_DNS_1}\\n"$'\t'"DNS Server 2:"$'\t'"${PIHOLE_DNS_2}" \
|
||||
"${r}" "${c}" && result=0 || result=$?
|
||||
|
||||
case ${result} in
|
||||
@@ -1264,35 +1268,30 @@ version_check_dnsmasq() {
|
||||
# Copy the new Pi-hole DNS config file into the dnsmasq.d directory
|
||||
install -D -m 644 -T "${dnsmasq_pihole_01_source}" "${dnsmasq_pihole_01_target}"
|
||||
printf "%b %b Installed %s\n" "${OVER}" "${TICK}" "${dnsmasq_pihole_01_target}"
|
||||
# Replace our placeholder values with the GLOBAL DNS variables that we populated earlier
|
||||
# First, swap in the interface to listen on,
|
||||
sed -i "s/@INT@/$PIHOLE_INTERFACE/" "${dnsmasq_pihole_01_target}"
|
||||
# Add settings with the GLOBAL DNS variables that we populated earlier
|
||||
# First, set the interface to listen on
|
||||
addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "interface" "$PIHOLE_INTERFACE"
|
||||
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
|
||||
# then swap in the primary DNS server.
|
||||
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" "${dnsmasq_pihole_01_target}"
|
||||
else
|
||||
# Otherwise, remove the line which sets DNS1.
|
||||
sed -i '/^server=@DNS1@/d' "${dnsmasq_pihole_01_target}"
|
||||
# then add in the primary DNS server.
|
||||
addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "server" "$PIHOLE_DNS_1"
|
||||
fi
|
||||
# Ditto if DNS2 is not empty
|
||||
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
|
||||
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" "${dnsmasq_pihole_01_target}"
|
||||
else
|
||||
sed -i '/^server=@DNS2@/d' "${dnsmasq_pihole_01_target}"
|
||||
addKey "${dnsmasq_pihole_01_target}" "server=$PIHOLE_DNS_2"
|
||||
fi
|
||||
|
||||
# Set the cache size
|
||||
sed -i "s/@CACHE_SIZE@/$CACHE_SIZE/" "${dnsmasq_pihole_01_target}"
|
||||
addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "cache-size" "$CACHE_SIZE"
|
||||
|
||||
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' "${dnsmasq_conf}"
|
||||
|
||||
# If the user does not want to enable logging,
|
||||
if [[ "${QUERY_LOGGING}" == false ]] ; then
|
||||
# disable it by commenting out the directive in the DNS config file
|
||||
sed -i 's/^log-queries/#log-queries/' "${dnsmasq_pihole_01_target}"
|
||||
# remove itfrom the DNS config file
|
||||
removeKey "${dnsmasq_pihole_01_target}" "log-queries"
|
||||
else
|
||||
# Otherwise, enable it by uncommenting the directive in the DNS config file
|
||||
sed -i 's/^#log-queries/log-queries/' "${dnsmasq_pihole_01_target}"
|
||||
# Otherwise, enable it by adding the directive to the DNS config file
|
||||
addKey "${dnsmasq_pihole_01_target}" "log-queries"
|
||||
fi
|
||||
|
||||
printf " %b Installing %s..." "${INFO}" "${dnsmasq_rfc6761_06_source}"
|
||||
@@ -1365,9 +1364,9 @@ installConfigs() {
|
||||
chmod 644 "${PI_HOLE_CONFIG_DIR}/dns-servers.conf"
|
||||
|
||||
# Install template file if it does not exist
|
||||
if [[ ! -r "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then
|
||||
if [[ ! -r "${FTL_CONFIG_FILE}" ]]; then
|
||||
install -d -m 0755 ${PI_HOLE_CONFIG_DIR}
|
||||
if ! install -T -o pihole -m 664 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.conf" "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" &>/dev/null; then
|
||||
if ! install -T -o pihole -m 664 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.conf" "${FTL_CONFIG_FILE}" &>/dev/null; then
|
||||
printf " %b Error: Unable to initialize configuration file %s/pihole-FTL.conf\\n" "${COL_LIGHT_RED}" "${PI_HOLE_CONFIG_DIR}"
|
||||
return 1
|
||||
fi
|
||||
@@ -1784,30 +1783,24 @@ create_pihole_user() {
|
||||
|
||||
# This function saves any changes to the setup variables into the setupvars.conf file for future runs
|
||||
finalExports() {
|
||||
# If the setup variable file exists,
|
||||
if [[ -e "${setupVars}" ]]; then
|
||||
# update the variables in the file
|
||||
sed -i.update.bak '/PIHOLE_INTERFACE/d;/PIHOLE_DNS_1\b/d;/PIHOLE_DNS_2\b/d;/QUERY_LOGGING/d;/INSTALL_WEB_SERVER/d;/INSTALL_WEB_INTERFACE/d;/LIGHTTPD_ENABLED/d;/CACHE_SIZE/d;/DNS_FQDN_REQUIRED/d;/DNS_BOGUS_PRIV/d;/DNSMASQ_LISTENING/d;' "${setupVars}"
|
||||
fi
|
||||
# echo the information to the user
|
||||
{
|
||||
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
|
||||
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
|
||||
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
|
||||
echo "QUERY_LOGGING=${QUERY_LOGGING}"
|
||||
echo "INSTALL_WEB_SERVER=${INSTALL_WEB_SERVER}"
|
||||
echo "INSTALL_WEB_INTERFACE=${INSTALL_WEB_INTERFACE}"
|
||||
echo "LIGHTTPD_ENABLED=${LIGHTTPD_ENABLED}"
|
||||
echo "CACHE_SIZE=${CACHE_SIZE}"
|
||||
echo "DNS_FQDN_REQUIRED=${DNS_FQDN_REQUIRED:-true}"
|
||||
echo "DNS_BOGUS_PRIV=${DNS_BOGUS_PRIV:-true}"
|
||||
echo "DNSMASQ_LISTENING=${DNSMASQ_LISTENING:-local}"
|
||||
}>> "${setupVars}"
|
||||
# set or update the variables in the file
|
||||
|
||||
addOrEditKeyValPair "${setupVars}" "PIHOLE_INTERFACE" "${PIHOLE_INTERFACE}"
|
||||
addOrEditKeyValPair "${setupVars}" "PIHOLE_DNS_1" "${PIHOLE_DNS_1}"
|
||||
addOrEditKeyValPair "${setupVars}" "PIHOLE_DNS_2" "${PIHOLE_DNS_2}"
|
||||
addOrEditKeyValPair "${setupVars}" "QUERY_LOGGING" "${QUERY_LOGGING}"
|
||||
addOrEditKeyValPair "${setupVars}" "INSTALL_WEB_SERVER" "${INSTALL_WEB_SERVER}"
|
||||
addOrEditKeyValPair "${setupVars}" "INSTALL_WEB_INTERFACE" "${INSTALL_WEB_INTERFACE}"
|
||||
addOrEditKeyValPair "${setupVars}" "LIGHTTPD_ENABLED" "${LIGHTTPD_ENABLED}"
|
||||
addOrEditKeyValPair "${setupVars}" "CACHE_SIZE" "${CACHE_SIZE}"
|
||||
addOrEditKeyValPair "${setupVars}" "DNS_FQDN_REQUIRED" "${DNS_FQDN_REQUIRED:-true}"
|
||||
addOrEditKeyValPair "${setupVars}" "DNS_BOGUS_PRIV" "${DNS_BOGUS_PRIV:-true}"
|
||||
addOrEditKeyValPair "${setupVars}" "DNSMASQ_LISTENING" "${DNSMASQ_LISTENING:-local}"
|
||||
|
||||
chmod 644 "${setupVars}"
|
||||
|
||||
# Set the privacy level
|
||||
sed -i '/PRIVACYLEVEL/d' "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf"
|
||||
echo "PRIVACYLEVEL=${PRIVACY_LEVEL}" >> "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf"
|
||||
addOrEditKeyValPair "${FTL_CONFIG_FILE}" "PRIVACYLEVEL" "${PRIVACY_LEVEL}"
|
||||
|
||||
# Bring in the current settings and the functions to manipulate them
|
||||
source "${setupVars}"
|
||||
@@ -1895,6 +1888,16 @@ installPihole() {
|
||||
printf " %b Failure in dependent script copy function.\\n" "${CROSS}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# /opt/pihole/utils.sh should be installed by installScripts now, so we can use it
|
||||
if [ -f "${PI_HOLE_INSTALL_DIR}/utils.sh" ]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "${PI_HOLE_INSTALL_DIR}/utils.sh"
|
||||
else
|
||||
printf " %b Failure: /opt/pihole/utils.sh does not exist .\\n" "${CROSS}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install config files
|
||||
if ! installConfigs; then
|
||||
printf " %b Failure in dependent config copy function.\\n" "${CROSS}"
|
||||
@@ -2022,9 +2025,8 @@ update_dialogs() {
|
||||
\\n($strAdd)"\
|
||||
"${r}" "${c}" 2 \
|
||||
"${opt1a}" "${opt1b}" \
|
||||
"${opt2a}" "${opt2b}" || true)
|
||||
"${opt2a}" "${opt2b}") || result=$?
|
||||
|
||||
result=$?
|
||||
case ${result} in
|
||||
"${DIALOG_CANCEL}" | "${DIALOG_ESC}")
|
||||
printf " %b Cancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"
|
||||
@@ -2268,7 +2270,7 @@ get_binary_name() {
|
||||
local rev
|
||||
rev=$(uname -m | sed "s/[^0-9]//g;")
|
||||
local lib
|
||||
lib=$(ldd "$(which sh)" | grep -E '^\s*/lib' | awk '{ print $1 }')
|
||||
lib=$(ldd "$(command -v sh)" | grep -E '^\s*/lib' | awk '{ print $1 }')
|
||||
if [[ "${lib}" == "/lib/ld-linux-aarch64.so.1" ]]; then
|
||||
printf "%b %b Detected AArch64 (64 Bit ARM) processor\\n" "${OVER}" "${TICK}"
|
||||
# set the binary to be used
|
||||
@@ -2569,8 +2571,8 @@ main() {
|
||||
source "${setupVars}"
|
||||
|
||||
# Get the privacy level if it exists (default is 0)
|
||||
if [[ -f "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then
|
||||
PRIVACY_LEVEL=$(sed -ne 's/PRIVACYLEVEL=\(.*\)/\1/p' "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf")
|
||||
if [[ -f "${FTL_CONFIG_FILE}" ]]; then
|
||||
PRIVACY_LEVEL=$(sed -ne 's/PRIVACYLEVEL=\(.*\)/\1/p' "${FTL_CONFIG_FILE}")
|
||||
|
||||
# If no setting was found, default to 0
|
||||
PRIVACY_LEVEL="${PRIVACY_LEVEL:-0}"
|
||||
@@ -2694,9 +2696,8 @@ main() {
|
||||
# Download and compile the aggregated block list
|
||||
runGravity
|
||||
|
||||
# Force an update of the updatechecker
|
||||
# Update local and remote versions via updatechecker
|
||||
/opt/pihole/updatecheck.sh
|
||||
/opt/pihole/updatecheck.sh x remote
|
||||
|
||||
if [[ "${useUpdateVars}" == false ]]; then
|
||||
displayFinalMessage "${pw}"
|
||||
|
||||
86
gravity.sh
86
gravity.sh
@@ -40,6 +40,7 @@ gravityDBschema="${piholeGitDir}/advanced/Templates/gravity.db.sql"
|
||||
gravityDBcopy="${piholeGitDir}/advanced/Templates/gravity_copy.sql"
|
||||
|
||||
domainsExtension="domains"
|
||||
curl_connect_timeout=10
|
||||
|
||||
# Source setupVars from install script
|
||||
setupVars="${piholeDir}/setupVars.conf"
|
||||
@@ -641,7 +642,7 @@ gravity_DownloadBlocklistFromUrl() {
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
httpCode=$(curl -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null)
|
||||
httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null)
|
||||
|
||||
case $url in
|
||||
# Did we "download" a local file?
|
||||
@@ -719,72 +720,25 @@ gravity_DownloadBlocklistFromUrl() {
|
||||
|
||||
# Parse source files into domains format
|
||||
gravity_ParseFileIntoDomains() {
|
||||
local src="${1}" destination="${2}" firstLine
|
||||
local src="${1}" destination="${2}"
|
||||
|
||||
# Determine if we are parsing a consolidated list
|
||||
#if [[ "${src}" == "${piholeDir}/${matterAndLight}" ]]; then
|
||||
# Remove comments and print only the domain name
|
||||
# Most of the lists downloaded are already in hosts file format but the spacing/formatting is not contiguous
|
||||
# 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
|
||||
# 1) Remove carriage returns
|
||||
# 2) Convert all characters to lowercase
|
||||
# 3) Remove comments (text starting with "#", include possible spaces before the hash sign)
|
||||
# 4) Remove lines containing "/"
|
||||
# 5) Remove leading tabs, spaces, etc.
|
||||
# 6) Delete lines not matching domain names
|
||||
< "${src}" tr -d '\r' | \
|
||||
tr '[:upper:]' '[:lower:]' | \
|
||||
sed 's/\s*#.*//g' | \
|
||||
sed -r '/(\/).*$/d' | \
|
||||
sed -r 's/^.*\s+//g' | \
|
||||
sed -r '/([^\.]+\.)+[^\.]{2,}/!d' > "${destination}"
|
||||
chmod 644 "${destination}"
|
||||
return 0
|
||||
#fi
|
||||
|
||||
# Individual file parsing: Keep comments, while parsing domains from each line
|
||||
# We keep comments to respect the list maintainer's licensing
|
||||
read -r firstLine < "${src}"
|
||||
|
||||
# Determine how to parse individual source file formats
|
||||
if [[ "${firstLine,,}" =~ (adblock|ublock|^!) ]]; then
|
||||
# Compare $firstLine against lower case words found in Adblock lists
|
||||
echo -e " ${CROSS} Format: Adblock (list type not supported)"
|
||||
elif grep -q "^address=/" "${src}" &> /dev/null; then
|
||||
# Parse Dnsmasq format lists
|
||||
echo -e " ${CROSS} Format: Dnsmasq (list type not supported)"
|
||||
elif grep -q -E "^https?://" "${src}" &> /dev/null; then
|
||||
# Parse URL list if source file contains "http://" or "https://"
|
||||
# Scanning for "^IPv4$" is too slow with large (1M) lists on low-end hardware
|
||||
echo -ne " ${INFO} Format: URL"
|
||||
|
||||
awk '
|
||||
# Remove URL scheme, optional "username:password@", and ":?/;"
|
||||
# The scheme must be matched carefully to avoid blocking the wrong URL
|
||||
# in cases like:
|
||||
# http://www.evil.com?http://www.good.com
|
||||
# See RFC 3986 section 3.1 for details.
|
||||
/[:?\/;]/ { gsub(/(^[a-zA-Z][a-zA-Z0-9+.-]*:\/\/(.*:.*@)?|[:?\/;].*)/, "", $0) }
|
||||
# Skip lines which are only IPv4 addresses
|
||||
/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ { next }
|
||||
# Print if nonempty
|
||||
length { print }
|
||||
' "${src}" 2> /dev/null > "${destination}"
|
||||
chmod 644 "${destination}"
|
||||
|
||||
echo -e "${OVER} ${TICK} Format: URL"
|
||||
else
|
||||
# Default: Keep hosts/domains file in same format as it was downloaded
|
||||
output=$( { mv "${src}" "${destination}"; } 2>&1 )
|
||||
chmod 644 "${destination}"
|
||||
|
||||
if [[ ! -e "${destination}" ]]; then
|
||||
echo -e "\\n ${CROSS} Unable to move tmp file to ${piholeDir}
|
||||
${output}"
|
||||
gravity_Cleanup "error"
|
||||
fi
|
||||
fi
|
||||
# Remove comments and print only the domain name
|
||||
# Most of the lists downloaded are already in hosts file format but the spacing/formatting is not contiguous
|
||||
# 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
|
||||
# 1) Remove carriage returns
|
||||
# 2) Convert all characters to lowercase
|
||||
# 3) Remove comments (text starting with "#", include possible spaces before the hash sign)
|
||||
# 4) Remove lines containing "/"
|
||||
# 5) Remove leading tabs, spaces, etc.
|
||||
# 6) Delete lines not matching domain names
|
||||
< "${src}" tr -d '\r' | \
|
||||
tr '[:upper:]' '[:lower:]' | \
|
||||
sed 's/\s*#.*//g' | \
|
||||
sed -r '/(\/).*$/d' | \
|
||||
sed -r 's/^.*\s+//g' | \
|
||||
sed -r '/([^\.]+\.)+[^\.]{2,}/!d' > "${destination}"
|
||||
chmod 644 "${destination}"
|
||||
}
|
||||
|
||||
# Report number of entries in a table
|
||||
|
||||
5
pihole
5
pihole
@@ -303,14 +303,13 @@ analyze_ports() {
|
||||
|
||||
statusFunc() {
|
||||
# Determine if there is pihole-FTL service is listening
|
||||
local pid port ftl_api_port ftl_pid_file ftl_apiport_file
|
||||
local pid port ftl_api_port ftl_pid_file
|
||||
|
||||
ftl_pid_file="$(getFTLPIDFile)"
|
||||
|
||||
pid="$(getFTLPID ${ftl_pid_file})"
|
||||
|
||||
ftl_apiport_file="${getFTLAPIPortFile}"
|
||||
ftl_api_port="$(getFTLAPIPort ${ftl_apiport_file})"
|
||||
ftl_api_port="$(getFTLAPIPort)"
|
||||
if [[ "$pid" -eq "-1" ]]; then
|
||||
case "${1}" in
|
||||
"web") echo "-1";;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FROM quay.io/centos/centos:stream8
|
||||
RUN yum install -y git
|
||||
RUN yum install -y git initscripts
|
||||
|
||||
ENV GITDIR /etc/.pihole
|
||||
ENV SCRIPTDIR /opt/pihole
|
||||
|
||||
18
test/_centos_9.Dockerfile
Normal file
18
test/_centos_9.Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM quay.io/centos/centos:stream9
|
||||
RUN yum install -y --allowerasing curl 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,5 +1,5 @@
|
||||
FROM fedora:34
|
||||
RUN dnf install -y git
|
||||
FROM fedora:35
|
||||
RUN dnf install -y git initscripts
|
||||
|
||||
ENV GITDIR /etc/.pihole
|
||||
ENV SCRIPTDIR /opt/pihole
|
||||
18
test/_fedora_36.Dockerfile
Normal file
18
test/_fedora_36.Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM fedora:36
|
||||
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 && \
|
||||
179
test/conftest.py
179
test/conftest.py
@@ -6,12 +6,12 @@ from textwrap import dedent
|
||||
|
||||
|
||||
SETUPVARS = {
|
||||
'PIHOLE_INTERFACE': 'eth99',
|
||||
'PIHOLE_DNS_1': '4.2.2.1',
|
||||
'PIHOLE_DNS_2': '4.2.2.2'
|
||||
"PIHOLE_INTERFACE": "eth99",
|
||||
"PIHOLE_DNS_1": "4.2.2.1",
|
||||
"PIHOLE_DNS_2": "4.2.2.2",
|
||||
}
|
||||
|
||||
IMAGE = 'pytest_pihole:test_container'
|
||||
IMAGE = "pytest_pihole:test_container"
|
||||
|
||||
tick_box = "[\x1b[1;32m\u2713\x1b[0m]"
|
||||
cross_box = "[\x1b[1;31m\u2717\x1b[0m]"
|
||||
@@ -38,132 +38,187 @@ testinfra.backend.docker.DockerBackend.run = run_bash
|
||||
@pytest.fixture
|
||||
def host():
|
||||
# run a container
|
||||
docker_id = subprocess.check_output(
|
||||
['docker', 'run', '-t', '-d', '--cap-add=ALL', IMAGE]).decode().strip()
|
||||
docker_id = (
|
||||
subprocess.check_output(["docker", "run", "-t", "-d", "--cap-add=ALL", IMAGE])
|
||||
.decode()
|
||||
.strip()
|
||||
)
|
||||
|
||||
# return a testinfra connection to the container
|
||||
docker_host = testinfra.get_host("docker://" + docker_id)
|
||||
|
||||
yield docker_host
|
||||
# at the end of the test suite, destroy the container
|
||||
subprocess.check_call(['docker', 'rm', '-f', docker_id])
|
||||
subprocess.check_call(["docker", "rm", "-f", docker_id])
|
||||
|
||||
|
||||
# Helper functions
|
||||
def mock_command(script, args, container):
|
||||
'''
|
||||
"""
|
||||
Allows for setup of commands we don't really want to have to run for real
|
||||
in unit tests
|
||||
'''
|
||||
full_script_path = '/usr/local/bin/{}'.format(script)
|
||||
mock_script = dedent(r'''\
|
||||
"""
|
||||
full_script_path = "/usr/local/bin/{}".format(script)
|
||||
mock_script = dedent(
|
||||
r"""\
|
||||
#!/bin/bash -e
|
||||
echo "\$0 \$@" >> /var/log/{script}
|
||||
case "\$1" in'''.format(script=script))
|
||||
case "\$1" in""".format(
|
||||
script=script
|
||||
)
|
||||
)
|
||||
for k, v in args.items():
|
||||
case = dedent('''
|
||||
case = dedent(
|
||||
"""
|
||||
{arg})
|
||||
echo {res}
|
||||
exit {retcode}
|
||||
;;'''.format(arg=k, res=v[0], retcode=v[1]))
|
||||
;;""".format(
|
||||
arg=k, res=v[0], retcode=v[1]
|
||||
)
|
||||
)
|
||||
mock_script += case
|
||||
mock_script += dedent('''
|
||||
esac''')
|
||||
container.run('''
|
||||
mock_script += dedent(
|
||||
"""
|
||||
esac"""
|
||||
)
|
||||
container.run(
|
||||
"""
|
||||
cat <<EOF> {script}\n{content}\nEOF
|
||||
chmod +x {script}
|
||||
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
|
||||
content=mock_script,
|
||||
scriptlog=script))
|
||||
rm -f /var/log/{scriptlog}""".format(
|
||||
script=full_script_path, content=mock_script, scriptlog=script
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def mock_command_passthrough(script, args, container):
|
||||
'''
|
||||
"""
|
||||
Per other mock_command* functions, allows intercepting of commands we don't want to run for real
|
||||
in unit tests, however also allows only specific arguments to be mocked. Anything not defined will
|
||||
be passed through to the actual command.
|
||||
|
||||
Example use-case: mocking `git pull` but still allowing `git clone` to work as intended
|
||||
'''
|
||||
orig_script_path = container.check_output('command -v {}'.format(script))
|
||||
full_script_path = '/usr/local/bin/{}'.format(script)
|
||||
mock_script = dedent(r'''\
|
||||
"""
|
||||
orig_script_path = container.check_output("command -v {}".format(script))
|
||||
full_script_path = "/usr/local/bin/{}".format(script)
|
||||
mock_script = dedent(
|
||||
r"""\
|
||||
#!/bin/bash -e
|
||||
echo "\$0 \$@" >> /var/log/{script}
|
||||
case "\$1" in'''.format(script=script))
|
||||
case "\$1" in""".format(
|
||||
script=script
|
||||
)
|
||||
)
|
||||
for k, v in args.items():
|
||||
case = dedent('''
|
||||
case = dedent(
|
||||
"""
|
||||
{arg})
|
||||
echo {res}
|
||||
exit {retcode}
|
||||
;;'''.format(arg=k, res=v[0], retcode=v[1]))
|
||||
;;""".format(
|
||||
arg=k, res=v[0], retcode=v[1]
|
||||
)
|
||||
)
|
||||
mock_script += case
|
||||
mock_script += dedent(r'''
|
||||
mock_script += dedent(
|
||||
r"""
|
||||
*)
|
||||
{orig_script_path} "\$@"
|
||||
;;'''.format(orig_script_path=orig_script_path))
|
||||
mock_script += dedent('''
|
||||
esac''')
|
||||
container.run('''
|
||||
;;""".format(
|
||||
orig_script_path=orig_script_path
|
||||
)
|
||||
)
|
||||
mock_script += dedent(
|
||||
"""
|
||||
esac"""
|
||||
)
|
||||
container.run(
|
||||
"""
|
||||
cat <<EOF> {script}\n{content}\nEOF
|
||||
chmod +x {script}
|
||||
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
|
||||
content=mock_script,
|
||||
scriptlog=script))
|
||||
rm -f /var/log/{scriptlog}""".format(
|
||||
script=full_script_path, content=mock_script, scriptlog=script
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def mock_command_run(script, args, container):
|
||||
'''
|
||||
"""
|
||||
Allows for setup of commands we don't really want to have to run for real
|
||||
in unit tests
|
||||
'''
|
||||
full_script_path = '/usr/local/bin/{}'.format(script)
|
||||
mock_script = dedent(r'''\
|
||||
"""
|
||||
full_script_path = "/usr/local/bin/{}".format(script)
|
||||
mock_script = dedent(
|
||||
r"""\
|
||||
#!/bin/bash -e
|
||||
echo "\$0 \$@" >> /var/log/{script}
|
||||
case "\$1 \$2" in'''.format(script=script))
|
||||
case "\$1 \$2" in""".format(
|
||||
script=script
|
||||
)
|
||||
)
|
||||
for k, v in args.items():
|
||||
case = dedent('''
|
||||
case = dedent(
|
||||
"""
|
||||
\"{arg}\")
|
||||
echo {res}
|
||||
exit {retcode}
|
||||
;;'''.format(arg=k, res=v[0], retcode=v[1]))
|
||||
;;""".format(
|
||||
arg=k, res=v[0], retcode=v[1]
|
||||
)
|
||||
)
|
||||
mock_script += case
|
||||
mock_script += dedent('''
|
||||
esac''')
|
||||
container.run('''
|
||||
mock_script += dedent(
|
||||
"""
|
||||
esac"""
|
||||
)
|
||||
container.run(
|
||||
"""
|
||||
cat <<EOF> {script}\n{content}\nEOF
|
||||
chmod +x {script}
|
||||
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
|
||||
content=mock_script,
|
||||
scriptlog=script))
|
||||
rm -f /var/log/{scriptlog}""".format(
|
||||
script=full_script_path, content=mock_script, scriptlog=script
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def mock_command_2(script, args, container):
|
||||
'''
|
||||
"""
|
||||
Allows for setup of commands we don't really want to have to run for real
|
||||
in unit tests
|
||||
'''
|
||||
full_script_path = '/usr/local/bin/{}'.format(script)
|
||||
mock_script = dedent(r'''\
|
||||
"""
|
||||
full_script_path = "/usr/local/bin/{}".format(script)
|
||||
mock_script = dedent(
|
||||
r"""\
|
||||
#!/bin/bash -e
|
||||
echo "\$0 \$@" >> /var/log/{script}
|
||||
case "\$1 \$2" in'''.format(script=script))
|
||||
case "\$1 \$2" in""".format(
|
||||
script=script
|
||||
)
|
||||
)
|
||||
for k, v in args.items():
|
||||
case = dedent('''
|
||||
case = dedent(
|
||||
"""
|
||||
\"{arg}\")
|
||||
echo \"{res}\"
|
||||
exit {retcode}
|
||||
;;'''.format(arg=k, res=v[0], retcode=v[1]))
|
||||
;;""".format(
|
||||
arg=k, res=v[0], retcode=v[1]
|
||||
)
|
||||
)
|
||||
mock_script += case
|
||||
mock_script += dedent('''
|
||||
esac''')
|
||||
container.run('''
|
||||
mock_script += dedent(
|
||||
"""
|
||||
esac"""
|
||||
)
|
||||
container.run(
|
||||
"""
|
||||
cat <<EOF> {script}\n{content}\nEOF
|
||||
chmod +x {script}
|
||||
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
|
||||
content=mock_script,
|
||||
scriptlog=script))
|
||||
rm -f /var/log/{scriptlog}""".format(
|
||||
script=full_script_path, content=mock_script, scriptlog=script
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def run_script(Pihole, script):
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
docker-compose
|
||||
pytest
|
||||
pytest-xdist
|
||||
pytest-cov
|
||||
pytest-testinfra
|
||||
tox
|
||||
|
||||
@@ -2,6 +2,6 @@ from setuptools import setup
|
||||
|
||||
setup(
|
||||
py_modules=[],
|
||||
setup_requires=['pytest-runner'],
|
||||
tests_require=['pytest'],
|
||||
setup_requires=["pytest-runner"],
|
||||
tests_require=["pytest"],
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,27 @@
|
||||
def test_key_val_replacement_works(host):
|
||||
''' Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file '''
|
||||
host.run('''
|
||||
"""Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file"""
|
||||
host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1"
|
||||
addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2"
|
||||
addOrEditKeyValPair "./testoutput" "KEY_ONE" "value3"
|
||||
addOrEditKeyValPair "./testoutput" "KEY_FOUR" "value4"
|
||||
''')
|
||||
output = host.run('''
|
||||
"""
|
||||
)
|
||||
output = host.run(
|
||||
"""
|
||||
cat ./testoutput
|
||||
''')
|
||||
expected_stdout = 'KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n'
|
||||
"""
|
||||
)
|
||||
expected_stdout = "KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_key_addition_works(host):
|
||||
''' Confirms addKey adds a key (no value) to a file without duplicating it '''
|
||||
host.run('''
|
||||
"""Confirms addKey adds a key (no value) to a file without duplicating it"""
|
||||
host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
addKey "./testoutput" "KEY_ONE"
|
||||
addKey "./testoutput" "KEY_ONE"
|
||||
@@ -24,17 +29,21 @@ def test_key_addition_works(host):
|
||||
addKey "./testoutput" "KEY_TWO"
|
||||
addKey "./testoutput" "KEY_THREE"
|
||||
addKey "./testoutput" "KEY_THREE"
|
||||
''')
|
||||
output = host.run('''
|
||||
"""
|
||||
)
|
||||
output = host.run(
|
||||
"""
|
||||
cat ./testoutput
|
||||
''')
|
||||
expected_stdout = 'KEY_ONE\nKEY_TWO\nKEY_THREE\n'
|
||||
"""
|
||||
)
|
||||
expected_stdout = "KEY_ONE\nKEY_TWO\nKEY_THREE\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_key_removal_works(host):
|
||||
''' Confirms removeKey removes a key or key/value pair '''
|
||||
host.run('''
|
||||
"""Confirms removeKey removes a key or key/value pair"""
|
||||
host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1"
|
||||
addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2"
|
||||
@@ -42,81 +51,102 @@ def test_key_removal_works(host):
|
||||
addKey "./testoutput" "KEY_FOUR"
|
||||
removeKey "./testoutput" "KEY_TWO"
|
||||
removeKey "./testoutput" "KEY_FOUR"
|
||||
''')
|
||||
output = host.run('''
|
||||
"""
|
||||
)
|
||||
output = host.run(
|
||||
"""
|
||||
cat ./testoutput
|
||||
''')
|
||||
expected_stdout = 'KEY_ONE=value1\nKEY_THREE=value3\n'
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLAPIPortFile_default(host):
|
||||
''' Confirms getFTLAPIPortFile returns the default API port file path '''
|
||||
output = host.run('''
|
||||
source /opt/pihole/utils.sh
|
||||
getFTLAPIPortFile
|
||||
''')
|
||||
expected_stdout = '/run/pihole-FTL.port\n'
|
||||
"""
|
||||
)
|
||||
expected_stdout = "KEY_ONE=value1\nKEY_THREE=value3\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLAPIPort_default(host):
|
||||
''' Confirms getFTLAPIPort returns the default API port '''
|
||||
output = host.run('''
|
||||
"""Confirms getFTLAPIPort returns the default API port"""
|
||||
output = host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
getFTLAPIPort "/run/pihole-FTL.port"
|
||||
''')
|
||||
expected_stdout = '4711\n'
|
||||
getFTLAPIPort
|
||||
"""
|
||||
)
|
||||
expected_stdout = "4711\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLAPIPortFile_and_getFTLAPIPort_custom(host):
|
||||
''' Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location '''
|
||||
host.run('''
|
||||
tmpfile=$(mktemp)
|
||||
echo "PORTFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf
|
||||
echo "1234" > ${tmpfile}
|
||||
''')
|
||||
output = host.run('''
|
||||
def test_getFTLAPIPort_custom(host):
|
||||
"""Confirms getFTLAPIPort returns a custom API port"""
|
||||
host.run(
|
||||
"""
|
||||
echo "FTLPORT=1234" > /etc/pihole/pihole-FTL.conf
|
||||
"""
|
||||
)
|
||||
output = host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
FTL_API_PORT_FILE=$(getFTLAPIPortFile)
|
||||
getFTLAPIPort "${FTL_API_PORT_FILE}"
|
||||
''')
|
||||
expected_stdout = '1234\n'
|
||||
getFTLAPIPort
|
||||
"""
|
||||
)
|
||||
expected_stdout = "1234\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLAPIPort_malicious(host):
|
||||
"""Confirms getFTLAPIPort returns 4711 if the setting in pihole-FTL.conf contains non-digits"""
|
||||
host.run(
|
||||
"""
|
||||
echo "FTLPORT=*$ssdfsd" > /etc/pihole/pihole-FTL.conf
|
||||
"""
|
||||
)
|
||||
output = host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
getFTLAPIPort
|
||||
"""
|
||||
)
|
||||
expected_stdout = "4711\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLPIDFile_default(host):
|
||||
''' Confirms getFTLPIDFile returns the default PID file path '''
|
||||
output = host.run('''
|
||||
"""Confirms getFTLPIDFile returns the default PID file path"""
|
||||
output = host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
getFTLPIDFile
|
||||
''')
|
||||
expected_stdout = '/run/pihole-FTL.pid\n'
|
||||
"""
|
||||
)
|
||||
expected_stdout = "/run/pihole-FTL.pid\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLPID_default(host):
|
||||
''' Confirms getFTLPID returns the default value if FTL is not running '''
|
||||
output = host.run('''
|
||||
"""Confirms getFTLPID returns the default value if FTL is not running"""
|
||||
output = host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
getFTLPID
|
||||
''')
|
||||
expected_stdout = '-1\n'
|
||||
"""
|
||||
)
|
||||
expected_stdout = "-1\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLPIDFile_and_getFTLPID_custom(host):
|
||||
''' Confirms getFTLPIDFile returns a custom PID file path '''
|
||||
host.run('''
|
||||
"""Confirms getFTLPIDFile returns a custom PID file path"""
|
||||
host.run(
|
||||
"""
|
||||
tmpfile=$(mktemp)
|
||||
echo "PIDFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf
|
||||
echo "1234" > ${tmpfile}
|
||||
''')
|
||||
output = host.run('''
|
||||
"""
|
||||
)
|
||||
output = host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
FTL_PID_FILE=$(getFTLPIDFile)
|
||||
getFTLPID "${FTL_PID_FILE}"
|
||||
''')
|
||||
expected_stdout = '1234\n'
|
||||
"""
|
||||
)
|
||||
expected_stdout = "1234\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
@@ -8,17 +8,20 @@ from .conftest import (
|
||||
|
||||
|
||||
def test_enable_epel_repository_centos(host):
|
||||
'''
|
||||
"""
|
||||
confirms the EPEL package repository is enabled when installed on CentOS
|
||||
'''
|
||||
package_manager_detect = host.run('''
|
||||
"""
|
||||
package_manager_detect = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
package_manager_detect
|
||||
''')
|
||||
expected_stdout = info_box + (' Enabling EPEL package repository '
|
||||
'(https://fedoraproject.org/wiki/EPEL)')
|
||||
"""
|
||||
)
|
||||
expected_stdout = info_box + (
|
||||
" Enabling EPEL package repository " "(https://fedoraproject.org/wiki/EPEL)"
|
||||
)
|
||||
assert expected_stdout in package_manager_detect.stdout
|
||||
expected_stdout = tick_box + ' Installed'
|
||||
expected_stdout = tick_box + " Installed"
|
||||
assert expected_stdout in package_manager_detect.stdout
|
||||
epel_package = host.package('epel-release')
|
||||
epel_package = host.package("epel-release")
|
||||
assert epel_package.is_installed
|
||||
|
||||
@@ -6,60 +6,70 @@ from .conftest import (
|
||||
|
||||
|
||||
def mock_selinux_config(state, host):
|
||||
'''
|
||||
"""
|
||||
Creates a mock SELinux config file with expected content
|
||||
'''
|
||||
"""
|
||||
# validate state string
|
||||
valid_states = ['enforcing', 'permissive', 'disabled']
|
||||
valid_states = ["enforcing", "permissive", "disabled"]
|
||||
assert state in valid_states
|
||||
# getenforce returns the running state of SELinux
|
||||
mock_command('getenforce', {'*': (state.capitalize(), '0')}, host)
|
||||
mock_command("getenforce", {"*": (state.capitalize(), "0")}, host)
|
||||
# create mock configuration with desired content
|
||||
host.run('''
|
||||
host.run(
|
||||
"""
|
||||
mkdir /etc/selinux
|
||||
echo "SELINUX={state}" > /etc/selinux/config
|
||||
'''.format(state=state.lower()))
|
||||
""".format(
|
||||
state=state.lower()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_selinux_enforcing_exit(host):
|
||||
'''
|
||||
"""
|
||||
confirms installer prompts to exit when SELinux is Enforcing by default
|
||||
'''
|
||||
"""
|
||||
mock_selinux_config("enforcing", host)
|
||||
check_selinux = host.run('''
|
||||
check_selinux = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
checkSelinux
|
||||
''')
|
||||
expected_stdout = cross_box + ' Current SELinux: enforcing'
|
||||
"""
|
||||
)
|
||||
expected_stdout = cross_box + " Current SELinux: enforcing"
|
||||
assert expected_stdout in check_selinux.stdout
|
||||
expected_stdout = 'SELinux Enforcing detected, exiting installer'
|
||||
expected_stdout = "SELinux Enforcing detected, exiting installer"
|
||||
assert expected_stdout in check_selinux.stdout
|
||||
assert check_selinux.rc == 1
|
||||
|
||||
|
||||
def test_selinux_permissive(host):
|
||||
'''
|
||||
"""
|
||||
confirms installer continues when SELinux is Permissive
|
||||
'''
|
||||
"""
|
||||
mock_selinux_config("permissive", host)
|
||||
check_selinux = host.run('''
|
||||
check_selinux = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
checkSelinux
|
||||
''')
|
||||
expected_stdout = tick_box + ' Current SELinux: permissive'
|
||||
"""
|
||||
)
|
||||
expected_stdout = tick_box + " Current SELinux: permissive"
|
||||
assert expected_stdout in check_selinux.stdout
|
||||
assert check_selinux.rc == 0
|
||||
|
||||
|
||||
def test_selinux_disabled(host):
|
||||
'''
|
||||
"""
|
||||
confirms installer continues when SELinux is Disabled
|
||||
'''
|
||||
"""
|
||||
mock_selinux_config("disabled", host)
|
||||
check_selinux = host.run('''
|
||||
check_selinux = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
checkSelinux
|
||||
''')
|
||||
expected_stdout = tick_box + ' Current SELinux: disabled'
|
||||
"""
|
||||
)
|
||||
expected_stdout = tick_box + " Current SELinux: disabled"
|
||||
assert expected_stdout in check_selinux.stdout
|
||||
assert check_selinux.rc == 0
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
def test_epel_and_remi_not_installed_fedora(host):
|
||||
'''
|
||||
"""
|
||||
confirms installer does not attempt to install EPEL/REMI repositories
|
||||
on Fedora
|
||||
'''
|
||||
package_manager_detect = host.run('''
|
||||
"""
|
||||
package_manager_detect = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
package_manager_detect
|
||||
''')
|
||||
assert package_manager_detect.stdout == ''
|
||||
"""
|
||||
)
|
||||
assert package_manager_detect.stdout == ""
|
||||
|
||||
epel_package = host.package('epel-release')
|
||||
epel_package = host.package("epel-release")
|
||||
assert not epel_package.is_installed
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = docker
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _centos_8.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 ./test_centos_common_support.py
|
||||
|
||||
8
test/tox.centos_9.ini
Normal file
8
test/tox.centos_9.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _centos_9.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 ./test_centos_common_support.py
|
||||
@@ -2,7 +2,7 @@
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = docker
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _debian_10.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = docker
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _debian_11.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = docker
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _fedora_34.Dockerfile -t pytest_pihole:test_container ../
|
||||
commands = docker build -f _fedora_35.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 ./test_fedora_support.py
|
||||
8
test/tox.fedora_36.ini
Normal file
8
test/tox.fedora_36.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -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 ./test_fedora_support.py
|
||||
@@ -2,7 +2,7 @@
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = docker
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _ubuntu_20.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = docker
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _ubuntu_22.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
|
||||
Reference in New Issue
Block a user