openweb / vrag /settings.py
Leon4gr45's picture
Upload folder using huggingface_hub
33962ff verified
Raw History Blame Contribute Delete
2.94 kB
"""Atomic configuration history. Defaults are read-only unless storage is configured."""
import asyncio
import json
import os
from pathlib import Path
import tempfile
from config.schema import Configuration
class ConfigStore:
def __init__(self, path=None):
self.path = Path(path or os.environ['VM_STATE_DIR']) if path or os.environ.get('VM_STATE_DIR') else None
self.lock = asyncio.Lock()
self.history = [Configuration()]
self.version = 1
if self.path:
self.path.mkdir(parents=True, exist_ok=True)
state = self.path / 'config-history.json'
if state.exists():
self.history = [Configuration.model_validate(c) for c in json.loads(state.read_text())]
self.version = len(self.history)
def snapshot(self):
# Deep copy prevents nested mutation of in-flight snapshots.
from .backup.service import queue
queue.request()
return self.version, self.history[-1].model_copy(deep=True)
async def apply(self, config, expected):
if not self.path:
raise ValueError('VM_STATE_DIR is required for configuration updates; defaults are read-only')
from .backup.github import state_lock
async with state_lock, self.lock:
if expected != self.version:
raise ValueError('configuration changed; reload before applying')
if len(self.history) >= 100:
raise ValueError('configuration history limit reached; archive state before more updates')
history = self.history + [config]
fd, tmp = tempfile.mkstemp(dir=self.path, prefix='.config-')
try:
with os.fdopen(fd, 'w') as f:
json.dump([c.model_dump() for c in history], f)
f.flush()
os.fsync(f.fileno())
# Persist the previous complete history before switching the active file.
if (self.path / 'config-history.json').exists():
import shutil
backup = self.path / '.config-history.backup.tmp'
shutil.copyfile(self.path / 'config-history.json', backup)
with backup.open('rb') as previous:
os.fsync(previous.fileno())
os.replace(backup, self.path / 'config-history.backup.json')
os.replace(tmp, self.path / 'config-history.json')
directory_fd = os.open(self.path, os.O_RDONLY)
try:
os.fsync(directory_fd)
finally:
os.close(directory_fd)
finally:
if os.path.exists(tmp):
os.unlink(tmp)
self.history, self.version = history, len(history)
from .backup.service import queue
queue.request()
return self.version
store = ConfigStore()