use the shared substitution namespace in go2rtc config

The generator rebuilt the namespace itself from os.environ and a hardcoded /run/secrets, so it never saw environment_vars or CREDENTIALS_DIRECTORY, and str.format made any stray brace fatal. It now installs the FRIGATE_ names from environment_vars and substitutes streams the same way every other field does.
This commit is contained in:
Josh Hawkins
2026-08-21 08:32:57 -05:00
parent 0be39232c1
commit 065f81ec24
@@ -3,13 +3,12 @@
import json import json
import os import os
import sys import sys
from pathlib import Path
from typing import Any from typing import Any
from ruamel.yaml import YAML from ruamel.yaml import YAML
sys.path.insert(0, "/opt/frigate") sys.path.insert(0, "/opt/frigate")
from frigate.config.env import substitute_frigate_vars from frigate.config.env import apply_config_env_vars, substitute_frigate_vars
from frigate.const import ( from frigate.const import (
BIRDSEYE_PIPE, BIRDSEYE_PIPE,
LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MAJOR,
@@ -25,15 +24,6 @@ sys.path.remove("/opt/frigate")
yaml = YAML() yaml = YAML()
FRIGATE_ENV_VARS = {k: v for k, v in os.environ.items() if k.startswith("FRIGATE_")}
# read docker secret files as env vars too
if os.path.isdir("/run/secrets"):
for secret_file in os.listdir("/run/secrets"):
if secret_file.startswith("FRIGATE_"):
FRIGATE_ENV_VARS[secret_file] = (
Path(os.path.join("/run/secrets", secret_file)).read_text().strip()
)
config_file = find_config_file() config_file = find_config_file()
try: try:
@@ -47,6 +37,20 @@ try:
except FileNotFoundError: except FileNotFoundError:
config: dict[str, Any] = {} config: dict[str, Any] = {}
# No validator runs here, so install environment_vars ourselves. FRIGATE_
# names only: anything else lands in os.environ, where the exec gate reads
# GO2RTC_ALLOW_ARBITRARY_EXEC.
config_env_vars = config.get("environment_vars")
apply_config_env_vars(
{
key: value
for key, value in config_env_vars.items()
if str(key).startswith("FRIGATE_")
}
if isinstance(config_env_vars, dict)
else {}
)
go2rtc_config: dict[str, Any] = config.get("go2rtc", {}) go2rtc_config: dict[str, Any] = config.get("go2rtc", {})
# Need to enable CORS for go2rtc so the frigate integration / card work automatically # Need to enable CORS for go2rtc so the frigate integration / card work automatically
@@ -113,7 +117,7 @@ for name in list(go2rtc_config.get("streams", {})):
if isinstance(stream, str): if isinstance(stream, str):
try: try:
formatted_stream = stream.format(**FRIGATE_ENV_VARS) formatted_stream = substitute_frigate_vars(stream)
if is_restricted_go2rtc_source(formatted_stream): if is_restricted_go2rtc_source(formatted_stream):
print( print(
f"[ERROR] Stream '{name}' uses a restricted source (echo/expr/exec) which is disabled by default for security. " f"[ERROR] Stream '{name}' uses a restricted source (echo/expr/exec) which is disabled by default for security. "
@@ -122,7 +126,7 @@ for name in list(go2rtc_config.get("streams", {})):
del go2rtc_config["streams"][name] del go2rtc_config["streams"][name]
continue continue
go2rtc_config["streams"][name] = formatted_stream go2rtc_config["streams"][name] = formatted_stream
except KeyError as e: except ValueError as e:
print( print(
"[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info." "[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info."
) )
@@ -132,7 +136,7 @@ for name in list(go2rtc_config.get("streams", {})):
filtered_streams = [] filtered_streams = []
for i, stream_item in enumerate(stream): for i, stream_item in enumerate(stream):
try: try:
formatted_stream = stream_item.format(**FRIGATE_ENV_VARS) formatted_stream = substitute_frigate_vars(stream_item)
if is_restricted_go2rtc_source(formatted_stream): if is_restricted_go2rtc_source(formatted_stream):
print( print(
f"[ERROR] Stream '{name}' item {i + 1} uses a restricted source (echo/expr/exec) which is disabled by default for security. " f"[ERROR] Stream '{name}' item {i + 1} uses a restricted source (echo/expr/exec) which is disabled by default for security. "
@@ -141,7 +145,7 @@ for name in list(go2rtc_config.get("streams", {})):
continue continue
filtered_streams.append(formatted_stream) filtered_streams.append(formatted_stream)
except KeyError as e: except ValueError as e:
print( print(
"[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info." "[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info."
) )