internal/buildgo, cmd/updatedisks: clean up old, unused VM disks

After CL 210237 and CL 210541 we'd run out of disk:

    Code:QUOTA_EXCEEDED Location: Message:Quota 'SSD_TOTAL_GB' exceeded.  Limit: 8192.0 in region us-central1.

So this now cleans up old stuff.

Fixes golang/go#35987 (again)

Change-Id: I187d55209c0efb6e7b398eec7b78d0df2e7cdb2d
Reviewed-on: https://go-review.googlesource.com/c/build/+/210542
Reviewed-by: Alexander Rakoczy <alex@golang.org>
This commit is contained in:
Brad Fitzpatrick 2019-12-09 20:42:26 +00:00
Родитель 326548a346
Коммит 4cca7725b4
2 изменённых файлов: 81 добавлений и 7 удалений

Просмотреть файл

@ -0,0 +1,44 @@
// Copyright 2019 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.
// The updatedisks command creates & deletes VM disks as needed
// across the various GCP zones.
//
// This code is run automatically in the background in the coordinator
// and is purely an optimization. It's only a separate tool for debugging
// purposes.
package main
import (
"context"
"flag"
"log"
"golang.org/x/build/buildenv"
"golang.org/x/build/internal/buildgo"
compute "google.golang.org/api/compute/v1"
)
var (
computeSvc *compute.Service
env *buildenv.Environment
)
func main() {
buildenv.RegisterFlags()
flag.Parse()
env = buildenv.FromFlags()
ctx := context.Background()
c, err := buildgo.NewClient(ctx, env)
if err != nil {
log.Fatal(err)
}
if err := c.MakeBasepinDisks(ctx); err != nil {
log.Fatal(err)
}
}

Просмотреть файл

@ -14,6 +14,7 @@ import (
"strings"
"time"
"golang.org/x/build/dashboard"
compute "google.golang.org/api/compute/v1"
)
@ -27,6 +28,13 @@ import (
// there's been a VM created within the past N minutes of that type,
// but we want VMs to always create quickly.
func (c *Client) MakeBasepinDisks(ctx context.Context) error {
currentImage := map[string]bool{}
for _, hc := range dashboard.Hosts {
if hc.VMImage != "" {
currentImage[hc.VMImage] = true
}
}
// Try to find it by name.
svc := c.Compute()
imList, err := svc.Images.List(c.Env.ProjectName).Do()
@ -37,6 +45,21 @@ func (c *Client) MakeBasepinDisks(ctx context.Context) error {
return errors.New("too many images; pagination not supported")
}
getNeedMap := func() map[string]*compute.Image {
need := make(map[string]*compute.Image) // keys like "https://www.googleapis.com/compute/v1/projects/symbolic-datum-552/global/images/linux-buildlet-arm"
for _, im := range imList.Items {
imBase := path.Base(im.SelfLink)
if strings.Contains(im.SelfLink, "-debug") {
continue
}
if !currentImage[imBase] {
continue
}
need[im.SelfLink] = im
}
return need
}
for _, zone := range c.Env.VMZones {
diskList, err := svc.Disks.List(c.Env.ProjectName, zone).Do()
if err != nil {
@ -46,13 +69,7 @@ func (c *Client) MakeBasepinDisks(ctx context.Context) error {
return fmt.Errorf("too many disks in %v; pagination not supported (yet?)", zone)
}
need := make(map[string]*compute.Image) // keys like "https://www.googleapis.com/compute/v1/projects/symbolic-datum-552/global/images/linux-buildlet-arm"
for _, im := range imList.Items {
if strings.Contains(im.SelfLink, "-debug") {
continue
}
need[im.SelfLink] = im
}
need := getNeedMap()
for _, d := range diskList.Items {
if !strings.HasPrefix(d.Name, "basepin-") {
@ -63,6 +80,19 @@ func (c *Client) MakeBasepinDisks(ctx context.Context) error {
log.Printf("basepin: have %s: %s (%v)\n", d.Name, d.SourceImage, d.SourceImageId)
}
delete(need, d.SourceImage)
continue
}
if zone != c.Env.ControlZone {
log.Printf("basepin: deleting unnecessary disk %v in zone %v", d.Name, zone)
op, err := svc.Disks.Delete(c.Env.ProjectName, zone, d.Name).Do()
if err != nil {
log.Printf("basepin: failed to delete disk %v in zone %v: %v", d.Name, zone, err)
continue
}
if err := c.AwaitOp(ctx, op); err != nil {
log.Printf("basepin: failed to delete disk %v in zone %v: %v", d.Name, zone, err)
continue
}
}
}