From 0f89a3d53458bc5c45cd35d6b765ecc11760ebf0 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 3 Sep 2026 15:55:28 +0000 Subject: [PATCH] Fix manage.sh controllers: sudo needed for Wolf's root-owned API socket Confirmed live: a plain-user curl against /var/run/wolf/wolf.sock failed with "Immediate connect fail ... Permission denied". The socket is srwxr-xr-x root:root - Docker auto-creates the host-side /var/run/wolf bind-mount source as root, and Wolf itself runs as root in its container, so group/other never had write permission on the socket file (required to connect() to a unix socket, not just read/traverse it - `ls -la` on the containing dir working fine was a red herring). Fix: sudo on both curl calls, matching how every other root-owned Wolf state file ($WOLF_CFG) is already touched elsewhere in this script via `sudo python3 -`. Documents the sudo prompt in the README too. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6 --- services/wolf.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/services/wolf.sh b/services/wolf.sh index 0564a97..0540a7c 100644 --- a/services/wolf.sh +++ b/services/wolf.sh @@ -3331,6 +3331,16 @@ COMPEOF # "PATCH .../clients//settings", but the real, current endpoint # is "POST /api/v1/clients/settings" with client_id in the JSON # body, not the URL path. + # + # The socket is root-owned with mode 0755 (Docker auto-creates the + # host-side /var/run/wolf bind-mount source as root, and Wolf itself + # runs as root inside the container) — confirmed live: a plain user + # curl gets "Immediate connect fail ... Permission denied" (connecting + # to a UNIX socket needs write permission on the socket file itself, + # which group/other don't have here). sudo on both curl calls below + # is the fix, matching how every other root-owned Wolf state file + # ($WOLF_CFG) is already touched elsewhere in this same script (grep + # for "sudo python3 -"). SOCK="/var/run/wolf/wolf.sock" if [ ! -S "$SOCK" ]; then echo "Wolf's API socket isn't up at $SOCK yet." @@ -3338,7 +3348,7 @@ COMPEOF echo " docker compose up -d # recreates the wolf container so it takes effect" exit 1 fi - CLIENTS_JSON=$(curl -fsS --unix-socket "$SOCK" http://localhost/api/v1/clients 2>/dev/null) + CLIENTS_JSON=$(sudo curl -fsS --unix-socket "$SOCK" http://localhost/api/v1/clients 2>/dev/null) if [ -z "$CLIENTS_JSON" ]; then echo "Could not reach Wolf's API — is Wolf running? (./manage.sh status)" exit 1 @@ -3406,7 +3416,7 @@ print(json.dumps({"client_id": client_id, "app_state_folder": None, "settings": {"controllers_override": overrides}})) BODYPY ) - RESP=$(curl -fsS --unix-socket "$SOCK" -X POST http://localhost/api/v1/clients/settings \ + RESP=$(sudo curl -fsS --unix-socket "$SOCK" -X POST http://localhost/api/v1/clients/settings \ -H 'Content-Type: application/json' -d "$BODY") echo "$RESP" | python3 -c " import json, sys @@ -4036,6 +4046,12 @@ vendor/product IDs — and therefore their SDL GUIDs — genuinely differ: \`\`\`bash cd $WOLF_DIR && ./manage.sh controllers \`\`\` +May prompt for your \`sudo\` password — Wolf's API socket is root-owned +(Docker creates its \`/var/run/wolf\` bind-mount source as root, and Wolf +itself runs as root in its container), so the curl calls behind this +command need it, the same as every other command here that touches +Wolf's own root-owned state. + Picks your paired Moonlight client (auto-selected if there's only one), then asks how many controllers to configure and what type to force each one to. There are only **3 concrete types** (confirmed against Wolf's own