From 7ed8539af72179412bd10d9e2b8118f58bbded6d Mon Sep 17 00:00:00 2001 From: librelad Date: Fri, 28 Aug 2026 06:35:16 +0100 Subject: [PATCH] setup: stop calling the app-data drive "System disk" when it is not MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wizard's Storage step builds its first entry from primaryRoot() — the app-data root — and labelled it "System disk". On a default install those are the same drive and the name is honest. Installed with --containers-dir on its own disk they are not, and the step then showed the DATA drive's size under the system disk's name while the actual system disk never appeared in the list. Seen on a matrix case-2 install (apps on a 29.4G test disk, system on a 912G root): "System disk — 26.7G free of 29.4G". The generator now reports whether that root is really on the OS disk (is_os_disk, by st_dev against /), and the wizard labels it from that: "System disk" when they coincide, otherwise the mount point. The "system" badge stays — it marks the default location, which is still what it is. Also add lp-shot --token / --cookie-js. A screenshot answers "does it render"; "does this wizard step work" needs clicking, which needs a real browser, which needs the session lp-shot already knows how to mint from the stored jwtSecret. This bug was found that way. Co-Authored-By: Claude Opus 5 --- .../frontend/core/setup/js/setup-wizard.js | 18 ++++++++++++++---- scripts/dev/lp-shot | 18 ++++++++++++++++++ .../system/webui_storage_candidates.sh | 8 ++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/containers/libreportal/frontend/core/setup/js/setup-wizard.js b/containers/libreportal/frontend/core/setup/js/setup-wizard.js index b2b9bc8..e71fd78 100755 --- a/containers/libreportal/frontend/core/setup/js/setup-wizard.js +++ b/containers/libreportal/frontend/core/setup/js/setup-wizard.js @@ -527,6 +527,16 @@ class SetupWizard { // // The badge carries severity and Details carries the explanation, so the card // stays a single row. + // What to call the default app-data location. It is the OS disk on a normal + // install, but --containers-dir can put it on its own drive, and calling that + // "System disk" showed the data drive's size under the system disk's name + // while the actual system disk was absent from the list. + _primaryLabel() { + const s = this.storageSystem; + if (!s || s.is_os_disk !== false) return 'System disk'; + return s.mount && s.mount !== '/' ? s.mount : (s.path || 'Default location'); + } + _storageCard(c, key, opts) { const o = opts || {}; const refused = c.verdict === 'refuse'; @@ -535,7 +545,7 @@ class SetupWizard { : (refused ? 'can\u2019t be used' : (c.verdict === 'warn' ? 'needs care' : '')); - const title = o.system ? 'System disk' : c.path; + const title = o.system ? this._primaryLabel() : c.path; return `
@@ -553,7 +563,7 @@ class SetupWizard { // Every place a root could go: the system disk, plus each usable candidate. _storageChoices() { - const opts = [{ value: 'primary', label: 'System disk' }]; + const opts = [{ value: 'primary', label: this._primaryLabel() }]; this.storageCandidates .filter(c => c.verdict !== 'refuse') .forEach(c => opts.push({ value: c.path, label: c.path })); @@ -681,7 +691,7 @@ class SetupWizard { this.storageCandidates .filter(c => c.verdict !== 'refuse') .forEach(c => opts.push({ value: c.path, label: c.path, shared: c.path === appTarget })); - opts.push({ value: 'primary', label: 'System disk', shared: this.storageDefault === 'primary' }); + opts.push({ value: 'primary', label: this._primaryLabel(), shared: this.storageDefault === 'primary' }); box.innerHTML = `
@@ -890,7 +900,7 @@ class SetupWizard { const m = window.openEoModal({ id: 'lp-storage-details', size: 'md', - title: isSystem ? 'System disk' : c.path, + title: isSystem ? this._primaryLabel() : c.path, desc: `${c.size} drive \u00b7 ${c.free} free \u00b7 ${c.fstype}${c.removable ? ' \u00b7 removable' : ''}`, body: parts.join(''), actions: [{ label: 'Close', variant: 'secondary' }], diff --git a/scripts/dev/lp-shot b/scripts/dev/lp-shot index 4c3fada..66dae89 100755 --- a/scripts/dev/lp-shot +++ b/scripts/dev/lp-shot @@ -358,6 +358,24 @@ class CDP: def main(): + # Print a session cookie and exit. A screenshot is enough for "does it + # render", but not for "does this wizard step work" — that needs clicking, + # which means driving a real browser, which needs the same session lp-shot + # already knows how to mint. Without this the only way in is typing the + # admin password into the login form. + # + # lp-shot --token -> the raw cookie VALUE + # lp-shot --cookie-js -> a document.cookie assignment to paste/eval + if len(sys.argv) > 1 and sys.argv[1] in ("--token", "--cookie-js"): + token, src = mint_token() + if os.environ.get("LP_SHOT_VERBOSE"): + print(f"signed from {src}", file=sys.stderr) + if sys.argv[1] == "--token": + print(token) + else: + print(f'document.cookie = "{COOKIE}={token}; path=/"') + sys.exit(0) + if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help"): print(__doc__.strip()) sys.exit(0 if len(sys.argv) > 1 else 2) diff --git a/scripts/webui/data/generators/system/webui_storage_candidates.sh b/scripts/webui/data/generators/system/webui_storage_candidates.sh index c9327f2..65160a1 100644 --- a/scripts/webui/data/generators/system/webui_storage_candidates.sh +++ b/scripts/webui/data/generators/system/webui_storage_candidates.sh @@ -73,6 +73,14 @@ webuiGenerateStorageCandidates() local sys_pct; sys_pct=$(df -Pk "$sys_root" 2>/dev/null | awk 'NR==2 {gsub("%","",$5); print $5}') system_json+=",\"used_pct\":${sys_pct:-0}" system_json+=",\"removable\":false" + # Is this entry actually the OS disk? On a default install the app-data root + # sits on /, and "System disk" is the honest name for it. Installed with + # --containers-dir on another drive it does not, and calling that the system + # disk reports the WRONG size (the data drive's) while the real system disk + # never appears in the list at all. + local sys_is_os=false + [[ "$(stat -c '%d' -- "$sys_root" 2>/dev/null)" == "$(stat -c '%d' -- / 2>/dev/null)" ]] && sys_is_os=true + system_json+=",\"is_os_disk\":$sys_is_os" system_json+=",\"apps\":\"$(_lpJsonEsc "$(storageAppsOnRoot "$sys_root" 2>/dev/null | paste -sd, -)")\"" system_json+=",\"checks\":$sys_checks}"