1
1
package server
2
2
3
3
import (
4
- "fmt"
5
4
"sort"
6
5
"time"
7
6
8
- "github.com/Sirupsen/logrus"
9
7
"github.com/docker/distribution"
10
8
"github.com/docker/distribution/context"
11
9
"github.com/docker/distribution/digest"
12
10
"github.com/docker/distribution/manifest/schema2"
13
- "github.com/docker/distribution/registry/middleware/registry"
14
- "github.com/docker/distribution/registry/storage"
15
11
16
12
kerrors "k8s.io/apimachinery/pkg/api/errors"
17
13
@@ -34,61 +30,50 @@ func (b ByGeneration) Less(i, j int) bool { return b[i].Generation > b[j].Genera
34
30
func (b ByGeneration ) Len () int { return len (b ) }
35
31
func (b ByGeneration ) Swap (i , j int ) { b [i ], b [j ] = b [j ], b [i ] }
36
32
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
43
34
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 )
51
37
}
52
38
53
39
type blobDescriptorService struct {
54
40
distribution.BlobDescriptorService
41
+ repo * repository
42
+ }
43
+
44
+ func (r * repository ) BlobDescriptorService (svc distribution.BlobDescriptorService ) distribution.BlobDescriptorService {
45
+ return & blobDescriptorService {svc , r }
55
46
}
56
47
57
48
// Stat returns a a blob descriptor if the given blob is either linked in repository or is referenced in
58
49
// corresponding image stream. This method is invoked from inside of upstream's linkedBlobStore. It expects
59
50
// a proper repository object to be set on given context by upper openshift middleware wrappers.
60
51
func (bs * blobDescriptorService ) Stat (ctx context.Context , dgst digest.Digest ) (distribution.Descriptor , error ) {
61
52
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
- }
68
53
69
54
// if there is a repo layer link, return its descriptor
70
55
desc , err := bs .BlobDescriptorService .Stat (ctx , dgst )
71
56
if err == nil {
72
57
// 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 ,
76
61
}.Exact ())
77
62
return desc , nil
78
63
}
79
64
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 )
81
66
82
67
// 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 )
84
69
if err == nil {
85
70
context .GetLogger (ctx ).Debugf ("(*blobDescriptorService).Stat: blob %s exists in the global blob store" , dgst .String ())
86
71
// only non-empty layers is wise to check for existence in the image stream.
87
72
// schema v2 has no empty layers.
88
73
if ! isEmptyDigest (dgst ) {
89
74
// 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 ())
92
77
return distribution.Descriptor {}, distribution .ErrBlobUnknown
93
78
}
94
79
}
@@ -97,23 +82,16 @@ func (bs *blobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (
97
82
98
83
if err == distribution .ErrBlobUnknown && remoteBlobAccessCheckEnabledFrom (ctx ) {
99
84
// 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 )
101
86
}
102
87
103
88
return desc , err
104
89
}
105
90
106
91
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 ,
117
95
}.Exact ())
118
96
return bs .BlobDescriptorService .Clear (ctx , dgst )
119
97
}
@@ -166,7 +144,7 @@ func imageStreamHasBlob(r *repository, dgst digest.Digest) bool {
166
144
if _ , processed := processedImages [tagEvent .Image ]; processed {
167
145
continue
168
146
}
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 ) {
170
148
tagName := event2Name [tagEvent ]
171
149
context .GetLogger (r .ctx ).Debugf ("blob found under istag %s/%s:%s in image %s" , r .namespace , r .name , tagName , tagEvent .Image )
172
150
return logFound (true )
0 commit comments