350 lines
9.4 KiB
Bash
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 "$@"
|