summaryrefslogtreecommitdiff
path: root/misc/dashboard/builder/http.go
diff options
context:
space:
mode:
Diffstat (limited to 'misc/dashboard/builder/http.go')
-rw-r--r--misc/dashboard/builder/http.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/misc/dashboard/builder/http.go b/misc/dashboard/builder/http.go
new file mode 100644
index 000000000..abef8faa4
--- /dev/null
+++ b/misc/dashboard/builder/http.go
@@ -0,0 +1,148 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "http"
+ "json"
+ "log"
+ "os"
+ "strconv"
+ "url"
+)
+
+type param map[string]string
+
+// dash runs the given method and command on the dashboard.
+// If args is not nil, it is the query or post parameters.
+// If resp is not nil, dash unmarshals the body as JSON into resp.
+func dash(meth, cmd string, resp interface{}, args param) os.Error {
+ var r *http.Response
+ var err os.Error
+ if *verbose {
+ log.Println("dash", cmd, args)
+ }
+ cmd = "http://" + *dashboard + "/" + cmd
+ vals := make(url.Values)
+ for k, v := range args {
+ vals.Add(k, v)
+ }
+ switch meth {
+ case "GET":
+ if q := vals.Encode(); q != "" {
+ cmd += "?" + q
+ }
+ r, err = http.Get(cmd)
+ case "POST":
+ r, err = http.PostForm(cmd, vals)
+ default:
+ return fmt.Errorf("unknown method %q", meth)
+ }
+ if err != nil {
+ return err
+ }
+ defer r.Body.Close()
+ var buf bytes.Buffer
+ buf.ReadFrom(r.Body)
+ if resp != nil {
+ if err = json.Unmarshal(buf.Bytes(), resp); err != nil {
+ log.Printf("json unmarshal %#q: %s\n", buf.Bytes(), err)
+ return err
+ }
+ }
+ return nil
+}
+
+func dashStatus(meth, cmd string, args param) os.Error {
+ var resp struct {
+ Status string
+ Error string
+ }
+ err := dash(meth, cmd, &resp, args)
+ if err != nil {
+ return err
+ }
+ if resp.Status != "OK" {
+ return os.NewError("/build: " + resp.Error)
+ }
+ return nil
+}
+
+// todo returns the next hash to build.
+func (b *Builder) todo() (rev string, err os.Error) {
+ var resp []struct {
+ Hash string
+ }
+ if err = dash("GET", "todo", &resp, param{"builder": b.name}); err != nil {
+ return
+ }
+ if len(resp) > 0 {
+ rev = resp[0].Hash
+ }
+ return
+}
+
+// recordResult sends build results to the dashboard
+func (b *Builder) recordResult(buildLog string, hash string) os.Error {
+ return dash("POST", "build", nil, param{
+ "builder": b.name,
+ "key": b.key,
+ "node": hash,
+ "log": buildLog,
+ })
+}
+
+// packages fetches a list of package paths from the dashboard
+func packages() (pkgs []string, err os.Error) {
+ var resp struct {
+ Packages []struct {
+ Path string
+ }
+ }
+ err = dash("GET", "package", &resp, param{"fmt": "json"})
+ if err != nil {
+ return
+ }
+ for _, p := range resp.Packages {
+ pkgs = append(pkgs, p.Path)
+ }
+ return
+}
+
+// updatePackage sends package build results and info dashboard
+func (b *Builder) updatePackage(pkg string, ok bool, buildLog, info string) os.Error {
+ return dash("POST", "package", nil, param{
+ "builder": b.name,
+ "key": b.key,
+ "path": pkg,
+ "ok": strconv.Btoa(ok),
+ "log": buildLog,
+ "info": info,
+ })
+}
+
+// postCommit informs the dashboard of a new commit
+func postCommit(key string, l *HgLog) os.Error {
+ return dashStatus("POST", "commit", param{
+ "key": key,
+ "node": l.Hash,
+ "date": l.Date,
+ "user": l.Author,
+ "parent": l.Parent,
+ "desc": l.Desc,
+ })
+}
+
+// dashboardCommit returns true if the dashboard knows about hash.
+func dashboardCommit(hash string) bool {
+ err := dashStatus("GET", "commit", param{"node": hash})
+ if err != nil {
+ log.Printf("check %s: %s", hash, err)
+ return false
+ }
+ return true
+}