Spaces:
Running
Running
Hermes Agent commited on
Commit ·
0bf0144
1
Parent(s): 8e49251
Fix OmniRoute missing binary & 502 error: install omniroute globally in Dockerfile and update gateway proxy to serve auto-refresh loading page with embedded /data/omniroute/omniroute.log output
Browse files- Dockerfile +2 -0
- gateway/utils.py +27 -5
Dockerfile
CHANGED
|
@@ -52,6 +52,8 @@ COPY --from=omniroute-source /usr/local/bin/npm /usr/local/bin/npm
|
|
| 52 |
COPY --from=omniroute-source /usr/local/bin/npx /usr/local/bin/npx
|
| 53 |
COPY --from=omniroute-source /usr/local/lib/node_modules /usr/local/lib/node_modules
|
| 54 |
|
|
|
|
|
|
|
| 55 |
RUN mkdir -p /root/.cache /data/cache /data/omniroute /data/open-webui
|
| 56 |
RUN chmod -R 777 /root/.cache /data/cache /omniroute
|
| 57 |
|
|
|
|
| 52 |
COPY --from=omniroute-source /usr/local/bin/npx /usr/local/bin/npx
|
| 53 |
COPY --from=omniroute-source /usr/local/lib/node_modules /usr/local/lib/node_modules
|
| 54 |
|
| 55 |
+
RUN npm install -g omniroute || true
|
| 56 |
+
|
| 57 |
RUN mkdir -p /root/.cache /data/cache /data/omniroute /data/open-webui
|
| 58 |
RUN chmod -R 777 /root/.cache /data/cache /omniroute
|
| 59 |
|
gateway/utils.py
CHANGED
|
@@ -161,31 +161,53 @@ async def proxy_http_request(
|
|
| 161 |
if attempt < 3:
|
| 162 |
await asyncio.sleep(0.3 * attempt)
|
| 163 |
continue
|
| 164 |
-
if method in ("GET", "HEAD") and request.url.path in ("/", "/index.html", "/healthz", "/health", "/omniroute", "/
|
| 165 |
-
service_name = "OmniRoute AI Gateway" if default_prefix == "/omniroute" else ("Jellyfin Media Server" if default_prefix == "/jellyfin" else "Open WebUI")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
html_retry = f"""<!DOCTYPE html>
|
| 167 |
<html>
|
| 168 |
<head>
|
| 169 |
<meta http-equiv="refresh" content="3">
|
| 170 |
<title>{service_name} Initializing...</title>
|
|
|
|
| 171 |
<style>
|
| 172 |
-
body {{ font-family: system-ui, -apple-system, sans-serif; background: #0d1117; color: #c9d1d9; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }}
|
| 173 |
-
.card {{ text-align: center; background: #161b22; padding: 2.5rem; border-radius: 12px; border: 1px solid #30363d; max-width:
|
| 174 |
.spinner {{ width: 40px; height: 40px; border: 4px solid #30363d; border-top-color: #58a6ff; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 1.5rem; }}
|
| 175 |
@keyframes spin {{ to {{ transform: rotate(360deg); }} }}
|
| 176 |
h2 {{ margin: 0 0 0.5rem; color: #f0f6fc; font-size: 1.25rem; }}
|
| 177 |
p {{ color: #8b949e; font-size: 0.9rem; margin: 0; }}
|
| 178 |
</style>
|
|
|
|
| 179 |
</head>
|
| 180 |
<body>
|
| 181 |
<div class="card">
|
| 182 |
<div class="spinner"></div>
|
| 183 |
<h2>Initializing {service_name}...</h2>
|
| 184 |
-
<p>The
|
|
|
|
| 185 |
</div>
|
| 186 |
</body>
|
| 187 |
</html>"""
|
| 188 |
return Response(content=html_retry, status_code=200, headers={"Retry-After": "3", "Refresh": "3"}, media_type="text/html")
|
|
|
|
| 189 |
return Response(
|
| 190 |
content=f"<h2>502 Service Unavailable</h2><p>Upstream starting: {exc}</p>",
|
| 191 |
status_code=502,
|
|
|
|
| 161 |
if attempt < 3:
|
| 162 |
await asyncio.sleep(0.3 * attempt)
|
| 163 |
continue
|
| 164 |
+
if method in ("GET", "HEAD") and ("html" in request.headers.get("accept", "").lower() or request.url.path in ("/", "/index.html", "/healthz", "/health", "/omniroute", "/dashboard", "/jellyfin") or request.url.path.startswith("/dashboard") or request.url.path.startswith("/omniroute") or request.url.path.startswith("/jellyfin")):
|
| 165 |
+
service_name = "OmniRoute AI Gateway" if default_prefix == "/omniroute" or "omniroute" in request.url.path or "dashboard" in request.url.path else ("Jellyfin Media Server" if default_prefix == "/jellyfin" or "jellyfin" in request.url.path else "Open WebUI")
|
| 166 |
+
|
| 167 |
+
log_content = ""
|
| 168 |
+
if service_name == "OmniRoute AI Gateway":
|
| 169 |
+
for log_file in ["/data/omniroute/omniroute.log", "/root/.omniroute/omniroute.log"]:
|
| 170 |
+
try:
|
| 171 |
+
if os.path.exists(log_file):
|
| 172 |
+
with open(log_file, "r", encoding="utf-8", errors="ignore") as f:
|
| 173 |
+
lines = f.readlines()
|
| 174 |
+
log_content = "".join(lines[-100:])
|
| 175 |
+
if log_content:
|
| 176 |
+
break
|
| 177 |
+
except Exception:
|
| 178 |
+
pass
|
| 179 |
+
|
| 180 |
+
safe_logs = log_content.replace("\\", "\\\\").replace("`", "\\`").replace("$", "\\$").replace("\n", "\\n") if log_content else ""
|
| 181 |
+
log_box = f'<pre style="text-align:left; background:#0d1117; padding:12px; border-radius:6px; color:#38bdf8; font-size:0.8rem; overflow-x:auto; max-height:200px; margin-top:1rem; border:1px solid #30363d;">{log_content}</pre>' if log_content else ''
|
| 182 |
+
log_script = f'<script>console.error("=== OMNIROUTE LOGS ==="); console.error(`{safe_logs}`);</script>' if safe_logs else ''
|
| 183 |
+
|
| 184 |
html_retry = f"""<!DOCTYPE html>
|
| 185 |
<html>
|
| 186 |
<head>
|
| 187 |
<meta http-equiv="refresh" content="3">
|
| 188 |
<title>{service_name} Initializing...</title>
|
| 189 |
+
|
| 190 |
<style>
|
| 191 |
+
body {{ font-family: system-ui, -apple-system, sans-serif; background: #0d1117; color: #c9d1d9; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; padding: 20px; box-sizing: border-box; }}
|
| 192 |
+
.card {{ text-align: center; background: #161b22; padding: 2.5rem; border-radius: 12px; border: 1px solid #30363d; max-width: 700px; width: 100%; }}
|
| 193 |
.spinner {{ width: 40px; height: 40px; border: 4px solid #30363d; border-top-color: #58a6ff; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 1.5rem; }}
|
| 194 |
@keyframes spin {{ to {{ transform: rotate(360deg); }} }}
|
| 195 |
h2 {{ margin: 0 0 0.5rem; color: #f0f6fc; font-size: 1.25rem; }}
|
| 196 |
p {{ color: #8b949e; font-size: 0.9rem; margin: 0; }}
|
| 197 |
</style>
|
| 198 |
+
{log_script}
|
| 199 |
</head>
|
| 200 |
<body>
|
| 201 |
<div class="card">
|
| 202 |
<div class="spinner"></div>
|
| 203 |
<h2>Initializing {service_name}...</h2>
|
| 204 |
+
<p>The service is completing backend startup. This page will refresh automatically in 3 seconds.</p>
|
| 205 |
+
{log_box}
|
| 206 |
</div>
|
| 207 |
</body>
|
| 208 |
</html>"""
|
| 209 |
return Response(content=html_retry, status_code=200, headers={"Retry-After": "3", "Refresh": "3"}, media_type="text/html")
|
| 210 |
+
|
| 211 |
return Response(
|
| 212 |
content=f"<h2>502 Service Unavailable</h2><p>Upstream starting: {exc}</p>",
|
| 213 |
status_code=502,
|