Compare commits
401 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60b6a1016c | ||
|
|
1fa5cb84db | ||
|
|
71357ecae7 | ||
|
|
0385b1d076 | ||
|
|
f52b2b9863 | ||
|
|
bef5d85e6b | ||
|
|
afa688e3a0 | ||
|
|
f5885c8f64 | ||
|
|
edf0060acf | ||
|
|
3f4e2105b3 | ||
|
|
c3d1f366ec | ||
|
|
4955c52af7 | ||
|
|
d6a018a3f8 | ||
|
|
fef2861eae | ||
|
|
7fbc7d458b | ||
|
|
c46a06b522 | ||
|
|
3f6e41e8f4 | ||
|
|
55f72ac925 | ||
|
|
047eac6d9c | ||
|
|
1f241a3d45 | ||
|
|
f035687fca | ||
|
|
843f57399c | ||
|
|
cdc1c1ace1 | ||
|
|
ff72650b8d | ||
|
|
9084b170cb | ||
|
|
fb831b5f48 | ||
|
|
2878c1ba84 | ||
|
|
9b68fa0b27 | ||
|
|
a7ed968ee2 | ||
|
|
924f8b8844 | ||
|
|
1c6919cf07 | ||
|
|
996234ad66 | ||
|
|
272ca8c55d | ||
|
|
9fc01263e6 | ||
|
|
7747cd2232 | ||
|
|
98c7d877ec | ||
|
|
7e240251d5 | ||
|
|
30661fedcb | ||
|
|
8495565a6f | ||
|
|
cefbfdf2a4 | ||
|
|
91dabc574d | ||
|
|
80091232a7 | ||
|
|
924de1d9ed | ||
|
|
60a7c50120 | ||
|
|
a01d31e25d | ||
|
|
1eb4ad8238 | ||
|
|
5490625d8d | ||
|
|
5389ef1a70 | ||
|
|
198ca65f7d | ||
|
|
7bc1126978 | ||
|
|
7a66083e68 | ||
|
|
17fffa4e49 | ||
|
|
3fd7b4ee24 | ||
|
|
306df56203 | ||
|
|
117c15319d | ||
|
|
b8419ba3c5 | ||
|
|
8347de1cc6 | ||
|
|
8e481e27da | ||
|
|
7d3f354dd7 | ||
|
|
eb0bd026d7 | ||
|
|
34a261e522 | ||
|
|
b0fa3795e9 | ||
|
|
364537b324 | ||
|
|
b2c73f8325 | ||
|
|
6a45c6a8e0 | ||
|
|
c1335c6852 | ||
|
|
6c302c9bc8 | ||
|
|
fc67de8c19 | ||
|
|
494734bf27 | ||
|
|
11679a5188 | ||
|
|
aa9b4530c8 | ||
|
|
bea63f9d2d | ||
|
|
de5e6e4163 | ||
|
|
350c9e02ea | ||
|
|
f59610081e | ||
|
|
50d67dce73 | ||
|
|
43ba31f402 | ||
|
|
3ae72114c7 | ||
|
|
783f9e5569 | ||
|
|
23f2db01bb | ||
|
|
82b60b09d4 | ||
|
|
5bdb089b7f | ||
|
|
c92826c152 | ||
|
|
85e7fc5a0e | ||
|
|
10fe85933b | ||
|
|
412079a798 | ||
|
|
f9b29cfb62 | ||
|
|
73733308ba | ||
|
|
614554f26f | ||
|
|
8d91ca874b | ||
|
|
b075e25ab9 | ||
|
|
eaded9fdb1 | ||
|
|
19d50b9669 | ||
|
|
8e5467de70 | ||
|
|
fe1618d697 | ||
|
|
a3e610dbf2 | ||
|
|
b8c3f6d999 | ||
|
|
e6ae2e98cc | ||
|
|
654e111038 | ||
|
|
cd638b102f | ||
|
|
b74c6d5120 | ||
|
|
fd4e8766e4 | ||
|
|
c95d34389b | ||
|
|
83afff953f | ||
|
|
b8ffd2700c | ||
|
|
9bcb323568 | ||
|
|
e9e0aa37f4 | ||
|
|
0df06dc2fb | ||
|
|
53d09417dd | ||
|
|
eed4b70512 | ||
|
|
8fbad01d45 | ||
|
|
1a9dbec83c | ||
|
|
5985d506f1 | ||
|
|
fc706b6cbb | ||
|
|
7eeedf1b5f | ||
|
|
364fd38996 | ||
|
|
b412e88b02 | ||
|
|
11725a0999 | ||
|
|
d065afdbb1 | ||
|
|
c36d0257ec | ||
|
|
87a612f884 | ||
|
|
dd3a7a4edb | ||
|
|
d10d59303e | ||
|
|
b9cf2d9959 | ||
|
|
aaf828117d | ||
|
|
9c4e74ffa7 | ||
|
|
2a0f720153 | ||
|
|
cc17fe18a9 | ||
|
|
61ff5b2c76 | ||
|
|
56eae4afbe | ||
|
|
66bfa606a7 | ||
|
|
32fb2e69ff | ||
|
|
c71460e4b6 | ||
|
|
d885e92674 | ||
|
|
9d4a69c1d0 | ||
|
|
0656ceb149 | ||
|
|
95b12bad34 | ||
|
|
fa116389c2 | ||
|
|
8ca5788561 | ||
|
|
1dc33129e5 | ||
|
|
c96463bda2 | ||
|
|
edbaf6d697 | ||
|
|
58275ecd13 | ||
|
|
c6d1137eb0 | ||
|
|
fb032ea6e7 | ||
|
|
536b3497c9 | ||
|
|
8f09a1d837 | ||
|
|
c255082ef5 | ||
|
|
76b7453f90 | ||
|
|
66ed7c9ea3 | ||
|
|
ac2f13adef | ||
|
|
6b919f3a2e | ||
|
|
4d21bae669 | ||
|
|
7ea0bbb85c | ||
|
|
3ddec99f4a | ||
|
|
e1f12668fa | ||
|
|
686da5a948 | ||
|
|
8a2829de87 | ||
|
|
3a592e56ba | ||
|
|
3c91b6558d | ||
|
|
b9a6970bfd | ||
|
|
20f8c6af3c | ||
|
|
c35ed68051 | ||
|
|
75a32d22a3 | ||
|
|
71e262c37f | ||
|
|
04b909c837 | ||
|
|
309ee78903 | ||
|
|
d6f5552ccf | ||
|
|
67a973a17d | ||
|
|
0b60601f86 | ||
|
|
0b5da9f0da | ||
|
|
0589641bf0 | ||
|
|
ddf972cede | ||
|
|
73de49323c | ||
|
|
16385af3ef | ||
|
|
6cb0be82ca | ||
|
|
2dd31ce6ee | ||
|
|
31a9e18997 | ||
|
|
821c7dc190 | ||
|
|
eedd93d782 | ||
|
|
c5faf3d174 | ||
|
|
1f3f849106 | ||
|
|
ca74152d1d | ||
|
|
4fd0f15d90 | ||
|
|
b9f19fc357 | ||
|
|
2380359270 | ||
|
|
d75adb49f4 | ||
|
|
90da155053 | ||
|
|
2a61a03bdf | ||
|
|
a4bdf2454b | ||
|
|
4b503a080b | ||
|
|
46fe37b4da | ||
|
|
d6275cdd7c | ||
|
|
45cab12392 | ||
|
|
5ecdfb53c2 | ||
|
|
d86b325dfe | ||
|
|
c65ea9c47c | ||
|
|
741717aa38 | ||
|
|
2d13cd2f1d | ||
|
|
788e7cc777 | ||
|
|
0ac89ac2e3 | ||
|
|
e5ea361b53 | ||
|
|
df0155abe1 | ||
|
|
ca00ffa101 | ||
|
|
3ad8965959 | ||
|
|
460f83580e | ||
|
|
c7ad7113d7 | ||
|
|
0a6ebadb52 | ||
|
|
b9e401aaa3 | ||
|
|
18ab94135f | ||
|
|
be0efa2332 | ||
|
|
9bde5de601 | ||
|
|
db42ed1e4f | ||
|
|
262ffe458b | ||
|
|
e59f5db145 | ||
|
|
362c604744 | ||
|
|
68a03cc877 | ||
|
|
671da760d3 | ||
|
|
3c3d913934 | ||
|
|
50be36400c | ||
|
|
5f9523afa6 | ||
|
|
81a31b9e7b | ||
|
|
d0affcb376 | ||
|
|
9939cf1d77 | ||
|
|
ce7f926e92 | ||
|
|
6b4f77bdfe | ||
|
|
267792aa1e | ||
|
|
9331cbff4b | ||
|
|
d30a5f1b95 | ||
|
|
d6e25403ee | ||
|
|
79f4a7cef0 | ||
|
|
9ed3ede0d9 | ||
|
|
771b7cfcc7 | ||
|
|
7bb86e4118 | ||
|
|
c992fd48b0 | ||
|
|
afc8241c2c | ||
|
|
6cae37e720 | ||
|
|
d604aec9f1 | ||
|
|
bb4698429f | ||
|
|
634e3b0e46 | ||
|
|
21c7c8a008 | ||
|
|
9048429bbb | ||
|
|
9c33fcb32a | ||
|
|
eb1f2ac01c | ||
|
|
d88e940a57 | ||
|
|
f27f796b34 | ||
|
|
318ee3b7d3 | ||
|
|
f894585a2e | ||
|
|
ac2f63b138 | ||
|
|
be8f25f8b8 | ||
|
|
c85e4227cf | ||
|
|
c9042704d5 | ||
|
|
57f29a2c5d | ||
|
|
142e9f4a1a | ||
|
|
0c65c27e0c | ||
|
|
4a53e56bd2 | ||
|
|
d349a4640f | ||
|
|
dfcdb1a747 | ||
|
|
e05ef73011 | ||
|
|
2c29b25782 | ||
|
|
d87cad76fb | ||
|
|
9e47b61c8f | ||
|
|
4413224a31 | ||
|
|
d882652a85 | ||
|
|
f73b965fcd | ||
|
|
fe598a05f6 | ||
|
|
09977fdfec | ||
|
|
b9ebb05246 | ||
|
|
955e36a955 | ||
|
|
972591fe39 | ||
|
|
14db88d6bb | ||
|
|
64d0621d2b | ||
|
|
5dabdfe354 | ||
|
|
e7c0ca47b4 | ||
|
|
2bb7c05ed1 | ||
|
|
20ad03fe15 | ||
|
|
58231e55df | ||
|
|
12674c0824 | ||
|
|
c59e11a332 | ||
|
|
ec1d4c5500 | ||
|
|
34f45d011d | ||
|
|
539f9d4da0 | ||
|
|
c6342ed84c | ||
|
|
9072a6a7f0 | ||
|
|
3b5d10d087 | ||
|
|
0d5d3a1b22 | ||
|
|
8d2e023ec0 | ||
|
|
4a1473aee9 | ||
|
|
78f9e38425 | ||
|
|
08c7691d1e | ||
|
|
62bf9957dc | ||
|
|
dafc9983f5 | ||
|
|
a44b8e4bfc | ||
|
|
c8e69c6139 | ||
|
|
da8893f477 | ||
|
|
7562376373 | ||
|
|
619cebb62c | ||
|
|
6a2200a8e6 | ||
|
|
661433c115 | ||
|
|
e7e7a817bb | ||
|
|
d245226053 | ||
|
|
a5d10a6256 | ||
|
|
c32761e786 | ||
|
|
095696ec04 | ||
|
|
7971cf0adc | ||
|
|
fc83883934 | ||
|
|
1550f29f06 | ||
|
|
a206980242 | ||
|
|
8c2f56b0e6 | ||
|
|
b4349b41ce | ||
|
|
67f04787d6 | ||
|
|
1ee922d16c | ||
|
|
14ab586603 | ||
|
|
372070ab39 | ||
|
|
4004a93d1a | ||
|
|
c2bb190dce | ||
|
|
b8eae60fcc | ||
|
|
c86ff5d084 | ||
|
|
126da094bd | ||
|
|
f713b14ba0 | ||
|
|
a4e20f79a3 | ||
|
|
6b146ed2d1 | ||
|
|
e0e0baf076 | ||
|
|
95e799ed6e | ||
|
|
202aa25c09 | ||
|
|
06de172952 | ||
|
|
ff5ee29566 | ||
|
|
d393497641 | ||
|
|
0034538794 | ||
|
|
33d2163f19 | ||
|
|
ea26171c18 | ||
|
|
82dfcbcd83 | ||
|
|
233453267e | ||
|
|
f3c27f706f | ||
|
|
983d79b3e6 | ||
|
|
6d8abc2e30 | ||
|
|
38775cffdf | ||
|
|
b13a75a223 | ||
|
|
21026d9414 | ||
|
|
ba74051502 | ||
|
|
cdbe4c9b86 | ||
|
|
ca04c13315 | ||
|
|
3c86af0e59 | ||
|
|
ddaa1bf0d4 | ||
|
|
6b8ba3c15e | ||
|
|
7536c312ee | ||
|
|
a8b6eb9b70 | ||
|
|
67385b7ed4 | ||
|
|
64e61aac4a | ||
|
|
2fd5b944ad | ||
|
|
f91606bb17 | ||
|
|
122bc6b927 | ||
|
|
3491dbfd04 | ||
|
|
871067acd8 | ||
|
|
06cf7afbc2 | ||
|
|
81927334f2 | ||
|
|
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 | ||
|
|
9471c69882 | ||
|
|
79c0b446e1 | ||
|
|
a478f2460b | ||
|
|
2dc599f266 | ||
|
|
d7f7ef9965 | ||
|
|
888e44e53d | ||
|
|
18d28533eb | ||
|
|
56527e5dd9 | ||
|
|
c90d8284ef | ||
|
|
7ab9664255 | ||
|
|
3a22657645 | ||
|
|
4567f264b4 |
31
.github/dependabot.yml
vendored
31
.github/dependabot.yml
vendored
@@ -10,3 +10,34 @@ updates:
|
||||
target-branch: development
|
||||
reviewers:
|
||||
- "pi-hole/core-maintainers"
|
||||
- package-ecosystem: pip
|
||||
directory: "/test"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "10:00"
|
||||
open-pull-requests-limit: 10
|
||||
target-branch: development
|
||||
reviewers:
|
||||
- "pi-hole/core-maintainers"
|
||||
# As above, but for development-v6
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "10:00"
|
||||
open-pull-requests-limit: 10
|
||||
target-branch: development-v6
|
||||
reviewers:
|
||||
- "pi-hole/core-maintainers"
|
||||
- package-ecosystem: pip
|
||||
directory: "/test"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "10:00"
|
||||
open-pull-requests-limit: 10
|
||||
target-branch: development-v6
|
||||
reviewers:
|
||||
- "pi-hole/core-maintainers"
|
||||
|
||||
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.1.0
|
||||
uses: actions/checkout@v4.1.0
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
-
|
||||
name: Initialize CodeQL
|
||||
|
||||
21
.github/workflows/merge-conflict.yml
vendored
Normal file
21
.github/workflows/merge-conflict.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: "Check for merge conflicts"
|
||||
on:
|
||||
# So that PRs touching the same files as the push are updated
|
||||
push:
|
||||
# So that the `dirtyLabel` is removed if conflicts are resolve
|
||||
# We recommend `pull_request_target` so that github secrets are available.
|
||||
# In `pull_request` we wouldn't be able to change labels of fork PRs
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check if PRs are have merge conflicts
|
||||
uses: eps1lon/actions-label-merge-conflict@v2.1.0
|
||||
with:
|
||||
dirtyLabel: "PR: Merge Conflict"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
commentOnDirty: "This pull request has conflicts, please resolve those before we can evaluate the pull request."
|
||||
commentOnClean: "Conflicts have been resolved."
|
||||
30
.github/workflows/stale.yml
vendored
30
.github/workflows/stale.yml
vendored
@@ -4,23 +4,45 @@ on:
|
||||
schedule:
|
||||
- cron: '0 8 * * *'
|
||||
workflow_dispatch:
|
||||
issue_comment:
|
||||
|
||||
env:
|
||||
stale_label: stale
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
stale_action:
|
||||
if: github.event_name != 'issue_comment'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v6.0.1
|
||||
- uses: actions/stale@v8.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 30
|
||||
days-before-close: 5
|
||||
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Please comment or update this issue or it will be closed in 5 days.'
|
||||
stale-issue-label: 'stale'
|
||||
stale-issue-label: '${{ env.stale_label }}'
|
||||
exempt-issue-labels: 'Internal, Fixed in next release, Bug: Confirmed, Documentation Needed'
|
||||
exempt-all-issue-assignees: true
|
||||
operations-per-run: 300
|
||||
close-issue-reason: 'not_planned'
|
||||
|
||||
remove_stale:
|
||||
# trigger "stale" removal immediately when stale issues are commented on
|
||||
# we need to explicitly check that the trigger does not run on comment on a PR as
|
||||
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment-on-issues-only-or-pull-requests-only
|
||||
if: ${{ !github.event.issue.pull_request && github.event_name != 'schedule' }}
|
||||
permissions:
|
||||
contents: read # for actions/checkout
|
||||
issues: write # to edit issues label
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Remove 'stale' label
|
||||
run: gh issue edit ${{ github.event.issue.number }} --remove-label ${{ env.stale_label }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
35
.github/workflows/stale_pr.yml
vendored
Normal file
35
.github/workflows/stale_pr.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Close stale PR
|
||||
# This action will add a `stale` label and close immediately every PR that meets the following conditions:
|
||||
# - it is already marked with "merge conflict" label
|
||||
# - there was no update/comment on the PR in the last 30 days.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v8.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Do not automatically mark PR/issue as stale
|
||||
days-before-stale: -1
|
||||
# Override 'days-before-stale' for PR only
|
||||
days-before-pr-stale: 30
|
||||
# Close PRs immediately, after marking them 'stale'
|
||||
days-before-pr-close: 0
|
||||
# only run the action on merge conflict PR
|
||||
any-of-labels: 'PR: Merge Conflict'
|
||||
exempt-pr-labels: 'internal, never-stale, ON HOLD, WIP'
|
||||
exempt-all-pr-assignees: true
|
||||
operations-per-run: 300
|
||||
stale-pr-message: ''
|
||||
close-pr-message: 'Existing merge conflicts have not been addressed. This PR is considered abandoned.'
|
||||
37
.github/workflows/sync-back-to-dev.yml
vendored
37
.github/workflows/sync-back-to-dev.yml
vendored
@@ -5,23 +5,36 @@ on:
|
||||
branches:
|
||||
- master
|
||||
|
||||
# The section is needed to drop the default write-all permissions for all jobs
|
||||
# that are granted on `push` event. By specifying any permission explicitly
|
||||
# all others are set to none. By using the principle of least privilege the damage a compromised
|
||||
# workflow can do (because of an injection or compromised third party tool or
|
||||
# action) is restricted. Adding labels to issues, commenting
|
||||
# on pull-requests, etc. may need additional permissions:
|
||||
#
|
||||
# Syntax for this section:
|
||||
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
|
||||
#
|
||||
# Reference for how to assign permissions on a job-by-job basis:
|
||||
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
||||
#
|
||||
# Reference for available permissions that we can enable if needed:
|
||||
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
sync-branches:
|
||||
# The job needs to be able to pull the code and create a pull request.
|
||||
permissions:
|
||||
contents: read # for actions/checkout
|
||||
pull-requests: write # to create pull request
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
name: Syncing branches
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Opening pull request
|
||||
id: pull
|
||||
uses: tretuna/sync-branches@1.4.0
|
||||
with:
|
||||
run: gh pr create -B development -H master --title 'Sync master back into development' --body 'Created by Github action' --label 'internal'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
FROM_BRANCH: 'master'
|
||||
TO_BRANCH: 'development'
|
||||
- name: Label the pull request to ignore for release note generation
|
||||
uses: actions-ecosystem/action-add-labels@v1.1.3
|
||||
with:
|
||||
labels: internal
|
||||
repo: ${{ github.repository }}
|
||||
number: ${{ steps.pull.outputs.PULL_REQUEST_NUMBER }}
|
||||
|
||||
15
.github/workflows/test.yml
vendored
15
.github/workflows/test.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4.1.0
|
||||
|
||||
- name: Check scripts in repository are executable
|
||||
run: |
|
||||
@@ -51,23 +51,30 @@ jobs:
|
||||
[
|
||||
debian_10,
|
||||
debian_11,
|
||||
debian_12,
|
||||
ubuntu_20,
|
||||
ubuntu_22,
|
||||
ubuntu_23,
|
||||
centos_8,
|
||||
fedora_35,
|
||||
centos_9,
|
||||
fedora_36,
|
||||
fedora_37,
|
||||
fedora_38,
|
||||
]
|
||||
env:
|
||||
DISTRO: ${{matrix.distro}}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4.1.0
|
||||
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v4.2.0
|
||||
uses: actions/setup-python@v4.7.1
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install wheel
|
||||
run: pip install wheel
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install -r test/requirements.txt
|
||||
|
||||
|
||||
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!**
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -150,7 +150,7 @@ You can read our [Core Feature Breakdown](https://docs.pi-hole.net/core/pihole-c
|
||||
|
||||
### The Web Interface Dashboard
|
||||
|
||||
This [optional dashboard](https://github.com/pi-hole/AdminLTE) allows you to view stats, change settings, and configure your Pi-hole. It's the power of the Command Line Interface, with none of the learning curve!
|
||||
This [optional dashboard](https://github.com/pi-hole/web) allows you to view stats, change settings, and configure your Pi-hole. It's the power of the Command Line Interface, with none of the learning curve!
|
||||
|
||||
Some notable features include:
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ get_sys_stats() {
|
||||
if [[ -n "${ph_ver_raw[0]}" ]]; then
|
||||
ph_core_ver="${ph_ver_raw[0]}"
|
||||
if [[ ${#ph_ver_raw[@]} -eq 2 ]]; then
|
||||
# AdminLTE not installed
|
||||
# web not installed
|
||||
ph_lte_ver="(not installed)"
|
||||
ph_ftl_ver="${ph_ver_raw[1]}"
|
||||
else
|
||||
|
||||
@@ -42,11 +42,6 @@ warning1() {
|
||||
esac
|
||||
}
|
||||
|
||||
updateCheckFunc() {
|
||||
/opt/pihole/updatecheck.sh
|
||||
/opt/pihole/updatecheck.sh x remote
|
||||
}
|
||||
|
||||
checkout() {
|
||||
local corebranches
|
||||
local webbranches
|
||||
@@ -169,8 +164,8 @@ checkout() {
|
||||
exit 1
|
||||
fi
|
||||
checkout_pull_branch "${webInterfaceDir}" "${2}"
|
||||
# Force an update of the updatechecker
|
||||
updateCheckFunc
|
||||
# Update local and remote versions via updatechecker
|
||||
/opt/pihole/updatecheck.sh
|
||||
elif [[ "${1}" == "ftl" ]] ; then
|
||||
local path
|
||||
local oldbranch
|
||||
@@ -185,8 +180,8 @@ checkout() {
|
||||
FTLinstall "${binary}"
|
||||
restart_service pihole-FTL
|
||||
enable_service pihole-FTL
|
||||
# Force an update of the updatechecker
|
||||
updateCheckFunc
|
||||
# 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}"
|
||||
@@ -71,9 +66,10 @@ RUN_DIRECTORY="/run"
|
||||
LOG_DIRECTORY="/var/log/pihole"
|
||||
WEB_SERVER_LOG_DIRECTORY="/var/log/lighttpd"
|
||||
WEB_SERVER_CONFIG_DIRECTORY="/etc/lighttpd"
|
||||
WEB_SERVER_CONFIG_DIRECTORY_FEDORA="${WEB_SERVER_CONFIG_DIRECTORY}/conf.d"
|
||||
WEB_SERVER_CONFIG_DIRECTORY_DEBIAN="${WEB_SERVER_CONFIG_DIRECTORY}/conf-enabled"
|
||||
HTML_DIRECTORY="/var/www/html"
|
||||
WEB_GIT_DIRECTORY="${HTML_DIRECTORY}/admin"
|
||||
#BLOCK_PAGE_DIRECTORY="${HTML_DIRECTORY}/pihole"
|
||||
SHM_DIRECTORY="/dev/shm"
|
||||
ETC="/etc"
|
||||
|
||||
@@ -83,6 +79,8 @@ PIHOLE_CRON_FILE="${CRON_D_DIRECTORY}/pihole"
|
||||
|
||||
WEB_SERVER_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/lighttpd.conf"
|
||||
WEB_SERVER_CUSTOM_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/external.conf"
|
||||
WEB_SERVER_PIHOLE_CONFIG_FILE_DEBIAN="${WEB_SERVER_CONFIG_DIRECTORY_DEBIAN}/15-pihole-admin.conf"
|
||||
WEB_SERVER_PIHOLE_CONFIG_FILE_FEDORA="${WEB_SERVER_CONFIG_DIRECTORY_FEDORA}/pihole-admin.conf"
|
||||
|
||||
PIHOLE_INSTALL_LOG_FILE="${PIHOLE_DIRECTORY}/install.log"
|
||||
PIHOLE_RAW_BLOCKLIST_FILES="${PIHOLE_DIRECTORY}/list.*"
|
||||
@@ -91,6 +89,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.
|
||||
#
|
||||
@@ -145,6 +144,8 @@ PIHOLE_PROCESSES=( "lighttpd" "pihole-FTL" )
|
||||
REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
|
||||
"${WEB_SERVER_CONFIG_FILE}"
|
||||
"${WEB_SERVER_CUSTOM_CONFIG_FILE}"
|
||||
"${WEB_SERVER_PIHOLE_CONFIG_FILE_DEBIAN}"
|
||||
"${WEB_SERVER_PIHOLE_CONFIG_FILE_FEDORA}"
|
||||
"${PIHOLE_INSTALL_LOG_FILE}"
|
||||
"${PIHOLE_RAW_BLOCKLIST_FILES}"
|
||||
"${PIHOLE_LOCAL_HOSTS_FILE}"
|
||||
@@ -162,7 +163,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.
|
||||
|
||||
@@ -228,10 +230,8 @@ initialize_debug() {
|
||||
|
||||
# This is a function for visually displaying the current test that is being run.
|
||||
# Accepts one variable: the name of what is being diagnosed
|
||||
# Colors do not show in the dasboard, but the icons do: [i], [✓], and [✗]
|
||||
echo_current_diagnostic() {
|
||||
# Colors are used for visually distinguishing each test in the output
|
||||
# These colors do not show in the GUI, but the formatting will
|
||||
log_write "\\n${COL_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
|
||||
}
|
||||
|
||||
@@ -240,15 +240,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
|
||||
@@ -261,43 +253,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
|
||||
@@ -331,22 +315,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}')
|
||||
FTL_VERSION=$(pihole-FTL version)
|
||||
FTL_BRANCH=$(pihole-FTL branch)
|
||||
FTL_COMMIT=$(pihole-FTL --hash)
|
||||
|
||||
# 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
|
||||
@@ -355,7 +332,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
|
||||
@@ -421,46 +398,58 @@ os_check() {
|
||||
# Extract dig response
|
||||
response="${cmdResult%%$'\n'*}"
|
||||
|
||||
IFS=" " read -r -a supportedOS < <(echo "${response}" | tr -d '"')
|
||||
for distro_and_versions in "${supportedOS[@]}"
|
||||
do
|
||||
distro_part="${distro_and_versions%%=*}"
|
||||
versions_part="${distro_and_versions##*=}"
|
||||
|
||||
if [[ "${detected_os^^}" =~ ${distro_part^^} ]]; then
|
||||
valid_os=true
|
||||
IFS="," read -r -a supportedVer <<<"${versions_part}"
|
||||
for version in "${supportedVer[@]}"
|
||||
do
|
||||
if [[ "${detected_version}" =~ $version ]]; then
|
||||
valid_version=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
log_write "${INFO} dig return code: ${digReturnCode}"
|
||||
log_write "${INFO} dig response: ${response}"
|
||||
|
||||
if [ "$valid_os" = true ]; then
|
||||
log_write "${TICK} Distro: ${COL_GREEN}${detected_os^}${COL_NC}"
|
||||
|
||||
if [ "$valid_version" = true ]; then
|
||||
log_write "${TICK} Version: ${COL_GREEN}${detected_version}${COL_NC}"
|
||||
else
|
||||
log_write "${CROSS} Version: ${COL_RED}${detected_version}${COL_NC}"
|
||||
log_write "${CROSS} Error: ${COL_RED}${detected_os^} is supported but version ${detected_version} is currently unsupported (${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}"
|
||||
fi
|
||||
if [ "${digReturnCode}" -ne 0 ]; then
|
||||
log_write "${INFO} Distro: ${detected_os^}"
|
||||
log_write "${INFO} Version: ${detected_version}"
|
||||
log_write "${CROSS} dig return code: ${COL_RED}${digReturnCode}${COL_NC}"
|
||||
log_write "${CROSS} dig response: ${response}"
|
||||
log_write "${CROSS} Error: ${COL_RED}dig command failed - Unable to check OS${COL_NC}"
|
||||
else
|
||||
log_write "${CROSS} Distro: ${COL_RED}${detected_os^}${COL_NC}"
|
||||
log_write "${CROSS} Error: ${COL_RED}${detected_os^} is not a supported distro (${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}"
|
||||
IFS=" " read -r -a supportedOS < <(echo "${response}" | tr -d '"')
|
||||
for distro_and_versions in "${supportedOS[@]}"
|
||||
do
|
||||
distro_part="${distro_and_versions%%=*}"
|
||||
versions_part="${distro_and_versions##*=}"
|
||||
|
||||
if [[ "${detected_os^^}" =~ ${distro_part^^} ]]; then
|
||||
valid_os=true
|
||||
IFS="," read -r -a supportedVer <<<"${versions_part}"
|
||||
for version in "${supportedVer[@]}"
|
||||
do
|
||||
if [[ "${detected_version}" =~ $version ]]; then
|
||||
valid_version=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
local finalmsg
|
||||
if [ "$valid_os" = true ]; then
|
||||
log_write "${TICK} Distro: ${COL_GREEN}${detected_os^}${COL_NC}"
|
||||
|
||||
if [ "$valid_version" = true ]; then
|
||||
log_write "${TICK} Version: ${COL_GREEN}${detected_version}${COL_NC}"
|
||||
finalmsg="${TICK} ${COL_GREEN}Distro and version supported${COL_NC}"
|
||||
else
|
||||
log_write "${CROSS} Version: ${COL_RED}${detected_version}${COL_NC}"
|
||||
finalmsg="${CROSS} Error: ${COL_RED}${detected_os^} is supported but version ${detected_version} is currently unsupported ${COL_NC}(${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}"
|
||||
fi
|
||||
else
|
||||
log_write "${CROSS} Distro: ${COL_RED}${detected_os^}${COL_NC}"
|
||||
finalmsg="${CROSS} Error: ${COL_RED}${detected_os^} is not a supported distro ${COL_NC}(${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}"
|
||||
fi
|
||||
|
||||
# Print dig response and the final check result
|
||||
log_write "${TICK} dig return code: ${COL_GREEN}${digReturnCode}${COL_NC}"
|
||||
log_write "${INFO} dig response: ${response}"
|
||||
log_write "${finalmsg}"
|
||||
fi
|
||||
}
|
||||
|
||||
diagnose_operating_system() {
|
||||
# error message in a variable so we can easily modify it later (or re-use it)
|
||||
# error message in a variable so we can easily modify it later (or reuse it)
|
||||
local error_msg="Distribution unknown -- most likely you are on an unsupported platform and may run into issues."
|
||||
# Display the current test that is running
|
||||
echo_current_diagnostic "Operating system"
|
||||
@@ -872,11 +861,15 @@ dig_at() {
|
||||
local record_type="A"
|
||||
fi
|
||||
|
||||
# Find a random blocked url that has not been whitelisted.
|
||||
# Find a random blocked url that has not been whitelisted 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
|
||||
random_url=$(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT domain FROM vw_gravity ORDER BY RANDOM() LIMIT 1")
|
||||
random_url=$(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT domain FROM vw_gravity WHERE domain not like '||%^' ORDER BY RANDOM() LIMIT 1")
|
||||
# Fallback if no non-ABP style domains were found
|
||||
if [ -z "${random_url}" ]; then
|
||||
random_url="flurry.com"
|
||||
fi
|
||||
|
||||
# Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
|
||||
# This better emulates how clients will interact with Pi-hole as opposed to above where Pi-hole is
|
||||
@@ -952,10 +945,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
|
||||
@@ -981,6 +985,20 @@ ftl_full_status(){
|
||||
fi
|
||||
}
|
||||
|
||||
lighttpd_test_configuration(){
|
||||
# let lighttpd test it's own configuration
|
||||
local lighttpd_conf_test
|
||||
echo_current_diagnostic "Lighttpd configuration test"
|
||||
lighttpd_conf_test=$(lighttpd -tt -f /etc/lighttpd/lighttpd.conf)
|
||||
if [ -z "${lighttpd_conf_test}" ]; then
|
||||
# empty output
|
||||
log_write "${TICK} ${COL_GREEN}No error in lighttpd configuration${COL_NC}"
|
||||
else
|
||||
log_write "${CROSS} ${COL_RED}Error in lighttpd configuration${COL_NC}"
|
||||
log_write " ${lighttpd_conf_test}"
|
||||
fi
|
||||
}
|
||||
|
||||
make_array_from_file() {
|
||||
local filename="${1}"
|
||||
# The second argument can put a limit on how many line should be read from the file
|
||||
@@ -1073,10 +1091,13 @@ dir_check() {
|
||||
# check if exists first; if it does,
|
||||
if ls "${filename}" 1> /dev/null 2>&1; then
|
||||
# do nothing
|
||||
:
|
||||
true
|
||||
return
|
||||
else
|
||||
# Otherwise, show an error
|
||||
log_write "${COL_RED}${directory} does not exist.${COL_NC}"
|
||||
false
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1084,6 +1105,19 @@ dir_check() {
|
||||
list_files_in_dir() {
|
||||
# Set the first argument passed to this function as a named variable for better readability
|
||||
local dir_to_parse="${1}"
|
||||
|
||||
# show files and sizes of some directories, don't print the file content (yet)
|
||||
if [[ "${dir_to_parse}" == "${SHM_DIRECTORY}" ]]; then
|
||||
# SHM file - we do not want to see the content, but we want to see the files and their sizes
|
||||
log_write "$(ls -lh "${dir_to_parse}/")"
|
||||
elif [[ "${dir_to_parse}" == "${WEB_SERVER_CONFIG_DIRECTORY_FEDORA}" ]]; then
|
||||
# we want to see all files files in /etc/lighttpd/conf.d
|
||||
log_write "$(ls -lh "${dir_to_parse}/" 2> /dev/null )"
|
||||
elif [[ "${dir_to_parse}" == "${WEB_SERVER_CONFIG_DIRECTORY_DEBIAN}" ]]; then
|
||||
# we want to see all files files in /etc/lighttpd/conf.d
|
||||
log_write "$(ls -lh "${dir_to_parse}/"/ 2> /dev/null )"
|
||||
fi
|
||||
|
||||
# Store the files found in an array
|
||||
mapfile -t files_found < <(ls "${dir_to_parse}")
|
||||
# For each file in the array,
|
||||
@@ -1099,11 +1133,8 @@ list_files_in_dir() {
|
||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_WEB_SERVER_ACCESS_LOG_FILE}" ]] || \
|
||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG_GZIPS}" ]]; then
|
||||
:
|
||||
elif [[ "${dir_to_parse}" == "${SHM_DIRECTORY}" ]]; then
|
||||
# SHM file - we do not want to see the content, but we want to see the files and their sizes
|
||||
log_write "$(ls -lhd "${dir_to_parse}"/"${each_file}")"
|
||||
elif [[ "${dir_to_parse}" == "${DNSMASQ_D_DIRECTORY}" ]]; then
|
||||
# in case of the dnsmasq directory inlcuede all files in the debug output
|
||||
# in case of the dnsmasq directory include all files in the debug output
|
||||
log_write "\\n${COL_GREEN}$(ls -lhd "${dir_to_parse}"/"${each_file}")${COL_NC}"
|
||||
make_array_from_file "${dir_to_parse}/${each_file}"
|
||||
else
|
||||
@@ -1136,9 +1167,10 @@ show_content_of_files_in_dir() {
|
||||
# Set a local variable for better readability
|
||||
local directory="${1}"
|
||||
# Check if the directory exists
|
||||
dir_check "${directory}"
|
||||
# if it does, list the files in it
|
||||
list_files_in_dir "${directory}"
|
||||
if dir_check "${directory}"; then
|
||||
# if it does, list the files in it
|
||||
list_files_in_dir "${directory}"
|
||||
fi
|
||||
}
|
||||
|
||||
show_content_of_pihole_files() {
|
||||
@@ -1146,6 +1178,8 @@ show_content_of_pihole_files() {
|
||||
show_content_of_files_in_dir "${PIHOLE_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${DNSMASQ_D_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY_FEDORA}"
|
||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY_DEBIAN}"
|
||||
show_content_of_files_in_dir "${CRON_D_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${WEB_SERVER_LOG_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${LOG_DIRECTORY}"
|
||||
@@ -1381,49 +1415,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
|
||||
|
||||
@@ -1433,22 +1426,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() {
|
||||
@@ -1522,7 +1503,7 @@ upload_to_tricorder() {
|
||||
# If no token was generated
|
||||
else
|
||||
# Show an error and some help instructions
|
||||
# Skip this if being called from web interface and autmatic mode was not chosen (users opt-out to upload)
|
||||
# Skip this if being called from web interface and automatic mode was not chosen (users opt-out to upload)
|
||||
if [[ "${WEBCALL}" ]] && [[ ! "${AUTOMATED}" ]]; then
|
||||
:
|
||||
else
|
||||
@@ -1553,6 +1534,7 @@ check_name_resolution
|
||||
check_dhcp_servers
|
||||
process_status
|
||||
ftl_full_status
|
||||
lighttpd_test_configuration
|
||||
parse_setup_vars
|
||||
check_x_headers
|
||||
analyze_ftl_db
|
||||
|
||||
@@ -30,33 +30,6 @@ gravityDBfile="${GRAVITYDB}"
|
||||
colfile="/opt/pihole/COL_TABLE"
|
||||
source "${colfile}"
|
||||
|
||||
# Scan an array of files for matching strings
|
||||
scanList(){
|
||||
# Escape full stops
|
||||
local domain="${1}" esc_domain="${1//./\\.}" lists="${2}" list_type="${3:-}"
|
||||
|
||||
# Prevent grep from printing file path
|
||||
cd "$piholeDir" || exit 1
|
||||
|
||||
# Prevent grep -i matching slowly: https://bit.ly/2xFXtUX
|
||||
export LC_CTYPE=C
|
||||
|
||||
# /dev/null forces filename to be printed when only one list has been generated
|
||||
case "${list_type}" in
|
||||
"exact" ) grep -i -E -l "(^|(?<!#)\\s)${esc_domain}($|\\s|#)" ${lists} /dev/null 2>/dev/null;;
|
||||
# Iterate through each regexp and check whether it matches the domainQuery
|
||||
# If it does, print the matching regexp and continue looping
|
||||
# Input 1 - regexps | Input 2 - domainQuery
|
||||
"regex" )
|
||||
for list in ${lists}; do
|
||||
if [[ "${domain}" =~ ${list} ]]; then
|
||||
printf "%b\n" "${list}";
|
||||
fi
|
||||
done;;
|
||||
* ) grep -i "${esc_domain}" ${lists} /dev/null 2>/dev/null;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [[ "${options}" == "-h" ]] || [[ "${options}" == "--help" ]]; then
|
||||
echo "Usage: pihole -q [option] <domain>
|
||||
Example: 'pihole -q -exact domain.com'
|
||||
@@ -77,24 +50,39 @@ fi
|
||||
|
||||
# Strip valid options, leaving only the domain and invalid options
|
||||
# This allows users to place the options before or after the domain
|
||||
options=$(sed -E 's/ ?-(adlists?|all|exact) ?//g' <<< "${options}")
|
||||
options=$(sed -E 's/ ?-(all|exact) ?//g' <<< "${options}")
|
||||
|
||||
# Handle remaining options
|
||||
# If $options contain non ASCII characters, convert to punycode
|
||||
case "${options}" in
|
||||
"" ) str="No domain specified";;
|
||||
*" "* ) str="Unknown query option specified";;
|
||||
*[![:ascii:]]* ) domainQuery=$(idn2 "${options}");;
|
||||
* ) domainQuery="${options}";;
|
||||
*[![:ascii:]]* ) rawDomainQuery=$(idn2 "${options}");;
|
||||
* ) rawDomainQuery="${options}";;
|
||||
esac
|
||||
|
||||
# convert the domain to lowercase
|
||||
domainQuery=$(echo "${rawDomainQuery}" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
if [[ -n "${str:-}" ]]; then
|
||||
echo -e "${str}${COL_NC}\\nTry 'pihole -q --help' for more information."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Scan a domain again a list of RegEX
|
||||
scanRegExList(){
|
||||
local domain="${1}" list="${2}"
|
||||
|
||||
for entry in ${list}; do
|
||||
if [[ "${domain}" =~ ${entry} ]]; then
|
||||
printf "%b\n" "${entry}";
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
scanDatabaseTable() {
|
||||
local domain table list_type querystr result extra
|
||||
local domain table list_type querystr result extra abpquerystr abpfound abpentry searchstr
|
||||
domain="$(printf "%q" "${1}")"
|
||||
table="${2}"
|
||||
list_type="${3:-}"
|
||||
@@ -104,9 +92,34 @@ scanDatabaseTable() {
|
||||
# behavior. The "ESCAPE '\'" clause specifies that an underscore preceded by an '\' should be matched
|
||||
# as a literal underscore character. We pretreat the $domain variable accordingly to escape underscores.
|
||||
if [[ "${table}" == "gravity" ]]; then
|
||||
|
||||
# Are there ABP entries on gravity?
|
||||
# Return 1 if abp_domain=1 or Zero if abp_domain=0 or not set
|
||||
abpquerystr="SELECT EXISTS (SELECT 1 FROM info WHERE property='abp_domains' and value='1')"
|
||||
abpfound="$(pihole-FTL sqlite3 "${gravityDBfile}" "${abpquerystr}")" 2> /dev/null
|
||||
|
||||
# Create search string for ABP entries only if needed
|
||||
if [ "${abpfound}" -eq 1 ]; then
|
||||
abpentry="${domain}"
|
||||
|
||||
searchstr="'||${abpentry}^'"
|
||||
|
||||
# While a dot is found ...
|
||||
while [ "${abpentry}" != "${abpentry/./}" ]
|
||||
do
|
||||
# ... remove text before the dot (including the dot) and append the result to $searchstr
|
||||
abpentry=$(echo "${abpentry}" | cut -f 2- -d '.')
|
||||
searchstr="$searchstr, '||${abpentry}^'"
|
||||
done
|
||||
|
||||
# The final search string will look like:
|
||||
# "domain IN ('||sub2.sub1.domain.com^', '||sub1.domain.com^', '||domain.com^', '||com^') OR"
|
||||
searchstr="domain IN (${searchstr}) OR "
|
||||
fi
|
||||
|
||||
case "${exact}" in
|
||||
"exact" ) querystr="SELECT gravity.domain,adlist.address,adlist.enabled FROM gravity LEFT JOIN adlist ON adlist.id = gravity.adlist_id WHERE domain = '${domain}'";;
|
||||
* ) querystr="SELECT gravity.domain,adlist.address,adlist.enabled FROM gravity LEFT JOIN adlist ON adlist.id = gravity.adlist_id WHERE domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
||||
* ) querystr="SELECT gravity.domain,adlist.address,adlist.enabled FROM gravity LEFT JOIN adlist ON adlist.id = gravity.adlist_id WHERE ${searchstr} domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
||||
esac
|
||||
else
|
||||
case "${exact}" in
|
||||
@@ -116,7 +129,7 @@ scanDatabaseTable() {
|
||||
fi
|
||||
|
||||
# Send prepared query to gravity database
|
||||
result="$(pihole-FTL sqlite3 "${gravityDBfile}" "${querystr}")" 2> /dev/null
|
||||
result="$(pihole-FTL sqlite3 -separator ',' "${gravityDBfile}" "${querystr}")" 2> /dev/null
|
||||
if [[ -z "${result}" ]]; then
|
||||
# Return early when there are no matches in this table
|
||||
return
|
||||
@@ -136,8 +149,8 @@ scanDatabaseTable() {
|
||||
# Loop over results and print them
|
||||
mapfile -t results <<< "${result}"
|
||||
for result in "${results[@]}"; do
|
||||
domain="${result/|*}"
|
||||
if [[ "${result#*|}" == "0" ]]; then
|
||||
domain="${result/,*}"
|
||||
if [[ "${result#*,}" == "0" ]]; then
|
||||
extra=" (disabled)"
|
||||
else
|
||||
extra=""
|
||||
@@ -160,7 +173,7 @@ scanRegexDatabaseTable() {
|
||||
# Split regexps over a new line
|
||||
str_regexList=$(printf '%s\n' "${regexList[@]}")
|
||||
# Check domain against regexps
|
||||
mapfile -t regexMatches < <(scanList "${domain}" "${str_regexList}" "regex")
|
||||
mapfile -t regexMatches < <(scanRegExList "${domain}" "${str_regexList}")
|
||||
# If there were regex matches
|
||||
if [[ "${#regexMatches[@]}" -ne 0 ]]; then
|
||||
# Split matching regexps over a new line
|
||||
@@ -212,10 +225,10 @@ if [[ -n "${exact}" ]]; then
|
||||
fi
|
||||
|
||||
for result in "${results[@]}"; do
|
||||
match="${result/|*/}"
|
||||
extra="${result#*|}"
|
||||
adlistAddress="${extra/|*/}"
|
||||
extra="${extra#*|}"
|
||||
match="${result/,*/}"
|
||||
extra="${result#*,}"
|
||||
adlistAddress="${extra/,*/}"
|
||||
extra="${extra#*,}"
|
||||
if [[ "${extra}" == "0" ]]; then
|
||||
extra=" (disabled)"
|
||||
else
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
# Variables
|
||||
readonly ADMIN_INTERFACE_GIT_URL="https://github.com/pi-hole/AdminLTE.git"
|
||||
readonly ADMIN_INTERFACE_GIT_URL="https://github.com/pi-hole/web.git"
|
||||
readonly ADMIN_INTERFACE_DIR="/var/www/html/admin"
|
||||
readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
|
||||
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
|
||||
@@ -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
|
||||
git describe --tags --always 2> /dev/null || return 1
|
||||
}
|
||||
|
||||
function get_local_hash() {
|
||||
cd "${1}" 2> /dev/null || return 1
|
||||
git rev-parse --short=8 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,8);}' || 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
|
||||
|
||||
@@ -46,54 +60,74 @@ if [[ ! "${DOCKER_TAG}" =~ $regex ]]; then
|
||||
unset DOCKER_TAG
|
||||
fi
|
||||
|
||||
if [[ "$2" == "remote" ]]; then
|
||||
|
||||
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 [[ "${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}"
|
||||
|
||||
if [[ "${DOCKER_TAG}" ]]; then
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "DOCKER_VERSION" "${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 web)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
|
||||
|
||||
GITHUB_WEB_HASH="$(get_remote_hash web "${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 --hash)"
|
||||
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,6 +31,9 @@ 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}"
|
||||
@@ -51,7 +54,14 @@ addKey(){
|
||||
local file="${1}"
|
||||
local key="${2}"
|
||||
|
||||
if ! grep -q "^${key}" "${file}"; then
|
||||
# touch file to prevent grep error if file does not exist yet
|
||||
touch "${file}"
|
||||
|
||||
# Match key against entire line, using both anchors. We assume
|
||||
# that the file's keys never have bounding whitespace. Anchors
|
||||
# are necessary to ensure the key is considered absent when it
|
||||
# is a substring of another key present in the file.
|
||||
if ! grep -q "^${key}$" "${file}"; then
|
||||
# Key does not exist, add it.
|
||||
echo "${key}" >> "${file}"
|
||||
fi
|
||||
|
||||
@@ -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,104 @@
|
||||
# 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}";;
|
||||
"web" ) [ "${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}";;
|
||||
"web" ) [ "${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}";;
|
||||
"web" ) [ "${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}";;
|
||||
"web" ) [ "${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}";;
|
||||
"web" ) [ "${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" = "web" ] && [ "${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"
|
||||
|
||||
# We do not want to show the branch name when we are on master,
|
||||
# blank out the variable in this case
|
||||
if [ "$branch" = "master" ]; then
|
||||
branch=""
|
||||
else
|
||||
branch="$branch "
|
||||
fi
|
||||
|
||||
if [ -n "$current" ] && [ -n "$latest" ]; then
|
||||
output="${1} version is $branch$current (Latest: $latest)"
|
||||
elif [ -n "$current" ] && [ -z "$latest" ]; then
|
||||
output="Current ${1} version is $branch$current"
|
||||
elif [ -z "$current" ] && [ -n "$latest" ]; then
|
||||
output="Latest ${1} version is $latest"
|
||||
elif [ -n "$curHash" ] && [ -n "$latHash" ]; then
|
||||
output="Local ${1} hash is $curHash (Remote: $latHash)"
|
||||
elif [ -n "$curHash" ] && [ -z "$latHash" ]; then
|
||||
output="Current local ${1} hash is $curHash"
|
||||
elif [ -z "$curHash" ] && [ -n "$latHash" ]; then
|
||||
output="Latest remote ${1} hash is $latHash"
|
||||
elif [ -z "$curHash" ] && [ -z "$latHash" ]; then
|
||||
output="Hashes for ${1} not available"
|
||||
else
|
||||
errorOutput
|
||||
return 1
|
||||
fi
|
||||
|
||||
[[ -n "$output" ]] && echo " $output"
|
||||
[ -n "$output" ] && echo " $output"
|
||||
}
|
||||
|
||||
errorOutput() {
|
||||
@@ -189,10 +114,10 @@ errorOutput() {
|
||||
}
|
||||
|
||||
defaultOutput() {
|
||||
versionOutput "pi-hole" "$@"
|
||||
versionOutput "Pi-hole" "$@"
|
||||
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
versionOutput "AdminLTE" "$@"
|
||||
if [ "${INSTALL_WEB_INTERFACE}" = true ]; then
|
||||
versionOutput "web" "$@"
|
||||
fi
|
||||
|
||||
versionOutput "FTL" "$@"
|
||||
@@ -205,7 +130,7 @@ Show Pi-hole, Admin Console & FTL versions
|
||||
|
||||
Repositories:
|
||||
-p, --pihole Only retrieve info regarding Pi-hole repository
|
||||
-a, --admin Only retrieve info regarding AdminLTE repository
|
||||
-a, --admin Only retrieve info regarding web repository
|
||||
-f, --ftl Only retrieve info regarding FTL repository
|
||||
|
||||
Options:
|
||||
@@ -217,8 +142,8 @@ Options:
|
||||
}
|
||||
|
||||
case "${1}" in
|
||||
"-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
|
||||
"-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
|
||||
"-p" | "--pihole" ) shift; versionOutput "Pi-hole" "$@";;
|
||||
"-a" | "--admin" ) shift; versionOutput "web" "$@";;
|
||||
"-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
|
||||
"-h" | "--help" ) helpFunc;;
|
||||
* ) defaultOutput "$@";;
|
||||
|
||||
@@ -22,12 +22,14 @@ readonly dnscustomcnamefile="/etc/dnsmasq.d/05-pihole-custom-cname.conf"
|
||||
|
||||
readonly gravityDBfile="/etc/pihole/gravity.db"
|
||||
|
||||
# Source install script for ${setupVars}, ${PI_HOLE_BIN_DIR} and valid_ip()
|
||||
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
|
||||
# shellcheck disable=SC2034 # used in basic-install to source the script without running it
|
||||
SKIP_INSTALL="true"
|
||||
source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
|
||||
|
||||
readonly setupVars="/etc/pihole/setupVars.conf"
|
||||
readonly PI_HOLE_BIN_DIR="/usr/local/bin"
|
||||
|
||||
# Root of the web server
|
||||
readonly webroot="/var/www/html"
|
||||
|
||||
# Source utils script
|
||||
utilsfile="/opt/pihole/utils.sh"
|
||||
source "${utilsfile}"
|
||||
|
||||
@@ -98,6 +100,47 @@ HashPassword() {
|
||||
echo "${return}"
|
||||
}
|
||||
|
||||
# Check an IP address to see if it is a valid one
|
||||
valid_ip() {
|
||||
# Local, named variables
|
||||
local ip=${1}
|
||||
local stat=1
|
||||
|
||||
# Regex matching one IPv4 component, i.e. an integer from 0 to 255.
|
||||
# See https://tools.ietf.org/html/rfc1340
|
||||
local ipv4elem="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)";
|
||||
# Regex matching an optional port (starting with '#') range of 1-65536
|
||||
local portelem="(#(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))?";
|
||||
# Build a full IPv4 regex from the above subexpressions
|
||||
local regex="^${ipv4elem}\\.${ipv4elem}\\.${ipv4elem}\\.${ipv4elem}${portelem}$"
|
||||
|
||||
# Evaluate the regex, and return the result
|
||||
[[ $ip =~ ${regex} ]]
|
||||
|
||||
stat=$?
|
||||
return "${stat}"
|
||||
}
|
||||
|
||||
valid_ip6() {
|
||||
local ip=${1}
|
||||
local stat=1
|
||||
|
||||
# Regex matching one IPv6 element, i.e. a hex value from 0000 to FFFF
|
||||
local ipv6elem="[0-9a-fA-F]{1,4}"
|
||||
# Regex matching an IPv6 CIDR, i.e. 1 to 128
|
||||
local v6cidr="(\\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}"
|
||||
# Regex matching an optional port (starting with '#') range of 1-65536
|
||||
local portelem="(#(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))?";
|
||||
# Build a full IPv6 regex from the above subexpressions
|
||||
local regex="^(((${ipv6elem}))*((:${ipv6elem}))*::((${ipv6elem}))*((:${ipv6elem}))*|((${ipv6elem}))((:${ipv6elem})){7})${v6cidr}${portelem}$"
|
||||
|
||||
# Evaluate the regex, and return the result
|
||||
[[ ${ip} =~ ${regex} ]]
|
||||
|
||||
stat=$?
|
||||
return "${stat}"
|
||||
}
|
||||
|
||||
SetWebPassword() {
|
||||
if [ "${SUDO_USER}" == "www-data" ]; then
|
||||
echo "Security measure: user www-data is not allowed to change webUI password!"
|
||||
@@ -305,7 +348,7 @@ SetDNSServers() {
|
||||
IFS=',' read -r -a array <<< "${args[2]}"
|
||||
for index in "${!array[@]}"
|
||||
do
|
||||
# Replace possible "\#" by "#". This fixes AdminLTE#1427
|
||||
# Replace possible "\#" by "#". This fixes web#1427
|
||||
local ip
|
||||
ip="${array[index]//\\#/#}"
|
||||
|
||||
@@ -613,7 +656,6 @@ Teleporter() {
|
||||
host="${host//./_}"
|
||||
filename="pi-hole-${host:-noname}-teleporter_${datetimestamp}.tar.gz"
|
||||
fi
|
||||
# webroot is sourced from basic-install above
|
||||
php "${webroot}/admin/scripts/pi-hole/php/teleporter.php" > "${filename}"
|
||||
}
|
||||
|
||||
@@ -622,11 +664,19 @@ checkDomain()
|
||||
local domain validDomain
|
||||
# Convert to lowercase
|
||||
domain="${1,,}"
|
||||
validDomain=$(grep -P "^((-|_)*[a-z\\d]((-|_)*[a-z\\d])*(-|_)*)(\\.(-|_)*([a-z\\d]((-|_)*[a-z\\d])*))*$" <<< "${domain}") # Valid chars check
|
||||
validDomain=$(grep -P "^((-|_)*[a-z0-9]((-|_)*[a-z0-9])*(-|_)*)(\\.(-|_)*([a-z0-9]((-|_)*[a-z0-9])*))*$" <<< "${domain}") # Valid chars check
|
||||
validDomain=$(grep -P "^[^\\.]{1,63}(\\.[^\\.]{1,63})*$" <<< "${validDomain}") # Length of each label
|
||||
echo "${validDomain}"
|
||||
}
|
||||
|
||||
escapeDots()
|
||||
{
|
||||
# SC suggest bashism ${variable//search/replace}
|
||||
# shellcheck disable=SC2001
|
||||
escaped=$(echo "$1" | sed 's/\./\\./g')
|
||||
echo "${escaped}"
|
||||
}
|
||||
|
||||
addAudit()
|
||||
{
|
||||
shift # skip "-a"
|
||||
@@ -702,6 +752,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"
|
||||
@@ -729,7 +780,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
|
||||
@@ -755,7 +811,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
|
||||
|
||||
@@ -19,8 +19,6 @@ INSERT OR REPLACE INTO adlist SELECT * FROM OLD.adlist;
|
||||
DELETE FROM OLD.adlist_by_group WHERE adlist_id NOT IN (SELECT id FROM OLD.adlist);
|
||||
INSERT OR REPLACE INTO adlist_by_group SELECT * FROM OLD.adlist_by_group;
|
||||
|
||||
INSERT OR REPLACE INTO info SELECT * FROM OLD.info;
|
||||
|
||||
INSERT OR REPLACE INTO client SELECT * FROM OLD.client;
|
||||
DELETE FROM OLD.client_by_group WHERE client_id NOT IN (SELECT id FROM OLD.client);
|
||||
INSERT OR REPLACE INTO client_by_group SELECT * FROM OLD.client_by_group;
|
||||
|
||||
13
advanced/Templates/pihole-FTL-poststop.sh
Executable file
13
advanced/Templates/pihole-FTL-poststop.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Source utils.sh for getFTLPIDFile()
|
||||
PI_HOLE_SCRIPT_DIR='/opt/pihole'
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
# shellcheck disable=SC1090
|
||||
. "${utilsfile}"
|
||||
|
||||
# Get file paths
|
||||
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||
|
||||
# Cleanup
|
||||
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}"
|
||||
38
advanced/Templates/pihole-FTL-prestart.sh
Executable file
38
advanced/Templates/pihole-FTL-prestart.sh
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Source utils.sh for getFTLPIDFile()
|
||||
PI_HOLE_SCRIPT_DIR='/opt/pihole'
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
# shellcheck disable=SC1090
|
||||
. "${utilsfile}"
|
||||
|
||||
# Get file paths
|
||||
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||
|
||||
# Touch files to ensure they exist (create if non-existing, preserve if existing)
|
||||
# shellcheck disable=SC2174
|
||||
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 /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
|
||||
# Ensure that permissions are set so that pihole-FTL can edit all necessary files
|
||||
chown pihole:pihole /run/pihole /etc/pihole /var/log/pihole /var/log/pihole/FTL.log /var/log/pihole/pihole.log /etc/pihole/dhcp.leases
|
||||
# Ensure that permissions are set so that pihole-FTL can edit the files. We ignore errors as the file may not (yet) exist
|
||||
chmod -f 0644 /etc/pihole/macvendor.db /etc/pihole/dhcp.leases /var/log/pihole/FTL.log
|
||||
chmod -f 0640 /var/log/pihole/pihole.log
|
||||
# Chown database files to the user FTL runs as. We ignore errors as the files may not (yet) exist
|
||||
chown -f pihole:pihole /etc/pihole/pihole-FTL.db /etc/pihole/gravity.db /etc/pihole/macvendor.db
|
||||
# Chmod database file permissions so that the pihole group (web interface) can edit the file. We ignore errors as the files may not (yet) exist
|
||||
chmod -f 0664 /etc/pihole/pihole-FTL.db
|
||||
|
||||
# Backward compatibility for user-scripts that still expect log files in /var/log instead of /var/log/pihole
|
||||
# Should be removed with Pi-hole v6.0
|
||||
if [ ! -f /var/log/pihole.log ]; then
|
||||
ln -sf /var/log/pihole/pihole.log /var/log/pihole.log
|
||||
chown -h pihole:pihole /var/log/pihole.log
|
||||
fi
|
||||
if [ ! -f /var/log/pihole-FTL.log ]; then
|
||||
ln -sf /var/log/pihole/FTL.log /var/log/pihole-FTL.log
|
||||
chown -h pihole:pihole /var/log/pihole-FTL.log
|
||||
fi
|
||||
@@ -9,9 +9,10 @@
|
||||
# Description: Enable service provided by pihole-FTL daemon
|
||||
### END INIT INFO
|
||||
|
||||
#source utils.sh for getFTLPIDFile(), getFTLPID ()
|
||||
# Source utils.sh for getFTLPIDFile(), getFTLPID()
|
||||
PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
# shellcheck disable=SC1090
|
||||
. "${utilsfile}"
|
||||
|
||||
|
||||
@@ -22,45 +23,31 @@ is_running() {
|
||||
return 1
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
# Run post-stop script, which does cleanup among runtime files
|
||||
sh "${PI_HOLE_SCRIPT_DIR}/pihole-FTL-poststop.sh"
|
||||
}
|
||||
|
||||
|
||||
# Start the service
|
||||
start() {
|
||||
if is_running; then
|
||||
echo "pihole-FTL is already running"
|
||||
else
|
||||
# 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 /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
|
||||
# Ensure that permissions are set so that pihole-FTL can edit all necessary files
|
||||
chown pihole:pihole /run/pihole /etc/pihole /var/log/pihole /var/log/pihole/FTL.log /var/log/pihole/pihole.log /etc/pihole/dhcp.leases
|
||||
# Ensure that permissions are set so that pihole-FTL can edit the files. We ignore errors as the file may not (yet) exist
|
||||
chmod -f 0644 /etc/pihole/macvendor.db /etc/pihole/dhcp.leases /var/log/pihole/FTL.log
|
||||
chmod -f 0640 /var/log/pihole/pihole.log
|
||||
# Chown database files to the user FTL runs as. We ignore errors as the files may not (yet) exist
|
||||
chown -f pihole:pihole /etc/pihole/pihole-FTL.db /etc/pihole/gravity.db /etc/pihole/macvendor.db
|
||||
# Chown database file permissions so that the pihole group (web interface) can edit the file. We ignore errors as the files may not (yet) exist
|
||||
chmod -f 0664 /etc/pihole/pihole-FTL.db
|
||||
|
||||
# Backward compatibility for user-scripts that still expect log files in /var/log instead of /var/log/pihole/
|
||||
# Should be removed with Pi-hole v6.0
|
||||
if [ ! -f /var/log/pihole.log ]; then
|
||||
ln -s /var/log/pihole/pihole.log /var/log/pihole.log
|
||||
chown -h pihole:pihole /var/log/pihole.log
|
||||
|
||||
fi
|
||||
if [ ! -f /var/log/pihole-FTL.log ]; then
|
||||
ln -s /var/log/pihole/FTL.log /var/log/pihole-FTL.log
|
||||
chown -h pihole:pihole /var/log/pihole-FTL.log
|
||||
fi
|
||||
# Run pre-start script, which pre-creates all expected files with correct permissions
|
||||
sh "${PI_HOLE_SCRIPT_DIR}/pihole-FTL-prestart.sh"
|
||||
|
||||
if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN+eip "/usr/bin/pihole-FTL"; then
|
||||
su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole || exit $?
|
||||
su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole
|
||||
else
|
||||
echo "Warning: Starting pihole-FTL as root because setting capabilities is not supported on this system"
|
||||
/usr/bin/pihole-FTL || exit $?
|
||||
/usr/bin/pihole-FTL
|
||||
fi
|
||||
rc=$?
|
||||
# Cleanup if startup failed
|
||||
if [ "${rc}" != 0 ]; then
|
||||
cleanup
|
||||
exit $rc
|
||||
fi
|
||||
echo
|
||||
fi
|
||||
@@ -89,8 +76,7 @@ stop() {
|
||||
else
|
||||
echo "Not running"
|
||||
fi
|
||||
# Cleanup
|
||||
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}"
|
||||
cleanup
|
||||
echo
|
||||
}
|
||||
|
||||
@@ -108,11 +94,14 @@ status() {
|
||||
|
||||
### main logic ###
|
||||
|
||||
# Get file paths
|
||||
# catch sudden termination
|
||||
trap 'cleanup; exit 1' INT HUP TERM ABRT
|
||||
|
||||
# Get FTL's PID file path
|
||||
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||
|
||||
# Get FTL's current PID
|
||||
FTL_PID="$(getFTLPID ${FTL_PID_FILE})"
|
||||
FTL_PID="$(getFTLPID "${FTL_PID_FILE}")"
|
||||
|
||||
case "$1" in
|
||||
stop)
|
||||
|
||||
41
advanced/Templates/pihole-FTL.systemd
Normal file
41
advanced/Templates/pihole-FTL.systemd
Normal file
@@ -0,0 +1,41 @@
|
||||
[Unit]
|
||||
Description=Pi-hole FTL
|
||||
# This unit is supposed to indicate when network functionality is available, but it is only
|
||||
# very weakly defined what that is supposed to mean, with one exception: at shutdown, a unit
|
||||
# that is ordered after network-online.target will be stopped before the network
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
# A target that should be used as synchronization point for all host/network name service lookups.
|
||||
# All services for which the availability of full host/network name resolution is essential should
|
||||
# be ordered after this target, but not pull it in.
|
||||
Wants=nss-lookup.target
|
||||
Before=nss-lookup.target
|
||||
|
||||
# Limit (re)start loop to 5 within 1 minute
|
||||
StartLimitBurst=5
|
||||
StartLimitIntervalSec=60s
|
||||
|
||||
[Service]
|
||||
User=pihole
|
||||
PermissionsStartOnly=true
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_NICE CAP_IPC_LOCK CAP_CHOWN
|
||||
|
||||
ExecStartPre=/opt/pihole/pihole-FTL-prestart.sh
|
||||
ExecStart=/usr/bin/pihole-FTL -f
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStopPost=/opt/pihole/pihole-FTL-poststop.sh
|
||||
|
||||
# Use graceful shutdown with a reasonable timeout
|
||||
TimeoutStopSec=10s
|
||||
|
||||
# Make /usr, /boot, /etc and possibly some more folders read-only...
|
||||
ProtectSystem=full
|
||||
# ... except /etc/pihole
|
||||
# This merely retains r/w access rights, it does not add any new.
|
||||
# Must still be writable on the host!
|
||||
ReadWriteDirectories=/etc/pihole
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -28,6 +28,6 @@
|
||||
|
||||
@reboot root /usr/sbin/logrotate --state /var/lib/logrotate/pihole /etc/pihole/logrotate
|
||||
|
||||
# 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
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
/* 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.
|
||||
*
|
||||
* This file is copyright under the latest version of the EUPL.
|
||||
* Please see LICENSE file for your rights under this license. */
|
||||
|
||||
// Sanitize SERVER_NAME output
|
||||
$serverName = htmlspecialchars($_SERVER["SERVER_NAME"]);
|
||||
// Remove external ipv6 brackets if any
|
||||
$serverName = preg_replace('/^\[(.*)\]$/', '${1}', $serverName);
|
||||
|
||||
// Set landing page location, found within /var/www/html/
|
||||
$landPage = "../landing.php";
|
||||
|
||||
// Define array for hostnames to be accepted as self address for splash page
|
||||
$authorizedHosts = [ "localhost" ];
|
||||
if (!empty($_SERVER["FQDN"])) {
|
||||
// If setenv.add-environment = ("fqdn" => "true") is configured in lighttpd,
|
||||
// append $serverName to $authorizedHosts
|
||||
array_push($authorizedHosts, $serverName);
|
||||
} else if (!empty($_SERVER["VIRTUAL_HOST"])) {
|
||||
// Append virtual hostname to $authorizedHosts
|
||||
array_push($authorizedHosts, $_SERVER["VIRTUAL_HOST"]);
|
||||
}
|
||||
|
||||
// Determine block page type
|
||||
if ($serverName === "pi.hole"
|
||||
|| (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) {
|
||||
// Redirect to Web Interface
|
||||
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
|
||||
// Unset variables so as to not be included in $landPage or $splashPage
|
||||
unset($authorizedHosts);
|
||||
// If $landPage file is present
|
||||
if (is_file(getcwd()."/$landPage")) {
|
||||
unset($serverName, $viewPort); // unset extra variables not to be included in $landpage
|
||||
include $landPage;
|
||||
exit();
|
||||
}
|
||||
// If $landPage file was not present, Set Splash Page output
|
||||
$splashPage = <<<EOT
|
||||
<!doctype html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
<title>● $serverName</title>
|
||||
<link rel='shortcut icon' href='/admin/img/favicons/favicon.ico' type='image/x-icon'>
|
||||
<style>
|
||||
html, body { height: 100% }
|
||||
body { margin: 0; font: 13pt "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; }
|
||||
body { background: #222; color: rgba(255, 255, 255, 0.7); text-align: center; }
|
||||
p { margin: 0; }
|
||||
a { color: #3c8dbc; text-decoration: none; }
|
||||
a:hover { color: #72afda; text-decoration: underline; }
|
||||
#splashpage { display: flex; align-items: center; justify-content: center; }
|
||||
#splashpage img { margin: 5px; width: 256px; }
|
||||
#splashpage b { color: inherit; }
|
||||
</style>
|
||||
</head>
|
||||
<body id='splashpage'>
|
||||
<div>
|
||||
<img src='/admin/img/logo.svg' alt='Pi-hole logo' width='256' height='377'>
|
||||
<br>
|
||||
<p>Pi-<strong>hole</strong>: Your black hole for Internet advertisements</p>
|
||||
<a href='/admin'>Did you mean to go to the admin panel?</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
EOT;
|
||||
exit($splashPage);
|
||||
}
|
||||
|
||||
header("HTTP/1.1 404 Not Found");
|
||||
exit();
|
||||
?>
|
||||
@@ -7,17 +7,18 @@
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY OVERWRITTEN BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
# #
|
||||
# CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE: #
|
||||
# /etc/lighttpd/external.conf #
|
||||
###############################################################################
|
||||
###################################################################################################
|
||||
# IF THIS HEADER EXISTS, THE FILE WILL BE OVERWRITTEN BY PI-HOLE'S UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON THE NEXT UPDATE UNLESS YOU REMOVE THIS HEADER #
|
||||
# #
|
||||
# ENSURE THAT YOU DO NOT REMOVE THE REQUIRED LINE: #
|
||||
# #
|
||||
# include "/etc/lighttpd/conf-enabled/*.conf" #
|
||||
# #
|
||||
###################################################################################################
|
||||
|
||||
server.modules = (
|
||||
"mod_access",
|
||||
"mod_accesslog",
|
||||
"mod_auth",
|
||||
"mod_expire",
|
||||
"mod_redirect",
|
||||
@@ -26,7 +27,6 @@ server.modules = (
|
||||
)
|
||||
|
||||
server.document-root = "/var/www/html"
|
||||
server.error-handler-404 = "/pihole/index.php"
|
||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||
server.errorlog = "/var/log/lighttpd/error-pihole.log"
|
||||
server.pid-file = "/run/lighttpd.pid"
|
||||
@@ -35,8 +35,6 @@ server.groupname = "www-data"
|
||||
# For lighttpd version 1.4.46 or above, the port can be overwritten in `/etc/lighttpd/external.conf` using the := operator
|
||||
# e.g. server.port := 8000
|
||||
server.port = 80
|
||||
accesslog.filename = "/var/log/lighttpd/access-pihole.log"
|
||||
accesslog.format = "%{%s}t|%V|%r|%s|%b"
|
||||
|
||||
# Allow streaming response
|
||||
# reference: https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_stream-response-bodyDetails
|
||||
@@ -67,48 +65,9 @@ mimetype.assign = (
|
||||
".woff2" => "font/woff2"
|
||||
)
|
||||
|
||||
# Add user chosen options held in external file
|
||||
# This uses include_shell instead of an include wildcard for compatibility
|
||||
include_shell "cat external.conf 2>/dev/null"
|
||||
# Add user chosen options held in (optional) external file
|
||||
include "external*.conf"
|
||||
|
||||
# default listening port for IPv6 falls back to the IPv4 port
|
||||
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
|
||||
|
||||
# Prevent Lighttpd from enabling Let's Encrypt SSL for every blocked domain
|
||||
#include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
||||
include_shell "find /etc/lighttpd/conf-enabled -name '*.conf' -a ! -name 'letsencrypt.conf' -printf 'include \"%p\"\n' 2>/dev/null"
|
||||
|
||||
# If the URL starts with /admin, it is the Web interface
|
||||
$HTTP["url"] =~ "^/admin/" {
|
||||
# X-Pi-hole is a response header for debugging using curl -I
|
||||
# X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
|
||||
# X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input.
|
||||
# X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
|
||||
# Content-Security-Policy tells the browser where resources are allowed to be loaded and if it’s allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
|
||||
# X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
|
||||
# Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
|
||||
setenv.add-response-header = (
|
||||
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
||||
"X-Frame-Options" => "DENY",
|
||||
"X-XSS-Protection" => "1; mode=block",
|
||||
"X-Content-Type-Options" => "nosniff",
|
||||
"Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
|
||||
"X-Permitted-Cross-Domain-Policies" => "none",
|
||||
"Referrer-Policy" => "same-origin"
|
||||
)
|
||||
}
|
||||
|
||||
# Block . files from being served, such as .git, .github, .gitignore
|
||||
$HTTP["url"] =~ "^/admin/\.(.*)" {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
|
||||
# allow teleporter and API qr code iframe on settings page
|
||||
$HTTP["url"] =~ "/(teleporter|api_token)\.php$" {
|
||||
$HTTP["referer"] =~ "/admin/settings\.php" {
|
||||
setenv.add-response-header = ( "X-Frame-Options" => "SAMEORIGIN" )
|
||||
}
|
||||
}
|
||||
|
||||
# Default expire header
|
||||
expire.url = ( "" => "access plus 0 seconds" )
|
||||
include "/etc/lighttpd/conf-enabled/*.conf"
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY OVERWRITTEN BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
# #
|
||||
# CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE: #
|
||||
# /etc/lighttpd/external.conf #
|
||||
###############################################################################
|
||||
###################################################################################################
|
||||
# IF THIS HEADER EXISTS, THE FILE WILL BE OVERWRITTEN BY PI-HOLE'S UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON THE NEXT UPDATE UNLESS YOU REMOVE THIS HEADER #
|
||||
# #
|
||||
# ENSURE THAT YOU DO NOT REMOVE THE REQUIRED LINE: #
|
||||
# #
|
||||
# include "/etc/lighttpd/conf.d/pihole-admin.conf" #
|
||||
# #
|
||||
###################################################################################################
|
||||
|
||||
server.modules = (
|
||||
"mod_access",
|
||||
@@ -27,7 +29,6 @@ server.modules = (
|
||||
)
|
||||
|
||||
server.document-root = "/var/www/html"
|
||||
server.error-handler-404 = "/pihole/index.php"
|
||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||
server.errorlog = "/var/log/lighttpd/error-pihole.log"
|
||||
server.pid-file = "/run/lighttpd.pid"
|
||||
@@ -36,8 +37,6 @@ server.groupname = "lighttpd"
|
||||
# For lighttpd version 1.4.46 or above, the port can be overwritten in `/etc/lighttpd/external.conf` using the := operator
|
||||
# e.g. server.port := 8000
|
||||
server.port = 80
|
||||
accesslog.filename = "/var/log/lighttpd/access-pihole.log"
|
||||
accesslog.format = "%{%s}t|%V|%r|%s|%b"
|
||||
|
||||
# Allow streaming response
|
||||
# reference: https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_stream-response-bodyDetails
|
||||
@@ -68,9 +67,8 @@ mimetype.assign = (
|
||||
".woff2" => "font/woff2"
|
||||
)
|
||||
|
||||
# Add user chosen options held in external file
|
||||
# This uses include_shell instead of an include wildcard for compatibility
|
||||
include_shell "cat external.conf 2>/dev/null"
|
||||
# Add user chosen options held in (optional) external file
|
||||
include "external*.conf"
|
||||
|
||||
# default listening port for IPv6 falls back to the IPv4 port
|
||||
#include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
|
||||
@@ -86,37 +84,4 @@ fastcgi.server = (
|
||||
)
|
||||
)
|
||||
|
||||
# If the URL starts with /admin, it is the Web interface
|
||||
$HTTP["url"] =~ "^/admin/" {
|
||||
# X-Pi-hole is a response header for debugging using curl -I
|
||||
# X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
|
||||
# X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input.
|
||||
# X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
|
||||
# Content-Security-Policy tells the browser where resources are allowed to be loaded and if it’s allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
|
||||
# X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
|
||||
# Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
|
||||
setenv.add-response-header = (
|
||||
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
||||
"X-Frame-Options" => "DENY",
|
||||
"X-XSS-Protection" => "1; mode=block",
|
||||
"X-Content-Type-Options" => "nosniff",
|
||||
"Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
|
||||
"X-Permitted-Cross-Domain-Policies" => "none",
|
||||
"Referrer-Policy" => "same-origin"
|
||||
)
|
||||
}
|
||||
|
||||
# Block . files from being served, such as .git, .github, .gitignore
|
||||
$HTTP["url"] =~ "^/admin/\.(.*)" {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
|
||||
# allow teleporter and API qr code iframe on settings page
|
||||
$HTTP["url"] =~ "/(teleporter|api_token)\.php$" {
|
||||
$HTTP["referer"] =~ "/admin/settings\.php" {
|
||||
setenv.add-response-header = ( "X-Frame-Options" => "SAMEORIGIN" )
|
||||
}
|
||||
}
|
||||
|
||||
# Default expire header
|
||||
expire.url = ( "" => "access plus 0 seconds" )
|
||||
include "/etc/lighttpd/conf.d/pihole-admin.conf"
|
||||
|
||||
82
advanced/pihole-admin.conf
Normal file
82
advanced/pihole-admin.conf
Normal file
@@ -0,0 +1,82 @@
|
||||
# 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.
|
||||
#
|
||||
# Lighttpd config for Pi-hole
|
||||
#
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY OVERWRITTEN BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
###############################################################################
|
||||
|
||||
server.errorlog := "/var/log/lighttpd/error-pihole.log"
|
||||
|
||||
$HTTP["url"] =~ "^/admin/" {
|
||||
server.document-root = "/var/www/html"
|
||||
server.stream-response-body = 1
|
||||
accesslog.filename = "/var/log/lighttpd/access-pihole.log"
|
||||
accesslog.format = "%{%s}t|%h|%V|%r|%s|%b"
|
||||
|
||||
fastcgi.server = (
|
||||
".php" => (
|
||||
"localhost" => (
|
||||
"socket" => "/run/lighttpd/pihole-php-fastcgi.socket",
|
||||
"bin-path" => "/usr/bin/php-cgi",
|
||||
"min-procs" => 1,
|
||||
"max-procs" => 1,
|
||||
"bin-environment" => (
|
||||
"PHP_FCGI_CHILDREN" => "4",
|
||||
"PHP_FCGI_MAX_REQUESTS" => "10000",
|
||||
),
|
||||
"bin-copy-environment" => (
|
||||
"PATH", "SHELL", "USER"
|
||||
),
|
||||
"broken-scriptfilename" => "enable",
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# X-Pi-hole is a response header for debugging using curl -I
|
||||
# X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
|
||||
# X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input. (deprecated; disabled)
|
||||
# X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
|
||||
# Content-Security-Policy tells the browser where resources are allowed to be loaded and if it’s allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
|
||||
# X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
|
||||
# Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
|
||||
setenv.add-response-header = (
|
||||
"X-Pi-hole" => "The Pi-hole Web interface is working!",
|
||||
"X-Frame-Options" => "DENY",
|
||||
"X-XSS-Protection" => "0",
|
||||
"X-Content-Type-Options" => "nosniff",
|
||||
"Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
|
||||
"X-Permitted-Cross-Domain-Policies" => "none",
|
||||
"Referrer-Policy" => "same-origin"
|
||||
)
|
||||
|
||||
# Block . files from being served, such as .git, .github, .gitignore
|
||||
$HTTP["url"] =~ "^/admin/\." {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
|
||||
# allow teleporter and API qr code iframe on settings page
|
||||
$HTTP["url"] =~ "/(teleporter|api_token)\.php$" {
|
||||
$HTTP["referer"] =~ "/admin/settings\.php" {
|
||||
setenv.set-response-header = ( "X-Frame-Options" => "SAMEORIGIN" )
|
||||
}
|
||||
}
|
||||
}
|
||||
else $HTTP["url"] == "/admin" {
|
||||
url.redirect = ("" => "/admin/")
|
||||
}
|
||||
|
||||
$HTTP["host"] == "pi.hole" {
|
||||
$HTTP["url"] == "/" {
|
||||
url.redirect = ("" => "/admin/")
|
||||
}
|
||||
}
|
||||
|
||||
# (keep this on one line for basic-install.sh filtering during install)
|
||||
server.modules += ( "mod_access", "mod_accesslog", "mod_redirect", "mod_fastcgi", "mod_setenv" )
|
||||
@@ -68,11 +68,11 @@ webroot="/var/www/html"
|
||||
|
||||
|
||||
# We clone (or update) two git repositories during the install. This helps to make sure that we always have the latest versions of the relevant files.
|
||||
# AdminLTE is used to set up the Web admin interface.
|
||||
# web is used to set up the Web admin interface.
|
||||
# Pi-hole contains various setup scripts and files which are critical to the installation.
|
||||
# Search for "PI_HOLE_LOCAL_REPO" in this file to see all such scripts.
|
||||
# Two notable scripts are gravity.sh (used to generate the HOSTS file) and advanced/Scripts/webpage.sh (used to install the Web admin interface)
|
||||
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
|
||||
webInterfaceGitUrl="https://github.com/pi-hole/web.git"
|
||||
webInterfaceDir="${webroot}/admin"
|
||||
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
|
||||
PI_HOLE_LOCAL_REPO="/etc/.pihole"
|
||||
@@ -82,7 +82,6 @@ PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update versi
|
||||
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
|
||||
@@ -335,7 +334,7 @@ package_manager_detect() {
|
||||
# Packages required for the Web admin interface (stored as an array)
|
||||
# It's useful to separate this from Pi-hole, since the two repos are also setup separately
|
||||
PIHOLE_WEB_DEPS=(lighttpd "${phpVer}-common" "${phpVer}-cgi" "${phpVer}-sqlite3" "${phpVer}-xml" "${phpVer}-intl")
|
||||
# Prior to PHP8.0, JSON functionality is provided as dedicated module, required by Pi-hole AdminLTE: https://www.php.net/manual/json.installation.php
|
||||
# Prior to PHP8.0, JSON functionality is provided as dedicated module, required by Pi-hole web: https://www.php.net/manual/json.installation.php
|
||||
if [[ -z "${phpInsMajor}" || "${phpInsMajor}" -lt 8 ]]; then
|
||||
PIHOLE_WEB_DEPS+=("${phpVer}-json")
|
||||
fi
|
||||
@@ -358,9 +357,9 @@ 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|.riscv64)' | wc -l || true"
|
||||
OS_CHECK_DEPS=(grep bind-utils)
|
||||
INSTALLER_DEPS=(git dialog iproute newt procps-ng which chkconfig ca-certificates)
|
||||
INSTALLER_DEPS=(git dialog iproute newt procps-ng chkconfig ca-certificates)
|
||||
PIHOLE_DEPS=(cronie curl findutils sudo unzip libidn2 psmisc libcap nmap-ncat jq)
|
||||
PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php-common php-cli php-pdo php-xml php-json php-intl)
|
||||
LIGHTTPD_USER="lighttpd"
|
||||
@@ -828,8 +827,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
|
||||
@@ -1377,37 +1379,96 @@ installConfigs() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install pihole-FTL.service
|
||||
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.service" "/etc/init.d/pihole-FTL"
|
||||
# Install pihole-FTL systemd or init.d service, based on whether systemd is the init system or not
|
||||
# Follow debhelper logic, which checks for /run/systemd/system to derive whether systemd is the init system
|
||||
if [[ -d '/run/systemd/system' ]]; then
|
||||
install -T -m 0644 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.systemd" '/etc/systemd/system/pihole-FTL.service'
|
||||
|
||||
# Remove init.d service if present
|
||||
if [[ -e '/etc/init.d/pihole-FTL' ]]; then
|
||||
rm '/etc/init.d/pihole-FTL'
|
||||
update-rc.d pihole-FTL remove
|
||||
fi
|
||||
|
||||
# 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'
|
||||
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"
|
||||
|
||||
# If the user chose to install the dashboard,
|
||||
if [[ "${INSTALL_WEB_SERVER}" == true ]]; then
|
||||
# and if the Web server conf directory does not exist,
|
||||
if [[ ! -d "/etc/lighttpd" ]]; then
|
||||
# make it and set the owners
|
||||
install -d -m 755 -o "${USER}" -g root /etc/lighttpd
|
||||
# Otherwise, if the config file already exists
|
||||
elif [[ -f "${lighttpdConfig}" ]]; then
|
||||
# back up the original
|
||||
mv "${lighttpdConfig}"{,.orig}
|
||||
fi
|
||||
# and copy in the config file Pi-hole needs
|
||||
install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/advanced/${LIGHTTPD_CFG} "${lighttpdConfig}"
|
||||
# Make sure the external.conf file exists, as lighttpd v1.4.50 crashes without it
|
||||
if [ ! -f /etc/lighttpd/external.conf ]; then
|
||||
install -m 644 /dev/null /etc/lighttpd/external.conf
|
||||
fi
|
||||
# If there is a custom block page in the html/pihole directory, replace 404 handler in lighttpd config
|
||||
if [[ -f "${PI_HOLE_404_DIR}/custom.php" ]]; then
|
||||
sed -i 's/^\(server\.error-handler-404\s*=\s*\).*$/\1"\/pihole\/custom\.php"/' "${lighttpdConfig}"
|
||||
fi
|
||||
# Make the directories if they do not exist and set the owners
|
||||
# set permissions on /etc/lighttpd/lighttpd.conf so pihole user (other) can read the file
|
||||
chmod o+x /etc/lighttpd
|
||||
chmod o+r "${lighttpdConfig}"
|
||||
|
||||
# Ensure /run/lighttpd exists and is owned by lighttpd user
|
||||
# Needed for the php socket
|
||||
mkdir -p /run/lighttpd
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /run/lighttpd
|
||||
mkdir -p /var/cache/lighttpd/compress
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
|
||||
mkdir -p /var/cache/lighttpd/uploads
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
|
||||
|
||||
if grep -q -F "OVERWRITTEN BY PI-HOLE" "${lighttpdConfig}"; then
|
||||
# Attempt to preserve backwards compatibility with older versions
|
||||
install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/advanced/${LIGHTTPD_CFG} "${lighttpdConfig}"
|
||||
# Make the directories if they do not exist and set the owners
|
||||
mkdir -p /var/cache/lighttpd/compress
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
|
||||
mkdir -p /var/cache/lighttpd/uploads
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
|
||||
fi
|
||||
# Copy the config file to include for pihole admin interface
|
||||
if [[ -d "/etc/lighttpd/conf.d" ]]; then
|
||||
install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/advanced/pihole-admin.conf /etc/lighttpd/conf.d/pihole-admin.conf
|
||||
if grep -q -F 'include "/etc/lighttpd/conf.d/pihole-admin.conf"' "${lighttpdConfig}"; then
|
||||
:
|
||||
else
|
||||
echo 'include "/etc/lighttpd/conf.d/pihole-admin.conf"' >> "${lighttpdConfig}"
|
||||
fi
|
||||
# Avoid some warnings trace from lighttpd, which might break tests
|
||||
conf=/etc/lighttpd/conf.d/pihole-admin.conf
|
||||
if lighttpd -f "${lighttpdConfig}" -tt 2>&1 | grep -q -F "WARNING: unknown config-key: dir-listing\."; then
|
||||
echo '# Avoid some warnings trace from lighttpd, which might break tests' >> $conf
|
||||
echo 'server.modules += ( "mod_dirlisting" )' >> $conf
|
||||
fi
|
||||
if lighttpd -f "${lighttpdConfig}" -tt 2>&1 | grep -q -F "warning: please use server.use-ipv6"; then
|
||||
echo '# Avoid some warnings trace from lighttpd, which might break tests' >> $conf
|
||||
echo 'server.use-ipv6 := "disable"' >> $conf
|
||||
fi
|
||||
elif [[ -d "/etc/lighttpd/conf-available" ]]; then
|
||||
conf=/etc/lighttpd/conf-available/15-pihole-admin.conf
|
||||
install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/advanced/pihole-admin.conf $conf
|
||||
|
||||
# Get the version number of lighttpd
|
||||
version=$(dpkg-query -f='${Version}\n' --show lighttpd)
|
||||
# Test if that version is greater than or euqal to 1.4.56
|
||||
if dpkg --compare-versions "$version" "ge" "1.4.56"; then
|
||||
# If it is, then we don't need to disable the modules
|
||||
# (server.modules duplication is ignored in lighttpd 1.4.56+)
|
||||
:
|
||||
else
|
||||
# disable server.modules += ( ... ) in $conf to avoid module dups
|
||||
if awk '!/^server\.modules/{print}' $conf > $conf.$$ && mv $conf.$$ $conf; then
|
||||
:
|
||||
else
|
||||
rm $conf.$$
|
||||
fi
|
||||
fi
|
||||
|
||||
chmod 644 $conf
|
||||
if is_command lighty-enable-mod ; then
|
||||
lighty-enable-mod pihole-admin access accesslog redirect fastcgi setenv > /dev/null || true
|
||||
else
|
||||
# Otherwise, show info about installing them
|
||||
printf " %b Warning: 'lighty-enable-mod' utility not found\\n" "${INFO}"
|
||||
printf " Please ensure fastcgi is enabled if you experience issues\\n"
|
||||
fi
|
||||
else
|
||||
# lighttpd config include dir not found
|
||||
printf " %b Warning: lighttpd config include dir not found\\n" "${INFO}"
|
||||
printf " Please manually install pihole-admin.conf\\n"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1658,30 +1719,6 @@ install_dependent_packages() {
|
||||
|
||||
# Install the Web interface dashboard
|
||||
installPiholeWeb() {
|
||||
printf "\\n %b Installing 404 page...\\n" "${INFO}"
|
||||
|
||||
local str="Creating directory for 404 page, and copying files"
|
||||
printf " %b %s..." "${INFO}" "${str}"
|
||||
# Install the directory
|
||||
install -d -m 0755 ${PI_HOLE_404_DIR}
|
||||
# and the 404 handler
|
||||
install -D -m 644 ${PI_HOLE_LOCAL_REPO}/advanced/index.php ${PI_HOLE_404_DIR}/
|
||||
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
|
||||
local str="Backing up index.lighttpd.html"
|
||||
printf " %b %s..." "${INFO}" "${str}"
|
||||
# If the default index file exists,
|
||||
if [[ -f "${webroot}/index.lighttpd.html" ]]; then
|
||||
# back it up
|
||||
mv ${webroot}/index.lighttpd.html ${webroot}/index.lighttpd.orig
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
else
|
||||
# Otherwise, don't do anything
|
||||
printf "%b %b %s\\n" "${OVER}" "${INFO}" "${str}"
|
||||
printf " No default index.lighttpd.html file found... not backing up\\n"
|
||||
fi
|
||||
|
||||
# Install Sudoers file
|
||||
local str="Installing sudoer file"
|
||||
printf "\\n %b %s..." "${INFO}" "${str}"
|
||||
@@ -1757,20 +1794,35 @@ create_pihole_user() {
|
||||
else
|
||||
# If the pihole user doesn't exist,
|
||||
printf "%b %b %s" "${OVER}" "${CROSS}" "${str}"
|
||||
local str="Creating user 'pihole'"
|
||||
printf "%b %b %s..." "${OVER}" "${INFO}" "${str}"
|
||||
# create her with the useradd command,
|
||||
local str="Checking for group 'pihole'"
|
||||
printf " %b %s..." "${INFO}" "${str}"
|
||||
if getent group pihole > /dev/null 2>&1; then
|
||||
# then add her to the pihole group (as it already exists)
|
||||
# group pihole exists
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
# 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
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
else
|
||||
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
|
||||
fi
|
||||
else
|
||||
# add user pihole with default group settings
|
||||
if useradd -r -s /usr/sbin/nologin pihole; then
|
||||
# group pihole does not exist
|
||||
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
|
||||
local str="Creating group 'pihole'"
|
||||
# if group can be created
|
||||
if groupadd pihole; then
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
# 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
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
else
|
||||
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
|
||||
fi
|
||||
|
||||
else
|
||||
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
|
||||
fi
|
||||
@@ -1869,15 +1921,6 @@ installPihole() {
|
||||
# Give lighttpd access to the pihole group so the web interface can
|
||||
# manage the gravity.db database
|
||||
usermod -a -G pihole ${LIGHTTPD_USER}
|
||||
# If the lighttpd command is executable,
|
||||
if is_command lighty-enable-mod ; then
|
||||
# enable fastcgi and fastcgi-php
|
||||
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
|
||||
else
|
||||
# Otherwise, show info about installing them
|
||||
printf " %b Warning: 'lighty-enable-mod' utility not found\\n" "${INFO}"
|
||||
printf " Please ensure fastcgi is enabled if you experience issues\\n"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# Install base files and web interface
|
||||
@@ -2267,7 +2310,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
|
||||
@@ -2323,6 +2366,9 @@ get_binary_name() {
|
||||
# set the binary to be used
|
||||
l_binary="pihole-FTL-linux-x86_64"
|
||||
fi
|
||||
elif [[ "${machine}" == "riscv64" ]]; then
|
||||
printf "%b %b Detected riscv64 processor\\n" "${OVER}" "${TICK}"
|
||||
l_binary="pihole-FTL-riscv64-linux-gnu"
|
||||
else
|
||||
# Something else - we try to use 32bit executable and warn the user
|
||||
if [[ ! "${machine}" == "i686" ]]; then
|
||||
@@ -2569,7 +2615,8 @@ main() {
|
||||
|
||||
# Get the privacy level if it exists (default is 0)
|
||||
if [[ -f "${FTL_CONFIG_FILE}" ]]; then
|
||||
PRIVACY_LEVEL=$(sed -ne 's/PRIVACYLEVEL=\(.*\)/\1/p' "${FTL_CONFIG_FILE}")
|
||||
# get the value from $FTL_CONFIG_FILE (and ignoring all commented lines)
|
||||
PRIVACY_LEVEL=$(sed -e '/^[[:blank:]]*#/d' "${FTL_CONFIG_FILE}" | grep "PRIVACYLEVEL" | awk -F "=" 'NR==1{printf$2}')
|
||||
|
||||
# If no setting was found, default to 0
|
||||
PRIVACY_LEVEL="${PRIVACY_LEVEL:-0}"
|
||||
@@ -2638,7 +2685,7 @@ main() {
|
||||
# Check for and disable systemd-resolved-DNSStubListener before reloading resolved
|
||||
# DNSStubListener needs to remain in place for installer to download needed files,
|
||||
# so this change needs to be made after installation is complete,
|
||||
# but before starting or resarting the dnsmasq or ftl services
|
||||
# but before starting or restarting the dnsmasq or ftl services
|
||||
disable_resolved_stublistener
|
||||
|
||||
# If the Web server was installed,
|
||||
@@ -2693,9 +2740,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}"
|
||||
|
||||
@@ -131,6 +131,7 @@ removeNoPurge() {
|
||||
fi
|
||||
|
||||
if package_check lighttpd > /dev/null; then
|
||||
# Attempt to preserve backwards compatibility with older versions
|
||||
if [[ -f /etc/lighttpd/lighttpd.conf.orig ]]; then
|
||||
${SUDO} mv /etc/lighttpd/lighttpd.conf.orig /etc/lighttpd/lighttpd.conf
|
||||
fi
|
||||
@@ -139,6 +140,29 @@ removeNoPurge() {
|
||||
${SUDO} rm /etc/lighttpd/external.conf
|
||||
fi
|
||||
|
||||
# Fedora-based
|
||||
if [[ -f /etc/lighttpd/conf.d/pihole-admin.conf ]]; then
|
||||
${SUDO} rm /etc/lighttpd/conf.d/pihole-admin.conf
|
||||
conf=/etc/lighttpd/lighttpd.conf
|
||||
tconf=/tmp/lighttpd.conf.$$
|
||||
if awk '!/^include "\/etc\/lighttpd\/conf\.d\/pihole-admin\.conf"$/{print}' \
|
||||
$conf > $tconf && mv $tconf $conf; then
|
||||
:
|
||||
else
|
||||
rm $tconf
|
||||
fi
|
||||
${SUDO} chown root:root $conf
|
||||
${SUDO} chmod 644 $conf
|
||||
fi
|
||||
|
||||
# Debian-based
|
||||
if [[ -f /etc/lighttpd/conf-available/pihole-admin.conf ]]; then
|
||||
if is_command lighty-disable-mod ; then
|
||||
${SUDO} lighty-disable-mod pihole-admin > /dev/null || true
|
||||
fi
|
||||
${SUDO} rm /etc/lighttpd/conf-available/15-pihole-admin.conf
|
||||
fi
|
||||
|
||||
echo -e " ${TICK} Removed lighttpd configs"
|
||||
fi
|
||||
|
||||
@@ -169,6 +193,18 @@ removeNoPurge() {
|
||||
else
|
||||
service pihole-FTL stop
|
||||
fi
|
||||
${SUDO} rm -f /etc/systemd/system/pihole-FTL.service
|
||||
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
|
||||
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
|
||||
echo -e "${OVER} ${TICK} Removed pihole-FTL"
|
||||
|
||||
301
gravity.sh
301
gravity.sh
@@ -52,6 +52,14 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set up tmp dir variable in case it's not configured
|
||||
: "${GRAVITY_TMPDIR:=/tmp}"
|
||||
|
||||
if [ ! -d "${GRAVITY_TMPDIR}" ] || [ ! -w "${GRAVITY_TMPDIR}" ]; then
|
||||
echo -e " ${COL_LIGHT_RED}Gravity temporary directory does not exist or is not a writeable directory, falling back to /tmp. ${COL_NC}"
|
||||
GRAVITY_TMPDIR="/tmp"
|
||||
fi
|
||||
|
||||
# Source pihole-FTL from install script
|
||||
pihole_FTL="${piholeDir}/pihole-FTL.conf"
|
||||
if [[ -f "${pihole_FTL}" ]]; then
|
||||
@@ -121,7 +129,7 @@ gravity_swap_databases() {
|
||||
echo -e "${OVER} ${TICK} ${str}"
|
||||
|
||||
if $oldAvail; then
|
||||
echo -e " ${TICK} The old database remains available."
|
||||
echo -e " ${TICK} The old database remains available"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -145,7 +153,10 @@ database_table_from_file() {
|
||||
src="${2}"
|
||||
backup_path="${piholeDir}/migration_backup"
|
||||
backup_file="${backup_path}/$(basename "${2}")"
|
||||
tmpFile="$(mktemp -p "/tmp" --suffix=".gravity")"
|
||||
# Create a temporary file. We don't use '--suffix' here because not all
|
||||
# implementations of mktemp support it, e.g. on Alpine
|
||||
tmpFile="$(mktemp -p "${GRAVITY_TMPDIR}")"
|
||||
mv "${tmpFile}" "${tmpFile%.*}.gravity"
|
||||
|
||||
local timestamp
|
||||
timestamp="$(date --utc +'%s')"
|
||||
@@ -216,20 +227,9 @@ database_table_from_file() {
|
||||
echo -e " ${CROSS} Unable to remove ${tmpFile}"
|
||||
}
|
||||
|
||||
# Update timestamp of last update of this list. We store this in the "old" database as all values in the new database will later be overwritten
|
||||
database_adlist_updated() {
|
||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET date_updated = (cast(strftime('%%s', 'now') as int)) WHERE id = %i;\\n" "${1}" | pihole-FTL sqlite3 "${gravityDBfile}"; } 2>&1 )
|
||||
status="$?"
|
||||
|
||||
if [[ "${status}" -ne 0 ]]; then
|
||||
echo -e "\\n ${CROSS} Unable to update timestamp of adlist with ID ${1} in database ${gravityDBfile}\\n ${output}"
|
||||
gravity_Cleanup "error"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if a column with name ${2} exists in gravity table with name ${1}
|
||||
gravity_column_exists() {
|
||||
output=$( { printf ".timeout 30000\\nSELECT EXISTS(SELECT * FROM pragma_table_info('%s') WHERE name='%s');\\n" "${1}" "${2}" | pihole-FTL sqlite3 "${gravityDBfile}"; } 2>&1 )
|
||||
output=$( { printf ".timeout 30000\\nSELECT EXISTS(SELECT * FROM pragma_table_info('%s') WHERE name='%s');\\n" "${1}" "${2}" | pihole-FTL sqlite3 "${gravityTEMPfile}"; } 2>&1 )
|
||||
if [[ "${output}" == "1" ]]; then
|
||||
return 0 # Bash 0 is success
|
||||
fi
|
||||
@@ -244,11 +244,11 @@ database_adlist_number() {
|
||||
return;
|
||||
fi
|
||||
|
||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET number = %i, invalid_domains = %i WHERE id = %i;\\n" "${num_source_lines}" "${num_invalid}" "${1}" | pihole-FTL sqlite3 "${gravityDBfile}"; } 2>&1 )
|
||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET number = %i, invalid_domains = %i WHERE id = %i;\\n" "${2}" "${3}" "${1}" | pihole-FTL sqlite3 "${gravityTEMPfile}"; } 2>&1 )
|
||||
status="$?"
|
||||
|
||||
if [[ "${status}" -ne 0 ]]; then
|
||||
echo -e "\\n ${CROSS} Unable to update number of domains in adlist with ID ${1} in database ${gravityDBfile}\\n ${output}"
|
||||
echo -e "\\n ${CROSS} Unable to update number of domains in adlist with ID ${1} in database ${gravityTEMPfile}\\n ${output}"
|
||||
gravity_Cleanup "error"
|
||||
fi
|
||||
}
|
||||
@@ -260,11 +260,11 @@ database_adlist_status() {
|
||||
return;
|
||||
fi
|
||||
|
||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET status = %i WHERE id = %i;\\n" "${2}" "${1}" | pihole-FTL sqlite3 "${gravityDBfile}"; } 2>&1 )
|
||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET status = %i WHERE id = %i;\\n" "${2}" "${1}" | pihole-FTL sqlite3 "${gravityTEMPfile}"; } 2>&1 )
|
||||
status="$?"
|
||||
|
||||
if [[ "${status}" -ne 0 ]]; then
|
||||
echo -e "\\n ${CROSS} Unable to update status of adlist with ID ${1} in database ${gravityDBfile}\\n ${output}"
|
||||
echo -e "\\n ${CROSS} Unable to update status of adlist with ID ${1} in database ${gravityTEMPfile}\\n ${output}"
|
||||
gravity_Cleanup "error"
|
||||
fi
|
||||
}
|
||||
@@ -401,7 +401,7 @@ gravity_DownloadBlocklists() {
|
||||
unset sources
|
||||
fi
|
||||
|
||||
local url domain agent cmd_ext str target compression
|
||||
local url domain str target compression
|
||||
echo ""
|
||||
|
||||
# Prepare new gravity database
|
||||
@@ -418,7 +418,24 @@ gravity_DownloadBlocklists() {
|
||||
echo -e "${OVER} ${TICK} ${str}"
|
||||
fi
|
||||
|
||||
target="$(mktemp -p "/tmp" --suffix=".gravity")"
|
||||
str="Creating new gravity databases"
|
||||
echo -ne " ${INFO} ${str}..."
|
||||
|
||||
# Gravity copying SQL script
|
||||
copyGravity="$(cat "${gravityDBcopy}")"
|
||||
if [[ "${gravityDBfile}" != "${gravityDBfile_default}" ]]; then
|
||||
# Replace default gravity script location by custom location
|
||||
copyGravity="${copyGravity//"${gravityDBfile_default}"/"${gravityDBfile}"}"
|
||||
fi
|
||||
|
||||
output=$( { pihole-FTL sqlite3 "${gravityTEMPfile}" <<< "${copyGravity}"; } 2>&1 )
|
||||
status="$?"
|
||||
|
||||
if [[ "${status}" -ne 0 ]]; then
|
||||
echo -e "\\n ${CROSS} Unable to copy data from ${gravityDBfile} to ${gravityTEMPfile}\\n ${output}"
|
||||
return 1
|
||||
fi
|
||||
echo -e "${OVER} ${TICK} ${str}"
|
||||
|
||||
# Use compression to reduce the amount of data that is transferred
|
||||
# between the Pi-hole and the ad list provider. Use this feature
|
||||
@@ -440,15 +457,6 @@ gravity_DownloadBlocklists() {
|
||||
saveLocation="${piholeDir}/list.${id}.${domain}.${domainsExtension}"
|
||||
activeDomains[$i]="${saveLocation}"
|
||||
|
||||
# Default user-agent (for Cloudflare's Browser Integrity Check: https://support.cloudflare.com/hc/en-us/articles/200170086-What-does-the-Browser-Integrity-Check-do-)
|
||||
agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36"
|
||||
|
||||
# Provide special commands for blocklists which may need them
|
||||
case "${domain}" in
|
||||
"pgl.yoyo.org") cmd_ext="-d mimetype=plaintext -d hostformat=hosts";;
|
||||
*) cmd_ext="";;
|
||||
esac
|
||||
|
||||
echo -e " ${INFO} Target: ${url}"
|
||||
local regex check_url
|
||||
# Check for characters NOT allowed in URLs
|
||||
@@ -461,103 +469,14 @@ gravity_DownloadBlocklists() {
|
||||
if [[ "${check_url}" =~ ${regex} ]]; then
|
||||
echo -e " ${CROSS} Invalid Target"
|
||||
else
|
||||
gravity_DownloadBlocklistFromUrl "${url}" "${cmd_ext}" "${agent}" "${sourceIDs[$i]}" "${saveLocation}" "${target}" "${compression}"
|
||||
gravity_DownloadBlocklistFromUrl "${url}" "${sourceIDs[$i]}" "${saveLocation}" "${target}" "${compression}"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
str="Creating new gravity databases"
|
||||
echo -ne " ${INFO} ${str}..."
|
||||
|
||||
# Gravity copying SQL script
|
||||
copyGravity="$(cat "${gravityDBcopy}")"
|
||||
if [[ "${gravityDBfile}" != "${gravityDBfile_default}" ]]; then
|
||||
# Replace default gravity script location by custom location
|
||||
copyGravity="${copyGravity//"${gravityDBfile_default}"/"${gravityDBfile}"}"
|
||||
fi
|
||||
|
||||
output=$( { pihole-FTL sqlite3 "${gravityTEMPfile}" <<< "${copyGravity}"; } 2>&1 )
|
||||
status="$?"
|
||||
|
||||
if [[ "${status}" -ne 0 ]]; then
|
||||
echo -e "\\n ${CROSS} Unable to copy data from ${gravityDBfile} to ${gravityTEMPfile}\\n ${output}"
|
||||
return 1
|
||||
fi
|
||||
echo -e "${OVER} ${TICK} ${str}"
|
||||
|
||||
str="Storing downloaded domains in new gravity database"
|
||||
echo -ne " ${INFO} ${str}..."
|
||||
output=$( { printf ".timeout 30000\\n.mode csv\\n.import \"%s\" gravity\\n" "${target}" | pihole-FTL sqlite3 "${gravityTEMPfile}"; } 2>&1 )
|
||||
status="$?"
|
||||
|
||||
if [[ "${status}" -ne 0 ]]; then
|
||||
echo -e "\\n ${CROSS} Unable to fill gravity table in database ${gravityTEMPfile}\\n ${output}"
|
||||
gravity_Cleanup "error"
|
||||
else
|
||||
echo -e "${OVER} ${TICK} ${str}"
|
||||
fi
|
||||
|
||||
if [[ "${status}" -eq 0 && -n "${output}" ]]; then
|
||||
echo -e " Encountered non-critical SQL warnings. Please check the suitability of the lists you're using!\\n\\n SQL warnings:"
|
||||
local warning file line lineno
|
||||
while IFS= read -r line; do
|
||||
echo " - ${line}"
|
||||
warning="$(grep -oh "^[^:]*:[0-9]*" <<< "${line}")"
|
||||
file="${warning%:*}"
|
||||
lineno="${warning#*:}"
|
||||
if [[ -n "${file}" && -n "${lineno}" ]]; then
|
||||
echo -n " Line contains: "
|
||||
awk "NR==${lineno}" < "${file}"
|
||||
fi
|
||||
done <<< "${output}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
rm "${target}" > /dev/null 2>&1 || \
|
||||
echo -e " ${CROSS} Unable to remove ${target}"
|
||||
|
||||
gravity_Blackbody=true
|
||||
}
|
||||
|
||||
# num_target_lines does increase for every correctly added domain in pareseList()
|
||||
num_target_lines=0
|
||||
num_source_lines=0
|
||||
num_invalid=0
|
||||
parseList() {
|
||||
local adlistID="${1}" src="${2}" target="${3}" incorrect_lines
|
||||
# This sed does the following things:
|
||||
# 1. Remove all domains containing invalid characters. Valid are: a-z, A-Z, 0-9, dot (.), minus (-), underscore (_)
|
||||
# 2. Append ,adlistID to every line
|
||||
# 3. Remove trailing period (see https://github.com/pi-hole/pi-hole/issues/4701)
|
||||
# 4. Ensures there is a newline on the last line
|
||||
sed -e "/[^a-zA-Z0-9.\_-]/d;s/\.$//;s/$/,${adlistID}/;/.$/a\\" "${src}" >> "${target}"
|
||||
# Find (up to) five domains containing invalid characters (see above)
|
||||
incorrect_lines="$(sed -e "/[^a-zA-Z0-9.\_-]/!d" "${src}" | head -n 5)"
|
||||
|
||||
local num_target_lines_new num_correct_lines
|
||||
# Get number of lines in source file
|
||||
num_source_lines="$(grep -c "^" "${src}")"
|
||||
# Get the new number of lines in destination file
|
||||
num_target_lines_new="$(grep -c "^" "${target}")"
|
||||
# Number of new correctly added lines
|
||||
num_correct_lines="$(( num_target_lines_new-num_target_lines ))"
|
||||
# Update number of lines in target file
|
||||
num_target_lines="$num_target_lines_new"
|
||||
num_invalid="$(( num_source_lines-num_correct_lines ))"
|
||||
if [[ "${num_invalid}" -eq 0 ]]; then
|
||||
echo " ${INFO} Analyzed ${num_source_lines} domains"
|
||||
else
|
||||
echo " ${INFO} Analyzed ${num_source_lines} domains, ${num_invalid} domains invalid!"
|
||||
fi
|
||||
|
||||
# Display sample of invalid lines if we found some
|
||||
if [[ -n "${incorrect_lines}" ]]; then
|
||||
echo " Sample of invalid domains:"
|
||||
while IFS= read -r line; do
|
||||
echo " - ${line}"
|
||||
done <<< "${incorrect_lines}"
|
||||
fi
|
||||
}
|
||||
compareLists() {
|
||||
local adlistID="${1}" target="${2}"
|
||||
|
||||
@@ -568,7 +487,6 @@ compareLists() {
|
||||
sha1sum "${target}" > "${target}.sha1"
|
||||
echo " ${INFO} List has been updated"
|
||||
database_adlist_status "${adlistID}" "1"
|
||||
database_adlist_updated "${adlistID}"
|
||||
else
|
||||
echo " ${INFO} List stayed unchanged"
|
||||
database_adlist_status "${adlistID}" "2"
|
||||
@@ -578,17 +496,18 @@ compareLists() {
|
||||
sha1sum "${target}" > "${target}.sha1"
|
||||
# We assume here it was changed upstream
|
||||
database_adlist_status "${adlistID}" "1"
|
||||
database_adlist_updated "${adlistID}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Download specified URL and perform checks on HTTP status and file content
|
||||
gravity_DownloadBlocklistFromUrl() {
|
||||
local url="${1}" cmd_ext="${2}" agent="${3}" adlistID="${4}" saveLocation="${5}" target="${6}" compression="${7}"
|
||||
local heisenbergCompensator="" patternBuffer str httpCode success="" ip
|
||||
local url="${1}" adlistID="${2}" saveLocation="${3}" target="${4}" compression="${5}"
|
||||
local heisenbergCompensator="" listCurlBuffer str httpCode success="" ip cmd_ext
|
||||
|
||||
# Create temp file to store content on disk instead of RAM
|
||||
patternBuffer=$(mktemp -p "/tmp" --suffix=".phgpb")
|
||||
# We don't use '--suffix' here because not all implementations of mktemp support it, e.g. on Alpine
|
||||
listCurlBuffer="$(mktemp -p "${GRAVITY_TMPDIR}")"
|
||||
mv "${listCurlBuffer}" "${listCurlBuffer%.*}.phgpb"
|
||||
|
||||
# Determine if $saveLocation has read permission
|
||||
if [[ -r "${saveLocation}" && $url != "file"* ]]; then
|
||||
@@ -638,16 +557,16 @@ gravity_DownloadBlocklistFromUrl() {
|
||||
bad_list=$(pihole -q -adlist "${domain}" | head -n1 | awk -F 'Match found in ' '{print $2}')
|
||||
echo -e "${OVER} ${CROSS} ${str} ${domain} is blocked by ${bad_list%:}. Using DNS on ${PIHOLE_DNS_1} to download ${url}";
|
||||
echo -ne " ${INFO} ${str} Pending..."
|
||||
cmd_ext="--resolve $domain:$port:$ip $cmd_ext"
|
||||
cmd_ext="--resolve $domain:$port:$ip"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
httpCode=$(curl --connect-timeout ${curl_connect_timeout} -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}" "${url}" -o "${listCurlBuffer}" 2> /dev/null)
|
||||
|
||||
case $url in
|
||||
# Did we "download" a local file?
|
||||
"file"*)
|
||||
if [[ -s "${patternBuffer}" ]]; then
|
||||
if [[ -s "${listCurlBuffer}" ]]; then
|
||||
echo -e "${OVER} ${TICK} ${str} Retrieval successful"; success=true
|
||||
else
|
||||
echo -e "${OVER} ${CROSS} ${str} Not found / empty list"
|
||||
@@ -676,24 +595,22 @@ gravity_DownloadBlocklistFromUrl() {
|
||||
if [[ "${success}" == true ]]; then
|
||||
if [[ "${httpCode}" == "304" ]]; then
|
||||
# Add domains to database table file
|
||||
parseList "${adlistID}" "${saveLocation}" "${target}"
|
||||
pihole-FTL gravity parseList "${saveLocation}" "${gravityTEMPfile}" "${adlistID}"
|
||||
database_adlist_status "${adlistID}" "2"
|
||||
database_adlist_number "${adlistID}"
|
||||
done="true"
|
||||
# Check if $patternbuffer is a non-zero length file
|
||||
elif [[ -s "${patternBuffer}" ]]; then
|
||||
# Check if $listCurlBuffer is a non-zero length file
|
||||
elif [[ -s "${listCurlBuffer}" ]]; then
|
||||
# Determine if blocklist is non-standard and parse as appropriate
|
||||
gravity_ParseFileIntoDomains "${patternBuffer}" "${saveLocation}"
|
||||
gravity_ParseFileIntoDomains "${listCurlBuffer}" "${saveLocation}"
|
||||
# Remove curl buffer file after its use
|
||||
rm "${listCurlBuffer}"
|
||||
# Add domains to database table file
|
||||
parseList "${adlistID}" "${saveLocation}" "${target}"
|
||||
pihole-FTL gravity parseList "${saveLocation}" "${gravityTEMPfile}" "${adlistID}"
|
||||
# Compare lists, are they identical?
|
||||
compareLists "${adlistID}" "${saveLocation}"
|
||||
# Update gravity database table (status and updated timestamp are set in
|
||||
# compareLists)
|
||||
database_adlist_number "${adlistID}"
|
||||
done="true"
|
||||
else
|
||||
# Fall back to previously cached list if $patternBuffer is empty
|
||||
# Fall back to previously cached list if $listCurlBuffer is empty
|
||||
echo -e " ${INFO} Received empty file"
|
||||
fi
|
||||
fi
|
||||
@@ -704,15 +621,12 @@ gravity_DownloadBlocklistFromUrl() {
|
||||
if [[ -r "${saveLocation}" ]]; then
|
||||
echo -e " ${CROSS} List download failed: ${COL_LIGHT_GREEN}using previously cached list${COL_NC}"
|
||||
# Add domains to database table file
|
||||
parseList "${adlistID}" "${saveLocation}" "${target}"
|
||||
database_adlist_number "${adlistID}"
|
||||
pihole-FTL gravity parseList "${saveLocation}" "${gravityTEMPfile}" "${adlistID}"
|
||||
database_adlist_status "${adlistID}" "3"
|
||||
else
|
||||
echo -e " ${CROSS} List download failed: ${COL_LIGHT_RED}no cached list available${COL_NC}"
|
||||
# Manually reset these two numbers because we do not call parseList here
|
||||
num_source_lines=0
|
||||
num_invalid=0
|
||||
database_adlist_number "${adlistID}"
|
||||
database_adlist_number "${adlistID}" 0 0
|
||||
database_adlist_status "${adlistID}" "4"
|
||||
fi
|
||||
fi
|
||||
@@ -720,72 +634,33 @@ 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
|
||||
# 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) Convert all characters to lowercase
|
||||
tr '[:upper:]' '[:lower:]' < "${src}" > "${destination}"
|
||||
|
||||
# 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}"
|
||||
# 2) Remove carriage returns
|
||||
# 3) Remove lines starting with ! (ABP Comments)
|
||||
# 4) Remove lines starting with [ (ABP Header)
|
||||
# 5) Remove lines containing ABP extended CSS selectors ("##", "#!#", "#@#", "#?#") preceded by a letter
|
||||
# 6) Remove comments (text starting with "#", include possible spaces before the hash sign)
|
||||
# 7) Remove leading tabs, spaces, etc. (Also removes leading IP addresses)
|
||||
# 8) Remove empty lines
|
||||
|
||||
# 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"
|
||||
sed -i -r \
|
||||
-e 's/\r$//' \
|
||||
-e 's/\s*!.*//g' \
|
||||
-e 's/\s*\[.*//g' \
|
||||
-e '/[a-z]\#[$?@]{0,1}\#/d' \
|
||||
-e 's/\s*#.*//g' \
|
||||
-e 's/^.*\s+//g' \
|
||||
-e '/^$/d' "${destination}"
|
||||
|
||||
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
|
||||
chmod 644 "${destination}"
|
||||
}
|
||||
|
||||
# Report number of entries in a table
|
||||
@@ -794,9 +669,9 @@ gravity_Table_Count() {
|
||||
local str="${2}"
|
||||
local num
|
||||
num="$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT COUNT(*) FROM ${table};")"
|
||||
if [[ "${table}" == "vw_gravity" ]]; then
|
||||
if [[ "${table}" == "gravity" ]]; then
|
||||
local unique
|
||||
unique="$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT COUNT(DISTINCT domain) FROM ${table};")"
|
||||
unique="$(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT COUNT(*) FROM (SELECT DISTINCT domain FROM ${table});")"
|
||||
echo -e " ${INFO} Number of ${str}: ${num} (${COL_BOLD}${unique} unique domains${COL_NC})"
|
||||
pihole-FTL sqlite3 "${gravityDBfile}" "INSERT OR REPLACE INTO info (property,value) VALUES ('gravity_count',${unique});"
|
||||
else
|
||||
@@ -806,7 +681,9 @@ gravity_Table_Count() {
|
||||
|
||||
# Output count of blacklisted domains and regex filters
|
||||
gravity_ShowCount() {
|
||||
gravity_Table_Count "vw_gravity" "gravity domains" ""
|
||||
# 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.
|
||||
gravity_Table_Count "gravity" "gravity domains" ""
|
||||
gravity_Table_Count "vw_blacklist" "exact blacklisted domains"
|
||||
gravity_Table_Count "vw_regex_blacklist" "regex blacklist filters"
|
||||
gravity_Table_Count "vw_whitelist" "exact whitelisted domains"
|
||||
@@ -840,7 +717,10 @@ gravity_Cleanup() {
|
||||
# Delete tmp content generated by Gravity
|
||||
rm ${piholeDir}/pihole.*.txt 2> /dev/null
|
||||
rm ${piholeDir}/*.tmp 2> /dev/null
|
||||
rm /tmp/*.phgpb 2> /dev/null
|
||||
# listCurlBuffer location
|
||||
rm "${GRAVITY_TMPDIR}"/*.phgpb 2> /dev/null
|
||||
# invalid_domains location
|
||||
rm "${GRAVITY_TMPDIR}"/*.ph-non-domains 2> /dev/null
|
||||
|
||||
# Ensure this function only runs when gravity_SetDownloadOptions() has completed
|
||||
if [[ "${gravity_Blackbody:-}" == true ]]; then
|
||||
@@ -1003,7 +883,10 @@ if ! gravity_CheckDNSResolutionAvailable; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gravity_DownloadBlocklists
|
||||
if ! gravity_DownloadBlocklists; then
|
||||
echo -e " ${CROSS} Unable to create gravity database. Please try again later. If the problem persists, please contact support."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create local.list
|
||||
gravity_generateLocalList
|
||||
|
||||
@@ -23,7 +23,7 @@ Pi-hole : A black-hole for internet advertisements
|
||||
.br
|
||||
pihole -r
|
||||
.br
|
||||
pihole -t
|
||||
\fBpihole\fR \fB-t\fR [arg]
|
||||
.br
|
||||
pihole -g\fR
|
||||
.br
|
||||
@@ -113,11 +113,15 @@ Available commands and options:
|
||||
Reconfigure or Repair Pi-hole subsystems
|
||||
.br
|
||||
|
||||
\fB-t, tail\fR
|
||||
\fB-t, tail\fR [arg]
|
||||
.br
|
||||
View the live output of the Pi-hole log
|
||||
.br
|
||||
|
||||
[arg] Optional argument to filter the log for
|
||||
(regular expressions are supported)
|
||||
.br
|
||||
|
||||
\fB-a, admin\fR [options]
|
||||
.br
|
||||
|
||||
@@ -208,7 +212,7 @@ Available commands and options:
|
||||
.br
|
||||
-p, --pihole Only retrieve info regarding Pi-hole repository
|
||||
.br
|
||||
-a, --admin Only retrieve info regarding AdminLTE
|
||||
-a, --admin Only retrieve info regarding web
|
||||
repository
|
||||
.br
|
||||
-f, --ftl Only retrieve info regarding FTL repository
|
||||
@@ -335,7 +339,7 @@ Displaying version information
|
||||
|
||||
\fBpihole -v -a -c\fR
|
||||
.br
|
||||
Display the current version of AdminLTE
|
||||
Display the current version of web
|
||||
.br
|
||||
|
||||
Temporarily disabling Pi-hole
|
||||
|
||||
41
pihole
41
pihole
@@ -23,6 +23,14 @@ source "${colfile}"
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
source "${utilsfile}"
|
||||
|
||||
versionsfile="/etc/pihole/versions"
|
||||
if [ -f "${versionsfile}" ]; then
|
||||
# Only source versionsfile if the file exits
|
||||
# fixes a warning during installation where versionsfile does not exist yet
|
||||
# but gravity calls `pihole -status` and thereby sourcing the file
|
||||
source "${versionsfile}"
|
||||
fi
|
||||
|
||||
webpageFunc() {
|
||||
source "${PI_HOLE_SCRIPT_DIR}/webpage.sh"
|
||||
main "$@"
|
||||
@@ -63,14 +71,22 @@ arpFunc() {
|
||||
}
|
||||
|
||||
updatePiholeFunc() {
|
||||
shift
|
||||
"${PI_HOLE_SCRIPT_DIR}"/update.sh "$@"
|
||||
exit 0
|
||||
if [ -n "${DOCKER_VERSION}" ]; then
|
||||
unsupportedFunc
|
||||
else
|
||||
shift
|
||||
"${PI_HOLE_SCRIPT_DIR}"/update.sh "$@"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
reconfigurePiholeFunc() {
|
||||
/etc/.pihole/automated\ install/basic-install.sh --reconfigure
|
||||
exit 0;
|
||||
if [ -n "${DOCKER_VERSION}" ]; then
|
||||
unsupportedFunc
|
||||
else
|
||||
/etc/.pihole/automated\ install/basic-install.sh --reconfigure
|
||||
exit 0;
|
||||
fi
|
||||
}
|
||||
|
||||
updateGravityFunc() {
|
||||
@@ -91,8 +107,12 @@ chronometerFunc() {
|
||||
|
||||
|
||||
uninstallFunc() {
|
||||
"${PI_HOLE_SCRIPT_DIR}"/uninstall.sh
|
||||
exit 0
|
||||
if [ -n "${DOCKER_VERSION}" ]; then
|
||||
unsupportedFunc
|
||||
else
|
||||
"${PI_HOLE_SCRIPT_DIR}"/uninstall.sh
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
versionFunc() {
|
||||
@@ -429,6 +449,11 @@ updateCheckFunc() {
|
||||
exit 0
|
||||
}
|
||||
|
||||
unsupportedFunc(){
|
||||
echo "Function not supported in Docker images"
|
||||
exit 0
|
||||
}
|
||||
|
||||
helpFunc() {
|
||||
echo "Usage: pihole [options]
|
||||
Example: 'pihole -w -h'
|
||||
@@ -553,7 +578,7 @@ case "${1}" in
|
||||
"restartdns" ) restartDNS "$2";;
|
||||
"-a" | "admin" ) webpageFunc "$@";;
|
||||
"checkout" ) piholeCheckoutFunc "$@";;
|
||||
"updatechecker" ) updateCheckFunc "$@";;
|
||||
"updatechecker" ) shift; updateCheckFunc "$@";;
|
||||
"arpflush" ) arpFunc "$@";;
|
||||
"-t" | "tail" ) tailFunc "$2";;
|
||||
esac
|
||||
|
||||
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 && \
|
||||
17
test/_debian_12.Dockerfile
Normal file
17
test/_debian_12.Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
FROM buildpack-deps:bookworm-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 $SCRIPTDIR/
|
||||
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
|
||||
|
||||
RUN true && \
|
||||
chmod +x $SCRIPTDIR/*
|
||||
|
||||
ENV SKIP_INSTALL true
|
||||
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
|
||||
|
||||
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM fedora:35
|
||||
FROM fedora:37
|
||||
RUN dnf install -y git initscripts
|
||||
|
||||
ENV GITDIR /etc/.pihole
|
||||
18
test/_fedora_38.Dockerfile
Normal file
18
test/_fedora_38.Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM fedora:38
|
||||
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 && \
|
||||
18
test/_ubuntu_23.Dockerfile
Normal file
18
test/_ubuntu_23.Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM buildpack-deps:lunar-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 $SCRIPTDIR/
|
||||
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
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,6 @@
|
||||
docker-compose
|
||||
pytest
|
||||
pytest-xdist
|
||||
pytest-testinfra
|
||||
tox
|
||||
pyyaml == 6.0.1
|
||||
pytest == 7.4.2
|
||||
pytest-xdist == 3.3.1
|
||||
pytest-testinfra == 9.0.0
|
||||
tox == 4.11.3
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ def test_setupVars_are_sourced_to_global_scope(host):
|
||||
|
||||
def test_setupVars_saved_to_file(host):
|
||||
"""
|
||||
confirm saved settings are written to a file for future updates to re-use
|
||||
confirm saved settings are written to a file for future updates to reuse
|
||||
"""
|
||||
# dedent works better with this and padding matching script below
|
||||
set_setup_vars = "\n"
|
||||
@@ -129,34 +129,16 @@ def test_installPiholeWeb_fresh_install_no_errors(host):
|
||||
installPiholeWeb
|
||||
"""
|
||||
)
|
||||
expected_stdout = info_box + " Installing 404 page..."
|
||||
assert expected_stdout in installWeb.stdout
|
||||
expected_stdout = tick_box + (
|
||||
" Creating directory for 404 page, " "and copying files"
|
||||
)
|
||||
assert expected_stdout in installWeb.stdout
|
||||
expected_stdout = info_box + " Backing up index.lighttpd.html"
|
||||
assert expected_stdout in installWeb.stdout
|
||||
expected_stdout = "No default index.lighttpd.html file found... " "not backing up"
|
||||
assert expected_stdout in installWeb.stdout
|
||||
expected_stdout = tick_box + " Installing sudoer file"
|
||||
assert expected_stdout in installWeb.stdout
|
||||
web_directory = host.run("ls -r /var/www/html/pihole").stdout
|
||||
assert "index.php" in web_directory
|
||||
|
||||
|
||||
def get_directories_recursive(host, directory):
|
||||
if directory is None:
|
||||
return directory
|
||||
ls = host.run("ls -d {}".format(directory + "/*/"))
|
||||
directories = list(filter(bool, ls.stdout.splitlines()))
|
||||
dirs = directories
|
||||
for dirval in directories:
|
||||
dir_rec = get_directories_recursive(host, dirval)
|
||||
if isinstance(dir_rec, str):
|
||||
dirs.extend([dir_rec])
|
||||
else:
|
||||
dirs.extend(dir_rec)
|
||||
# returns all non-hidden subdirs of 'directory'
|
||||
dirs_raw = host.run("find {} -type d -not -path '*/.*'".format(directory))
|
||||
dirs = list(filter(bool, dirs_raw.stdout.splitlines()))
|
||||
return dirs
|
||||
|
||||
|
||||
@@ -211,6 +193,8 @@ def test_installPihole_fresh_install_readableFiles(host):
|
||||
maninstalled = True
|
||||
if (info_box + " man not installed") in install.stdout:
|
||||
maninstalled = False
|
||||
if (info_box + " man pages not installed") in install.stdout:
|
||||
maninstalled = False
|
||||
piholeuser = "pihole"
|
||||
exit_status_success = 0
|
||||
test_cmd = 'su --shell /bin/bash --command "test -{0} {1}" -p {2}'
|
||||
@@ -287,6 +271,24 @@ def test_installPihole_fresh_install_readableFiles(host):
|
||||
check_lighttpd = test_cmd.format("r", "/etc/lighttpd/lighttpd.conf", piholeuser)
|
||||
actual_rc = host.run(check_lighttpd).rc
|
||||
assert exit_status_success == actual_rc
|
||||
# check readable /etc/lighttpd/conf*/pihole-admin.conf
|
||||
check_lighttpd = test_cmd.format("r", "/etc/lighttpd/conf.d", piholeuser)
|
||||
if host.run(check_lighttpd).rc == exit_status_success:
|
||||
check_lighttpd = test_cmd.format(
|
||||
"r", "/etc/lighttpd/conf.d/pihole-admin.conf", piholeuser
|
||||
)
|
||||
actual_rc = host.run(check_lighttpd).rc
|
||||
assert exit_status_success == actual_rc
|
||||
else:
|
||||
check_lighttpd = test_cmd.format(
|
||||
"r", "/etc/lighttpd/conf-available", piholeuser
|
||||
)
|
||||
if host.run(check_lighttpd).rc == exit_status_success:
|
||||
check_lighttpd = test_cmd.format(
|
||||
"r", "/etc/lighttpd/conf-available/15-pihole-admin.conf", piholeuser
|
||||
)
|
||||
actual_rc = host.run(check_lighttpd).rc
|
||||
assert exit_status_success == actual_rc
|
||||
# check readable and executable manpages
|
||||
if maninstalled is True:
|
||||
check_man = test_cmd.format("x", "/usr/local/share/man", piholeuser)
|
||||
@@ -396,7 +398,7 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage):
|
||||
usergroup="${{LIGHTTPD_USER}}:${{LIGHTTPD_GROUP}}",
|
||||
chmodarg="{{}}",
|
||||
config="/etc/lighttpd/lighttpd.conf",
|
||||
run="/var/run/lighttpd",
|
||||
run="/run/lighttpd",
|
||||
cache="/var/cache/lighttpd",
|
||||
uploads="/var/cache/lighttpd/uploads",
|
||||
compress="/var/cache/lighttpd/compress",
|
||||
@@ -512,7 +514,7 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage):
|
||||
check_admin = test_cmd.format("x", webroot + "/admin", webuser)
|
||||
actual_rc = host.run(check_admin).rc
|
||||
assert exit_status_success == actual_rc
|
||||
directories = get_directories_recursive(host, webroot + "/admin/*/")
|
||||
directories = get_directories_recursive(host, webroot + "/admin/")
|
||||
for directory in directories:
|
||||
check_pihole = test_cmd.format("r", directory, webuser)
|
||||
actual_rc = host.run(check_pihole).rc
|
||||
@@ -536,16 +538,6 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage):
|
||||
return bool(m)
|
||||
|
||||
if installWebInterface is True:
|
||||
check_pihole = test_cmd.format("r", webroot + "/pihole", webuser)
|
||||
actual_rc = host.run(check_pihole).rc
|
||||
assert exit_status_success == actual_rc
|
||||
check_pihole = test_cmd.format("x", webroot + "/pihole", webuser)
|
||||
actual_rc = host.run(check_pihole).rc
|
||||
assert exit_status_success == actual_rc
|
||||
# check most important files in $webroot for read permission
|
||||
check_index = test_cmd.format("r", webroot + "/pihole/index.php", webuser)
|
||||
actual_rc = host.run(check_index).rc
|
||||
assert exit_status_success == actual_rc
|
||||
if test_webpage is True:
|
||||
# check webpage for unreadable files
|
||||
noPHPfopen = re.compile(
|
||||
@@ -619,10 +611,15 @@ def test_FTL_detect_aarch64_no_errors(host):
|
||||
"""
|
||||
# mock uname to return aarch64 platform
|
||||
mock_command("uname", {"-m": ("aarch64", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
# mock ldd to respond with aarch64 shared library
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-aarch64.so.1", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux-aarch64.so.1", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux-aarch64.so.1", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -647,10 +644,15 @@ def test_FTL_detect_armv4t_no_errors(host):
|
||||
"""
|
||||
# mock uname to return armv4t platform
|
||||
mock_command("uname", {"-m": ("armv4t", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
# mock ldd to respond with armv4t shared library
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -675,10 +677,15 @@ def test_FTL_detect_armv5te_no_errors(host):
|
||||
"""
|
||||
# mock uname to return armv5te platform
|
||||
mock_command("uname", {"-m": ("armv5te", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
# mock ldd to respond with ld-linux shared library
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -704,9 +711,14 @@ def test_FTL_detect_armv6l_no_errors(host):
|
||||
# mock uname to return armv6l platform
|
||||
mock_command("uname", {"-m": ("armv6l", "0")}, host)
|
||||
# mock ldd to respond with ld-linux-armhf shared library
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -734,9 +746,14 @@ def test_FTL_detect_armv7l_no_errors(host):
|
||||
# mock uname to return armv7l platform
|
||||
mock_command("uname", {"-m": ("armv7l", "0")}, host)
|
||||
# mock ldd to respond with ld-linux-armhf shared library
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -763,10 +780,15 @@ def test_FTL_detect_armv8a_no_errors(host):
|
||||
"""
|
||||
# mock uname to return armv8a platform
|
||||
mock_command("uname", {"-m": ("armv8a", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
# mock ldd to respond with ld-linux-armhf shared library
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -789,8 +811,6 @@ def test_FTL_detect_x86_64_no_errors(host):
|
||||
"""
|
||||
confirms only x86_64 package is downloaded for FTL engine
|
||||
"""
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -813,8 +833,6 @@ def test_FTL_detect_unknown_no_errors(host):
|
||||
"""confirms only generic package is downloaded for FTL engine"""
|
||||
# mock uname to return generic platform
|
||||
mock_command("uname", {"-m": ("mips", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -1133,3 +1151,30 @@ def test_package_manager_has_web_deps(host):
|
||||
|
||||
assert "No package" not in output.stdout
|
||||
assert output.rc == 0
|
||||
|
||||
|
||||
def test_webpage_sh_valid_domain(host):
|
||||
"""Confirms checkDomain function in webpage.sh works as expected"""
|
||||
check1 = host.run(
|
||||
"""
|
||||
source /opt/pihole/webpage.sh
|
||||
checkDomain "pi-hole.net"
|
||||
"""
|
||||
)
|
||||
check2 = host.run(
|
||||
"""
|
||||
source /opt/pihole/webpage.sh
|
||||
checkDomain "ab.pi-hole.net"
|
||||
"""
|
||||
)
|
||||
|
||||
check3 = host.run(
|
||||
"""
|
||||
source /opt/pihole/webpage.sh
|
||||
checkDomain "abc.pi-hole.net"
|
||||
"""
|
||||
)
|
||||
|
||||
assert "pi-hole.net" in check1.stdout
|
||||
assert "ab.pi-hole.net" in check2.stdout
|
||||
assert "abc.pi-hole.net" in check3.stdout
|
||||
|
||||
@@ -40,6 +40,26 @@ def test_key_addition_works(host):
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_key_addition_substr(host):
|
||||
"""Confirms addKey adds substring keys (no value) to a file"""
|
||||
host.run(
|
||||
"""
|
||||
source /opt/pihole/utils.sh
|
||||
addKey "./testoutput" "KEY_ONE"
|
||||
addKey "./testoutput" "KEY_O"
|
||||
addKey "./testoutput" "KEY_TWO"
|
||||
addKey "./testoutput" "Y_TWO"
|
||||
"""
|
||||
)
|
||||
output = host.run(
|
||||
"""
|
||||
cat ./testoutput
|
||||
"""
|
||||
)
|
||||
expected_stdout = "KEY_ONE\nKEY_O\nKEY_TWO\nY_TWO\n"
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_key_removal_works(host):
|
||||
"""Confirms removeKey removes a key or key/value pair"""
|
||||
host.run(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
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
|
||||
commands = docker buildx build --load --progress plain -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:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker buildx build --load --progress plain -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
|
||||
@@ -1,8 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _debian_10.Dockerfile -t pytest_pihole:test_container ../
|
||||
commands = docker buildx build --load --progress plain -f _debian_10.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _debian_11.Dockerfile -t pytest_pihole:test_container ../
|
||||
commands = docker buildx build --load --progress plain -f _debian_11.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
|
||||
8
test/tox.debian_12.ini
Normal file
8
test/tox.debian_12.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker buildx build --load --progress plain -f _debian_12.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
@@ -1,8 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _fedora_36.Dockerfile -t pytest_pihole:test_container ../
|
||||
commands = docker buildx build --load --progress plain -f _fedora_36.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_fedora_support.py
|
||||
|
||||
@@ -4,5 +4,5 @@ envlist = py3
|
||||
[testenv]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _fedora_35.Dockerfile -t pytest_pihole:test_container ../
|
||||
commands = docker buildx build --load --progress plain -f _fedora_37.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_38.ini
Normal file
8
test/tox.fedora_38.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker buildx build --load --progress plain -f _fedora_38.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
|
||||
@@ -1,8 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _ubuntu_20.Dockerfile -t pytest_pihole:test_container ../
|
||||
commands = docker buildx build --load --progress plain -f _ubuntu_20.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _ubuntu_22.Dockerfile -t pytest_pihole:test_container ../
|
||||
commands = docker buildx build --load --progress plain -f _ubuntu_22.Dockerfile -t pytest_pihole:test_container ../
|
||||
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py
|
||||
|
||||
8
test/tox.ubuntu_23.ini
Normal file
8
test/tox.ubuntu_23.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker buildx build --load --progress plain -f _ubuntu_23.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