context: remove definition of Context

Back in the before time, the best practices surrounding usage of Context
weren't quite worked out. We defined our own type to make usage easier.
As this packaged was used elsewhere, it make it more and more
challenging to integrate with the forked `Context` type. Now that it is
available in the standard library, we can just use that one directly.

To make usage more consistent, we now use `dcontext` when referring to
the distribution context package.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day
2017-08-11 15:31:16 -07:00
parent 7a8efe719e
commit 9c88801a12
90 changed files with 396 additions and 373 deletions

View File

@@ -1,6 +1,7 @@
package handlers
import (
"context"
cryptorand "crypto/rand"
"expvar"
"fmt"
@@ -16,7 +17,7 @@ import (
"github.com/docker/distribution"
"github.com/docker/distribution/configuration"
ctxu "github.com/docker/distribution/context"
dcontext "github.com/docker/distribution/context"
"github.com/docker/distribution/health"
"github.com/docker/distribution/health/checks"
"github.com/docker/distribution/notifications"
@@ -37,8 +38,7 @@ import (
"github.com/docker/libtrust"
"github.com/garyburd/redigo/redis"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"github.com/sirupsen/logrus"
)
// randomSecretSize is the number of random bytes to generate if no secret
@@ -145,7 +145,7 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App {
}
}
startUploadPurger(app, app.driver, ctxu.GetLogger(app), purgeConfig)
startUploadPurger(app, app.driver, dcontext.GetLogger(app), purgeConfig)
app.driver, err = applyStorageMiddleware(app.driver, config.Middleware["storage"])
if err != nil {
@@ -208,7 +208,7 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App {
}
}
if redirectDisabled {
ctxu.GetLogger(app).Infof("backend redirection disabled")
dcontext.GetLogger(app).Infof("backend redirection disabled")
} else {
options = append(options, storage.EnableRedirect)
}
@@ -269,7 +269,7 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App {
if err != nil {
panic("could not create registry: " + err.Error())
}
ctxu.GetLogger(app).Infof("using redis blob descriptor cache")
dcontext.GetLogger(app).Infof("using redis blob descriptor cache")
case "inmemory":
cacheProvider := memorycache.NewInMemoryBlobDescriptorCacheProvider()
localOptions := append(options, storage.BlobDescriptorCacheProvider(cacheProvider))
@@ -277,10 +277,10 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App {
if err != nil {
panic("could not create registry: " + err.Error())
}
ctxu.GetLogger(app).Infof("using inmemory blob descriptor cache")
dcontext.GetLogger(app).Infof("using inmemory blob descriptor cache")
default:
if v != "" {
ctxu.GetLogger(app).Warnf("unknown cache type %q, caching disabled", config.Storage["cache"])
dcontext.GetLogger(app).Warnf("unknown cache type %q, caching disabled", config.Storage["cache"])
}
}
}
@@ -306,7 +306,7 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App {
panic(fmt.Sprintf("unable to configure authorization (%s): %v", authType, err))
}
app.accessController = accessController
ctxu.GetLogger(app).Debugf("configured %q access controller", authType)
dcontext.GetLogger(app).Debugf("configured %q access controller", authType)
}
// configure as a pull through cache
@@ -316,7 +316,7 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App {
panic(err.Error())
}
app.isCache = true
ctxu.GetLogger(app).Info("Registry configured as a proxy cache to ", config.Proxy.RemoteURL)
dcontext.GetLogger(app).Info("Registry configured as a proxy cache to ", config.Proxy.RemoteURL)
}
return app
@@ -361,7 +361,7 @@ func (app *App) RegisterHealthChecks(healthRegistries ...*health.Registry) {
if interval == 0 {
interval = defaultCheckInterval
}
ctxu.GetLogger(app).Infof("configuring file health check path=%s, interval=%d", fileChecker.File, interval/time.Second)
dcontext.GetLogger(app).Infof("configuring file health check path=%s, interval=%d", fileChecker.File, interval/time.Second)
healthRegistry.Register(fileChecker.File, health.PeriodicChecker(checks.FileChecker(fileChecker.File), interval))
}
@@ -379,10 +379,10 @@ func (app *App) RegisterHealthChecks(healthRegistries ...*health.Registry) {
checker := checks.HTTPChecker(httpChecker.URI, statusCode, httpChecker.Timeout, httpChecker.Headers)
if httpChecker.Threshold != 0 {
ctxu.GetLogger(app).Infof("configuring HTTP health check uri=%s, interval=%d, threshold=%d", httpChecker.URI, interval/time.Second, httpChecker.Threshold)
dcontext.GetLogger(app).Infof("configuring HTTP health check uri=%s, interval=%d, threshold=%d", httpChecker.URI, interval/time.Second, httpChecker.Threshold)
healthRegistry.Register(httpChecker.URI, health.PeriodicThresholdChecker(checker, interval, httpChecker.Threshold))
} else {
ctxu.GetLogger(app).Infof("configuring HTTP health check uri=%s, interval=%d", httpChecker.URI, interval/time.Second)
dcontext.GetLogger(app).Infof("configuring HTTP health check uri=%s, interval=%d", httpChecker.URI, interval/time.Second)
healthRegistry.Register(httpChecker.URI, health.PeriodicChecker(checker, interval))
}
}
@@ -396,10 +396,10 @@ func (app *App) RegisterHealthChecks(healthRegistries ...*health.Registry) {
checker := checks.TCPChecker(tcpChecker.Addr, tcpChecker.Timeout)
if tcpChecker.Threshold != 0 {
ctxu.GetLogger(app).Infof("configuring TCP health check addr=%s, interval=%d, threshold=%d", tcpChecker.Addr, interval/time.Second, tcpChecker.Threshold)
dcontext.GetLogger(app).Infof("configuring TCP health check addr=%s, interval=%d, threshold=%d", tcpChecker.Addr, interval/time.Second, tcpChecker.Threshold)
healthRegistry.Register(tcpChecker.Addr, health.PeriodicThresholdChecker(checker, interval, tcpChecker.Threshold))
} else {
ctxu.GetLogger(app).Infof("configuring TCP health check addr=%s, interval=%d", tcpChecker.Addr, interval/time.Second)
dcontext.GetLogger(app).Infof("configuring TCP health check addr=%s, interval=%d", tcpChecker.Addr, interval/time.Second)
healthRegistry.Register(tcpChecker.Addr, health.PeriodicChecker(checker, interval))
}
}
@@ -425,11 +425,11 @@ func (app *App) configureEvents(configuration *configuration.Configuration) {
var sinks []notifications.Sink
for _, endpoint := range configuration.Notifications.Endpoints {
if endpoint.Disabled {
ctxu.GetLogger(app).Infof("endpoint %s disabled, skipping", endpoint.Name)
dcontext.GetLogger(app).Infof("endpoint %s disabled, skipping", endpoint.Name)
continue
}
ctxu.GetLogger(app).Infof("configuring endpoint %v (%v), timeout=%s, headers=%v", endpoint.Name, endpoint.URL, endpoint.Timeout, endpoint.Headers)
dcontext.GetLogger(app).Infof("configuring endpoint %v (%v), timeout=%s, headers=%v", endpoint.Name, endpoint.URL, endpoint.Timeout, endpoint.Headers)
endpoint := notifications.NewEndpoint(endpoint.Name, endpoint.URL, notifications.EndpointConfig{
Timeout: endpoint.Timeout,
Threshold: endpoint.Threshold,
@@ -461,7 +461,7 @@ func (app *App) configureEvents(configuration *configuration.Configuration) {
app.events.source = notifications.SourceRecord{
Addr: hostname,
InstanceID: ctxu.GetStringValue(app, "instance.id"),
InstanceID: dcontext.GetStringValue(app, "instance.id"),
}
}
@@ -469,7 +469,7 @@ type redisStartAtKey struct{}
func (app *App) configureRedis(configuration *configuration.Configuration) {
if configuration.Redis.Addr == "" {
ctxu.GetLogger(app).Infof("redis not configured")
dcontext.GetLogger(app).Infof("redis not configured")
return
}
@@ -479,8 +479,8 @@ func (app *App) configureRedis(configuration *configuration.Configuration) {
ctx := context.WithValue(app, redisStartAtKey{}, time.Now())
done := func(err error) {
logger := ctxu.GetLoggerWithField(ctx, "redis.connect.duration",
ctxu.Since(ctx, redisStartAtKey{}))
logger := dcontext.GetLoggerWithField(ctx, "redis.connect.duration",
dcontext.Since(ctx, redisStartAtKey{}))
if err != nil {
logger.Errorf("redis: error connecting: %v", err)
} else {
@@ -494,7 +494,7 @@ func (app *App) configureRedis(configuration *configuration.Configuration) {
configuration.Redis.ReadTimeout,
configuration.Redis.WriteTimeout)
if err != nil {
ctxu.GetLogger(app).Errorf("error connecting to redis instance %s: %v",
dcontext.GetLogger(app).Errorf("error connecting to redis instance %s: %v",
configuration.Redis.Addr, err)
done(err)
return nil, err
@@ -551,7 +551,7 @@ func (app *App) configureRedis(configuration *configuration.Configuration) {
// configureLogHook prepares logging hook parameters.
func (app *App) configureLogHook(configuration *configuration.Configuration) {
entry, ok := ctxu.GetLogger(app).(*log.Entry)
entry, ok := dcontext.GetLogger(app).(*logrus.Entry)
if !ok {
// somehow, we are not using logrus
return
@@ -589,7 +589,7 @@ func (app *App) configureSecret(configuration *configuration.Configuration) {
panic(fmt.Sprintf("could not generate random bytes for HTTP secret: %v", err))
}
configuration.HTTP.Secret = string(secretBytes[:])
ctxu.GetLogger(app).Warn("No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable.")
dcontext.GetLogger(app).Warn("No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable.")
}
}
@@ -598,15 +598,15 @@ func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Prepare the context with our own little decorations.
ctx := r.Context()
ctx = ctxu.WithRequest(ctx, r)
ctx, w = ctxu.WithResponseWriter(ctx, w)
ctx = ctxu.WithLogger(ctx, ctxu.GetRequestLogger(ctx))
ctx = dcontext.WithRequest(ctx, r)
ctx, w = dcontext.WithResponseWriter(ctx, w)
ctx = dcontext.WithLogger(ctx, dcontext.GetRequestLogger(ctx))
r = r.WithContext(ctx)
defer func() {
status, ok := ctx.Value("http.response.status").(int)
if ok && status >= 200 && status <= 399 {
ctxu.GetResponseLogger(r.Context()).Infof("response completed")
dcontext.GetResponseLogger(r.Context()).Infof("response completed")
}
}()
@@ -637,12 +637,12 @@ func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
context := app.context(w, r)
if err := app.authorized(w, r, context); err != nil {
ctxu.GetLogger(context).Warnf("error authorizing context: %v", err)
dcontext.GetLogger(context).Warnf("error authorizing context: %v", err)
return
}
// Add username to request logging
context.Context = ctxu.WithLogger(context.Context, ctxu.GetLogger(context.Context, auth.UserNameKey))
context.Context = dcontext.WithLogger(context.Context, dcontext.GetLogger(context.Context, auth.UserNameKey))
// sync up context on the request.
r = r.WithContext(context)
@@ -650,20 +650,20 @@ func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
if app.nameRequired(r) {
nameRef, err := reference.WithName(getName(context))
if err != nil {
ctxu.GetLogger(context).Errorf("error parsing reference from context: %v", err)
dcontext.GetLogger(context).Errorf("error parsing reference from context: %v", err)
context.Errors = append(context.Errors, distribution.ErrRepositoryNameInvalid{
Name: getName(context),
Reason: err,
})
if err := errcode.ServeJSON(w, context.Errors); err != nil {
ctxu.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
}
return
}
repository, err := app.registry.Repository(context, nameRef)
if err != nil {
ctxu.GetLogger(context).Errorf("error resolving repository: %v", err)
dcontext.GetLogger(context).Errorf("error resolving repository: %v", err)
switch err := err.(type) {
case distribution.ErrRepositoryUnknown:
@@ -675,7 +675,7 @@ func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
}
if err := errcode.ServeJSON(w, context.Errors); err != nil {
ctxu.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
}
return
}
@@ -687,11 +687,11 @@ func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
context.Repository, err = applyRepoMiddleware(app, context.Repository, app.Config.Middleware["repository"])
if err != nil {
ctxu.GetLogger(context).Errorf("error initializing repository middleware: %v", err)
dcontext.GetLogger(context).Errorf("error initializing repository middleware: %v", err)
context.Errors = append(context.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
if err := errcode.ServeJSON(w, context.Errors); err != nil {
ctxu.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
}
return
}
@@ -703,7 +703,7 @@ func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
// for layer upload).
if context.Errors.Len() > 0 {
if err := errcode.ServeJSON(w, context.Errors); err != nil {
ctxu.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
}
app.logError(context, context.Errors)
@@ -723,31 +723,31 @@ type errDetailKey struct{}
func (errDetailKey) String() string { return "err.detail" }
func (app *App) logError(context context.Context, errors errcode.Errors) {
func (app *App) logError(ctx context.Context, errors errcode.Errors) {
for _, e1 := range errors {
var c ctxu.Context
var c context.Context
switch e1.(type) {
case errcode.Error:
e, _ := e1.(errcode.Error)
c = ctxu.WithValue(context, errCodeKey{}, e.Code)
c = ctxu.WithValue(c, errMessageKey{}, e.Code.Message())
c = ctxu.WithValue(c, errDetailKey{}, e.Detail)
c = context.WithValue(ctx, errCodeKey{}, e.Code)
c = context.WithValue(c, errMessageKey{}, e.Code.Message())
c = context.WithValue(c, errDetailKey{}, e.Detail)
case errcode.ErrorCode:
e, _ := e1.(errcode.ErrorCode)
c = ctxu.WithValue(context, errCodeKey{}, e)
c = ctxu.WithValue(c, errMessageKey{}, e.Message())
c = context.WithValue(ctx, errCodeKey{}, e)
c = context.WithValue(c, errMessageKey{}, e.Message())
default:
// just normal go 'error'
c = ctxu.WithValue(context, errCodeKey{}, errcode.ErrorCodeUnknown)
c = ctxu.WithValue(c, errMessageKey{}, e1.Error())
c = context.WithValue(ctx, errCodeKey{}, errcode.ErrorCodeUnknown)
c = context.WithValue(c, errMessageKey{}, e1.Error())
}
c = ctxu.WithLogger(c, ctxu.GetLogger(c,
c = dcontext.WithLogger(c, dcontext.GetLogger(c,
errCodeKey{},
errMessageKey{},
errDetailKey{}))
ctxu.GetResponseLogger(c).Errorf("response completed with error")
dcontext.GetResponseLogger(c).Errorf("response completed with error")
}
}
@@ -755,8 +755,8 @@ func (app *App) logError(context context.Context, errors errcode.Errors) {
// called once per request.
func (app *App) context(w http.ResponseWriter, r *http.Request) *Context {
ctx := r.Context()
ctx = ctxu.WithVars(ctx, r)
ctx = ctxu.WithLogger(ctx, ctxu.GetLogger(ctx,
ctx = dcontext.WithVars(ctx, r)
ctx = dcontext.WithLogger(ctx, dcontext.GetLogger(ctx,
"vars.name",
"vars.reference",
"vars.digest",
@@ -783,7 +783,7 @@ func (app *App) context(w http.ResponseWriter, r *http.Request) *Context {
// repository. If it succeeds, the context may access the requested
// repository. An error will be returned if access is not available.
func (app *App) authorized(w http.ResponseWriter, r *http.Request, context *Context) error {
ctxu.GetLogger(context).Debug("authorizing request")
dcontext.GetLogger(context).Debug("authorizing request")
repo := getName(context)
if app.accessController == nil {
@@ -809,7 +809,7 @@ func (app *App) authorized(w http.ResponseWriter, r *http.Request, context *Cont
// that mistake elsewhere in the code, allowing any operation to
// proceed.
if err := errcode.ServeJSON(w, errcode.ErrorCodeUnauthorized); err != nil {
ctxu.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
}
return fmt.Errorf("forbidden: no repository name")
}
@@ -824,20 +824,21 @@ func (app *App) authorized(w http.ResponseWriter, r *http.Request, context *Cont
err.SetHeaders(w)
if err := errcode.ServeJSON(w, errcode.ErrorCodeUnauthorized.WithDetail(accessRecords)); err != nil {
ctxu.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
}
default:
// This condition is a potential security problem either in
// the configuration or whatever is backing the access
// controller. Just return a bad request with no information
// to avoid exposure. The request should not proceed.
ctxu.GetLogger(context).Errorf("error checking authorization: %v", err)
dcontext.GetLogger(context).Errorf("error checking authorization: %v", err)
w.WriteHeader(http.StatusBadRequest)
}
return err
}
dcontext.GetLogger(ctx).Info("authorized request")
// TODO(stevvooe): This pattern needs to be cleaned up a bit. One context
// should be replaced by another, rather than replacing the context on a
// mutable object.
@@ -851,7 +852,7 @@ func (app *App) eventBridge(ctx *Context, r *http.Request) notifications.Listene
actor := notifications.ActorRecord{
Name: getUserName(ctx, r),
}
request := notifications.NewRequestRecord(ctxu.GetRequestID(ctx), r)
request := notifications.NewRequestRecord(dcontext.GetRequestID(ctx), r)
return notifications.NewBridge(ctx.urlBuilder, app.events.source, actor, request, app.events.sink)
}
@@ -986,7 +987,7 @@ func badPurgeUploadConfig(reason string) {
// startUploadPurger schedules a goroutine which will periodically
// check upload directories for old files and delete them
func startUploadPurger(ctx context.Context, storageDriver storagedriver.StorageDriver, log ctxu.Logger, config map[interface{}]interface{}) {
func startUploadPurger(ctx context.Context, storageDriver storagedriver.StorageDriver, log dcontext.Logger, config map[interface{}]interface{}) {
if config["enabled"] == false {
return
}