Compare commits

...

41 Commits

Author SHA1 Message Date
RD WebDesign
ac78066657 Fix the github suggestion mess
Some checks are pending
CodeQL / Analyze (pull_request) Waiting to run
Test Supported Distributions / smoke-tests (pull_request) Waiting to run
Test Supported Distributions / distro-test (alpine_3_21) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (alpine_3_22) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (centos_10) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (centos_9) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (debian_11) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (debian_12) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (debian_13) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (fedora_40) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (fedora_41) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (fedora_42) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (ubuntu_20) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (ubuntu_22) (pull_request) Blocked by required conditions
Test Supported Distributions / distro-test (ubuntu_24) (pull_request) Blocked by required conditions
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2025-10-19 16:14:55 -03:00
RD WebDesign
f4a395cb06 Apply suggestion from @MichaIng
Do not handle HTTP code "000" separately.
Use curl error messages for every error, including unknown/unexpected HTTP codes or non-HTTP errors.

Co-authored-by: MichaIng <micha@dietpi.com>
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2025-10-19 14:48:54 -03:00
RD WebDesign
0cfc02cbab Apply suggestion from @MichaIng
Remove the STDERR mute from curl command.

The `-s` flag already mutes all curl errors, so STDERR would only contain something if curl itself (or a shared library) is damaged/missing.

Co-authored-by: MichaIng <micha@dietpi.com>
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2025-10-19 14:41:39 -03:00
RD WebDesign
4e191da1a0 Improve curl error message including exit code and error message
This commit replaces the 3 digits http_code returned by curl with the json
output. This output contains all returned values, including http_code,
exitcode and errormsg.

Using json format, the old http_error "000" string is formated as a number "0".

Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2025-10-17 22:37:45 -03:00
yubiuser
d0ce95c385 Tiny change to make prev2 also a local variable (#6420) 2025-10-15 05:54:57 +02:00
casperklein
9e8e360591 add missing local variable
Signed-off-by: casperklein <casperklein@users.noreply.github.com>
2025-10-15 04:37:19 +02:00
yubiuser
5b53661a79 Bump tox from 4.30.3 to 4.31.0 in /test in the python-dependencies group (#6418) 2025-10-11 12:13:53 +02:00
yubiuser
a626e7de48 Bump the github-actions-dependencies group with 2 updates (#6417) 2025-10-11 12:12:52 +02:00
dependabot[bot]
71dbf2715a Bump tox from 4.30.3 to 4.31.0 in /test in the python-dependencies group
Bumps the python-dependencies group in /test with 1 update: [tox](https://github.com/tox-dev/tox).


Updates `tox` from 4.30.3 to 4.31.0
- [Release notes](https://github.com/tox-dev/tox/releases)
- [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/tox/compare/4.30.3...4.31.0)

---
updated-dependencies:
- dependency-name: tox
  dependency-version: 4.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: python-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-11 10:01:51 +00:00
dependabot[bot]
08ce6499fc Bump the github-actions-dependencies group with 2 updates
Bumps the github-actions-dependencies group with 2 updates: [github/codeql-action](https://github.com/github/codeql-action) and [editorconfig-checker/action-editorconfig-checker](https://github.com/editorconfig-checker/action-editorconfig-checker).


Updates `github/codeql-action` from 3.30.6 to 4.30.8
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](64d10c1313...f443b600d9)

Updates `editorconfig-checker/action-editorconfig-checker` from f40bac9e7d9e7d298fbe36b83e1eff8f0de13fb8 to 1a41284d59c6fe7f1b21ddc4a2b36400a33dc1b4
- [Release notes](https://github.com/editorconfig-checker/action-editorconfig-checker/releases)
- [Commits](f40bac9e7d...1a41284d59)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.30.8
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions-dependencies
- dependency-name: editorconfig-checker/action-editorconfig-checker
  dependency-version: 1a41284d59c6fe7f1b21ddc4a2b36400a33dc1b4
  dependency-type: direct:production
  dependency-group: github-actions-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-11 10:01:39 +00:00
Dominik
106b999054 Rename views, upgrade gravity database and bump gravity databae version (#6386) 2025-10-05 20:33:30 +02:00
yubiuser
564d917022 Bump the python-dependencies group across 1 directory with 3 updates (#6407) 2025-10-04 21:32:30 +02:00
yubiuser
a53dc8fa41 Bump the github-actions-dependencies group across 1 directory with 4 updates (#6409) 2025-10-04 21:30:30 +02:00
dependabot[bot]
37fc86410f Bump the github-actions-dependencies group across 1 directory with 4 updates
Bumps the github-actions-dependencies group with 4 updates in the / directory: [github/codeql-action](https://github.com/github/codeql-action), [actions/stale](https://github.com/actions/stale), [psf/black](https://github.com/psf/black) and [actions/setup-python](https://github.com/actions/setup-python).


Updates `github/codeql-action` from 3.29.10 to 3.30.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](96f518a34f...64d10c1313)

Updates `actions/stale` from 9.1.0 to 10.1.0
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](5bef64f19d...5f858e3efb)

Updates `psf/black` from 25.1.0 to 25.9.0
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](8a737e727a...af0ba72a73)

Updates `actions/setup-python` from 5.6.0 to 6.0.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](a26af69be9...e797f83bcb)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.30.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: actions/stale
  dependency-version: 10.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions-dependencies
- dependency-name: psf/black
  dependency-version: 25.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: actions/setup-python
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-04 19:26:34 +00:00
yubiuser
e0a9b06b8e Use SHA to pin github actions (#6392) 2025-10-04 21:25:09 +02:00
Christian König
f8d14c398e Use sha also fpr editor-config-checker without adding a specific tag commit
Signed-off-by: Christian König <github@yubiuser.dev>
2025-10-04 21:15:12 +02:00
dependabot[bot]
f5ce7b29e0 Bump the python-dependencies group across 1 directory with 3 updates
Bumps the python-dependencies group with 3 updates in the /test directory: [pyyaml](https://github.com/yaml/pyyaml), [pytest](https://github.com/pytest-dev/pytest) and [tox](https://github.com/tox-dev/tox).


Updates `pyyaml` from 6.0.2 to 6.0.3
- [Release notes](https://github.com/yaml/pyyaml/releases)
- [Changelog](https://github.com/yaml/pyyaml/blob/6.0.3/CHANGES)
- [Commits](https://github.com/yaml/pyyaml/compare/6.0.2...6.0.3)

Updates `pytest` from 8.4.1 to 8.4.2
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.4.1...8.4.2)

Updates `tox` from 4.28.4 to 4.30.2
- [Release notes](https://github.com/tox-dev/tox/releases)
- [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/tox/compare/4.28.4...4.30.2)

---
updated-dependencies:
- dependency-name: pyyaml
  dependency-version: 6.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: python-dependencies
- dependency-name: pytest
  dependency-version: 8.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: python-dependencies
- dependency-name: tox
  dependency-version: 4.30.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: python-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-04 10:02:17 +00:00
Dominik
c0a05297e6 Adjust .shellcheckrc to 0.11 and enable some optional checks (#6374) 2025-10-04 09:11:48 +02:00
Dominik
e5112a9fb8 Add Debian 13 Trixie to the test suite (#6382) 2025-10-04 09:10:30 +02:00
yubiuser
c31bfb8d82 Fix typo found during install (#6406) 2025-09-24 18:06:55 +02:00
Jon Herron
59ccfd6d13 Fix typo found during install
Signed-off-by: Jon Herron <jon.herron@yahoo.com>
2025-09-24 08:43:25 -04:00
Adam Warner
950107503d uninstall refactor and improvement (#6339) 2025-08-29 13:30:51 +01:00
Rob Gill
87f307f1d8 Uninstall refactor
Split removePiholeFiles into functions for each category.

Reorder execution so that:
  Pihole-FTL is stopped and removed before shutdown scripts are removed.
  User and group are removed before needed commands are removed.

Remove database and log files in user-specified non-default locations,
and use local directories from basic install.sh, falling back to defaults.

Remove use of sudo as the script already checks that it is called as root.

Advise user of location of crontab backup if is created

Make use of service control functions, command detection and default
directories from basic_install.sh

Align variable names with current basic-install.sh

Disable pihole-FTL service immediately, if systemctl is available

Call systemd daemon-reload after removing service files (on systemd systems)

Signed-off-by: Rob Gill <rrobgill@protonmail.com>
2025-08-29 08:47:00 +10:00
Adam Warner
0a837dd955 Alpine Linux Support and Tests (#6275) 2025-08-27 21:13:37 +01:00
Christian König
7140953500 Use SHA to pin github actions
Signed-off-by: Christian König <github@yubiuser.dev>
2025-08-27 21:02:18 +02:00
Michael Ziminsky (Z)
f50a4c1c89 Don't use hard-coded path for pihole user nologin shell
Signed-off-by: Michael Ziminsky (Z) <mgziminsky@users.noreply.github.com>
2025-08-16 21:47:57 +00:00
Michael Ziminsky (Z)
3908be911c Alpine: Switch cron service from busybox to cronie during install
Signed-off-by: Michael Ziminsky (Z) <mgziminsky@users.noreply.github.com>
2025-08-16 21:47:56 +00:00
Michael Ziminsky (Z)
44f95a4f57 Alpine: Ensure community repo is enabled and handle dependency install errors
Signed-off-by: Michael Ziminsky (Z) <mgziminsky@users.noreply.github.com>
2025-08-16 21:47:56 +00:00
Michael Ziminsky (Z)
4bf67a3c79 Alpine: Add some additional dependencies and minor script fixes
Signed-off-by: Michael Ziminsky (Z) <mgziminsky@users.noreply.github.com>
2025-08-16 21:47:55 +00:00
Rob Gill
d75dae788d Alpine Linux tests
Add Dockerfile and corresponding tox file to add alpine linux 3.21 & 3.22 to the test suite
Add apk as another package manager in the automated install tests
Use short switches for su command as busybox's su does not accept long switches here
Add Alpine test to github workflow

Signed-off-by: Michael Ziminsky (Z) <mgziminsky@users.noreply.github.com>
2025-08-16 21:47:54 +00:00
Michael Ziminsky (Z)
0db48383ae Add support for alpine
Signed-off-by: Michael Ziminsky (Z) <mgziminsky@users.noreply.github.com>
2025-08-16 21:47:54 +00:00
Dominik
73521bb110 Add FTL bash autocomplete (#6376) 2025-08-16 21:02:42 +02:00
yubiuser
36c4193dc5 Bump actions/checkout from 4.2.2 to 5.0.0 in the github-actions-dependencies group (#6387) 2025-08-16 12:36:52 +02:00
dependabot[bot]
6e9e961d3c Bump actions/checkout in the github-actions-dependencies group
Bumps the github-actions-dependencies group with 1 update: [actions/checkout](https://github.com/actions/checkout).


Updates `actions/checkout` from 4.2.2 to 5.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.2.2...v5.0.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-16 10:23:35 +00:00
DL6ER
9e258e7005 Rename views, upgrade gravity database and bump gravity databae version
Signed-off-by: DL6ER <dl6er@dl6er.de>
2025-08-15 19:39:21 +02:00
Christian König
ea274073b4 Add Debian 13 Trixie to the test suite
Signed-off-by: Christian König <github@yubiuser.dev>
2025-08-13 06:27:19 +02:00
Christian König
94bbf5f429 Fix shellcheck warnings
Signed-off-by: Christian König <github@yubiuser.dev>
2025-08-07 19:44:26 +02:00
Christian König
4511daf560 Use pihole-FTL --complete to generate autocomplete suggestions
Signed-off-by: Christian König <github@yubiuser.dev>
2025-08-06 21:01:37 +02:00
Christian König
5d1ef6279f Fix shellcheck warnings for pihole bash completion
Signed-off-by: Christian König <github@yubiuser.dev>
2025-08-06 13:05:48 +02:00
Christian König
340ffbe5e8 Add pihole-FTL bash completion
Signed-off-by: Christian König <github@yubiuser.dev>
2025-08-06 13:05:36 +02:00
Christian König
7baa9c5de0 Adjust .shellcheckrc to 0.11 and enable some optional checks
Signed-off-by: Christian König <github@yubiuser.dev>
2025-08-04 20:38:27 +02:00
27 changed files with 512 additions and 152 deletions

View File

@@ -25,16 +25,16 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
# Initializes the CodeQL tools for scanning.
-
name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@f443b600d91635bebf5b0d9ebc620189c0d6fba5 #v4.30.8
with:
languages: 'python'
-
name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@f443b600d91635bebf5b0d9ebc620189c0d6fba5 #v4.30.8
-
name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@f443b600d91635bebf5b0d9ebc620189c0d6fba5 #v4.30.8

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check if PRs are have merge conflicts
uses: eps1lon/actions-label-merge-conflict@v3.0.3
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 #v3.0.3
with:
dirtyLabel: "PR: Merge Conflict"
repoToken: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -17,7 +17,7 @@ jobs:
issues: write
steps:
- uses: actions/stale@v9.1.0
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 #v10.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30
@@ -40,7 +40,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
- name: Remove 'stale' label
run: gh issue edit ${{ github.event.issue.number }} --remove-label ${{ env.stale_label }}
env:

View File

@@ -17,7 +17,7 @@ jobs:
pull-requests: write
steps:
- uses: actions/stale@v9.1.0
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 #v10.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# Do not automatically mark PR/issue as stale

View File

@@ -33,7 +33,7 @@ jobs:
name: Syncing branches
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
- name: Opening pull request
run: gh pr create -B development -H master --title 'Sync master back into development' --body 'Created by Github action' --label 'internal'
env:

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
with:
fetch-depth: 0 # Differential ShellCheck requires full git history
@@ -31,25 +31,25 @@ jobs:
[[ $FAIL == 1 ]] && exit 1 || echo "Scripts are executable!"
- name: Differential ShellCheck
uses: redhat-plumbers-in-action/differential-shellcheck@v5
uses: redhat-plumbers-in-action/differential-shellcheck@0d9e5b29625f871e6a4215380486d6f1a7cb6cdd #v5.5.5
with:
severity: warning
display-engine: sarif-fmt
- name: Spell-Checking
uses: codespell-project/actions-codespell@master
uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 #v2.1
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
uses: editorconfig-checker/action-editorconfig-checker@1a41284d59c6fe7f1b21ddc4a2b36400a33dc1b4 # tag v2. is really out of date
- name: Run editorconfig-checker
run: editorconfig-checker
- name: Check python code formatting with black
uses: psf/black@stable
uses: psf/black@af0ba72a73598c76189d6dd1b21d8532255d5942 #25.9.0
with:
src: "./test"
options: "--check --diff --color"
@@ -65,6 +65,7 @@ jobs:
[
debian_11,
debian_12,
debian_13,
ubuntu_20,
ubuntu_22,
ubuntu_24,
@@ -73,15 +74,17 @@ jobs:
fedora_40,
fedora_41,
fedora_42,
alpine_3_21,
alpine_3_22,
]
env:
DISTRO: ${{matrix.distro}}
steps:
- name: Checkout repository
uses: actions/checkout@v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
- name: Set up Python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #v6.0.0
with:
python-version: "3.13"

View File

@@ -1,2 +1,6 @@
external-sources=true # allow shellcheck to read external sources
disable=SC3043 #disable SC3043: In POSIX sh, local is undefined.
enable=useless-use-of-cat # disabled by default as of shellcheck 0.11.0
enable=avoid-negated-conditions # avoid-negated-conditions is optional as of shellcheck 0.11.0
enable=require-variable-braces
enable=deprecate-which

View File

@@ -150,4 +150,10 @@ upgrade_gravityDB(){
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/18_to_19.sql"
version=19
fi
if [[ "$version" == "19" ]]; then
# Update views to use new allowlist/denylist names
echo -e " ${INFO} Upgrading gravity database from version 19 to 20"
pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/19_to_20.sql"
version=20
fi
}

View File

@@ -0,0 +1,43 @@
.timeout 30000
BEGIN TRANSACTION;
DROP VIEW vw_whitelist;
CREATE VIEW vw_allowlist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
FROM domainlist
LEFT JOIN domainlist_by_group ON domainlist_by_group.domainlist_id = domainlist.id
LEFT JOIN "group" ON "group".id = domainlist_by_group.group_id
WHERE domainlist.enabled = 1 AND (domainlist_by_group.group_id IS NULL OR "group".enabled = 1)
AND domainlist.type = 0
ORDER BY domainlist.id;
DROP VIEW vw_blacklist;
CREATE VIEW vw_denylist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
FROM domainlist
LEFT JOIN domainlist_by_group ON domainlist_by_group.domainlist_id = domainlist.id
LEFT JOIN "group" ON "group".id = domainlist_by_group.group_id
WHERE domainlist.enabled = 1 AND (domainlist_by_group.group_id IS NULL OR "group".enabled = 1)
AND domainlist.type = 1
ORDER BY domainlist.id;
DROP VIEW vw_regex_whitelist;
CREATE VIEW vw_regex_allowlist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
FROM domainlist
LEFT JOIN domainlist_by_group ON domainlist_by_group.domainlist_id = domainlist.id
LEFT JOIN "group" ON "group".id = domainlist_by_group.group_id
WHERE domainlist.enabled = 1 AND (domainlist_by_group.group_id IS NULL OR "group".enabled = 1)
AND domainlist.type = 2
ORDER BY domainlist.id;
DROP VIEW vw_regex_blacklist;
CREATE VIEW vw_regex_denylist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
FROM domainlist
LEFT JOIN domainlist_by_group ON domainlist_by_group.domainlist_id = domainlist.id
LEFT JOIN "group" ON "group".id = domainlist_by_group.group_id
WHERE domainlist.enabled = 1 AND (domainlist_by_group.group_id IS NULL OR "group".enabled = 1)
AND domainlist.type = 3
ORDER BY domainlist.id;
UPDATE info SET value = 20 WHERE property = 'version';
COMMIT;

View File

@@ -672,7 +672,7 @@ dig_at() {
local record_type="A"
fi
# Find a random blocked url that has not been whitelisted and is not ABP style.
# Find a random blocked url that has not been allowlisted and is not ABP style.
# This helps emulate queries to different domains that a user might query
# It will also give extra assurance that Pi-hole is correctly resolving and blocking domains
local random_url
@@ -778,7 +778,7 @@ process_status(){
:
else
# non-Docker system
if service "${i}" status | grep -E 'is\srunning' &> /dev/null; then
if service "${i}" status | grep -q -E 'is\srunning|started'; then
status_of_process="active"
else
status_of_process="inactive"
@@ -1088,7 +1088,7 @@ show_adlists() {
}
show_domainlist() {
show_db_entries "Domainlist (0/1 = exact white-/blacklist, 2/3 = regex white-/blacklist)" "SELECT id,CASE type WHEN '0' THEN '0 ' WHEN '1' THEN ' 1 ' WHEN '2' THEN ' 2 ' WHEN '3' THEN ' 3' ELSE type END type,CASE enabled WHEN '0' THEN ' 0' WHEN '1' THEN ' 1' ELSE enabled END enabled,GROUP_CONCAT(domainlist_by_group.group_id) group_ids,domain,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM domainlist LEFT JOIN domainlist_by_group ON domainlist.id = domainlist_by_group.domainlist_id GROUP BY id;" "5 4 7 12 100 19 19 50"
show_db_entries "Domainlist (0/1 = exact allow-/denylist, 2/3 = regex allow-/denylist)" "SELECT id,CASE type WHEN '0' THEN '0 ' WHEN '1' THEN ' 1 ' WHEN '2' THEN ' 2 ' WHEN '3' THEN ' 3' ELSE type END type,CASE enabled WHEN '0' THEN ' 0' WHEN '1' THEN ' 1' ELSE enabled END enabled,GROUP_CONCAT(domainlist_by_group.group_id) group_ids,domain,datetime(date_added,'unixepoch','localtime') date_added,datetime(date_modified,'unixepoch','localtime') date_modified,comment FROM domainlist LEFT JOIN domainlist_by_group ON domainlist.id = domainlist_by_group.domainlist_id GROUP BY id;" "5 4 7 12 100 19 19 50"
}
show_clients() {

View File

@@ -86,6 +86,7 @@ if [[ "$*" == *"once"* ]]; then
if [[ "$*" != *"quiet"* ]]; then
echo -ne " ${INFO} Running logrotate ..."
fi
mkdir -p "${STATEFILE%/*}"
/usr/sbin/logrotate --force --state "${STATEFILE}" /etc/pihole/logrotate
else
# Handle rotation for each log file
@@ -115,4 +116,3 @@ else
echo -e "${OVER} ${TICK} Deleted ${deleted} queries from long-term query database"
fi
fi

View File

@@ -66,7 +66,7 @@ CREATE TABLE info
value TEXT NOT NULL
);
INSERT INTO "info" VALUES('version','19');
INSERT INTO "info" VALUES('version','20');
/* This is a flag to indicate if gravity was restored from a backup
false = not restored,
failed = restoration failed due to no backup
@@ -111,7 +111,7 @@ CREATE TRIGGER tr_domainlist_update AFTER UPDATE ON domainlist
UPDATE domainlist SET date_modified = (cast(strftime('%s', 'now') as int)) WHERE domain = NEW.domain;
END;
CREATE VIEW vw_whitelist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
CREATE VIEW vw_allowlist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
FROM domainlist
LEFT JOIN domainlist_by_group ON domainlist_by_group.domainlist_id = domainlist.id
LEFT JOIN "group" ON "group".id = domainlist_by_group.group_id
@@ -119,7 +119,7 @@ CREATE VIEW vw_whitelist AS SELECT domain, domainlist.id AS id, domainlist_by_gr
AND domainlist.type = 0
ORDER BY domainlist.id;
CREATE VIEW vw_blacklist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
CREATE VIEW vw_denylist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
FROM domainlist
LEFT JOIN domainlist_by_group ON domainlist_by_group.domainlist_id = domainlist.id
LEFT JOIN "group" ON "group".id = domainlist_by_group.group_id
@@ -127,7 +127,7 @@ CREATE VIEW vw_blacklist AS SELECT domain, domainlist.id AS id, domainlist_by_gr
AND domainlist.type = 1
ORDER BY domainlist.id;
CREATE VIEW vw_regex_whitelist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
CREATE VIEW vw_regex_allowlist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
FROM domainlist
LEFT JOIN domainlist_by_group ON domainlist_by_group.domainlist_id = domainlist.id
LEFT JOIN "group" ON "group".id = domainlist_by_group.group_id
@@ -135,7 +135,7 @@ CREATE VIEW vw_regex_whitelist AS SELECT domain, domainlist.id AS id, domainlist
AND domainlist.type = 2
ORDER BY domainlist.id;
CREATE VIEW vw_regex_blacklist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
CREATE VIEW vw_regex_denylist AS SELECT domain, domainlist.id AS id, domainlist_by_group.group_id AS group_id
FROM domainlist
LEFT JOIN domainlist_by_group ON domainlist_by_group.domainlist_id = domainlist.id
LEFT JOIN "group" ON "group".id = domainlist_by_group.group_id

View File

@@ -0,0 +1,40 @@
#!/sbin/openrc-run
# shellcheck shell=sh disable=SC2034
: "${PI_HOLE_SCRIPT_DIR:=/opt/pihole}"
command="/usr/bin/pihole-FTL"
command_user="pihole:pihole"
supervisor=supervise-daemon
command_args_foreground="-f"
command_background=true
pidfile="/run/${RC_SVCNAME}_openrc.pid"
extra_started_commands="reload"
respawn_max=5
respawn_period=60
capabilities="^CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN,CAP_SYS_TIME"
depend() {
want net
provide dns
}
checkconfig() {
$command -f test
}
start_pre() {
sh "${PI_HOLE_SCRIPT_DIR}/pihole-FTL-prestart.sh"
}
stop_post() {
sh "${PI_HOLE_SCRIPT_DIR}/pihole-FTL-poststop.sh"
}
reload() {
checkconfig || return $?
ebegin "Reloading ${RC_SVCNAME}"
start-stop-daemon --signal HUP --pidfile "${pidfile}"
eend $?
}

View File

@@ -0,0 +1,9 @@
#!/bin/bash
#
# Bash completion script for pihole-FTL
#
# This completion script provides tab completion for pihole-FTL CLI flags and commands.
# It uses the `pihole-FTL --complete` command to generate the completion options.
_complete_FTL() { mapfile -t COMPREPLY < <(pihole-FTL --complete "${COMP_WORDS[@]}"); }
complete -F _complete_FTL pihole-FTL

View File

@@ -1,5 +1,9 @@
#!/bin/bash
#
# Bash completion script for pihole
#
_pihole() {
local cur prev opts opts_lists opts_checkout opts_debug opts_logging opts_query opts_update opts_networkflush
local cur prev prev2 opts opts_lists opts_checkout opts_debug opts_logging opts_query opts_update opts_networkflush
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
@@ -8,40 +12,40 @@ _pihole() {
case "${prev}" in
"pihole")
opts="allow allow-regex allow-wild deny checkout debug disable enable flush help logging query repair regex reloaddns reloadlists setpassword status tail uninstall updateGravity updatePihole version wildcard networkflush api"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts}" -- "${cur}")
;;
"allow"|"deny"|"wildcard"|"regex"|"allow-regex"|"allow-wild")
opts_lists="\not \--delmode \--quiet \--list \--help"
COMPREPLY=( $(compgen -W "${opts_lists}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts_lists}" -- "${cur}")
;;
"checkout")
opts_checkout="core ftl web master dev"
COMPREPLY=( $(compgen -W "${opts_checkout}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts_checkout}" -- "${cur}")
;;
"debug")
opts_debug="-a"
COMPREPLY=( $(compgen -W "${opts_debug}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts_debug}" -- "${cur}")
;;
"logging")
opts_logging="on off 'off noflush'"
COMPREPLY=( $(compgen -W "${opts_logging}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts_logging}" -- "${cur}")
;;
"query")
opts_query="--partial --all"
COMPREPLY=( $(compgen -W "${opts_query}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts_query}" -- "${cur}")
;;
"updatePihole"|"-up")
opts_update="--check-only"
COMPREPLY=( $(compgen -W "${opts_update}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts_update}" -- "${cur}")
;;
"networkflush")
opts_networkflush="--arp"
COMPREPLY=( $(compgen -W "${opts_networkflush}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts_networkflush}" -- "${cur}")
;;
"core"|"web"|"ftl")
if [[ "$prev2" == "checkout" ]]; then
opts_checkout="master development"
COMPREPLY=( $(compgen -W "${opts_checkout}" -- ${cur}) )
mapfile -t COMPREPLY < <(compgen -W "${opts_checkout}" -- "${cur}")
else
return 1
fi

View File

@@ -94,8 +94,8 @@ fresh_install=true
adlistFile="/etc/pihole/adlists.list"
# Pi-hole needs an IP address; to begin, these variables are empty since we don't know what the IP is until this script can run
IPV4_ADDRESS=${IPV4_ADDRESS}
IPV6_ADDRESS=${IPV6_ADDRESS}
IPV4_ADDRESS=
IPV6_ADDRESS=
# Give settings their default values. These may be changed by prompts later in the script.
QUERY_LOGGING=
PRIVACY_LEVEL=
@@ -154,6 +154,36 @@ Pi-hole dependency meta package
EOM
)
# List of required packages on APK based systems
PIHOLE_META_VERSION_APK=0.1
PIHOLE_META_DEPS_APK=(
bash
bash-completion
bind-tools
binutils
coreutils
cronie
curl
dialog
git
grep
iproute2-minimal # piholeARPTable.sh
iproute2-ss # piholeDebug.sh
jq
libcap
logrotate
lscpu # piholeDebug.sh
lshw # piholeDebug.sh
ncurses
procps-ng
psmisc
shadow
sudo
tzdata
unzip
wget
)
######## Undocumented Flags. Shhh ########
# These are undocumented flags; some of which we can use when repairing an installation
# The runUnattended flag is one example of this
@@ -161,7 +191,7 @@ repair=false
runUnattended=false
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
case "${var}" in
"--repair") repair=true ;;
"--unattended") runUnattended=true ;;
esac
@@ -271,7 +301,15 @@ package_manager_detect() {
PKG_COUNT="${PKG_MANAGER} check-update | grep -E '(.i686|.x86|.noarch|.arm|.src|.riscv64)' | wc -l || true"
# The command we will use to remove packages (used in the uninstaller)
PKG_REMOVE="${PKG_MANAGER} remove -y"
# If neither apt-get or yum/dnf package managers were found
# If neither apt-get or yum/dnf package managers were found, check for apk.
elif is_command apk; then
PKG_MANAGER="apk"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_INSTALL="${PKG_MANAGER} add"
PKG_COUNT="${PKG_MANAGER} list --upgradable -q | wc -l"
PKG_REMOVE="${PKG_MANAGER} del"
else
# we cannot install required packages
printf " %b No supported package manager found\\n" "${CROSS}"
@@ -282,13 +320,20 @@ package_manager_detect() {
build_dependency_package(){
# This function will build a package that contains all the dependencies needed for Pi-hole
if is_command apk ; then
local str="APK based system detected. Dependencies will be installed using a virtual package named pihole-meta"
printf " %b %s...\\n" "${INFO}" "${str}"
return 0
fi
# remove any leftover build directory that may exist
rm -rf /tmp/pihole-meta_*
# Create a fresh build directory with random name
# Busybox Compat: `mktemp` long flags unsupported
# -d flag is short form of --directory
local tempdir
tempdir="$(mktemp --directory /tmp/pihole-meta_XXXXX)"
tempdir="$(mktemp -d /tmp/pihole-meta_XXXXX)"
chmod 0755 "${tempdir}"
if is_command apt-get; then
@@ -576,7 +621,7 @@ Do you wish to continue with an IPv6-only installation?\\n\\n" \
;;
esac
DNS_SERVERS="$DNS_SERVERS_IPV6_ONLY"
DNS_SERVERS="${DNS_SERVERS_IPV6_ONLY}"
printf " %b Proceeding with IPv6 only installation.\\n" "${INFO}"
}
@@ -652,7 +697,7 @@ chooseInterface() {
PIHOLE_INTERFACE=$(dialog --no-shadow --keep-tite --output-fd 1 \
--cancel-label "Exit" --ok-label "Select" \
--radiolist "Choose An Interface (press space to toggle selection)" \
${r} ${c} "${interfaceCount}" ${interfacesList})
${r} ${c} "${interfaceCount}" "${interfacesList}")
result=$?
case ${result} in
@@ -674,9 +719,9 @@ testIPv6() {
# first will contain fda2 (ULA)
printf -v first "%s" "${1%%:*}"
# value1 will contain 253 which is the decimal value corresponding to 0xFD
value1=$(((0x$first) / 256))
value1=$(((0x${first}) / 256))
# value2 will contain 162 which is the decimal value corresponding to 0xA2
value2=$(((0x$first) % 256))
value2=$(((0x${first}) % 256))
# the ULA test is testing for fc00::/7 according to RFC 4193
if (((value1 & 254) == 252)); then
# echoing result to calling function as return value
@@ -701,7 +746,7 @@ find_IPv6_information() {
# For each address in the array above, determine the type of IPv6 address it is
for i in "${IPV6_ADDRESSES[@]}"; do
# Check if it's ULA, GUA, or LL by using the function created earlier
result=$(testIPv6 "$i")
result=$(testIPv6 "${i}")
# If it's a ULA address, use it and store it as a global variable
[[ "${result}" == "ULA" ]] && ULA_ADDRESS="${i%/*}"
# If it's a GUA address, use it and store it as a global variable
@@ -736,7 +781,7 @@ collect_v4andv6_information() {
printf " %b IPv4 address: %s\\n" "${INFO}" "${IPV4_ADDRESS}"
find_IPv6_information
printf " %b IPv6 address: %s\\n" "${INFO}" "${IPV6_ADDRESS}"
if [ "$IPV4_ADDRESS" == "" ] && [ "$IPV6_ADDRESS" != "" ]; then
if [ "${IPV4_ADDRESS}" == "" ] && [ "${IPV6_ADDRESS}" != "" ]; then
confirm_ipv6_only
fi
}
@@ -756,7 +801,7 @@ valid_ip() {
local regex="^${ipv4elem}\\.${ipv4elem}\\.${ipv4elem}\\.${ipv4elem}${portelem}$"
# Evaluate the regex, and return the result
[[ $ip =~ ${regex} ]]
[[ ${ip} =~ ${regex} ]]
stat=$?
return "${stat}"
@@ -791,7 +836,7 @@ setDNS() {
DNSChooseOptions=()
local DNSServerCount=0
# Save the old Internal Field Separator in a variable,
OIFS=$IFS
OIFS=${IFS}
# and set the new one to newline
IFS=$'\n'
# Put the DNS Servers into an array
@@ -859,7 +904,7 @@ If you want to specify a port other than 53, separate it with a hash.\
esac
# Clean user input and replace whitespace with comma.
piholeDNS=$(sed 's/[, \t]\+/,/g' <<<"${piholeDNS}")
piholeDNS="${piholeDNS//[[:blank:]]/,}"
# Separate the user input into the two DNS values (separated by a comma)
printf -v PIHOLE_DNS_1 "%s" "${piholeDNS%%,*}"
@@ -915,7 +960,7 @@ If you want to specify a port other than 53, separate it with a hash.\
done
else
# Save the old Internal Field Separator in a variable,
OIFS=$IFS
OIFS=${IFS}
# and set the new one to newline
IFS=$'\n'
for DNSServer in ${DNS_SERVERS}; do
@@ -1137,7 +1182,8 @@ installScripts() {
install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./automated\ install/uninstall.sh
install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./advanced/Scripts/COL_TABLE
install -o "${USER}" -Dm755 -t "${PI_HOLE_BIN_DIR}" pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
install -Dm644 ./advanced/bash-completion/pihole.bash /etc/bash_completion.d/pihole
install -Dm644 ./advanced/bash-completion/pihole-ftl.bash /etc/bash_completion.d/pihole-FTL
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
else
@@ -1176,7 +1222,12 @@ installConfigs() {
# Load final service
systemctl daemon-reload
else
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.service" '/etc/init.d/pihole-FTL'
local INIT="service"
if is_command openrc; then
INIT="openrc"
fi
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.${INIT}" '/etc/init.d/pihole-FTL'
fi
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL-prestart.sh" "${PI_HOLE_INSTALL_DIR}/pihole-FTL-prestart.sh"
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL-poststop.sh" "${PI_HOLE_INSTALL_DIR}/pihole-FTL-poststop.sh"
@@ -1265,6 +1316,8 @@ enable_service() {
if is_command systemctl; then
# use that to enable the service
systemctl -q enable "${1}"
elif is_command openrc; then
rc-update add "${1}" "${2:-default}" &> /dev/null
else
# Otherwise, use update-rc.d to accomplish this
update-rc.d "${1}" defaults >/dev/null
@@ -1280,7 +1333,10 @@ disable_service() {
# If systemctl exists,
if is_command systemctl; then
# use that to disable the service
systemctl -q disable "${1}"
systemctl -q disable --now "${1}"
elif is_command openrc; then
rc-update del "${1}" "${2:-default}" &> /dev/null
else
# Otherwise, use update-rc.d to accomplish this
update-rc.d "${1}" disable >/dev/null
@@ -1293,6 +1349,8 @@ check_service_active() {
if is_command systemctl; then
# use that to check the status of the service
systemctl -q is-enabled "${1}" 2>/dev/null
elif is_command openrc; then
rc-status default boot | grep -q "${1}"
else
# Otherwise, fall back to service command
service "${1}" status &>/dev/null
@@ -1394,8 +1452,27 @@ install_dependent_packages() {
printf " %b Error: Unable to find Pi-hole dependency package.\\n" "${COL_RED}"
return 1
fi
# Install Alpine packages
elif is_command apk; then
local repo_str="Ensuring alpine 'community' repo is enabled."
printf "%b %b %s" "${OVER}" "${INFO}" "${repo_str}"
# If neither apt-get or yum/dnf package managers were found
local pattern='^\s*#(.*/community/?)\s*$'
sed -Ei "s:${pattern}:\1:" /etc/apk/repositories
if grep -Eq "${pattern}" /etc/apk/repositories; then
# Repo still commented out = Failure
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${repo_str}"
else
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${repo_str}"
fi
printf " %b %s..." "${INFO}" "${str}"
if { ${PKG_INSTALL} -q -t "pihole-meta=${PIHOLE_META_VERSION_APK}" "${PIHOLE_META_DEPS_APK[@]}" &>/dev/null; }; then
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
else
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
printf " %b Error: Unable to install Pi-hole dependency package.\\n" "${COL_RED}"
return 1
fi
else
# we cannot install the dependency package
printf " %b No supported package manager found\\n" "${CROSS}"
@@ -1420,6 +1497,15 @@ installCron() {
# Randomize update checker time
sed -i "s/59 17/$((1 + RANDOM % 58)) $((12 + RANDOM % 8))/" /etc/cron.d/pihole
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
# Switch off of busybox cron on alpine
if is_command openrc; then
printf " %b Switching from busybox crond to cronie...\\n" "${INFO}"
stop_service crond
disable_service crond
enable_service cronie
restart_service cronie
fi
}
# Gravity is a very important script as it aggregates all of the domains into a single HOSTS formatted list,
@@ -1469,7 +1555,7 @@ create_pihole_user() {
# then create and add her to the pihole group
local str="Creating user 'pihole'"
printf "%b %b %s..." "${OVER}" "${INFO}" "${str}"
if useradd -r --no-user-group -g pihole -s /usr/sbin/nologin pihole; then
if useradd -r --no-user-group -g pihole -s "$(command -v nologin)" pihole; then
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
else
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
@@ -1484,7 +1570,7 @@ create_pihole_user() {
# create and add pihole user to the pihole group
local str="Creating user 'pihole'"
printf "%b %b %s..." "${OVER}" "${INFO}" "${str}"
if useradd -r --no-user-group -g pihole -s /usr/sbin/nologin pihole; then
if useradd -r --no-user-group -g pihole -s "$(command -v nologin)" pihole; then
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
else
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
@@ -1636,9 +1722,9 @@ check_download_exists() {
status=$(curl --head --silent "https://ftl.pi-hole.net/${1}" | head -n 1)
# Check the status code
if grep -q "200" <<<"$status"; then
if grep -q "200" <<<"${status}"; then
return 0
elif grep -q "404" <<<"$status"; then
elif grep -q "404" <<<"${status}"; then
return 1
fi
@@ -1671,7 +1757,7 @@ get_available_branches() {
# Get reachable remote branches, but store STDERR as STDOUT variable
output=$({ git ls-remote --heads --quiet | cut -d'/' -f3- -; } 2>&1)
# echo status for calling function to capture
echo "$output"
echo "${output}"
return
}
@@ -1704,9 +1790,9 @@ checkout_pull_branch() {
oldbranch="$(git symbolic-ref HEAD)"
str="Switching to branch: '${branch}' from '${oldbranch}'"
printf " %b %s" "${INFO}" "$str"
printf " %b %s" "${INFO}" "${str}"
git checkout "${branch}" --quiet || return 1
printf "%b %b %s\\n" "${OVER}" "${TICK}" "$str"
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
# Data in the repositories is public anyway so we can make it readable by everyone (+r to keep executable permission if already set by git)
chmod -R a+rX "${directory}"
@@ -1913,7 +1999,7 @@ get_binary_name() {
l_binary="pihole-FTL-riscv64"
else
# Something else - we try to use 32bit executable and warn the user
if [[ ! "${machine}" == "i686" ]]; then
if [[ "${machine}" != "i686" ]]; then
printf "%b %b %s...\\n" "${OVER}" "${CROSS}" "${str}"
printf " %b %bNot able to detect architecture (unknown: %s), trying x86 (32bit) executable%b\\n" "${INFO}" "${COL_RED}" "${machine}" "${COL_NC}"
printf " %b Contact Pi-hole Support if you experience issues (e.g: FTL not running)\\n" "${INFO}"
@@ -1947,14 +2033,14 @@ FTLcheckUpdate() {
local remoteSha1
local localSha1
if [[ ! "${ftlBranch}" == "master" ]]; then
if [[ "${ftlBranch}" != "master" ]]; then
# This is not the master branch
local path
path="${ftlBranch}/${binary}"
# Check whether or not the binary for this FTL branch actually exists. If not, then there is no update!
local status
if ! check_download_exists "$path"; then
if ! check_download_exists "${path}"; then
status=$?
if [ "${status}" -eq 1 ]; then
printf " %b Branch \"%s\" is not available.\\n" "${INFO}" "${ftlBranch}"
@@ -2057,11 +2143,11 @@ make_temporary_log() {
TEMPLOG=$(mktemp /tmp/pihole_temp.XXXXXX)
# Open handle 3 for templog
# https://stackoverflow.com/questions/18460186/writing-outputs-to-log-file-and-console
exec 3>"$TEMPLOG"
exec 3>"${TEMPLOG}"
# Delete templog, but allow for addressing via file handle
# This lets us write to the log without having a temporary file on the drive, which
# is meant to be a security measure so there is not a lingering file on the drive during the install process
rm "$TEMPLOG"
rm "${TEMPLOG}"
}
copy_to_install_log() {
@@ -2351,7 +2437,7 @@ main() {
if [ -n "${PIHOLE_DNS_1}" ]; then
local string="\"${PIHOLE_DNS_1}\""
[ -n "${PIHOLE_DNS_2}" ] && string+=", \"${PIHOLE_DNS_2}\""
setFTLConfigValue "dns.upstreams" "[ $string ]"
setFTLConfigValue "dns.upstreams" "[ ${string} ]"
fi
if [ -n "${QUERY_LOGGING}" ]; then
@@ -2402,7 +2488,7 @@ main() {
\\n\\nIPv4: ${IPV4_ADDRESS%/*}\
\\nIPv6: ${IPV6_ADDRESS:-"Not Configured"}\
\\nIf you have not done so already, the above IP should be set to static.\
\\nView the web interface at http://pi.hole/admin:${WEBPORT} or http://${IPV4_ADDRESS%/*}:${WEBPORT}/admin\\n\\nYour Admin Webpage login password is ${pw}\
\\nView the web interface at http://pi.hole:${WEBPORT}/admin or http://${IPV4_ADDRESS%/*}:${WEBPORT}/admin\\n\\nYour Admin Webpage login password is ${pw}\
\\n
\\n
\\nTo allow your user to use all CLI functions without authentication,\

View File

@@ -12,9 +12,7 @@
source "/opt/pihole/COL_TABLE"
# shellcheck source="./advanced/Scripts/utils.sh"
source "/opt/pihole/utils.sh"
ADMIN_INTERFACE_DIR=$(getFTLConfigValue "webserver.paths.webroot")$(getFTLConfigValue "webserver.paths.webhome")
readonly ADMIN_INTERFACE_DIR
# getFTLConfigValue() from utils.sh
while true; do
read -rp " ${QST} Are you sure you would like to remove ${COL_BOLD}Pi-hole${COL_NC}? [y/N] " answer
@@ -29,125 +27,179 @@ str="Root user check"
if [[ ${EUID} -eq 0 ]]; then
echo -e " ${TICK} ${str}"
else
# Check if sudo is actually installed
# If it isn't, exit because the uninstall can not complete
if [ -x "$(command -v sudo)" ]; then
export SUDO="sudo"
else
echo -e " ${CROSS} ${str}
Script called with non-root privileges
The Pi-hole requires elevated privileges to uninstall"
exit 1
fi
echo -e " ${CROSS} ${str}
Script called with non-root privileges
The Pi-hole requires elevated privileges to uninstall"
exit 1
fi
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
# Get paths for admin interface, log files and database files,
# to allow deletion where user has specified a non-default location
ADMIN_INTERFACE_DIR=$(getFTLConfigValue "webserver.paths.webroot")$(getFTLConfigValue "webserver.paths.webhome")
FTL_LOG=$(getFTLConfigValue "files.log.ftl")
DNSMASQ_LOG=$(getFTLConfigValue "files.log.dnsmasq")
WEBSERVER_LOG=$(getFTLConfigValue "files.log.webserver")
PIHOLE_DB=$(getFTLConfigValue "files.database")
GRAVITY_DB=$(getFTLConfigValue "files.gravity")
MACVENDOR_DB=$(getFTLConfigValue "files.macvendor")
PI_HOLE_LOCAL_REPO="/etc/.pihole"
# Setting SKIP_INSTALL="true" to source the installer functions without running them
SKIP_INSTALL="true"
# shellcheck source="./automated install/basic-install.sh"
source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
# package_manager_detect() sourced from basic-install.sh
package_manager_detect
source "${PI_HOLE_LOCAL_REPO}/automated install/basic-install.sh"
# Functions and Variables sources from basic-install:
# package_manager_detect(), disable_service(), stop_service(),
# restart service() and is_command()
# PI_HOLE_CONFIG_DIR PI_HOLE_INSTALL_DIR PI_HOLE_LOCAL_REPO
removeMetaPackage() {
# Purge Pi-hole meta package
echo ""
echo -ne " ${INFO} Removing Pi-hole meta package...";
eval "${SUDO}" "${PKG_REMOVE}" "pihole-meta" &> /dev/null;
eval "${PKG_REMOVE}" "pihole-meta" &> /dev/null;
echo -e "${OVER} ${INFO} Removed Pi-hole meta package";
}
removePiholeFiles() {
removeWebInterface() {
# Remove the web interface of Pi-hole
echo -ne " ${INFO} Removing Web Interface..."
${SUDO} rm -rf "${ADMIN_INTERFACE_DIR}" &> /dev/null
rm -rf "${ADMIN_INTERFACE_DIR:-/var/www/html/admin/}" &> /dev/null
echo -e "${OVER} ${TICK} Removed Web Interface"
}
# Attempt to preserve backwards compatibility with older versions
# to guarantee no additional changes were made to /etc/crontab after
# the installation of pihole, /etc/crontab.pihole should be permanently
# preserved.
if [[ -f /etc/crontab.orig ]]; then
${SUDO} mv /etc/crontab /etc/crontab.pihole
${SUDO} mv /etc/crontab.orig /etc/crontab
${SUDO} service cron restart
echo -e " ${TICK} Restored the default system cron"
fi
removeFTL() {
# Remove FTL and stop any running FTL service
if is_command "pihole-FTL"; then
# service stop & disable from basic_install.sh
stop_service pihole-FTL
disable_service pihole-FTL
# Attempt to preserve backwards compatibility with older versions
if [[ -f /etc/cron.d/pihole ]];then
${SUDO} rm -f /etc/cron.d/pihole &> /dev/null
echo -e " ${TICK} Removed /etc/cron.d/pihole"
fi
${SUDO} rm -rf /var/log/*pihole* &> /dev/null
${SUDO} rm -rf /var/log/pihole/*pihole* &> /dev/null
${SUDO} rm -rf /etc/pihole/ &> /dev/null
${SUDO} rm -rf /etc/.pihole/ &> /dev/null
${SUDO} rm -rf /opt/pihole/ &> /dev/null
${SUDO} rm -f /usr/local/bin/pihole &> /dev/null
${SUDO} rm -f /etc/bash_completion.d/pihole &> /dev/null
${SUDO} rm -f /etc/sudoers.d/pihole &> /dev/null
echo -e " ${TICK} Removed config files"
# Restore Resolved
if [[ -e /etc/systemd/resolved.conf.orig ]] || [[ -e /etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf ]]; then
${SUDO} cp -p /etc/systemd/resolved.conf.orig /etc/systemd/resolved.conf &> /dev/null || true
${SUDO} rm -f /etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf
systemctl reload-or-restart systemd-resolved
fi
# Remove FTL
if command -v pihole-FTL &> /dev/null; then
echo -ne " ${INFO} Removing pihole-FTL..."
if [[ -x "$(command -v systemctl)" ]]; then
systemctl stop pihole-FTL
else
service pihole-FTL stop
fi
${SUDO} rm -f /etc/systemd/system/pihole-FTL.service
rm -f /etc/systemd/system/pihole-FTL.service &> /dev/null
if [[ -d '/etc/systemd/system/pihole-FTL.service.d' ]]; then
read -rp " ${QST} FTL service override directory /etc/systemd/system/pihole-FTL.service.d detected. Do you wish to remove this from your system? [y/N] " answer
case $answer in
[yY]*)
echo -ne " ${INFO} Removing /etc/systemd/system/pihole-FTL.service.d..."
${SUDO} rm -R /etc/systemd/system/pihole-FTL.service.d
rm -R /etc/systemd/system/pihole-FTL.service.d &> /dev/null
echo -e "${OVER} ${INFO} Removed /etc/systemd/system/pihole-FTL.service.d"
;;
*) echo -e " ${INFO} Leaving /etc/systemd/system/pihole-FTL.service.d in place.";;
esac
fi
${SUDO} rm -f /etc/init.d/pihole-FTL
${SUDO} rm -f /usr/bin/pihole-FTL
rm -f /etc/init.d/pihole-FTL &> /dev/null
rm -f /usr/bin/pihole-FTL &> /dev/null
echo -e "${OVER} ${TICK} Removed pihole-FTL"
# Force systemd reload after service files are removed
if is_command "systemctl"; then
echo -ne " ${INFO} Restarting systemd..."
systemctl daemon-reload
echo -e "${OVER} ${TICK} Restarted systemd..."
fi
fi
}
removeCronFiles() {
# Attempt to preserve backwards compatibility with older versions
# to guarantee no additional changes were made to /etc/crontab after
# the installation of pihole, /etc/crontab.pihole should be permanently
# preserved.
if [[ -f /etc/crontab.orig ]]; then
mv /etc/crontab /etc/crontab.pihole
mv /etc/crontab.orig /etc/crontab
restart_service cron
echo -e " ${TICK} Restored the default system cron"
echo -e " ${INFO} A backup of the most recent crontab is saved at /etc/crontab.pihole"
fi
# If the pihole manpage exists, then delete and rebuild man-db
# Attempt to preserve backwards compatibility with older versions
if [[ -f /etc/cron.d/pihole ]];then
rm -f /etc/cron.d/pihole &> /dev/null
echo -e " ${TICK} Removed /etc/cron.d/pihole"
fi
}
removePiholeFiles() {
# Remove databases (including user specified non-default paths)
rm -f "${PIHOLE_DB:-/etc/pihole/pihole-FTL.db}" &> /dev/null
rm -f "${GRAVITY_DB:-/etc/pihole/gravity.db}" &> /dev/null
rm -f "${MACVENDOR_DB:-/etc/pihole/macvendor.db}" &> /dev/null
# Remove pihole config, repo and local files
rm -rf "${PI_HOLE_CONFIG_DIR:-/etc/pihole}" &> /dev/null
rm -rf "${PI_HOLE_LOCAL_REPO:-/etc/.pihole}" &> /dev/null
rm -rf "${PI_HOLE_INSTALL_DIR:-/opt/pihole}" &> /dev/null
# Remove log files (including user specified non-default paths)
# and rotated logs
# Explicitly escape spaces, in case of trailing space in path before wildcard
rm -f "$(printf '%q' "${FTL_LOG:-/var/log/pihole/FTL.log}")*" &> /dev/null
rm -f "$(printf '%q' "${DNSMASQ_LOG:-/var/log/pihole/pihole.log}")*" &> /dev/null
rm -f "$(printf '%q' "${WEBSERVER_LOG:-/var/log/pihole/webserver.log}")*" &> /dev/null
# remove any remnant log-files from old versions
rm -rf /var/log/*pihole* &> /dev/null
# remove log directory
rm -rf /var/log/pihole &> /dev/null
# remove the pihole command
rm -f /usr/local/bin/pihole &> /dev/null
# remove Pi-hole's bash completion
rm -f /etc/bash_completion.d/pihole &> /dev/null
rm -f /etc/bash_completion.d/pihole-FTL &> /dev/null
# Remove pihole from sudoers for compatibility with old versions
rm -f /etc/sudoers.d/pihole &> /dev/null
echo -e " ${TICK} Removed config files"
}
removeManPage() {
# If the pihole manpage exists, then delete
if [[ -f /usr/local/share/man/man8/pihole.8 ]]; then
${SUDO} rm -f /usr/local/share/man/man8/pihole.8 /usr/local/share/man/man8/pihole-FTL.8 /usr/local/share/man/man5/pihole-FTL.conf.5
${SUDO} mandb -q &>/dev/null
rm -f /usr/local/share/man/man8/pihole.8 /usr/local/share/man/man8/pihole-FTL.8 /usr/local/share/man/man5/pihole-FTL.conf.5
# Rebuild man-db if present
if is_command "mandb"; then
mandb -q &>/dev/null
fi
echo -e " ${TICK} Removed pihole man page"
fi
}
removeUser() {
# If the pihole user exists, then remove
if id "pihole" &> /dev/null; then
if ${SUDO} userdel -r pihole 2> /dev/null; then
if userdel -r pihole 2> /dev/null; then
echo -e " ${TICK} Removed 'pihole' user"
else
echo -e " ${CROSS} Unable to remove 'pihole' user"
fi
fi
# If the pihole group exists, then remove
if getent group "pihole" &> /dev/null; then
if ${SUDO} groupdel pihole 2> /dev/null; then
if groupdel pihole 2> /dev/null; then
echo -e " ${TICK} Removed 'pihole' group"
else
echo -e " ${CROSS} Unable to remove 'pihole' group"
fi
fi
}
restoreResolved() {
# Restore Resolved from saved configuration, if present
if [[ -e /etc/systemd/resolved.conf.orig ]] || [[ -e /etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf ]]; then
cp -p /etc/systemd/resolved.conf.orig /etc/systemd/resolved.conf &> /dev/null || true
rm -f /etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf &> /dev/null
systemctl reload-or-restart systemd-resolved
fi
}
completionMessage() {
echo -e "\\n We're sorry to see you go, but thanks for checking out Pi-hole!
If you need help, reach out to us on GitHub, Discourse, Reddit or Twitter
Reinstall at any time: ${COL_BOLD}curl -sSL https://install.pi-hole.net | bash${COL_NC}
@@ -158,5 +210,17 @@ removePiholeFiles() {
}
######### SCRIPT ###########
# The ordering here allows clean uninstallation with nothing
# removed before anything that depends upon it.
# eg removeFTL relies on scripts removed by removePiholeFiles
# removeUser relies on commands removed by removeMetaPackage
package_manager_detect
removeWebInterface
removeCronFiles
restoreResolved
removeManPage
removeFTL
removeUser
removeMetaPackage
removePiholeFiles
completionMessage

View File

@@ -118,9 +118,12 @@ gravity_swap_databases() {
# Swap databases and remove or conditionally rename old database
# Number of available blocks on disk
availableBlocks=$(stat -f --format "%a" "${gravityDIR}")
# Busybox Compat: `stat` long flags unsupported
# -f flag is short form of --file-system.
# -c flag is short form of --format.
availableBlocks=$(stat -f -c "%a" "${gravityDIR}")
# Number of blocks, used by gravity.db
gravityBlocks=$(stat --format "%b" "${gravityDBfile}")
gravityBlocks=$(stat -c "%b" "${gravityDBfile}")
# Only keep the old database if available disk space is at least twice the size of the existing gravity.db.
# Better be safe than sorry...
oldAvail=false
@@ -608,7 +611,7 @@ compareLists() {
# Download specified URL and perform checks on HTTP status and file content
gravity_DownloadBlocklistFromUrl() {
local url="${1}" adlistID="${2}" saveLocation="${3}" compression="${4}" gravity_type="${5}" domain="${6}"
local listCurlBuffer str httpCode success="" ip customUpstreamResolver=""
local listCurlBuffer str curlJson httpCode curlErrorMsg="" curlExitCode="" success="" ip customUpstreamResolver=""
local file_path permissions ip_addr port blocked=false download=true
# modifiedOptions is an array to store all the options used to check if the adlist has been changed upstream
local modifiedOptions=()
@@ -752,9 +755,14 @@ gravity_DownloadBlocklistFromUrl() {
fi
if [[ "${download}" == true ]]; then
httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression:+${compression}} ${customUpstreamResolver:+${customUpstreamResolver}} "${modifiedOptions[@]}" -w "%{http_code}" "${url}" -o "${listCurlBuffer}" 2>/dev/null)
curlJson=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression:+${compression}} ${customUpstreamResolver:+${customUpstreamResolver}} "${modifiedOptions[@]}" -w "%{json}" "${url}" -o "${listCurlBuffer}")
fi
# Retrieve the HTTP code, exit code and error message returned by curl command
httpCode=$(echo "${curlJson}" | jq '.http_code')
curlErrorMsg=$(echo "${curlJson}" | jq '.errormsg')
curlExitCode=$(echo "${curlJson}" | jq '.exitcode')
case $url in
# Did we "download" a local file?
"file"*)
@@ -777,7 +785,6 @@ gravity_DownloadBlocklistFromUrl() {
echo -e "${OVER} ${TICK} ${str} No changes detected"
success=true
;;
"000") echo -e "${OVER} ${CROSS} ${str} Connection Refused" ;;
"403") echo -e "${OVER} ${CROSS} ${str} Forbidden" ;;
"404") echo -e "${OVER} ${CROSS} ${str} Not found" ;;
"408") echo -e "${OVER} ${CROSS} ${str} Time-out" ;;
@@ -786,7 +793,7 @@ gravity_DownloadBlocklistFromUrl() {
"504") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Gateway)" ;;
"521") echo -e "${OVER} ${CROSS} ${str} Web Server Is Down (Cloudflare)" ;;
"522") echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Cloudflare)" ;;
*) echo -e "${OVER} ${CROSS} ${str} ${url} (${httpCode})" ;;
*) echo -e "${OVER} ${CROSS} ${str} Failure (exit_code=${COL_RED}${curlExitCode}${COL_NC} Msg: ${COL_CYAN}${curlErrorMsg}${COL_NC})" ;;
esac
;;
esac
@@ -851,7 +858,7 @@ gravity_Table_Count() {
fi
}
# Output count of blacklisted domains and regex filters
# Output count of denied and allowed domains and regex filters
gravity_ShowCount() {
# Here we use the table "gravity" instead of the view "vw_gravity" for speed.
# It's safe to replace it here, because right after a gravity run both will show the exactly same number of domains.

View File

@@ -268,7 +268,7 @@ Allow-/denylist manipulation
\fBpihole --regex "ad.*\\.example\\.com$"\fR
.br
Adds "ad.*\\.example\\.com$" to the regex blacklist.
Adds "ad.*\\.example\\.com$" to the regex denylist.
Would block all subdomains of example.com which start with "ad"
.br

View File

@@ -0,0 +1,18 @@
FROM alpine:3.21
ENV GITDIR=/etc/.pihole
ENV SCRIPTDIR=/opt/pihole
RUN sed -i 's/#\(.*\/community\)/\1/' /etc/apk/repositories
RUN apk --no-cache add bash coreutils curl git jq openrc shadow
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
ADD . $GITDIR
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $GITDIR/advanced/Scripts/COL_TABLE $SCRIPTDIR/
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV SKIP_INSTALL=true
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -0,0 +1,18 @@
FROM alpine:3.22
ENV GITDIR=/etc/.pihole
ENV SCRIPTDIR=/opt/pihole
RUN sed -i 's/#\(.*\/community\)/\1/' /etc/apk/repositories
RUN apk --no-cache add bash coreutils curl git jq openrc shadow
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
ADD . $GITDIR
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $GITDIR/advanced/Scripts/COL_TABLE $SCRIPTDIR/
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV SKIP_INSTALL=true
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -0,0 +1,16 @@
FROM buildpack-deps:trixie-scm
ENV GITDIR=/etc/.pihole
ENV SCRIPTDIR=/opt/pihole
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
ADD . $GITDIR
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $GITDIR/advanced/Scripts/COL_TABLE $SCRIPTDIR/
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV SKIP_INSTALL=true
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -1,6 +1,6 @@
pyyaml == 6.0.2
pytest == 8.4.1
pyyaml == 6.0.3
pytest == 8.4.2
pytest-xdist == 3.8.0
pytest-testinfra == 10.2.2
tox == 4.28.4
tox == 4.31.0
pytest-clarity == 1.0.1

View File

@@ -22,6 +22,7 @@ def test_supported_package_manager(host):
# break supported package managers
host.run("rm -rf /usr/bin/apt-get")
host.run("rm -rf /usr/bin/rpm")
host.run("rm -rf /sbin/apk")
package_manager_detect = host.run(
"""
source /opt/pihole/basic-install.sh
@@ -77,10 +78,21 @@ def test_installPihole_fresh_install_readableFiles(host):
},
host,
)
mock_command_2(
"rc-service",
{
"rc-service pihole-FTL enable": ("", "0"),
"rc-service pihole-FTL restart": ("", "0"),
"rc-service pihole-FTL start": ("", "0"),
"*": ('echo "rc-service call with $@"', "0"),
},
host,
)
# try to install man
host.run("command -v apt-get > /dev/null && apt-get install -qq man")
host.run("command -v dnf > /dev/null && dnf install -y man")
host.run("command -v yum > /dev/null && yum install -y man")
host.run("command -v apk > /dev/null && apk add mandoc man-pages")
# Workaround to get FTLv6 installed until it reaches master branch
host.run('echo "' + FTL_BRANCH + '" > /etc/pihole/ftlbranch')
install = host.run(
@@ -103,7 +115,7 @@ def test_installPihole_fresh_install_readableFiles(host):
maninstalled = False
piholeuser = "pihole"
exit_status_success = 0
test_cmd = 'su --shell /bin/bash --command "test -{0} {1}" -p {2}'
test_cmd = 'su -s /bin/bash -c "test -{0} {1}" -p {2}'
# check files in /etc/pihole for read, write and execute permission
check_etc = test_cmd.format("r", "/etc/pihole", piholeuser)
actual_rc = host.run(check_etc).rc

10
test/tox.alpine_3_21.ini Normal file
View File

@@ -0,0 +1,10 @@
[tox]
envlist = py3
[testenv:py3]
allowlist_externals = docker
deps = -rrequirements.txt
setenv =
COLUMNS=120
commands = docker buildx build --load --progress plain -f _alpine_3_21.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py

10
test/tox.alpine_3_22.ini Normal file
View File

@@ -0,0 +1,10 @@
[tox]
envlist = py3
[testenv:py3]
allowlist_externals = docker
deps = -rrequirements.txt
setenv =
COLUMNS=120
commands = docker buildx build --load --progress plain -f _alpine_3_22.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py

10
test/tox.debian_13.ini Normal file
View File

@@ -0,0 +1,10 @@
[tox]
envlist = py3
[testenv:py3]
allowlist_externals = docker
deps = -rrequirements.txt
setenv =
COLUMNS=120
commands = docker buildx build --load --progress plain -f _debian_13.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py