Add docker-ip-addr-manager initial app
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
import threading
|
||||
from typing import Iterable
|
||||
|
||||
from app.models import IpEntry
|
||||
|
||||
|
||||
class EntryStorage:
|
||||
def __init__(self, file_path: str):
|
||||
self._path = Path(file_path)
|
||||
self._lock = threading.Lock()
|
||||
|
||||
def list_entries(self) -> list[IpEntry]:
|
||||
with self._lock:
|
||||
return self._read_entries_unlocked()
|
||||
|
||||
def save_entries(self, entries: Iterable[IpEntry]) -> None:
|
||||
serializable = [entry.to_dict() for entry in entries]
|
||||
with self._lock:
|
||||
self._path.parent.mkdir(parents=True, exist_ok=True)
|
||||
tmp_path = self._path.with_suffix(self._path.suffix + ".tmp")
|
||||
tmp_path.write_text(json.dumps(serializable, indent=2, sort_keys=True), encoding="utf-8")
|
||||
tmp_path.replace(self._path)
|
||||
|
||||
def _read_entries_unlocked(self) -> list[IpEntry]:
|
||||
if not self._path.exists():
|
||||
return []
|
||||
|
||||
raw = self._path.read_text(encoding="utf-8").strip()
|
||||
if not raw:
|
||||
return []
|
||||
|
||||
parsed = json.loads(raw)
|
||||
if not isinstance(parsed, list):
|
||||
raise ValueError(f"State file must be a list: {self._path}")
|
||||
|
||||
return [IpEntry.from_dict(item) for item in parsed]
|
||||
Reference in New Issue
Block a user