Introduces a standalone `soundtouch-backup` CLI with three subcommands: - `all`: authenticates with the Bose cloud, backs up account data, then reads device IPs from devices.xml and backs up each reachable speaker - `cloud`: fetches account profile, devices, sources, presets, and full endpoint from streaming.bose.com - `local`: backs up each speaker via HTTP API (12 endpoints) and optionally via SSH (individual files + /opt/Bose/etc/ and /mnt/nv/BoseApp-Persistence/1/ directories) Also centralises pkg/service/ssh → pkg/ssh so both the service and the backup tool share the same SSH client; adds ReadFile and ReadDir methods, and handles the firmware quirk where cat exits 1 on empty files. Output is a single dated .tar.gz or .zip archive. Example flow: ```shell gesellix@Mac Bose-SoundTouch % go run ./cmd/soundtouch-backup all --output _/cloud-backup --email user@example.com Password: Authenticating as user@example.com... ✓ Authenticated (account ID: 1234567) ✓ email address (107 bytes) ✓ devices (1492 bytes) ✓ sources (1111 bytes) ✓ presets (2585 bytes) ✓ full account (55037 bytes) Found 2 device(s) in cloud account, attempting local backup... ✓ ST20: 12 files via HTTP ⚠ ST20: SSH skipped /etc/remote_services (Process exited with status 1) ⚠ ST20: SSH empty file /mnt/nv/remote_services ✓ ST20: 64 files via SSH ✓ ST10: 12 files via HTTP ⚠ ST10: SSH empty file /etc/remote_services ⚠ ST10: SSH skipped /mnt/nv/remote_services (Process exited with status 1) ✓ ST10: 48 files via SSH Archive written: _/cloud-backup/soundtouch-backup-2026-05-02.tar.gz (141 files) ``` --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
9.4 KiB
soundtouch-backup
A standalone tool for backing up Bose SoundTouch data — both your cloud account (presets, devices, sources) and the local filesystem of each speaker — before the Bose cloud services shut down on May 6, 2026.
Overview
| Subcommand | What it backs up |
|---|---|
all |
Cloud account and all paired speakers in one step — the recommended starting point |
cloud |
Bose account profile, paired devices, cloud presets, music service sources |
local |
Speaker HTTP API data (presets, sources, volume, …) and optionally device filesystem files via SSH |
Output is a single .tar.gz archive (or .zip) with a dated root directory.
Building
make build-backup
# binary: ./build/soundtouch-backup
Or install alongside the other tools:
make install
Usage
Combined backup (recommended)
The all command is the simplest way to capture everything: it authenticates with the Bose cloud, backs up your account data, then reads the IP addresses from devices.xml and backs up each reachable speaker over HTTP.
# Interactive — prompts for email and password
soundtouch-backup all
# Non-interactive
soundtouch-backup all --email you@example.com --password secret
# Include SSH filesystem backup for each speaker
soundtouch-backup all --ssh
# Environment variables
BOSE_EMAIL=you@example.com BOSE_PASSWORD=secret soundtouch-backup all --ssh
Flags
| Flag | Short | Default | Description |
|---|---|---|---|
--email |
-e |
— | Bose account email ($BOSE_EMAIL) |
--password |
--pw |
— | Bose account password ($BOSE_PASSWORD) |
--ssh |
on | Also capture filesystem files via SSH for each speaker | |
--output |
-o |
soundtouch-backup-YYYY-MM-DD.tar.gz |
Output archive path |
--format |
tar.gz |
Archive format: tar.gz or zip |
Speakers that are offline or unreachable at the time of backup are skipped with a ✗ warning; the cloud data is still saved.
Cloud backup
Backs up data from your Bose account at streaming.bose.com. Credentials are prompted interactively if not supplied as flags.
# Interactive — prompts for email, masked password input
soundtouch-backup cloud
# Non-interactive
soundtouch-backup cloud --email you@example.com --password secret
# Environment variables (avoids secrets in shell history)
BOSE_EMAIL=you@example.com BOSE_PASSWORD=secret soundtouch-backup cloud
# Zip output
soundtouch-backup cloud --format zip --output my-bose-cloud.zip
Flags
| Flag | Short | Default | Description |
|---|---|---|---|
--email |
-e |
— | Bose account email ($BOSE_EMAIL) |
--password |
--pw |
— | Bose account password ($BOSE_PASSWORD) |
--output |
-o |
soundtouch-backup-YYYY-MM-DD.tar.gz |
Output archive path ($SOUNDTOUCH_BACKUP_OUTPUT) |
--format |
tar.gz |
Archive format: tar.gz or zip |
What gets fetched
| File in archive | Source endpoint |
|---|---|
cloud/emailaddress.xml |
GET /streaming/account/{id}/emailaddress |
cloud/devices.xml |
GET /streaming/account/{id}/devices |
cloud/sources.xml |
GET /streaming/account/{id}/sources |
cloud/presets.xml |
GET /streaming/account/{id}/presets/all |
cloud/full.xml |
GET /streaming/account/{id}/full (may overlap with the above; skipped if 4xx) |
Local backup
Backs up each speaker over its HTTP API on port 8090. With --ssh, also captures key filesystem files via SSH.
# Auto-discover all speakers on the local network
soundtouch-backup local
# Specific speaker
soundtouch-backup local --host 192.168.178.28
# Multiple speakers
soundtouch-backup local --host 192.168.178.28 --host 192.168.178.35
# Include SSH filesystem backup
soundtouch-backup local --ssh
# Longer discovery window on busy networks
soundtouch-backup local --discover-timeout 10s
Flags
| Flag | Short | Default | Description |
|---|---|---|---|
--host |
-H |
— | Speaker host/IP, repeatable ($SOUNDTOUCH_HOST) |
--port |
-p |
8090 |
Speaker HTTP port ($SOUNDTOUCH_PORT) |
--discover |
-d |
auto | Force mDNS/UPnP discovery |
--discover-timeout |
5s |
Discovery timeout | |
--ssh |
on | Also capture filesystem files via SSH | |
--output |
-o |
soundtouch-backup-YYYY-MM-DD.tar.gz |
Output archive path |
--format |
tar.gz |
Archive format: tar.gz or zip |
What gets fetched via HTTP
| File | Device endpoint |
|---|---|
info.xml |
/info |
name.xml |
/name |
presets.xml |
/presets |
sources.xml |
/sources |
now_playing.xml |
/now_playing |
volume.xml |
/volume |
bass.xml |
/bass |
balance.xml |
/balance |
capabilities.xml |
/capabilities |
network_info.xml |
/networkInfo |
clock_display.xml |
/clockDisplay |
zone.xml |
/getZone |
Endpoints that return HTTP 4xx (not supported on the device model) are silently skipped.
What gets fetched via SSH (--ssh)
SSH connects as root@<host>:22 with an empty password, which is the default for SoundTouch firmware.
Individual files:
| Remote path | Notes |
|---|---|
/etc/hosts |
DNS redirect state |
/etc/resolv.conf |
DNS resolver configuration |
/etc/remote_services |
Service registration (post-migration only) |
/mnt/nv/remote_services |
Alternative location for remote services |
Directories (all regular files recursively):
| Remote path | Contents |
|---|---|
/opt/Bose/etc/ |
Full Bose configuration directory, including SoundTouchSdkPrivateCfg.xml |
/mnt/nv/BoseApp-Persistence/1/ |
Persisted app state |
Missing files and directories are silently skipped with a ⚠ warning.
Archive structure
Both subcommands write into a single dated archive:
soundtouch-backup-2026-05-02/
├── cloud/
│ ├── emailaddress.xml
│ ├── devices.xml
│ ├── sources.xml
│ └── presets.xml
└── local/
├── A_Sound_Machine/
│ ├── info.xml
│ ├── presets.xml
│ ├── sources.xml
│ ├── volume.xml
│ ├── …
│ └── ssh/
│ ├── etc/
│ │ ├── hosts
│ │ └── resolv.conf
│ ├── opt/Bose/etc/
│ │ └── SoundTouchSdkPrivateCfg.xml
│ └── mnt/nv/BoseApp-Persistence/1/
└── Sound_Machinechen/
└── …
Running cloud and local separately produces two archives. To combine them, use the same --output path for both invocations — each adds its own subdirectory so they won't collide (.tar.gz does not support appending; use --format zip if you need a single archive from two runs, or just keep them separate).
See also
- Cloud Shutdown Survival Guide — full migration context
soundtouch-cli— live device controlsoundtouch-service— local cloud replacement