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,
|
"""Настройки хаба: пары ключ → JSON в таблице setting. Любая правка поднимает settings_version,
|
||||||
агент перечитывает настройки, когда видит новую версию в ответе claim."""
|
агент перечитывает настройки, когда видит новую версию в ответе claim."""
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import secrets
|
import secrets
|
||||||
|
|
||||||
DEFAULT_PACING = {"ensure_issue": 120, "ensure_fields": 120, "ensure_comment": 30, "ensure_status": 30,
|
DEFAULT_PACING = {"ensure_issue": 120, "ensure_fields": 120, "ensure_comment": 30, "ensure_status": 30,
|
||||||
@ -29,6 +30,7 @@ DEFAULTS = {
|
|||||||
"transitions_map": {},
|
"transitions_map": {},
|
||||||
"link_types": {},
|
"link_types": {},
|
||||||
"board_id": None,
|
"board_id": None,
|
||||||
|
"relay_dir": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Что получает агент (без токенов и служебных ключей хаба)
|
# Что получает агент (без токенов и служебных ключей хаба)
|
||||||
@ -47,6 +49,7 @@ def validate(key, value) -> None:
|
|||||||
"""Проверить значение настройки до записи; ValueError — на 422 в API.
|
"""Проверить значение настройки до записи; ValueError — на 422 в API.
|
||||||
pacing — объект {тип команды: целое >= 0} только с известными типами команд;
|
pacing — объект {тип команды: целое >= 0} только с известными типами команд;
|
||||||
backup_keep, auto_refresh_minutes, min_agent_version — целые >= 0; port — целое 1..65535;
|
backup_keep, auto_refresh_minutes, min_agent_version — целые >= 0; port — целое 1..65535;
|
||||||
|
relay_dir — null или абсолютный путь строкой;
|
||||||
остальные ключи — по типу значения по умолчанию (объект, список, строка, флаг), если оно не None;
|
остальные ключи — по типу значения по умолчанию (объект, список, строка, флаг), если оно не None;
|
||||||
неизвестные ключи и ключи с умолчанием None принимаются как есть."""
|
неизвестные ключи и ключи с умолчанием None принимаются как есть."""
|
||||||
if key == "pacing":
|
if key == "pacing":
|
||||||
@ -66,6 +69,10 @@ def validate(key, value) -> None:
|
|||||||
if not _is_int(value) or value < 0:
|
if not _is_int(value) or value < 0:
|
||||||
raise ValueError(f"{key} — целое >= 0")
|
raise ValueError(f"{key} — целое >= 0")
|
||||||
return
|
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)
|
default = DEFAULTS.get(key)
|
||||||
if default is not None and type(value) is not type(default):
|
if default is not None and type(value) is not type(default):
|
||||||
names = {dict: "объект", list: "список", str: "строка", bool: "true/false", int: "целое"}
|
names = {dict: "объект", list: "список", str: "строка", bool: "true/false", int: "целое"}
|
||||||
|
|||||||
@ -301,3 +301,15 @@ def test_full_refresh_marks_unseen_issue_as_neighbor(hub):
|
|||||||
# частичный refresh (по ключам) других задач ничего не помечает
|
# частичный refresh (по ключам) других задач ничего не помечает
|
||||||
_run_refresh(hub, {"keys": ["A-1"]}, [{"key": "A-1", "summary": "т2", "labels": []}])
|
_run_refresh(hub, {"keys": ["A-1"]}, [{"key": "A-1", "summary": "т2", "labels": []}])
|
||||||
assert hub["client"].get("/issues/A-1")["neighbor"] is False
|
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):
|
with pytest.raises(RuntimeError):
|
||||||
settings.init_from_config(conn, cfg)
|
settings.init_from_config(conn, cfg)
|
||||||
settings.init_from_config(conn, cfg, force=True)
|
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