Skip to content

DietPi-CloudShell: Add Pi-hole v6 REST API support for the Pi-hole scene - #8456

Merged
MichaIng merged 5 commits into
devfrom
copilot/dietpi-cloudshell-add-support-for-pihole-v6
Nov 1, 2026
Merged

MichaIng merged 5 commits into
devfrom
copilot/dietpi-cloudshell-add-support-for-pihole-v6

Conversation

Copilot AI commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Pi-hole v6 removed the FTL TCP socket API, so the Pi-hole scene only showed "Pi-hole v6 not supported yet". This change fetches the same stats from the new HTTP REST API, authenticating with /etc/pihole/cli_pw.

  • API access (v6 path in Obtain_PIHOLE)

    • Detects v6 via /etc/pihole/pihole.toml and takes the web port from its port entry, defaulting to 80.
    • Logs in with POST /api/auth using the cli_pw password, then reads GET /api/stats/summary. This gives total queries, blocked queries and blocked domains, and the percentage is computed as before.
    • Reads the last blocked domain from /api/queries?length=1&upstream=blocked, then closes the session with DELETE /api/auth.
    • JSON is parsed with sed, so there is no jq dependency.
    • Failed requests show "connection failed" and a rejected login shows "authentication failed", both as the first-line message.
    • The v5 socket path is unchanged.
  • cli_pw handling (new Pihole_CLI_Password)

    • Uses the file if it exists.
    • If it doesn't exist and the script runs as root, it writes a random 32-character password there (mode 0600, owned by pihole) and prints a notice.
    • If it doesn't exist and the script isn't root, the scene shows "Run dietpi-cloudshell as root once". There is no sudo fallback, so non-root runs need the file created by a root run first.
    • In menu mode, enabling the Pi-hole scene on a v6 install calls the helper, so the file is created at that point.
curl -sSf -m 3 -H 'Content-Type: application/json' -d '{"password":"…"}' http://127.0.0.1:80/api/auth   # → session.sid
curl -sSf -m 3 -H "sid: $sid" http://127.0.0.1:80/api/stats/summary

Review notes

  • Not yet exercised against a live Pi-hole v6 instance.
  • I'm unsure whether FTL accepts a password we write into cli_pw ourselves, or whether it expects to generate the file. If login fails after we create the file, that is the first thing to check.

@MichaIng MichaIng added this to the v10.9 milestone Oct 31, 2026
Copilot AI linked an issue Oct 31, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add support for Pi-hole v6 in DietPi-CloudShell DietPi-CloudShell: Add Pi-hole v6 REST API support for the Pi-hole scene Oct 31, 2026
Copilot AI requested a review from MichaIng October 31, 2026 19:15

@MichaIng MichaIng left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot
Please address my new code comments.

Comment thread dietpi/dietpi-cloudshell Resolved
Comment thread dietpi/dietpi-cloudshell Resolved
Comment thread dietpi/dietpi-cloudshell Resolved
Comment thread dietpi/dietpi-cloudshell Resolved
Copilot AI requested a review from MichaIng October 31, 2026 20:18
@MichaIng
MichaIng marked this pull request as ready for review October 31, 2026 20:54
Copilot AI and others added 3 commits November 1, 2026 00:59
Co-authored-by: MichaIng <28480705+MichaIng@users.noreply.github.com>
Co-authored-by: MichaIng <28480705+MichaIng@users.noreply.github.com>
@MichaIng
MichaIng force-pushed the copilot/dietpi-cloudshell-add-support-for-pihole-v6 branch 2 times, most recently from cb2d5a5 to 61cd45d Compare November 1, 2026 00:07
@MichaIng
MichaIng force-pushed the copilot/dietpi-cloudshell-add-support-for-pihole-v6 branch from 61cd45d to e9dc6a8 Compare November 1, 2026 00:09
@MichaIng
MichaIng merged commit 07b3948 into dev Nov 1, 2026
4 checks passed
@MichaIng
MichaIng deleted the copilot/dietpi-cloudshell-add-support-for-pihole-v6 branch November 1, 2026 00:18
@Joulinar

Joulinar commented Nov 1, 2026

Copy link
Copy Markdown
Collaborator

Post-merge review + live test

Test setup: NanoPi Zero2 (DietPi on Trixie), Pi-hole FTL v6.8 installed via dietpi-software (webserver.port = 8089,8489s). I ran dietpi-cloudshell from current dev with only the Pi-hole scene enabled, driven in a pseudo terminal, and checked the API calls directly with curl.

The stats values (ads blocked, queries, blocked domains, percentage) are correct, and session reuse works, also across an FTL restart. Three issues, though:

1. Last blocked domain is always empty
upstream=blocked is not a pseudo upstream. FTL knows only blocklist, cache and permitted (src/api/queries.c); any other value is matched against f.forward. Result: HTTP 200 with "recordsFiltered":0, and an empty line in the scene. queries?length=1&upstream=blocklist works, and so does the dedicated endpoint, which returns {"blocked":["ladsup.com"],...}. I'd suggest the latter, since its response is much smaller:

Pihole_Request 'stats/recent_blocked?count=1' || return 1
PIHOLE_LAST_DOMAIN_BLOCKED=$(sed -n 's/.*"blocked":\["\([^"]*\)".*/\1/p' <<< "$PIHOLE_RESPONSE")

2. Cached password goes stale after an FTL restart
FTL regenerates /etc/pihole/cli_pw on every start. Sessions are restored across restarts by default (webserver.session.restore = true), so this doesn't hit right away. But once the session is lost later on, the re-auth after the 401 uses the old cached password and gets "password incorrect". That happens after 1800 s without requests, e.g. with the screen blanked overnight, or when session restore is disabled. From then on the scene shows "API authentication failed" until cloudshell is restarted. I reproduced this twice. Fix: don't cache the password. It's only read on the first auth and after a 401 anyway.

3. Creating cli_pw ourselves cannot work
FTL only accepts the password it generated itself and keeps in memory (verify_login() in src/config/password.c). Tested: a self-written file is rejected with webserver.api.cli_pw = false, and with cli_pw = true FTL replaces it on start. So Pihole_CLI_Password() and the menu hook can be removed. If the file is missing, webserver.api.cli_pw is disabled, so a hint like "/etc/pihole/cli_pw missing, webserver.api.cli_pw disabled?" would help the user more.

Minor

  • SID in the process list: the SID is a curl argument on every refresh, so every local user can see it with ps (caught with a ps loop). CLI sessions cannot change the config, but they can manage lists. It could go via stdin instead: curl -H @- ... <<< "sid: $PIHOLE_SID" (curl >= 7.55). The same works for the password with -d @-.
  • prettyJSON: webserver.api.prettyJSON = true breaks all the sed parsing (values end up empty or 0). Probably acceptable, just noting it.
  • Port parsing: it takes the first number of webserver.port. That's fine for the defaults and for DietPi's 8089,8489s, but e.g. HTTPS only (443s) or a redirect (80r,443s) would fail. Edge case.

I can open a follow-up PR for 1-3 if you like.

@MichaIng

MichaIng commented Nov 1, 2026

Copy link
Copy Markdown
Owner

All addressed in #8463.

  • The CLI password is passed via STDIN, and via --json option (which implies the content type).
  • Redirected ports and IPv6 ports are not supported yet. And if plain HTTP ports are listed after HTTPS ports, the prior are used. It would be better to loop through the comma-separated list, skip redirected r ports, take the first plain IPv4 port, if present, else first plain IPv6 port (adding another loopback IP variable our end), else first HTTPS IPv4, else first HTTPS IPv6. But I am too tired today, and IPv4 incl. HTTPS-only should cover 99.5% of cases.

Another point I wanted to check is whether the /padd endpoints provides all info at once, so that we can skip the 2nd API request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DietPi-CloudShell | Add support for Pi-hole v6

3 participants