{"action":"created","comment":{"url":"https://api.github.com/repos/docker/docker/pulls/comments/34710838","id":34710838,"diff_hunk":"@@ -0,0 +1,369 @@\n+package graph\n+\n+import (\n+\t\"fmt\"\n+\t\"io\"\n+\t\"io/ioutil\"\n+\t\"os\"\n+\n+\t\"github.com/Sirupsen/logrus\"\n+\t\"github.com/docker/distribution\"\n+\t\"github.com/docker/distribution/digest\"\n+\t\"github.com/docker/distribution/manifest\"\n+\t\"github.com/docker/docker/pkg/progressreader\"\n+\t\"github.com/docker/docker/pkg/streamformatter\"\n+\t\"github.com/docker/docker/pkg/stringid\"\n+\t\"github.com/docker/docker/registry\"\n+\t\"github.com/docker/docker/trust\"\n+\t\"github.com/docker/docker/utils\"\n+\t\"github.com/docker/libtrust\"\n+)\n+\n+type v2Puller struct {\n+\t*TagStore\n+\tendpoint registry.APIEndpoint\n+}\n+\n+func (p *v2Puller) Pull(canonicalImageName, name, tag string, imagePullConfig *ImagePullConfig, sf *streamformatter.StreamFormatter) (fallback bool, err error) {\n+\t// TODO(tiborvass): was ReceiveTimeout\n+\trepo, err := NewV2Repository(name, p.endpoint, imagePullConfig.MetaHeaders, imagePullConfig.AuthConfig)\n+\tif err != nil {\n+\t\tlogrus.Debugf(\"Error getting v2 registry: %v\", err)\n+\t\treturn true, err\n+\t}\n+\n+\tif err := p.pullV2Repository(repo, canonicalImageName, tag, imagePullConfig, sf); err != nil {\n+\t\tif registry.ContinueOnError(err) {\n+\t\t\tlogrus.Debugf(\"Error trying v2 registry: %v\", err)\n+\t\t\treturn true, err\n+\t\t}\n+\t\treturn false, err\n+\t}\n+\treturn false, nil\n+}\n+\n+func (p *v2Puller) pullV2Repository(repo distribution.Repository, image, tag string, imagePullConfig *ImagePullConfig, sf *streamformatter.StreamFormatter) (err error) {\n+\tvar tags []string\n+\ttaggedName := image\n+\tif len(tag) > 0 {\n+\t\ttags = []string{tag}\n+\t\ttaggedName = utils.ImageReference(image, tag)\n+\t} else {\n+\t\tvar err error\n+\t\ttags, err = repo.Manifests().Tags()\n+\t\tif err != nil {\n+\t\t\treturn err\n+\t\t}\n+\n+\t}\n+\n+\tc, err := p.poolAdd(\"pull\", taggedName)\n+\tif err != nil {\n+\t\tif c != nil {\n+\t\t\t// Another pull of the same repository is already taking place; just wait for it to finish\n+\t\t\tsf.FormatStatus(\"\", \"Repository %s already being pulled by another client. Waiting.\", image)\n+\t\t\t<-c\n+\t\t\treturn nil\n+\t\t}\n+\t\treturn err\n+\t}\n+\tdefer p.poolRemove(\"pull\", taggedName)\n+\n+\tvar layersDownloaded bool\n+\tfor _, tag := range tags {\n+\t\t// pulledNew is true if either new layers were downloaded OR if existing images were newly tagged\n+\t\t// TODO(tiborvass): should we change the name of `layersDownload`? What about message in WriteStatus?\n+\t\tpulledNew, err := p.pullV2Tag(repo, image, tag, taggedName, imagePullConfig.OutStream, sf)\n+\t\tif err != nil {\n+\t\t\treturn err\n+\t\t}\n+\t\tlayersDownloaded = layersDownloaded || pulledNew\n+\t}\n+\n+\tWriteStatus(taggedName, imagePullConfig.OutStream, sf, layersDownloaded)\n+\n+\treturn nil\n+}\n+\n+func (p *v2Puller) pullV2Tag(repo distribution.Repository, localName, tag, taggedName string, out io.Writer, sf *streamformatter.StreamFormatter) (bool, error) {\n+\tlogrus.Debugf(\"Pulling tag from V2 registry: %q\", tag)\n+\n+\t// downloadInfo is used to pass information from download to extractor\n+\ttype downloadInfo struct {\n+\t\timg     *Image\n+\t\ttmpFile *os.File\n+\t\tdigest  digest.Digest\n+\t\tlayer   distribution.ReadSeekCloser\n+\t\tsize    int64\n+\t\terr     chan error\n+\t}\n+\n+\tmanifest, err := repo.Manifests().GetByTag(tag)\n+\tif err != nil {\n+\t\treturn false, err\n+\t}\n+\tverified, err := p.validateManifest(manifest, tag)\n+\tif err != nil {\n+\t\treturn false, fmt.Errorf(\"error verifying manifest keys: %v\", err)\n+\t}\n+\tif verified {\n+\t\t// TODO(tiborvass): isn't this misleading since the layers have not been verified yet?","path":"graph/pull_v2.go","position":110,"original_position":110,"commit_id":"496067b992286005bf583d7633d3f10ed3640601","original_commit_id":"496067b992286005bf583d7633d3f10ed3640601","user":{"login":"dmcgowan","id":169601,"avatar_url":"https://avatars.githubusercontent.com/u/169601?v=3","gravatar_id":"","url":"https://api.github.com/users/dmcgowan","html_url":"https://github.com/dmcgowan","followers_url":"https://api.github.com/users/dmcgowan/followers","following_url":"https://api.github.com/users/dmcgowan/following{/other_user}","gists_url":"https://api.github.com/users/dmcgowan/gists{/gist_id}","starred_url":"https://api.github.com/users/dmcgowan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmcgowan/subscriptions","organizations_url":"https://api.github.com/users/dmcgowan/orgs","repos_url":"https://api.github.com/users/dmcgowan/repos","events_url":"https://api.github.com/users/dmcgowan/events{/privacy}","received_events_url":"https://api.github.com/users/dmcgowan/received_events","type":"User","site_admin":false},"body":"This is just intended to inform on whether the manifest is verified. If the manifest is verified then every other value downloaded will also be verified. If any verification fails, the operation will fail. Yes the operation can fail despite the manifest being verified, this could still be used for informative purposes about the manifest which provided the content addresses which failed.","created_at":"2015-07-15T18:17:55Z","updated_at":"2015-07-15T18:17:55Z","html_url":"https://github.com/docker/docker/pull/13375#discussion_r34710838","pull_request_url":"https://api.github.com/repos/docker/docker/pulls/13375","_links":{"self":{"href":"https://api.github.com/repos/docker/docker/pulls/comments/34710838"},"html":{"href":"https://github.com/docker/docker/pull/13375#discussion_r34710838"},"pull_request":{"href":"https://api.github.com/repos/docker/docker/pulls/13375"}}},"pull_request":{"url":"https://api.github.com/repos/docker/docker/pulls/13375","id":35892363,"html_url":"https://github.com/docker/docker/pull/13375","diff_url":"https://github.com/docker/docker/pull/13375.diff","patch_url":"https://github.com/docker/docker/pull/13375.patch","issue_url":"https://api.github.com/repos/docker/docker/issues/13375","number":13375,"state":"open","locked":false,"title":"Vendor distribution client v2","user":{"login":"tiborvass","id":827131,"avatar_url":"https://avatars.githubusercontent.com/u/827131?v=3","gravatar_id":"","url":"https://api.github.com/users/tiborvass","html_url":"https://github.com/tiborvass","followers_url":"https://api.github.com/users/tiborvass/followers","following_url":"https://api.github.com/users/tiborvass/following{/other_user}","gists_url":"https://api.github.com/users/tiborvass/gists{/gist_id}","starred_url":"https://api.github.com/users/tiborvass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tiborvass/subscriptions","organizations_url":"https://api.github.com/users/tiborvass/orgs","repos_url":"https://api.github.com/users/tiborvass/repos","events_url":"https://api.github.com/users/tiborvass/events{/privacy}","received_events_url":"https://api.github.com/users/tiborvass/received_events","type":"User","site_admin":false},"body":"This patch vendors the v2 distribution registry client and uses it instead of the v2 codepath in graph/ and registry/ folders. It should not affect the v1 codepath.\r\n\r\nPraise @dmcgowan for the good, blame me for the bad :)\r\n\r\nFixes #12969\r\n\r\n========\r\n\r\nSome clarifications on the value of this PR to help it get merged:\r\n\r\n* **gets rid of the v2 distribution client code from engine**. This alone is HUGE, because it means the distribution team can iterate faster on improvements on both the client and the server. It also means we will have much higher test coverage, so higher quality, less risk.\r\n* Abstracted v1 and v2 behind a Pusher and Puller interface in graph/ to show that those are two completely separate codepaths waiting to be merged and abstracted at a lower level (on the registry client level).\r\n* rewrote ping and fallback logic. This had to be redone, because of how to bootstrap the new v2 glue code. Currently, master has a ping logic that would, on EVERY USER/API REQUEST, ping a v2 endpoint, then ping a v1 endpoint if it failed, and this is what would determine what version of the registry Docker is talking to. Now with this PR, we assume v2 hence skipping the pinging v2 part, we have a (new) notion of endpoints (called `APIEndpoint` in the code) that we try one after the other, if the error returned by a registry API call satisfies a typed-error fallback logic detailed in `registry.WrapError`: so not all errors will fallback to v1. This part will be improved in the future, for instance: allow registry endpoints to determine their fallback policies.\r\n* Towards having one TLS logic: this code got rid of setting up certs, not on every user/api request, but on EVERY REQUEST to the registry (one user request can result in multiple registry requests). @diogomonica @NathanMcCauley please review that part, we added more constraints on ciphers. The idea for the future is to have one package that prepares ready-to-use TLSConfigs for Docker.\r\n* As a result of the previous two, an APIEndpoint is no longer \"secure\" or \"insecure\". It's HTTP, or HTTPS with an InsecureSkipVerify flag set to true or false. Having the HTTP endpoint be a different one than the HTTPS endpoint is cleaner in the code and easier to reason about: if HTTPS fails, try HTTP (which was added to the list of endpoints, only because the registry was marked as insecure).\r\n\r\nBig future direction: the brightest day will be when we can get rid of the v1 code. In order to get there, we will have to refactor some more. Most importantly, we will make what many hoped this PR would do: have the code in graph talk only one API, which gets dispatched to the appropriate API version codepath. We will also get rid of much of the old code in registry/, things like `Endpoint` will retire.\r\n","created_at":"2015-05-21T01:26:48Z","updated_at":"2015-07-15T18:17:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"822da60554a8a677aecbba19e95cfe7b9fbd5275","assignee":{"login":"stevvooe","id":120601,"avatar_url":"https://avatars.githubusercontent.com/u/120601?v=3","gravatar_id":"","url":"https://api.github.com/users/stevvooe","html_url":"https://github.com/stevvooe","followers_url":"https://api.github.com/users/stevvooe/followers","following_url":"https://api.github.com/users/stevvooe/following{/other_user}","gists_url":"https://api.github.com/users/stevvooe/gists{/gist_id}","starred_url":"https://api.github.com/users/stevvooe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevvooe/subscriptions","organizations_url":"https://api.github.com/users/stevvooe/orgs","repos_url":"https://api.github.com/users/stevvooe/repos","events_url":"https://api.github.com/users/stevvooe/events{/privacy}","received_events_url":"https://api.github.com/users/stevvooe/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/docker/docker/milestones/39","html_url":"https://github.com/docker/docker/milestones/1.8.0","labels_url":"https://api.github.com/repos/docker/docker/milestones/39/labels","id":1151952,"number":39,"title":"1.8.0","description":"","creator":{"login":"thaJeztah","id":1804568,"avatar_url":"https://avatars.githubusercontent.com/u/1804568?v=3","gravatar_id":"","url":"https://api.github.com/users/thaJeztah","html_url":"https://github.com/thaJeztah","followers_url":"https://api.github.com/users/thaJeztah/followers","following_url":"https://api.github.com/users/thaJeztah/following{/other_user}","gists_url":"https://api.github.com/users/thaJeztah/gists{/gist_id}","starred_url":"https://api.github.com/users/thaJeztah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thaJeztah/subscriptions","organizations_url":"https://api.github.com/users/thaJeztah/orgs","repos_url":"https://api.github.com/users/thaJeztah/repos","events_url":"https://api.github.com/users/thaJeztah/events{/privacy}","received_events_url":"https://api.github.com/users/thaJeztah/received_events","type":"User","site_admin":false},"open_issues":24,"closed_issues":11,"state":"open","created_at":"2015-06-05T19:27:06Z","updated_at":"2015-07-15T16:39:01Z","due_on":"2015-08-09T22:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/docker/docker/pulls/13375/commits","review_comments_url":"https://api.github.com/repos/docker/docker/pulls/13375/comments","review_comment_url":"https://api.github.com/repos/docker/docker/pulls/comments{/number}","comments_url":"https://api.github.com/repos/docker/docker/issues/13375/comments","statuses_url":"https://api.github.com/repos/docker/docker/statuses/496067b992286005bf583d7633d3f10ed3640601","head":{"label":"tiborvass:distribution-refactor","ref":"distribution-refactor","sha":"496067b992286005bf583d7633d3f10ed3640601","user":{"login":"tiborvass","id":827131,"avatar_url":"https://avatars.githubusercontent.com/u/827131?v=3","gravatar_id":"","url":"https://api.github.com/users/tiborvass","html_url":"https://github.com/tiborvass","followers_url":"https://api.github.com/users/tiborvass/followers","following_url":"https://api.github.com/users/tiborvass/following{/other_user}","gists_url":"https://api.github.com/users/tiborvass/gists{/gist_id}","starred_url":"https://api.github.com/users/tiborvass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tiborvass/subscriptions","organizations_url":"https://api.github.com/users/tiborvass/orgs","repos_url":"https://api.github.com/users/tiborvass/repos","events_url":"https://api.github.com/users/tiborvass/events{/privacy}","received_events_url":"https://api.github.com/users/tiborvass/received_events","type":"User","site_admin":false},"repo":{"id":16678776,"name":"docker","full_name":"tiborvass/docker","owner":{"login":"tiborvass","id":827131,"avatar_url":"https://avatars.githubusercontent.com/u/827131?v=3","gravatar_id":"","url":"https://api.github.com/users/tiborvass","html_url":"https://github.com/tiborvass","followers_url":"https://api.github.com/users/tiborvass/followers","following_url":"https://api.github.com/users/tiborvass/following{/other_user}","gists_url":"https://api.github.com/users/tiborvass/gists{/gist_id}","starred_url":"https://api.github.com/users/tiborvass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tiborvass/subscriptions","organizations_url":"https://api.github.com/users/tiborvass/orgs","repos_url":"https://api.github.com/users/tiborvass/repos","events_url":"https://api.github.com/users/tiborvass/events{/privacy}","received_events_url":"https://api.github.com/users/tiborvass/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tiborvass/docker","description":"Docker - the open-source application container engine","fork":true,"url":"https://api.github.com/repos/tiborvass/docker","forks_url":"https://api.github.com/repos/tiborvass/docker/forks","keys_url":"https://api.github.com/repos/tiborvass/docker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tiborvass/docker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tiborvass/docker/teams","hooks_url":"https://api.github.com/repos/tiborvass/docker/hooks","issue_events_url":"https://api.github.com/repos/tiborvass/docker/issues/events{/number}","events_url":"https://api.github.com/repos/tiborvass/docker/events","assignees_url":"https://api.github.com/repos/tiborvass/docker/assignees{/user}","branches_url":"https://api.github.com/repos/tiborvass/docker/branches{/branch}","tags_url":"https://api.github.com/repos/tiborvass/docker/tags","blobs_url":"https://api.github.com/repos/tiborvass/docker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tiborvass/docker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tiborvass/docker/git/refs{/sha}","trees_url":"https://api.github.com/repos/tiborvass/docker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tiborvass/docker/statuses/{sha}","languages_url":"https://api.github.com/repos/tiborvass/docker/languages","stargazers_url":"https://api.github.com/repos/tiborvass/docker/stargazers","contributors_url":"https://api.github.com/repos/tiborvass/docker/contributors","subscribers_url":"https://api.github.com/repos/tiborvass/docker/subscribers","subscription_url":"https://api.github.com/repos/tiborvass/docker/subscription","commits_url":"https://api.github.com/repos/tiborvass/docker/commits{/sha}","git_commits_url":"https://api.github.com/repos/tiborvass/docker/git/commits{/sha}","comments_url":"https://api.github.com/repos/tiborvass/docker/comments{/number}","issue_comment_url":"https://api.github.com/repos/tiborvass/docker/issues/comments{/number}","contents_url":"https://api.github.com/repos/tiborvass/docker/contents/{+path}","compare_url":"https://api.github.com/repos/tiborvass/docker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tiborvass/docker/merges","archive_url":"https://api.github.com/repos/tiborvass/docker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tiborvass/docker/downloads","issues_url":"https://api.github.com/repos/tiborvass/docker/issues{/number}","pulls_url":"https://api.github.com/repos/tiborvass/docker/pulls{/number}","milestones_url":"https://api.github.com/repos/tiborvass/docker/milestones{/number}","notifications_url":"https://api.github.com/repos/tiborvass/docker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tiborvass/docker/labels{/name}","releases_url":"https://api.github.com/repos/tiborvass/docker/releases{/id}","created_at":"2014-02-09T23:31:28Z","updated_at":"2014-07-24T21:22:38Z","pushed_at":"2015-07-14T21:48:43Z","git_url":"git://github.com/tiborvass/docker.git","ssh_url":"git@github.com:tiborvass/docker.git","clone_url":"https://github.com/tiborvass/docker.git","svn_url":"https://github.com/tiborvass/docker","homepage":"http://www.docker.io","size":62276,"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":"4e9280ffdb40f6370f808c81f72a19f1332a0287","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":7691631,"name":"docker","full_name":"docker/docker","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/docker","description":"Docker - the open-source application container engine","fork":false,"url":"https://api.github.com/repos/docker/docker","forks_url":"https://api.github.com/repos/docker/docker/forks","keys_url":"https://api.github.com/repos/docker/docker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/docker/docker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/docker/docker/teams","hooks_url":"https://api.github.com/repos/docker/docker/hooks","issue_events_url":"https://api.github.com/repos/docker/docker/issues/events{/number}","events_url":"https://api.github.com/repos/docker/docker/events","assignees_url":"https://api.github.com/repos/docker/docker/assignees{/user}","branches_url":"https://api.github.com/repos/docker/docker/branches{/branch}","tags_url":"https://api.github.com/repos/docker/docker/tags","blobs_url":"https://api.github.com/repos/docker/docker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/docker/docker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/docker/docker/git/refs{/sha}","trees_url":"https://api.github.com/repos/docker/docker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/docker/docker/statuses/{sha}","languages_url":"https://api.github.com/repos/docker/docker/languages","stargazers_url":"https://api.github.com/repos/docker/docker/stargazers","contributors_url":"https://api.github.com/repos/docker/docker/contributors","subscribers_url":"https://api.github.com/repos/docker/docker/subscribers","subscription_url":"https://api.github.com/repos/docker/docker/subscription","commits_url":"https://api.github.com/repos/docker/docker/commits{/sha}","git_commits_url":"https://api.github.com/repos/docker/docker/git/commits{/sha}","comments_url":"https://api.github.com/repos/docker/docker/comments{/number}","issue_comment_url":"https://api.github.com/repos/docker/docker/issues/comments{/number}","contents_url":"https://api.github.com/repos/docker/docker/contents/{+path}","compare_url":"https://api.github.com/repos/docker/docker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/docker/docker/merges","archive_url":"https://api.github.com/repos/docker/docker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/docker/docker/downloads","issues_url":"https://api.github.com/repos/docker/docker/issues{/number}","pulls_url":"https://api.github.com/repos/docker/docker/pulls{/number}","milestones_url":"https://api.github.com/repos/docker/docker/milestones{/number}","notifications_url":"https://api.github.com/repos/docker/docker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/docker/docker/labels{/name}","releases_url":"https://api.github.com/repos/docker/docker/releases{/id}","created_at":"2013-01-18T18:10:57Z","updated_at":"2015-07-15T17:59:48Z","pushed_at":"2015-07-15T18:09:15Z","git_url":"git://github.com/docker/docker.git","ssh_url":"git@github.com:docker/docker.git","clone_url":"https://github.com/docker/docker.git","svn_url":"https://github.com/docker/docker","homepage":"http://www.docker.com","size":224059,"stargazers_count":23271,"watchers_count":23271,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5767,"mirror_url":null,"open_issues_count":1031,"forks":5767,"open_issues":1031,"watchers":23271,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/docker/docker/pulls/13375"},"html":{"href":"https://github.com/docker/docker/pull/13375"},"issue":{"href":"https://api.github.com/repos/docker/docker/issues/13375"},"comments":{"href":"https://api.github.com/repos/docker/docker/issues/13375/comments"},"review_comments":{"href":"https://api.github.com/repos/docker/docker/pulls/13375/comments"},"review_comment":{"href":"https://api.github.com/repos/docker/docker/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/docker/docker/pulls/13375/commits"},"statuses":{"href":"https://api.github.com/repos/docker/docker/statuses/496067b992286005bf583d7633d3f10ed3640601"}}}}