Brad Fitzpatrick | 46cc759 | 2015-01-15 12:46:22 -0800 | [diff] [blame] | 1 | // Copyright 2015 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | // Package dashboard contains shared configuration and logic used by various |
| 6 | // pieces of the Go continuous build system. |
| 7 | package dashboard |
| 8 | |
| 9 | import ( |
| 10 | "errors" |
| 11 | "io/ioutil" |
| 12 | "os" |
| 13 | "strings" |
| 14 | ) |
| 15 | |
| 16 | // Builders are the different build configurations. |
| 17 | // The keys are like "darwin-amd64" or "linux-386-387". |
| 18 | // This map should not be modified by other packages. |
| 19 | var Builders = map[string]BuildConfig{} |
| 20 | |
| 21 | // A BuildConfig describes how to run either a Docker-based or VM-based builder. |
| 22 | type BuildConfig struct { |
| 23 | // Name is the unique name of the builder, in the form of |
| 24 | // "darwin-386" or "linux-amd64-race". |
| 25 | Name string |
| 26 | |
| 27 | // VM-specific settings: |
| 28 | VMImage string // e.g. "openbsd-amd64-56" |
| 29 | machineType string // optional GCE instance type |
Brad Fitzpatrick | 20d8483 | 2015-01-21 10:03:07 -0800 | [diff] [blame] | 30 | Go14URL string // URL to built Go 1.4 tar.gz |
Brad Fitzpatrick | 46cc759 | 2015-01-15 12:46:22 -0800 | [diff] [blame] | 31 | |
| 32 | // Docker-specific settings: (used if VMImage == "") |
Brad Fitzpatrick | 32d0520 | 2015-01-21 15:15:48 -0800 | [diff] [blame^] | 33 | Image string // Docker image to use to build |
| 34 | cmd string // optional -cmd flag (relative to go/src/) |
| 35 | dashURL string // url of the build dashboard |
| 36 | tool string // the tool this configuration is for |
| 37 | |
| 38 | // Use by both VMs and Docker: |
| 39 | env []string // extra environment ("key=value") pairs |
Brad Fitzpatrick | 46cc759 | 2015-01-15 12:46:22 -0800 | [diff] [blame] | 40 | } |
| 41 | |
Brad Fitzpatrick | 32d0520 | 2015-01-21 15:15:48 -0800 | [diff] [blame^] | 42 | func (c *BuildConfig) Env() []string { return append([]string(nil), c.env...) } |
| 43 | |
Brad Fitzpatrick | f3c0193 | 2015-01-15 16:29:16 -0800 | [diff] [blame] | 44 | func (c *BuildConfig) GOOS() string { return c.Name[:strings.Index(c.Name, "-")] } |
| 45 | |
| 46 | func (c *BuildConfig) GOARCH() string { |
| 47 | arch := c.Name[strings.Index(c.Name, "-")+1:] |
| 48 | i := strings.Index(arch, "-") |
| 49 | if i == -1 { |
| 50 | return arch |
| 51 | } |
| 52 | return arch[:i] |
| 53 | } |
| 54 | |
Brad Fitzpatrick | f8c2484 | 2015-01-16 09:54:03 -0800 | [diff] [blame] | 55 | // AllScript returns the relative path to the operating system's script to |
| 56 | // do the build and run its standard set of tests. |
| 57 | // Example values are "src/all.bash", "src/all.bat", "src/all.rc". |
| 58 | func (c *BuildConfig) AllScript() string { |
Brad Fitzpatrick | 32d0520 | 2015-01-21 15:15:48 -0800 | [diff] [blame^] | 59 | if strings.HasSuffix(c.Name, "-race") { |
| 60 | if strings.HasPrefix(c.Name, "windows-") { |
| 61 | return "src/race.bat" |
| 62 | } |
| 63 | return "src/race.bash" |
| 64 | } |
Brad Fitzpatrick | f8c2484 | 2015-01-16 09:54:03 -0800 | [diff] [blame] | 65 | if strings.HasPrefix(c.Name, "windows-") { |
| 66 | return "src/all.bat" |
| 67 | } |
| 68 | if strings.HasPrefix(c.Name, "plan9-") { |
| 69 | return "src/all.rc" |
| 70 | } |
Brad Fitzpatrick | f8c2484 | 2015-01-16 09:54:03 -0800 | [diff] [blame] | 71 | return "src/all.bash" |
| 72 | } |
| 73 | |
Brad Fitzpatrick | 46cc759 | 2015-01-15 12:46:22 -0800 | [diff] [blame] | 74 | func (c *BuildConfig) UsesDocker() bool { return c.VMImage == "" } |
| 75 | func (c *BuildConfig) UsesVM() bool { return c.VMImage != "" } |
| 76 | |
| 77 | // MachineType returns the GCE machine type to use for this builder. |
| 78 | func (c *BuildConfig) MachineType() string { |
| 79 | if v := c.machineType; v != "" { |
| 80 | return v |
| 81 | } |
| 82 | return "n1-highcpu-2" |
| 83 | } |
| 84 | |
| 85 | // DockerRunArgs returns the arguments that go after "docker run" to execute |
| 86 | // this docker image. The rev (git hash) is required. The builderKey is optional. |
| 87 | // TODO(bradfitz): remove the builderKey being passed down, once the coordinator |
| 88 | // does the reporting to the dashboard for docker builds too. |
| 89 | func (conf BuildConfig) DockerRunArgs(rev, builderKey string) ([]string, error) { |
| 90 | if !conf.UsesDocker() { |
| 91 | return nil, errors.New("not a docker-based build") |
| 92 | } |
| 93 | var args []string |
| 94 | if builderKey != "" { |
| 95 | tmpKey := "/tmp/" + conf.Name + ".buildkey" |
| 96 | if _, err := os.Stat(tmpKey); err != nil { |
| 97 | if err := ioutil.WriteFile(tmpKey, []byte(builderKey), 0600); err != nil { |
| 98 | return nil, err |
| 99 | } |
| 100 | } |
| 101 | // Images may look for .gobuildkey in / or /root, so provide both. |
| 102 | // TODO(adg): fix images that look in the wrong place. |
| 103 | args = append(args, "-v", tmpKey+":/.gobuildkey") |
| 104 | args = append(args, "-v", tmpKey+":/root/.gobuildkey") |
| 105 | } |
| 106 | for _, pair := range conf.env { |
| 107 | args = append(args, "-e", pair) |
| 108 | } |
| 109 | if strings.HasPrefix(conf.Name, "linux-amd64") { |
| 110 | args = append(args, "-e", "GOROOT_BOOTSTRAP=/go1.4-amd64/go") |
| 111 | } else if strings.HasPrefix(conf.Name, "linux-386") { |
| 112 | args = append(args, "-e", "GOROOT_BOOTSTRAP=/go1.4-386/go") |
| 113 | } |
| 114 | args = append(args, |
| 115 | conf.Image, |
| 116 | "/usr/local/bin/builder", |
| 117 | "-rev="+rev, |
| 118 | "-dashboard="+conf.dashURL, |
| 119 | "-tool="+conf.tool, |
| 120 | "-buildroot=/", |
| 121 | "-v", |
| 122 | ) |
| 123 | if conf.cmd != "" { |
| 124 | args = append(args, "-cmd", conf.cmd) |
| 125 | } |
| 126 | args = append(args, conf.Name) |
| 127 | return args, nil |
| 128 | } |
| 129 | |
| 130 | func init() { |
| 131 | addBuilder(BuildConfig{Name: "linux-386"}) |
| 132 | addBuilder(BuildConfig{Name: "linux-386-387", env: []string{"GO386=387"}}) |
| 133 | addBuilder(BuildConfig{Name: "linux-amd64"}) |
| 134 | addBuilder(BuildConfig{Name: "linux-amd64-nocgo", env: []string{"CGO_ENABLED=0", "USER=root"}}) |
| 135 | addBuilder(BuildConfig{Name: "linux-amd64-noopt", env: []string{"GO_GCFLAGS=-N -l"}}) |
| 136 | addBuilder(BuildConfig{Name: "linux-amd64-race"}) |
| 137 | addBuilder(BuildConfig{Name: "nacl-386"}) |
| 138 | addBuilder(BuildConfig{Name: "nacl-amd64p32"}) |
| 139 | addBuilder(BuildConfig{ |
| 140 | Name: "linux-amd64-gccgo", |
| 141 | Image: "gobuilders/linux-x86-gccgo", |
| 142 | cmd: "make RUNTESTFLAGS=\"--target_board=unix/-m64\" check-go -j16", |
| 143 | dashURL: "https://build.golang.org/gccgo", |
| 144 | tool: "gccgo", |
| 145 | }) |
| 146 | addBuilder(BuildConfig{ |
| 147 | Name: "linux-386-gccgo", |
| 148 | Image: "gobuilders/linux-x86-gccgo", |
| 149 | cmd: "make RUNTESTFLAGS=\"--target_board=unix/-m32\" check-go -j16", |
| 150 | dashURL: "https://build.golang.org/gccgo", |
| 151 | tool: "gccgo", |
| 152 | }) |
| 153 | addBuilder(BuildConfig{Name: "linux-386-sid", Image: "gobuilders/linux-x86-sid"}) |
| 154 | addBuilder(BuildConfig{Name: "linux-amd64-sid", Image: "gobuilders/linux-x86-sid"}) |
| 155 | addBuilder(BuildConfig{Name: "linux-386-clang", Image: "gobuilders/linux-x86-clang"}) |
| 156 | addBuilder(BuildConfig{Name: "linux-amd64-clang", Image: "gobuilders/linux-x86-clang"}) |
| 157 | |
| 158 | // VMs: |
| 159 | addBuilder(BuildConfig{ |
Brad Fitzpatrick | 32d0520 | 2015-01-21 15:15:48 -0800 | [diff] [blame^] | 160 | Name: "freebsd-amd64-gce101", |
| 161 | VMImage: "freebsd-amd64-gce101", |
| 162 | machineType: "n1-highcpu-2", |
| 163 | Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-freebsd-amd64.tar.gz", |
| 164 | env: []string{"CC=clang"}, |
| 165 | }) |
| 166 | addBuilder(BuildConfig{ |
| 167 | Name: "freebsd-amd64-race", |
| 168 | VMImage: "freebsd-amd64-gce101", |
| 169 | machineType: "n1-highcpu-4", |
| 170 | Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-freebsd-amd64.tar.gz", |
| 171 | env: []string{"CC=clang"}, |
| 172 | }) |
| 173 | addBuilder(BuildConfig{ |
| 174 | Name: "freebsd-386-gce101", |
| 175 | VMImage: "freebsd-amd64-gce101", |
| 176 | machineType: "n1-highcpu-2", |
| 177 | Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-freebsd-amd64.tar.gz", |
| 178 | env: []string{"GOARCH=386", "CC=clang"}, |
| 179 | }) |
| 180 | addBuilder(BuildConfig{ |
Brad Fitzpatrick | 46cc759 | 2015-01-15 12:46:22 -0800 | [diff] [blame] | 181 | Name: "openbsd-amd64-gce56", |
| 182 | VMImage: "openbsd-amd64-56", |
| 183 | machineType: "n1-highcpu-2", |
Brad Fitzpatrick | 20d8483 | 2015-01-21 10:03:07 -0800 | [diff] [blame] | 184 | Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-openbsd-amd64.tar.gz", |
Brad Fitzpatrick | 46cc759 | 2015-01-15 12:46:22 -0800 | [diff] [blame] | 185 | }) |
| 186 | addBuilder(BuildConfig{ |
Brad Fitzpatrick | 32d0520 | 2015-01-21 15:15:48 -0800 | [diff] [blame^] | 187 | Name: "plan9-386-gcepartial", |
| 188 | VMImage: "plan9-386", |
| 189 | Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-plan9-386.tar.gz", |
Brad Fitzpatrick | 46cc759 | 2015-01-15 12:46:22 -0800 | [diff] [blame] | 190 | // It's named "partial" because the buildlet sets |
| 191 | // GOTESTONLY=std to stop after the "go test std" |
| 192 | // tests because it's so slow otherwise. |
Brad Fitzpatrick | 32d0520 | 2015-01-21 15:15:48 -0800 | [diff] [blame^] | 193 | env: []string{"GOTESTONLY=std"}, |
| 194 | |
Brad Fitzpatrick | 46cc759 | 2015-01-15 12:46:22 -0800 | [diff] [blame] | 195 | // We *were* using n1-standard-1 because Plan 9 can only |
| 196 | // reliably use a single CPU. Using 2 or 4 and we see |
| 197 | // test failures. See: |
| 198 | // https://golang.org/issue/8393 |
| 199 | // https://golang.org/issue/9491 |
| 200 | // n1-standard-1 has 3.6 GB of memory which is |
| 201 | // overkill (userspace probably only sees 2GB anyway), |
| 202 | // but it's the cheapest option. And plenty to keep |
| 203 | // our ~250 MB of inputs+outputs in its ramfs. |
| 204 | // |
| 205 | // But the docs says "For the n1 series of machine |
| 206 | // types, a virtual CPU is implemented as a single |
| 207 | // hyperthread on a 2.6GHz Intel Sandy Bridge Xeon or |
| 208 | // Intel Ivy Bridge Xeon (or newer) processor. This |
| 209 | // means that the n1-standard-2 machine type will see |
| 210 | // a whole physical core." |
| 211 | // |
| 212 | // ... so we use n1-highcpu-2 (1.80 RAM, still |
| 213 | // plenty), just so we can get 1 whole core for the |
| 214 | // single-core Plan 9. It will see 2 virtual cores and |
| 215 | // only use 1, but we hope that 1 will be more powerful |
| 216 | // and we'll stop timing out on tests. |
| 217 | machineType: "n1-highcpu-2", |
| 218 | }) |
| 219 | |
| 220 | } |
| 221 | |
| 222 | func addBuilder(c BuildConfig) { |
| 223 | if c.tool == "gccgo" { |
| 224 | // TODO(cmang,bradfitz,adg): fix gccgo |
| 225 | return |
| 226 | } |
| 227 | if c.Name == "" { |
| 228 | panic("empty name") |
| 229 | } |
| 230 | if _, dup := Builders[c.Name]; dup { |
| 231 | panic("dup name") |
| 232 | } |
| 233 | if c.dashURL == "" { |
| 234 | c.dashURL = "https://build.golang.org" |
| 235 | } |
| 236 | if c.tool == "" { |
| 237 | c.tool = "go" |
| 238 | } |
| 239 | |
| 240 | if strings.HasPrefix(c.Name, "nacl-") { |
| 241 | if c.Image == "" { |
| 242 | c.Image = "gobuilders/linux-x86-nacl" |
| 243 | } |
| 244 | if c.cmd == "" { |
| 245 | c.cmd = "/usr/local/bin/build-command.pl" |
| 246 | } |
| 247 | } |
| 248 | if strings.HasPrefix(c.Name, "linux-") && c.Image == "" { |
| 249 | c.Image = "gobuilders/linux-x86-base" |
| 250 | } |
| 251 | if c.Image == "" && c.VMImage == "" { |
| 252 | panic("empty image and vmImage") |
| 253 | } |
| 254 | if c.Image != "" && c.VMImage != "" { |
| 255 | panic("can't specify both image and vmImage") |
| 256 | } |
| 257 | Builders[c.Name] = c |
| 258 | } |