frontend link fix

This commit is contained in:
2026-04-02 15:43:32 -05:00
parent b6dfbc4a56
commit ad0f04c0bf
3 changed files with 31 additions and 35 deletions

View File

@@ -30,6 +30,8 @@ UPDATE_LOG = "/var/log/sovran-hub-update.log"
UPDATE_STATUS = "/var/log/sovran-hub-update.status" UPDATE_STATUS = "/var/log/sovran-hub-update.status"
UPDATE_UNIT = "sovran-hub-update.service" UPDATE_UNIT = "sovran-hub-update.service"
INTERNAL_IP_FILE = "/var/lib/secrets/internal-ip"
REBOOT_COMMAND = ["reboot"] REBOOT_COMMAND = ["reboot"]
CATEGORY_ORDER = [ CATEGORY_ORDER = [
@@ -154,6 +156,17 @@ def _get_internal_ip() -> str:
return "unavailable" return "unavailable"
def _save_internal_ip(ip: str):
"""Write the internal IP to a file so credentials can reference it."""
if ip and ip != "unavailable":
try:
os.makedirs(os.path.dirname(INTERNAL_IP_FILE), exist_ok=True)
with open(INTERNAL_IP_FILE, "w") as f:
f.write(ip)
except OSError:
pass
def _get_external_ip() -> str: def _get_external_ip() -> str:
MAX_IP_LENGTH = 46 MAX_IP_LENGTH = 46
for url in [ for url in [
@@ -245,7 +258,7 @@ def _resolve_credential(cred: dict) -> dict | None:
return {"label": label, "value": value, "multiline": multiline} return {"label": label, "value": value, "multiline": multiline}
# ── Routes ───────────<EFBFBD><EFBFBD>─────────────────────────────────────────── # ── Routes ──────────────────────────────────────────────────────
@app.get("/", response_class=HTMLResponse) @app.get("/", response_class=HTMLResponse)
async def index(request: Request): async def index(request: Request):
@@ -392,6 +405,8 @@ async def api_network():
loop.run_in_executor(None, _get_internal_ip), loop.run_in_executor(None, _get_internal_ip),
loop.run_in_executor(None, _get_external_ip), loop.run_in_executor(None, _get_external_ip),
) )
# Keep the internal-ip file in sync for credential lookups
_save_internal_ip(internal)
return {"internal_ip": internal, "external_ip": external} return {"internal_ip": internal, "external_ip": external}
@@ -462,3 +477,13 @@ async def api_updates_status(offset: int = 0):
"log": new_log, "log": new_log,
"offset": new_offset, "offset": new_offset,
} }
# ── Startup: seed the internal IP file immediately ───────────────
@app.on_event("startup")
async def _startup_save_ip():
"""Write internal IP to file on server start so credentials work immediately."""
loop = asyncio.get_event_loop()
ip = await loop.run_in_executor(None, _get_internal_ip)
_save_internal_ip(ip)

View File

@@ -793,13 +793,15 @@ button.btn-reboot:hover:not(:disabled) {
/* ── Credential links ─────────────────────────────────────── */ /* ── Credential links ─────────────────────────────────────── */
.creds-link { .creds-link {
color: #58a6ff; color: #7ee787;
text-decoration: none; text-decoration: none;
word-break: break-all; word-break: break-all;
} }
.creds-link:hover { .creds-link:hover {
text-decoration: underline; text-decoration: underline;
color: #79c0ff; color: #a5f0b0;
}
} }

View File

@@ -209,37 +209,6 @@ LAUNCHER
in in
{ {
config = { config = {
# ── Save internal IP for hub credentials ────────────────────
systemd.services.save-internal-ip = {
description = "Save internal IP address for hub credentials";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.iproute2 pkgs.coreutils pkgs.hostname ];
script = ''
mkdir -p /var/lib/secrets
IP=$(hostname -I | awk '{print $1}')
if [ -n "$IP" ]; then
echo "$IP" > /var/lib/secrets/internal-ip
chmod 644 /var/lib/secrets/internal-ip
fi
'';
};
# ── Refresh IP periodically (in case DHCP changes it) ──────
systemd.timers.save-internal-ip = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "30s";
OnUnitActiveSec = "15min";
Unit = "save-internal-ip.service";
};
};
# ── Web server as a systemd service ──────────────────────── # ── Web server as a systemd service ────────────────────────
systemd.services.sovran-hub-web = { systemd.services.sovran-hub-web = {
description = "Sovran_SystemsOS Hub Web Interface"; description = "Sovran_SystemsOS Hub Web Interface";