Fix app_voicemail module-load collision via modules.conf

Live-discovered bug, present on every install using this script, not
specific to any one box or extension: the easy-asterisk image ships
app_voicemail.so, app_voicemail_imap.so, and app_voicemail_odbc.so all
autoloading by default -- three alternative storage backends for the
SAME application (VoiceMail, VoiceMailMain, VMAuthenticate,
VoiceMailPlayMsg, VMSayName, the VM_INFO function, several AMI
actions), which collide registering those names against each other on
every single Asterisk start. This box's own container log showed the
exact signature on every restart: "Already have an application
'VoiceMail'" (and every sibling) followed by "app_voicemail.c:15897
load_module: Failure registering applications, functions or tests" --
app_voicemail never actually finished loading. Confirmed against
Asterisk's own documentation this session rather than assumed: this
is a known multi-backend conflict ("administrators should enable only
one module at a time"), not something specific to this repo's config.

Fix: new _asterisk_write_modules_conf, called from both the fresh-
install and update paths (matching voicemail-dialplan.conf's own
call-site pattern) alongside the other config/asterisk files, all
sharing the already-bind-mounted ./config/asterisk:/etc/asterisk
volume -- no new mount needed. noloads the two backends this repo
never configures (no IMAP/ODBC settings are ever written anywhere in
this script), leaving only the plain file-based app_voicemail.so
(the one voicemail.conf's [default] mailboxes actually target) to
load cleanly. Regenerated on every install/update, unlike
voicemail.conf, since modules.conf carries no per-install state of
its own -- consistent with how messaging-dialplan.conf/voicemail-
dialplan.conf are already handled, and added to their same chmod 644
line.

Requires a container restart to take effect on an existing install
(re-run `sudo ./setup.sh asterisk` -> Update, which regenerates this
file, then restart the container once).

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-16 19:50:23 +00:00
parent be684e114d
commit 930233cc7f
+39 -2
View File
@@ -1063,6 +1063,41 @@ operator=no
EOF EOF
} }
# The easy-asterisk image ships app_voicemail.so, app_voicemail_imap.so, and
# app_voicemail_odbc.so all autoloading by default — three alternative
# storage backends for the SAME application (VoiceMail, VoiceMailMain,
# VM_INFO, etc.), which collide registering those names against each other
# on every single Asterisk start. Confirmed live: this box's own log on
# every restart shows "Already have an application 'VoiceMail'" (and every
# sibling app/function) followed by "app_voicemail.c:15897 load_module:
# Failure registering applications, functions or tests" — app_voicemail
# never actually finishes loading, on every install using this script, not
# something specific to one box or one extension. This repo only ever uses
# the plain file-based backend (voicemail.conf's [default] mailboxes,
# written above), so noload the other two — modules.conf lands in the same
# already-bind-mounted config/asterisk directory, no new volume needed.
# Regenerated on every install/update (unlike voicemail.conf) since it
# carries no per-install state of its own.
_asterisk_write_modules_conf() {
local FILE="$1"
cat > "$FILE" << 'EOF'
; services/asterisk.sh — regenerated on every install/update; edit there,
; not here directly.
;
; app_voicemail_imap/_odbc are alternative voicemail storage backends this
; repo never configures (no IMAP/ODBC settings are ever written) — loading
; them alongside the plain file-based app_voicemail.so makes all three
; collide registering the same application/function names, and
; app_voicemail.so is the one that ends up losing that race and failing to
; load at all. noload the two unused backends so the one actually
; configured (file-based, via voicemail.conf) loads cleanly.
[modules]
autoload=yes
noload => app_voicemail_imap.so
noload => app_voicemail_odbc.so
EOF
}
# Same anchor-position reasoning as _asterisk_patch_messaging_vendor_files: # Same anchor-position reasoning as _asterisk_patch_messaging_vendor_files:
# Same anchor as messaging's own patch (see the comment above # Same anchor as messaging's own patch (see the comment above
# _asterisk_patch_messaging_vendor_files for the live-confirmed reasoning): # _asterisk_patch_messaging_vendor_files for the live-confirmed reasoning):
@@ -2021,9 +2056,10 @@ install_asterisk() {
_asterisk_patch_voicemail_vendor_files "$EA_DIR" _asterisk_patch_voicemail_vendor_files "$EA_DIR"
_asterisk_write_voicemail_dialplan "$EA_DIR/config/asterisk/voicemail-dialplan.conf" _asterisk_write_voicemail_dialplan "$EA_DIR/config/asterisk/voicemail-dialplan.conf"
_asterisk_write_voicemail_conf "$EA_DIR/config/asterisk/voicemail.conf" _asterisk_write_voicemail_conf "$EA_DIR/config/asterisk/voicemail.conf"
_asterisk_write_modules_conf "$EA_DIR/config/asterisk/modules.conf"
_asterisk_ensure_live_voicemail_include "$EA_DIR" "$CONTAINER" _asterisk_ensure_live_voicemail_include "$EA_DIR" "$CONTAINER"
ensure_docker_dir_ownership "$EA_DIR/config/asterisk" ensure_docker_dir_ownership "$EA_DIR/config/asterisk"
chmod 644 "$EA_DIR/config/asterisk/messaging-dialplan.conf" "$EA_DIR/config/asterisk/voicemail-dialplan.conf" chmod 644 "$EA_DIR/config/asterisk/messaging-dialplan.conf" "$EA_DIR/config/asterisk/voicemail-dialplan.conf" "$EA_DIR/config/asterisk/modules.conf"
log_info "Rebuilding and restarting containers..." log_info "Rebuilding and restarting containers..."
if docker compose up -d --build --force-recreate; then if docker compose up -d --build --force-recreate; then
@@ -2116,9 +2152,10 @@ install_asterisk() {
_asterisk_patch_voicemail_vendor_files "$EA_DIR" _asterisk_patch_voicemail_vendor_files "$EA_DIR"
_asterisk_write_voicemail_dialplan "$EA_DIR/config/asterisk/voicemail-dialplan.conf" _asterisk_write_voicemail_dialplan "$EA_DIR/config/asterisk/voicemail-dialplan.conf"
_asterisk_write_voicemail_conf "$EA_DIR/config/asterisk/voicemail.conf" _asterisk_write_voicemail_conf "$EA_DIR/config/asterisk/voicemail.conf"
_asterisk_write_modules_conf "$EA_DIR/config/asterisk/modules.conf"
_asterisk_ensure_live_voicemail_include "$EA_DIR" "$CONTAINER" _asterisk_ensure_live_voicemail_include "$EA_DIR" "$CONTAINER"
ensure_docker_dir_ownership "$EA_DIR/config/asterisk" ensure_docker_dir_ownership "$EA_DIR/config/asterisk"
chmod 644 "$EA_DIR/config/asterisk/messaging-dialplan.conf" "$EA_DIR/config/asterisk/voicemail-dialplan.conf" chmod 644 "$EA_DIR/config/asterisk/messaging-dialplan.conf" "$EA_DIR/config/asterisk/voicemail-dialplan.conf" "$EA_DIR/config/asterisk/modules.conf"
# ── Domain / networking mode ────────────────────────────────────────────── # ── Domain / networking mode ──────────────────────────────────────────────
# A public cloud box is always reachable from anywhere, so there's no # A public cloud box is always reachable from anywhere, so there's no