marvis docker container, ignore ueransim
This commit is contained in:
BIN
app/services/__pycache__/ai.cpython-314.pyc
Normal file
BIN
app/services/__pycache__/ai.cpython-314.pyc
Normal file
Binary file not shown.
BIN
app/services/__pycache__/log_analyzer.cpython-314.pyc
Normal file
BIN
app/services/__pycache__/log_analyzer.cpython-314.pyc
Normal file
Binary file not shown.
BIN
app/services/__pycache__/ueransim.cpython-314.pyc
Normal file
BIN
app/services/__pycache__/ueransim.cpython-314.pyc
Normal file
Binary file not shown.
@@ -6,7 +6,15 @@ Phase 2: swap MARVIS_AI_MODE=openai or MARVIS_AI_MODE=ollama to route through LL
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from app.config import AI_MODE, OPENAI_API_KEY, OPENAI_MODEL, OPENAI_BASE_URL, OLLAMA_URL, OLLAMA_MODEL
|
||||
from app.config import (
|
||||
AI_MODE,
|
||||
CONTAINER_RUNTIME,
|
||||
OPENAI_API_KEY,
|
||||
OPENAI_MODEL,
|
||||
OPENAI_BASE_URL,
|
||||
OLLAMA_MODEL,
|
||||
OLLAMA_URL,
|
||||
)
|
||||
|
||||
|
||||
async def answer(query: str, network_state: dict, alerts: list) -> str:
|
||||
@@ -69,7 +77,7 @@ def _health_summary(up: list, down: list, alerts: list) -> str:
|
||||
lines.append(f"✅ **{len(up)} UP**: {', '.join(n['name'] for n in up)}")
|
||||
if down:
|
||||
lines.append(f"🔴 **{len(down)} DOWN**: {', '.join(n['name'] for n in down)}")
|
||||
lines.append(f" ⚡ Action: check `podman logs <nf>` on the VM")
|
||||
lines.append(f" ⚡ Action: check `{CONTAINER_RUNTIME} logs <nf>` in the runtime host")
|
||||
|
||||
if alerts:
|
||||
lines.append(f"\n⚠️ **{len(alerts)} alert(s)** — {len(crit)} critical, {len(warn)} warning")
|
||||
@@ -91,7 +99,7 @@ def _nf_detail(nf_name: str, nfs: list, alerts: list) -> str:
|
||||
|
||||
if not nf or nf["state"] == "unknown":
|
||||
return (f"ℹ️ No Prometheus data found for **{nf_name}**.\n"
|
||||
f"Check: `podman ps | grep {nf_name.lower()}`")
|
||||
f"Check: `{CONTAINER_RUNTIME} ps | grep {nf_name.lower()}`")
|
||||
|
||||
icon = "✅" if nf["state"] == "up" else "🔴"
|
||||
lines = [f"{icon} **{nf_name}** is **{nf['state'].upper()}**",
|
||||
|
||||
@@ -10,6 +10,8 @@ import time
|
||||
from collections import deque
|
||||
from datetime import datetime
|
||||
|
||||
from app.config import CONTAINER_HOST, CONTAINER_RUNTIME
|
||||
|
||||
# ── In-memory history (up to 96 snapshots ≈ 48 min at 30 s refresh) ────────
|
||||
_history: deque = deque(maxlen=96)
|
||||
|
||||
@@ -137,14 +139,18 @@ _container_cache_ts: float = 0.0
|
||||
|
||||
|
||||
async def _discover_containers() -> dict[str, str]:
|
||||
"""Run `podman ps` and map NF names to actual container names."""
|
||||
"""Run the configured container runtime and map NF names to actual container names."""
|
||||
global _container_cache, _container_cache_ts
|
||||
now = time.monotonic()
|
||||
if _container_cache and now - _container_cache_ts < 60:
|
||||
return _container_cache
|
||||
try:
|
||||
cmd = [CONTAINER_RUNTIME]
|
||||
if CONTAINER_HOST:
|
||||
cmd.extend(["--host", CONTAINER_HOST])
|
||||
cmd.extend(["ps", "--format", "{{.Names}}"])
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
"podman", "ps", "--format", "{{.Names}}",
|
||||
*cmd,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
@@ -167,10 +173,14 @@ async def _discover_containers() -> dict[str, str]:
|
||||
|
||||
|
||||
async def _read_logs(container: str, tail: int = 400) -> str:
|
||||
"""Read recent logs from a podman container (stdout + stderr)."""
|
||||
"""Read recent logs from a container (stdout + stderr)."""
|
||||
try:
|
||||
cmd = [CONTAINER_RUNTIME]
|
||||
if CONTAINER_HOST:
|
||||
cmd.extend(["--host", CONTAINER_HOST])
|
||||
cmd.extend(["logs", "--tail", str(tail), container])
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
"podman", "logs", "--tail", str(tail), container,
|
||||
*cmd,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
@@ -277,7 +287,7 @@ async def analyze_logs() -> dict:
|
||||
"severity": "critical",
|
||||
"count": 1,
|
||||
"description": f"{nf_st['name']} is unreachable",
|
||||
"remediation": (f"Run `podman ps` on the VM and check if {nf_st['name']} "
|
||||
"remediation": (f"Run `{CONTAINER_RUNTIME} ps` and check if {nf_st['name']} "
|
||||
f"container is running; inspect its logs."),
|
||||
"source": "prometheus",
|
||||
})
|
||||
|
||||
@@ -3,6 +3,16 @@ import uuid
|
||||
import time
|
||||
from typing import Dict, Optional
|
||||
|
||||
from app.config import (
|
||||
CONTAINER_HOST,
|
||||
CONTAINER_RUNTIME,
|
||||
UERANSIM_CONTAINER_NAME,
|
||||
UERANSIM_ENV_FILE,
|
||||
UERANSIM_IMAGE,
|
||||
UERANSIM_NETWORK_MODE,
|
||||
UERANSIM_PRIVILEGED,
|
||||
)
|
||||
|
||||
_tasks: Dict[str, dict] = {}
|
||||
|
||||
|
||||
@@ -28,31 +38,39 @@ async def run_test(task_id: str) -> None:
|
||||
def log(msg: str, type: str = "info") -> None:
|
||||
task["logs"].append({"msg": msg, "type": type, "ts": time.strftime("%H:%M:%S")})
|
||||
|
||||
log("▸ Checking UERANSIM Docker image…", "run")
|
||||
runtime_cmd = [CONTAINER_RUNTIME]
|
||||
if CONTAINER_HOST:
|
||||
runtime_cmd.extend(["--host", CONTAINER_HOST])
|
||||
|
||||
log(f"▸ Checking UERANSIM image via {CONTAINER_RUNTIME}…", "run")
|
||||
check = await asyncio.create_subprocess_exec(
|
||||
"docker", "images", "-q", "ueransim",
|
||||
*runtime_cmd, "images", "-q", UERANSIM_IMAGE,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
out, _ = await check.communicate()
|
||||
if not out.strip():
|
||||
log("✗ UERANSIM image not found.", "err")
|
||||
log(" SSH to host and run: bash /opt/p5g-marvis/build-ueransim.sh", "err")
|
||||
log(" Build it with `docker compose build ueransim` or set MARVIS_UERANSIM_IMAGE.", "err")
|
||||
task["status"] = "error"
|
||||
return
|
||||
|
||||
log(" UERANSIM image ready", "ok")
|
||||
log("▸ Starting test container — allow up to 60s…", "run")
|
||||
|
||||
env_file = "/opt/p5g-marvis/config/ueransim.env"
|
||||
|
||||
try:
|
||||
run_cmd = [*runtime_cmd, "run", "--rm", "--name", UERANSIM_CONTAINER_NAME]
|
||||
if UERANSIM_NETWORK_MODE:
|
||||
run_cmd.append(f"--network={UERANSIM_NETWORK_MODE}")
|
||||
if UERANSIM_PRIVILEGED:
|
||||
run_cmd.append("--privileged")
|
||||
run_cmd.extend([
|
||||
"--env-file", UERANSIM_ENV_FILE,
|
||||
UERANSIM_IMAGE,
|
||||
])
|
||||
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
"docker", "run", "--rm",
|
||||
"--network=host",
|
||||
"--privileged",
|
||||
"--env-file", env_file,
|
||||
"ueransim",
|
||||
*run_cmd,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.STDOUT,
|
||||
)
|
||||
@@ -81,7 +99,7 @@ async def run_test(task_id: str) -> None:
|
||||
log("✓ Emulated data session completed successfully", "ok")
|
||||
task["status"] = "done"
|
||||
elif proc.returncode == 2:
|
||||
log("⚠ Credentials not configured — edit /opt/p5g-marvis/config/ueransim.env", "warn")
|
||||
log(f"⚠ Credentials not configured — edit {UERANSIM_ENV_FILE}", "warn")
|
||||
task["status"] = "error"
|
||||
else:
|
||||
log(f"✗ Test exited with code {proc.returncode}", "err")
|
||||
|
||||
Reference in New Issue
Block a user