require effective config for slots ttl
This commit is contained in:
parent
8fdf2d5e5b
commit
a4f642402b
2 changed files with 32 additions and 14 deletions
|
|
@ -96,10 +96,7 @@ def _slot_age_seconds(slot: dict[str, Any]) -> float | None:
|
||||||
return (datetime.now(UTC) - dt).total_seconds()
|
return (datetime.now(UTC) - dt).total_seconds()
|
||||||
|
|
||||||
|
|
||||||
def _slot_ttl(slot: dict[str, Any], policy: dict[str, Any] | None, active_slots: int) -> str:
|
def _slot_ttl(slot: dict[str, Any], policy: dict[str, Any], active_slots: int) -> str:
|
||||||
if policy is None:
|
|
||||||
return "-"
|
|
||||||
|
|
||||||
capacity = policy.get("capacity")
|
capacity = policy.get("capacity")
|
||||||
scheduler = policy.get("scheduler")
|
scheduler = policy.get("scheduler")
|
||||||
if not isinstance(capacity, dict) or not isinstance(scheduler, dict):
|
if not isinstance(capacity, dict) or not isinstance(scheduler, dict):
|
||||||
|
|
@ -138,7 +135,7 @@ def _slot_ttl(slot: dict[str, Any], policy: dict[str, Any] | None, active_slots:
|
||||||
return "-"
|
return "-"
|
||||||
|
|
||||||
|
|
||||||
def _print_slots(data: list[dict[str, Any]], policy: dict[str, Any] | None = None) -> None:
|
def _print_slots(data: list[dict[str, Any]], policy: dict[str, Any]) -> None:
|
||||||
active_slots = sum(1 for slot in data if str(slot.get("state", "")) not in {"empty", "error"})
|
active_slots = sum(1 for slot in data if str(slot.get("state", "")) not in {"empty", "error"})
|
||||||
rows: list[list[str]] = []
|
rows: list[list[str]] = []
|
||||||
for slot in data:
|
for slot in data:
|
||||||
|
|
@ -193,16 +190,15 @@ def _print_status_summary(data: dict[str, Any]) -> None:
|
||||||
_print_table(["metric", "value"], rows)
|
_print_table(["metric", "value"], rows)
|
||||||
|
|
||||||
|
|
||||||
def _get_effective_config(socket_path: str) -> dict[str, Any] | None:
|
def _get_effective_config(socket_path: str) -> dict[str, Any]:
|
||||||
try:
|
status, data = _uds_request(socket_path, "GET", "/v1/config/effective")
|
||||||
status, data = _uds_request(socket_path, "GET", "/v1/config/effective")
|
|
||||||
except OSError:
|
|
||||||
return None
|
|
||||||
if status < 200 or status >= 300:
|
if status < 200 or status >= 300:
|
||||||
return None
|
msg = "failed to fetch effective config"
|
||||||
|
raise RuntimeError(msg)
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
return data
|
return data
|
||||||
return None
|
msg = "invalid effective config payload"
|
||||||
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
|
|
||||||
def _bulk_slot_action(socket_path: str, action: str) -> dict[str, Any]:
|
def _bulk_slot_action(socket_path: str, action: str) -> dict[str, Any]:
|
||||||
|
|
@ -395,7 +391,11 @@ def main() -> None:
|
||||||
print(json.dumps(data, indent=2))
|
print(json.dumps(data, indent=2))
|
||||||
elif args.command == "slots":
|
elif args.command == "slots":
|
||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
policy = _get_effective_config(args.socket)
|
try:
|
||||||
|
policy = _get_effective_config(args.socket)
|
||||||
|
except RuntimeError as err:
|
||||||
|
print(str(err))
|
||||||
|
raise SystemExit(1) from err
|
||||||
_print_slots(data, policy)
|
_print_slots(data, policy)
|
||||||
else:
|
else:
|
||||||
_print_error(data)
|
_print_error(data)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,13 @@ from datetime import UTC, datetime, timedelta
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from nix_builder_autoscaler import cli
|
from nix_builder_autoscaler import cli
|
||||||
from nix_builder_autoscaler.cli import _parse_args, _print_slots, _print_status_summary, _slot_ttl
|
from nix_builder_autoscaler.cli import (
|
||||||
|
_get_effective_config,
|
||||||
|
_parse_args,
|
||||||
|
_print_slots,
|
||||||
|
_print_status_summary,
|
||||||
|
_slot_ttl,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_parse_args_without_command_prints_help_and_exits_zero(
|
def test_parse_args_without_command_prints_help_and_exits_zero(
|
||||||
|
|
@ -149,3 +155,15 @@ def test_print_slots_includes_ttl_column(capsys: pytest.CaptureFixture[str]) ->
|
||||||
out = capsys.readouterr().out
|
out = capsys.readouterr().out
|
||||||
assert "ttl" in out
|
assert "ttl" in out
|
||||||
assert "slot001" in out
|
assert "slot001" in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_effective_config_raises_on_non_2xx(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
|
def _fake_request(socket_path: str, method: str, path: str, body=None): # noqa: ANN001
|
||||||
|
assert socket_path == "/tmp/sock"
|
||||||
|
assert method == "GET"
|
||||||
|
assert path == "/v1/config/effective"
|
||||||
|
return 404, {"error": "not found"}
|
||||||
|
|
||||||
|
monkeypatch.setattr(cli, "_uds_request", _fake_request)
|
||||||
|
with pytest.raises(RuntimeError, match="failed to fetch effective config"):
|
||||||
|
_get_effective_config("/tmp/sock")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue