Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package swarming | 5 package swarming |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "net/http" | 8 "net/http" |
| 9 "os" | 9 "os" |
| 10 | 10 |
| 11 "github.com/julienschmidt/httprouter" | |
| 12 "golang.org/x/net/context" | 11 "golang.org/x/net/context" |
| 13 "google.golang.org/api/googleapi" | 12 "google.golang.org/api/googleapi" |
| 14 | 13 |
| 15 » "github.com/luci/luci-go/milo/appengine/settings" | 14 » "github.com/luci/luci-go/milo/appengine/common" |
| 16 "github.com/luci/luci-go/milo/common/miloerror" | 15 "github.com/luci/luci-go/milo/common/miloerror" |
| 16 "github.com/luci/luci-go/server/router" | |
| 17 "github.com/luci/luci-go/server/templates" | 17 "github.com/luci/luci-go/server/templates" |
| 18 ) | 18 ) |
| 19 | 19 |
| 20 const ( | 20 const ( |
| 21 defaultSwarmingServer = "chromium-swarm.appspot.com" | 21 defaultSwarmingServer = "chromium-swarm.appspot.com" |
| 22 defaultSwarmingDevServer = "chromium-swarm-dev.appspot.com" | 22 defaultSwarmingDevServer = "chromium-swarm-dev.appspot.com" |
| 23 ) | 23 ) |
| 24 | 24 |
| 25 func getSwarmingHost(r *http.Request) string { | 25 func getSwarmingHost(r *http.Request) string { |
| 26 server := r.FormValue("server") | 26 server := r.FormValue("server") |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 43 return newProdService(c, host) | 43 return newProdService(c, host) |
| 44 | 44 |
| 45 default: | 45 default: |
| 46 return nil, &miloerror.Error{ | 46 return nil, &miloerror.Error{ |
| 47 Message: "unregistered Swarming host", | 47 Message: "unregistered Swarming host", |
| 48 Code: http.StatusNotFound, | 48 Code: http.StatusNotFound, |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 // Log is for fetching logs from swarming. | |
| 54 type Log struct{} | |
| 55 | |
| 56 // Build is for deciphering recipe builds from swarming based off of logs. | 53 // Build is for deciphering recipe builds from swarming based off of logs. |
| 57 type Build struct { | 54 type Build struct { |
|
nodir
2017/03/17 20:47:58
why do we need this type?
hinoka
2017/03/17 22:04:55
It's used as a delivery mechanism to pass the buil
| |
| 58 // bl is the buildLoader to use. A zero value is suitable for production , but | 55 // bl is the buildLoader to use. A zero value is suitable for production , but |
| 59 // this can be overridden for testing. | 56 // this can be overridden for testing. |
| 60 bl buildLoader | 57 bl buildLoader |
| 61 } | 58 } |
| 62 | 59 |
| 63 // GetTemplateName for Log returns the template name for log pages. | 60 // LogHandler writes the build log to the given response writer. |
| 64 func (l Log) GetTemplateName(t settings.Theme) string { | 61 func LogHandler(c *router.Context) { |
| 65 » return "log.html" | 62 » id := c.Params.ByName("id") |
| 63 » if id == "" { | |
| 64 » » common.ErrorPage(c, http.StatusBadRequest, "No id") | |
| 65 » » return | |
| 66 » } | |
| 67 » logname := c.Params.ByName("logname") | |
| 68 » if logname == "" { | |
| 69 » » common.ErrorPage(c, http.StatusBadRequest, "No log name") | |
| 70 » } | |
| 71 | |
| 72 » sf, err := getSwarmingService(c.Context, getSwarmingHost(c.Request)) | |
| 73 » if err != nil { | |
| 74 » » common.ErrorPage(c, errCode(err), "No log name") | |
| 75 » » return | |
| 76 » } | |
| 77 | |
| 78 » log, closed, err := swarmingBuildLogImpl(c.Context, sf, id, logname) | |
| 79 » if err != nil { | |
| 80 » » common.ErrorPage(c, errCode(err), err.Error()) | |
| 81 » » return | |
| 82 » } | |
| 83 | |
| 84 » templates.MustRender(c.Context, c.Writer, "pages/log.html", templates.Ar gs{ | |
| 85 » » "Log": log, | |
| 86 » » "Closed": closed, | |
| 87 » }) | |
| 66 } | 88 } |
| 67 | 89 |
| 68 // Render writes the build log to the given response writer. | 90 func BuildHandler(c *router.Context) { |
| 69 func (l Log) Render(c context.Context, r *http.Request, p httprouter.Params) (*t emplates.Args, error) { | 91 » (Build{}).handler(c) |
| 70 » id := p.ByName("id") | |
| 71 » if id == "" { | |
| 72 » » return nil, &miloerror.Error{ | |
| 73 » » » Message: "No id", | |
| 74 » » » Code: http.StatusBadRequest, | |
| 75 » » } | |
| 76 » } | |
| 77 » logname := p.ByName("logname") | |
| 78 » if logname == "" { | |
| 79 » » return nil, &miloerror.Error{ | |
| 80 » » » Message: "No log name", | |
| 81 » » » Code: http.StatusBadRequest, | |
| 82 » » } | |
| 83 » } | |
| 84 | |
| 85 » sf, err := getSwarmingService(c, getSwarmingHost(r)) | |
| 86 » if err != nil { | |
| 87 » » return nil, convertErr(err) | |
| 88 » } | |
| 89 | |
| 90 » log, closed, err := swarmingBuildLogImpl(c, sf, id, logname) | |
| 91 » if err != nil { | |
| 92 » » return nil, convertErr(err) | |
| 93 » } | |
| 94 | |
| 95 » args := &templates.Args{ | |
| 96 » » "Log": log, | |
| 97 » » "Closed": closed, | |
| 98 » } | |
| 99 » return args, nil | |
| 100 } | |
| 101 | |
| 102 // GetTemplateName for Build returns the template name for build pages. | |
| 103 func (b Build) GetTemplateName(t settings.Theme) string { | |
| 104 » return "build.html" | |
| 105 } | 92 } |
| 106 | 93 |
| 107 // Render renders both the build page and the log. | 94 // Render renders both the build page and the log. |
|
nodir
2017/03/17 20:47:58
s/Render/handler
or rename func to Render
hinoka
2017/03/17 22:04:55
Done.
| |
| 108 func (b Build) Render(c context.Context, r *http.Request, p httprouter.Params) ( *templates.Args, error) { | 95 func (b Build) handler(c *router.Context) { |
| 109 // Get the swarming ID | 96 // Get the swarming ID |
| 110 » id := p.ByName("id") | 97 » id := c.Params.ByName("id") |
| 111 if id == "" { | 98 if id == "" { |
| 112 » » return nil, &miloerror.Error{ | 99 » » common.ErrorPage(c, http.StatusBadRequest, "No id") |
| 113 » » » Message: "No id", | 100 » » return |
| 114 » » » Code: http.StatusBadRequest, | |
| 115 » » } | |
| 116 } | 101 } |
| 117 | 102 |
| 118 » sf, err := getSwarmingService(c, getSwarmingHost(r)) | 103 » sf, err := getSwarmingService(c.Context, getSwarmingHost(c.Request)) |
| 119 if err != nil { | 104 if err != nil { |
| 120 » » return nil, convertErr(err) | 105 » » common.ErrorPage(c, errCode(err), err.Error()) |
| 106 » » return | |
| 121 } | 107 } |
| 122 | 108 |
| 123 » result, err := b.bl.swarmingBuildImpl(c, sf, r.URL.String(), id) | 109 » result, err := b.bl.swarmingBuildImpl(c.Context, sf, c.Request.URL.Strin g(), id) |
| 124 if err != nil { | 110 if err != nil { |
| 125 » » return nil, convertErr(err) | 111 » » common.ErrorPage(c, errCode(err), err.Error()) |
| 112 » » return | |
| 126 } | 113 } |
| 127 | 114 |
| 128 » // Render into the template | 115 » templates.MustRender(c.Context, c.Writer, "pages/build.html", templates. Args{ |
| 129 » args := &templates.Args{ | |
| 130 "Build": result, | 116 "Build": result, |
| 131 » } | 117 » }) |
| 132 » return args, nil | |
| 133 } | 118 } |
| 134 | 119 |
| 135 func convertErr(err error) error { | 120 func errCode(err error) int { |
| 136 if isAPINotFound(err) || os.IsNotExist(err) { | 121 if isAPINotFound(err) || os.IsNotExist(err) { |
| 137 » » return &miloerror.Error{ | 122 » » return http.StatusNotFound |
| 138 » » » Message: err.Error(), | |
| 139 » » » Code: http.StatusNotFound, | |
| 140 » » } | |
| 141 } | 123 } |
| 142 » return err | 124 » return http.StatusInternalServerError |
| 143 } | 125 } |
| 144 | 126 |
| 145 // isAPINotFound returns true if err is a HTTP 404 API response. | 127 // isAPINotFound returns true if err is a HTTP 404 API response. |
| 146 func isAPINotFound(err error) bool { | 128 func isAPINotFound(err error) bool { |
| 147 if apiErr, ok := err.(*googleapi.Error); ok && apiErr.Code == http.Statu sNotFound { | 129 if apiErr, ok := err.(*googleapi.Error); ok && apiErr.Code == http.Statu sNotFound { |
| 148 return true | 130 return true |
| 149 } | 131 } |
| 150 | |
| 151 return false | 132 return false |
| 152 } | 133 } |
| OLD | NEW |