Merge pull request #366 from naturallaw777/arena/019fae93-sovran-systemsos

fix(hub): resolve 'vdev' version badge and align it under the Hub title
This commit is contained in:
Sovran Systems
2026-07-29 11:07:52 -05:00
committed by GitHub
4 changed files with 62 additions and 18 deletions
+31 -10
View File
@@ -2275,18 +2275,39 @@ async def api_logout(request: Request):
def _get_sovran_version() -> str: def _get_sovran_version() -> str:
"""Read the OS version from the VERSION file.""" """Read the OS version to display in the Hub header.
Resolution order (first match wins):
1. ``sovran_version`` baked into the Nix-generated config.json — this
is the authoritative, build-time value and is what's used on a
real Sovran_SystemsOS install.
2. ``/etc/nixos/VERSION`` — present on an installed system.
3. A ``VERSION`` file shipped next to this package (installed by the
Nix build) or in the repo root (local development checkout).
4. A hard-coded fallback so the badge never renders a broken/empty
value such as the old "vdev" placeholder.
"""
try: try:
with open("/etc/nixos/VERSION", "r") as f: version = load_config().get("sovran_version")
return f.read().strip() if version:
except FileNotFoundError: return str(version).strip().lstrip("vV")
try:
with open("VERSION", "r") as f: # fallback for development
return f.read().strip()
except FileNotFoundError:
return "dev"
except Exception: except Exception:
return "dev" pass
for candidate in (
"/etc/nixos/VERSION",
os.path.join(os.path.dirname(os.path.abspath(__file__)), "VERSION"),
"VERSION",
):
try:
with open(candidate, "r") as f:
version = f.read().strip().lstrip("vV")
if version and version.lower() != "dev":
return version
except (FileNotFoundError, OSError):
continue
return "1.0.0"
@app.get("/", response_class=HTMLResponse) @app.get("/", response_class=HTMLResponse)
@@ -29,6 +29,14 @@
color: var(--text-primary); color: var(--text-primary);
} }
.title-group {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 2px;
}
.header-buttons { .header-buttons {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -58,8 +66,8 @@
color: #4ade80; color: #4ade80;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
margin-left: 12px;
white-space: nowrap; white-space: nowrap;
align-self: flex-start;
} }
.os-version-badge:hover { .os-version-badge:hover {
@@ -21,6 +21,8 @@
<!-- Header bar --> <!-- Header bar -->
<header class="header-bar"> <header class="header-bar">
<img src="/static/sovran-hub-icon.svg" alt="Sovran Hub" class="header-logo" /> <img src="/static/sovran-hub-icon.svg" alt="Sovran Hub" class="header-logo" />
<div class="title-group">
<span class="title">Sovran_SystemsOS Hub</span> <span class="title">Sovran_SystemsOS Hub</span>
<!-- OS Version Badge --> <!-- OS Version Badge -->
@@ -28,6 +30,7 @@
<span class="version-label">v</span> <span class="version-label">v</span>
<span class="version-number" id="version-number">{{ sovran_version }}</span> <span class="version-number" id="version-number">{{ sovran_version }}</span>
</span> </span>
</div>
<div class="header-buttons"> <div class="header-buttons">
<span class="role-badge" id="role-badge">Loading…</span> <span class="role-badge" id="role-badge">Loading…</span>
+12
View File
@@ -3,6 +3,16 @@
let let
cfg = config.sovran_systemsOS; cfg = config.sovran_systemsOS;
# Read the OS version from the repo-root VERSION file at eval time so the
# Hub always ships a real, baked-in version string instead of relying on
# a runtime file lookup (which returns "dev" when /etc/nixos/VERSION is
# missing, e.g. in a dev checkout — this is the "vdev" bug in the Hub UI).
versionFile = ../../VERSION;
sovranVersion =
if builtins.pathExists versionFile
then builtins.replaceStrings [ "v" "\n" "\r" ] [ "" "" "" ] (builtins.readFile versionFile)
else "1.0.0";
monitoredServices = monitoredServices =
# ── Infrastructure — System Passwords (always present) ───── # ── Infrastructure — System Passwords (always present) ─────
[ [
@@ -116,6 +126,7 @@ let
role = activeRole; role = activeRole;
services = monitoredServices; services = monitoredServices;
feature_manager = true; feature_manager = true;
sovran_version = sovranVersion;
}); });
generatedVersions = pkgs.writeText "sovran-hub-versions.json" (builtins.toJSON { generatedVersions = pkgs.writeText "sovran-hub-versions.json" (builtins.toJSON {
@@ -331,6 +342,7 @@ let
cp ${generatedConfig} $out/lib/sovran-hub-web/config.json cp ${generatedConfig} $out/lib/sovran-hub-web/config.json
cp ${generatedVersions} $out/lib/sovran-hub-web/versions.json cp ${generatedVersions} $out/lib/sovran-hub-web/versions.json
printf '%s' "${sovranVersion}" > $out/lib/sovran-hub-web/VERSION
install -d $out/share/sovran-hub/icons install -d $out/share/sovran-hub/icons
cp icons/* $out/share/sovran-hub/icons/ 2>/dev/null || true cp icons/* $out/share/sovran-hub/icons/ 2>/dev/null || true