mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 08:36:13 +00:00
feat(admin): show the resolved data directory in Settings
Prompted by not being able to tell where a locally-run instance's data dir actually was without inspecting the running process (ps/lsof). Adds data_dir to /api/setup/version's response, resolved to an absolute path so it's unambiguous regardless of whether --data-dir/DATA_DIR was relative or left at the default. Shown as a read-only line at the top of the Settings tab, not the always- visible footer — the footer is prime real estate seen on every tab/every page load, and this is a rarely-needed piece of diagnostic info that belongs alongside the rest of System Settings instead. Also filled in a test-helper gap: the pkg/service/handlers package's internal test router (main_test.go) never registered /setup/version at all, unlike the real production router — added it so the new test (and any future one exercising this endpoint) can actually run. Unrelated to #419, but found while verifying that work against a running instance.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -1357,6 +1358,19 @@ func (s *Server) HandleGetVersionInfo(w http.ResponseWriter, _ *http.Request) {
|
||||
repoURL := s.RepoURL
|
||||
s.mu.RUnlock()
|
||||
|
||||
var dataDir string
|
||||
|
||||
if s.ds != nil && s.ds.DataDir != "" {
|
||||
// Resolve to absolute: the default ("data") and any relative
|
||||
// --data-dir/DATA_DIR value are otherwise ambiguous without knowing
|
||||
// the process's working directory at startup.
|
||||
if abs, err := filepath.Abs(s.ds.DataDir); err == nil {
|
||||
dataDir = abs
|
||||
} else {
|
||||
dataDir = s.ds.DataDir
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var (
|
||||
@@ -1381,6 +1395,7 @@ func (s *Server) HandleGetVersionInfo(w http.ResponseWriter, _ *http.Request) {
|
||||
"repo_url": repoURL,
|
||||
"release_url": releaseURL,
|
||||
"commit_url": commitURL,
|
||||
"data_dir": dataDir,
|
||||
}); err != nil {
|
||||
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
@@ -443,6 +443,46 @@ func TestAdminAreaAuthRoundTrip(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestHandleGetVersionInfo_IncludesAbsoluteDataDir verifies /api/setup/version
|
||||
// reports the actual data directory in use, resolved to an absolute path —
|
||||
// added so operators running the service locally (not in Docker, where the
|
||||
// path is obvious from the bind mount) can find it without having to
|
||||
// inspect the running process. See NEXT.md/#419 session notes.
|
||||
func TestHandleGetVersionInfo_IncludesAbsoluteDataDir(t *testing.T) {
|
||||
tempDir, err := os.MkdirTemp("", "version-info-datadir-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
ds := datastore.NewDataStore(tempDir)
|
||||
_ = ds.Initialize()
|
||||
|
||||
r, _ := setupRouter("http://127.0.0.1:8000", ds)
|
||||
ts := httptest.NewServer(r)
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/setup/version")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
var got map[string]string
|
||||
if err := json.NewDecoder(res.Body).Decode(&got); err != nil {
|
||||
t.Fatalf("Failed to decode response: %v", err)
|
||||
}
|
||||
|
||||
wantAbs, err := filepath.Abs(tempDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to resolve expected absolute path: %v", err)
|
||||
}
|
||||
|
||||
if got["data_dir"] != wantAbs {
|
||||
t.Errorf("Expected data_dir %q, got %q", wantAbs, got["data_dir"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrationAndCA(t *testing.T) {
|
||||
tempDir, err := os.MkdirTemp("", "handlers-test")
|
||||
if err != nil {
|
||||
|
||||
@@ -131,6 +131,7 @@ func setupRouter(targetURL string, ds *datastore.DataStore) (*chi.Mux, *Server)
|
||||
r.Delete("/devices/{deviceId}", server.HandleRemoveDevice)
|
||||
r.Get("/settings", server.HandleGetSettings)
|
||||
r.Post("/settings", server.HandleUpdateSettings)
|
||||
r.Get("/version", server.HandleGetVersionInfo)
|
||||
r.Get("/logging-settings", server.HandleGetLoggingSettings)
|
||||
r.Post("/logging-settings", server.HandleUpdateLoggingSettings)
|
||||
r.Post("/ensure-remote-services/{deviceId}", server.HandleEnsureRemoteServices)
|
||||
|
||||
@@ -171,6 +171,9 @@
|
||||
<!-- Tab 1: Settings -->
|
||||
<div id="tab-settings" class="tab-content">
|
||||
<h2>System Settings</h2>
|
||||
<p style="font-size: 0.85em; color: #666; margin: -8px 0 20px 0;">
|
||||
Data directory: <code id="settings-data-dir">-</code>
|
||||
</p>
|
||||
<div style="margin-bottom: 20px">
|
||||
<strong>Service URLs</strong>
|
||||
<p style="font-size: 0.9em; color: #555; margin: 6px 0 12px 0">
|
||||
|
||||
@@ -891,6 +891,11 @@ async function fetchVersion() {
|
||||
}
|
||||
info.innerHTML = `AfterTouch ${versionStr} (${commitStr}) • ${data.date}`;
|
||||
}
|
||||
|
||||
const dataDirEl = document.getElementById("settings-data-dir");
|
||||
if (dataDirEl && data.data_dir) {
|
||||
dataDirEl.textContent = data.data_dir;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch version info", error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user