mirror of
https://github.com/distribution/distribution.git
synced 2025-09-01 15:07:25 +00:00
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:
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user