From 3eadcdb58472abe5cd7cbd0a87b80564b814bb03 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 19 Aug 2026 02:28:05 +0000 Subject: [PATCH] Migrate Asterisk Intercom, redesigned as SIP-extension-only; bump to v2.10.0 New menus/addon_asterisk_intercom.sh, wired into install.sh's Addons menu. The legacy addon offered Client Only (Baresip SIP client), Server Only, and Full (server + client), where Server/Full downloaded and ran a third-party installer from a separate "Easy Asterisk" repository to stand up a whole Asterisk PBX. That repository has since gone through a major rework upstream, so this migration drops the PBX-install path entirely: the addon now only installs Baresip and registers this kiosk as a SIP extension against an Asterisk server the user already has running elsewhere. It never installs or manages Asterisk itself. The legacy script's own three-option version is untouched, same as every other migrated menu. Dropped the legacy client path's dependency on the Easy Asterisk repo's GitHub API for version tracking - now reads the real installed baresip package version via dpkg instead. Added an uninstall option, which the legacy addon never had at all. Bug fix found while testing: an unguarded `ver=$(baresip_installed_version)` assignment crashed the whole session under set -e the first time status was checked before Baresip was installed (dpkg-query legitimately fails when the package isn't there). Guarded with `|| true`. Full command-level stubbed test suite covering configure (manual/auto- answer, TLS port bump, apt-install failure) and uninstall (keep/purge config) for both fresh and already-configured states. Full 13-suite regression + real end-to-end menu navigation via install.sh all pass. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01VfsFSoRqfbRG7XAg5RoE7e --- Readme.md | 120 +++++++------ install.sh | 9 +- menus/addon_asterisk_intercom.sh | 279 +++++++++++++++++++++++++++++++ ubuntu-based-kiosk.sh | 34 +++- 4 files changed, 390 insertions(+), 52 deletions(-) create mode 100644 menus/addon_asterisk_intercom.sh diff --git a/Readme.md b/Readme.md index f0c2338..037e68a 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ # Ubuntu Based Kiosk -**Current Version:** 2.9.0 (check script header for latest version) +**Current Version:** 2.10.0 (check script header for latest version) **Built with Claude Sonnet 4.6 AI assistance** **License:** GPL v3 - Keep derivatives open source **Repository:** https://github.com/outis1one/ubuntu-based-kiosk/ @@ -251,12 +251,20 @@ Both can be used at the same time — they serve different purposes: --- ### Communication -- **Easy Asterisk Intercom** - Voice communication and intercom system - - Downloads latest version from Easy Asterisk repository - - Automatic update detection and installation - - Configuration preservation during updates - - Full Asterisk PBX integration - - SIP/PJSIP support for IP phones and softphones +- **Asterisk Intercom** (`./install.sh` → Addons) - connects this kiosk + as a Baresip SIP extension to an Asterisk server you already have + running elsewhere; does not install or manage Asterisk itself + - Manual or auto-answer (intercom) mode + - Optional TLS/SRTP transport + - Uninstall support (with or without removing saved credentials) +- **Legacy Easy Asterisk Intercom** (`./ubuntu-based-kiosk.sh` → Addons, + not yet retired) - the original three-option version: Client Only + (same Baresip client as above), Server Only, or Full, where Server/ + Full download and run a third-party installer from a separate + "Easy Asterisk" repository to stand up a whole Asterisk PBX on this + device. That repository has since gone through a major rework + upstream, so the modular `./install.sh` version above only carries + the client/endpoint piece forward - see "Modular Management" below. ### Audio - **Lyrion Music Server (LMS)** - Formerly Logitech Media Server @@ -594,51 +602,55 @@ smb://WORKGROUP/COMPUTER/PrinterName # 4. Restart Kiosk Display ``` -### Installing Easy Asterisk Intercom +### Installing Asterisk Intercom -The Easy Asterisk Intercom addon provides voice communication capabilities to your kiosk system. +The Asterisk Intercom addon connects this kiosk as a SIP extension to an +Asterisk server you already have running elsewhere (your own PBX, a +Docker container, another box on the network - anywhere). It installs +and configures Baresip as that extension; it does not install or manage +Asterisk itself. **Access the addon menu:** ```bash -./ubuntu-based-kiosk.sh -# Select: 2) Addons -# Then: 4) Easy Asterisk Intercom +git clone https://github.com/outis1one/ubuntu-based-kiosk/ +cd ubuntu-based-kiosk +./install.sh +# Select: 2) Addons → Asterisk Intercom (SIP Extension) ``` -**Features:** -- **Automatic installation** - Downloads and installs the latest version from the Easy Asterisk repository -- **Update detection** - Checks for newer versions and prompts to update -- **Safe re-runs** - Can be run multiple times without breaking existing configurations -- **Config preservation** - Automatically backs up and restores configurations during updates -- **Full Asterisk PBX** - Complete telephony features including SIP, extensions, voicemail +**What you'll be asked for** (must match what's already configured on +the Asterisk server): server IP/hostname, SIP port (default 5060, or +5061 if you enable TLS), extension number, SIP password, and whether to +auto-answer incoming calls (intercom mode) or ring for manual answer. -**Installation behavior:** -- **First install:** Downloads latest version from https://github.com/outis1one/easy-asterisk -- **Already installed (latest):** Prompts to re-run installation (preserves configs) -- **Update available:** Prompts to update and shows version difference -- **All scenarios:** Configuration files in `/etc/asterisk/` and installation settings are preserved - -**Managing Easy Asterisk:** +**Managing the client:** ```bash -# Check installation status -systemctl status asterisk +# Check status (as the kiosk user) +sudo -u kiosk systemctl --user status baresip -# View Asterisk console -asterisk -rvvv +# Restart +sudo -u kiosk systemctl --user restart baresip -# Restart Asterisk -systemctl restart asterisk +# View logs +sudo -u kiosk journalctl --user -u baresip -f -# Configure intercom (rerun installation to update) -./ubuntu-based-kiosk.sh -# Select: 2) Addons → 4) Easy Asterisk Intercom +# Reconfigure or uninstall +./install.sh +# Select: 2) Addons → Asterisk Intercom (SIP Extension) ``` **Installation location:** -- Installation files: `/opt/easy-asterisk/` -- Configuration: `/etc/asterisk/` -- Version tracking: `/opt/easy-asterisk/.version` -- Config backups: `/opt/easy-asterisk/config_backup/` +- Baresip config: `~kiosk/.baresip/` (`accounts`, `config`) +- systemd user unit: `~kiosk/.config/systemd/user/baresip.service` + +**Not covered here:** standing up the Asterisk PBX server itself. The +legacy `ubuntu-based-kiosk.sh` still offers a Server/Full option that +downloads and runs a third-party installer from a separate "Easy +Asterisk" repository - that repository has since gone through a major +rework upstream, so it isn't carried forward into this addon. If you +need a PBX, set one up separately (that same legacy option, a +FreePBX/Issabel image, a Dockerized Asterisk, etc.) and point this +addon at it as a plain SIP extension. ### Updating Electron @@ -1221,6 +1233,12 @@ terminal menu and the web UI, so they can't drift apart). start script and systemd unit go through `$BIN_DIR`/`$SYSTEMD_DIR` like every other addon; LMS's own apt repo/GPG key/ufw rules stay at their real fixed system paths, same as CUPS. +- `menus/addon_asterisk_intercom.sh` — **Asterisk Intercom** (Addons): + installs Baresip and registers this kiosk as a SIP extension against + an Asterisk server you already have running elsewhere. Redesigned + during migration, not a straight port — see "Recent Updates (v2.10.0)" + below for why the legacy Server/Full PBX-install options didn't come + along. - `install.sh` — entry point for the modular tool, now grouped **Core Settings / Addons / Advanced** like the legacy menu. Run it against an *already-installed* kiosk: @@ -1233,13 +1251,15 @@ terminal menu and the web UI, so they can't drift apart). **Honest status:** this does not yet replace first-time installation, or most of the old installer. `ubuntu-based-kiosk.sh` is still ~12,000 lines and still contains its own unremoved, unmodified copies of every -menu above (plus Upgrade, Reinstall, Uninstall, 1 more Addon — Easy -Asterisk Intercom — and the other 8 Advanced items — none of that has -moved yet). Both copies coexist deliberately: the old ones stay until -enough of Core Settings/Addons/Advanced is migrated to retire them in -one pass, rather than leaving the legacy menu half-wired. Migration -continues one `menus/*.sh` file at a time; first-time installation -itself is the last and largest piece to move, if it moves at all. +menu above, including the legacy three-option (Client/Server/Full) +Easy Asterisk Intercom — the modular version only replaces the Client +option, by design (plus Upgrade, Reinstall, Uninstall, and the other 8 +Advanced items — none of that has moved yet). Both copies coexist +deliberately: the old ones stay until enough of Core Settings/Addons/ +Advanced is migrated to retire them in one pass, rather than leaving +the legacy menu half-wired. Migration continues one `menus/*.sh` file +at a time; first-time installation itself is the last and largest piece +to move, if it moves at all. **Resolved (v2.9.0):** `is_service_enabled()` — shared by both scripts — had a pre-check (`systemctl list-unit-files | grep -q "^${service}\s"`) @@ -1266,9 +1286,15 @@ full migration pass. ## Project Status & Future Plans -**Current Version:** 2.9.0 +**Current Version:** 2.10.0 -**Recent Updates (v2.9.0):** +**Recent Updates (v2.10.0):** +- **Asterisk Intercom migrated, and redesigned in the process.** The legacy addon offered Client Only (Baresip SIP client), Server Only, and Full (server + client) — the latter two downloaded and ran a third-party installer from a separate "Easy Asterisk" repository to stand up a whole Asterisk PBX. That repository has since gone through a major rework upstream, so the PBX-install path is dropped entirely rather than carrying a dependency on code that's moved on without it. The migrated addon (`menus/addon_asterisk_intercom.sh`) now does only the client/endpoint piece: install Baresip and register this kiosk as one SIP extension against an Asterisk server you already have running elsewhere. It never installs or manages Asterisk itself. The legacy script's own three-option version is untouched, same as every other migrated menu. +- Dropped the dependency on the (now-reworked) Easy Asterisk repo's GitHub API for version tracking — reads the real installed `baresip` package version via `dpkg` instead. +- **New capability:** an uninstall option for the Baresip client — the legacy addon never had one. +- **Bug fix:** an unguarded `ver=$(baresip_installed_version)` assignment would have crashed the whole session the first time status was checked before Baresip was installed (`dpkg-query` legitimately fails when the package isn't there). Guarded with `|| true` before it shipped. + +**Previous (v2.9.0):** - **LMS Server / Squeezelite Player migrated** — install/reconfigure/uninstall for both, in `./install.sh`. Squeezelite's own start script and systemd unit now go through `$BIN_DIR`/`$SYSTEMD_DIR` like every other addon instead of hardcoded `/usr/local/bin`/`/etc/systemd/system`; LMS's own apt repo/GPG key/ufw rules stay at their real fixed system paths, same approach as CUPS. - **Bug fix:** the legacy `install_lms()` enabled/started the detected service via `sudo systemctl enable "$service_name" 2>&1 | tee /tmp/lms-enable.log` — piped through `tee`, the statement's exit status reflected `tee` (always 0), not `systemctl enable`, so a real enable/start failure was silently swallowed instead of falling through to a warning. Now uses the shared `enable_and_start_units()` helper. - **Bug fix (shared, backported to the legacy script too):** `is_service_enabled()`'s pre-check never matched a bare service name against `list-unit-files`' `"$service.service"` lines, so it always reported "not enabled" regardless of the real state. Dropped the dead pre-check — see "Modular Management" below. diff --git a/install.sh b/install.sh index 73f9a03..38f633c 100755 --- a/install.sh +++ b/install.sh @@ -19,7 +19,8 @@ # Addons: CUPS Printing (menus/addon_cups.sh), Authelia Auto-Login # (menus/addon_authelia.sh), Remote Access - VNC/WireGuard/ # Tailscale/Netbird (menus/addon_remote_access.sh), LMS Server / -# Squeezelite Player (menus/addon_lms_squeezelite.sh). +# Squeezelite Player (menus/addon_lms_squeezelite.sh), Asterisk +# Intercom - SIP extension client (menus/addon_asterisk_intercom.sh). # Advanced: Diagnostics (menus/diagnostics.sh - system status/logs/ # audio/network). # @@ -61,6 +62,8 @@ source "$SCRIPT_DIR/menus/addon_authelia.sh" source "$SCRIPT_DIR/menus/addon_remote_access.sh" # shellcheck source=menus/addon_lms_squeezelite.sh source "$SCRIPT_DIR/menus/addon_lms_squeezelite.sh" +# shellcheck source=menus/addon_asterisk_intercom.sh +source "$SCRIPT_DIR/menus/addon_asterisk_intercom.sh" ################################################################################ # Preflight @@ -124,8 +127,8 @@ core_settings_menu() { } addons_menu_builder() { - MENU_LABELS=("CUPS Printing" "Authelia Auto-Login" "Remote Access" "LMS Server / Squeezelite Player") - MENU_HANDLERS=(addon_cups_menu addon_authelia_menu remote_access_menu addon_lms_squeezelite_menu) + MENU_LABELS=("CUPS Printing" "Authelia Auto-Login" "Remote Access" "LMS Server / Squeezelite Player" "Asterisk Intercom (SIP Extension)") + MENU_HANDLERS=(addon_cups_menu addon_authelia_menu remote_access_menu addon_lms_squeezelite_menu addon_asterisk_intercom_menu) } addons_menu() { diff --git a/menus/addon_asterisk_intercom.sh b/menus/addon_asterisk_intercom.sh new file mode 100644 index 0000000..bb12a6a --- /dev/null +++ b/menus/addon_asterisk_intercom.sh @@ -0,0 +1,279 @@ +#!/bin/bash +################################################################################ +# menus/addon_asterisk_intercom.sh - "Asterisk Intercom" addon: connect the +# kiosk as a SIP extension to an *existing* Asterisk server. +# +# The legacy addon offered three options: Client Only (a Baresip SIP +# client - what this file is), Server Only, and Full (server + client). +# Server/Full downloaded and ran a third-party installer from a separate +# "Easy Asterisk" repository to stand up a whole Asterisk PBX. That +# repository has since gone through a major rework upstream, so wiring a +# full PBX install through it here no longer makes sense to maintain - +# and most kiosk deployments don't need this device to *be* the PBX +# anyway. This addon now does only the client/endpoint piece: install +# Baresip and register it as one extension against an Asterisk server +# the user already has running somewhere else. It never installs or +# manages Asterisk itself. +# +# Two other things fixed while narrowing the scope: +# - The legacy client path tracked its own version by calling out to the +# (now-reworked) Easy Asterisk repo's GitHub API and stamping a +# "-client" string in a side file. That coupling is +# exactly what's being dropped, so version tracking now just reads the +# real installed `baresip` package version via dpkg - one less network +# dependency and one less thing to keep in sync with an external repo. +# - The legacy addon had no uninstall option for the client at all - +# added below. +# +# Real system state: apt package, a per-user config directory under +# $KIOSK_HOME, and a systemd --user unit for $KIOSK_USER (not a system +# service - Baresip needs the desktop session's PulseAudio/PipeWire +# socket). Every write goes through `sudo`/`sudo -u "$KIOSK_USER"`, all +# stubbed at the command level in tests - there's no real D-Bus user +# session to target in a test container regardless. +# +# Depends on: lib/menu.sh, lib/config.sh being sourced first. +################################################################################ + +BARESIP_CONFIG_DIR="${KIOSK_HOME}/.baresip" +BARESIP_USER_SERVICE_DIR="${KIOSK_HOME}/.config/systemd/user" + +# Runs `systemctl --user ...` as $KIOSK_USER with the runtime dir/D-Bus +# address it needs to find that user's session. Always call from an +# `if`/`&&`/`||` context - see run_menu's own comment on why a bare call +# that can legitimately fail must never be a standalone statement. +baresip_systemctl_user() { + local kiosk_uid + kiosk_uid=$(id -u "$KIOSK_USER" 2>/dev/null) || return 1 + sudo -u "$KIOSK_USER" \ + XDG_RUNTIME_DIR="/run/user/${kiosk_uid}" \ + DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${kiosk_uid}/bus" \ + systemctl --user "$@" +} + +baresip_installed_version() { + dpkg-query -W -f='${Version}' baresip 2>/dev/null || true +} + +# "Installed" means both the package and a written account - a bare +# `apt install baresip` with no configured extension isn't something +# this menu should call done. +baresip_is_installed() { + command -v baresip &>/dev/null && [[ -f "$BARESIP_CONFIG_DIR/accounts" ]] +} + +baresip_is_running() { + baresip_systemctl_user is-active --quiet baresip.service 2>/dev/null +} + +addon_asterisk_intercom_status() { + if baresip_is_installed; then + local ver + ver=$(baresip_installed_version) + if baresip_is_running; then + echo "Asterisk Intercom: Installed (v${ver:-unknown}) - Running" + else + echo "Asterisk Intercom: Installed (v${ver:-unknown}) - Not running" + fi + if [[ -f "$BARESIP_CONFIG_DIR/accounts" ]]; then + local account + account=$(head -1 "$BARESIP_CONFIG_DIR/accounts" 2>/dev/null) + local extension="${account#/dev/null; then + if ! sudo apt install -y baresip; then + log_error "Failed to install baresip package" + pause + return 1 + fi + fi + sudo apt install -y pulseaudio-utils pipewire-pulse 2>/dev/null || true + + sudo mkdir -p "$BARESIP_CONFIG_DIR" + + sudo tee "$BARESIP_CONFIG_DIR/accounts" > /dev/null <;auth_pass=${password};answermode=${answermode}${media_enc} +EOF + + if [[ ! -f "$BARESIP_CONFIG_DIR/config" ]]; then + sudo tee "$BARESIP_CONFIG_DIR/config" > /dev/null <<'BARESIPCONFIG' +# Baresip configuration for Asterisk Intercom + +# Audio settings +audio_player pulse,default +audio_source pulse,default +audio_alert pulse,default + +# Call settings +call_local_timeout 120 +call_max_calls 4 + +# Network settings +net_interface + +# SIP settings +sip_trans_bsize 128 +sip_verify_server no + +# Module loading +module pulse.so +module account.so +module contact.so +module menu.so +module stdio.so +module uuid.so +module debug_cmd.so +BARESIPCONFIG + fi + + sudo chown -R "${KIOSK_USER}:${KIOSK_USER}" "$BARESIP_CONFIG_DIR" + sudo chmod 600 "$BARESIP_CONFIG_DIR/accounts" + + sudo mkdir -p "$BARESIP_USER_SERVICE_DIR" + sudo tee "$BARESIP_USER_SERVICE_DIR/baresip.service" > /dev/null <<'BARESIPUNIT' +[Unit] +Description=Baresip SIP Client +After=pipewire.service pipewire-pulse.service +Wants=pipewire-pulse.service + +[Service] +Type=simple +ExecStart=/usr/bin/baresip -f %h/.baresip +Restart=always +RestartSec=5 +Environment=PULSE_SERVER=unix:/run/user/%U/pulse/native + +[Install] +WantedBy=default.target +BARESIPUNIT + sudo chown -R "${KIOSK_USER}:${KIOSK_USER}" "${KIOSK_HOME}/.config" + + if baresip_systemctl_user daemon-reload 2>/dev/null && \ + baresip_systemctl_user enable baresip.service 2>/dev/null && \ + baresip_systemctl_user start baresip.service 2>/dev/null; then + log_success "Baresip service enabled and started" + else + log_warning "Baresip files written, but enabling/starting the user service failed - it will start automatically on next login. Check: systemctl --user status baresip" + fi + + echo + log_success "Asterisk Intercom configured" + echo " Config dir: ${BARESIP_CONFIG_DIR}" + echo " Server: ${server_ip}:${server_port}" + echo " Extension: ${extension}" + echo + echo "Management commands (as $KIOSK_USER):" + echo " Check status: systemctl --user status baresip" + echo " Restart: systemctl --user restart baresip" + echo " View logs: journalctl --user -u baresip -f" + + pause +} + +action_uninstall_asterisk_intercom() { + echo + ask_yes_no "Remove Asterisk Intercom (Baresip)?" "n" || { echo "Cancelled"; pause; return; } + + baresip_systemctl_user stop baresip.service 2>/dev/null || true + baresip_systemctl_user disable baresip.service 2>/dev/null || true + sudo rm -f "$BARESIP_USER_SERVICE_DIR/baresip.service" + sudo apt remove -y baresip 2>/dev/null || true + + if ask_yes_no "Remove saved SIP configuration too?" "n"; then + sudo rm -rf "$BARESIP_CONFIG_DIR" + log_success "Asterisk Intercom removed (configuration deleted)" + else + log_success "Asterisk Intercom removed (configuration preserved)" + fi + + pause +} diff --git a/ubuntu-based-kiosk.sh b/ubuntu-based-kiosk.sh index 1f41281..de80e23 100644 --- a/ubuntu-based-kiosk.sh +++ b/ubuntu-based-kiosk.sh @@ -1,8 +1,38 @@ #!/bin/bash ################################################################################ -### Ubuntu Based Kiosk v2.9.0 ### +### Ubuntu Based Kiosk v2.10.0 ### ################################################################################ # +# RELEASE v2.10.0 - Asterisk Intercom Migrated, Redesigned as a SIP +# Extension Client (No More PBX Server Install) +# - New in ./install.sh: Asterisk Intercom (menus/addon_asterisk_intercom.sh). +# The legacy addon offered three options: Client Only (a Baresip SIP +# client), Server Only, and Full (server + client) - the latter two +# downloaded and ran a third-party installer from a separate "Easy +# Asterisk" repository to stand up a whole Asterisk PBX. That +# repository has since gone through a major rework upstream, so this +# migration drops the PBX-install path entirely rather than carrying +# a dependency on code that's moved on without it. The addon now does +# only the client/endpoint piece: install Baresip and register it as +# one SIP extension against an Asterisk server the user already has +# running somewhere else. It never installs or manages Asterisk +# itself. The legacy script's own three-option version is untouched - +# both copies coexist deliberately, same as every other migrated menu. +# - Dropped the legacy client path's dependency on the (now-reworked) +# Easy Asterisk repo's GitHub API for version tracking. It now reads +# the real installed `baresip` package version via dpkg instead - one +# less network dependency and one less thing to keep in sync with an +# external repo. +# - New capability: an uninstall option for the Baresip client, which +# the legacy addon never had at all. +# - Bug fix (found while porting): `baresip_installed_version()`'s +# `dpkg-query` call fails (as expected) when the package isn't +# installed, and the unguarded `ver=$(...)` assignment around it would +# have crashed the whole session under this tool's `set -e` the first +# time status was checked before Baresip was installed. Guarded with +# `|| true` - the same class of bug hunted throughout this migration, +# caught by testing before it shipped. +# # RELEASE v2.9.0 - LMS Server / Squeezelite Player Migrated; # is_service_enabled() Dead Pre-Check Fixed # - New in ./install.sh: LMS Server / Squeezelite Player @@ -349,7 +379,7 @@ set -euo pipefail ### SECTION 1: CONSTANTS & GLOBALS ################################################################################ -SCRIPT_VERSION="2.9.0" +SCRIPT_VERSION="2.10.0" # Resolve the real path to this script file. # When piped (curl|bash or wget|bash), BASH_SOURCE[0] is a pipe descriptor,