aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2023-07-28 13:53:30 -0400
committerRuss Cox <rsc@golang.org>2023-08-03 02:08:39 +0000
commit1e75b26cba0e55a9f61c79dbb46459a4e6ddbd65 (patch)
tree926db32bbabc6420067cf58e7bb9e254b2586bfd /cmd
parentc999d513375b4ada88a6da915515cd15868bb20d (diff)
downloadgo-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.go76
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
+}