go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/config_service/internal/settings/globalconfig.go (about) 1 // Copyright 2023 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 settings contains global settings for starting a Config Server. 16 package settings 17 18 import ( 19 "context" 20 "flag" 21 "fmt" 22 "regexp" 23 24 "go.chromium.org/luci/common/data/text" 25 "go.chromium.org/luci/common/errors" 26 cfgcommonpb "go.chromium.org/luci/common/proto/config" 27 28 "go.chromium.org/luci/config_service/internal/common" 29 ) 30 31 var globalConfigLocRegex = regexp.MustCompile(`^gitiles\((.*),(.*),(.*)\)$`) 32 33 // GlobalConfigLoc is a setting to indicate the global config root location. 34 type GlobalConfigLoc struct { 35 *cfgcommonpb.GitilesLocation 36 } 37 38 // RegisterFlags registers "-global-config-location" into command line flag set. 39 func (l *GlobalConfigLoc) RegisterFlags(fs *flag.FlagSet) { 40 fs.TextVar(l, "global-config-location", &GlobalConfigLoc{}, text.Doc(` 41 A string representation of luci.common.proto.config.GitilesLocation object 42 which points to the root of service configs directory. The format should be 43 'gitiles(<repo>,<ref>,<path>)' 44 `)) 45 } 46 47 // UnmarshalText unmarshal a textual representation of GlobalConfigLoc. 48 // Implements encoding.TextUnmarshaler. 49 func (l *GlobalConfigLoc) UnmarshalText(text []byte) error { 50 if len(text) == 0 { 51 l.GitilesLocation = nil 52 return nil 53 } 54 55 matches := globalConfigLocRegex.FindStringSubmatch(string(text)) 56 if len(matches) == 0 { 57 return errors.Reason(`does not match regex "%s"`, globalConfigLocRegex).Err() 58 } 59 60 l.GitilesLocation = &cfgcommonpb.GitilesLocation{ 61 Repo: matches[1], 62 Ref: matches[2], 63 Path: matches[3], 64 } 65 return nil 66 } 67 68 // MarshalText marshal itself into a textual form. 69 // Implements encoding.TextMarshaler. 70 func (l *GlobalConfigLoc) MarshalText() (text []byte, err error) { 71 if l.GitilesLocation == nil { 72 return nil, nil 73 } 74 return []byte(fmt.Sprintf("gitiles(%s,%s,%s)", l.Repo, l.Ref, l.Path)), nil 75 } 76 77 // Validate validates the GlobalConfigLoc 78 func (l *GlobalConfigLoc) Validate() error { 79 return common.ValidateGitilesLocation(l.GitilesLocation) 80 } 81 82 var globalConfigLocKey = "holds the global config location" 83 84 // WithGlobalConfigLoc returns a context with the given config location. 85 func WithGlobalConfigLoc(ctx context.Context, location *cfgcommonpb.GitilesLocation) context.Context { 86 return context.WithValue(ctx, &globalConfigLocKey, location) 87 } 88 89 // GetGlobalConfigLoc returns a GitilesLocation installed in the context. 90 func GetGlobalConfigLoc(ctx context.Context) *cfgcommonpb.GitilesLocation { 91 return ctx.Value(&globalConfigLocKey).(*cfgcommonpb.GitilesLocation) 92 }