Files
Tobias GesellchenandClaude Sonnet 4.6 73d0d4b176 fix(install): reliable stop, VERSION flag, and on-device walkthrough
- aftertouch init script: stop) now waits up to 15 s for SIGTERM
  to take effect, then escalates to SIGKILL; prevents stale daemon
  processes after '/etc/init.d/aftertouch stop' returns (weissigera's
  workaround was manual 'killall aftertouch-service')

- install.sh: add --version / -v CLI flag so the version to install
  can be passed as a command-line argument in addition to the VERSION
  env var; document the trade-off of the hard-coded default in a
  comment; update scripts/on-device-install/README.md with concrete
  usage examples for env-override, CLI flag, and rollback tip

- docs/guides/ON-DEVICE-INSTALL-WALKTHROUGH.md: 10-step runbook
  derived from weissigera's field-tested procedure (issue #329
  comment #4521280831): SSH connection, storage cleanup, install via
  install.sh, reboot, SSH tunnel, Health QuickFix, pairing
  verification, soundtouch-cli download, custom-radio preset setup,
  and final verification; troubleshooting table at the end

Closes #329 (remaining two tasks)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 11:31:16 +02:00

150 lines
4.2 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
PID=$(cat "$PIDFILE")
start-stop-daemon --stop \
--quiet \
--oknodo \
--pidfile "$PIDFILE"
# Wait up to 15 s for SIGTERM to take effect before escalating.
# The Go HTTP server exits promptly on SIGTERM in normal conditions;
# the loop handles the rare case where it is stuck in a blocking syscall.
tries=0
while [ $tries -lt 15 ] && kill -0 "$PID" 2>/dev/null; do
sleep 1
tries=$((tries + 1))
done
if kill -0 "$PID" 2>/dev/null; then
echo "Warning: $NAME (PID $PID) still alive after ${tries}s; sending SIGKILL..." >&2
kill -9 "$PID" 2>/dev/null || true
sleep 1
fi
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