2011-03-02 20:41:09 -07:00
|
|
|
// 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.
|
|
|
|
|
2010-09-12 18:46:17 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"http"
|
2011-03-02 20:41:09 -07:00
|
|
|
"json"
|
|
|
|
"log"
|
2010-09-12 18:46:17 -06:00
|
|
|
"os"
|
2011-03-02 20:41:09 -07:00
|
|
|
"strconv"
|
2010-09-12 18:46:17 -06:00
|
|
|
)
|
|
|
|
|
2011-05-12 09:21:34 -06:00
|
|
|
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
|
2011-06-08 14:38:20 -06:00
|
|
|
vals := make(http.Values)
|
|
|
|
for k, v := range args {
|
|
|
|
vals.Add(k, v)
|
|
|
|
}
|
2011-05-12 09:21:34 -06:00
|
|
|
switch meth {
|
|
|
|
case "GET":
|
2011-06-08 14:38:20 -06:00
|
|
|
if q := vals.Encode(); q != "" {
|
|
|
|
cmd += "?" + q
|
2011-05-12 09:21:34 -06:00
|
|
|
}
|
2011-05-13 08:31:24 -06:00
|
|
|
r, err = http.Get(cmd)
|
2011-05-12 09:21:34 -06:00
|
|
|
case "POST":
|
2011-06-08 14:38:20 -06:00
|
|
|
r, err = http.PostForm(cmd, vals)
|
2011-05-12 09:21:34 -06:00
|
|
|
default:
|
|
|
|
return fmt.Errorf("unknown method %q", meth)
|
|
|
|
}
|
2010-09-12 18:46:17 -06:00
|
|
|
if err != nil {
|
2011-05-12 09:21:34 -06:00
|
|
|
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
|
|
|
|
}
|
2010-09-12 18:46:17 -06:00
|
|
|
}
|
2011-05-12 09:21:34 -06:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func dashStatus(meth, cmd string, args param) os.Error {
|
|
|
|
var resp struct {
|
|
|
|
Status string
|
2011-05-19 18:05:35 -06:00
|
|
|
Error string
|
2011-05-12 09:21:34 -06:00
|
|
|
}
|
|
|
|
err := dash(meth, cmd, &resp, args)
|
2010-09-12 18:46:17 -06:00
|
|
|
if err != nil {
|
2011-05-12 09:21:34 -06:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
if resp.Status != "OK" {
|
|
|
|
return os.NewError("/build: " + resp.Error)
|
|
|
|
}
|
2011-05-19 18:05:35 -06:00
|
|
|
return nil
|
2011-05-12 09:21:34 -06:00
|
|
|
}
|
2011-05-19 18:05:35 -06:00
|
|
|
|
2011-05-12 09:21:34 -06:00
|
|
|
// todo returns the next hash to build.
|
|
|
|
func (b *Builder) todo() (rev string, err os.Error) {
|
2011-05-19 18:05:35 -06:00
|
|
|
var resp []struct {
|
2011-05-12 09:21:34 -06:00
|
|
|
Hash string
|
|
|
|
}
|
|
|
|
if err = dash("GET", "todo", &resp, param{"builder": b.name}); err != nil {
|
2010-09-12 18:46:17 -06:00
|
|
|
return
|
|
|
|
}
|
2011-05-12 09:21:34 -06:00
|
|
|
if len(resp) > 0 {
|
|
|
|
rev = resp[0].Hash
|
|
|
|
}
|
|
|
|
return
|
2010-09-12 18:46:17 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// recordResult sends build results to the dashboard
|
2011-05-12 09:21:34 -06:00
|
|
|
func (b *Builder) recordResult(buildLog string, hash string) os.Error {
|
|
|
|
return dash("POST", "build", nil, param{
|
2010-09-12 18:46:17 -06:00
|
|
|
"builder": b.name,
|
|
|
|
"key": b.key,
|
2011-05-12 09:21:34 -06:00
|
|
|
"node": hash,
|
2010-09-12 18:46:17 -06:00
|
|
|
"log": buildLog,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2011-05-12 09:21:34 -06:00
|
|
|
// packages fetches a list of package paths from the dashboard
|
|
|
|
func packages() (pkgs []string, err os.Error) {
|
2011-03-02 20:41:09 -07:00
|
|
|
var resp struct {
|
|
|
|
Packages []struct {
|
|
|
|
Path string
|
|
|
|
}
|
|
|
|
}
|
2011-05-12 09:21:34 -06:00
|
|
|
err = dash("GET", "package", &resp, param{"fmt": "json"})
|
|
|
|
if err != nil {
|
2011-03-02 20:41:09 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
for _, p := range resp.Packages {
|
|
|
|
pkgs = append(pkgs, p.Path)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2011-07-01 22:02:42 -06:00
|
|
|
// updatePackage sends package build results and info dashboard
|
|
|
|
func (b *Builder) updatePackage(pkg string, ok bool, buildLog, info string) os.Error {
|
2011-05-12 09:21:34 -06:00
|
|
|
return dash("POST", "package", nil, param{
|
2011-03-02 20:41:09 -07:00
|
|
|
"builder": b.name,
|
|
|
|
"key": b.key,
|
|
|
|
"path": pkg,
|
2011-07-01 22:02:42 -06:00
|
|
|
"ok": strconv.Btoa(ok),
|
2011-03-02 20:41:09 -07:00
|
|
|
"log": buildLog,
|
|
|
|
"info": info,
|
2011-05-12 09:21:34 -06:00
|
|
|
})
|
2011-03-02 20:41:09 -07:00
|
|
|
}
|
|
|
|
|
2011-05-12 09:21:34 -06:00
|
|
|
// postCommit informs the dashboard of a new commit
|
|
|
|
func postCommit(key string, l *HgLog) os.Error {
|
|
|
|
return dashStatus("POST", "commit", param{
|
2011-05-19 18:05:35 -06:00
|
|
|
"key": key,
|
|
|
|
"node": l.Hash,
|
|
|
|
"date": l.Date,
|
|
|
|
"user": l.Author,
|
2011-05-12 09:21:34 -06:00
|
|
|
"parent": l.Parent,
|
2011-05-19 18:05:35 -06:00
|
|
|
"desc": l.Desc,
|
2011-05-12 09:21:34 -06:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2011-03-02 20:41:09 -07:00
|
|
|
}
|
2011-05-12 09:21:34 -06:00
|
|
|
return true
|
2010-09-12 18:46:17 -06:00
|
|
|
}
|