refactor(tools): modular per-app tools convention (containers/<app>/tools/) + migrate adguard

Establish the self-contained tools convention and prove it on a core app:
- discovery now reads containers/<app>/tools/<app>.tools.json (the tools/ subfolder);
  tool functions live at containers/<app>/tools/*.sh, auto-sourced by the container
  scan (depth 3) — no scripts/app/ entry, no array regen.
- adguard migrated: its 2 Tools-tab actions (reset_password, apply_dns_updater) moved
  to containers/adguard/tools/ + tools/adguard.tools.json, and dropped from the
  central webui_tools.sh heredoc. adguard_auth.sh stays in scripts/app/ — it's a logic
  helper, NOT a tool (the key distinction: only DECLARED tools move).

Central + per-app styles coexist (pihole etc. still central), so the remaining apps
can migrate one at a time with nothing breaking. Verified: heredoc valid sans adguard,
per-app merge re-adds adguard's 2 tools, scripts array dropped the moved fns.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
librelad 2026-05-25 22:30:49 +01:00
parent 7213322cf3
commit 3bc91eef55
5 changed files with 22 additions and 24 deletions

View File

@ -0,0 +1,20 @@
{
"tools": [
{
"id": "reset_password",
"label": "Reset Admin Password",
"description": "Reset the AdGuard Home admin password. Leave the field blank to generate a random one — the new password is saved to the config so you can see it after.",
"icon": "🔑",
"fields": [
{ "name": "password", "label": "New password (leave blank to generate)", "type": "password", "placeholder": "Leave blank for random" }
]
},
{
"id": "apply_dns_updater",
"label": "Apply DNS Updater",
"description": "Rewrite this server's /etc/resolv.conf to use AdGuard as its DNS resolver right now. Same action that runs automatically when the global DNS Updater requirement is enabled.",
"icon": "🌐",
"fields": []
}
]
}

View File

@ -10,9 +10,7 @@ app_scripts=(
"app/app_status.sh"
"app/app_update_specifics.sh"
"app/auth_adapter.sh"
"app/containers/adguard/adguard_apply_dns_updater.sh"
"app/containers/adguard/adguard_auth.sh"
"app/containers/adguard/adguard_reset_password.sh"
"app/containers/bookstack/bookstack_auth.sh"
"app/containers/bookstack/bookstack_create_account.sh"
"app/containers/bookstack/bookstack_delete_user.sh"

View File

@ -54,26 +54,6 @@ webuiGenerateAppsToolsConfig() {
cat > "$tmp" <<'JSON'
{
"apps": {
"adguard": {
"tools": [
{
"id": "reset_password",
"label": "Reset Admin Password",
"description": "Reset the AdGuard Home admin password. Leave the field blank to generate a random one — the new password is saved to the config so you can see it after.",
"icon": "🔑",
"fields": [
{ "name": "password", "label": "New password (leave blank to generate)", "type": "password", "placeholder": "Leave blank for random" }
]
},
{
"id": "apply_dns_updater",
"label": "Apply DNS Updater",
"description": "Rewrite this server's /etc/resolv.conf to use AdGuard as its DNS resolver right now. Same action that runs automatically when the global DNS Updater requirement is enabled.",
"icon": "🌐",
"fields": []
}
]
},
"pihole": {
"tools": [
{
@ -420,9 +400,9 @@ JSON
# it sets .apps[<app>]. Core apps declared in the heredoc need no such file.
if command -v jq >/dev/null 2>&1; then
local _tj _app
for _tj in "${install_containers_dir}"*/*.tools.json; do
for _tj in "${install_containers_dir}"*/tools/*.tools.json; do
[[ -f "$_tj" ]] || continue
_app="$(basename "$(dirname "$_tj")")"
_app="$(basename "$(dirname "$(dirname "$_tj")")")" # …/<app>/tools/<x>.tools.json
if jq -e . "$_tj" >/dev/null 2>&1; then
jq --arg app "$_app" --slurpfile t "$_tj" '.apps[$app] = $t[0]' "$tmp" > "$tmp.m" && mv "$tmp.m" "$tmp"
else