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

Side by Side Diff: logdog/appengine/coordinator/config/projects.go

Issue 2575383002: Add server/cache support to gaeconfig. (Closed)
Patch Set: Un-collapse. Created 3 years, 11 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 | « logdog/appengine/coordinator/config/config.go ('k') | logdog/appengine/coordinator/context.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 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package config 5 package config
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 » "strings" 9 » "sort"
10 10
11 "github.com/luci/gae/service/info"
12 "github.com/luci/luci-go/common/config"
13 log "github.com/luci/luci-go/common/logging" 11 log "github.com/luci/luci-go/common/logging"
14 "github.com/luci/luci-go/logdog/api/config/svcconfig" 12 "github.com/luci/luci-go/logdog/api/config/svcconfig"
15 "github.com/luci/luci-go/luci_config/common/cfgtypes" 13 "github.com/luci/luci-go/luci_config/common/cfgtypes"
14 "github.com/luci/luci-go/luci_config/server/cfgclient"
15 "github.com/luci/luci-go/luci_config/server/cfgclient/textproto"
16 16
17 "github.com/golang/protobuf/proto"
18 "golang.org/x/net/context" 17 "golang.org/x/net/context"
19 ) 18 )
20 19
21 const maxProjectWorkers = 32
22
23 // ProjectConfigPath returns the path of the project-specific configuration. 20 // ProjectConfigPath returns the path of the project-specific configuration.
24 // This path should be used with a project config set. 21 // This path should be used with a project config set.
25 // 22 //
26 // A given project's configuration is named after the current App ID. 23 // A given project's configuration is named after the current App ID.
27 func ProjectConfigPath(c context.Context) string { 24 func ProjectConfigPath(c context.Context) string {
28 » return fmt.Sprintf("%s.cfg", info.AppID(c)) 25 » return fmt.Sprintf("%s.cfg", cfgclient.CurrentServiceName(c))
29 } 26 }
30 27
31 // ProjectConfig loads the project config protobuf from the config service. 28 // ProjectConfig loads the project config protobuf from the config service.
32 // 29 //
33 // This function will return: 30 // This function will return:
34 // - nil, if the project exists and the configuration successfully loaded 31 // - nil, if the project exists and the configuration successfully loaded
35 // - config.ErrNoConfig if the project configuration was not present. 32 // - config.ErrNoConfig if the project configuration was not present.
36 // - ErrInvalidConfig if the project configuration was present, but could n ot 33 // - ErrInvalidConfig if the project configuration was present, but could n ot
37 // be loaded. 34 // be loaded.
38 // - Some other error if an error occurred that does not fit one of the 35 // - Some other error if an error occurred that does not fit one of the
39 // previous categories. 36 // previous categories.
40 func ProjectConfig(c context.Context, project cfgtypes.ProjectName) (*svcconfig. ProjectConfig, error) { 37 func ProjectConfig(c context.Context, project cfgtypes.ProjectName) (*svcconfig. ProjectConfig, error) {
41 if project == "" { 38 if project == "" {
42 » » return nil, config.ErrNoConfig 39 » » return nil, cfgclient.ErrNoConfig
43 } 40 }
44 41
45 // Get the config from the config service. If the configuration doesn't exist, 42 // Get the config from the config service. If the configuration doesn't exist,
46 » // this will return config.ErrNoConfig. 43 » // this will return cfgclient.ErrNoConfig.
47 configSet, configPath := cfgtypes.ProjectConfigSet(project), ProjectConf igPath(c) 44 configSet, configPath := cfgtypes.ProjectConfigSet(project), ProjectConf igPath(c)
48 » cfg, err := config.GetConfig(c, string(configSet), configPath, false) 45
49 » if err != nil { 46 » var pcfg svcconfig.ProjectConfig
47 » if err := cfgclient.Get(c, cfgclient.AsService, configSet, configPath, t extproto.Message(&pcfg), nil); err != nil {
50 log.Fields{ 48 log.Fields{
51 log.ErrorKey: err, 49 log.ErrorKey: err,
52 "project": project, 50 "project": project,
53 "configSet": configSet, 51 "configSet": configSet,
54 "configPath": configPath, 52 "configPath": configPath,
55 }.Errorf(c, "Failed to load project configuration content.") 53 }.Errorf(c, "Failed to load project configuration content.")
56 return nil, err 54 return nil, err
57 } 55 }
58 56 » return &pcfg, nil
59 » pcfg, err := unmarshalProjectConfig(cfg)
60 » if err != nil {
61 » » log.Fields{
62 » » » log.ErrorKey: err,
63 » » » "project": project,
64 » » » "configSet": cfg.ConfigSet,
65 » » » "path": cfg.Path,
66 » » » "contentHash": cfg.ContentHash,
67 » » }.Errorf(c, "Failed to unmarshal project configuration.")
68 » » return nil, ErrInvalidConfig
69 » }
70 » return pcfg, nil
71 } 57 }
72 58
73 // AllProjectConfigs returns the project configurations for all projects that 59 // ProjectNames returns a sorted list of the names of all of the projects
74 // have a configuration. 60 // that the supplied authority can view.
75 // 61 func ProjectNames(c context.Context, a cfgclient.Authority) ([]cfgtypes.ProjectN ame, error) {
76 // If a project's configuration fails to load, an error will be logged and the 62 » configPath := ProjectConfigPath(c)
77 // project will be omitted from the output map. 63
78 func AllProjectConfigs(c context.Context) (map[cfgtypes.ProjectName]*svcconfig.P rojectConfig, error) { 64 » var metas []*cfgclient.Meta
79 » // TODO: This endpoint is generally slow. Even though there is memcache- based 65 » if err := cfgclient.Projects(c, a, configPath, nil, &metas); err != nil {
80 » // config cache, this really should be loaded from a more failsafe cache like
81 » // datastore to protect against config service outages.
82 » configs, err := config.GetProjectConfigs(c, ProjectConfigPath(c), false)
83 » if err != nil {
84 log.WithError(err).Errorf(c, "Failed to load project configs.") 66 log.WithError(err).Errorf(c, "Failed to load project configs.")
85 return nil, err 67 return nil, err
86 } 68 }
87 69
88 » result := make(map[cfgtypes.ProjectName]*svcconfig.ProjectConfig, len(co nfigs)) 70 » // Iterate through our Metas and extract the project names.
89 » for _, cfg := range configs { 71 » projects := make([]cfgtypes.ProjectName, 0, len(metas))
90 » » // Identify the project by removng the "projects/" prefix. 72 » for _, meta := range metas {
91 » » project := cfgtypes.ProjectName(strings.TrimPrefix(cfg.ConfigSet , "projects/")) 73 » » projectName, _, _ := meta.ConfigSet.SplitProject()
92 » » if err := project.Validate(); err != nil { 74 » » if projectName != "" {
93 » » » log.Fields{ 75 » » » projects = append(projects, projectName)
94 » » » » log.ErrorKey: err,
95 » » » » "configSet": cfg.ConfigSet,
96 » » » }.Errorf(c, "Invalid project name returned.")
97 » » » continue
98 } 76 }
99
100 // Unmarshal the project's configuration.
101 pcfg, err := unmarshalProjectConfig(&cfg)
102 if err != nil {
103 log.Fields{
104 log.ErrorKey: err,
105 "configSet": cfg.ConfigSet,
106 "path": cfg.Path,
107 "contentHash": cfg.ContentHash,
108 }.Errorf(c, "Failed to unmarshal project configuration." )
109 continue
110 }
111
112 result[project] = pcfg
113 } 77 }
114 » return result, nil 78 » sort.Sort(projectNameSlice(projects))
79 » return projects, nil
115 } 80 }
116 81
117 func unmarshalProjectConfig(cfg *config.Config) (*svcconfig.ProjectConfig, error ) { 82 // ActiveProjects returns a full list of all config service projects with
118 » var pcfg svcconfig.ProjectConfig 83 // LogDog project configurations.
119 » if err := proto.UnmarshalText(cfg.Content, &pcfg); err != nil { 84 //
120 » » return nil, err 85 // The list will be alphabetically sorted.
121 » } 86 func ActiveProjects(c context.Context) ([]cfgtypes.ProjectName, error) {
122 » return &pcfg, nil 87 » return ProjectNames(c, cfgclient.AsService)
123 } 88 }
89
90 // ActiveUserProjects returns a full list of all config service projects with
91 // LogDog project configurations that the current user can see.
92 //
93 // The list will be alphabetically sorted.
94 func ActiveUserProjects(c context.Context) ([]cfgtypes.ProjectName, error) {
95 return ProjectNames(c, cfgclient.AsUser)
96 }
97
98 type projectNameSlice []cfgtypes.ProjectName
99
100 func (s projectNameSlice) Len() int { return len(s) }
101 func (s projectNameSlice) Less(i, j int) bool { return s[i] < s[j] }
102 func (s projectNameSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
OLDNEW
« no previous file with comments | « logdog/appengine/coordinator/config/config.go ('k') | logdog/appengine/coordinator/context.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698