Merge pull request #3061 from guillaumerose/reconciliate
Add pathspec for repo _layers directory and allow Repository.BlobStore to enumerate over blobsmaster
						commit
						f18781257e
					
				|  | @ -5,6 +5,7 @@ import ( | |||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"testing" | ||||
| 
 | ||||
|  | @ -14,6 +15,54 @@ import ( | |||
| 	"github.com/opencontainers/go-digest" | ||||
| ) | ||||
| 
 | ||||
| func TestLinkedBlobStoreEnumerator(t *testing.T) { | ||||
| 	fooRepoName, _ := reference.WithName("nm/foo") | ||||
| 	fooEnv := newManifestStoreTestEnv(t, fooRepoName, "thetag") | ||||
| 	ctx := context.Background() | ||||
| 
 | ||||
| 	var expected []string | ||||
| 	for i := 0; i < 2; i++ { | ||||
| 		rs, dgst, err := testutil.CreateRandomTarFile() | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("unexpected error generating test layer file") | ||||
| 		} | ||||
| 
 | ||||
| 		expected = append(expected, dgst.String()) | ||||
| 
 | ||||
| 		wr, err := fooEnv.repository.Blobs(fooEnv.ctx).Create(fooEnv.ctx) | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("unexpected error creating test upload: %v", err) | ||||
| 		} | ||||
| 
 | ||||
| 		if _, err := io.Copy(wr, rs); err != nil { | ||||
| 			t.Fatalf("unexpected error copying to upload: %v", err) | ||||
| 		} | ||||
| 
 | ||||
| 		if _, err := wr.Commit(fooEnv.ctx, distribution.Descriptor{Digest: dgst}); err != nil { | ||||
| 			t.Fatalf("unexpected error finishing upload: %v", err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	enumerator, ok := fooEnv.repository.Blobs(fooEnv.ctx).(distribution.BlobEnumerator) | ||||
| 	if !ok { | ||||
| 		t.Fatalf("Blobs is not a BlobEnumerator") | ||||
| 	} | ||||
| 
 | ||||
| 	var actual []string | ||||
| 	if err := enumerator.Enumerate(ctx, func(dgst digest.Digest) error { | ||||
| 		actual = append(actual, dgst.String()) | ||||
| 		return nil | ||||
| 	}); err != nil { | ||||
| 		t.Fatalf("cannot enumerate on repository: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	sort.Strings(actual) | ||||
| 	sort.Strings(expected) | ||||
| 	if !reflect.DeepEqual(expected, actual) { | ||||
| 		t.Fatalf("unexpected array difference (expected: %v actual: %v)", expected, actual) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestLinkedBlobStoreCreateWithMountFrom(t *testing.T) { | ||||
| 	fooRepoName, _ := reference.WithName("nm/foo") | ||||
| 	fooEnv := newManifestStoreTestEnv(t, fooRepoName, "thetag") | ||||
|  |  | |||
|  | @ -87,6 +87,7 @@ const ( | |||
| // 	Blobs:
 | ||||
| //
 | ||||
| // 	layerLinkPathSpec:            <root>/v2/repositories/<name>/_layers/<algorithm>/<hex digest>/link
 | ||||
| // 	layersPathSpec:               <root>/v2/repositories/<name>/_layers
 | ||||
| //
 | ||||
| //	Uploads:
 | ||||
| //
 | ||||
|  | @ -206,6 +207,8 @@ func pathFor(spec pathSpec) (string, error) { | |||
| 		blobLinkPathComponents := append(repoPrefix, v.name, "_layers") | ||||
| 
 | ||||
| 		return path.Join(path.Join(append(blobLinkPathComponents, components...)...), "link"), nil | ||||
| 	case layersPathSpec: | ||||
| 		return path.Join(append(repoPrefix, v.name, "_layers")...), nil | ||||
| 	case blobsPathSpec: | ||||
| 		blobsPathPrefix := append(rootPrefix, "blobs") | ||||
| 		return path.Join(blobsPathPrefix...), nil | ||||
|  | @ -335,6 +338,13 @@ type manifestTagIndexEntryLinkPathSpec struct { | |||
| 
 | ||||
| func (manifestTagIndexEntryLinkPathSpec) pathSpec() {} | ||||
| 
 | ||||
| // layersPathSpec contains the path for the layers inside a repo
 | ||||
| type layersPathSpec struct { | ||||
| 	name string | ||||
| } | ||||
| 
 | ||||
| func (layersPathSpec) pathSpec() {} | ||||
| 
 | ||||
| // blobLinkPathSpec specifies a path for a blob link, which is a file with a
 | ||||
| // blob id. The blob link will contain a content addressable blob id reference
 | ||||
| // into the blob store. The format of the contents is as follows:
 | ||||
|  |  | |||
|  | @ -83,6 +83,10 @@ func TestPathMapper(t *testing.T) { | |||
| 			}, | ||||
| 			expected: "/docker/registry/v2/repositories/foo/bar/_uploads/asdf-asdf-asdf-adsf/startedat", | ||||
| 		}, | ||||
| 		{ | ||||
| 			spec:     layersPathSpec{name: "foo/bar"}, | ||||
| 			expected: "/docker/registry/v2/repositories/foo/bar/_layers", | ||||
| 		}, | ||||
| 	} { | ||||
| 		p, err := pathFor(testcase.spec) | ||||
| 		if err != nil { | ||||
|  |  | |||
|  | @ -330,6 +330,7 @@ func (repo *repository) Blobs(ctx context.Context) distribution.BlobStore { | |||
| 		// TODO(stevvooe): linkPath limits this blob store to only layers.
 | ||||
| 		// This instance cannot be used for manifest checks.
 | ||||
| 		linkPathFns:            []linkPathFunc{blobLinkPath}, | ||||
| 		linkDirectoryPathSpec:  layersPathSpec{name: repo.name.Name()}, | ||||
| 		deleteEnabled:          repo.registry.deleteEnabled, | ||||
| 		resumableDigestEnabled: repo.resumableDigestEnabled, | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue