hermes-hub/scripts/enable_lan_access.py
Hermes Team e90f6331a2 fix(launcher): сообщение при запуске не совпадало с настройками; смена токена
Владелец привязал хаб на сервере к сети, а лаунчер всё равно напечатал
«Headless Mode», показал http://127.0.0.1:5800 и посоветовал пробросить порт
через ssh -L. Текст был зашит и настроек не читал: инструкция вела поднимать
туннель к серверу, который уже был виден напрямую. Инструкция, не
совпадающая с реальностью, хуже отсутствующей — тот же класс дефекта, что и
снятая заглушка про «вход через веб невозможен».

Теперь сообщение читает web_api_host из hub_settings.json: при 127.0.0.1
показывает проброс порта и подсказывает про enable_lan_access.py, при
сетевой привязке — реальный адрес из hostname -I и напоминание про токен.

Добавлен --rotate: смена токена понадобилась немедленно, потому что
выданный токен был вставлен в переписку и скомпрометирован. Без флага
поведение прежнее — повторный запуск токен не трогает.

Проверено: без --rotate токен сохраняется, с --rotate меняется; bash -n на
лаунчере проходит; переводы строк LF.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 10:47:29 +07:00

75 lines
3.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Открыть веб-хаб в домашнюю сеть: привязка к 0.0.0.0 плюс обязательный токен.
python3 scripts/enable_lan_access.py # показать, что будет сделано
python3 scripts/enable_lan_access.py --yes # применить
python3 scripts/enable_lan_access.py --yes --rotate # сменить токен
Почему подтверждение обязательно. Каталог берётся из HERMES_HOME, а эта
переменная часто задана в окружении незаметно для запускающего. При отладке
скрипт из-за этого записал настройки не туда, куда предполагалось, и привязал
к сети не тот хаб. Поэтому цель печатается всегда, а изменение требует --yes.
Настройки ДОПОЛНЯЮТСЯ, а не переписываются: рядом лежат тема, интервал
обновления квот и параметры маршрутизации. Запись атомарная.
"""
import json
import os
import secrets
import sys
from pathlib import Path
def main() -> int:
apply = "--yes" in sys.argv
rotate = "--rotate" in sys.argv
env_home = os.environ.get("HERMES_HOME")
home = Path(env_home) if env_home else (Path.home() / ".hermes")
target = home / "hub_settings.json"
print(f"Каталог Hermes : {home}")
print(f" источник : {'переменная HERMES_HOME' if env_home else 'по умолчанию ~/.hermes'}")
print(f"Файл настроек : {target}")
print(f" существует : {'да' if target.exists() else 'нет, будет создан'}")
data = {}
if target.exists():
try:
data = json.loads(target.read_text(encoding="utf-8"))
except ValueError:
print(f"\nОТКАЗ: {target} повреждён. Разберитесь вручную — перезаписывать не буду.")
return 1
existing = None if rotate else data.get("web_api_token")
keep = sorted(k for k in data if not k.startswith("web_api"))
print(f"Будут сохранены: {', '.join(keep) if keep else '(файл пуст)'}")
if rotate:
note = "БУДЕТ ЗАМЕНЁН — прежний перестанет действовать"
elif existing:
note = "уже задан, оставляю прежний"
else:
note = "будет создан новый"
print(f"Токен : {note}")
if not apply:
print("\nПоказан предпросмотр. Чтобы применить, повторите с --yes")
return 0
token = existing or secrets.token_urlsafe(32)
data["web_api_host"] = "0.0.0.0"
data["web_api_token"] = token
data.setdefault("web_api_port", 5800)
tmp = target.with_suffix(".json.tmp")
tmp.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
os.replace(tmp, target)
print(f"\nГотово: {target}")
print("\nТОКЕН — вставить в «Настройки» в интерфейсе:")
print(f" {token}")
print("\nДальше: перезапустить хаб, затем открыть http://<адрес-сервера>:5800")
print("Токен хранится в этом файле; в снапшот и в /api/settings он не попадает.")
return 0
if __name__ == "__main__":
raise SystemExit(main())