forked from Github/frigate
Implement config migration and restructure config for new review format (#10961)
* Update reference config to reflect new config * Migrate 0.13 config to match 0.14 config style * Overwrite existing config * Adjust config schema to remove events required zones and include reviews * Update object config to check correct required zones config * Refactor reviews to remove motion and only create review segments in expected circumstances * Cleanup * Formatting * Fix update ordering * Update pydantic * Remove rtmp references as part of migration * Catch file not found for alert frame
This commit is contained in:
127
frigate/util/config.py
Normal file
127
frigate/util/config.py
Normal file
@@ -0,0 +1,127 @@
|
||||
"""configuration utils."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
from frigate.const import CONFIG_DIR
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CURRENT_CONFIG_VERSION = 0.14
|
||||
|
||||
|
||||
def migrate_frigate_config(config_file: str):
|
||||
"""handle migrating the frigate config."""
|
||||
logger.info("Checking if frigate config needs migration...")
|
||||
version_file = os.path.join(CONFIG_DIR, ".version")
|
||||
|
||||
if not os.path.isfile(version_file):
|
||||
previous_version = 0.13
|
||||
else:
|
||||
with open(version_file) as f:
|
||||
try:
|
||||
previous_version = float(f.readline())
|
||||
except Exception:
|
||||
previous_version = 0.13
|
||||
|
||||
if previous_version == CURRENT_CONFIG_VERSION:
|
||||
logger.info("frigate config does not need migration...")
|
||||
return
|
||||
|
||||
logger.info("copying config as backup...")
|
||||
shutil.copy(config_file, os.path.join(CONFIG_DIR, "backup_config.yaml"))
|
||||
|
||||
yaml = YAML()
|
||||
yaml.indent(mapping=2, sequence=4, offset=2)
|
||||
with open(config_file, "r") as f:
|
||||
config: dict[str, dict[str, any]] = yaml.load(f)
|
||||
|
||||
if previous_version < 0.14:
|
||||
logger.info(f"Migrating frigate config from {previous_version} to 0.14...")
|
||||
new_config = migrate_014(config)
|
||||
with open(config_file, "w") as f:
|
||||
yaml.dump(new_config, f)
|
||||
previous_version = 0.14
|
||||
|
||||
with open(version_file, "w") as f:
|
||||
f.write(str(CURRENT_CONFIG_VERSION))
|
||||
|
||||
logger.info("Finished frigate config migration...")
|
||||
|
||||
|
||||
def migrate_014(config: dict[str, dict[str, any]]) -> dict[str, dict[str, any]]:
|
||||
"""Handle migrating frigate config to 0.14"""
|
||||
# migrate record.events.required_zones to review.alerts.required_zones
|
||||
new_config = config.copy()
|
||||
global_required_zones = (
|
||||
config.get("record", {}).get("events", {}).get("required_zones", [])
|
||||
)
|
||||
|
||||
if global_required_zones:
|
||||
# migrate to new review config
|
||||
if not new_config.get("review"):
|
||||
new_config["review"] = {}
|
||||
|
||||
if not new_config["review"].get("alerts"):
|
||||
new_config["review"]["alerts"] = {}
|
||||
|
||||
if not new_config["review"]["alerts"].get("required_zones"):
|
||||
new_config["review"]["alerts"]["required_zones"] = global_required_zones
|
||||
|
||||
# remove record required zones config
|
||||
del new_config["record"]["events"]["required_zones"]
|
||||
|
||||
# remove record altogether if there is not other config
|
||||
if not new_config["record"]["events"]:
|
||||
del new_config["record"]["events"]
|
||||
|
||||
if not new_config["record"]:
|
||||
del new_config["record"]
|
||||
|
||||
# remove rtmp
|
||||
if new_config.get("ffmpeg", {}).get("output_args", {}).get("rtmp"):
|
||||
del new_config["ffmpeg"]["output_args"]["rtmp"]
|
||||
|
||||
if new_config.get("rtmp"):
|
||||
del new_config["rtmp"]
|
||||
|
||||
for name, camera in config.get("cameras", {}).items():
|
||||
camera_config: dict[str, dict[str, any]] = camera.copy()
|
||||
required_zones = (
|
||||
camera_config.get("record", {}).get("events", {}).get("required_zones", [])
|
||||
)
|
||||
|
||||
if required_zones:
|
||||
# migrate to new review config
|
||||
if not camera_config.get("review"):
|
||||
camera_config["review"] = {}
|
||||
|
||||
if not camera_config["review"].get("alerts"):
|
||||
camera_config["review"]["alerts"] = {}
|
||||
|
||||
if not camera_config["review"]["alerts"].get("required_zones"):
|
||||
camera_config["review"]["alerts"]["required_zones"] = required_zones
|
||||
|
||||
# remove record required zones config
|
||||
del camera_config["record"]["events"]["required_zones"]
|
||||
|
||||
# remove record altogether if there is not other config
|
||||
if not camera_config["record"]["events"]:
|
||||
del camera_config["record"]["events"]
|
||||
|
||||
if not camera_config["record"]:
|
||||
del camera_config["record"]
|
||||
|
||||
# remove rtmp
|
||||
if camera_config.get("ffmpeg", {}).get("output_args", {}).get("rtmp"):
|
||||
del camera_config["ffmpeg"]["output_args"]["rtmp"]
|
||||
|
||||
if camera_config.get("rtmp"):
|
||||
del camera_config["rtmp"]
|
||||
|
||||
new_config["cameras"][name] = camera_config
|
||||
|
||||
return new_config
|
||||
Reference in New Issue
Block a user