Skip to content

Commit ade8647

Browse files
author
Oleg Bulatov
committed
Move hacks for middlewares into a separate package
1 parent 85c2542 commit ade8647

27 files changed

+961
-606
lines changed

pkg/dockerregistry/server/app.go

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,33 @@ import (
66
"github.com/docker/distribution"
77
"github.com/docker/distribution/configuration"
88
"github.com/docker/distribution/context"
9-
"github.com/docker/distribution/registry/handlers"
109
storagedriver "github.com/docker/distribution/registry/storage/driver"
1110

1211
"github.com/openshift/image-registry/pkg/dockerregistry/server/client"
1312
registryconfig "github.com/openshift/image-registry/pkg/dockerregistry/server/configuration"
1413
"github.com/openshift/image-registry/pkg/dockerregistry/server/maxconnections"
14+
"github.com/openshift/image-registry/pkg/dockerregistry/server/supermiddleware"
1515
)
1616

1717
const (
1818
// Default values
1919
defaultDigestToRepositoryCacheSize = 2048
2020
)
2121

22+
// appMiddleware should be used only in tests.
23+
type appMiddleware interface {
24+
Apply(supermiddleware.App) supermiddleware.App
25+
}
26+
2227
// App is a global registry application object. Shared resources can be placed
2328
// on this object that will be accessible from all requests.
2429
type App struct {
2530
// ctx is the parent context.
2631
ctx context.Context
2732

28-
registryClient client.RegistryClient
29-
extraConfig *registryconfig.Configuration
30-
repositoryConfig repositoryConfig
31-
writeLimiter maxconnections.Limiter
33+
registryClient client.RegistryClient
34+
extraConfig *registryconfig.Configuration
35+
writeLimiter maxconnections.Limiter
3236

3337
// driver gives access to the blob store.
3438
// This variable holds the object created by docker/distribution. We
@@ -57,6 +61,16 @@ type App struct {
5761
quotaEnforcing *quotaEnforcingConfig
5862
}
5963

64+
func (app *App) Storage(driver storagedriver.StorageDriver, options map[string]interface{}) (storagedriver.StorageDriver, error) {
65+
app.driver = driver
66+
return driver, nil
67+
}
68+
69+
func (app *App) Registry(registry distribution.Namespace, options map[string]interface{}) (distribution.Namespace, error) {
70+
app.registry = registry
71+
return registry, nil
72+
}
73+
6074
// NewApp configures the registry application and returns http.Handler for it.
6175
// The program will be terminated if an error happens.
6276
func NewApp(ctx context.Context, registryClient client.RegistryClient, dockerConfig *configuration.Configuration, extraConfig *registryconfig.Configuration, writeLimiter maxconnections.Limiter) http.Handler {
@@ -74,35 +88,21 @@ func NewApp(ctx context.Context, registryClient client.RegistryClient, dockerCon
7488
}
7589
app.cachedLayers = cache
7690

77-
weaveAppIntoConfig(app, dockerConfig)
78-
79-
repositoryEnabled := false
80-
for _, middleware := range dockerConfig.Middleware["repository"] {
81-
if middleware.Name == middlewareOpenShift {
82-
rc, err := newRepositoryConfig(ctx, extraConfig, middleware.Options)
83-
if err != nil {
84-
context.GetLogger(ctx).Fatalf("error configuring the repository middleware: %s", err)
85-
}
86-
app.repositoryConfig = rc
87-
repositoryEnabled = true
88-
break
89-
}
91+
superapp := supermiddleware.App(app)
92+
if am := appMiddlewareFrom(ctx); am != nil {
93+
superapp = am.Apply(superapp)
9094
}
95+
dockerApp := supermiddleware.NewApp(ctx, dockerConfig, superapp)
9196

92-
dockerApp := handlers.NewApp(ctx, dockerConfig)
93-
94-
if repositoryEnabled {
95-
if app.driver == nil {
96-
context.GetLogger(ctx).Fatalf("configuration error: the storage driver middleware %q is not activated", middlewareOpenShift)
97-
}
98-
99-
if app.registry == nil {
100-
context.GetLogger(ctx).Fatalf("configuration error: the registry middleware %q is not activated", middlewareOpenShift)
101-
}
97+
if app.driver == nil {
98+
context.GetLogger(ctx).Fatalf("configuration error: the storage driver middleware %q is not activated", supermiddleware.Name)
99+
}
100+
if app.registry == nil {
101+
context.GetLogger(ctx).Fatalf("configuration error: the registry middleware %q is not activated", supermiddleware.Name)
102102
}
103103

104104
// Add a token handling endpoint
105-
if dockerConfig.Auth.Type() == middlewareOpenShift {
105+
if dockerConfig.Auth.Type() == supermiddleware.Name {
106106
tokenRealm, err := registryconfig.TokenRealm(extraConfig.Auth.TokenRealm)
107107
if err != nil {
108108
context.GetLogger(dockerApp).Fatalf("error setting up token auth: %s", err)

pkg/dockerregistry/server/auth.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ var (
8989
ErrUnsupportedResource = errors.New("unsupported resource")
9090
)
9191

92-
func (app *App) newAccessController(authcfg *configuration.Auth) (registryauth.AccessController, error) {
92+
func (app *App) Auth(options map[string]interface{}) (registryauth.AccessController, error) {
93+
authcfg := app.extraConfig.Auth
9394
tokenRealm, err := configuration.TokenRealm(authcfg.TokenRealm)
9495
if err != nil {
9596
return nil, err

pkg/dockerregistry/server/auth_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ func TestAccessController(t *testing.T) {
433433
if err := configuration.InitExtraConfig(config, app.extraConfig); err != nil {
434434
t.Fatal(err)
435435
}
436-
accessController, err := app.newAccessController(app.extraConfig.Auth)
436+
accessController, err := app.Auth(nil)
437437
if err != nil {
438438
t.Fatal(err)
439439
}

pkg/dockerregistry/server/blobdescriptorservice.go

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
package server
22

33
import (
4-
"fmt"
54
"sort"
65
"time"
76

8-
"github.com/Sirupsen/logrus"
97
"github.com/docker/distribution"
108
"github.com/docker/distribution/context"
119
"github.com/docker/distribution/digest"
1210
"github.com/docker/distribution/manifest/schema2"
13-
"github.com/docker/distribution/registry/middleware/registry"
14-
"github.com/docker/distribution/registry/storage"
1511

1612
kerrors "k8s.io/apimachinery/pkg/api/errors"
1713

@@ -34,61 +30,50 @@ func (b ByGeneration) Less(i, j int) bool { return b[i].Generation > b[j].Genera
3430
func (b ByGeneration) Len() int { return len(b) }
3531
func (b ByGeneration) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
3632

37-
func init() {
38-
err := middleware.RegisterOptions(storage.BlobDescriptorServiceFactory(&blobDescriptorServiceFactory{}))
39-
if err != nil {
40-
logrus.Fatalf("Unable to register BlobDescriptorServiceFactory: %v", err)
41-
}
42-
}
33+
type blobDescriptorServiceFactoryFunc func(svc distribution.BlobDescriptorService) distribution.BlobDescriptorService
4334

44-
// blobDescriptorServiceFactory needs to be able to work with blobs
45-
// directly without using links. This allows us to ignore the distribution
46-
// of blobs between repositories.
47-
type blobDescriptorServiceFactory struct{}
48-
49-
func (bf *blobDescriptorServiceFactory) BlobAccessController(svc distribution.BlobDescriptorService) distribution.BlobDescriptorService {
50-
return &blobDescriptorService{svc}
35+
func (f blobDescriptorServiceFactoryFunc) BlobAccessController(svc distribution.BlobDescriptorService) distribution.BlobDescriptorService {
36+
return f(svc)
5137
}
5238

5339
type blobDescriptorService struct {
5440
distribution.BlobDescriptorService
41+
repo *repository
42+
}
43+
44+
func (r *repository) BlobDescriptorService(svc distribution.BlobDescriptorService) distribution.BlobDescriptorService {
45+
return &blobDescriptorService{svc, r}
5546
}
5647

5748
// Stat returns a a blob descriptor if the given blob is either linked in repository or is referenced in
5849
// corresponding image stream. This method is invoked from inside of upstream's linkedBlobStore. It expects
5950
// a proper repository object to be set on given context by upper openshift middleware wrappers.
6051
func (bs *blobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
6152
context.GetLogger(ctx).Debugf("(*blobDescriptorService).Stat: starting with digest=%s", dgst.String())
62-
repo, found := repositoryFrom(ctx)
63-
if !found || repo == nil {
64-
err := fmt.Errorf("failed to retrieve repository from context")
65-
context.GetLogger(ctx).Error(err)
66-
return distribution.Descriptor{}, err
67-
}
6853

6954
// if there is a repo layer link, return its descriptor
7055
desc, err := bs.BlobDescriptorService.Stat(ctx, dgst)
7156
if err == nil {
7257
// and remember the association
73-
repo.cachedLayers.RememberDigest(dgst, repo.config.blobRepositoryCacheTTL, imageapi.DockerImageReference{
74-
Namespace: repo.namespace,
75-
Name: repo.name,
58+
bs.repo.cachedLayers.RememberDigest(dgst, bs.repo.app.extraConfig.Cache.BlobRepositoryTTL, imageapi.DockerImageReference{
59+
Namespace: bs.repo.namespace,
60+
Name: bs.repo.name,
7661
}.Exact())
7762
return desc, nil
7863
}
7964

80-
context.GetLogger(ctx).Debugf("(*blobDescriptorService).Stat: could not stat layer link %s in repository %s: %v", dgst.String(), repo.Named().Name(), err)
65+
context.GetLogger(ctx).Debugf("(*blobDescriptorService).Stat: could not stat layer link %s in repository %s: %v", dgst.String(), bs.repo.Named().Name(), err)
8166

8267
// First attempt: looking for the blob locally
83-
desc, err = repo.app.registry.BlobStatter().Stat(ctx, dgst)
68+
desc, err = bs.repo.app.registry.BlobStatter().Stat(ctx, dgst)
8469
if err == nil {
8570
context.GetLogger(ctx).Debugf("(*blobDescriptorService).Stat: blob %s exists in the global blob store", dgst.String())
8671
// only non-empty layers is wise to check for existence in the image stream.
8772
// schema v2 has no empty layers.
8873
if !isEmptyDigest(dgst) {
8974
// ensure it's referenced inside of corresponding image stream
90-
if !imageStreamHasBlob(repo, dgst) {
91-
context.GetLogger(ctx).Debugf("(*blobDescriptorService).Stat: blob %s is neither empty nor referenced in image stream %s", dgst.String(), repo.Named().Name())
75+
if !imageStreamHasBlob(bs.repo, dgst) {
76+
context.GetLogger(ctx).Debugf("(*blobDescriptorService).Stat: blob %s is neither empty nor referenced in image stream %s", dgst.String(), bs.repo.Named().Name())
9277
return distribution.Descriptor{}, distribution.ErrBlobUnknown
9378
}
9479
}
@@ -97,23 +82,16 @@ func (bs *blobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (
9782

9883
if err == distribution.ErrBlobUnknown && remoteBlobAccessCheckEnabledFrom(ctx) {
9984
// Second attempt: looking for the blob on a remote server
100-
desc, err = repo.remoteBlobGetter.Stat(ctx, dgst)
85+
desc, err = bs.repo.remoteBlobGetter.Stat(ctx, dgst)
10186
}
10287

10388
return desc, err
10489
}
10590

10691
func (bs *blobDescriptorService) Clear(ctx context.Context, dgst digest.Digest) error {
107-
repo, found := repositoryFrom(ctx)
108-
if !found || repo == nil {
109-
err := fmt.Errorf("failed to retrieve repository from context")
110-
context.GetLogger(ctx).Error(err)
111-
return err
112-
}
113-
114-
repo.cachedLayers.ForgetDigest(dgst, imageapi.DockerImageReference{
115-
Namespace: repo.namespace,
116-
Name: repo.name,
92+
bs.repo.cachedLayers.ForgetDigest(dgst, imageapi.DockerImageReference{
93+
Namespace: bs.repo.namespace,
94+
Name: bs.repo.name,
11795
}.Exact())
11896
return bs.BlobDescriptorService.Clear(ctx, dgst)
11997
}
@@ -166,7 +144,7 @@ func imageStreamHasBlob(r *repository, dgst digest.Digest) bool {
166144
if _, processed := processedImages[tagEvent.Image]; processed {
167145
continue
168146
}
169-
if imageHasBlob(r, repoCacheName, tagEvent.Image, dgst.String(), !r.config.pullthrough) {
147+
if imageHasBlob(r, repoCacheName, tagEvent.Image, dgst.String(), !r.app.extraConfig.Pullthrough.Enabled) {
170148
tagName := event2Name[tagEvent]
171149
context.GetLogger(r.ctx).Debugf("blob found under istag %s/%s:%s in image %s", r.namespace, r.name, tagName, tagEvent.Image)
172150
return logFound(true)

0 commit comments

Comments
 (0)