aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-01-30 12:38:26 +0100
committerAleksandr Nogikh <nogikh@google.com>2025-02-04 14:57:28 +0000
commitfaad89b8bb82e638f0b30b3bc10ce9b450402be2 (patch)
treed01d7c27828175bfaea4bad19aa61dbe7eedbfcd
parentd39ef2f9994801180e552101c3b63a7b4e4a8579 (diff)
syz-cluster/dashboard: display logs and reports of findings
-rw-r--r--syz-cluster/dashboard/handler.go20
-rw-r--r--syz-cluster/dashboard/main.go1
-rw-r--r--syz-cluster/dashboard/templates/series.html9
-rw-r--r--syz-cluster/pkg/db/finding_repo.go6
4 files changed, 35 insertions, 1 deletions
diff --git a/syz-cluster/dashboard/handler.go b/syz-cluster/dashboard/handler.go
index e85a587c8..f744a5ca9 100644
--- a/syz-cluster/dashboard/handler.go
+++ b/syz-cluster/dashboard/handler.go
@@ -167,6 +167,26 @@ func (h *dashboardHandler) patchContent(w http.ResponseWriter, r *http.Request)
h.streamBlob(w, patch.BodyURI)
}
+func (h *dashboardHandler) findingInfo(w http.ResponseWriter, r *http.Request) {
+ finding, err := h.findingRepo.GetByID(r.Context(), r.PathValue("id"))
+ if err != nil {
+ http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
+ return
+ }
+ if finding == nil {
+ http.Error(w, "no such finding exists in the DB", http.StatusNotFound)
+ return
+ }
+ switch r.PathValue("key") {
+ case "report":
+ h.streamBlob(w, finding.ReportURI)
+ case "log":
+ h.streamBlob(w, finding.LogURI)
+ default:
+ http.Error(w, "unknown key value", http.StatusBadRequest)
+ }
+}
+
func (h *dashboardHandler) streamBlob(w http.ResponseWriter, uri string) {
if uri == "" {
return
diff --git a/syz-cluster/dashboard/main.go b/syz-cluster/dashboard/main.go
index 2f551048c..0497cc86b 100644
--- a/syz-cluster/dashboard/main.go
+++ b/syz-cluster/dashboard/main.go
@@ -29,6 +29,7 @@ func main() {
http.HandleFunc("/sessions/{id}/log", handler.sessionLog)
http.HandleFunc("/series/{id}", handler.seriesInfo)
http.HandleFunc("/patches/{id}", handler.patchContent)
+ http.HandleFunc("/findings/{id}/{key}", handler.findingInfo)
http.HandleFunc("/", handler.seriesList)
staticFiles, err := fs.Sub(staticFs, "static")
diff --git a/syz-cluster/dashboard/templates/series.html b/syz-cluster/dashboard/templates/series.html
index 96b5d9ab6..adc10b8d2 100644
--- a/syz-cluster/dashboard/templates/series.html
+++ b/syz-cluster/dashboard/templates/series.html
@@ -126,7 +126,14 @@
<tbody>
{{range .Findings}}
<tr>
- <td>{{.Title}}</td>
+ <td>
+ {{if .ReportURI}}
+ <a href="/findings/{{.ID}}/report" class="modal-link-raw">{{.Title}}</a>
+ {{else}}
+ {{.Title}}
+ {{end}}
+ </td>
+ <td><a href="/findings/{{.ID}}/log" class="modal-link-raw">[Log]</a></td>
</tr>
{{end}}
</tbody>
diff --git a/syz-cluster/pkg/db/finding_repo.go b/syz-cluster/pkg/db/finding_repo.go
index c2964df8d..dff2acdd8 100644
--- a/syz-cluster/pkg/db/finding_repo.go
+++ b/syz-cluster/pkg/db/finding_repo.go
@@ -14,11 +14,17 @@ import (
type FindingRepository struct {
client *spanner.Client
+ *genericEntityOps[Finding, string]
}
func NewFindingRepository(client *spanner.Client) *FindingRepository {
return &FindingRepository{
client: client,
+ genericEntityOps: &genericEntityOps[Finding, string]{
+ client: client,
+ keyField: "ID",
+ table: "Findings",
+ },
}
}