Browse code

Pullthrough blobs using Get() as well

Manifest configs are fetched using Get() method from blob store.
Pullthrough middleware needs to override it as well to allow for pulling
manifest v2 schema 2 images from remote repositories.

Signed-off-by: Michal Minář <miminar@redhat.com>

Michal Minář authored on 2016/09/01 20:54:07
Showing 1 changed files
... ...
@@ -43,6 +43,12 @@ func (r *pullthroughBlobStore) Stat(ctx context.Context, dgst digest.Digest) (di
43 43
 		return desc, err
44 44
 	}
45 45
 
46
+	return r.remoteStat(ctx, dgst)
47
+}
48
+
49
+// remoteStat attempts to find requested blob in candidate remote repositories and if found, it updates
50
+// digestToRepository store. ErrBlobUnknown will be returned if not found.
51
+func (r *pullthroughBlobStore) remoteStat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
46 52
 	// look up the potential remote repositories that this blob could be part of (at this time,
47 53
 	// we don't know which image in the image stream surfaced the content).
48 54
 	is, err := r.repo.getImageStream()
... ...
@@ -112,13 +118,13 @@ func (r *pullthroughBlobStore) ServeBlob(ctx context.Context, w http.ResponseWri
112 112
 
113 113
 	desc, err := store.Stat(ctx, dgst)
114 114
 	if err != nil {
115
-		context.GetLogger(ctx).Errorf("Failed to stat digest %q: %v", dgst.String(), err)
115
+		context.GetLogger(ctx).Errorf("failed to stat digest %q: %v", dgst.String(), err)
116 116
 		return err
117 117
 	}
118 118
 
119 119
 	remoteReader, err := store.Open(ctx, dgst)
120 120
 	if err != nil {
121
-		context.GetLogger(ctx).Errorf("Failure to open remote store for digest %q: %v", dgst.String(), err)
121
+		context.GetLogger(ctx).Errorf("failure to open remote store for digest %q: %v", dgst.String(), err)
122 122
 		return err
123 123
 	}
124 124
 	defer remoteReader.Close()
... ...
@@ -130,6 +136,30 @@ func (r *pullthroughBlobStore) ServeBlob(ctx context.Context, w http.ResponseWri
130 130
 	return nil
131 131
 }
132 132
 
133
+// Get attempts to fetch the requested blob by digest using a remote proxy store if necessary.
134
+func (r *pullthroughBlobStore) Get(ctx context.Context, dgst digest.Digest) ([]byte, error) {
135
+	store, ok := r.digestToStore[dgst.String()]
136
+	if ok {
137
+		return store.Get(ctx, dgst)
138
+	}
139
+
140
+	data, originalErr := r.BlobStore.Get(ctx, dgst)
141
+	if originalErr == nil {
142
+		return data, nil
143
+	}
144
+
145
+	desc, err := r.remoteStat(ctx, dgst)
146
+	if err != nil {
147
+		context.GetLogger(ctx).Errorf("failed to stat blob %q in remote repositories: %v", dgst.String(), err)
148
+		return nil, originalErr
149
+	}
150
+	store, ok = r.digestToStore[desc.Digest.String()]
151
+	if !ok {
152
+		return nil, originalErr
153
+	}
154
+	return store.Get(ctx, desc.Digest)
155
+}
156
+
133 157
 // findCandidateRepository looks in search for a particular blob, referring to previously cached items
134 158
 func (r *pullthroughBlobStore) findCandidateRepository(ctx context.Context, search map[string]*imageapi.DockerImageReference, cachedLayers []string, dgst digest.Digest, retriever importer.RepositoryRetriever) (distribution.Descriptor, error) {
135 159
 	// no possible remote locations to search, exit early