mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 08:36:13 +00:00
Bundles the install-time hygiene work for issues #268 and #250. # Install location — #268 Stock SoundTouch rootfs has only a few MB free (~4 MB on the ST20 the reporter captured); the AfterTouch binary is ~12 MB. The previous flow downloaded into tmpfs (/media/aftertouch) and then `mv`'d the binary into /opt/aftertouch on rootfs — which fails with "No space left on device" on any speaker with the standard layout. install.sh now installs to /mnt/nv/aftertouch by default (the persistent partition, ~30 MB free on the same captures) and points /opt/aftertouch at it via a symlink so the init script's hardcoded DAEMON path keeps working unchanged. Power users can override with INSTALL_DIR=/some/other/path. The interactive prompt from the community patch in #268's thread is dropped — STDIN is the curl pipe under the documented `curl | sh` invocation, so a read prompt would hang or read garbage. uninstall.sh is updated to resolve the symlink and remove the target before unlinking, so the 12 MB binary doesn't get orphaned on /mnt/nv when users uninstall. # Logging — #250 Issue #250 surfaced a "running but unreachable" state: the install script reported AfterTouch as running, the init script's status agreed, but `curl :8000` returned connection-refused. start-stop- daemon's --background detaches stdout/stderr, so any panic the daemon emitted before dying went to /dev/null with no diagnostic trail. The fix is to route the daemon's stdout/stderr through `logger -t aftertouch` so output lands in BusyBox syslog — a bounded in-memory ring buffer that never grows on disk (writing to a file in /mnt/nv would have eaten the volume over months). Diagnostic flow is now: logread | grep aftertouch | tail -20 logread -f | grep aftertouch # live tail Matches the recipe already documented in TROUBLESHOOTING.md for the speaker's own logs (Curl 7 section). Tightening on top of the syslog change: - The init script's `status` case now also curls localhost:8000 when the PID is alive — distinguishes "PID alive, listener up" from "PID alive, listener silently died" (which is what fooled everyone on #250). A bare PID-liveness check returned "running" in both cases. - install.sh's post-install verification now does its own 10s curl probe after the init script returns; on failure it tails the aftertouch syslog so the user sees the actual error rather than the install script claiming success. - `exec` is added inside the start-stop-daemon's shell wrapper so --make-pidfile records the daemon's own PID (not the shell's), which keeps `stop` semantics correct. README updated to document the install location, INSTALL_DIR override, and the syslog tag. No automated tests — these are shell scripts the install pipeline runs once on the device. All three scripts pass `bash -n` / `sh -n` syntax checks. Real validation is end-user retest, gated on the next release. Refs #268, refs #250. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
136 lines
3.7 KiB
Bash
136 lines
3.7 KiB
Bash
#!/bin/sh
|
|
### BEGIN INIT INFO
|
|
# Provides: aftertouch-service
|
|
# Required-Start: $network $local_fs
|
|
# Required-Stop: $network $local_fs
|
|
# Default-Start: 2 3 4 5
|
|
# Default-Stop: 0 1 6
|
|
# Short-Description: Run AfterTouch on this device
|
|
# Description: Start/stop AfterTouch soundtouch-service
|
|
### END INIT INFO
|
|
|
|
|
|
NAME="aftertouch-service"
|
|
DESC="Bose AfterTouch service"
|
|
DAEMON="/opt/aftertouch/aftertouch-service"
|
|
PIDFILE="/var/run/$NAME.pid"
|
|
DATADIR="/opt/aftertouch/data"
|
|
SCRIPTNAME="/etc/init.d/$NAME"
|
|
USER="root"
|
|
LOG_TAG="aftertouch"
|
|
|
|
|
|
# Export PATH
|
|
export PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
|
|
|
|
|
|
# Sanity check executable
|
|
test -x "$DAEMON" || {
|
|
echo "ERROR: Cannot execute $DAEMON (check path and permissions)." >&2
|
|
exit 1
|
|
}
|
|
|
|
|
|
case "$1" in
|
|
start)
|
|
echo "Starting $DESC..."
|
|
|
|
mount -o remount,rw / >/dev/null 2>&1 || {
|
|
echo "ERROR: remount failed." >&2
|
|
exit 1
|
|
}
|
|
|
|
mkdir -p "$DATADIR"
|
|
|
|
# Pipe stdout + stderr through `logger -t $LOG_TAG` so the
|
|
# daemon's output lands in busybox syslog (bounded ring buffer,
|
|
# never grows on disk). Users diagnose with:
|
|
#
|
|
# logread | grep aftertouch | tail -20
|
|
# logread -f | grep aftertouch # live tail
|
|
#
|
|
# `exec` on the daemon replaces /bin/sh so --make-pidfile records
|
|
# the daemon's own PID (not the shell wrapper). The `logger`
|
|
# process sits on the read end of the pipe and exits cleanly
|
|
# when the daemon dies and closes its end.
|
|
start-stop-daemon --start \
|
|
--quiet \
|
|
--pidfile "$PIDFILE" \
|
|
--background \
|
|
--make-pidfile \
|
|
--chuid "$USER" \
|
|
--startas "/bin/sh" \
|
|
-- -c "exec \"$DAEMON\" --data-dir '$DATADIR' --record-interactions=false --discovery-interval=60m 2>&1 | logger -t $LOG_TAG"
|
|
|
|
tries=0
|
|
max_tries=60
|
|
while [ $tries -lt $max_tries ]; do
|
|
if curl -fsS http://localhost:8000 >/dev/null 2>&1; then
|
|
exit 0
|
|
fi
|
|
sleep 2
|
|
tries=$((tries + 1))
|
|
done
|
|
|
|
echo "ERROR: daemon started but http://localhost:8000 never responded within $((max_tries * 2))s." >&2
|
|
echo " Inspect the daemon's syslog output:" >&2
|
|
echo " logread | grep $LOG_TAG | tail -20" >&2
|
|
exit 1
|
|
;;
|
|
|
|
stop)
|
|
echo "Stopping $DESC..."
|
|
if [ -f "$PIDFILE" ]; then
|
|
start-stop-daemon --stop \
|
|
--quiet \
|
|
--oknodo \
|
|
--pidfile "$PIDFILE"
|
|
rm -f "$PIDFILE"
|
|
else
|
|
echo "No $NAME running (no PID file)." >&2
|
|
fi
|
|
;;
|
|
|
|
restart|force-reload)
|
|
"$0" stop
|
|
sleep 2
|
|
"$0" start
|
|
;;
|
|
|
|
status)
|
|
if [ -f "$PIDFILE" ]; then
|
|
PID=$(cat "$PIDFILE")
|
|
if kill -0 "$PID" 2>/dev/null; then
|
|
# PID is alive — does it actually serve HTTP? A live process
|
|
# with a dead listener is the symptom behind issue #250
|
|
# (Gustour's ST30: status said running, curl said
|
|
# connection-refused). Distinguish the two states here so
|
|
# status isn't a false-positive.
|
|
if curl -fsS --max-time 3 http://localhost:8000 >/dev/null 2>&1; then
|
|
echo "$NAME is running (PID $PID, http://localhost:8000 responding)."
|
|
exit 0
|
|
else
|
|
echo "$NAME PID $PID is alive but http://localhost:8000 is not responding." >&2
|
|
echo "Recent log:" >&2
|
|
logread 2>/dev/null | grep "$LOG_TAG" | tail -10 >&2
|
|
exit 3
|
|
fi
|
|
else
|
|
echo "$NAME is not running (PID file exists but process is dead)." >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "$NAME is not running."
|
|
exit 3
|
|
fi
|
|
;;
|
|
|
|
*)
|
|
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
|
|
exit 0
|