#!/command/with-contenv bash # shellcheck shell=bash # Grant the runtime users access to mapped-in device nodes with POSIX ACLs, # so --device works without host-side group or udev setup. # No-op when: started with --user (euid != 0), FRIGATE_RUN_AS_ROOT=true, # or FRIGATE_DEVICE_ACLS=false. set -o errexit -o nounset -o pipefail if [[ "$(id -u)" -ne 0 ]]; then exit 0 fi if [[ "${FRIGATE_RUN_AS_ROOT:-false}" == "true" ]]; then exit 0 fi if [[ "${FRIGATE_DEVICE_ACLS:-true}" == "false" ]]; then echo "[INFO] FRIGATE_DEVICE_ACLS=false: skipping device access grants" exit 0 fi shopt -s nullglob device_globs=( "/dev/dri/*" "/dev/accel/*" "/dev/apex_*" "/dev/hailo*" "/dev/video*" "/dev/kfd" "/dev/rknpu*" "/dev/mpp_service" "/dev/rga" "/dev/dma_heap/*" "/dev/nvhost*" "/dev/nvmap" "/dev/nvidia*" "/dev/memx*" "/dev/dxrt*" ) IFS=',' read -ra extra_globs <<< "${DEVICE_ACL_PATHS:-}" for extra in "${extra_globs[@]}"; do extra="${extra//[[:space:]]/}" if [[ -z "$extra" ]]; then continue fi if [[ "$extra" != /dev/* || "$extra" == *..* ]]; then echo "[ERROR] DEVICE_ACL_PATHS entries must be under /dev, got '${extra}'" >&2 exit 1 fi device_globs+=("$extra") done granted=0 failed=0 grant() { local node="$1" # nullglob only drops patterns that hold a metacharacter, so a literal # table entry for absent hardware arrives here verbatim. Warn only about # nodes that exist and could not be granted. if [[ ! -e "$node" ]]; then return 0 fi local spec="u:frigate:rw,u:go2rtc:rw" # directories need traverse or nothing under them is reachable if [[ -d "$node" ]]; then spec="u:frigate:rwx,u:go2rtc:rwx" fi if setfacl -m "$spec" "$node" 2>/dev/null; then granted=$((granted + 1)) else failed=$((failed + 1)) echo "[WARN] could not grant device access on ${node}; see EXTRA_GROUPS in the non-root docs for the fallback" fi } for glob in "${device_globs[@]}"; do # shellcheck disable=SC2231 for node in $glob; do grant "$node" done done # USB devices re-enumerate (the Coral uploads firmware and reattaches as a new # node), so the directories also get a default ACL new nodes inherit. The # inherited grant is clamped by the creating mode's group bits, which is rw on # udev hosts (0664) and nothing on raw devtmpfs (0600); hardware-verified. if [[ -d /dev/bus/usb ]]; then while IFS= read -r -d '' node; do grant "$node" done < <(find /dev/bus/usb -mindepth 1 -print0) while IFS= read -r -d '' dir; do setfacl -d -m "u:frigate:rw,u:go2rtc:rw" "$dir" 2>/dev/null || \ echo "[WARN] could not set a default ACL on ${dir}; a re-enumerating USB device may lose access" done < <(find /dev/bus/usb -type d -print0) fi if [[ "$failed" -gt 0 ]]; then echo "[INFO] device access: granted ${granted} node(s), ${failed} failed" elif [[ "$granted" -gt 0 ]]; then echo "[INFO] device access: granted ${granted} node(s) to the runtime users" fi