{"action":"created","comment":{"url":"https://api.github.com/repos/docker/distribution/pulls/comments/47713087","id":47713087,"diff_hunk":"@@ -9,45 +12,61 @@ import (\n \tstoragedriver \"github.com/docker/distribution/registry/storage/driver\"\n )\n \n+var _ distribution.TagService = &tagStore{}\n+\n // tagStore provides methods to manage manifest tags in a backend storage driver.\n+// This implementation uses the same on-disk layout as the (now deleted) signature\n+// store.  This provides backward compatibility with current registry deployments\n+// which only makes use of the Digest field of the returned distribution.Descriptor\n+// but does not enable full roundtripping of Descriptor objects\n type tagStore struct {\n \trepository *repository\n \tblobStore  *blobStore\n-\tctx        context.Context\n }\n \n-// tags lists the manifest tags for the specified repository.\n-func (ts *tagStore) tags() ([]string, error) {\n-\tp, err := pathFor(manifestTagPathSpec{\n+// Enumerate enumerates the tags stored in this tag store.\n+func (ts *tagStore) Enumerate(ctx context.Context, tags []string, last string) (n int, err error) {\n+\tif len(tags) == 0 {\n+\t\treturn 0, errors.New(\"no space in slice\")\n+\t}\n+\n+\tpathSpec, err := pathFor(manifestTagPathSpec{\n \t\tname: ts.repository.Name(),\n \t})\n-\n \tif err != nil {\n-\t\treturn nil, err\n+\t\treturn 0, err\n \t}\n \n-\tvar tags []string\n-\tentries, err := ts.blobStore.driver.List(ts.ctx, p)\n+\tentries, err := ts.blobStore.driver.List(ctx, pathSpec)\n \tif err != nil {\n \t\tswitch err := err.(type) {\n \t\tcase storagedriver.PathNotFoundError:\n-\t\t\treturn nil, distribution.ErrRepositoryUnknown{Name: ts.repository.Name()}\n+\t\t\treturn 0, distribution.ErrRepositoryUnknown{Name: ts.repository.Name()}\n \t\tdefault:\n-\t\t\treturn nil, err\n+\t\t\treturn 0, err\n \t\t}\n \t}\n \n+\tsort.Strings(entries)\n+\tvar tagNames []string\n \tfor _, entry := range entries {\n-\t\t_, filename := path.Split(entry)\n+\t\tif len(tagNames) == len(tags) {\n+\t\t\tcopy(tags, tagNames)\n+\t\t\treturn len(tags), nil\n+\t\t}\n \n-\t\ttags = append(tags, filename)\n+\t\t_, filename := path.Split(entry)\n+\t\tif filename > last {\n+\t\t\ttagNames = append(tagNames, filename)\n+\t\t}\n \t}\n \n-\treturn tags, nil\n+\tn = copy(tags, tagNames)\n+\treturn n, io.EOF","path":"registry/storage/tagstore.go","position":78,"original_position":78,"commit_id":"d21d199198b2484afc73c24a9593f64bfdda8eb4","original_commit_id":"d21d199198b2484afc73c24a9593f64bfdda8eb4","user":{"login":"aaronlehmann","id":10601430,"avatar_url":"https://avatars.githubusercontent.com/u/10601430?v=3","gravatar_id":"","url":"https://api.github.com/users/aaronlehmann","html_url":"https://github.com/aaronlehmann","followers_url":"https://api.github.com/users/aaronlehmann/followers","following_url":"https://api.github.com/users/aaronlehmann/following{/other_user}","gists_url":"https://api.github.com/users/aaronlehmann/gists{/gist_id}","starred_url":"https://api.github.com/users/aaronlehmann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aaronlehmann/subscriptions","organizations_url":"https://api.github.com/users/aaronlehmann/orgs","repos_url":"https://api.github.com/users/aaronlehmann/repos","events_url":"https://api.github.com/users/aaronlehmann/events{/privacy}","received_events_url":"https://api.github.com/users/aaronlehmann/received_events","type":"User","site_admin":false},"body":"As with the client side version of `Enumerate`, I don't like how the pagination is simulated, and would rather just return all the tags if we're internally listing all of them anyway.","created_at":"2015-12-15T23:03:11Z","updated_at":"2015-12-15T23:03:11Z","html_url":"https://github.com/docker/distribution/pull/1268#discussion_r47713087","pull_request_url":"https://api.github.com/repos/docker/distribution/pulls/1268","_links":{"self":{"href":"https://api.github.com/repos/docker/distribution/pulls/comments/47713087"},"html":{"href":"https://github.com/docker/distribution/pull/1268#discussion_r47713087"},"pull_request":{"href":"https://api.github.com/repos/docker/distribution/pulls/1268"}}},"pull_request":{"url":"https://api.github.com/repos/docker/distribution/pulls/1268","id":53762785,"html_url":"https://github.com/docker/distribution/pull/1268","diff_url":"https://github.com/docker/distribution/pull/1268.diff","patch_url":"https://github.com/docker/distribution/pull/1268.patch","issue_url":"https://api.github.com/repos/docker/distribution/issues/1268","number":1268,"state":"open","locked":false,"title":"Implementation of the Manifest Service API refactor.","user":{"login":"RichardScothern","id":922018,"avatar_url":"https://avatars.githubusercontent.com/u/922018?v=3","gravatar_id":"","url":"https://api.github.com/users/RichardScothern","html_url":"https://github.com/RichardScothern","followers_url":"https://api.github.com/users/RichardScothern/followers","following_url":"https://api.github.com/users/RichardScothern/following{/other_user}","gists_url":"https://api.github.com/users/RichardScothern/gists{/gist_id}","starred_url":"https://api.github.com/users/RichardScothern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RichardScothern/subscriptions","organizations_url":"https://api.github.com/users/RichardScothern/orgs","repos_url":"https://api.github.com/users/RichardScothern/repos","events_url":"https://api.github.com/users/RichardScothern/events{/privacy}","received_events_url":"https://api.github.com/users/RichardScothern/received_events","type":"User","site_admin":false},"body":"Add a generic Manifest interface to represent manifests in the registry and\r\nremove references to schema specific manifests.\r\n\r\nAdd a ManifestBuilder to construct Manifest objects. Concrete manifest builders\r\nwill exist for each manifest type and implementations will contain manifest\r\nspecific data used to build a manifest.\r\n\r\nschema1\r\n-------\r\n\r\nChange the way data is stored in schema1.Manifest to enable Payload() to be used\r\nto return complete Manifest JSON from the HTTP handler without knowledge of the\r\nschema1 protocol.\r\n\r\ntags\r\n----\r\n\r\nMove tag functionality to a seperate TagService and update ManifestService\r\nto use the new interfaces.  Implement a driver based tagService to be backward\r\ncompatible with the current tag service.\r\n\r\nAdd a proxyTagService to enable the registry to get a digest for remote manifests\r\nfrom a tag.\r\n\r\nmanifest store\r\n--------------\r\n\r\nRemove revision store and move all signing functionality into the signed manifeststore.\r\n\r\nmanifest registration\r\n---------------------\r\n\r\nAdd a mechanism to register manifest media types and to allow different manifest\r\ntypes to be Unmarshalled correctly.\r\n\r\nclient\r\n------\r\n\r\nAdd ManifestServiceOptions to client functions to allow tags to be passed into Put and\r\nGet for building correct registry URLs.  Change functional arguments to be an interface type\r\nto allow passing data without mutating shared state.\r\n\r\nSigned-off-by: Richard Scothern <richard.scothern@docker.com>","created_at":"2015-12-15T21:12:15Z","updated_at":"2015-12-15T23:03:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bdff851a7092a37c66ed4549ea4332f6fc35e737","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/docker/distribution/pulls/1268/commits","review_comments_url":"https://api.github.com/repos/docker/distribution/pulls/1268/comments","review_comment_url":"https://api.github.com/repos/docker/distribution/pulls/comments{/number}","comments_url":"https://api.github.com/repos/docker/distribution/issues/1268/comments","statuses_url":"https://api.github.com/repos/docker/distribution/statuses/d21d199198b2484afc73c24a9593f64bfdda8eb4","head":{"label":"RichardScothern:manifest-refactor-impl","ref":"manifest-refactor-impl","sha":"d21d199198b2484afc73c24a9593f64bfdda8eb4","user":{"login":"RichardScothern","id":922018,"avatar_url":"https://avatars.githubusercontent.com/u/922018?v=3","gravatar_id":"","url":"https://api.github.com/users/RichardScothern","html_url":"https://github.com/RichardScothern","followers_url":"https://api.github.com/users/RichardScothern/followers","following_url":"https://api.github.com/users/RichardScothern/following{/other_user}","gists_url":"https://api.github.com/users/RichardScothern/gists{/gist_id}","starred_url":"https://api.github.com/users/RichardScothern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RichardScothern/subscriptions","organizations_url":"https://api.github.com/users/RichardScothern/orgs","repos_url":"https://api.github.com/users/RichardScothern/repos","events_url":"https://api.github.com/users/RichardScothern/events{/privacy}","received_events_url":"https://api.github.com/users/RichardScothern/received_events","type":"User","site_admin":false},"repo":{"id":32835922,"name":"distribution","full_name":"RichardScothern/distribution","owner":{"login":"RichardScothern","id":922018,"avatar_url":"https://avatars.githubusercontent.com/u/922018?v=3","gravatar_id":"","url":"https://api.github.com/users/RichardScothern","html_url":"https://github.com/RichardScothern","followers_url":"https://api.github.com/users/RichardScothern/followers","following_url":"https://api.github.com/users/RichardScothern/following{/other_user}","gists_url":"https://api.github.com/users/RichardScothern/gists{/gist_id}","starred_url":"https://api.github.com/users/RichardScothern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RichardScothern/subscriptions","organizations_url":"https://api.github.com/users/RichardScothern/orgs","repos_url":"https://api.github.com/users/RichardScothern/repos","events_url":"https://api.github.com/users/RichardScothern/events{/privacy}","received_events_url":"https://api.github.com/users/RichardScothern/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/RichardScothern/distribution","description":"The Docker toolset to pack, ship, store, and deliver content","fork":true,"url":"https://api.github.com/repos/RichardScothern/distribution","forks_url":"https://api.github.com/repos/RichardScothern/distribution/forks","keys_url":"https://api.github.com/repos/RichardScothern/distribution/keys{/key_id}","collaborators_url":"https://api.github.com/repos/RichardScothern/distribution/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/RichardScothern/distribution/teams","hooks_url":"https://api.github.com/repos/RichardScothern/distribution/hooks","issue_events_url":"https://api.github.com/repos/RichardScothern/distribution/issues/events{/number}","events_url":"https://api.github.com/repos/RichardScothern/distribution/events","assignees_url":"https://api.github.com/repos/RichardScothern/distribution/assignees{/user}","branches_url":"https://api.github.com/repos/RichardScothern/distribution/branches{/branch}","tags_url":"https://api.github.com/repos/RichardScothern/distribution/tags","blobs_url":"https://api.github.com/repos/RichardScothern/distribution/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/RichardScothern/distribution/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/RichardScothern/distribution/git/refs{/sha}","trees_url":"https://api.github.com/repos/RichardScothern/distribution/git/trees{/sha}","statuses_url":"https://api.github.com/repos/RichardScothern/distribution/statuses/{sha}","languages_url":"https://api.github.com/repos/RichardScothern/distribution/languages","stargazers_url":"https://api.github.com/repos/RichardScothern/distribution/stargazers","contributors_url":"https://api.github.com/repos/RichardScothern/distribution/contributors","subscribers_url":"https://api.github.com/repos/RichardScothern/distribution/subscribers","subscription_url":"https://api.github.com/repos/RichardScothern/distribution/subscription","commits_url":"https://api.github.com/repos/RichardScothern/distribution/commits{/sha}","git_commits_url":"https://api.github.com/repos/RichardScothern/distribution/git/commits{/sha}","comments_url":"https://api.github.com/repos/RichardScothern/distribution/comments{/number}","issue_comment_url":"https://api.github.com/repos/RichardScothern/distribution/issues/comments{/number}","contents_url":"https://api.github.com/repos/RichardScothern/distribution/contents/{+path}","compare_url":"https://api.github.com/repos/RichardScothern/distribution/compare/{base}...{head}","merges_url":"https://api.github.com/repos/RichardScothern/distribution/merges","archive_url":"https://api.github.com/repos/RichardScothern/distribution/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/RichardScothern/distribution/downloads","issues_url":"https://api.github.com/repos/RichardScothern/distribution/issues{/number}","pulls_url":"https://api.github.com/repos/RichardScothern/distribution/pulls{/number}","milestones_url":"https://api.github.com/repos/RichardScothern/distribution/milestones{/number}","notifications_url":"https://api.github.com/repos/RichardScothern/distribution/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/RichardScothern/distribution/labels{/name}","releases_url":"https://api.github.com/repos/RichardScothern/distribution/releases{/id}","created_at":"2015-03-25T01:41:58Z","updated_at":"2015-05-08T16:24:12Z","pushed_at":"2015-12-15T21:11:30Z","git_url":"git://github.com/RichardScothern/distribution.git","ssh_url":"git@github.com:RichardScothern/distribution.git","clone_url":"https://github.com/RichardScothern/distribution.git","svn_url":"https://github.com/RichardScothern/distribution","homepage":null,"size":7580,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"docker:master","ref":"master","sha":"bf09bb1314a5d0d3d582ac8e83fa1a1d9e01a274","user":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=3","gravatar_id":"","url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"repo":{"id":28366058,"name":"distribution","full_name":"docker/distribution","owner":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=3","gravatar_id":"","url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/docker/distribution","description":"The Docker toolset to pack, ship, store, and deliver content","fork":false,"url":"https://api.github.com/repos/docker/distribution","forks_url":"https://api.github.com/repos/docker/distribution/forks","keys_url":"https://api.github.com/repos/docker/distribution/keys{/key_id}","collaborators_url":"https://api.github.com/repos/docker/distribution/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/docker/distribution/teams","hooks_url":"https://api.github.com/repos/docker/distribution/hooks","issue_events_url":"https://api.github.com/repos/docker/distribution/issues/events{/number}","events_url":"https://api.github.com/repos/docker/distribution/events","assignees_url":"https://api.github.com/repos/docker/distribution/assignees{/user}","branches_url":"https://api.github.com/repos/docker/distribution/branches{/branch}","tags_url":"https://api.github.com/repos/docker/distribution/tags","blobs_url":"https://api.github.com/repos/docker/distribution/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/docker/distribution/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/docker/distribution/git/refs{/sha}","trees_url":"https://api.github.com/repos/docker/distribution/git/trees{/sha}","statuses_url":"https://api.github.com/repos/docker/distribution/statuses/{sha}","languages_url":"https://api.github.com/repos/docker/distribution/languages","stargazers_url":"https://api.github.com/repos/docker/distribution/stargazers","contributors_url":"https://api.github.com/repos/docker/distribution/contributors","subscribers_url":"https://api.github.com/repos/docker/distribution/subscribers","subscription_url":"https://api.github.com/repos/docker/distribution/subscription","commits_url":"https://api.github.com/repos/docker/distribution/commits{/sha}","git_commits_url":"https://api.github.com/repos/docker/distribution/git/commits{/sha}","comments_url":"https://api.github.com/repos/docker/distribution/comments{/number}","issue_comment_url":"https://api.github.com/repos/docker/distribution/issues/comments{/number}","contents_url":"https://api.github.com/repos/docker/distribution/contents/{+path}","compare_url":"https://api.github.com/repos/docker/distribution/compare/{base}...{head}","merges_url":"https://api.github.com/repos/docker/distribution/merges","archive_url":"https://api.github.com/repos/docker/distribution/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/docker/distribution/downloads","issues_url":"https://api.github.com/repos/docker/distribution/issues{/number}","pulls_url":"https://api.github.com/repos/docker/distribution/pulls{/number}","milestones_url":"https://api.github.com/repos/docker/distribution/milestones{/number}","notifications_url":"https://api.github.com/repos/docker/distribution/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/docker/distribution/labels{/name}","releases_url":"https://api.github.com/repos/docker/distribution/releases{/id}","created_at":"2014-12-22T23:49:26Z","updated_at":"2015-12-15T17:34:10Z","pushed_at":"2015-12-15T22:55:01Z","git_url":"git://github.com/docker/distribution.git","ssh_url":"git@github.com:docker/distribution.git","clone_url":"https://github.com/docker/distribution.git","svn_url":"https://github.com/docker/distribution","homepage":null,"size":10447,"stargazers_count":1459,"watchers_count":1459,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":554,"mirror_url":null,"open_issues_count":184,"forks":554,"open_issues":184,"watchers":1459,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/docker/distribution/pulls/1268"},"html":{"href":"https://github.com/docker/distribution/pull/1268"},"issue":{"href":"https://api.github.com/repos/docker/distribution/issues/1268"},"comments":{"href":"https://api.github.com/repos/docker/distribution/issues/1268/comments"},"review_comments":{"href":"https://api.github.com/repos/docker/distribution/pulls/1268/comments"},"review_comment":{"href":"https://api.github.com/repos/docker/distribution/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/docker/distribution/pulls/1268/commits"},"statuses":{"href":"https://api.github.com/repos/docker/distribution/statuses/d21d199198b2484afc73c24a9593f64bfdda8eb4"}}}}