diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2019-04-05 16:00:20 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-04-05 17:56:42 +0200 |
| commit | fa763482c3e2ef60aa7210e1bff6b206ef814229 (patch) | |
| tree | 1eb39831df3bbe69b4acb87ecc1ff5d80ee3d42a | |
| parent | ecbfbf0bcfe4febf21a44d8e008b72e787b9fe98 (diff) | |
dashboard/app: add admin page
Add /admin page and move logs, jobs, manager onto it.
The main page is too overloaded and takes too long to load.
We need to start splitting it. This is a first step.
| -rw-r--r-- | dashboard/app/admin.html | 80 | ||||
| -rw-r--r-- | dashboard/app/app.yaml | 2 | ||||
| -rw-r--r-- | dashboard/app/handler.go | 2 | ||||
| -rw-r--r-- | dashboard/app/main.go | 57 | ||||
| -rw-r--r-- | dashboard/app/main.html | 67 | ||||
| -rw-r--r-- | dashboard/app/templates.html | 3 | ||||
| -rw-r--r-- | dashboard/app/util_test.go | 1 |
7 files changed, 122 insertions, 90 deletions
diff --git a/dashboard/app/admin.html b/dashboard/app/admin.html new file mode 100644 index 000000000..09fd67513 --- /dev/null +++ b/dashboard/app/admin.html @@ -0,0 +1,80 @@ +{{/* +Copyright 2019 syzkaller project authors. All rights reserved. +Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +Main page. +*/}} + +<!doctype html> +<html> +<head> + {{template "head" .Header}} + <title>syzbot</title> +</head> +<body> + {{template "header" .Header}} + + <a class="plain" href="#log"><div id="log"><b>Error log:</b></div></a> + <textarea id="log_textarea" readonly rows="20" wrap=off>{{printf "%s" .Log}}</textarea> + <script> + var textarea = document.getElementById("log_textarea"); + textarea.scrollTop = textarea.scrollHeight; + </script> + <br><br> + + {{template "manager_list" $.Managers}} + + <table class="list_table"> + <caption id="jobs"><a class="plain" href="#jobs">Recent jobs:</a></caption> + <tr> + <th>Bug</th> + <th>Created</th> + <th>Duration</th> + <th>User</th> + <th>Patch</th> + <th>Repo</th> + <th>Manager</th> + <th>Result</th> + </tr> + {{range $job := $.Jobs}} + <tr> + <td class="title"><a href="{{$job.BugLink}}">{{$job.BugTitle}}</a></td> + <td class="time">{{link $job.ExternalLink (formatTime $job.Created)}}</td> + <td class="time" title="started: {{formatTime $job.Started}}
finished: {{formatTime $job.Finished}}"> + {{formatDuration $job.Duration}}{{if gt $job.Attempts 1}} ({{$job.Attempts}}){{end}} + </td> + <td> + {{if eq $job.Type 0}} + {{$job.User}} + {{else if eq $job.Type 1}} + bisect + {{else if eq $job.Type 2}} + bisect fix + {{end}} + </td> + <td>{{optlink $job.PatchLink "patch"}}</td> + <td class="kernel" title="{{$job.KernelAlias}}">{{$job.KernelAlias}}</td> + <td title="{{$job.Namespace}}/{{$job.Reporting}}">{{$job.Manager}}</td> + <td class="result"> + {{if $job.ErrorLink}} + {{link $job.ErrorLink "error"}} + {{else if $job.LogLink}} + {{link $job.LogLink "log"}} + ({{if $job.Commit}}1{{else}}{{len $job.Commits}}{{end}}) + {{else if $job.CrashTitle}} + {{optlink $job.CrashReportLink "report"}} + {{optlink $job.CrashLogLink "log"}} + {{else if formatTime $job.Finished}} + OK + {{else if formatTime $job.Started}} + running + {{else}} + pending + {{end}} + </td> + </tr> + {{end}} + </table> + <br><br> +</body> +</html> diff --git a/dashboard/app/app.yaml b/dashboard/app/app.yaml index e3300bfa6..7c8d90ab9 100644 --- a/dashboard/app/app.yaml +++ b/dashboard/app/app.yaml @@ -25,7 +25,7 @@ handlers: - url: /(api) script: _go_app secure: always -- url: /(email_poll) +- url: /(admin|email_poll) script: _go_app login: admin secure: always diff --git a/dashboard/app/handler.go b/dashboard/app/handler.go index 167ca5857..7fc133bee 100644 --- a/dashboard/app/handler.go +++ b/dashboard/app/handler.go @@ -73,12 +73,14 @@ func serveTemplate(w http.ResponseWriter, name string, data interface{}) error { } type uiHeader struct { + Admin bool LoginLink string AnalyticsTrackingID string } func commonHeader(c context.Context, r *http.Request) *uiHeader { h := &uiHeader{ + Admin: accessLevel(c, r) == AccessAdmin, AnalyticsTrackingID: config.AnalyticsTrackingID, } if user.Current(c) == nil { diff --git a/dashboard/app/main.go b/dashboard/app/main.go index 01e2f683a..fdf3904fc 100644 --- a/dashboard/app/main.go +++ b/dashboard/app/main.go @@ -27,6 +27,7 @@ func initHTTPHandlers() { http.Handle("/", handlerWrapper(handleMain)) http.Handle("/bug", handlerWrapper(handleBug)) http.Handle("/text", handlerWrapper(handleText)) + http.Handle("/admin", handlerWrapper(handleAdmin)) http.Handle("/x/.config", handlerWrapper(handleTextX(textKernelConfig))) http.Handle("/x/log.txt", handlerWrapper(handleTextX(textCrashLog))) http.Handle("/x/report.txt", handlerWrapper(handleTextX(textCrashReport))) @@ -40,12 +41,16 @@ func initHTTPHandlers() { type uiMain struct { Header *uiHeader Now time.Time - Log []byte - Managers []*uiManager - Jobs []*uiJob BugNamespaces []*uiBugNamespace } +type uiAdminPage struct { + Header *uiHeader + Log []byte + Managers []*uiManager + Jobs []*uiJob +} + type uiManager struct { Now time.Time Namespace string @@ -186,27 +191,14 @@ type uiJob struct { // handleMain serves main page. func handleMain(c context.Context, w http.ResponseWriter, r *http.Request) error { - var errorLog []byte - var managers []*uiManager - var jobs []*uiJob accessLevel := accessLevel(c, r) - + var managers []*uiManager if r.FormValue("fixed") == "" { var err error managers, err = loadManagers(c, accessLevel) if err != nil { return err } - if accessLevel == AccessAdmin { - errorLog, err = fetchErrorLogs(c) - if err != nil { - return err - } - jobs, err = loadRecentJobs(c) - if err != nil { - return err - } - } } bugNamespaces, err := fetchBugs(c, r) if err != nil { @@ -222,16 +214,37 @@ func handleMain(c context.Context, w http.ResponseWriter, r *http.Request) error data := &uiMain{ Header: commonHeader(c, r), Now: timeNow(c), - Log: errorLog, - Jobs: jobs, BugNamespaces: bugNamespaces, } - if accessLevel == AccessAdmin { - data.Managers = managers - } return serveTemplate(w, "main.html", data) } +func handleAdmin(c context.Context, w http.ResponseWriter, r *http.Request) error { + accessLevel := accessLevel(c, r) + if accessLevel != AccessAdmin { + return ErrAccess + } + managers, err := loadManagers(c, accessLevel) + if err != nil { + return err + } + errorLog, err := fetchErrorLogs(c) + if err != nil { + return err + } + jobs, err := loadRecentJobs(c) + if err != nil { + return err + } + data := &uiAdminPage{ + Header: commonHeader(c, r), + Log: errorLog, + Managers: managers, + Jobs: jobs, + } + return serveTemplate(w, "admin.html", data) +} + // handleBug serves page about a single bug (which is passed in id argument). func handleBug(c context.Context, w http.ResponseWriter, r *http.Request) error { bug := new(Bug) diff --git a/dashboard/app/main.html b/dashboard/app/main.html index f0f2db9e7..e1fc5a5ec 100644 --- a/dashboard/app/main.html +++ b/dashboard/app/main.html @@ -14,73 +14,6 @@ Main page. <body> {{template "header" .Header}} - {{if .Log}} - <a class="plain" href="#log"><div id="log"><b>Error log:</b></div></a> - <textarea id="log_textarea" readonly rows="20" wrap=off>{{printf "%s" .Log}}</textarea> - <script> - var textarea = document.getElementById("log_textarea"); - textarea.scrollTop = textarea.scrollHeight; - </script> - <br><br> - {{end}} - - {{template "manager_list" $.Managers}} - - {{if $.Jobs}} - <table class="list_table"> - <caption id="jobs"><a class="plain" href="#jobs">Recent jobs:</a></caption> - <tr> - <th>Bug</th> - <th>Created</th> - <th>Duration</th> - <th>User</th> - <th>Patch</th> - <th>Repo</th> - <th>Manager</th> - <th>Result</th> - </tr> - {{range $job := $.Jobs}} - <tr> - <td class="title"><a href="{{$job.BugLink}}">{{$job.BugTitle}}</a></td> - <td class="time">{{link $job.ExternalLink (formatTime $job.Created)}}</td> - <td class="time" title="started: {{formatTime $job.Started}}
finished: {{formatTime $job.Finished}}"> - {{formatDuration $job.Duration}}{{if gt $job.Attempts 1}} ({{$job.Attempts}}){{end}} - </td> - <td> - {{if eq $job.Type 0}} - {{$job.User}} - {{else if eq $job.Type 1}} - bisect - {{else if eq $job.Type 2}} - bisect fix - {{end}} - </td> - <td>{{optlink $job.PatchLink "patch"}}</td> - <td class="kernel" title="{{$job.KernelAlias}}">{{$job.KernelAlias}}</td> - <td title="{{$job.Namespace}}/{{$job.Reporting}}">{{$job.Manager}}</td> - <td class="result"> - {{if $job.ErrorLink}} - {{link $job.ErrorLink "error"}} - {{else if $job.LogLink}} - {{link $job.LogLink "log"}} - ({{if $job.Commit}}1{{else}}{{len $job.Commits}}{{end}}) - {{else if $job.CrashTitle}} - {{optlink $job.CrashReportLink "report"}} - {{optlink $job.CrashLogLink "log"}} - {{else if formatTime $job.Finished}} - OK - {{else if formatTime $job.Started}} - running - {{else}} - pending - {{end}} - </td> - </tr> - {{end}} - </table> - <br><br> - {{end}} - {{range $ns := $.BugNamespaces}} <br> <a class="plain" href="#{{$ns.Name}}"><h2 id="{{$ns.Name}}">{{$ns.Caption}}</h2></a> diff --git a/dashboard/app/templates.html b/dashboard/app/templates.html index 3d7bba401..5747aa722 100644 --- a/dashboard/app/templates.html +++ b/dashboard/app/templates.html @@ -27,6 +27,9 @@ Use of this source code is governed by Apache 2 LICENSE that can be found in the <h1><a href="/">syzbot</a></h1> </td> <td class="search"> + {{if .Admin}} + <a href="/admin">admin</a> | + {{end}} {{if .LoginLink}} <a href="{{.LoginLink}}">sign-in</a> | {{end}} diff --git a/dashboard/app/util_test.go b/dashboard/app/util_test.go index a12b9ec41..73d1986ad 100644 --- a/dashboard/app/util_test.go +++ b/dashboard/app/util_test.go @@ -140,6 +140,7 @@ func (c *Ctx) Close() { if !c.t.Failed() { // Ensure that we can render main page and all bugs in the final test state. c.expectOK(c.GET("/")) + c.expectOK(c.GET("/admin")) var bugs []*Bug keys, err := db.NewQuery("Bug").GetAll(c.ctx, &bugs) if err != nil { |
