Fix ISO installer: remove ports dialog, fix Plymouth paths/logo, add welcome page, fix pixelated icon, fix disko args

Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/6b00bbbd-8ed5-4ef2-b2fc-bfbe6361e77c

Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-05 06:33:44 +00:00
committed by GitHub
parent f4a644dc05
commit 48826590de
3 changed files with 80 additions and 178 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -117,11 +117,8 @@ class InstallerWindow(Adw.ApplicationWindow):
self.nav = Adw.NavigationView()
self.set_content(self.nav)
# Check for internet before anything else
if check_internet():
self.push_welcome()
else:
self.push_no_internet()
# Always show the landing/welcome page first
self.push_landing()
# ── Navigation helpers ─────────────────────────────────────────────────
@@ -197,54 +194,93 @@ class InstallerWindow(Adw.ApplicationWindow):
return box
# ── No Internet Screen ─────────────────────────────────────────────────
# ── Landing / Welcome Screen ───────────────────────────────────────────
def push_no_internet(self):
def push_landing(self):
"""First screen: always shown. Welcomes the user and checks connectivity."""
outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
status = Adw.StatusPage()
status.set_title("No Internet Connection")
status.set_description(
"An active internet connection is required to install Sovran_SystemsOS.\n\n"
"Please connect an Ethernet cable or configure Wi-Fi,\n"
"then press Retry."
)
status.set_icon_name("network-offline-symbolic")
status.set_vexpand(True)
outer.append(status)
# Hero
hero = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
hero.set_margin_top(40)
hero.set_margin_bottom(16)
hero.set_halign(Gtk.Align.CENTER)
if os.path.exists(LOGO):
try:
img = Gtk.Image.new_from_file(LOGO)
img.set_pixel_size(320)
hero.append(img)
except Exception:
pass
title = Gtk.Label()
title.set_markup("<span size='xx-large' weight='heavy'>Welcome to Sovran SystemsOS</span>")
title.set_margin_top(8)
hero.append(title)
sub = Gtk.Label()
sub.set_markup("<span size='large' style='italic' foreground='#888888'>Be Digitally Sovereign</span>")
hero.append(sub)
outer.append(hero)
sep = Gtk.Separator()
sep.set_margin_start(40)
sep.set_margin_end(40)
sep.set_margin_top(8)
outer.append(sep)
# Internet requirement notice
notice = Gtk.Label()
notice.set_markup(
"<span size='medium'>"
"Before installation begins, please ensure you have an <b>active internet connection</b>.\n"
"Sovran SystemsOS downloads packages during installation and requires internet access\n"
"to complete the process. Connect via <b>Ethernet cable</b> or configure <b>Wi-Fi</b> now."
"</span>"
)
notice.set_justify(Gtk.Justification.CENTER)
notice.set_wrap(True)
notice.set_margin_top(20)
notice.set_margin_start(48)
notice.set_margin_end(48)
outer.append(notice)
# Inline offline warning banner (hidden by default)
self._offline_banner = Adw.Banner()
self._offline_banner.set_title(
"No internet connection detected. Please connect Ethernet or Wi-Fi and try again."
)
self._offline_banner.set_revealed(False)
self._offline_banner.set_margin_top(12)
self._offline_banner.set_margin_start(40)
self._offline_banner.set_margin_end(40)
outer.append(self._offline_banner)
outer.append(Gtk.Label(label="", vexpand=True))
# Check & Continue button
btn_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
btn_box.set_halign(Gtk.Align.CENTER)
btn_box.set_margin_bottom(32)
retry_btn = Gtk.Button(label="Retry")
retry_btn.add_css_class("suggested-action")
retry_btn.add_css_class("pill")
retry_btn.connect("clicked", self.on_retry_internet)
btn_box.append(retry_btn)
connect_btn = Gtk.Button(label="Check Connection & Continue →")
connect_btn.add_css_class("suggested-action")
connect_btn.add_css_class("pill")
connect_btn.connect("clicked", self._on_landing_connect)
btn_box.append(connect_btn)
outer.append(btn_box)
self.push_page("No Internet", outer)
self.push_page("Sovran_SystemsOS Installer", outer)
def on_retry_internet(self, btn):
def _on_landing_connect(self, btn):
if check_internet():
# Pop the no-internet page and proceed to welcome
try:
self.nav.pop()
except Exception:
pass
self._offline_banner.set_revealed(False)
self.push_welcome()
else:
dlg = Adw.MessageDialog()
dlg.set_transient_for(self)
dlg.set_heading("Still Offline")
dlg.set_body(
"Could not reach the internet.\n"
"Please check your network connection and try again."
)
dlg.add_response("ok", "OK")
dlg.present()
self._offline_banner.set_revealed(True)
# ── Step 1: Welcome & Role ─────────────────────────────────────────────
@@ -341,140 +377,7 @@ class InstallerWindow(Adw.ApplicationWindow):
if radio.get_active():
self.role = radio.get_name()
break
self.push_port_requirements()
# ── Step 1b: Port Requirements Notice ─────────────────────────────────
def push_port_requirements(self):
"""Inform the user about required router/firewall ports before install."""
outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
# Detect internal IP at install time
internal_ip = "this machine's LAN IP"
try:
import subprocess as _sp
_r = _sp.run(["hostname", "-I"], capture_output=True, text=True, timeout=5)
if _r.returncode == 0:
_parts = _r.stdout.strip().split()
if _parts:
internal_ip = _parts[0]
except Exception:
pass
# Warning banner
banner = Adw.Banner()
banner.set_title(
"⚠ Port Forwarding Setup Required — configure your router before install"
)
banner.set_revealed(True)
banner.set_margin_top(16)
banner.set_margin_start(40)
banner.set_margin_end(40)
outer.append(banner)
intro = Gtk.Label()
intro.set_markup(
"<span foreground='#a6adc8'>"
"Many Sovran_SystemsOS features require <b>port forwarding</b> to be configured "
"in your router's admin panel. This means telling your router to forward "
"specific ports to <b>this machine's internal LAN IP</b>.\n\n"
"Services like Element Video/Audio Calling and Matrix Federation "
"<b>will not work for clients outside your LAN</b> unless these ports are "
"forwarded to this machine."
"</span>"
)
intro.set_wrap(True)
intro.set_justify(Gtk.Justification.FILL)
intro.set_margin_top(14)
intro.set_margin_start(40)
intro.set_margin_end(40)
outer.append(intro)
ip_label = Gtk.Label()
ip_label.set_markup(
f"<span foreground='#89b4fa' font_desc='monospace'>"
f" Forward ports to this machine's internal IP: <b>{internal_ip}</b>"
f"</span>"
)
ip_label.set_margin_top(10)
ip_label.set_margin_start(40)
ip_label.set_margin_end(40)
outer.append(ip_label)
sw = Gtk.ScrolledWindow()
sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
sw.set_vexpand(True)
sw.set_margin_start(40)
sw.set_margin_end(40)
sw.set_margin_top(12)
sw.set_margin_bottom(8)
ports_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
port_sections = [
(
"🌐 Web / HTTPS (all domain-based services)",
[("80", "TCP", "HTTP (redirects to HTTPS)"),
("443", "TCP", "HTTPS")],
),
(
"💬 Matrix Federation (Matrix-Synapse)",
[("8448", "TCP", "Server-to-server federation")],
),
(
"🎥 Element Video & Audio Calling (LiveKit / Element-call)",
[("7881", "TCP", "LiveKit WebRTC signalling"),
("7882-7894", "UDP", "LiveKit media streams"),
("5349", "TCP", "TURN over TLS"),
("3478", "UDP", "TURN (STUN / relay)"),
("30000-40000", "TCP/UDP", "TURN relay (WebRTC media)")],
),
(
"🖥 Remote SSH (optional — only if you want WAN SSH access)",
[("22", "TCP", "SSH")],
),
]
for section_title, rows in port_sections:
group = Adw.PreferencesGroup()
group.set_title(section_title)
for port, proto, desc in rows:
row = Adw.ActionRow()
row.set_title(f"Port {port} ({proto})")
row.set_subtitle(desc)
group.add(row)
ports_box.append(group)
note = Gtk.Label()
note.set_markup(
"<span foreground='#6c7086' size='small'>"
" In your router's admin panel (usually at 192.168.1.1), find the "
"\"<b>Port Forwarding</b>\" section and add a rule for each port above with "
"the destination set to <b>this machine's internal IP</b>. "
"These ports only need to be forwarded to this specific machine — "
"this does <b>NOT</b> expose your entire network.\n"
"To verify forwarding is working, test from a device on a different network "
"(e.g. a phone on mobile data) or check your router's port forwarding page."
"</span>"
)
note.set_wrap(True)
note.set_justify(Gtk.Justification.FILL)
note.set_margin_top(8)
ports_box.append(note)
sw.set_child(ports_box)
outer.append(sw)
outer.append(self.nav_row(
back_label="← Back",
back_cb=lambda b: self.nav.pop(),
next_label="I Understand →",
next_cb=lambda b: self.push_disk_detect(),
))
self.push_page("Network Port Requirements", outer, show_back=True)
self.push_disk_detect()
# ── Step 2a: Disk Detect ──────────────────────────────────────────────
@@ -773,7 +676,6 @@ class InstallerWindow(Adw.ApplicationWindow):
status = Adw.StatusPage()
status.set_title(title)
status.set_description(subtitle)
status.set_icon_name("emblem-synchronizing-symbolic")
status.set_vexpand(False)
outer.append(status)
@@ -830,10 +732,10 @@ class InstallerWindow(Adw.ApplicationWindow):
cmd = [
"sudo", "disko", "--mode", "destroy,format,mount",
f"{FLAKE}/iso/disko.nix",
"--arg", "device", f'"{boot_path}"'
"--arg", "device", boot_path
]
if data_path:
cmd += ["--arg", "dataDevice", f'"{data_path}"']
cmd += ["--arg", "dataDevice", data_path]
run_stream(cmd, buf)
GLib.idle_add(append_text, buf, "\n=== Generating hardware config ===\n")

View File

@@ -10,15 +10,15 @@ pkgs.stdenv.mkDerivation {
mkdir -p $out/share/plymouth/themes/sovran
cp ${./assets/splash-logo.png} $out/share/plymouth/themes/sovran/logo.png
cat > $out/share/plymouth/themes/sovran/sovran.plymouth <<'EOF'
cat > $out/share/plymouth/themes/sovran/sovran.plymouth <<EOF
[Plymouth Theme]
Name=Sovran Systems
Description=Sovran Systems Splash
ModuleName=script
[script]
ImageDir=/share/plymouth/themes/sovran
ScriptFile=/share/plymouth/themes/sovran/sovran.script
ImageDir=$out/share/plymouth/themes/sovran
ScriptFile=$out/share/plymouth/themes/sovran/sovran.script
EOF
cat > $out/share/plymouth/themes/sovran/sovran.script <<'EOF'