diff options
| author | Russ Cox <rsc@golang.org> | 2023-07-28 13:53:30 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2023-08-03 02:08:39 +0000 |
| commit | 1e75b26cba0e55a9f61c79dbb46459a4e6ddbd65 (patch) | |
| tree | 926db32bbabc6420067cf58e7bb9e254b2586bfd /cmd | |
| parent | c999d513375b4ada88a6da915515cd15868bb20d (diff) | |
| download | go-x-website-1e75b26cba0e55a9f61c79dbb46459a4e6ddbd65.tar.xz | |
_content: add rebuild page with reproducible build information
We now have a command to reproduce Go builds posted on go.dev/dl.
Add a dashboard that people can check to see its results.
We should be able to link to this page from https://reproducible-builds.org/citests/.
For golang/go#57120.
For golang/go#58884.
Change-Id: I0bd1f9c26a9a003aa1f301125083195fdeb048b4
Reviewed-on: https://go-review.googlesource.com/c/website/+/513700
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/golangorg/server.go | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/cmd/golangorg/server.go b/cmd/golangorg/server.go index 1fb1a7c8..2a7f66b0 100644 --- a/cmd/golangorg/server.go +++ b/cmd/golangorg/server.go @@ -16,6 +16,7 @@ import ( "fmt" "go/format" "html/template" + "io" "io/fs" "io/ioutil" "log" @@ -27,6 +28,7 @@ import ( "runtime" "runtime/debug" "strings" + "sync" "sync/atomic" "time" @@ -242,6 +244,8 @@ func NewHandler(contentDir, goroot string) http.Handler { return h } +var gorebuild = NewCachedURL("https://gorebuild.storage.googleapis.com/gorebuild.json", 5*time.Minute) + // newSite creates a new site for a given content and goroot file system pair // and registers it in mux to handle requests for host. // If host is the empty string, the registrations are for the wildcard host. @@ -251,11 +255,14 @@ func newSite(mux *http.ServeMux, host string, content, goroot fs.FS) (*web.Site, site.Funcs(template.FuncMap{ "googleAnalytics": func() string { return googleAnalytics }, "googleCN": func() bool { return host == "golang.google.cn" }, + "gorebuild": gorebuild.Get, + "json": jsonUnmarshal, "newest": newest, + "now": func() time.Time { return time.Now() }, "releases": func() []*history.Major { return history.Majors }, + "rfc3339": parseRFC3339, "section": section, "version": func() string { return runtime.Version() }, - "now": func() time.Time { return time.Now() }, }) docs, err := pkgdoc.NewServer(fsys, site, googleCN) if err != nil { @@ -269,6 +276,10 @@ func newSite(mux *http.ServeMux, host string, content, goroot fs.FS) (*web.Site, return site, nil } +func parseRFC3339(s string) (time.Time, error) { + return time.Parse(time.RFC3339, s) +} + // watchTip is a background goroutine that watches the main Go repo for updates. // When a new commit is available, watchTip downloads the new tree and calls // tipGoroot.Set to install the new file system. @@ -803,3 +814,66 @@ func redirectPrefix(prefix string) http.Handler { http.Redirect(w, r, url, http.StatusMovedPermanently) }) } + +type CachedURL struct { + url string + timeout time.Duration + + mu sync.Mutex + data []byte + err error + etag string + updated time.Time +} + +func NewCachedURL(url string, timeout time.Duration) *CachedURL { + return &CachedURL{url: url, timeout: timeout} +} + +func (c *CachedURL) Get() (data []byte, err error) { + c.mu.Lock() + defer c.mu.Unlock() + + if time.Since(c.updated) < c.timeout { + return c.data, c.err + } + defer func() { + c.updated = time.Now() + c.data, c.err = data, err + }() + + cli := &http.Client{Timeout: 60 * time.Second} + req, err := http.NewRequest("GET", c.url, nil) + if err != nil { + return nil, err + } + if c.etag != "" { + req.Header.Set("If-None-Match", c.etag) + } + resp, err := cli.Do(req) + if err != nil { + return nil, fmt.Errorf("loading rebuild report JSON: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode == 206 { + // Unmodified. + log.Printf("checked %s - unmodified", c.url) + return c.data, c.err + } + log.Printf("reloading %s", c.url) + if resp.StatusCode != 200 { + return nil, fmt.Errorf("loading rebuild report JSON: %v", resp.Status) + } + c.etag = resp.Header.Get("Etag") + data, err = io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("loading rebuild report JSON: %v", err) + } + return data, nil +} + +func jsonUnmarshal(data []byte) (any, error) { + var x any + err := json.Unmarshal(data, &x) + return x, err +} |
