go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/rpc/v0/runs.go (about) 1 // Copyright 2021 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 rpc 16 17 import ( 18 "context" 19 20 "google.golang.org/grpc/codes" 21 22 "go.chromium.org/luci/grpc/appstatus" 23 24 apiv0pb "go.chromium.org/luci/cv/api/v0" 25 "go.chromium.org/luci/cv/internal/common" 26 "go.chromium.org/luci/cv/internal/rpc/versioning" 27 "go.chromium.org/luci/cv/internal/run" 28 ) 29 30 // RunsServer implements the v0 API. 31 type RunsServer struct { 32 apiv0pb.UnimplementedRunsServer 33 } 34 35 // populateRunResponse constructs and populates a apiv0pb.Run to use in a response. 36 func populateRunResponse(ctx context.Context, r *run.Run) (resp *apiv0pb.Run, err error) { 37 rcls, err := run.LoadRunCLs(ctx, r.ID, r.CLs) 38 if err != nil { 39 return nil, appstatus.Attachf(err, codes.Internal, "failed to load cls of the run") 40 } 41 gcls := make([]*apiv0pb.GerritChange, len(rcls)) 42 sCLSet := common.MakeCLIDsSet(r.Submission.GetSubmittedCls()...) 43 fCLSet := common.MakeCLIDsSet(r.Submission.GetFailedCls()...) 44 sCLIndexes := make([]int32, 0, len(fCLSet)) 45 fCLIndexes := make([]int32, 0, len(sCLSet)) 46 47 for i, rcl := range rcls { 48 host, change, err := rcl.ExternalID.ParseGobID() 49 switch { 50 case err != nil: 51 return nil, appstatus.Attachf(err, codes.Unimplemented, "only Gerrit CL is supported") 52 case sCLSet.Has(rcl.ID): 53 sCLIndexes = append(sCLIndexes, int32(i)) 54 case fCLSet.Has(rcl.ID): 55 fCLIndexes = append(fCLIndexes, int32(i)) 56 } 57 gcls[i] = &apiv0pb.GerritChange{ 58 Host: host, 59 Change: change, 60 Patchset: rcl.Detail.GetPatchset(), 61 } 62 } 63 64 var submission *apiv0pb.Run_Submission 65 if len(sCLIndexes) > 0 || len(fCLIndexes) > 0 { 66 submission = &apiv0pb.Run_Submission{ 67 SubmittedClIndexes: sCLIndexes, 68 FailedClIndexes: fCLIndexes, 69 } 70 } 71 72 res := &apiv0pb.Run{ 73 Id: r.ID.PublicID(), 74 Eversion: int64(r.EVersion), 75 Status: versioning.RunStatusV0(r.Status), 76 Mode: string(r.Mode), 77 CreateTime: common.Time2PBNillable(r.CreateTime), 78 StartTime: common.Time2PBNillable(r.StartTime), 79 UpdateTime: common.Time2PBNillable(r.UpdateTime), 80 EndTime: common.Time2PBNillable(r.EndTime), 81 Owner: string(r.Owner), 82 CreatedBy: string(r.CreatedBy), 83 BilledTo: string(r.BilledTo), 84 Cls: gcls, 85 Tryjobs: constructLegacyTryjobs(ctx, r), 86 Submission: submission, 87 } 88 res.TryjobInvocations, err = makeTryjobInvocations(ctx, r) 89 if err != nil { 90 return nil, err 91 } 92 return res, nil 93 } 94 95 func constructLegacyTryjobs(ctx context.Context, r *run.Run) []*apiv0pb.Tryjob { 96 var ret []*apiv0pb.Tryjob 97 for i, execution := range r.Tryjobs.GetState().GetExecutions() { 98 definition := r.Tryjobs.GetState().GetRequirement().GetDefinitions()[i] 99 for _, attempt := range execution.GetAttempts() { 100 tj := &apiv0pb.Tryjob{ 101 Status: versioning.LegacyTryjobStatusV0(attempt.GetStatus()), 102 Critical: definition.GetCritical(), 103 Reuse: attempt.GetReused(), 104 } 105 if result := attempt.GetResult(); result != nil { 106 tj.Result = &apiv0pb.Tryjob_Result{ 107 Status: versioning.LegacyTryjobResultStatusV0(result.GetStatus()), 108 } 109 if bbid := result.GetBuildbucket().GetId(); bbid != 0 { 110 tj.Result.Backend = &apiv0pb.Tryjob_Result_Buildbucket_{ 111 Buildbucket: &apiv0pb.Tryjob_Result_Buildbucket{ 112 Id: bbid, 113 }, 114 } 115 } 116 } 117 ret = append(ret, tj) 118 } 119 } 120 return ret 121 }