made scripts just an easy startup and first setup over web admin page
This commit is contained in:
parent
7b788408b9
commit
e59d85cf57
3 changed files with 168 additions and 19 deletions
|
|
@ -2,10 +2,17 @@
|
||||||
setlocal enabledelayedexpansion
|
setlocal enabledelayedexpansion
|
||||||
cd /d "%~dp0"
|
cd /d "%~dp0"
|
||||||
|
|
||||||
rem Checks prerequisites (Go, Python 3, and its packages), then launches the
|
rem Checks prerequisites (Go, Python 3, and its packages), then hands off to
|
||||||
rem interactive server-panel TUI (tui-panel\server-panel.py). Run this instead
|
rem tui-panel\server-panel.py. Run this instead of that script directly so
|
||||||
rem of the TUI directly so missing prerequisites get a clear message instead
|
rem missing prerequisites get a clear message instead of a Python traceback.
|
||||||
rem of a Python traceback.
|
rem
|
||||||
|
rem owpengram-server.bat bootstraps .env on a fresh install, starts
|
||||||
|
rem everything, prints the admin panel URL,
|
||||||
|
rem and exits -- no prompts. First-time setup
|
||||||
|
rem (branding, SMTP, the admin password) then
|
||||||
|
rem happens in that web panel, not here.
|
||||||
|
rem owpengram-server.bat panel the interactive TUI instead -- stop/
|
||||||
|
rem restart/logs/.env editing from a menu.
|
||||||
|
|
||||||
echo == Checking prerequisites ==
|
echo == Checking prerequisites ==
|
||||||
|
|
||||||
|
|
@ -71,6 +78,6 @@ if "%PROBLEMS%"=="1" (
|
||||||
)
|
)
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo [cfg] All prerequisites OK, launching server panel...
|
echo [cfg] All prerequisites OK.
|
||||||
echo.
|
echo.
|
||||||
!PYTHON! tui-panel\server-panel.py %*
|
!PYTHON! tui-panel\server-panel.py %*
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,15 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Checks prerequisites (Go, Python 3, and its packages), then launches the
|
# Checks prerequisites (Go, Python 3, and its packages), then hands off to
|
||||||
# interactive server-panel TUI (tui-panel/server-panel.py). Run this instead
|
# tui-panel/server-panel.py. Run this instead of that script directly so
|
||||||
# of the TUI directly so missing prerequisites get a clear message instead of
|
# missing prerequisites get a clear message instead of a Python traceback.
|
||||||
# a Python traceback.
|
#
|
||||||
|
# ./owpengram-server.sh bootstraps .env on a fresh install, starts
|
||||||
|
# everything, prints the admin panel URL,
|
||||||
|
# and exits -- no prompts. First-time setup
|
||||||
|
# (branding, SMTP, the admin password) then
|
||||||
|
# happens in that web panel, not here.
|
||||||
|
# ./owpengram-server.sh panel the interactive TUI instead -- stop/
|
||||||
|
# restart/logs/.env editing from a menu.
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
|
@ -83,6 +90,6 @@ if [[ "$PROBLEMS" -ne 0 ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "[cfg] All prerequisites OK, launching server panel..."
|
echo "[cfg] All prerequisites OK."
|
||||||
echo
|
echo
|
||||||
exec "$PYTHON" tui-panel/server-panel.py "$@"
|
exec "$PYTHON" tui-panel/server-panel.py "$@"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,18 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Interactive TUI control panel for the OwpenGram server.
|
"""Control panel for the OwpenGram server: a non-interactive quickstart mode
|
||||||
|
and an interactive TUI, both built on the same ServerManager.
|
||||||
|
|
||||||
Wraps the same operations as start-server.sh / start-server.bat (Docker
|
With no arguments (the default `owpengram-server.sh` / .bat invocation),
|
||||||
naming migration, Postgres naming migration, docker compose up, Go build,
|
quickstart() bootstraps .env on a fresh install (generating the one secret
|
||||||
launching owpengram-server / owpengram-admin-panel) behind a menu you can
|
that has no safe default -- the admin panel password -- instead of asking
|
||||||
navigate instead of re-running a script from scratch each time.
|
for it), brings up Docker, builds, launches both binaries, and prints the
|
||||||
|
admin panel URL. No prompts; first-time configuration (branding, SMTP,
|
||||||
|
changing that password) happens afterward in the web panel instead of here.
|
||||||
|
|
||||||
|
The `panel` argument instead opens the interactive TUI below: Docker naming
|
||||||
|
migration, Postgres naming migration, docker compose up, Go build, launching
|
||||||
|
owpengram-server / owpengram-admin-panel, all behind a menu, for anyone who
|
||||||
|
wants stop/restart/logs/.env editing from the terminal.
|
||||||
|
|
||||||
Starting the server launches both binaries as fully detached background
|
Starting the server launches both binaries as fully detached background
|
||||||
processes and writes their PIDs to .server_panel.json next to .env; closing
|
processes and writes their PIDs to .server_panel.json next to .env; closing
|
||||||
|
|
@ -609,6 +617,126 @@ def server_public_key_pem() -> str | None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# --- quickstart (non-interactive: bootstrap .env, start, print the URL) ----
|
||||||
|
#
|
||||||
|
# The interactive Setup screen asks for four things a human has an opinion
|
||||||
|
# on (advertise IP, public URL, app scheme, admin password) plus two pure
|
||||||
|
# secrets it already generates without asking (TELESRV_ADMIN_API_TOKEN,
|
||||||
|
# TELESRV_ADMIN_SESSION_KEY). Of the four, three already have a working
|
||||||
|
# .env.example default (loopback/localhost) -- editable later from the web
|
||||||
|
# panel's Server Settings, which parses the same .env.example groups this
|
||||||
|
# does. The fourth, the admin password, is the one thing telesrv-admin
|
||||||
|
# refuses to boot without and can't default to something public, so
|
||||||
|
# quickstart generates that one too instead of blocking on terminal input.
|
||||||
|
|
||||||
|
|
||||||
|
def bootstrap_env() -> str | None:
|
||||||
|
"""Creates .env from .env.example if this is a fresh install. Returns
|
||||||
|
the freshly generated admin password, or None if .env already existed
|
||||||
|
(nothing was generated or touched -- an existing password is never read
|
||||||
|
back for display, generated or not)."""
|
||||||
|
if is_initialized():
|
||||||
|
return None
|
||||||
|
values = current_env_values(parse_env_template())
|
||||||
|
admin_password = secrets.token_urlsafe(12)
|
||||||
|
values["TELESRV_ADMIN_API_TOKEN"] = secrets.token_hex(32)
|
||||||
|
values["TELESRV_ADMIN_SESSION_KEY"] = secrets.token_urlsafe(32)
|
||||||
|
values["TELESRV_ADMIN_UI_PASSWORD"] = admin_password
|
||||||
|
save_env(values)
|
||||||
|
return admin_password
|
||||||
|
|
||||||
|
|
||||||
|
def _run_naming_helper(cmd: list[str]) -> str:
|
||||||
|
"""Runs a Docker/DB naming-migration helper directly against the real
|
||||||
|
console. StartupProgressScreen's equivalent (_run_interactive) goes
|
||||||
|
through self.app.suspend() because Textual owns the terminal at that
|
||||||
|
point; quickstart never starts Textual, so there is nothing to suspend.
|
||||||
|
Safe to call unconditionally, even on a first-ever run: both scripts
|
||||||
|
only prompt when they find pre-existing 'telesrv_*' Docker state to
|
||||||
|
migrate, and fall back cleanly rather than hang when stdin isn't a real
|
||||||
|
terminal -- see their own doc comments."""
|
||||||
|
proc = subprocess.run(cmd, cwd=ROOT, stdout=subprocess.PIPE, text=True)
|
||||||
|
return proc.stdout or ""
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_naming_headless() -> tuple[str, str]:
|
||||||
|
cached = MANAGER.cached_docker_naming()
|
||||||
|
if cached is not None:
|
||||||
|
project, prefix = cached, cached
|
||||||
|
else:
|
||||||
|
project, prefix = MANAGER.resolve_docker_naming(_run_naming_helper)
|
||||||
|
if prefix == "owpengram" and MANAGER.cached_db_naming() is None:
|
||||||
|
MANAGER.resolve_db_naming(_run_naming_helper, f"{prefix}-postgres")
|
||||||
|
return project, prefix
|
||||||
|
|
||||||
|
|
||||||
|
def quickstart() -> int:
|
||||||
|
"""The default entry point: bootstrap, start, print where to go, exit --
|
||||||
|
no menu, no prompts. First-run configuration (branding, SMTP, the admin
|
||||||
|
password itself) all happens afterward in the web admin panel instead
|
||||||
|
of here; the interactive TUI (stop/restart/logs/.env editing) is still
|
||||||
|
available with the 'panel' argument for anyone who wants it. Returns a
|
||||||
|
process exit code."""
|
||||||
|
generated_password = bootstrap_env()
|
||||||
|
|
||||||
|
status = MANAGER.status()
|
||||||
|
if status.running:
|
||||||
|
print("[ok] Already running.")
|
||||||
|
else:
|
||||||
|
print("== Starting OwpenGram ==")
|
||||||
|
print()
|
||||||
|
try:
|
||||||
|
project, prefix = resolve_naming_headless()
|
||||||
|
except Exception as exc: # noqa: BLE001 - report and exit, no traceback
|
||||||
|
print(f"[ERROR] Docker naming resolution failed: {exc}")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print("[..] Starting Docker infrastructure...")
|
||||||
|
ok, out = MANAGER.docker_compose_up(project, prefix)
|
||||||
|
if not ok:
|
||||||
|
print(f"[ERROR] docker compose up failed:\n{out.strip()}")
|
||||||
|
return 1
|
||||||
|
print("[ok] Docker infrastructure up.")
|
||||||
|
|
||||||
|
print("[..] Waiting for PostgreSQL...")
|
||||||
|
if not MANAGER.wait_postgres(prefix):
|
||||||
|
print("[ERROR] PostgreSQL did not become ready within 60s.")
|
||||||
|
return 1
|
||||||
|
print("[ok] PostgreSQL ready.")
|
||||||
|
|
||||||
|
print("[..] Building binaries (go build)...")
|
||||||
|
ok, out = MANAGER.build()
|
||||||
|
if not ok:
|
||||||
|
print(f"[ERROR] Build failed:\n{out.strip()}")
|
||||||
|
return 1
|
||||||
|
print("[ok] Build complete.")
|
||||||
|
|
||||||
|
print("[..] Launching owpengram-server and owpengram-admin-panel...")
|
||||||
|
server_pid = MANAGER.launch(SERVER_EXE, SERVER_LOG)
|
||||||
|
admin_pid = MANAGER.launch(ADMIN_EXE, ADMIN_LOG)
|
||||||
|
save_state({
|
||||||
|
"server_pid": server_pid,
|
||||||
|
"admin_pid": admin_pid,
|
||||||
|
"docker_project": project,
|
||||||
|
"docker_prefix": prefix,
|
||||||
|
})
|
||||||
|
print("[ok] Launched.")
|
||||||
|
|
||||||
|
print()
|
||||||
|
info = admin_ui_info()
|
||||||
|
if info is None:
|
||||||
|
print("[WARN] TELESRV_ADMIN_UI_ADDR is not set -- can't show the admin panel URL.")
|
||||||
|
else:
|
||||||
|
url, _ = info
|
||||||
|
print(f"Open {url} to finish setting up your server.")
|
||||||
|
if generated_password:
|
||||||
|
print(f"Initial admin password: {generated_password}")
|
||||||
|
print("(create a named operator account, or change this one, from Operators in the admin panel)")
|
||||||
|
print()
|
||||||
|
print("For stop/restart/logs/.env editing from the terminal instead: owpengram-server.bat panel")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def copy_to_clipboard(text: str) -> bool:
|
def copy_to_clipboard(text: str) -> bool:
|
||||||
if IS_WINDOWS:
|
if IS_WINDOWS:
|
||||||
candidates = [["clip"]]
|
candidates = [["clip"]]
|
||||||
|
|
@ -1731,7 +1859,14 @@ class ServerPanelApp(App):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = ServerPanelApp()
|
# No argument (the normal `owpengram-server.bat` / .sh invocation):
|
||||||
app.run()
|
# quickstart -- bootstrap, start, print the admin panel URL, exit.
|
||||||
if app.request_restart:
|
# `panel`: the interactive TUI this file used to always open, still
|
||||||
os.execv(sys.executable, [sys.executable] + sys.argv)
|
# available for stop/restart/logs/.env editing from the terminal.
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1] == "panel":
|
||||||
|
app = ServerPanelApp()
|
||||||
|
app.run()
|
||||||
|
if app.request_restart:
|
||||||
|
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||||
|
else:
|
||||||
|
sys.exit(quickstart())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue