| OLD | NEW |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 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 gaeconfig | 5 package gaeconfig |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "errors" | 8 "errors" |
| 9 "fmt" | 9 "fmt" |
| 10 "os" | 10 "os" |
| 11 "path/filepath" | 11 "path/filepath" |
| 12 "time" | 12 "time" |
| 13 | 13 |
| 14 "github.com/luci/luci-go/common/config/impl/filesystem" | 14 "github.com/luci/luci-go/common/config/impl/filesystem" |
| 15 "github.com/luci/luci-go/luci_config/appengine/backend/datastore" |
| 15 "github.com/luci/luci-go/luci_config/appengine/backend/memcache" | 16 "github.com/luci/luci-go/luci_config/appengine/backend/memcache" |
| 16 gaeformat "github.com/luci/luci-go/luci_config/appengine/format" | 17 gaeformat "github.com/luci/luci-go/luci_config/appengine/format" |
| 17 "github.com/luci/luci-go/luci_config/server/cfgclient/backend" | 18 "github.com/luci/luci-go/luci_config/server/cfgclient/backend" |
| 18 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/caching" | 19 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/caching" |
| 19 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/client" | 20 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/client" |
| 20 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/erroring" | 21 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/erroring" |
| 21 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/format" | 22 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/format" |
| 22 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/testconfig
" | 23 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/testconfig
" |
| 24 "github.com/luci/luci-go/server/router" |
| 23 | 25 |
| 24 "github.com/luci/gae/service/info" | 26 "github.com/luci/gae/service/info" |
| 25 | 27 |
| 26 "golang.org/x/net/context" | 28 "golang.org/x/net/context" |
| 27 ) | 29 ) |
| 28 | 30 |
| 29 // ErrNotConfigured is returned by cfgclient methods if the config service URL | 31 // ErrNotConfigured is returned by cfgclient methods if the config service URL |
| 30 // is not set. Usually happens for new apps. | 32 // is not set. Usually happens for new apps. |
| 31 var ErrNotConfigured = errors.New("config service URL is not set in settings") | 33 var ErrNotConfigured = errors.New("config service URL is not set in settings") |
| 32 | 34 |
| 33 // devCfgDir is a name of the directory with config files when running in | 35 // devCfgDir is a name of the directory with config files when running in |
| 34 // local dev appserver model. See New for details. | 36 // local dev appserver model. See New for details. |
| 35 const devCfgDir = "devcfg" | 37 const devCfgDir = "devcfg" |
| 36 | 38 |
| 39 // InstallCacheCronHandler installs the configuration service datastore caching |
| 40 // cron handler. This must be installed, and an associated cron must be set up, |
| 41 // if datastore caching is enabled. |
| 42 // |
| 43 // The cron should be configured to hit the handler at: |
| 44 // /admin/config/cache/manager |
| 45 func InstallCacheCronHandler(r *router.Router, base router.MiddlewareChain) { |
| 46 installCacheCronHandlerImpl(r, base, nil) |
| 47 } |
| 48 |
| 49 // Install our cache cron handler into the supplied Router. |
| 50 // |
| 51 // bf is a generator function used to get the primary (service) Backend to build |
| 52 // on top of. If nil, the "production" (one used by Use) Backend will be used. |
| 53 func installCacheCronHandlerImpl(r *router.Router, base router.MiddlewareChain,
be backend.B) { |
| 54 base = base.Extend(func(c *router.Context, next router.Handler) { |
| 55 // Install our Backend into our Context. |
| 56 c.Context = installConfigBackend(c.Context, mustFetchCachedSetti
ngs(c.Context), be, true) |
| 57 next(c) |
| 58 }) |
| 59 |
| 60 datastore.Cache.InstallCronRoute("/admin/config/cache/manager", r, base) |
| 61 } |
| 62 |
| 37 // Use installs the default luci-config client. | 63 // Use installs the default luci-config client. |
| 38 // | 64 // |
| 39 // The client is configured to use luci-config URL specified in the settings, | 65 // The client is configured to use luci-config URL specified in the settings, |
| 40 // using GAE app service account for authentication. | 66 // using GAE app service account for authentication. |
| 41 // | 67 // |
| 42 // If running in prod, and the settings don't specify luci-config URL, produces | 68 // If running in prod, and the settings don't specify luci-config URL, produces |
| 43 // an implementation of backend.B that returns ErrNotConfigured from all | 69 // an implementation of backend.B that returns ErrNotConfigured from all |
| 44 // methods. | 70 // methods. |
| 45 // | 71 // |
| 46 // If running on devserver, and the settings don't specify luci-config URL, | 72 // If running on devserver, and the settings don't specify luci-config URL, |
| 47 // returns a filesystem-based implementation that reads configs from a directory | 73 // returns a filesystem-based implementation that reads configs from a directory |
| 48 // (or a symlink) named 'devcfg' located in the GAE module directory (where | 74 // (or a symlink) named 'devcfg' located in the GAE module directory (where |
| 49 // app.yaml is) or its immediate parent directory. | 75 // app.yaml is) or its immediate parent directory. |
| 50 // | 76 // |
| 51 // If such directory can not be located, produces an implementation of | 77 // If such directory can not be located, produces an implementation of |
| 52 // cfgclient that returns errors from all methods. | 78 // cfgclient that returns errors from all methods. |
| 53 // | 79 // |
| 54 // Panics if it can't load the settings (should not happen since they are in | 80 // Panics if it can't load the settings (should not happen since they are in |
| 55 // the local memory cache usually). | 81 // the local memory cache usually). |
| 56 func Use(c context.Context) context.Context { return useImpl(c, nil) } | 82 func Use(c context.Context) context.Context { return useImpl(c, nil) } |
| 57 | 83 |
| 58 func useImpl(c context.Context, be backend.B) context.Context { | 84 func useImpl(c context.Context, be backend.B) context.Context { |
| 59 » return installConfigBackend(c, mustFetchCachedSettings(c), be) | 85 » return installConfigBackend(c, mustFetchCachedSettings(c), be, false) |
| 60 } | 86 } |
| 61 | 87 |
| 62 func installConfigBackend(c context.Context, s *Settings, be backend.B) context.
Context { | 88 func installConfigBackend(c context.Context, s *Settings, be backend.B, dsCron b
ool) context.Context { |
| 63 if be == nil { | 89 if be == nil { |
| 64 // Non-testing, build a Backend. | 90 // Non-testing, build a Backend. |
| 65 be = getPrimaryBackend(c, s) | 91 be = getPrimaryBackend(c, s) |
| 66 } | 92 } |
| 67 | 93 |
| 68 // Install a FormatRegistry. Register common config service protobufs wi
th it. | 94 // Install a FormatRegistry. Register common config service protobufs wi
th it. |
| 69 c = gaeformat.WithRegistry(c, gaeformat.Default()) | 95 c = gaeformat.WithRegistry(c, gaeformat.Default()) |
| 70 | 96 |
| 71 be = &format.Backend{ | 97 be = &format.Backend{ |
| 72 B: be, | 98 B: be, |
| 73 GetRegistry: gaeformat.GetRegistry, | 99 GetRegistry: gaeformat.GetRegistry, |
| 74 } | 100 } |
| 75 | 101 |
| 76 // Apply caching configuration. | 102 // Apply caching configuration. |
| 77 exp := time.Duration(s.CacheExpirationSec) * time.Second | 103 exp := time.Duration(s.CacheExpirationSec) * time.Second |
| 78 if exp > 0 { | 104 if exp > 0 { |
| 79 // Add a ProcCache, backed by memcache. | 105 // Add a ProcCache, backed by memcache. |
| 80 be = memcache.Backend(be, exp) | 106 be = memcache.Backend(be, exp) |
| 81 be = caching.ProcCache(be, exp) | 107 be = caching.ProcCache(be, exp) |
| 108 |
| 109 // If our datastore cache is enabled, install a handler for refr
esh. This |
| 110 // will be loaded by dsCache's "HandlerFunc". |
| 111 if s.DatastoreCacheMode != dsCacheDisabled { |
| 112 dsc := datastore.Config{ |
| 113 RefreshInterval: exp, |
| 114 FailOpen: s.DatastoreCacheMode == dsCache
Enabled, |
| 115 } |
| 116 |
| 117 if !dsCron { |
| 118 // For non-cron, install the datastore cache Bac
kend. |
| 119 be = dsc.Backend(be) |
| 120 } else { |
| 121 // For cron, do not install the datastore cache
Backend. Instead, |
| 122 // install a lasting Handler into the Context to
be used for cache |
| 123 // resolution. This is necessary since resolutio
n calls will not be |
| 124 // the result of an actual resolution command (e
.g., cache.Get). |
| 125 c = dsc.WithHandler(c, datastore.CronLoader(be),
datastore.RPCDeadline) |
| 126 } |
| 127 } |
| 82 } | 128 } |
| 83 | 129 |
| 84 c = backend.WithBackend(c, be) | 130 c = backend.WithBackend(c, be) |
| 85 return c | 131 return c |
| 86 } | 132 } |
| 87 | 133 |
| 88 func getPrimaryBackend(c context.Context, settings *Settings) backend.B { | 134 func getPrimaryBackend(c context.Context, settings *Settings) backend.B { |
| 89 // Identify our config service backend (in testing, it will be supplied)
. | 135 // Identify our config service backend (in testing, it will be supplied)
. |
| 90 if settings.ConfigServiceURL == "" { | 136 if settings.ConfigServiceURL == "" { |
| 91 if info.IsDevAppServer(c) { | 137 if info.IsDevAppServer(c) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 113 if err != nil { | 159 if err != nil { |
| 114 return erroring.New(err) | 160 return erroring.New(err) |
| 115 } | 161 } |
| 116 return &client.Backend{&testconfig.Provider{ | 162 return &client.Backend{&testconfig.Provider{ |
| 117 Base: fs, | 163 Base: fs, |
| 118 }} | 164 }} |
| 119 } | 165 } |
| 120 } | 166 } |
| 121 return erroring.New(fmt.Errorf("luci-config: could not find local config
s in any of %s", candidates)) | 167 return erroring.New(fmt.Errorf("luci-config: could not find local config
s in any of %s", candidates)) |
| 122 } | 168 } |
| OLD | NEW |