go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/led/ledcmd/get_build.go (about)

     1  // Copyright 2020 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ledcmd
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"net/http"
    21  
    22  	"google.golang.org/protobuf/types/known/fieldmaskpb"
    23  
    24  	bbpb "go.chromium.org/luci/buildbucket/proto"
    25  	"go.chromium.org/luci/common/errors"
    26  	"go.chromium.org/luci/common/logging"
    27  
    28  	"go.chromium.org/luci/led/job"
    29  	"go.chromium.org/luci/led/job/jobcreate"
    30  )
    31  
    32  // GetBuildOpts are the options for GetBuild.
    33  type GetBuildOpts struct {
    34  	BuildbucketHost string
    35  	BuildID         int64
    36  	PinBotID        bool
    37  	PriorityDiff    int
    38  	KitchenSupport  job.KitchenSupport
    39  	RealBuild       bool
    40  	Experiments     map[string]bool
    41  }
    42  
    43  func getBuildJobName(opts GetBuildOpts) string {
    44  	return fmt.Sprintf("get-build %d", opts.BuildID)
    45  }
    46  
    47  // GetBuild retrieves a job Definition from a Buildbucket build.
    48  func GetBuild(ctx context.Context, authClient *http.Client, opts GetBuildOpts) (*job.Definition, error) {
    49  	logging.Infof(ctx, "getting build definition")
    50  
    51  	if opts.RealBuild {
    52  		return synthesizeBuildFromTemplate(ctx, authClient, opts)
    53  	}
    54  
    55  	bbClient := newBuildbucketClient(authClient, opts.BuildbucketHost)
    56  
    57  	answer, err := bbClient.GetBuild(ctx, &bbpb.GetBuildRequest{
    58  		Id: opts.BuildID,
    59  		Mask: &bbpb.BuildMask{
    60  			Fields: &fieldmaskpb.FieldMask{
    61  				Paths: []string{
    62  					"builder",
    63  					"infra",
    64  					"input",
    65  					"scheduling_timeout",
    66  					"execution_timeout",
    67  					"grace_period",
    68  					"exe",
    69  					"tags",
    70  				},
    71  			},
    72  		},
    73  	})
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	if answer.Infra.GetBuildbucket().GetAgent().GetOutput() != nil {
    79  		answer.Infra.Buildbucket.Agent.Output = nil
    80  	}
    81  
    82  	logging.Infof(ctx, "getting build definition: done")
    83  
    84  	swarmingTaskID := answer.Infra.Swarming.GetTaskId()
    85  	swarmingHostname := answer.Infra.Swarming.GetHostname()
    86  
    87  	if swarmingTaskID == "" {
    88  		return nil, errors.New("unable to find swarming task ID on buildbucket task")
    89  	}
    90  	if swarmingHostname == "" {
    91  		return nil, errors.New("unable to find swarming hostname on buildbucket task")
    92  	}
    93  
    94  	return GetFromSwarmingTask(ctx, authClient, answer, GetFromSwarmingTaskOpts{
    95  		SwarmingHost:   swarmingHostname,
    96  		TaskID:         swarmingTaskID,
    97  		PinBotID:       opts.PinBotID,
    98  		Name:           getBuildJobName(opts),
    99  		PriorityDiff:   opts.PriorityDiff,
   100  		KitchenSupport: opts.KitchenSupport,
   101  	})
   102  }
   103  
   104  func synthesizeBuildFromTemplate(ctx context.Context, authClient *http.Client, opts GetBuildOpts) (*job.Definition, error) {
   105  	bbClient := newBuildbucketClient(authClient, opts.BuildbucketHost)
   106  	build, err := bbClient.SynthesizeBuild(ctx, &bbpb.SynthesizeBuildRequest{
   107  		TemplateBuildId: opts.BuildID,
   108  		Experiments:     opts.Experiments,
   109  	})
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  	return jobcreate.FromBuild(build, opts.BuildbucketHost, getBuildJobName(opts), opts.PriorityDiff, nil), nil
   114  }