From 5ac551f36a661e356a6313f8e292c535a9ce7fc8 Mon Sep 17 00:00:00 2001 From: Simon Quigley Date: Fri, 31 Jan 2025 16:00:49 -0600 Subject: [PATCH] Allow fetching the log for a specific task --- cpp/ci_logic.cpp | 16 +++++--- cpp/ci_logic.h | 5 +-- cpp/lubuntuci_lib.cpp | 10 ----- cpp/lubuntuci_lib.h | 5 --- cpp/web_server.cpp | 87 +++++++++++++++++++++---------------------- templates/home.html | 8 ++++ templates/log.html | 6 +++ 7 files changed, 69 insertions(+), 68 deletions(-) create mode 100644 templates/log.html diff --git a/cpp/ci_logic.cpp b/cpp/ci_logic.cpp index 0a29d33..d6bafb8 100644 --- a/cpp/ci_logic.cpp +++ b/cpp/ci_logic.cpp @@ -817,9 +817,15 @@ void CiLogic::sync(std::shared_ptr pkgconf) { pkgconf->sync(); } -/** - * Stub logs - */ -std::string CiLogic::get_logs_for_repo_conf(int package_conf_id) { - return "Not implemented"; +std::string CiLogic::get_task_log(int task_id) { + QSqlQuery query(get_thread_connection()); + query.prepare("SELECT log FROM task WHERE id = ?"); + query.bindValue(0, task_id); + + if (!ci_query_exec(&query)) qDebug() << "Error getting log for task:" << query.lastError().text(); + while (query.next()) { + QString log = query.value("log").toString(); + if (!log.isEmpty()) return log.toStdString(); + } + return ""; } diff --git a/cpp/ci_logic.h b/cpp/ci_logic.h index 9b1df93..6e52e64 100644 --- a/cpp/ci_logic.h +++ b/cpp/ci_logic.h @@ -81,9 +81,6 @@ class CiLogic { // Function to enqueue tasks void enqueue(std::function task); - // Fetch logs for a specific PackageConf ID - std::string get_logs_for_repo_conf(int package_conf_id); - std::shared_ptr>> get_job_statuses(); std::vector> get_packageconfs(); std::shared_ptr get_packageconf_by_id(int id); @@ -98,6 +95,8 @@ class CiLogic { std::unique_ptr& task_queue, std::shared_ptr>> job_statuses); + std::string get_task_log(int task_id); + std::vector releases; std::vector packages; std::vector branches; diff --git a/cpp/lubuntuci_lib.cpp b/cpp/lubuntuci_lib.cpp index db64836..0e7f872 100644 --- a/cpp/lubuntuci_lib.cpp +++ b/cpp/lubuntuci_lib.cpp @@ -80,13 +80,3 @@ bool LubuntuCI::build_repo(const std::string &repo_name, std::shared_ptr lo } return success; } - -/** - * get_repo_log(): - * - Directly opens the repo in /srv/lubuntu-ci/repos/ - * - Reads HEAD commit message - */ -std::string LubuntuCI::get_repo_log(const std::string &repo_name) -{ - // FIXME: unused -} diff --git a/cpp/lubuntuci_lib.h b/cpp/lubuntuci_lib.h index fe5eb0b..39eca5b 100644 --- a/cpp/lubuntuci_lib.h +++ b/cpp/lubuntuci_lib.h @@ -42,11 +42,6 @@ public: */ bool build_repo(const std::string &repo_name, std::shared_ptr log = NULL); - /** - * Retrieve the most recent commit log from a named repo. - */ - std::string get_repo_log(const std::string &repo_name); - CiLogic cilogic = CiLogic(); }; diff --git a/cpp/web_server.cpp b/cpp/web_server.cpp index 08c19c5..7c7f2c6 100644 --- a/cpp/web_server.cpp +++ b/cpp/web_server.cpp @@ -559,23 +559,24 @@ bool WebServer::start_server(quint16 port) { item["upstream_commit"] = upstream_commit_str; item["upstream_commit_url"] = upstream_commit_url_str; - // For each job in the map, fetch the real task and set a CSS class accordingly. for (auto const & [job_name, job_ptr] : *job_statuses) { auto t = r->get_task_by_jobstatus(job_ptr); if (t) { - std::string css_class = "bg-secondary"; // default + std::string css_class = "bg-secondary"; if (t->finish_time > 0) { css_class = t->successful ? "bg-success" : "bg-danger"; } else if (t->start_time > 0) { - css_class = "bg-warning"; // started but not finished + css_class = "bg-warning"; } else { - css_class = "bg-info"; // queued but not started + css_class = "bg-info"; } item[job_name + "_class"] = css_class; + item[job_name + "_id"] = r->id; } else { item[job_name + "_class"] = ""; + item[job_name + "_id"] = ""; } } @@ -639,47 +640,6 @@ bool WebServer::start_server(quint16 port) { }); }); - ////////////////////////////////////////// - // /logs?repo=foo - ////////////////////////////////////////// - http_server_.route("/logs", [this, lubuntuci, job_statuses](const QHttpServerRequest &req) -> QFuture { - { - QHttpServerResponse session_response = verify_session_token(req, req.headers()); - if (session_response.statusCode() == StatusCodeFound) return QtConcurrent::run([response = std::move(session_response)]() mutable { return std::move(response); }); - } - auto query = req.query(); - std::string repo = query.queryItemValue("repo").toStdString(); - - return QtConcurrent::run([=, this]() { - if (repo.empty()) { - std::string msg = "No repo specified."; - return QHttpServerResponse("text/html", QByteArray(msg.c_str(), (int)msg.size())); - } - std::string log_content = lubuntuci->get_repo_log(repo); - - std::map>> list_context; - std::map context; - context["title"] = "Logs for " + repo; - - std::string body; - body += "

Logs: " + repo + "

"; - body += "
" + log_content + "
"; - - context["BODY_CONTENT"] = body; - - std::string final_html = TemplateRenderer::render_with_inheritance( - "base.html", - context, - list_context - ); - if (final_html.empty()) { - final_html = "

Log Output

"
-                             + log_content + "
"; - } - return QHttpServerResponse("text/html", QByteArray(final_html.c_str(), (int)final_html.size())); - }); - }); - ////////////////////////////////////////// // /pull-selected?repos= ////////////////////////////////////////// @@ -1004,6 +964,43 @@ bool WebServer::start_server(quint16 port) { }); }); + ////////////////////////////////////////// + // /log/ + ////////////////////////////////////////// + http_server_.route("/log/", [this, lubuntuci, job_statuses](const QString _task_id, const QHttpServerRequest &req) -> QFuture { + { + QHttpServerResponse session_response = verify_session_token(req, req.headers()); + if (session_response.statusCode() == StatusCodeFound) return QtConcurrent::run([response = std::move(session_response)]() mutable { return std::move(response); }); + } + return QtConcurrent::run([=, this]() { + int task_id; + try { + task_id = _task_id.toInt(); + if (task_id <= 0) { + std::string msg = "

Invalid task ID specified.

"; + return QHttpServerResponse("text/html", QByteArray(msg.c_str(), (int)msg.size())); + } + } catch (...) { + std::string msg = "

Invalid task ID specified.

"; + return QHttpServerResponse("text/html", QByteArray(msg.c_str(), (int)msg.size())); + } + + std::string log_content = lubuntuci->cilogic.get_task_log(task_id); + + std::map>> list_context; + std::map context; + context["title"] = "Task Logs"; + context["log"] = log_content; + + std::string final_html = TemplateRenderer::render_with_inheritance( + "log.html", + context, + list_context + ); + return QHttpServerResponse("text/html", QByteArray(final_html.c_str(), (int)final_html.size())); + }); + }); + { QSslConfiguration ssl_config = QSslConfiguration::defaultConfiguration(); QFile cert_file("/srv/lubuntu-ci/repos/ci-tools/server.crt"); diff --git a/templates/home.html b/templates/home.html index 12047fc..99ae84f 100644 --- a/templates/home.html +++ b/templates/home.html @@ -75,6 +75,7 @@
Pull +
{% endif %} @@ -83,6 +84,7 @@
Tarball +
{% endif %} @@ -91,6 +93,7 @@
Source Build +
{% endif %} @@ -99,6 +102,7 @@
Upload +
{% endif %} @@ -108,6 +112,7 @@
Source Check +
{% endif %} @@ -116,6 +121,7 @@
Build Check +
{% endif %} @@ -124,6 +130,7 @@
Lintian +
{% endif %} @@ -132,6 +139,7 @@
Britney +
{% endif %} diff --git a/templates/log.html b/templates/log.html new file mode 100644 index 0000000..ca537c3 --- /dev/null +++ b/templates/log.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} +{% block content %} +

{{PAGE_TITLE}}

+ +
{{ log }}
+{% endblock %}