mirror of
https://github.com/soulis-1256/assemblrr.git
synced 2026-10-19 01:11:09 +00:00
Route Prowlarr indexer HTTP through Gluetun
Enable Gluetun's HTTP proxy and add it as a Prowlarr indexer proxy when VPN is on so searches leave via the tunnel, not the host ISP. Remove the managed proxy when VPN is off. Log the real Prowlarr error when an indexer can only be saved disabled, instead of always blaming FlareSolverr.
This commit is contained in:
parent
edac50f8a2
commit
881403b128
3 changed files with 133 additions and 6 deletions
|
|
@ -27,6 +27,8 @@ services:
|
|||
- PORT_FORWARD_ONLY=${PORT_FORWARD_ONLY:-off}
|
||||
- VPN_PORT_FORWARDING=${VPN_PORT_FORWARDING:-off}
|
||||
- FIREWALL_OUTBOUND_SUBNETS=172.60.0.0/24
|
||||
# Prowlarr indexer HTTP (see prowlarr_sync_gluetun_proxy). Off unless set.
|
||||
- HTTPPROXY=on
|
||||
- TZ=${TZ}
|
||||
healthcheck:
|
||||
test:
|
||||
|
|
|
|||
133
lib/arr.sh
133
lib/arr.sh
|
|
@ -2,7 +2,8 @@
|
|||
# assemblrr *arr service configuration — sourced by config.sh
|
||||
# Provides: set_arr_auth, qbit helpers, configure_arr_service, profile lookups,
|
||||
# configure_radarr, configure_sonarr, configure_prowlarr,
|
||||
# apply_selected_indexers, sync_selected_indexers
|
||||
# apply_selected_indexers, sync_selected_indexers,
|
||||
# prowlarr_sync_gluetun_proxy
|
||||
# Requires: lib/core.sh (logging), lib/api.sh (api_get/post/put/delete helpers),
|
||||
# config.sh (_cfg_log_info, log_step, log_step_fail, AUTH_USERNAME, etc.)
|
||||
|
||||
|
|
@ -1046,6 +1047,116 @@ wait_for_arr_indexer_sync() {
|
|||
return 1
|
||||
}
|
||||
|
||||
# Route Prowlarr indexer HTTP through Gluetun when VPN is on; remove it when off.
|
||||
# Empty tags = every indexer. Does not wrap Radarr/Sonarr app sync (LAN hostnames).
|
||||
# Manages only the proxy named below (or an existing Http proxy already on gluetun:8888).
|
||||
PROWLARR_GLUETUN_PROXY_NAME="assemblrr Gluetun"
|
||||
PROWLARR_GLUETUN_PROXY_HOST="gluetun"
|
||||
PROWLARR_GLUETUN_PROXY_PORT="8888"
|
||||
|
||||
# $2 = "name" (managed only) or "any" (name or host:port — avoid duplicates)
|
||||
_prowlarr_gluetun_proxy_id() {
|
||||
local proxies="$1"
|
||||
local mode="${2:-any}"
|
||||
echo "$proxies" | jq -r \
|
||||
--arg name "$PROWLARR_GLUETUN_PROXY_NAME" \
|
||||
--arg host "$PROWLARR_GLUETUN_PROXY_HOST" \
|
||||
--argjson port "$PROWLARR_GLUETUN_PROXY_PORT" \
|
||||
--arg mode "$mode" '
|
||||
.[] | select(
|
||||
.name == $name
|
||||
or (
|
||||
$mode == "any"
|
||||
and .implementation == "Http"
|
||||
and (([.fields[]? | select(.name == "host") | .value][0] // "") | tostring) == $host
|
||||
and (([.fields[]? | select(.name == "port") | .value][0] // 0) | tonumber) == $port
|
||||
)
|
||||
) | .id
|
||||
' 2>/dev/null | head -1
|
||||
}
|
||||
|
||||
_prowlarr_gluetun_proxy_payload() {
|
||||
local schema="$1"
|
||||
echo "$schema" | jq -c \
|
||||
--arg name "$PROWLARR_GLUETUN_PROXY_NAME" \
|
||||
--arg host "$PROWLARR_GLUETUN_PROXY_HOST" \
|
||||
--argjson port "$PROWLARR_GLUETUN_PROXY_PORT" '
|
||||
[.[] | select(.implementation == "Http")][0] |
|
||||
.fields = [.fields[] | if .name == "host" then .value = $host
|
||||
elif .name == "port" then .value = $port
|
||||
elif .name == "username" then .value = ""
|
||||
elif .name == "password" then .value = ""
|
||||
else . end] |
|
||||
.name = $name | .tags = []
|
||||
' 2>/dev/null || echo ""
|
||||
}
|
||||
|
||||
prowlarr_sync_gluetun_proxy() {
|
||||
local apikey="$1"
|
||||
local proxies existing_id
|
||||
|
||||
if [ -z "$apikey" ]; then
|
||||
log_step_fail "Prowlarr: missing API key — cannot sync Gluetun HTTP proxy"
|
||||
return 1
|
||||
fi
|
||||
|
||||
proxies=$(api_get "9696" "/api/v1/indexerProxy" "$apikey")
|
||||
if [ -z "$proxies" ]; then
|
||||
log_step_fail "Prowlarr: failed to list indexer proxies"
|
||||
return 1
|
||||
fi
|
||||
if ! qbit_vpn_enabled; then
|
||||
existing_id=$(_prowlarr_gluetun_proxy_id "$proxies" "name")
|
||||
if [ -z "$existing_id" ]; then
|
||||
log_step "Prowlarr: no Gluetun HTTP proxy (VPN off)"
|
||||
return 0
|
||||
fi
|
||||
local code
|
||||
code=$(api_delete "9696" "/api/v1/indexerProxy/${existing_id}" "$apikey")
|
||||
if [ "$code" = "200" ] || [ "$code" = "204" ]; then
|
||||
log_step "Prowlarr: removed Gluetun HTTP proxy (VPN off)"
|
||||
return 0
|
||||
fi
|
||||
log_step_fail "Prowlarr: failed to remove Gluetun HTTP proxy (HTTP ${code:-?})"
|
||||
return 1
|
||||
fi
|
||||
|
||||
existing_id=$(_prowlarr_gluetun_proxy_id "$proxies" "any")
|
||||
|
||||
local schema payload result
|
||||
schema=$(api_get "9696" "/api/v1/indexerProxy/schema" "$apikey")
|
||||
payload=$(_prowlarr_gluetun_proxy_payload "$schema")
|
||||
if [ -z "$payload" ]; then
|
||||
log_step_fail "Prowlarr: Http indexer-proxy schema not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -n "$existing_id" ]; then
|
||||
payload=$(echo "$payload" | jq -c --argjson id "$existing_id" '.id = $id' 2>/dev/null || echo "$payload")
|
||||
result=$(curl -s --connect-timeout 5 -X PUT \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$payload" \
|
||||
"http://${API_HOST}:9696/api/v1/indexerProxy/${existing_id}?apikey=${apikey}&forceSave=true" 2>/dev/null)
|
||||
if jq_json_has_key "$result" "id"; then
|
||||
log_step "Prowlarr: indexer traffic via Gluetun HTTP proxy"
|
||||
return 0
|
||||
fi
|
||||
log_step_fail "Prowlarr: failed to update Gluetun HTTP proxy"
|
||||
return 1
|
||||
fi
|
||||
|
||||
result=$(curl -s --connect-timeout 5 -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$payload" \
|
||||
"http://${API_HOST}:9696/api/v1/indexerProxy?apikey=${apikey}&forceSave=true" 2>/dev/null)
|
||||
if jq_json_has_key "$result" "id"; then
|
||||
log_step "Prowlarr: indexer traffic via Gluetun HTTP proxy"
|
||||
return 0
|
||||
fi
|
||||
log_step_fail "Prowlarr: failed to add Gluetun HTTP proxy"
|
||||
return 1
|
||||
}
|
||||
|
||||
# POST indexers named in SELECTED_INDEXERS into Prowlarr (skip existing).
|
||||
# Used by first-run wiring and `assemblrr config edit`.
|
||||
apply_selected_indexers() {
|
||||
|
|
@ -1097,14 +1208,19 @@ apply_selected_indexers() {
|
|||
if jq_json_has_key "$idx_result" "id"; then
|
||||
log_step "Prowlarr: added ${indexer_name} indexer"
|
||||
else
|
||||
local disabled_payload
|
||||
local err_msg disabled_payload
|
||||
err_msg=$(echo "$idx_result" | jq -r 'if type == "array" then .[0].errorMessage // empty else .errorMessage // empty end' 2>/dev/null || echo "")
|
||||
disabled_payload=$(echo "$indexer_payload" | jq -c '.enable = false' 2>/dev/null || echo "")
|
||||
idx_result=$(curl -s --connect-timeout 5 -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$disabled_payload" \
|
||||
"http://${API_HOST}:9696/api/v1/indexer?apikey=${apikey}&forceSave=true" 2>/dev/null)
|
||||
if jq_json_has_key "$idx_result" "id"; then
|
||||
log_step "Prowlarr: added ${indexer_name} indexer (disabled — needs FlareSolverr for Cloudflare)"
|
||||
if [ -n "$err_msg" ]; then
|
||||
log_step "Prowlarr: added ${indexer_name} indexer (disabled — ${err_msg})"
|
||||
else
|
||||
log_step "Prowlarr: added ${indexer_name} indexer (disabled — enabled save failed)"
|
||||
fi
|
||||
else
|
||||
log_step_fail "Prowlarr: failed to add ${indexer_name} indexer"
|
||||
fi
|
||||
|
|
@ -1223,15 +1339,20 @@ configure_prowlarr() {
|
|||
fi
|
||||
fi
|
||||
|
||||
# 2. Selected indexers (optional; can add later via `config edit`)
|
||||
# 2. Indexer HTTP via Gluetun when VPN is on (empty tags = all indexers)
|
||||
if ! prowlarr_sync_gluetun_proxy "$apikey"; then
|
||||
critical_errors=$((critical_errors + 1))
|
||||
fi
|
||||
|
||||
# 3. Selected indexers (optional; can add later via `config edit`)
|
||||
apply_selected_indexers "$apikey"
|
||||
|
||||
# 3) After fullSync, set min seeders on *arr indexers (best-effort)
|
||||
# 4) After fullSync, set min seeders on *arr indexers (best-effort)
|
||||
wait_for_arr_indexer_sync "$radarr_apikey" || true
|
||||
arr_set_indexer_min_seeders "Radarr" "7878" "$radarr_apikey" || true
|
||||
arr_set_indexer_min_seeders "Sonarr" "8989" "$sonarr_apikey" || true
|
||||
|
||||
# 4. Set authentication
|
||||
# 5. Set authentication
|
||||
if ! set_arr_auth "Prowlarr" "9696" "$apikey" "v1"; then
|
||||
critical_errors=$((critical_errors + 1))
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -450,6 +450,10 @@ _config_edit_vpn() {
|
|||
wait_for_api "Sonarr" "8989" "$SONARR_API_KEY" || true
|
||||
arr_update_qb_host "Sonarr" "8989" "$SONARR_API_KEY" || true
|
||||
fi
|
||||
if [ -n "${PROWLARR_API_KEY:-}" ]; then
|
||||
wait_for_api "Prowlarr" "9696" "$PROWLARR_API_KEY" "/api/v1/system/status" || true
|
||||
prowlarr_sync_gluetun_proxy "$PROWLARR_API_KEY" || true
|
||||
fi
|
||||
}
|
||||
|
||||
_config_edit_media() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue