| // Copyright 2024 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package main | |
| import ( | |
| "cmp" | |
| "fmt" | |
| "log" | |
| "slices" | |
| "go.chromium.org/luci/swarming/client/swarming" | |
| ) | |
| // swarmingConfig describes a swarming server. | |
| type swarmingConfig struct { | |
| Host string // Swarming host URL | |
| Pool string // Pool containing MacService bots | |
| client swarming.Client | |
| } | |
| var ( | |
| // Public swarming host. | |
| publicSwarming = &swarmingConfig{ | |
| Host: "chromium-swarm.appspot.com", | |
| Pool: "luci.golang.shared-workers", | |
| } | |
| // Security swarming host. | |
| internalSwarming = &swarmingConfig{ | |
| Host: "chrome-swarming.appspot.com", | |
| Pool: "luci.golang.security-try-workers", | |
| } | |
| ) | |
| // imageConfig describes how many instances of a specific image type should | |
| // exist. | |
| type imageConfig struct { | |
| Hostname string // LUCI hostname prefix | |
| Cert string // Bot certificate (resolved with internal/secret) | |
| Key string // bot key (resolved with internal/secret) | |
| Image string // image SHA | |
| Count int // target instance count to maintain | |
| } | |
| // Production image configuration for each swarming host. | |
| // | |
| // After changing an image here, makemac will automatically destroy instances | |
| // with the old image. Changing hostname, cert, or key will _not_ automatically | |
| // destroy instances. | |
| // | |
| // TODO(prattmic): rather than storing secrets in secret manager, makemac could | |
| // use genbotcert to generate valid certificate/key pairs on the fly, unique to | |
| // each lease, which could then have unique hostnames. | |
| var prodImageConfig = map[*swarmingConfig][]imageConfig{ | |
| publicSwarming: { | |
| // amd64 | |
| { | |
| Hostname: "darwin-amd64-12", | |
| Cert: "secret:symbolic-datum-552/darwin-amd64-12-cert", | |
| Key: "secret:symbolic-datum-552/darwin-amd64-12-key", | |
| Image: "f48c5538d2ac7b91c592dcce18f247e3aad70503558f92b41bdc010f2c8728a9", | |
| Count: 5, // Fewer because it runs on release branches only. | |
| }, | |
| { | |
| Hostname: "darwin-amd64-13", | |
| Cert: "secret:symbolic-datum-552/darwin-amd64-13-cert", | |
| Key: "secret:symbolic-datum-552/darwin-amd64-13-key", | |
| Image: "3baa47241c34feeb46318f3e9f1f5ce26d79994088179ab8d6d60a1183bbacfe", | |
| Count: 10, | |
| }, | |
| { | |
| Hostname: "darwin-amd64-14", | |
| Cert: "secret:symbolic-datum-552/darwin-amd64-14-cert", | |
| Key: "secret:symbolic-datum-552/darwin-amd64-14-key", | |
| Image: "b16a8a5f2d1e383667c3764d915551f4af56d63edd0679539703688a6b9f6754", | |
| Count: 20, // More to cover longtest, race, nocgo, etc. | |
| }, | |
| // arm64 | |
| { | |
| Hostname: "darwin-arm64-14", | |
| Cert: "secret:symbolic-datum-552/darwin-arm64-14-cert", | |
| Key: "secret:symbolic-datum-552/darwin-arm64-14-key", | |
| Image: "edbf519386cb968127d9e682ac5bbc9ca9fbc9b8e8657bade9488089bb842405", | |
| Count: 7, | |
| }, | |
| { | |
| Hostname: "darwin-arm64-15", | |
| Cert: "secret:symbolic-datum-552/darwin-arm64-15-cert", | |
| Key: "secret:symbolic-datum-552/darwin-arm64-15-key", | |
| Image: "203520220bdfe6b42592d2ae731c9cb985768c701c569ff1bc572d1573e63ad6", | |
| Count: 7, | |
| }, | |
| { | |
| Hostname: "darwin-arm64-26", | |
| Cert: "secret:symbolic-datum-552/darwin-arm64-26-cert", | |
| Key: "secret:symbolic-datum-552/darwin-arm64-26-key", | |
| Image: "b39d12df6bb6702c4ea1ae1d061b9964eb5912b514f073ece0fc5fd0bedec0cb", | |
| Count: 7, | |
| }, | |
| }, | |
| internalSwarming: { | |
| // amd64 | |
| { | |
| Hostname: "darwin-amd64-12-security", | |
| Cert: "secret:symbolic-datum-552/darwin-amd64-12-security-cert", | |
| Key: "secret:symbolic-datum-552/darwin-amd64-12-security-key", | |
| Image: "f48c5538d2ac7b91c592dcce18f247e3aad70503558f92b41bdc010f2c8728a9", | |
| Count: 4, | |
| }, | |
| { | |
| Hostname: "darwin-amd64-13-security", | |
| Cert: "secret:symbolic-datum-552/darwin-amd64-13-security-cert", | |
| Key: "secret:symbolic-datum-552/darwin-amd64-13-security-key", | |
| Image: "3baa47241c34feeb46318f3e9f1f5ce26d79994088179ab8d6d60a1183bbacfe", | |
| Count: 4, | |
| }, | |
| { | |
| Hostname: "darwin-amd64-14-security", | |
| Cert: "secret:symbolic-datum-552/darwin-amd64-14-security-cert", | |
| Key: "secret:symbolic-datum-552/darwin-amd64-14-security-key", | |
| Image: "b16a8a5f2d1e383667c3764d915551f4af56d63edd0679539703688a6b9f6754", | |
| Count: 7, // More to cover longtest, race, nocgo, etc. | |
| }, | |
| // arm64 | |
| { | |
| Hostname: "darwin-arm64-14-security", | |
| Cert: "secret:symbolic-datum-552/darwin-arm64-14-security-cert", | |
| Key: "secret:symbolic-datum-552/darwin-arm64-14-security-key", | |
| Image: "edbf519386cb968127d9e682ac5bbc9ca9fbc9b8e8657bade9488089bb842405", | |
| Count: 3, | |
| }, | |
| { | |
| Hostname: "darwin-arm64-15-security", | |
| Cert: "secret:symbolic-datum-552/darwin-arm64-15-security-cert", | |
| Key: "secret:symbolic-datum-552/darwin-arm64-15-security-key", | |
| Image: "203520220bdfe6b42592d2ae731c9cb985768c701c569ff1bc572d1573e63ad6", | |
| Count: 3, | |
| }, | |
| { | |
| Hostname: "darwin-arm64-26-security", | |
| Cert: "secret:symbolic-datum-552/darwin-arm64-26-security-cert", | |
| Key: "secret:symbolic-datum-552/darwin-arm64-26-security-key", | |
| Image: "b39d12df6bb6702c4ea1ae1d061b9964eb5912b514f073ece0fc5fd0bedec0cb", | |
| Count: 3, | |
| }, | |
| }, | |
| } | |
| // imageConfigMap returns a map from imageConfig.Image to imageConfig. | |
| func imageConfigMap(cc []imageConfig) map[string]*imageConfig { | |
| m := make(map[string]*imageConfig) | |
| for _, c := range cc { | |
| if _, ok := m[c.Image]; ok { | |
| panic(fmt.Sprintf("duplicate image %s in image config", c.Image)) | |
| } | |
| m[c.Image] = &c | |
| } | |
| return m | |
| } | |
| // sortedSwarmingConfigs returns the swarming configs in c, sorted by host. | |
| func sortedSwarmingConfigs(c map[*swarmingConfig][]imageConfig) []*swarmingConfig { | |
| scs := make([]*swarmingConfig, 0, len(c)) | |
| for sc := range c { | |
| scs = append(scs, sc) | |
| } | |
| slices.SortFunc(scs, func(a, b *swarmingConfig) int { | |
| return cmp.Compare(a.Host, b.Host) | |
| }) | |
| return scs | |
| } | |
| func init() { | |
| // Panic if prodImageConfig contains duplicates. | |
| for _, c := range prodImageConfig { | |
| imageConfigMap(c) | |
| } | |
| } | |
| func logImageConfig(sc *swarmingConfig, cc []imageConfig) { | |
| log.Printf("%s image configuration:", sc.Host) | |
| for _, c := range cc { | |
| log.Printf("\t%s: image=%s\tcount=%d", c.Hostname, c.Image, c.Count) | |
| } | |
| } |