Files

350 lines
9.4 KiB
Bash

#!/bin/sh
set -eu
find_janus_config() {
for candidate in \
/usr/local/etc/janus/janus.jcfg \
/etc/janus/janus.jcfg
do
if [ -f "$candidate" ]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
find_signaling_config() {
for candidate in \
/conf/signaling.conf
do
if [ -f "$candidate" ]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
find_eturnal_vm_args() {
for candidate in /opt/eturnal/releases/*/vm.args; do
if [ -f "$candidate" ]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
find_eturnal_epmd_override_files() {
find /opt/eturnal /etc -type f 2>/dev/null \
| while IFS= read -r candidate; do
if [ "$candidate" = "/usr/local/bin/qni-talk-entrypoint.sh" ] || [ "$candidate" = "$0" ]; then
continue
fi
if [ ! -w "$candidate" ]; then
continue
fi
if grep -Iq . "$candidate" 2>/dev/null && grep -q -- '-erl_epmd_port' "$candidate" 2>/dev/null; then
printf '%s\n' "$candidate"
fi
done
}
apply_janus_stun_patch() {
config_path="$1"
stun_server="$2"
stun_port="$3"
tmp_path="$(mktemp)"
awk -v stun_server="$stun_server" -v stun_port="$stun_port" '
BEGIN {
in_nat = 0
nat_found = 0
server_written = 0
port_written = 0
}
/^[[:space:]]*nat[[:space:]]*:[[:space:]]*\{/ {
print
in_nat = 1
nat_found = 1
next
}
in_nat && /^[[:space:]]*stun_server[[:space:]]*=/ {
if (!server_written) {
print " stun_server = \"" stun_server "\""
server_written = 1
}
next
}
in_nat && /^[[:space:]]*stun_port[[:space:]]*=/ {
if (!port_written) {
print " stun_port = " stun_port
port_written = 1
}
next
}
in_nat && /^[[:space:]]*\}/ {
if (!server_written) {
print " stun_server = \"" stun_server "\""
server_written = 1
}
if (!port_written) {
print " stun_port = " stun_port
port_written = 1
}
print
in_nat = 0
next
}
{ print }
END {
if (!nat_found) {
print ""
print "nat: {"
print " stun_server = \"" stun_server "\""
print " stun_port = " stun_port
print "}"
}
}
' "$config_path" > "$tmp_path"
cat "$tmp_path" > "$config_path"
rm -f "$tmp_path"
}
apply_signaling_port_patch() {
config_path="$1"
listen_host="$2"
listen_port="$3"
tmp_path="$(mktemp)"
awk -v listen_host="$listen_host" -v listen_port="$listen_port" '
BEGIN {
in_http = 0
http_found = 0
listen_written = 0
}
/^[[:space:]]*\[http\][[:space:]]*$/ {
print
in_http = 1
http_found = 1
next
}
in_http && /^[[:space:]]*\[/ {
if (!listen_written) {
print "listen = " listen_host ":" listen_port
listen_written = 1
}
print
in_http = 0
next
}
in_http && /^[[:space:]]*listen[[:space:]]*=/ {
if (!listen_written) {
print "listen = " listen_host ":" listen_port
listen_written = 1
}
next
}
{ print }
END {
if (in_http && !listen_written) {
print "listen = " listen_host ":" listen_port
listen_written = 1
}
if (!http_found) {
print ""
print "[http]"
print "listen = " listen_host ":" listen_port
}
}
' "$config_path" > "$tmp_path"
cat "$tmp_path" > "$config_path"
rm -f "$tmp_path"
}
apply_eturnal_epmd_patch() {
config_path="$1"
epmd_port="$2"
tmp_path="$(mktemp)"
if [ ! -w "$config_path" ]; then
echo "Warning: eturnal EPMD patch target is not writable: ${config_path}" >&2
rm -f "$tmp_path"
return 1
fi
awk -v epmd_port="$epmd_port" '
{
line = $0
# Literal port usage.
gsub(/-erl_epmd_port[[:space:]]+[0-9]+/, "-erl_epmd_port " epmd_port, line)
# Shell-expanded defaults commonly used by release scripts.
gsub(/-erl_epmd_port[[:space:]]+\$\{ERL_EPMD_PORT:-[0-9]+\}/, "-erl_epmd_port " epmd_port, line)
gsub(/-erl_epmd_port[[:space:]]+\$\{EPMD_PORT:-[0-9]+\}/, "-erl_epmd_port " epmd_port, line)
gsub(/ERL_EPMD_PORT:-[0-9]+/, "ERL_EPMD_PORT:-" epmd_port, line)
gsub(/EPMD_PORT:-[0-9]+/, "EPMD_PORT:-" epmd_port, line)
print line
}
' "$config_path" > "$tmp_path"
cat "$tmp_path" > "$config_path"
rm -f "$tmp_path"
}
apply_eturnal_epmd_patch_all() {
epmd_port="$1"
patched_any="0"
overrides_list="$(mktemp)"
if eturnal_vm_args_path="$(find_eturnal_vm_args)"; then
echo "Applying eturnal EPMD patch: port=${epmd_port} config=${eturnal_vm_args_path}"
if apply_eturnal_epmd_patch "$eturnal_vm_args_path" "$epmd_port"; then
patched_any="1"
fi
else
echo "Warning: eturnal vm.args file not found; cannot apply EPMD vm.args patch." >&2
fi
find_eturnal_epmd_override_files > "$overrides_list"
while IFS= read -r override_path; do
if [ -n "$override_path" ] && [ "$override_path" != "${eturnal_vm_args_path:-}" ]; then
echo "Applying eturnal EPMD override patch: port=${epmd_port} file=${override_path}"
if apply_eturnal_epmd_patch "$override_path" "$epmd_port"; then
patched_any="1"
fi
fi
done < "$overrides_list"
rm -f "$overrides_list"
if [ "$patched_any" != "1" ]; then
echo "Warning: no eturnal files containing -erl_epmd_port were patched." >&2
fi
}
restart_signaling_supervisor_programs() {
if ! command -v supervisorctl >/dev/null 2>&1; then
return 0
fi
program_names="$(
supervisorctl status 2>/dev/null | awk '
{
name = $1
lowered = tolower(name)
if (lowered ~ /signal/ || lowered ~ /spreed/) {
print name
}
}
' | sort -u
)"
if [ -n "$program_names" ]; then
echo "Restarting signaling supervisor programs: $(echo "$program_names" | tr '\n' ' ')"
echo "$program_names" | while IFS= read -r program_name; do
if [ -n "$program_name" ]; then
supervisorctl restart "$program_name" >/dev/null 2>&1 || true
fi
done
return 0
fi
supervisorctl restart all >/dev/null 2>&1 || true
}
ensure_signaling_port_after_startup() {
desired_listen="$1:$2"
attempts="${3:-30}"
while [ "$attempts" -gt 0 ]; do
if signaling_config_path="$(find_signaling_config)"; then
current_listen="$(
awk '
/^[[:space:]]*\[http\][[:space:]]*$/ { in_http = 1; next }
in_http && /^[[:space:]]*\[/ { in_http = 0 }
in_http && /^[[:space:]]*listen[[:space:]]*=/ {
sub(/^[[:space:]]*listen[[:space:]]*=[[:space:]]*/, "", $0)
print $0
exit
}
' "$signaling_config_path" 2>/dev/null
)"
if [ "$current_listen" = "$desired_listen" ]; then
return 0
fi
if [ -n "$current_listen" ]; then
echo "Re-applying signaling listen patch after base startup: current=${current_listen} desired=${desired_listen}"
apply_signaling_port_patch "$signaling_config_path" "$1" "$2"
restart_signaling_supervisor_programs
return 0
fi
fi
attempts=$((attempts - 1))
sleep 1
done
echo "Warning: signaling config did not become patchable after startup; desired listen=${desired_listen}" >&2
return 1
}
janus_stun_server="${TALK_JANUS_STUN_SERVER:-${TALK_STUN_SERVER:-${TALK_TURN_HOST:-}}}"
janus_stun_server="${janus_stun_server%%:*}"
janus_stun_port="${TALK_JANUS_STUN_PORT:-${TALK_TURN_PORT:-3478}}"
signaling_port="${TALK_SIGNALING_PORT:-8081}"
signaling_bind_host="${TALK_SIGNALING_BIND_HOST:-0.0.0.0}"
eturnal_epmd_port="${TALK_ETURNAL_EPMD_PORT:-3470}"
if [ -n "$eturnal_epmd_port" ]; then
# Some eturnal launcher scripts expand ERL_EPMD_PORT defaults at runtime
# (e.g. ${ERL_EPMD_PORT:-3470}). Exporting here ensures the runtime value wins
# even if upstream startup scripts are regenerated after our file patches.
export ERL_EPMD_PORT="$eturnal_epmd_port"
export EPMD_PORT="$eturnal_epmd_port"
echo "Applying eturnal runtime env: ERL_EPMD_PORT=${ERL_EPMD_PORT}"
fi
if [ -n "$janus_stun_server" ]; then
if janus_config_path="$(find_janus_config)"; then
echo "Applying Janus STUN patch: server=${janus_stun_server} port=${janus_stun_port} config=${janus_config_path}"
apply_janus_stun_patch "$janus_config_path" "$janus_stun_server" "$janus_stun_port"
else
echo "Warning: Janus config file not found; cannot apply STUN patch." >&2
fi
else
echo "Janus STUN patch skipped: TALK_JANUS_STUN_SERVER/TALK_STUN_SERVER/TALK_TURN_HOST not set."
fi
if [ -n "$signaling_port" ]; then
if signaling_config_path="$(find_signaling_config)"; then
echo "Applying signaling listen patch: listen=${signaling_bind_host}:${signaling_port} config=${signaling_config_path}"
apply_signaling_port_patch "$signaling_config_path" "$signaling_bind_host" "$signaling_port"
else
echo "Warning: signaling config file not found; cannot apply signaling listen patch." >&2
fi
fi
if [ -n "$eturnal_epmd_port" ]; then
apply_eturnal_epmd_patch_all "$eturnal_epmd_port"
fi
if [ "$#" -eq 0 ]; then
set -- /start.sh supervisord -c /supervisord.conf
fi
if [ "$1" = "/start.sh" ]; then
"$@" &
main_pid="$!"
if [ -n "$signaling_port" ]; then
ensure_signaling_port_after_startup "$signaling_bind_host" "$signaling_port" 45 || true
fi
wait "$main_pid"
exit $?
fi
exec "$@"