feat(settings): настройка relay_dir — абсолютный путь папки реле или null (#5)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d4a7f29cbd
commit
e025577d05
@ -1,6 +1,7 @@
|
||||
"""Настройки хаба: пары ключ → JSON в таблице setting. Любая правка поднимает settings_version,
|
||||
агент перечитывает настройки, когда видит новую версию в ответе claim."""
|
||||
import json
|
||||
import os
|
||||
import secrets
|
||||
|
||||
DEFAULT_PACING = {"ensure_issue": 120, "ensure_fields": 120, "ensure_comment": 30, "ensure_status": 30,
|
||||
@ -29,6 +30,7 @@ DEFAULTS = {
|
||||
"transitions_map": {},
|
||||
"link_types": {},
|
||||
"board_id": None,
|
||||
"relay_dir": None,
|
||||
}
|
||||
|
||||
# Что получает агент (без токенов и служебных ключей хаба)
|
||||
@ -47,6 +49,7 @@ def validate(key, value) -> None:
|
||||
"""Проверить значение настройки до записи; ValueError — на 422 в API.
|
||||
pacing — объект {тип команды: целое >= 0} только с известными типами команд;
|
||||
backup_keep, auto_refresh_minutes, min_agent_version — целые >= 0; port — целое 1..65535;
|
||||
relay_dir — null или абсолютный путь строкой;
|
||||
остальные ключи — по типу значения по умолчанию (объект, список, строка, флаг), если оно не None;
|
||||
неизвестные ключи и ключи с умолчанием None принимаются как есть."""
|
||||
if key == "pacing":
|
||||
@ -66,6 +69,10 @@ def validate(key, value) -> None:
|
||||
if not _is_int(value) or value < 0:
|
||||
raise ValueError(f"{key} — целое >= 0")
|
||||
return
|
||||
if key == "relay_dir":
|
||||
if value is not None and (not isinstance(value, str) or not os.path.isabs(value)):
|
||||
raise ValueError("relay_dir — абсолютный путь папки реле или null")
|
||||
return
|
||||
default = DEFAULTS.get(key)
|
||||
if default is not None and type(value) is not type(default):
|
||||
names = {dict: "объект", list: "список", str: "строка", bool: "true/false", int: "целое"}
|
||||
|
||||
@ -301,3 +301,15 @@ def test_full_refresh_marks_unseen_issue_as_neighbor(hub):
|
||||
# частичный refresh (по ключам) других задач ничего не помечает
|
||||
_run_refresh(hub, {"keys": ["A-1"]}, [{"key": "A-1", "summary": "т2", "labels": []}])
|
||||
assert hub["client"].get("/issues/A-1")["neighbor"] is False
|
||||
|
||||
|
||||
def test_relay_dir_put_validation(hub):
|
||||
c = hub["client"]
|
||||
before = c.get("/settings")["settings_version"]
|
||||
with pytest.raises(HubError) as e:
|
||||
c.put("/settings", {"relay_dir": "rshb/jira-bridge"})
|
||||
assert e.value.status == 422
|
||||
assert c.get("/settings")["settings_version"] == before
|
||||
assert c.put("/settings", {"relay_dir": "/tmp/jira-bridge"})["settings_version"] == before + 1
|
||||
assert c.put("/settings", {"relay_dir": None})["settings_version"] == before + 2
|
||||
assert "relay_dir" not in hub["agent"].get("/agent/settings")
|
||||
|
||||
@ -53,3 +53,16 @@ def test_init_from_config():
|
||||
with pytest.raises(RuntimeError):
|
||||
settings.init_from_config(conn, cfg)
|
||||
settings.init_from_config(conn, cfg, force=True)
|
||||
|
||||
|
||||
def test_relay_dir_default_and_validation(tmp_path):
|
||||
conn = db.connect(tmp_path / "hub.sqlite")
|
||||
settings.ensure_defaults(conn)
|
||||
assert settings.get(conn, "relay_dir") is None
|
||||
settings.validate("relay_dir", None)
|
||||
settings.validate("relay_dir", "/Volumes/externalSSD/utm/rshb/jira-bridge")
|
||||
for bad in ("rshb/jira-bridge", "", 5, ["/x"]):
|
||||
with pytest.raises(ValueError):
|
||||
settings.validate("relay_dir", bad)
|
||||
assert "relay_dir" not in settings.AGENT_KEYS
|
||||
conn.close()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user