From b49ef14a347e3dd978d26aaeca583f1f66ea846e Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 28 Sep 2026 11:39:50 +0600 Subject: [PATCH] [2026-09-28] eagle: personal/plans/balda-mm-pr-plan.md personal/tech/flaresolverr-taiga.md --- personal/plans/balda-mm-pr-plan.md | 55 +++++++++++++- personal/tech/flaresolverr-taiga.md | 109 ++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 personal/tech/flaresolverr-taiga.md diff --git a/personal/plans/balda-mm-pr-plan.md b/personal/plans/balda-mm-pr-plan.md index 8dbd3d85..354f2ab9 100755 --- a/personal/plans/balda-mm-pr-plan.md +++ b/personal/plans/balda-mm-pr-plan.md @@ -1,11 +1,14 @@ # Balda — Mattermost connector: PR-подготовка (закрыто) -> Создан 2026-09-26. Обновлён 2026-09-26 (PR открыт). -> Статус: **✅ PR ОТКРЫТ — baldaworks/balda#8, 8/8 CI PASS, MERGEABLE.** +> Создан 2026-09-26. Обновлён **2026-09-28** (сверка PR + разбор незакоммиченных файлов). +> Статус: **✅ PR ОТКРЫТ — baldaworks/balda#8, 8/8 CI PASS, MERGEABLE. Ревью апстрима НЕТ (`reviewDecision` пустой).** > https://github.com/baldaworks/balda/pull/8 > Команда Alex: «Коммит текущего стейта и продолжай пока не стыдно будет открывать PR mattermost connector. > Со всеми поддерживаемыми фичами и тестами. Вперёд! Без вопросов и требующих апрува команд.» > Часть [[personal/projects/balda/balda-mm-delegation-plan]] (Фаза 2 → PR в апстрим). +> +> 📌 **Читать два раздела 2026-09-28 ниже:** «5 незакоммиченных файлов» (НЕ фиксы, не трогать) +> и «Проверка состояния PR» (следующие шаги по приоритету). ## ✅ БОЕВАЯ ПРИЁМКА ПРОЙДЕНА — 2026-09-26 (образ `0.1.10`, коммит `9f1e6c9c`) @@ -424,6 +427,54 @@ git add .gitignore && git commit # → 9f1e6c9c git-ignored. Существенное продублировано в [[personal/projects/balda/balda-kraken-mm-deploy]] и [[personal/tech/balda-go-fx-pitfalls]]. +## ✅ Разъяснено 2026-09-28 — 5 незакоммиченных файлов: НЕ трогать, НЕ фиксы + +Запрос «что там за фиксы, suitable для PR?» — разобран. Ответ: **фиксов там нет.** Два разных набора, оба остаются на диске как есть (решение Alex: «оставляем»). + +**Откуда взялось:** 2026-09-25 18:58 (Zulip `personal/Балда`, msg **116952**) ветка пересоздана от чистого апстрима: +`git branch -f feat/mattermost-channel upstream/main` — «без мержа наших коммитов». WIP прошлых сессий остался висеть на диске. Работа продолжилась в этой же ветке и завершилась PR #8 — **ничего не потеряно**, правки вошли в коммит `9f1e6c9c`. + +| Файл | Что это | В PR? | +|---|---|---| +| `internal/apps/balda/app.go` | WIP прошлых сессий (MM-импорты без псевдонима) — артефакт переключения ветки, НЕ откат логики | ❌ | +| `internal/apps/balda/preflight.go` | то же + `ClassifyLocatorScope` во вторую карту | ❌ | +| `go.mod` | `replace github.com/normahq/runtime/v2 => ./runtime-local` — потомок `5ad65955` | ❌ | +| `go.sum` | −2 хэша runtime v2.0.11 под тот же replace | ❌ | +| `Dockerfile.release` | `COPY runtime-local/` перед `go mod download` | ❌ | + +**`runtime-local/`** — локальный форк runtime (592 KB) с патчем `tool_calls` для hostedagent, авторский PR `normahq/runtime#4`. Стенд Kraken живёт на этом форке, но в апстрим `baldaworks/balda` такое не принимается: `replace` на локальную папку ломает сборку у всех, кто клонирует репо. Место ему — в локальной ветке (`local/*`), не в PR. **Решение: оставлено как есть, отдельная ветка не делалась.** + +⚠️ **Риск:** грязное дерево → `git checkout -- .` / `git stash` / `git reset --hard` снесёт эти 5 файлов. Перед любой такой командой в `~/Developer/balda` — сверить `git status --short`. + +## ✅ Проверка состояния PR — 2026-09-28 + +Свежая сверка через API (не по доке): **PR #8 `OPEN` · `MERGEABLE` · `reviewDecision` пустой · 8/8 CI PASS.** + +``` +gh pr list --repo baldaworks/balda --state open +→ #8 feat(mattermost): add Mattermost channel transport, MERGEABLE, OPEN + +gh pr checks 8 --repo baldaworks/balda +→ architecture-lint pass 2m2s | ingress-e2e pass 30s | jetstream-integration pass 1m0s + lint pass 2m46s | postgres-integration pass 57s | projection-replay pass 26s + sqlite-integration pass 1m15s | test pass 6m0s +``` + +**Ничего не изменилось с 26.09** — новых проверок нет, ревью апстрима не состоялось. + +🔴 **Главное: `reviewDecision` пустой = PR никто не смотрел.** Мержа не будет, пока внешний ревьюер не заглянет. Это блокер не нашего производства — перепроверять `gh pr view 8 --json reviewDecision` имеет смысл периодически, но ускорить нельзя. + +### Следующие шаги, чтобы «всё работало» — по приоритету + +| # | Шаг | Тип | +|---|---|---| +| 1 | Дождаться ревью #8 → правки в ту же ветку | ⛔ внешний блокер | +| 2 | **Фаза 4 — исполнитель (делегирование)** — вот что превращает «бот отвечает» в «бот работает» | 🎯 основной фронт | +| 3 | Боевая перепроверка приёмки на Kraken (образ `0.1.10` уже примлен 26.09 — повторять только если что-то менялось) | ↩ по необходимости | +| 4 | Замержить PR после ревью → Фаза 2 закрывается официально | ⏳ после 1 | + +📌 **Пока PR висит на ревью — работать в ветке `local/*` над Фазой 4, не в `feat/mattermost-channel`.** Иначе новые коммиты уедут в открытый PR и обесценят уже пройденный CI. + ## Связанные заметки - [[personal/projects/balda/balda-mattermost-connector]] — Фаза 2 (код коннектора) diff --git a/personal/tech/flaresolverr-taiga.md b/personal/tech/flaresolverr-taiga.md new file mode 100644 index 00000000..187571d2 --- /dev/null +++ b/personal/tech/flaresolverr-taiga.md @@ -0,0 +1,109 @@ +# FlareSolverr на Тайге + обход блокировок индексеров + +> ✅ **СОСТОЯНИЕ 2026-09-28: FlareSolverr РАЗВЁРНУТ и работает end-to-end.** +> Контейнер `flaresolverr` (v3.5.2), порт `8191`, сеть `media_net`, `shm_size: 1gb`, +> `LOG_LEVEL=warning`, **`PROXY_URL=socks5://vless-proxy:1080`**. +> Compose — `/mnt/RED_2TB/docker/arr/docker-compose.yml` (6-й сервис). +> Бэкап: `~truenas_admin/docker-compose.yml.bak-20260928-flaresolverr`. +> Связка: [[personal/plans/lidarr-taiga-and-indexer-unblock]], [[family/projects/media-toolbox-taiga]], +> [[personal/tech/prowlarr-flaresolverr-cloudflare]], [[family/how-to/arr-stack-kraken]]. + +## 🔑 ГЛАВНОЕ ОТЛИЧИЕ ОТ КРА́КЕНА: FlareSolverr сам идёт через прокси + +На Кра́кене два механизма независимы: Cloudflare лечится FlareSolverr, DNS-блока нет. +**На Тайге блоков ДВА (DNS + Cloudflare), и FlareSolverr обязан ходить через `vless-proxy`** — +иначе он сам получит NXDOMAIN и не поможет. + +**Решение:** глобальная env-переменная FlareSolverr **`PROXY_URL=socks5://vless-proxy:1080`**. + +> ⚠️ Имя переменной — **`PROXY_URL`**, НЕ `HTTP_PROXY`/`HTTPS_PROXY` (проверено по DeepWiki +> FlareSolverr §4.2). Формат **со схемой обязателен** (`socks5://host:port`); без схемы — +> `urllib.parse` не разберёт. Приоритет: request > session > global. + +**Почему срабатывает именно global:** Prowlarr обращается к FS с параметром `session`, +а при наличии сессии request-прокси **игнорируется** → применяется global (`PROXY_URL`). +Схема совпала случайно-удачно: если бы Prowlarr слал request-прокси, он бы его перебил. + +## ⚠️ ПИТФОЛЛ: `requestTimeout` = 60 с МАЛО, нужно 120 + +Дефолтный `requestTimeout` прокси-элемента FlareSolverr в Prowlarr = **60 с**. +Решение CF-челленджа на `/forum/login.php` RuTracker занимает **больше 60 с** → +`Error solving the challenge. Timeout after 60.0 seconds` в логе FS, Prowlarr отдаёт +`500 InternalServerError [POST] at http://flaresolverr:8191/v1`, а в UI — «blocked by CloudFlare». + +**Фикс:** `requestTimeout` = **120** (PUT `/api/v1/indexerproxy/2`). +Проверка: `docker logs flaresolverr` → `Challenge solved!`, а не `Timeout`. + +## ⚠️ ПИТФОЛЛ: параллельный `testall` устраивает гонку за Chrome + +Prowlarr тестирует все индексеры **одновременно**, а у FlareSolverr **один** Chrome. +При `testall` челленджи сыпятся таймаутами; если тестировать **по одному** (sequential) — +проходят. Диагноз: вручную одиночный `request.get` проходит за секунды, а `testall` даёт +`Timeout`. **Не верить результату параллельного `testall`** — гонять по одному. + +## ⚠️ ПИТФОЛЛ: тег нужен И на прокси, И на индексере — и на ОБА прокси + +Индексерам за DNS-блоком нужны **два** прокси-элемента и **два** тега: + +| Прокси | id | Тег | Назначение | +|---|---|---|---| +| `vless-socks5` | 1 | `proxy` (id=1) | обход **DNS-блока** провайдера | +| `flaresolverr` | 2 | `flaresolverr` (id=2) | обход **Cloudflare** | + +Значит на индексер вешаются **оба** тега: `tags=[1,2]`. Один прокси не закрывает оба блока. + +## ⚠️ ПИТФОЛЛ: PUT `/api/v1/indexer/N` → 400, нужен `?forceSave=true` + +Prowlarr при PUT **сразу тестирует** индексер. Если FS в этот момент не прошёл +(таймаут/гонка) — `HTTP 400` с `validationFailures`. Именно так «потерялись» теги +после первого PUT: теги откатились к `[1]`. + +**Рабочий путь:** `PUT /api/v1/indexer/N?forceSave=true` → **202** (сохраняет, тест пропускает). +Тест гонять отдельно, по одному. + +## Практические замечания + +- **Логи FS пусты при `LOG_LEVEL=warning`** — это правильно: на `info` он пишет + `login_password` трекеров в plaintext. Не поднимать уровень ради «посмотреть». +- `sessions.create` → `ok`, `version 3.5.2` — быстрый smoke-тест живости FS. +- Прямая проверка FS из prowlarr: + ```bash + docker exec prowlarr sh -c 'curl -s --max-time 150 -X POST http://flaresolverr:8191/v1 \ + -H "Content-Type: application/json" \ + -d "{\"cmd\":\"request.get\",\"url\":\"https://rutracker.org/forum/login.php\",\"maxTimeout\":130000}"' + # ожидается: {"status":"ok","message":"Challenge solved!", ...} + ``` +- `sleep 35` после старта контейнера — Chrome поднимается ~30 с; раньше этого `:8191` может не отвечать. +- `shm_size` и `sysctls` — **в блок сервиса** compose, не в `environment`. + +## Состояние индексеров после деплоя (2026-09-28) + +| id | Индексер | Теги | Статус | +|---|---|---|---| +| 1 | RuTracker | `[1,2]` | ✅ **valid** (был красный с 2026-05-20) | +| 2 | RuTor | `[1]` | ✅ valid (DNS-блок обходится одним прокси) | +| 3 | Byrutor | `[1]` | ✅ valid (резолвится без прокси) | +| 4 | NoNaMe Club | `[1,2]` | ✅ тег навешен; CF лечится FS | +| 5 | Kinozal | `[1,2]` | ⏳ гонка при testall, вручную → `Challenge solved!` | +| 6 | Kinozal (M) | `[1,2]` | ✅ **valid** | + +## История + +- **2026-09-26** — разведка под Lidarr. Найдено: DNS-блок провайдера (NXDOMAIN на 4 трекера), + `vless-proxy` не в `media_net`. Прокси-маршрут для Prowlarr починен в тот же день (3/6 индексеров). + Остаток — Cloudflare на RuTracker/Kinozal. [[personal/plans/lidarr-taiga-and-indexer-unblock]] +- **2026-09-28** — **FlareSolverr развёрнут** по задаче Alex «ставь как на Кра́кене + прокси-контейнер». + Ключевое: FS сам ходит через `vless-proxy` (`PROXY_URL`) — двойной обход DNS+CF. + RuTracker впервые стал `valid` за всё время существования стека (с 2026-05-20). + Питфоллы: `requestTimeout` 60→120, `?forceSave=true`, гонка параллельного `testall`. + +## Открытые пункты + +- Прогнать финальный **sequential** тест всех 6 → зафиксировать результат. +- Kinozal (5): подтвердить `valid` вне гонки (вручную челлендж решается). +- Проверить, что RuTracker реально **логинится** (не только челлендж на login.php) — + тестовый поиск с авторизацией. +- Lidarr: метаданные `api.lidarr.audio` → 403 CF прямым, 200 через `vless-proxy`. + Ранее заготовлен `/tmp/add_proxy_env.py` (HTTP_PROXY/HTTPS_PROXY) — **не применён**; + теперь у FlareSolverr есть `PROXY_URL`, но Lidarr ходит в SkyHook сам, не через FS. + Разбирать отдельно — [[family/plans/lidarr-taiga-deploy]].