Skip to content

Commit

Permalink
dashboard/app: add admin page
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dvyukov committed Apr 5, 2019
1 parent ecbfbf0 commit fa76348
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 90 deletions.
80 changes: 80 additions & 0 deletions 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}}&#013;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>
2 changes: 1 addition & 1 deletion dashboard/app/app.yaml
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions dashboard/app/handler.go
Expand Up @@ -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 {
Expand Down
57 changes: 35 additions & 22 deletions dashboard/app/main.go
Expand Up @@ -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)))
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
Expand Down
67 changes: 0 additions & 67 deletions dashboard/app/main.html
Expand Up @@ -14,73 +14,6 @@
<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}}&#013;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>
Expand Down
3 changes: 3 additions & 0 deletions dashboard/app/templates.html
Expand Up @@ -27,6 +27,9 @@
<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}}
Expand Down
1 change: 1 addition & 0 deletions dashboard/app/util_test.go
Expand Up @@ -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 {
Expand Down

0 comments on commit fa76348

Please sign in to comment.