Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: milo/common/config.go

Issue 2980153002: Milo: Fix project importer so it doesn't error out on a bad config (Closed)
Patch Set: Review Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | milo/common/config_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. 1 // Copyright 2016 The LUCI Authors.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 package common 15 package common
16 16
17 import ( 17 import (
18 "fmt" 18 "fmt"
19 "time" 19 "time"
20 20
21 "github.com/golang/protobuf/proto" 21 "github.com/golang/protobuf/proto"
22 "golang.org/x/net/context" 22 "golang.org/x/net/context"
23 23
24 "github.com/luci/gae/service/datastore" 24 "github.com/luci/gae/service/datastore"
25 "github.com/luci/gae/service/info" 25 "github.com/luci/gae/service/info"
26 "github.com/luci/luci-go/common/data/caching/proccache" 26 "github.com/luci/luci-go/common/data/caching/proccache"
27 "github.com/luci/luci-go/common/errors"
27 "github.com/luci/luci-go/common/logging" 28 "github.com/luci/luci-go/common/logging"
28 "github.com/luci/luci-go/luci_config/server/cfgclient" 29 "github.com/luci/luci-go/luci_config/server/cfgclient"
29 "github.com/luci/luci-go/luci_config/server/cfgclient/backend" 30 "github.com/luci/luci-go/luci_config/server/cfgclient/backend"
30 "github.com/luci/luci-go/luci_config/server/cfgclient/textproto" 31 "github.com/luci/luci-go/luci_config/server/cfgclient/textproto"
31 32
32 "github.com/luci/luci-go/milo/api/config" 33 "github.com/luci/luci-go/milo/api/config"
33 ) 34 )
34 35
35 // Project is a LUCI project. 36 // Project is a LUCI project.
36 type Project struct { 37 type Project struct {
37 » // The ID of the project, as per self defined. This is not the luci-con fig 38 » // ID of the project, as per self defined. This is the luci-config name .
38 » // name.
39 ID string `gae:"$id"` 39 ID string `gae:"$id"`
40 » // The luci-config name of the project. 40 » // Data is the Project data in protobuf binary format.
41 » Name string
42 » // The Project data in protobuf binary format.
43 Data []byte `gae:",noindex"` 41 Data []byte `gae:",noindex"`
42 // Revision is the latest revision we have of this project's config.
43 Revision string
44 } 44 }
45 45
46 // The key for the service config entity in datastore. 46 // The key for the service config entity in datastore.
47 const ServiceConfigID = "service_config" 47 const ServiceConfigID = "service_config"
48 48
49 // ServiceConfig is a container for the instance's service config. 49 // ServiceConfig is a container for the instance's service config.
50 type ServiceConfig struct { 50 type ServiceConfig struct {
51 // ID is the datastore key. This should be static, as there should only be 51 // ID is the datastore key. This should be static, as there should only be
52 // one service config. 52 // one service config.
53 ID string `gae:"$id"` 53 ID string `gae:"$id"`
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 180
181 // UpdateProjectConfigs internal project configuration based off luci-config. 181 // UpdateProjectConfigs internal project configuration based off luci-config.
182 // update updates Milo's configuration based off luci config. This includes 182 // update updates Milo's configuration based off luci config. This includes
183 // scanning through all project and extract all console configs. 183 // scanning through all project and extract all console configs.
184 func UpdateProjectConfigs(c context.Context) error { 184 func UpdateProjectConfigs(c context.Context) error {
185 cfgName := info.AppID(c) + ".cfg" 185 cfgName := info.AppID(c) + ".cfg"
186 186
187 var ( 187 var (
188 configs []*config.Project 188 configs []*config.Project
189 metas []*cfgclient.Meta 189 metas []*cfgclient.Meta
190 merr errors.MultiError
190 ) 191 )
192
191 logging.Debugf(c, "fetching configs for %s", cfgName) 193 logging.Debugf(c, "fetching configs for %s", cfgName)
192 if err := cfgclient.Projects(c, cfgclient.AsService, cfgName, textproto. Slice(&configs), &metas); err != nil { 194 if err := cfgclient.Projects(c, cfgclient.AsService, cfgName, textproto. Slice(&configs), &metas); err != nil {
193 » » logging.WithError(err).Errorf(c, "Encountered error while gettin g project config for %s", cfgName) 195 » » merr = err.(errors.MultiError)
194 » » return err 196 » » // Some configs errored out, but we can continue with the ones t hat work still.
195 } 197 }
196 198
197 // A map of project ID to project. 199 // A map of project ID to project.
198 projects := map[string]*Project{} 200 projects := map[string]*Project{}
199 for i, proj := range configs { 201 for i, proj := range configs {
200 » » projectName, _, _ := metas[i].ConfigSet.SplitProject() 202 » » meta := metas[i]
203 » » projectName, _, _ := meta.ConfigSet.SplitProject()
204 » » name := string(projectName)
205 » » projects[name] = nil
206 » » if merr != nil && merr[i] != nil {
207 » » » logging.WithError(merr[i]).Warningf(c, "skipping %s due to error", name)
208 » » » continue
209 » » }
201 210
202 » » logging.Infof(c, "Prossing %s", projectName) 211 » » p := &Project{
203 » » if dup, ok := projects[proj.ID]; ok { 212 » » » ID: name,
204 » » » return fmt.Errorf( 213 » » » Revision: meta.Revision,
205 » » » » "Duplicate project ID: %s. (%s and %s)", proj.ID , dup.Name, projectName)
206 } 214 }
207 » » p := &Project{ 215
208 » » » ID: proj.ID, 216 » » logging.Infof(c, "prossing %s", name)
209 » » » Name: string(projectName),
210 » » }
211 » » projects[proj.ID] = p
212 217
213 var err error 218 var err error
214 p.Data, err = proto.Marshal(proj) 219 p.Data, err = proto.Marshal(proj)
215 if err != nil { 220 if err != nil {
216 » » » return err 221 » » » logging.WithError(err).Errorf(c, "Encountered error whil e processing project %s", name)
222 » » » // Set this to nil to signal this project exists but we don't want to update it.
223 » » » projects[name] = nil
224 » » » continue
217 } 225 }
226 projects[name] = p
218 } 227 }
219 228
220 // Now load all the data into the datastore. 229 // Now load all the data into the datastore.
221 projs := make([]*Project, 0, len(projects)) 230 projs := make([]*Project, 0, len(projects))
222 for _, proj := range projects { 231 for _, proj := range projects {
223 » » projs = append(projs, proj) 232 » » if proj != nil {
233 » » » projs = append(projs, proj)
234 » » }
224 } 235 }
225 if err := datastore.Put(c, projs); err != nil { 236 if err := datastore.Put(c, projs); err != nil {
226 return err 237 return err
227 } 238 }
228 239
229 // Delete entries that no longer exist. 240 // Delete entries that no longer exist.
230 q := datastore.NewQuery("Project").KeysOnly(true) 241 q := datastore.NewQuery("Project").KeysOnly(true)
231 allProjs := []Project{} 242 allProjs := []Project{}
232 datastore.GetAll(c, q, &allProjs) 243 datastore.GetAll(c, q, &allProjs)
233 toDelete := []Project{} 244 toDelete := []Project{}
234 for _, proj := range allProjs { 245 for _, proj := range allProjs {
235 if _, ok := projects[proj.ID]; !ok { 246 if _, ok := projects[proj.ID]; !ok {
236 toDelete = append(toDelete, proj) 247 toDelete = append(toDelete, proj)
237 } 248 }
238 } 249 }
239 » datastore.Delete(c, toDelete) 250 » return datastore.Delete(c, toDelete)
240
241 » return nil
242 } 251 }
243 252
244 // GetAllProjects returns all registered projects. 253 // GetAllProjects returns all registered projects.
245 func GetAllProjects(c context.Context) ([]*config.Project, error) { 254 func GetAllProjects(c context.Context) ([]*config.Project, error) {
246 q := datastore.NewQuery("Project") 255 q := datastore.NewQuery("Project")
247 q.Order("ID") 256 q.Order("ID")
248 257
249 ps := []*Project{} 258 ps := []*Project{}
250 err := datastore.GetAll(c, q, &ps) 259 err := datastore.GetAll(c, q, &ps)
251 if err != nil { 260 if err != nil {
(...skipping 30 matching lines...) Expand all
282 if err != nil { 291 if err != nil {
283 return nil, err 292 return nil, err
284 } 293 }
285 for _, cs := range p.Consoles { 294 for _, cs := range p.Consoles {
286 if cs.Name == consoleName { 295 if cs.Name == consoleName {
287 return cs, nil 296 return cs, nil
288 } 297 }
289 } 298 }
290 return nil, fmt.Errorf("Console %s not found in project %s", consoleName , projName) 299 return nil, fmt.Errorf("Console %s not found in project %s", consoleName , projName)
291 } 300 }
OLDNEW
« no previous file with comments | « no previous file | milo/common/config_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698