x/tools/dashboard/app: update to support git

This adds a "Git" dashboard at "/git/", which has its own namespace for
datastore and memcache. Once we have pushed out the new git repositories
we will spin up a commit watcher and builders that point to the Git
dashboard.

Once we are ready to switch the dashboard over to the new Git builders,
the (*Dashboard).Context method will be changed to return "Git"
as the default namespace. The old builders will be retired, and the
new builders will be configured to report to "/" instead of "/git/".
At that point all our old data will still be available in the default
namespace, but hidden from view.

LGTM=dsymonds, cmang
R=bradfitz, cmang, dsymonds, adg
CC=golang-codereviews
https://golang.org/cl/183050043
This commit is contained in:
Andrew Gerrand 2014-12-04 10:45:11 +11:00
parent 4ed659d592
commit 2d83fa5bf1
15 changed files with 124 additions and 54 deletions

View File

@ -11,11 +11,11 @@ api_version: go1
handlers:
- url: /static
static_dir: static
- url: /(|gccgo/)log/.+
- url: /(|gccgo/|git/)log/.+
script: _go_app
- url: /(|gccgo/)(|commit|packages|result|perf-result|tag|todo|perf|perfdetail|perfgraph|updatebenchmark)
- url: /(|gccgo/|git/)(|commit|packages|result|perf-result|tag|todo|perf|perfdetail|perfgraph|updatebenchmark)
script: _go_app
- url: /(|gccgo/)(init|buildtest|key|perflearn|_ah/queue/go/delay)
- url: /(|gccgo/|git/)(init|buildtest|key|perflearn|_ah/queue/go/delay)
script: _go_app
login: admin

View File

@ -13,18 +13,27 @@ import (
"appengine"
)
func handleFunc(path string, h http.HandlerFunc) {
for _, d := range dashboards {
http.HandleFunc(d.Prefix+path, h)
}
}
// Dashboard describes a unique build dashboard.
type Dashboard struct {
Name string // This dashboard's name and namespace
RelPath string // The relative url path
Prefix string // The path prefix (no trailing /)
Packages []*Package // The project's packages to build
}
// dashboardForRequest returns the appropriate dashboard for a given URL path.
func dashboardForRequest(r *http.Request) *Dashboard {
if strings.HasPrefix(r.URL.Path, gccgoDash.RelPath) {
if strings.HasPrefix(r.URL.Path, gccgoDash.Prefix) {
return gccgoDash
}
if strings.HasPrefix(r.URL.Path, gitDash.Prefix) {
return gitDash
}
return goDash
}
@ -43,12 +52,12 @@ func (d *Dashboard) Context(c appengine.Context) appengine.Context {
}
// the currently known dashboards.
var dashboards = []*Dashboard{goDash, gccgoDash}
var dashboards = []*Dashboard{goDash, gitDash, gccgoDash}
// goDash is the dashboard for the main go repository.
var goDash = &Dashboard{
Name: "Go",
RelPath: "/",
Prefix: "",
Packages: goPackages,
}
@ -105,10 +114,71 @@ var goPackages = []*Package{
},
}
// gitDash is the dashboard for the main go repository on git.
var gitDash = &Dashboard{
Name: "Git",
Prefix: "/git",
Packages: gitPackages,
}
// gitPackages is a list of all of the packages built by the main go repository
// on git.
var gitPackages = []*Package{
{
Kind: "go",
Name: "Go",
},
{
Kind: "subrepo",
Name: "blog",
Path: "golang.org/x/blog",
},
{
Kind: "subrepo",
Name: "codereview",
Path: "golang.org/x/codereview",
},
{
Kind: "subrepo",
Name: "crypto",
Path: "golang.org/x/crypto",
},
{
Kind: "subrepo",
Name: "exp",
Path: "golang.org/x/exp",
},
{
Kind: "subrepo",
Name: "image",
Path: "golang.org/x/image",
},
{
Kind: "subrepo",
Name: "net",
Path: "golang.org/x/net",
},
{
Kind: "subrepo",
Name: "sys",
Path: "golang.org/x/sys",
},
{
Kind: "subrepo",
Name: "talks",
Path: "golang.org/x/talks",
},
{
Kind: "subrepo",
Name: "tools",
Path: "golang.org/x/tools",
},
}
// gccgoDash is the dashboard for gccgo.
var gccgoDash = &Dashboard{
Name: "Gccgo",
RelPath: "/gccgo/",
Name: "Gccgo",
Prefix: "/gccgo",
Packages: []*Package{
{
Kind: "gccgo",

View File

@ -841,22 +841,20 @@ func keyHandler(w http.ResponseWriter, r *http.Request) {
}
func init() {
for _, d := range dashboards {
// admin handlers
http.HandleFunc(d.RelPath+"init", initHandler)
http.HandleFunc(d.RelPath+"key", keyHandler)
// admin handlers
handleFunc("/init", initHandler)
handleFunc("/key", keyHandler)
// authenticated handlers
http.HandleFunc(d.RelPath+"commit", AuthHandler(commitHandler))
http.HandleFunc(d.RelPath+"packages", AuthHandler(packagesHandler))
http.HandleFunc(d.RelPath+"result", AuthHandler(resultHandler))
http.HandleFunc(d.RelPath+"perf-result", AuthHandler(perfResultHandler))
http.HandleFunc(d.RelPath+"tag", AuthHandler(tagHandler))
http.HandleFunc(d.RelPath+"todo", AuthHandler(todoHandler))
// authenticated handlers
handleFunc("/commit", AuthHandler(commitHandler))
handleFunc("/packages", AuthHandler(packagesHandler))
handleFunc("/result", AuthHandler(resultHandler))
handleFunc("/perf-result", AuthHandler(perfResultHandler))
handleFunc("/tag", AuthHandler(tagHandler))
handleFunc("/todo", AuthHandler(todoHandler))
// public handlers
http.HandleFunc(d.RelPath+"log/", logHandler)
}
// public handlers
handleFunc("/log/", logHandler)
}
func validHash(hash string) bool {

View File

@ -33,6 +33,7 @@ func initHandler(w http.ResponseWriter, r *http.Request) {
logErr(w, r, err)
return
}
p.NextNum = 1 // So we can add the first commit.
if _, err := datastore.Put(c, p.Key(c), p); err != nil {
logErr(w, r, err)
return

View File

@ -19,7 +19,7 @@ import (
)
func init() {
http.HandleFunc("/perf", perfChangesHandler)
handleFunc("/perf", perfChangesHandler)
}
// perfSummaryHandler draws the main benchmarking page.

View File

@ -8,9 +8,9 @@
<header id="topbar">
<h1>Go Dashboard</h1>
<nav>
<a href="{{$.Dashboard.RelPath}}">Test</a>
<a href="{{$.Dashboard.RelPath}}perf">Perf</a>
<a href="{{$.Dashboard.RelPath}}perfgraph">Graphs</a>
<a href="{{$.Dashboard.Prefix}}/">Test</a>
<a href="{{$.Dashboard.Prefix}}/perf">Perf</a>
<a href="{{$.Dashboard.Prefix}}/perfgraph">Graphs</a>
</nav>
<div class="clear"></div>
</header>

View File

@ -20,9 +20,7 @@ import (
)
func init() {
for _, d := range dashboards {
http.HandleFunc(d.RelPath+"perfdetail", perfDetailUIHandler)
}
handleFunc("/perfdetail", perfDetailUIHandler)
}
func perfDetailUIHandler(w http.ResponseWriter, r *http.Request) {

View File

@ -21,9 +21,9 @@
<header id="topbar">
<h1>Go Dashboard</h1>
<nav>
<a href="{{$.Dashboard.RelPath}}">Test</a>
<a href="{{$.Dashboard.RelPath}}perf">Perf</a>
<a href="{{$.Dashboard.RelPath}}perfgraph">Graphs</a>
<a href="{{$.Dashboard.Prefix}}/">Test</a>
<a href="{{$.Dashboard.Prefix}}/perf">Perf</a>
<a href="{{$.Dashboard.Prefix}}/perfgraph">Graphs</a>
</nav>
<div class="clear"></div>
</header>
@ -74,12 +74,12 @@
<tr>
<td class="metric">{{$m.Name}}</td>
{{if $m.Link0}}
<td><a href="{{$.Dashboard.RelPath}}{{$m.Link0}}">{{$m.Val0}}</td>
<td><a href="{{$.Dashboard.Prefix}}/{{$m.Link0}}">{{$m.Val0}}</td>
{{else}}
<td>{{$m.Val0}}</td>
{{end}}
{{if $m.Link1}}
<td><a href="{{$.Dashboard.RelPath}}{{$m.Link1}}">{{$m.Val1}}</td>
<td><a href="{{$.Dashboard.Prefix}}/{{$m.Link1}}">{{$m.Val1}}</td>
{{else}}
<td>{{$m.Val1}}</td>
{{end}}

View File

@ -18,9 +18,7 @@ import (
)
func init() {
for _, d := range dashboards {
http.HandleFunc(d.RelPath+"perfgraph", perfGraphHandler)
}
handleFunc("/perfgraph", perfGraphHandler)
}
func perfGraphHandler(w http.ResponseWriter, r *http.Request) {

View File

@ -53,9 +53,9 @@
<header id="topbar">
<h1>Go Dashboard</h1>
<nav>
<a href="{{$.Dashboard.RelPath}}">Test</a>
<a href="{{$.Dashboard.RelPath}}perf">Perf</a>
<a href="{{$.Dashboard.RelPath}}perfgraph">Graphs</a>
<a href="{{$.Dashboard.Prefix}}/">Test</a>
<a href="{{$.Dashboard.Prefix}}/perf">Perf</a>
<a href="{{$.Dashboard.Prefix}}/perfgraph">Graphs</a>
</nav>
<div class="clear"></div>
</header>

View File

@ -18,7 +18,7 @@ import (
)
func init() {
http.HandleFunc("/perflearn", perfLearnHandler)
handleFunc("/perflearn", perfLearnHandler)
}
const (

View File

@ -26,7 +26,7 @@ import (
)
func init() {
http.HandleFunc("/buildtest", testHandler)
handleFunc("/buildtest", testHandler)
}
var testEntityKinds = []string{

View File

@ -27,9 +27,7 @@ import (
)
func init() {
for _, d := range dashboards {
http.HandleFunc(d.RelPath, uiHandler)
}
handleFunc("/", uiHandler)
}
// uiHandler draws the build status page.
@ -437,7 +435,14 @@ func repoURL(dashboard, hash, packagePath string) (string, error) {
if dashboard == "Gccgo" {
return "https://code.google.com/p/gofrontend/source/detail?r=" + hash, nil
}
return "https://code.google.com/p/go/source/detail?r=" + hash, nil
if dashboard == "Git" {
return "https://go.googlesource.com/go/+/" + hash, nil
}
return "https://golang.org/change/" + hash, nil
}
if dashboard == "Git" {
repo := strings.TrimPrefix(packagePath, "golang.org/x/")
return "https://go.googlesource.com/" + repo + "/+/" + hash, nil
}
m := repoRe.FindStringSubmatch(packagePath)
if m == nil {

View File

@ -22,16 +22,16 @@
<header id="topbar">
<h1>Go Dashboard</h1>
<nav>
<a href="{{$.Dashboard.RelPath}}">Test</a>
<a href="{{$.Dashboard.RelPath}}perf">Perf</a>
<a href="{{$.Dashboard.RelPath}}perfgraph">Graphs</a>
<a href="{{$.Dashboard.Prefix}}/">Test</a>
<a href="{{$.Dashboard.Prefix}}/perf">Perf</a>
<a href="{{$.Dashboard.Prefix}}/perfgraph">Graphs</a>
</nav>
<div class="clear"></div>
</header>
<nav class="dashboards">
{{range buildDashboards}}
<a href="{{.RelPath}}">{{.Name}}</a>
<a href="{{.Prefix}}/">{{.Name}}</a>
{{end}}
<label>
<input type=checkbox id="showshort">
@ -99,7 +99,7 @@
{{if .OK}}
<span class="ok">ok</span>
{{else}}
<a href="{{$.Dashboard.RelPath}}log/{{.LogHash}}" class="fail">fail</a>
<a href="{{$.Dashboard.Prefix}}/log/{{.LogHash}}" class="fail">fail</a>
{{end}}
{{else}}
&nbsp;
@ -187,7 +187,7 @@
{{if .OK}}
<span class="ok">ok</span>
{{else}}
<a href="{{$.Dashboard.RelPath}}log/{{.LogHash}}" class="fail">fail</a>
<a href="{{$.Dashboard.Prefix}}/log/{{.LogHash}}" class="fail">fail</a>
{{end}}
{{else}}
&nbsp;

View File

@ -16,7 +16,7 @@ import (
)
func init() {
http.HandleFunc("/updatebenchmark", updateBenchmark)
handleFunc("/updatebenchmark", updateBenchmark)
}
func updateBenchmark(w http.ResponseWriter, r *http.Request) {