mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-08 15:52:48 +03:00
record the root-services mode in the sentinel and sweep small trees each boot
This commit is contained in:
@@ -157,11 +157,29 @@ if [[ "$(id -u)" -eq 0 ]]; then
|
|||||||
# below it. A parent /media mount doesn't count: a dedicated
|
# below it. A parent /media mount doesn't count: a dedicated
|
||||||
# /media/frigate volume added later would be shadowed and skipped.
|
# /media/frigate volume added later would be shadowed and skipped.
|
||||||
sentinel_args=(--sentinel /config/.permissions_version)
|
sentinel_args=(--sentinel /config/.permissions_version)
|
||||||
|
root_services_mode=""
|
||||||
|
if [[ -n "${FRIGATE_ROOT_SERVICES:-}" ]]; then
|
||||||
|
# || true: grep -v exits non-zero on an all-empty list (e.g. ",")
|
||||||
|
# and errexit+pipefail would otherwise abort the boot over it
|
||||||
|
root_services_mode=$(tr ',' '\n' <<< "${FRIGATE_ROOT_SERVICES//[[:space:]]/}" | grep -v '^$' | sort -u | paste -sd, - || true)
|
||||||
|
if [[ -n "$root_services_mode" ]]; then
|
||||||
|
sentinel_args+=(--mode "$root_services_mode")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if ! awk '$2 == "/media/frigate" || $2 ~ /^\/media\/frigate\//' /proc/mounts | grep -q .; then
|
if ! awk '$2 == "/media/frigate" || $2 ~ /^\/media\/frigate\//' /proc/mounts | grep -q .; then
|
||||||
sentinel_args=()
|
sentinel_args=()
|
||||||
fi
|
fi
|
||||||
/usr/local/bin/fix-ownership "${sentinel_args[@]}" \
|
/usr/local/bin/fix-ownership "${sentinel_args[@]}" \
|
||||||
"${PUID:-1000}" "${PGID:-1000}" /config /media/frigate
|
"${PUID:-1000}" "${PGID:-1000}" /config /media/frigate
|
||||||
|
|
||||||
|
# Root services write some files as root while running (clips
|
||||||
|
# stragglers, caches, stale db journals). These trees are small, so
|
||||||
|
# realign them on every boot. Recordings are chowned at create and
|
||||||
|
# stay behind the sentinel sweep above.
|
||||||
|
if [[ -n "$root_services_mode" ]]; then
|
||||||
|
/usr/local/bin/fix-ownership \
|
||||||
|
"${PUID:-1000}" "${PGID:-1000}" /config /media/frigate/clips /media/frigate/exports
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Single source of truth for aligning volume ownership with the runtime user.
|
# Single source of truth for aligning volume ownership with the runtime user.
|
||||||
#
|
#
|
||||||
# Usage: fix-ownership [--dry-run] [--sentinel FILE] UID GID PATH [PATH...]
|
# Usage: fix-ownership [--dry-run] [--sentinel FILE] [--mode STRING] UID GID PATH [PATH...]
|
||||||
#
|
#
|
||||||
# --dry-run report what would change, touch nothing
|
# --dry-run report what would change, touch nothing
|
||||||
# --sentinel skip entirely when FILE already records "SCHEMA:UID:GID";
|
# --sentinel skip entirely when FILE already records "SCHEMA:UID:GID";
|
||||||
# write it after a successful run (used by the boot path so
|
# write it after a successful run (used by the boot path so
|
||||||
# multi-TB volumes are swept once per UID/schema change, not
|
# multi-TB volumes are swept once per UID/schema change, not
|
||||||
# on every boot)
|
# on every boot)
|
||||||
|
# --mode append STRING to the sentinel, so changing it re-sweeps once
|
||||||
#
|
#
|
||||||
# Only files whose uid OR gid differs are touched, so re-runs are cheap.
|
# Only files whose uid OR gid differs are touched, so re-runs are cheap.
|
||||||
# lost+found is skipped: it belongs to the filesystem, not to Frigate, and
|
# lost+found is skipped: it belongs to the filesystem, not to Frigate, and
|
||||||
@@ -28,6 +29,7 @@ schema=2
|
|||||||
|
|
||||||
dry_run=0
|
dry_run=0
|
||||||
sentinel=""
|
sentinel=""
|
||||||
|
mode=""
|
||||||
|
|
||||||
while [[ "${1:-}" == --* ]]; do
|
while [[ "${1:-}" == --* ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@@ -38,12 +40,18 @@ while [[ "${1:-}" == --* ]]; do
|
|||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
sentinel="$2"; shift 2 ;;
|
sentinel="$2"; shift 2 ;;
|
||||||
|
--mode)
|
||||||
|
if [[ -z "${2:-}" ]]; then
|
||||||
|
echo "[ERROR] fix-ownership: --mode requires a value" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
mode="$2"; shift 2 ;;
|
||||||
*) echo "[ERROR] fix-ownership: unknown option $1" >&2; exit 2 ;;
|
*) echo "[ERROR] fix-ownership: unknown option $1" >&2; exit 2 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ $# -lt 3 ]]; then
|
if [[ $# -lt 3 ]]; then
|
||||||
echo "Usage: fix-ownership [--dry-run] [--sentinel FILE] UID GID PATH..." >&2
|
echo "Usage: fix-ownership [--dry-run] [--sentinel FILE] [--mode STRING] UID GID PATH..." >&2
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -56,9 +64,18 @@ if [[ "$(id -u)" -ne 0 ]]; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# The mode string folds the FRIGATE_ROOT_SERVICES list into the sentinel, so
|
||||||
|
# entering or leaving a granular root mode re-sweeps once. That is the
|
||||||
|
# backstop for anything a root service created that the per-boot sweep and
|
||||||
|
# chown-at-create did not cover.
|
||||||
|
sentinel_content="${schema}:${target_uid}:${target_gid}"
|
||||||
|
if [[ -n "$mode" ]]; then
|
||||||
|
sentinel_content="${sentinel_content}:${mode}"
|
||||||
|
fi
|
||||||
|
|
||||||
# A dry run always inspects: the sentinel records what a past sweep did, not
|
# A dry run always inspects: the sentinel records what a past sweep did, not
|
||||||
# what the volume looks like now, and reporting from it would hide later drift.
|
# what the volume looks like now, and reporting from it would hide later drift.
|
||||||
if [[ "$dry_run" -eq 0 && -n "$sentinel" && -f "$sentinel" && "$(cat "$sentinel")" == "${schema}:${target_uid}:${target_gid}" ]]; then
|
if [[ "$dry_run" -eq 0 && -n "$sentinel" && -f "$sentinel" && "$(cat "$sentinel")" == "$sentinel_content" ]]; then
|
||||||
echo "[INFO] fix-ownership: ${target_uid}:${target_gid} (schema ${schema}) already applied, skipping"
|
echo "[INFO] fix-ownership: ${target_uid}:${target_gid} (schema ${schema}) already applied, skipping"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
@@ -152,6 +169,6 @@ if [[ "$dry_run" -eq 0 && -d /config ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$dry_run" -eq 0 && -n "$sentinel" && "$swept_clean" -eq 1 ]]; then
|
if [[ "$dry_run" -eq 0 && -n "$sentinel" && "$swept_clean" -eq 1 ]]; then
|
||||||
echo "${schema}:${target_uid}:${target_gid}" > "$sentinel" || \
|
echo "$sentinel_content" > "$sentinel" || \
|
||||||
echo "[WARN] fix-ownership: could not write ${sentinel}; the sweep will run again on next boot"
|
echo "[WARN] fix-ownership: could not write ${sentinel}; the sweep will run again on next boot"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user