mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-09 15:05:26 +03:00
use filelock to ensure atomic config updates from endpoint
This commit is contained in:
parent
b4462138fb
commit
1e061538a1
@ -19,6 +19,7 @@ from fastapi import APIRouter, Body, Path, Request, Response
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.params import Depends
|
||||
from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse
|
||||
from filelock import FileLock, Timeout
|
||||
from markupsafe import escape
|
||||
from peewee import SQL, fn, operator
|
||||
from pydantic import ValidationError
|
||||
@ -424,7 +425,10 @@ def config_save(save_option: str, body: Any = Body(media_type="text/plain")):
|
||||
@router.put("/config/set", dependencies=[Depends(require_role(["admin"]))])
|
||||
def config_set(request: Request, body: AppConfigSetBody):
|
||||
config_file = find_config_file()
|
||||
lock = FileLock(f"{config_file}.lock", timeout=5)
|
||||
|
||||
try:
|
||||
with lock:
|
||||
with open(config_file, "r") as f:
|
||||
old_raw_config = f.read()
|
||||
|
||||
@ -433,7 +437,9 @@ def config_set(request: Request, body: AppConfigSetBody):
|
||||
|
||||
# process query string parameters (takes precedence over body.config_data)
|
||||
parsed_url = urllib.parse.urlparse(str(request.url))
|
||||
query_string = urllib.parse.parse_qs(parsed_url.query, keep_blank_values=True)
|
||||
query_string = urllib.parse.parse_qs(
|
||||
parsed_url.query, keep_blank_values=True
|
||||
)
|
||||
|
||||
# Filter out empty keys but keep blank values for non-empty keys
|
||||
query_string = {k: v for k, v in query_string.items() if k}
|
||||
@ -448,7 +454,10 @@ def config_set(request: Request, body: AppConfigSetBody):
|
||||
if not updates:
|
||||
return JSONResponse(
|
||||
content=(
|
||||
{"success": False, "message": "No configuration data provided"}
|
||||
{
|
||||
"success": False,
|
||||
"message": "No configuration data provided",
|
||||
}
|
||||
),
|
||||
status_code=400,
|
||||
)
|
||||
@ -500,7 +509,9 @@ def config_set(request: Request, body: AppConfigSetBody):
|
||||
settings = config.get_nested_object(body.update_topic)
|
||||
|
||||
request.app.config_publisher.publish_update(
|
||||
CameraConfigUpdateTopic(CameraConfigUpdateEnum[field], camera),
|
||||
CameraConfigUpdateTopic(
|
||||
CameraConfigUpdateEnum[field], camera
|
||||
),
|
||||
settings,
|
||||
)
|
||||
else:
|
||||
@ -521,6 +532,16 @@ def config_set(request: Request, body: AppConfigSetBody):
|
||||
),
|
||||
status_code=200,
|
||||
)
|
||||
except Timeout:
|
||||
return JSONResponse(
|
||||
content=(
|
||||
{
|
||||
"success": False,
|
||||
"message": "Another process is currently updating the config. Please try again in a few seconds.",
|
||||
}
|
||||
),
|
||||
status_code=503,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/vainfo", dependencies=[Depends(allow_any_authenticated())])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user