Path: blob/main/dev/gpctl/cmd/imagebuilds-build-batch.go
2498 views
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package cmd56import (7"bufio"8"context"9"os"10"strings"11"sync"12"time"1314"github.com/spf13/cobra"1516"github.com/gitpod-io/gitpod/common-go/log"17builder "github.com/gitpod-io/gitpod/image-builder/api"18)1920// imagebuildsBuildBatch represents the build command2122var imagebuildsBuildBatch = &cobra.Command{23Use: "build-batch",24Short: "Builds workspace images from base-image refs read from STDIN",25Long: `Tip: re-build the workspace images of all workspaces started in the last 30 days.26mysql -N -B -u gitpod -p -h 127.0.0.1 gitpod -e 'SELECT ws.baseImageNameResolved FROM d_b_workspace_instance wsi LEFT JOIN d_b_workspace ws ON ws.id = workspaceId WHERE wsi.creationTime > (NOW() - INTERVAL 30 DAY)' | \27sort | \28uniq | \29gpctl imagebuilds build-batch3031`,32Args: cobra.ExactArgs(0),33Run: func(cmd *cobra.Command, args []string) {34forceRebuild, _ := cmd.Flags().GetBool("force-rebuild")3536ctx, cancel := context.WithCancel(context.Background())3738conn, client, err := getImagebuildsClient(ctx)39if err != nil {40log.WithError(err).Fatal("cannot connect")41}42log.Info("connected to image-builder")43defer conn.Close()4445timeBetweenBuilds, _ := cmd.Flags().GetInt("time-between-builds")46delay := time.Duration(timeBetweenBuilds) * time.Second4748var wg sync.WaitGroup49scanner := bufio.NewScanner(os.Stdin)50for scanner.Scan() {51ref := strings.TrimSpace(scanner.Text())52if len(ref) == 0 {53continue54}5556wg.Add(1)57go buildWorkspaceImage(&wg, ctx, client, forceRebuild, ref)5859if delay > 0 {60time.Sleep(delay)61}62}6364wg.Wait()65cancel()66},67}6869func buildWorkspaceImage(wg *sync.WaitGroup, ctx context.Context, client builder.ImageBuilderClient, forceRebuild bool, ref string) {70defer wg.Done()7172br, err := client.Build(ctx, &builder.BuildRequest{73Source: &builder.BuildSource{74From: &builder.BuildSource_Ref{75Ref: &builder.BuildSourceReference{76Ref: ref,77},78},79},80ForceRebuild: forceRebuild,81Auth: &builder.BuildRegistryAuth{82Mode: &builder.BuildRegistryAuth_Total{83Total: &builder.BuildRegistryAuthTotal{84AllowAll: true,85},86},87},88// TODO: this shouldn't be hard coded89SupervisorRef: "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-4cb5b6b9c0e993f3964e978e387fb0e7c1c04276",90TriggeredBy: "c0f5dbf1-8d50-4d2a-8cd9-fe563fa53c71",91})92if err != nil {93log.WithField("ref", ref).WithError(err).Warn("cannot build workspace image")94return95}9697r, err := br.Recv()98if err != nil {99log.WithField("ref", ref).WithError(err).Warn("cannot receive build response")100return101}102err = br.CloseSend()103if err != nil {104log.WithField("ref", ref).WithError(err).Warn("close send error")105}106107switch r.Status {108case builder.BuildStatus_done_failure, builder.BuildStatus_done_success:109log.WithField("ref", ref).Infof("build done: %s, message: %s", builder.BuildStatus_name[int32(r.Status)], r.GetMessage())110case builder.BuildStatus_unknown:111log.WithField("ref", ref).Error("build status unknown")112case builder.BuildStatus_running:113log.WithField("ref", ref).Info("build running")114}115116}117118func init() {119imagebuildsCmd.AddCommand(imagebuildsBuildBatch)120121imagebuildsBuildBatch.Flags().Bool("force-rebuild", false, "force an image build even if the image exists already")122imagebuildsBuildBatch.Flags().IntP("time-between-builds", "", 0, "wait N seconds between starting builds")123}124125126