Esempio n. 1
0
// GetBuildPage accepts a request to retrieve the build
// output page for the package version, channel and SDK
// from the datastore in JSON format.
//
// If the SDK is not provided, the system will lookup
// the latest SDK version for this package.
//
//     GET /:name/:number/:channel/:sdk
//
func GetBuildPage(c web.C, w http.ResponseWriter, r *http.Request) {
	ctx := context.FromC(c)
	name := c.URLParams["name"]
	number := c.URLParams["number"]
	channel := c.URLParams["channel"]
	sdk := c.URLParams["sdk"]

	// If no SDK is provided we should use the most recent
	// SDK number associated with the Package version.
	var build *resource.Build
	var err error
	if len(sdk) == 0 {
		build, err = datastore.GetBuildLatest(ctx, name, number, channel)
	} else {
		build, err = datastore.GetBuild(ctx, name, number, channel, sdk)
	}

	// If the error is not nil then we can
	// display some sort of NotFound page.
	if err != nil {
		http.Error(w, "Not Found", http.StatusNotFound)
		return
	}

	BuildTempl.Execute(w, struct {
		Build *resource.Build
		Error error
	}{build, err})
}
Esempio n. 2
0
// GetBuild accepts a request to retrieve the build
// details for the package version, channel and SDK
// from the datastore in JSON format.
//
//     GET /api/packages/:name/:number/channel/:channel/sdk/:sdk
//
func GetBuild(c web.C, w http.ResponseWriter, r *http.Request) {
	ctx := context.FromC(c)
	name := c.URLParams["name"]
	number := c.URLParams["number"]
	channel := c.URLParams["channel"]
	sdk := c.URLParams["sdk"]

	build, err := datastore.GetBuild(ctx, name, number, channel, sdk)
	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		return
	}
	json.NewEncoder(w).Encode(build)
}
Esempio n. 3
0
// PostBuild accepts a request to execute a build
// for the named package, version, channel and SDK.
//
//    POST /sudo/api/build
//
func PostBuild(c web.C, w http.ResponseWriter, r *http.Request) {
	ctx := context.FromC(c)
	name := r.FormValue("package")
	number := r.FormValue("version")
	channel := r.FormValue("channel")
	rev := r.FormValue("revision")
	sdk := r.FormValue("sdk")
	force := r.FormValue("force")

	// parse the revision number from string to int64
	// format so that we can run version comparisons.
	revision, err := strconv.ParseInt(rev, 10, 64)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	// get the build from the datastore. If it does not
	// yet exist, populate fields required upon creation.
	build, err := datastore.GetBuild(ctx, name, number, channel, sdk)
	if err == nil && len(force) == 0 {
		w.WriteHeader(http.StatusConflict)
		return
	} else if err != nil {
		build.Name = name
		build.Version = number
		build.Channel = channel
		build.SDK = sdk
		build.Created = time.Now().UTC().Unix()
	}
	build.Revision = revision
	build.Status = resource.StatusPending
	build.Updated = time.Now().UTC().Unix()
	if err := datastore.PutBuild(ctx, build); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	work := worker.Work{build}
	go worker.Do(ctx, &work)

	w.WriteHeader(http.StatusNoContent)
}
Esempio n. 4
0
// GetBadge accepts a request to retrieve the named
// package and version build details from the datastore
// and return an SVG badges representing the build results.
//
//     GET /api/badges/:name/:number/channel/:channel/status.svg
//     GET /api/badges/:name/:number/channel/:channel/sdk/:sdk/status.svg
//
func GetBadge(c web.C, w http.ResponseWriter, r *http.Request) {
	ctx := context.FromC(c)
	name := c.URLParams["name"]
	number := c.URLParams["number"]
	channel := c.URLParams["channel"]
	sdk := c.URLParams["sdk"]

	// Ensure we set the correct content-type
	// for the badge to ensure it displays
	// correctly on GitHub.
	w.Header().Set("Content-Type", "image/svg+xml")

	// If no SDK is provided we should use the most recent
	// SDK number associated with the Package version.
	var build *resource.Build
	var err error
	if len(sdk) == 0 {
		build, err = datastore.GetBuildLatest(ctx, name, number, channel)
	} else {
		build, err = datastore.GetBuild(ctx, name, number, channel, sdk)
	}

	// If there was an error default to a build status None
	if err != nil {
		build.Status = resource.StatusNone
	}

	var badgeStr string
	var badgeMsg string = build.SDK

	switch build.Status {
	case resource.StatusSuccess:
		badgeStr = badgeSuccess
	case resource.StatusFailure:
		badgeStr = badgeFailure
	case resource.StatusWarning:
		badgeStr = badgeWarning
	case resource.StatusStarted, resource.StatusPending:
		badgeStr = badgeStarted
	case resource.StatusKilled, resource.StatusError:
		badgeStr = badgeError
	default:
		badgeStr = badgeNone
		badgeMsg = channel
	}

	// replace any - with -- for compatibility with
	// the shields.io service.
	badgeMsg = strings.Replace(badgeMsg, "-", "--", -1)

	// generate the badge url and check to see if the
	// badge already exists in the cache
	var badgeUrl = fmt.Sprintf(badgeStr, badgeMsg)
	if badgeRaw, ok := badgeCache.Get(badgeUrl); ok {
		w.Write(badgeRaw.([]byte))
		return
	}

	// retrieve the badge from shields.io
	res, err := http.Get(badgeUrl)
	if err != nil {
		http.Error(w, err.Error(), res.StatusCode)
		return
	}
	defer res.Body.Close()

	// read the svg data from the request body,
	// write to the response + the local lru cache.
	badgeRaw, err := ioutil.ReadAll(res.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	badgeCache.Add(badgeUrl, badgeRaw)
	w.Write(badgeRaw)
}