From 8b2a11ca81b39b74c9cd36c38e2d339597db2fda Mon Sep 17 00:00:00 2001 From: kazet Date: Wed, 17 Jan 2024 19:15:49 +0100 Subject: [PATCH] Dashboard can be served on a non-root path (#79) --- karton/dashboard/app.py | 67 ++++++++++++-------- karton/dashboard/static/graph/graph.js | 2 +- karton/dashboard/templates/analysis.html | 4 +- karton/dashboard/templates/crashed.html | 10 +-- karton/dashboard/templates/graph.html | 6 +- karton/dashboard/templates/index.html | 4 +- karton/dashboard/templates/layout.html | 12 ++-- karton/dashboard/templates/queue.html | 6 +- karton/dashboard/templates/queue_layout.html | 4 +- karton/dashboard/templates/task.html | 6 +- requirements.txt | 2 +- 11 files changed, 68 insertions(+), 55 deletions(-) diff --git a/karton/dashboard/app.py b/karton/dashboard/app.py index 0c642fb..23591c0 100644 --- a/karton/dashboard/app.py +++ b/karton/dashboard/app.py @@ -10,7 +10,8 @@ from typing import Any, Dict, List, Optional, Tuple import mistune # type: ignore -from flask import ( # type: ignore +from flask import ( + Blueprint, Flask, jsonify, redirect, @@ -29,11 +30,6 @@ logging.basicConfig(level=logging.INFO) -app_path = Path(__file__).parent -static_folder = app_path / "static" -graph_folder = app_path / "graph" -app = Flask(__name__, static_folder=None, template_folder=str(app_path / "templates")) - class KartonDashboard(KartonBase): identity = "karton.dashboard" @@ -43,6 +39,17 @@ class KartonDashboard(KartonBase): karton = KartonDashboard() +base_path = karton.config.get("dashboard", "base_path", fallback="") + +app_path = Path(__file__).parent +static_folder = app_path / "static" +graph_folder = app_path / "graph" +app = Flask(__name__, static_folder=None) +blueprint = Blueprint( + "dashboard", __name__, template_folder=str(app_path / "templates") +) + + markdown = mistune.create_markdown( escape=True, renderer="html", @@ -186,12 +193,15 @@ def get_xrefs(root_uid) -> List[Tuple[str, str]]: def add_metrics(state: KartonState, metric: KartonMetrics, key: str) -> None: - metrics = {k: int(v) for k, v in state.backend.redis.hgetall(metric.value).items()} + metrics = { + k: int(v) + for k, v in state.backend.redis.hgetall(metric.value).items() # type: ignore + } for name, value in metrics.items(): karton_metrics.labels(key, name).set(value) -@app.route("/varz", methods=["GET"]) +@blueprint.route("/varz", methods=["GET"]) def varz(): """Update and get prometheus metrics""" @@ -208,7 +218,7 @@ def varz(): task_infos[(safe_name, task.priority, task.status)] += 1 # set the default of active queues to 0 to avoid gaps in graphs - for (priority, status) in product(TaskPriority, TaskState): + for priority, status in product(TaskPriority, TaskState): karton_tasks.labels(safe_name, priority.value, status.value).set(0) for (name, priority, status), count in task_infos.items(): @@ -226,18 +236,18 @@ def varz(): return generate_latest() -@app.route("/static/", methods=["GET"]) +@blueprint.route("/static/", methods=["GET"]) def static(path: str): return send_from_directory(static_folder, path) -@app.route("/", methods=["GET"]) +@blueprint.route("/", methods=["GET"]) def get_queues(): state = KartonState(karton.backend) return render_template("index.html", queues=state.queues) -@app.route("/services", methods=["GET"]) +@blueprint.route("/services", methods=["GET"]) def get_services(): aggregated_services = defaultdict(list) online_services = karton.backend.get_online_services() @@ -246,7 +256,7 @@ def get_services(): return render_template("services.html", services=aggregated_services) -@app.route("/api/queues", methods=["GET"]) +@blueprint.route("/api/queues", methods=["GET"]) def get_queues_api(): state = KartonState(karton.backend) return jsonify( @@ -257,7 +267,7 @@ def get_queues_api(): ) -@app.route("//restart_crashed", methods=["POST"]) +@blueprint.route("//restart_crashed", methods=["POST"]) def restart_crashed_queue_tasks(queue_name): state = KartonState(karton.backend) queue = state.queues.get(queue_name) @@ -269,7 +279,7 @@ def restart_crashed_queue_tasks(queue_name): return redirect(request.referrer) -@app.route("//cancel_crashed", methods=["POST"]) +@blueprint.route("//cancel_crashed", methods=["POST"]) def cancel_crashed_queue_tasks(queue_name): state = KartonState(karton.backend) queue = state.queues.get(queue_name) @@ -280,7 +290,7 @@ def cancel_crashed_queue_tasks(queue_name): return redirect(request.referrer) -@app.route("//cancel_pending", methods=["POST"]) +@blueprint.route("//cancel_pending", methods=["POST"]) def cancel_pending_queue_tasks(queue_name): state = KartonState(karton.backend) queue = state.queues.get(queue_name) @@ -291,7 +301,7 @@ def cancel_pending_queue_tasks(queue_name): return redirect(request.referrer) -@app.route("/restart_task//restart", methods=["POST"]) +@blueprint.route("/restart_task//restart", methods=["POST"]) def restart_task(task_id): task = karton.backend.get_task(task_id) if not task: @@ -301,7 +311,7 @@ def restart_task(task_id): return redirect(request.referrer) -@app.route("/cancel_task//cancel", methods=["POST"]) +@blueprint.route("/cancel_task//cancel", methods=["POST"]) def cancel_task(task_id): task = karton.backend.get_task(task_id) if not task: @@ -311,7 +321,7 @@ def cancel_task(task_id): return redirect(request.referrer) -@app.route("/queue/", methods=["GET"]) +@blueprint.route("/queue/", methods=["GET"]) def get_queue(queue_name): state = KartonState(karton.backend) queue = state.queues.get(queue_name) @@ -321,7 +331,7 @@ def get_queue(queue_name): return render_template("queue.html", name=queue_name, queue=queue) -@app.route("/queue//crashed", methods=["GET"]) +@blueprint.route("/queue//crashed", methods=["GET"]) def get_crashed_queue(queue_name): state = KartonState(karton.backend) queue = state.queues.get(queue_name) @@ -331,7 +341,7 @@ def get_crashed_queue(queue_name): return render_template("crashed.html", name=queue_name, queue=queue) -@app.route("/api/queue/", methods=["GET"]) +@blueprint.route("/api/queue/", methods=["GET"]) def get_queue_api(queue_name): state = KartonState(karton.backend) queue = state.queues.get(queue_name) @@ -340,7 +350,7 @@ def get_queue_api(queue_name): return jsonify(QueueView(queue).to_dict()) -@app.route("/task/", methods=["GET"]) +@blueprint.route("/task/", methods=["GET"]) def get_task(task_id): task = karton.backend.get_task(task_id) if not task: @@ -351,7 +361,7 @@ def get_task(task_id): ) -@app.route("/api/task/", methods=["GET"]) +@blueprint.route("/api/task/", methods=["GET"]) def get_task_api(task_id): task = karton.backend.get_task(task_id) if not task: @@ -359,7 +369,7 @@ def get_task_api(task_id): return jsonify(TaskView(task).to_dict()) -@app.route("/analysis/", methods=["GET"]) +@blueprint.route("/analysis/", methods=["GET"]) def get_analysis(root_id): state = KartonState(karton.backend) analysis = state.analyses.get(root_id) @@ -371,7 +381,7 @@ def get_analysis(root_id): ) -@app.route("/api/analysis/", methods=["GET"]) +@blueprint.route("/api/analysis/", methods=["GET"]) def get_analysis_api(root_id): state = KartonState(karton.backend) analysis = state.analyses.get(root_id) @@ -381,15 +391,18 @@ def get_analysis_api(root_id): return jsonify(AnalysisView(analysis).to_dict()) -@app.route("/graph", methods=["GET"]) +@blueprint.route("/graph", methods=["GET"]) def get_graph(): return render_template("graph.html") -@app.route("/graph/generate", methods=["GET"]) +@blueprint.route("/graph/generate", methods=["GET"]) def generate_graph(): state = KartonState(karton.backend) graph = KartonGraph(state) raw_graph = graph.generate_graph() return raw_graph + + +app.register_blueprint(blueprint, url_prefix=base_path) diff --git a/karton/dashboard/static/graph/graph.js b/karton/dashboard/static/graph/graph.js index 729e940..906ece5 100644 --- a/karton/dashboard/static/graph/graph.js +++ b/karton/dashboard/static/graph/graph.js @@ -26,7 +26,7 @@ window.onresize = function() { option = null; myChart.showLoading('default', loadingOpts); -$.get("/graph/generate", function(raw_graph) { +$.get(dom.getAttribute('data-generate-url'), function(raw_graph) { myChart.hideLoading(); myChart.resize(); diff --git a/karton/dashboard/templates/analysis.html b/karton/dashboard/templates/analysis.html index 104adff..358d269 100644 --- a/karton/dashboard/templates/analysis.html +++ b/karton/dashboard/templates/analysis.html @@ -32,10 +32,10 @@

Tasks

{% for task in queue.pending_tasks %} - {{identity}} + {{identity}} - {{ task.uid }} + {{ task.uid }} {% if task.priority.value != 'normal' %} diff --git a/karton/dashboard/templates/crashed.html b/karton/dashboard/templates/crashed.html index d1fd9e6..c2a3518 100644 --- a/karton/dashboard/templates/crashed.html +++ b/karton/dashboard/templates/crashed.html @@ -4,11 +4,11 @@

Crashed tasks {% if queue.crashed_tasks %}
-
+
-
+
@@ -28,7 +28,7 @@

{% for task in queue.crashed_tasks|sort(attribute='last_update', reverse=True) %} - {{ task.uid }} + {{ task.uid }}
{{ task.last_update|render_timestamp }}
@@ -54,7 +54,7 @@

-
+
-
+
@@ -23,7 +23,7 @@

{% for task in queue.pending_tasks|sort(attribute='last_update', reverse=True) %} - {{ task.uid }} + {{ task.uid }}
{{ task.last_update|render_timestamp }}
@@ -46,7 +46,7 @@

-
+
diff --git a/karton/dashboard/templates/queue_layout.html b/karton/dashboard/templates/queue_layout.html index 2b79759..e25d8eb 100644 --- a/karton/dashboard/templates/queue_layout.html +++ b/karton/dashboard/templates/queue_layout.html @@ -46,7 +46,7 @@

queue {{ name }}

no {% endif %} -
Spawned tasks
+
Spawned tasks
{% set length = queue.pending_tasks | length %} {% if length == 0 %} @@ -57,7 +57,7 @@

queue {{ name }}

{{length}} {% endif %}
-
Crashed tasks
+
Crashed tasks
{% if queue.crashed_tasks | length > 0 %} {{queue.crashed_tasks | length}} diff --git a/karton/dashboard/templates/task.html b/karton/dashboard/templates/task.html index 853c31b..5a648f8 100644 --- a/karton/dashboard/templates/task.html +++ b/karton/dashboard/templates/task.html @@ -17,17 +17,17 @@

task {{ task.uid }}

{{task.parent_uid}}
Root UID
- + {{task.root_uid}}
Origin
- {{task.headers['origin']}} + {{task.headers['origin']}}
Receiver
- {{task.headers['receiver']}} + {{task.headers['receiver']}}
Xrefs
diff --git a/requirements.txt b/requirements.txt index 78a4790..b62d18e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Flask==2.0.3 +Flask==3.0.0 karton-core>=5.1.0,<6.0.0 mistune<3.0.0 prometheus_client==0.11.0