// todoHandler returns the next action to be performed by a builder. // It expects "builder" and "kind" query parameters and returns a *Todo value. // Multiple "kind" parameters may be specified. func todoHandler(r *http.Request) (interface{}, error) { c := appengine.NewContext(r) now := cache.Now(c) key := "build-todo-" + r.Form.Encode() var todo *Todo if cache.Get(r, now, key, &todo) { return todo, nil } var err error builder := r.FormValue("builder") for _, kind := range r.Form["kind"] { var data interface{} switch kind { case "build-go-commit": data, err = buildTodo(c, builder, "", "") case "build-package": packagePath := r.FormValue("packagePath") goHash := r.FormValue("goHash") data, err = buildTodo(c, builder, packagePath, goHash) } if data != nil || err != nil { todo = &Todo{Kind: kind, Data: data} break } } if err == nil { cache.Set(r, now, key, todo) } return todo, err }
// todoHandler returns the next action to be performed by a builder. // It expects "builder" and "kind" query parameters and returns a *Todo value. // Multiple "kind" parameters may be specified. func todoHandler(r *http.Request) (interface{}, error) { c := contextForRequest(r) now := cache.Now(c) key := "build-todo-" + r.Form.Encode() var todo *Todo if cache.Get(r, now, key, &todo) { return todo, nil } var err error builder := r.FormValue("builder") for _, kind := range r.Form["kind"] { var com *Commit switch kind { case "build-go-commit": com, err = buildTodo(c, builder, "", "") case "build-package": packagePath := r.FormValue("packagePath") goHash := r.FormValue("goHash") com, err = buildTodo(c, builder, packagePath, goHash) } if com != nil || err != nil { if com != nil { // ResultData can be large and not needed on builder. com.ResultData = []string{} } todo = &Todo{Kind: kind, Data: com} break } } if err == nil { cache.Set(r, now, key, todo) } return todo, err }
// uiHandler draws the build status page. func uiHandler(w http.ResponseWriter, r *http.Request) { d := dashboardForRequest(r) c := d.Context(appengine.NewContext(r)) now := cache.Now(c) const key = "build-ui" page, _ := strconv.Atoi(r.FormValue("page")) if page < 0 { page = 0 } // Used cached version of front page, if available. if page == 0 { var b []byte if cache.Get(r, now, key, &b) { w.Write(b) return } } commits, err := dashCommits(c, page) if err != nil { logErr(w, r, err) return } builders := commitBuilders(commits, "") var tipState *TagState if page == 0 { // only show sub-repo state on first page tipState, err = TagStateByName(c, "tip") if err != nil { logErr(w, r, err) return } } p := &Pagination{} if len(commits) == commitsPerPage { p.Next = page + 1 } if page > 0 { p.Prev = page - 1 p.HasPrev = true } data := &uiTemplateData{d, commits, builders, tipState, p} var buf bytes.Buffer if err := uiTemplate.Execute(&buf, data); err != nil { logErr(w, r, err) return } // Cache the front page. if page == 0 { cache.Set(r, now, key, buf.Bytes()) } buf.WriteTo(w) }
// todoHandler returns the next action to be performed by a builder. // It expects "builder" and "kind" query parameters and returns a *Todo value. // Multiple "kind" parameters may be specified. func todoHandler(r *http.Request) (interface{}, error) { c := contextForRequest(r) now := cache.Now(c) key := "build-todo-" + r.Form.Encode() var todo *Todo if cache.Get(c, r, now, key, &todo) { // Hack to avoid storing nil in memcache. if todo.Kind == "none" { return nil, nil } return todo, nil } var err error builder := r.FormValue("builder") if builderKeyRevoked(builder) { return nil, fmt.Errorf("builder key revoked; no work given") } for _, kind := range r.Form["kind"] { var com *Commit switch kind { case "build-go-commit": com, err = buildTodo(c, builder, "", "") if com != nil { com.PerfResults = []string{} } case "build-package": packagePath := r.FormValue("packagePath") goHash := r.FormValue("goHash") com, err = buildTodo(c, builder, packagePath, goHash) if com != nil { com.PerfResults = []string{} } case "benchmark-go-commit": com, err = perfTodo(c, builder) } if com != nil || err != nil { if com != nil { // ResultData can be large and not needed on builder. com.ResultData = []string{} } todo = &Todo{Kind: kind, Data: com} break } } if err == nil { // Hack to avoid storing nil in memcache. if todo == nil { todo = &Todo{Kind: "none"} } cache.Set(c, r, now, key, todo) } // Hack to avoid storing nil in memcache. if todo.Kind == "none" { return nil, nil } return todo, err }
func GetPerfConfig(c appengine.Context, r *http.Request) (*PerfConfig, error) { pc := new(PerfConfig) now := cache.Now(c) if cache.Get(r, now, perfConfigCacheKey, pc) { return pc, nil } err := datastore.Get(c, PerfConfigKey(c), pc) if err != nil && err != datastore.ErrNoSuchEntity { return nil, fmt.Errorf("GetPerfConfig: %v", err) } cache.Set(r, now, perfConfigCacheKey, pc) return pc, nil }
// packagesHandler returns a list of the non-Go Packages monitored // by the dashboard. func packagesHandler(r *http.Request) (interface{}, error) { kind := r.FormValue("kind") c := contextForRequest(r) now := cache.Now(c) key := "build-packages-" + kind var p []*Package if cache.Get(r, now, key, &p) { return p, nil } p, err := Packages(c, kind) if err != nil { return nil, err } cache.Set(r, now, key, p) return p, nil }
// uiHandler draws the build status page. func uiHandler(w http.ResponseWriter, r *http.Request) { d := dashboardForRequest(r) c := d.Context(appengine.NewContext(r)) now := cache.Now(c) const key = "build-ui" page, _ := strconv.Atoi(r.FormValue("page")) if page < 0 { page = 0 } repo := r.FormValue("repo") useCache := page == 0 && repo == "" // Used cached version of front page, if available. if useCache { var b []byte if cache.Get(r, now, key, &b) { w.Write(b) return } } pkg := &Package{} // empty package is the main repository if repo != "" { var err error pkg, err = GetPackage(c, repo) if err != nil { logErr(w, r, err) return } } commits, err := dashCommits(c, pkg, page) if err != nil { logErr(w, r, err) return } builders := commitBuilders(commits) var tipState *TagState if pkg.Kind == "" && page == 0 && commits != nil { // only show sub-repo state on first page of normal repo view tipState, err = TagStateByName(c, "tip") if err != nil { logErr(w, r, err) return } } p := &Pagination{} if len(commits) == commitsPerPage { p.Next = page + 1 } if page > 0 { p.Prev = page - 1 p.HasPrev = true } data := &uiTemplateData{d, pkg, commits, builders, tipState, p} var buf bytes.Buffer if err := uiTemplate.Execute(&buf, data); err != nil { logErr(w, r, err) return } // Cache the front page. if useCache { cache.Set(r, now, key, buf.Bytes()) } buf.WriteTo(w) }
// uiHandler draws the build status page. func uiHandler(w http.ResponseWriter, r *http.Request) { d := dashboardForRequest(r) c := d.Context(appengine.NewContext(r)) now := cache.Now(c) key := "build-ui" mode := r.FormValue("mode") page, _ := strconv.Atoi(r.FormValue("page")) if page < 0 { page = 0 } key += fmt.Sprintf("-page%v", page) repo := r.FormValue("repo") if repo != "" { key += "-repo-" + repo } branch := r.FormValue("branch") switch branch { case "all": branch = "" case "": branch = "master" } if repo != "" || mode == "json" { // Don't filter on branches in sub-repos. // TODO(adg): figure out how to make this work sensibly. // Don't filter on branches in json mode. branch = "" } if branch != "" { key += "-branch-" + branch } var data uiTemplateData if !cache.Get(c, r, now, key, &data) { pkg := &Package{} // empty package is the main repository if repo != "" { var err error pkg, err = GetPackage(c, repo) if err != nil { logErr(w, r, err) return } } commits, err := dashCommits(c, pkg, page, branch) if err != nil { logErr(w, r, err) return } builders := commitBuilders(commits) branches := listBranches(c) var tagState []*TagState // Only show sub-repo state on first page of normal repo view. if pkg.Kind == "" && page == 0 && (branch == "" || branch == "master") { s, err := GetTagState(c, "tip", "") if err != nil { if err == datastore.ErrNoSuchEntity { err = fmt.Errorf("tip tag not found") } logErr(w, r, err) return } tagState = []*TagState{s} for _, b := range branches { if !strings.HasPrefix(b, "release-branch.") { continue } s, err := GetTagState(c, "release", b) if err == datastore.ErrNoSuchEntity { continue } if err != nil { logErr(w, r, err) return } tagState = append(tagState, s) } } p := &Pagination{} if len(commits) == commitsPerPage { p.Next = page + 1 } if page > 0 { p.Prev = page - 1 p.HasPrev = true } data = uiTemplateData{ Package: pkg, Commits: commits, Builders: builders, TagState: tagState, Pagination: p, Branches: branches, Branch: branch, } cache.Set(c, r, now, key, &data) } data.Dashboard = d switch mode { case "failures": failuresHandler(w, r, &data) return case "json": jsonHandler(w, r, &data) return } // Populate building URLs for the HTML UI only. data.populateBuildingURLs(c) var buf bytes.Buffer if err := uiTemplate.Execute(&buf, &data); err != nil { logErr(w, r, err) return } buf.WriteTo(w) }
// uiHandler draws the build status page. func uiHandler(w http.ResponseWriter, r *http.Request) { d := dashboardForRequest(r) c := d.Context(appengine.NewContext(r)) now := cache.Now(c) key := "build-ui" page, _ := strconv.Atoi(r.FormValue("page")) if page < 0 { page = 0 } key += fmt.Sprintf("-page%v", page) branch := r.FormValue("branch") if branch != "" { key += "-branch-" + branch } repo := r.FormValue("repo") if repo != "" { key += "-repo-" + repo } var b []byte if cache.Get(r, now, key, &b) { w.Write(b) return } pkg := &Package{} // empty package is the main repository if repo != "" { var err error pkg, err = GetPackage(c, repo) if err != nil { logErr(w, r, err) return } } commits, err := dashCommits(c, pkg, page, branch) if err != nil { logErr(w, r, err) return } builders := commitBuilders(commits) var tipState *TagState if pkg.Kind == "" && page == 0 && (branch == "" || branch == "default") { // only show sub-repo state on first page of normal repo view tipState, err = TagStateByName(c, "tip") if err != nil { logErr(w, r, err) return } } p := &Pagination{} if len(commits) == commitsPerPage { p.Next = page + 1 } if page > 0 { p.Prev = page - 1 p.HasPrev = true } data := &uiTemplateData{d, pkg, commits, builders, tipState, p, branch} var buf bytes.Buffer if err := uiTemplate.Execute(&buf, data); err != nil { logErr(w, r, err) return } cache.Set(r, now, key, buf.Bytes()) buf.WriteTo(w) }
func Blacklist(thing string) { cache.Set(hashie.Sha1([]byte(thing)), "blacklisted", TTL) }
func Notify(key string, message string) { cache.Set(key, message, TTL) }