Пример #1
0
// 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
}
Пример #2
0
// 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
}
Пример #3
0
// 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)
}
Пример #4
0
// 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
}
Пример #5
0
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
}
Пример #6
0
// 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
}
Пример #7
0
// 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)
}
Пример #8
0
// 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)
}
Пример #9
0
// 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)
}
Пример #10
0
func Blacklist(thing string) {
	cache.Set(hashie.Sha1([]byte(thing)), "blacklisted", TTL)
}
Пример #11
0
func Notify(key string, message string) {
	cache.Set(key, message, TTL)
}