Self-heal orphaned coturn credentials in ensure_coturn_user()

Answers a direct question from this session: no, reinstalling
asterisk/mattermost did NOT fix a coturn user missing from the live
database, because ensure_coturn_user() only ever calls turnadmin -a in
the else branch — reached only when the cache file (users/<consumer>.env)
is MISSING. A stale-but-present cache file (exactly what a coturn
container/volume recreation without preserving ./db leaves behind, per
this session's real diagnosis) looked identical to a healthy one and was
trusted blindly, so every consumer's installer kept silently reusing
credentials that no longer existed in coturn's database.

Now checks the cached username against coturn's actual live user list on
every call, and re-registers it with the same cached password if it's
missing — the same self-heal pattern this repo already applies elsewhere
(Beszel's compose patch, Vaultwarden's SMTP half-state, FMD's chown).
Re-uses the turnadmin -l log-noise filter from tools/coturn-test-check.sh
(a real "user[realm]" line never contains a space; at least one coturn
build writes its own startup log lines to stdout, not stderr, so a bare
2>/dev/null doesn't catch them).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn
This commit is contained in:
Claude
2026-08-12 11:13:46 +00:00
parent cd1d0e3b40
commit f94f43786f
+25
View File
@@ -1076,6 +1076,31 @@ ensure_coturn_user() {
_u="$(grep '^COTURN_USER=' "$_userfile" | cut -d= -f2-)"
_p="$(grep '^COTURN_PASS=' "$_userfile" | cut -d= -f2-)"
COTURN_USERNAME="$_u" COTURN_PASSWORD="$_p"
# The cache file surviving doesn't mean the username still exists in
# coturn's own live database — confirmed live: a coturn
# container/volume recreated without preserving ./db wipes the
# database while this file (a separate directory) survives
# untouched, silently orphaning every consumer's credentials until
# something re-registers them. Without this check, re-running the
# consumer's installer (fresh or update) never re-registers anything
# since it only ever hits the else branch below on a MISSING cache
# file — a stale-but-present one looked identical to a healthy one.
# A real "user[realm]" line never contains a space; turnadmin -l's
# own startup log lines do (confirmed live, at least one coturn
# build writes them to stdout, not stderr), so filtering on that
# keeps this robust across builds without needing to match a
# specific log format.
local _db_users
_db_users="$(docker exec coturn turnadmin -l -b /var/lib/coturn/turndb 2>/dev/null | grep -v ' ' | sed -E 's/\[.*//' | awk 'NF')"
if ! grep -qx "$_u" <<< "$_db_users"; then
log_warning "coturn user '$_u' ($_consumer) has cached credentials but isn't in coturn's live database — re-registering with the same password."
if docker exec coturn turnadmin -a -u "$_u" -p "$_p" -r "$_realm" -b /var/lib/coturn/turndb >/dev/null 2>&1; then
log_success "Re-registered coturn user '$_u' for $_consumer"
else
log_warning "Could not re-register coturn user '$_u' for $_consumer — is the coturn container running?"
fi
fi
else
COTURN_USERNAME="$_consumer"
COTURN_PASSWORD="$(generate_password 24)"