Merge pull request #317 from outis1one/claude/ionos-script-integration-x32ofw

Claude/ionos script integration x32ofw
This commit is contained in:
Outis
2026-08-12 09:11:45 -04:00
committed by GitHub
8 changed files with 172 additions and 20 deletions
+1 -1
View File
@@ -143,7 +143,7 @@ account default in step 6 and skip even that:
sudo ./setup.sh pstn-trunk
```
- Existing install → choose **update** (`r`) if you're just changing the
- Existing install → choose **update** (`u`) if you're just changing the
DID/server, or the CLI will walk fresh prompts if none exists yet.
- Provider quick-pick: **1) Anveo Direct** — pre-fills `sbc.anveo.com` and
Anveo's 4 published signaling IPs (only one of which the hostname
+29 -4
View File
@@ -718,12 +718,12 @@ prompt_reinstall_mode() {
return
fi
echo " Existing install detected. Choose:"
echo " r) Reinstall in place — refresh vendor files/config, keep existing settings"
echo " f) Full install — re-run every prompt from scratch"
echo " u) Update — refresh vendor files/config, keep existing settings"
echo " f) Full reinstall — re-run every prompt from scratch"
echo " c) Cancel — leave everything as-is [default]"
read -p " Choice [r/f/c, Enter=cancel]: " response
read -p " Choice [u/f/c, Enter=cancel]: " response
case "${response,,}" in
r) eval "$varname='update'" ;;
u) eval "$varname='update'" ;;
f) eval "$varname='fresh'" ;;
*) eval "$varname='cancel'" ;;
esac
@@ -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)"
+39 -5
View File
@@ -82,12 +82,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
return
fi
echo " Existing install detected. Choose:"
echo " r) Reinstall in place — refresh vendor files/config, keep existing settings"
echo " f) Full install — re-run every prompt from scratch"
echo " u) Update — refresh vendor files/config, keep existing settings"
echo " f) Full reinstall — re-run every prompt from scratch"
echo " c) Cancel — leave everything as-is [default]"
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
case "${_r,,}" in
r) eval "$_var='update'" ;;
u) eval "$_var='update'" ;;
f) eval "$_var='fresh'" ;;
*) eval "$_var='cancel'" ;;
esac
@@ -1655,6 +1655,21 @@ install_asterisk() {
log_warning "docker compose up failed — check: docker compose -f $EA_DIR/docker-compose.yml logs"
fi
# Self-heal a stale/orphaned shared-coturn registration on
# every update, not just a full reinstall — the check inside
# ensure_coturn_user() is what actually re-registers a
# missing user, this just needs to reach it. Gated on NOT
# having an embedded coturn: an install with its own
# dedicated coturn deliberately never touches the shared one
# on update (see the warning above and CLAUDE.md's coturn
# migration guidance) — calling this unconditionally would
# silently chain-install services/coturn.sh for a box that
# was never using it, the exact "don't migrate silently on
# update" mistake that guidance warns against.
if [[ "$_HAD_EMBEDDED_COTURN" != true ]]; then
ensure_coturn_user "asterisk"
fi
_asterisk_run_presence_step "$EA_DIR" "$CONTAINER"
_asterisk_offer_dashboard_and_trunk "$EA_DIR"
@@ -1677,7 +1692,26 @@ install_asterisk() {
return 0
;;
fresh)
log_info "Proceeding with a full fresh reinstall — every prompt below runs from scratch."
echo ""
log_warning "Full reinstall stops the existing containers and re-runs every"
log_warning "prompt below from scratch (domain, networking, firewall, Caddy/"
log_warning "Authelia). The TURN credential registered with the shared coturn"
log_warning "service is reused as-is — no need to touch coturn for this."
local _WIPE_PBX_DATA=""
prompt_yn " Also delete stored PBX data (extensions, voicemail, recordings, spool)? (y/n):" "n" _WIPE_PBX_DATA
log_info "Stopping the existing containers..."
(cd "$EA_DIR" && docker compose down 2>/dev/null)
if [[ "$_WIPE_PBX_DATA" =~ ^[Yy]$ ]]; then
rm -rf "$EA_DIR/config/asterisk" "$EA_DIR/spool" "$EA_DIR/logs" "$EA_DIR/lib"
log_warning "Deleted config/asterisk, spool, logs, and lib — extensions,"
log_warning "voicemail, and call recordings are gone."
if declare -F install_pstn-trunk >/dev/null 2>&1 || [ -f "$EA_DIR/pstn-trunk-usage-alert.sh" ]; then
log_warning "PSTN trunk patches config/asterisk's dialplan — re-run"
log_warning "'sudo ./setup.sh pstn-trunk' afterward to restore it."
fi
fi
;;
esac
fi
+25 -4
View File
@@ -87,12 +87,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
local _var="$1" _r
if [[ "${UNATTENDED:-false}" == "true" ]]; then eval "$_var='cancel'"; return; fi
echo " Existing install detected. Choose:"
echo " r) Reinstall in place — refresh vendor files, keep existing settings"
echo " f) Full install — re-run every prompt from scratch"
echo " u) Update — refresh vendor files, keep existing settings"
echo " f) Full reinstall — re-run every prompt from scratch"
echo " c) Cancel — leave everything as-is [default]"
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
case "${_r,,}" in
r) eval "$_var='update'" ;;
u) eval "$_var='update'" ;;
f) eval "$_var='fresh'" ;;
*) eval "$_var='cancel'" ;;
esac
@@ -186,6 +186,27 @@ install_coturn() {
log_warning "change the host/port/realm below, every already-registered consumer"
log_warning "(Asterisk, Mattermost, ...) keeps pointing at the OLD values in its own"
log_warning ".env until you re-run that service's installer too."
local _consumers=""
[ -d "$DIR/users" ] && _consumers="$(find "$DIR/users" -maxdepth 1 -name '*.env' -printf '%f\n' 2>/dev/null | sed 's/\.env$//' | tr '\n' ' ')"
if [ -n "$_consumers" ]; then
echo ""
log_info "Registered consumers: $_consumers"
local _WIPE_USERS=""
prompt_yn " Also delete all TURN user credentials and the user database (forces every consumer above to re-register)? (y/n):" "n" _WIPE_USERS
if [[ "$_WIPE_USERS" =~ ^[Yy]$ ]]; then
rm -rf "$DIR/users" "$DIR/db"
mkdir -p "$DIR/db" "$DIR/users"
# The running container (if any) still holds the old,
# now-deleted turndb file open — new turnadmin writes
# to the fresh file at that path go unseen until the
# server process restarts and reopens it.
docker restart coturn >/dev/null 2>&1
log_warning "Deleted TURN credentials and the user database."
log_warning "Re-run each consumer's installer in Update mode afterward —"
log_warning "ensure_coturn_user() auto-recovers a fresh credential for it."
fi
fi
;;
esac
fi
+14
View File
@@ -314,6 +314,20 @@ install_mattermost() {
log_warning "the shared coturn service — the Calls plugin's TURN config in System"
log_warning "Console will need updating to the new credentials afterward (see below)."
fi
echo ""
log_warning "Full reinstall stops the existing containers and re-runs every prompt"
log_warning "below from scratch. The TURN credential registered with the shared"
log_warning "coturn service is reused as-is — no need to touch coturn for this."
local _WIPE_MM_DATA=""
prompt_yn " Also delete stored data (Postgres database, uploaded files, config, plugins)? (y/n):" "n" _WIPE_MM_DATA
log_info "Stopping the existing containers..."
(cd "$DIR" && docker compose down 2>/dev/null)
if [[ "$_WIPE_MM_DATA" =~ ^[Yy]$ ]]; then
rm -rf "$DIR/db" "$DIR/data" "$DIR/logs" "$DIR/config" "$DIR/plugins"
log_warning "Deleted the Postgres database, uploaded files, config, and plugins."
fi
;;
esac
fi
+52 -1
View File
@@ -184,7 +184,24 @@ install_security-dashboard() {
log_info "Leaving the existing install as-is."
return 0
;;
fresh) ;;
fresh)
echo ""
log_warning "Full reinstall stops the dashboard and removes its systemd unit,"
log_warning "sudoers grant, Caddy block, service user, and app files, then sets"
log_warning "it up again from scratch — every prompt below runs as if this were"
log_warning "a brand new install."
local _WIPE_ADMINS=""
prompt_yn " Also delete dashboard-admins.conf (per-admin Calls/Texts/Voicemail scoping)? (y/n):" "n" _WIPE_ADMINS
local _ADMINS_BACKUP=""
if [[ ! "$_WIPE_ADMINS" =~ ^[Yy]$ ]] && [ -f "$APP_DIR/dashboard-admins.conf" ]; then
_ADMINS_BACKUP="$(mktemp)"
cp "$APP_DIR/dashboard-admins.conf" "$_ADMINS_BACKUP"
log_info "Preserving dashboard-admins.conf across the reinstall."
fi
_secdash_teardown "$APP_DIR" "$SVC_USER" "$DASHBOARD_PORT"
;;
esac
fi
@@ -197,6 +214,11 @@ install_security-dashboard() {
_secdash_grant_asterisk_access "$SVC_USER" "$ASTERISK_LOG_DIR" "$ASTERISK_CONFIG_DIR" "$ASTERISK_EA_CONFIG_DIR" "$ASTERISK_SPOOL_DIR"
mkdir -p "$APP_DIR"
if [ -n "${_ADMINS_BACKUP:-}" ]; then
cp "$_ADMINS_BACKUP" "$APP_DIR/dashboard-admins.conf"
rm -f "$_ADMINS_BACKUP"
log_success "Restored dashboard-admins.conf"
fi
_secdash_write_app "$APP_DIR"
chown -R "$SVC_USER:$SVC_USER" "$APP_DIR"
_secdash_write_asn_helper "$APP_DIR"
@@ -974,6 +996,35 @@ _secdash_remove_caddy_block() {
log_info "Removed the existing dashboard Caddy block (regenerating it fresh)."
}
# Full teardown for "Full reinstall" — stops the service and removes
# everything a fresh install recreates: systemd unit, sudoers grant, Caddy
# site block, the secdash system user, and the app directory. Non-Docker
# service (systemd + /opt, not a container), so lib/common.sh's
# remove_service() (Docker-only, $DOCKER_DIR/<name>) doesn't apply here —
# this is the equivalent for this one service. Callers are responsible for
# backing up/restoring anything under $_app_dir they want to survive (see
# the dashboard-admins.conf handling around the "fresh" case in
# install_security-dashboard() — this function does not know which files,
# if any, the caller wants to keep).
_secdash_teardown() {
local _app_dir="$1" _svc_user="$2" _port="$3"
systemctl stop security-dashboard 2>/dev/null || true
systemctl disable security-dashboard 2>/dev/null || true
rm -f /etc/systemd/system/security-dashboard.service
systemctl daemon-reload
rm -f /etc/sudoers.d/security-dashboard
_secdash_remove_caddy_block "$_port"
id "$_svc_user" &>/dev/null && userdel "$_svc_user" 2>/dev/null
rm -rf "$_app_dir"
log_success "Removed security-dashboard's systemd unit, sudoers grant, Caddy block, user, and app files."
}
# Root-owned helper for editing CrowdSec's Asterisk-scenario YAMLs — the
# secdash service user (--shell /usr/sbin/nologin, no special file grants)
# cannot write /etc/crowdsec/scenarios/*.yaml directly (root:root, mode
+4 -4
View File
@@ -95,12 +95,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
local _var="$1" _r
if [[ "${UNATTENDED:-false}" == "true" ]]; then eval "$_var='cancel'"; return; fi
echo " Existing install detected. Choose:"
echo " r) Reinstall in place — refresh image/compose, keep database and settings"
echo " f) Full install — re-run every prompt from scratch"
echo " u) Update — refresh image/compose, keep database and settings"
echo " f) Full reinstall — re-run every prompt from scratch"
echo " c) Cancel — leave everything as-is [default]"
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
case "${_r,,}" in
r) eval "$_var='update'" ;;
u) eval "$_var='update'" ;;
f) eval "$_var='fresh'" ;;
*) eval "$_var='cancel'" ;;
esac
+8 -1
View File
@@ -76,7 +76,14 @@ ok "Relay port range: ${COTURN_MIN_PORT}-${COTURN_MAX_PORT}"
# ── Registered consumers ──────────────────────────────────────────────────────
section "Registered consumers"
DB_USERS="$(docker exec coturn turnadmin -l -b /var/lib/coturn/turndb 2>/dev/null | sed -E 's/\[.*//' | awk 'NF' | sort -u)"
# turnadmin -l writes its own startup log lines ("INFO SQLite connection
# was closed.", "INFO log file opened: ...") to STDOUT on at least some
# coturn builds, not stderr — confirmed live, `2>/dev/null` alone let them
# through and got misparsed as usernames. A real "user[realm]" line never
# contains a space; every log line here does, so filtering those out is a
# safe, simple way to keep only genuine entries regardless of which coturn
# build's log-noise happens to leak onto stdout.
DB_USERS="$(docker exec coturn turnadmin -l -b /var/lib/coturn/turndb 2>/dev/null | grep -v ' ' | sed -E 's/\[.*//' | awk 'NF' | sort -u)"
if [ -z "$DB_USERS" ]; then
warn "No users found in coturn's own database — nothing has actually registered yet, or turnadmin -l's output format changed. Raw:"
docker exec coturn turnadmin -l -b /var/lib/coturn/turndb 2>&1 | sed 's/^/ /'