go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/led/job/info_swarming.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 job 16 17 import ( 18 "reflect" 19 "time" 20 21 "google.golang.org/protobuf/proto" 22 23 "go.chromium.org/luci/common/errors" 24 swarmingpb "go.chromium.org/luci/swarming/proto/api_v2" 25 ) 26 27 type swInfo struct { 28 *Swarming 29 } 30 31 var _ Info = swInfo{} 32 33 func (s swInfo) SwarmingHostname() string { 34 return s.GetHostname() 35 } 36 37 func (s swInfo) TaskName() string { 38 return s.GetTask().GetName() 39 } 40 41 func (s swInfo) CurrentIsolated() (*swarmingpb.CASReference, error) { 42 casOptions := map[string]*swarmingpb.CASReference{} 43 if p := s.GetCasUserPayload(); p.GetDigest().GetHash() != "" { 44 casOptions[p.Digest.Hash] = p 45 } 46 47 if sw := s.Swarming; sw != nil { 48 for _, slc := range sw.GetTask().GetTaskSlices() { 49 input := slc.GetProperties().GetCasInputRoot() 50 if input != nil { 51 casOptions[input.Digest.GetHash()] = input 52 } 53 } 54 } 55 if len(casOptions) > 1 { 56 return nil, errors.Reason( 57 "Definition contains multiple RBE-CAS inputs: %v", casOptions).Err() 58 } 59 for _, v := range casOptions { 60 return proto.Clone(v).(*swarmingpb.CASReference), nil 61 } 62 return nil, nil 63 } 64 65 func (s swInfo) Dimensions() (ExpiringDimensions, error) { 66 ldims := logicalDimensions{} 67 var totalExpiration time.Duration 68 for _, slc := range s.GetTask().GetTaskSlices() { 69 exp := time.Duration(slc.ExpirationSecs) * time.Second 70 totalExpiration += exp 71 72 for _, dim := range slc.GetProperties().GetDimensions() { 73 ldims.updateDuration(dim.Key, dim.Value, totalExpiration) 74 } 75 } 76 return ldims.toExpiringDimensions(), nil 77 } 78 79 func (s swInfo) CIPDPkgs() (ret CIPDPkgs, err error) { 80 slices := s.GetTask().GetTaskSlices() 81 if len(slices) >= 1 { 82 if pkgs := slices[0].GetProperties().GetCipdInput().GetPackages(); len(pkgs) > 0 { 83 ret = CIPDPkgs{} 84 ret.fromList(pkgs) 85 } 86 } 87 if len(slices) > 1 { 88 for idx, slc := range slices[1:] { 89 pkgDict := CIPDPkgs{} 90 pkgDict.fromList(slc.GetProperties().GetCipdInput().GetPackages()) 91 if !ret.equal(pkgDict) { 92 return nil, errors.Reason( 93 "slice %d has cipd pkgs which differ from slice 0: %v vs %v", 94 idx+1, pkgDict, ret).Err() 95 } 96 } 97 } 98 return 99 } 100 101 func (s swInfo) Env() (ret map[string]string, err error) { 102 slices := s.GetTask().GetTaskSlices() 103 extractEnv := func(slc *swarmingpb.TaskSlice) (slcEnv map[string]string) { 104 if env := slices[0].GetProperties().GetEnv(); len(env) > 0 { 105 slcEnv = make(map[string]string, len(env)) 106 for _, pair := range env { 107 slcEnv[pair.Key] = pair.Value 108 } 109 } 110 return 111 } 112 113 if len(slices) >= 1 { 114 ret = extractEnv(slices[0]) 115 116 for idx, slc := range slices[1:] { 117 if slcEnv := extractEnv(slc); !reflect.DeepEqual(ret, slcEnv) { 118 return nil, errors.Reason( 119 "slice %d has env which differs from slice 0: %v vs %v", 120 idx+1, slcEnv, ret).Err() 121 } 122 } 123 } 124 return 125 } 126 127 func (s swInfo) Priority() int32 { 128 return s.GetTask().GetPriority() 129 } 130 131 func (s swInfo) PrefixPathEnv() (ret []string, err error) { 132 slices := s.GetTask().GetTaskSlices() 133 if len(slices) >= 1 { 134 for _, keyVals := range slices[0].GetProperties().GetEnvPrefixes() { 135 if keyVals.Key == "PATH" { 136 ret = make([]string, len(keyVals.Value)) 137 copy(ret, keyVals.Value) 138 break 139 } 140 } 141 } 142 if len(slices) > 1 { 143 for idx, slc := range slices[1:] { 144 foundIt := false 145 for _, keyVal := range slc.GetProperties().GetEnvPrefixes() { 146 if keyVal.Key == "PATH" { 147 foundIt = true 148 if !reflect.DeepEqual(ret, keyVal.Value) { 149 return nil, errors.Reason( 150 "slice %d has $PATH env prefixes which differ from slice 0: %v vs %v", 151 idx+1, keyVal.Value, ret).Err() 152 } 153 break 154 } 155 } 156 if !foundIt && len(ret) > 0 { 157 return nil, errors.Reason( 158 "slice %d has $PATH env prefixes which differ from slice 0: %v vs %v", 159 idx+1, []string{}, ret).Err() 160 } 161 } 162 } 163 return 164 } 165 166 func (s swInfo) Tags() (ret []string) { 167 if tags := s.GetTask().GetTags(); len(tags) > 0 { 168 ret = make([]string, len(tags)) 169 copy(ret, tags) 170 } 171 return 172 }