Integrate self-update logic into Raspberry Pi installer and simplify update workflow

This commit is contained in:
Tobias Gesellchen
2026-02-14 22:21:43 +01:00
parent b8ab4b5723
commit 1e61adbb46
4 changed files with 78 additions and 13 deletions
+1
View File
@@ -16,6 +16,7 @@
### Useful Links
* [Cloud Shutdown Survival Guide](guides/SURVIVAL-GUIDE.md)
* [Raspberry Pi Installer](../../scripts/raspberry-pi/README.md)
* [Updating the Service](../../scripts/raspberry-pi/README.md#updating-to-a-new-version)
* [CLI Reference](guides/CLI-REFERENCE.md)
## Technical Reference
+10
View File
@@ -37,6 +37,16 @@ sudo \
bash install.sh
```
### Updating the Service
To update the service to a specific version, run the installer with the version as an argument:
```bash
sudo bash install.sh v0.18.1
```
The installer will automatically fetch the latest version of itself for that release and then update the service binary and restart it.
## Management
Once installed, use standard `systemctl` commands to manage the service:
+7 -6
View File
@@ -166,19 +166,20 @@ Then restart the service.
# Updating to a New Version
To upgrade:
To upgrade, simply run the installer with the desired version as an argument:
```bash
sudo VERSION=vX.Y.Z bash install-soundtouch-service.sh
sudo bash install.sh vX.Y.Z
```
The script will:
* Download the new binary
* Overwrite the old one
* Restart the service
* Automatically fetch the latest version of the installer script for that release
* Download the new service binary
* Backup the old binary to `.old`
* Overwrite the binary and restart the service
No need to reconfigure anything.
No need to reconfigure anything; your existing `.env` file and data will be preserved.
---
+60 -7
View File
@@ -4,7 +4,10 @@ set -euo pipefail
# ==============================================================================
# Bose-SoundTouch soundtouch-service installer (systemd, headless)
#
# Example usage (override defaults via env vars):
# Usage:
# sudo bash install.sh [vX.Y.Z]
#
# Examples (override defaults via env vars):
#
# sudo \
# VERSION=v0.17.0 \
@@ -12,11 +15,10 @@ set -euo pipefail
# HTTP_PORT=80 \
# HTTPS_PORT=443 \
# DATA_DIR=/var/lib/soundtouch-service \
# LOG_PROXY_BODY=false \
# REDACT_PROXY_LOGS=true \
# RECORD_INTERACTIONS=true \
# DISCOVERY_INTERVAL=5m \
# bash install-soundtouch-service.sh
# bash install.sh
#
# Or with a version argument to perform an update:
# sudo bash install.sh v0.18.1
#
# Notes:
# - This script downloads a release binary for your CPU (auto-detects armv7/arm64/amd64).
@@ -26,7 +28,11 @@ set -euo pipefail
# - Safe to re-run; it will update binary/config/unit and restart the service.
# ==============================================================================
VERSION="${VERSION:-v0.17.0}"
VERSION="${1:-${VERSION:-v0.17.0}}"
# Normalize version prefix
if [[ ! "$VERSION" =~ ^v ]]; then
VERSION="v${VERSION}"
fi
SERVICE_NAME="${SERVICE_NAME:-soundtouch-service}"
BIN_PATH="${BIN_PATH:-/usr/local/bin/soundtouch-service}"
@@ -56,6 +62,10 @@ DISCOVERY_INTERVAL="${DISCOVERY_INTERVAL:-5m}"
# ARCH_ASSET=linux-armv7|linux-arm64|linux-amd64
ARCH_ASSET="${ARCH_ASSET:-}"
# Internal variables
SCRIPT_PATH="$(realpath "$0" 2>/dev/null || echo "$0")"
IS_SELF_UPDATE="${IS_SELF_UPDATE:-false}"
log() { printf "\n==> %s\n" "$*"; }
die() { echo "ERROR: $*" >&2; exit 1; }
@@ -157,6 +167,47 @@ download_binary() {
log "Installed binary to ${BIN_PATH}"
}
self_update() {
# If we are already a self-update re-exec, don't do it again
if [[ "$IS_SELF_UPDATE" == "true" ]]; then
return
fi
local url="https://raw.githubusercontent.com/gesellix/Bose-SoundTouch/${VERSION}/scripts/raspberry-pi/install.sh"
local tmp_script="/tmp/soundtouch-install-${VERSION}.sh"
log "Checking for installer updates for ${VERSION}..."
log "URL: ${url}"
if command -v curl >/dev/null 2>&1; then
if ! curl -fsSL -o "${tmp_script}" "${url}"; then
log "⚠️ Could not fetch installer for ${VERSION}, continuing with current script."
return
fi
else
if ! wget -qO "${tmp_script}" "${url}"; then
log "⚠️ Could not fetch installer for ${VERSION}, continuing with current script."
return
fi
fi
# Compare scripts to see if we actually need to re-exec
if diff -q "${SCRIPT_PATH}" "${tmp_script}" >/dev/null 2>&1; then
log "Installer is already up to date."
rm -f "${tmp_script}"
return
fi
log "Newer installer found for ${VERSION}. Re-executing..."
chmod +x "${tmp_script}"
# Export current env vars to the new script
export IS_SELF_UPDATE="true"
export VERSION HOSTNAME_FQDN HTTP_PORT HTTPS_PORT DATA_DIR BIN_PATH CONFIG_DIR ENV_FILE SERVICE_USER SERVICE_GROUP
exec "${tmp_script}" "$@"
}
write_env_file() {
log "Writing env file: ${ENV_FILE}"
cat > "${ENV_FILE}" <<EOF
@@ -282,6 +333,8 @@ main() {
apt_install_if_missing curl
fi
self_update "$@"
ensure_user_group
ensure_dirs
download_binary