cache the runtime ids in the ownership helper

This commit is contained in:
Josh Hawkins
2026-08-28 07:28:47 -05:00
parent 8ed9f34981
commit d02771f07a
2 changed files with 18 additions and 0 deletions
+14
View File
@@ -14,6 +14,9 @@ class FakePwEntry:
# The devcontainer image exports FRIGATE_RUN_AS_ROOT, so any test that has to
# reach past the escape-hatch check pins the variable instead of inheriting it.
class TestGetRuntimeIds(unittest.TestCase):
def setUp(self) -> None:
ownership.get_runtime_ids.cache_clear()
@patch("frigate.util.ownership.os.geteuid", return_value=1000)
def test_returns_none_when_not_root(self, _):
assert ownership.get_runtime_ids() is None
@@ -35,8 +38,19 @@ class TestGetRuntimeIds(unittest.TestCase):
def test_returns_frigate_ids_as_root(self, *_):
assert ownership.get_runtime_ids() == (1500, 1500)
@patch.dict("os.environ", {"FRIGATE_RUN_AS_ROOT": "false"})
@patch("frigate.util.ownership.pwd.getpwnam", return_value=FakePwEntry())
@patch("frigate.util.ownership.os.geteuid", return_value=0)
def test_caches_lookup(self, _geteuid, getpwnam):
assert ownership.get_runtime_ids() == (1500, 1500)
assert ownership.get_runtime_ids() == (1500, 1500)
getpwnam.assert_called_once()
class TestChownToRuntime(unittest.TestCase):
def setUp(self) -> None:
ownership.get_runtime_ids.cache_clear()
@patch("frigate.util.ownership.os.chown")
@patch("frigate.util.ownership.get_runtime_ids", return_value=None)
def test_noop_when_no_runtime_ids(self, _, chown):
+4
View File
@@ -1,5 +1,6 @@
"""Helpers for aligning created files with the non-root runtime user."""
import functools
import logging
import os
import pwd
@@ -9,12 +10,15 @@ logger = logging.getLogger(__name__)
RUNTIME_USER = "frigate"
@functools.lru_cache(maxsize=1)
def get_runtime_ids() -> tuple[int, int] | None:
"""Return (uid, gid) that services run as, or None when chown is not applicable.
None when: not root (docker --user, so the host already mapped us),
FRIGATE_RUN_AS_ROOT=true (escape hatch must not mutate ownership),
or outside the Frigate container image (no frigate user).
The result is cached for the process lifetime because the runtime user
cannot change after boot.
"""
if os.geteuid() != 0:
return None