Skip to content

Commit f2d63a8

Browse files
committed
cmd/coordinator: more reliable and debuggable mirroring from gerrit to github
* Use ssh instead of https. (git-remote-https seems buggy and slow, unable to deal with 40k+ refs efficiently at all) * Add /debug/watcher/<repo> status pages on the coordinator (proxying through to the watcher child process) * more logging * do mirroring of refs in batches, prioritizing heads and tags over refs/changes/* (although this is admittedly less useful now that we use ssh instead of https). * update go-watcher-world from git 1.7 to git 2.8 (and Debian sid) Fixes golang/go#16388 Change-Id: If3e2cf67afddd544892886a466938e8f46df8c95 Reviewed-on: https://go-review.googlesource.com/25110 Reviewed-by: Andrew Gerrand <adg@golang.org>
1 parent fa4ab61 commit f2d63a8

File tree

5 files changed

+358
-57
lines changed

5 files changed

+358
-57
lines changed

cmd/coordinator/coordinator.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ func main() {
286286

287287
http.HandleFunc("/", handleStatus)
288288
http.HandleFunc("/debug/goroutines", handleDebugGoroutines)
289-
http.HandleFunc("/debug/watcher", handleDebugWatcher)
289+
http.HandleFunc("/debug/watcherlogs", handleDebugWatcherLogs)
290+
http.HandleFunc("/debug/watcher/", handleDebugWatcher)
290291
http.HandleFunc("/builders", handleBuilders)
291292
http.HandleFunc("/temporarylogs", handleLogs)
292293
http.HandleFunc("/reverse", handleReverse)
@@ -2872,11 +2873,9 @@ func getSourceTgz(sl spanLogger, repo, rev string, isTry bool) (tgz io.Reader, e
28722873
sp := sl.createSpan("get_source")
28732874
defer func() { sp.done(err) }()
28742875

2875-
fromCache := false
28762876
key := fmt.Sprintf("%v-%v", repo, rev)
28772877
vi, err, _ := sourceGroup.Do(key, func() (interface{}, error) {
28782878
if tgzBytes, ok := sourceCache.Get(key); ok {
2879-
fromCache = true
28802879
return tgzBytes, nil
28812880
}
28822881

cmd/coordinator/watcher.go

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"io/ioutil"
1414
"log"
1515
"net/http"
16+
"net/http/httputil"
1617
"net/url"
1718
"os"
1819
"os/exec"
@@ -29,12 +30,12 @@ var (
2930
)
3031

3132
type watchConfig struct {
32-
repo string // "https://go.googlesource.com/go"
33-
dash string // "https://build.golang.org/" (must end in /)
34-
interval time.Duration // Polling interval
35-
mirrorBase string // "https://github.com/golang/" or empty to disable mirroring
36-
netHost bool // run docker container in the host's network namespace
37-
httpAddr string
33+
repo string // "https://go.googlesource.com/go"
34+
dash string // "https://build.golang.org/" (must end in /)
35+
interval time.Duration // Polling interval
36+
mirror bool // whether to enable mirroring to github
37+
netHost bool // run docker container in the host's network namespace
38+
httpAddr string
3839
}
3940

4041
type imageInfo struct {
@@ -59,16 +60,16 @@ var images = map[string]*imageInfo{
5960
const gitArchiveAddr = "127.0.0.1:21536" // 21536 == keys above WATCH
6061

6162
func startWatchers() {
62-
mirrorBase := "https://github.com/golang/"
63+
mirror := true
6364
if inStaging {
64-
mirrorBase = "" // don't mirror from dev cluster
65+
mirror = false
6566
}
6667
addWatcher(watchConfig{
67-
repo: "https://go.googlesource.com/go",
68-
dash: dashBase(),
69-
mirrorBase: mirrorBase,
70-
netHost: true,
71-
httpAddr: gitArchiveAddr,
68+
repo: "https://go.googlesource.com/go",
69+
dash: dashBase(),
70+
mirror: mirror,
71+
netHost: true,
72+
httpAddr: gitArchiveAddr,
7273
})
7374
if false {
7475
// TODO(cmang,adg): only use one watcher or the other, depending on which build
@@ -122,15 +123,32 @@ func (conf watchConfig) dockerRunArgs() (args []string) {
122123
log.Fatalf("Failed to created watcher's git cache dir: %v", err)
123124
}
124125

126+
args = append(args, "-v", os.Args[0]+":/usr/local/bin/watcher")
127+
args = append(args, "-v", watcherGitCacheDir+":"+watcherGitCacheDir)
128+
129+
// Bind mount in gopherbot's private ed25519 ssh key from the PEM contents
130+
// in the GCE metadata. (Appending a newline, else it's invalid)
131+
if priv, err := metadata.ProjectAttributeValue("github-ssh"); err == nil {
132+
file := "/tmp/id_ed25519.gopherbot.ssh"
133+
if _, err := os.Stat(file); err != nil {
134+
if err := ioutil.WriteFile(file, []byte(priv+"\n"), 0600); err != nil {
135+
log.Fatal(err)
136+
}
137+
}
138+
log.Printf("added gopherbot ssh key")
139+
args = append(args, "-v", file+":/root/.ssh/id_ed25519")
140+
} else {
141+
log.Printf("no gopherbot ssh key found in GCE metadata: %v", err)
142+
}
143+
144+
// Bind mount in the key for the build.golang.org private token.
125145
if key := masterKey(); len(key) > 0 {
126146
tmpKey := "/tmp/watcher.buildkey"
127147
if _, err := os.Stat(tmpKey); err != nil {
128148
if err := ioutil.WriteFile(tmpKey, key, 0600); err != nil {
129149
log.Fatal(err)
130150
}
131151
}
132-
args = append(args, "-v", os.Args[0]+":/usr/local/bin/watcher")
133-
args = append(args, "-v", watcherGitCacheDir+":"+watcherGitCacheDir)
134152
// Images may look for .gobuildkey in / or /root, so provide both.
135153
// TODO(adg): fix images that look in the wrong place.
136154
args = append(args, "-v", tmpKey+":/.gobuildkey")
@@ -148,13 +166,8 @@ func (conf watchConfig) dockerRunArgs() (args []string) {
148166
"-watcher.poll="+conf.interval.String(),
149167
"-watcher.http="+conf.httpAddr,
150168
)
151-
if conf.mirrorBase != "" {
152-
dst, err := url.Parse(conf.mirrorBase)
153-
if err != nil {
154-
log.Fatalf("Bad mirror destination URL: %q", conf.mirrorBase)
155-
}
156-
dst.User = url.UserPassword(mirrorCred())
157-
args = append(args, "-watcher.mirror="+dst.String())
169+
if conf.mirror {
170+
args = append(args, "-watcher.mirror")
158171
}
159172
return
160173
}
@@ -224,7 +237,7 @@ var (
224237

225238
var matchTokens = regexp.MustCompile(`\b[0-9a-f]{40}\b`)
226239

227-
func handleDebugWatcher(w http.ResponseWriter, r *http.Request) {
240+
func handleDebugWatcherLogs(w http.ResponseWriter, r *http.Request) {
228241
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
229242
watchLogMu.Lock()
230243
defer watchLogMu.Unlock()
@@ -237,6 +250,26 @@ func handleDebugWatcher(w http.ResponseWriter, r *http.Request) {
237250
}
238251
}
239252

253+
// watcherProxy is the proxy which forwards from
254+
// http://farmer.golang.org/ to the watcher (git cache+sync) child
255+
// process listening on http://127.0.0.1:21536. This is used for
256+
// /debug/watcher/<reponame> status pages, which are served at the
257+
// same URL paths for both the farmer.golang.org host and the internal
258+
// backend.
259+
var watcherProxy *httputil.ReverseProxy
260+
261+
func init() {
262+
u, err := url.Parse("http://" + gitArchiveAddr)
263+
if err != nil {
264+
log.Fatal(err)
265+
}
266+
watcherProxy = httputil.NewSingleHostReverseProxy(u)
267+
}
268+
269+
func handleDebugWatcher(w http.ResponseWriter, r *http.Request) {
270+
watcherProxy.ServeHTTP(w, r)
271+
}
272+
240273
func startWatching(conf watchConfig) (err error) {
241274
defer func() {
242275
if err != nil {

0 commit comments

Comments
 (0)