Add container info as well
This commit is contained in:
80
app.py
80
app.py
@@ -159,6 +159,62 @@ def get_container_logs(container_name: str, lines: int = 50) -> list[dict]:
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
def get_container_detail(container_name: str) -> dict:
|
||||
"""
|
||||
Get detailed container information using docker inspect.
|
||||
Returns parsed container metadata.
|
||||
"""
|
||||
try:
|
||||
out = sh([DOCKER, "inspect", container_name])
|
||||
inspect_data = json.loads(out)
|
||||
|
||||
if not inspect_data:
|
||||
return {}
|
||||
|
||||
container = inspect_data[0]
|
||||
|
||||
# Extract useful information
|
||||
config = container.get("Config", {})
|
||||
state = container.get("State", {})
|
||||
network_settings = container.get("NetworkSettings", {})
|
||||
mounts = container.get("Mounts", [])
|
||||
|
||||
return {
|
||||
"name": container.get("Name", "").lstrip("/"),
|
||||
"id": container.get("Id", "")[:12],
|
||||
"image": config.get("Image", ""),
|
||||
"created": container.get("Created", ""),
|
||||
"state": {
|
||||
"status": state.get("Status", ""),
|
||||
"running": state.get("Running", False),
|
||||
"paused": state.get("Paused", False),
|
||||
"restarting": state.get("Restarting", False),
|
||||
"started_at": state.get("StartedAt", ""),
|
||||
"finished_at": state.get("FinishedAt", ""),
|
||||
},
|
||||
"env": config.get("Env", []),
|
||||
"cmd": config.get("Cmd", []),
|
||||
"entrypoint": config.get("Entrypoint", []),
|
||||
"working_dir": config.get("WorkingDir", ""),
|
||||
"exposed_ports": list(config.get("ExposedPorts", {}).keys()),
|
||||
"ports": network_settings.get("Ports", {}),
|
||||
"networks": list(network_settings.get("Networks", {}).keys()),
|
||||
"ip_address": network_settings.get("IPAddress", ""),
|
||||
"mounts": [
|
||||
{
|
||||
"type": m.get("Type", ""),
|
||||
"source": m.get("Source", ""),
|
||||
"destination": m.get("Destination", ""),
|
||||
"mode": m.get("Mode", ""),
|
||||
"rw": m.get("RW", False),
|
||||
}
|
||||
for m in mounts
|
||||
],
|
||||
"restart_policy": container.get("HostConfig", {}).get("RestartPolicy", {}),
|
||||
}
|
||||
except Exception as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
def is_app_web_container(name: str) -> bool:
|
||||
# Dokku apps typically have containers like "<app>.web.1"
|
||||
return name.endswith(".web.1") and not name.startswith("dokku.")
|
||||
@@ -362,7 +418,7 @@ def login():
|
||||
password = request.form.get("password", "")
|
||||
if password == LOGS_PASSWORD:
|
||||
session['logged_in'] = True
|
||||
return redirect(url_for('logs'))
|
||||
return redirect(url_for('admin'))
|
||||
else:
|
||||
return render_template("login.html", error="Invalid password")
|
||||
return render_template("login.html", error=None)
|
||||
@@ -372,9 +428,23 @@ def logout():
|
||||
session.pop('logged_in', None)
|
||||
return redirect(url_for('index'))
|
||||
|
||||
# Protected logs page
|
||||
@app.get("/logs")
|
||||
# Protected admin page (logs + container details)
|
||||
@app.get("/admin")
|
||||
@login_required
|
||||
def logs():
|
||||
def admin():
|
||||
data = collect_logs_only()
|
||||
return render_template("logs.html", data=data, poll_seconds=POLL_SECONDS)
|
||||
return render_template("admin.html", data=data, poll_seconds=POLL_SECONDS)
|
||||
|
||||
# Protected container detail page
|
||||
@app.get("/admin/container/<container_name>")
|
||||
@login_required
|
||||
def container_detail(container_name):
|
||||
detail = get_container_detail(container_name)
|
||||
return render_template("container_detail.html", container=detail, container_name=container_name)
|
||||
|
||||
# API endpoint for container details (used by admin panel)
|
||||
@app.get("/api/container/<container_name>")
|
||||
@login_required
|
||||
def api_container_detail(container_name):
|
||||
detail = get_container_detail(container_name)
|
||||
return jsonify(detail)
|
||||
|
||||
Reference in New Issue
Block a user