{"action":"created","comment":{"url":"https://api.github.com/repos/alibaba/pouch/pulls/comments/228846196","pull_request_review_id":169203571,"id":228846196,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyODg0NjE5Ng==","diff_hunk":"@@ -0,0 +1,81 @@\n+package logger\n+\n+import (\n+\t\"bufio\"\n+\t\"io\"\n+\t\"sync\"\n+\t\"time\"\n+\n+\t\"github.com/sirupsen/logrus\"\n+)\n+\n+// LogCopier is used to copy data from stream and write it into LogDriver.\n+type LogCopier struct {\n+\tsync.WaitGroup\n+\tsrcs map[string]io.Reader\n+\tdst  LogDriver\n+}\n+\n+// NewLogCopier creates copier for logger.\n+func NewLogCopier(dst LogDriver, srcs map[string]io.Reader) *LogCopier {\n+\treturn &LogCopier{\n+\t\tsrcs: srcs,\n+\t\tdst:  dst,\n+\t}\n+}\n+\n+// StartCopy starts to read the data and write it into logger.\n+func (lc *LogCopier) StartCopy() {\n+\tfor source, r := range lc.srcs {\n+\t\tlc.Add(1)\n+\t\tgo lc.copy(source, r)\n+\t}\n+}\n+\n+func (lc *LogCopier) copy(source string, reader io.Reader) {\n+\tdefer logrus.Debugf(\"finish %s stream type logcopy for %s\", source, lc.dst.Name())\n+\tdefer lc.Done()\n+\n+\tvar (\n+\t\tbs  []byte\n+\t\terr error\n+\n+\t\tfirstPartial = true\n+\t\tisPartial    bool\n+\t\tcreatedTime  time.Time\n+\n+\t\tdefaultBufSize = 16 * 1024\n+\t)\n+\n+\tbr := bufio.NewReaderSize(reader, defaultBufSize)\n+\tfor {\n+\t\tbs, isPartial, err = br.ReadLine()","path":"daemon/logger/copier.go","position":52,"original_position":52,"commit_id":"77019b6b4800d1953df51dc5fd5f4ae61801fa77","original_commit_id":"77019b6b4800d1953df51dc5fd5f4ae61801fa77","user":{"login":"Starnop","id":31209634,"node_id":"MDQ6VXNlcjMxMjA5NjM0","avatar_url":"https://avatars2.githubusercontent.com/u/31209634?v=4","gravatar_id":"","url":"https://api.github.com/users/Starnop","html_url":"https://github.com/Starnop","followers_url":"https://api.github.com/users/Starnop/followers","following_url":"https://api.github.com/users/Starnop/following{/other_user}","gists_url":"https://api.github.com/users/Starnop/gists{/gist_id}","starred_url":"https://api.github.com/users/Starnop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Starnop/subscriptions","organizations_url":"https://api.github.com/users/Starnop/orgs","repos_url":"https://api.github.com/users/Starnop/repos","events_url":"https://api.github.com/users/Starnop/events{/privacy}","received_events_url":"https://api.github.com/users/Starnop/received_events","type":"User","site_admin":false},"body":"ReadLine is a low-level line-reading primitive. Most callers should use ReadBytes('\\n') or ReadString('\\n') instead or use a Scanner. WDYT?","created_at":"2018-10-29T09:18:01Z","updated_at":"2018-10-29T09:18:11Z","html_url":"https://github.com/alibaba/pouch/pull/2375#discussion_r228846196","pull_request_url":"https://api.github.com/repos/alibaba/pouch/pulls/2375","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/alibaba/pouch/pulls/comments/228846196"},"html":{"href":"https://github.com/alibaba/pouch/pull/2375#discussion_r228846196"},"pull_request":{"href":"https://api.github.com/repos/alibaba/pouch/pulls/2375"}}},"pull_request":{"url":"https://api.github.com/repos/alibaba/pouch/pulls/2375","id":226355897,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI2MzU1ODk3","html_url":"https://github.com/alibaba/pouch/pull/2375","diff_url":"https://github.com/alibaba/pouch/pull/2375.diff","patch_url":"https://github.com/alibaba/pouch/pull/2375.patch","issue_url":"https://api.github.com/repos/alibaba/pouch/issues/2375","number":2375,"state":"open","locked":false,"title":"[WIP|RFC] refactor: redesign container io in pouch","user":{"login":"fuweid","id":17510957,"node_id":"MDQ6VXNlcjE3NTEwOTU3","avatar_url":"https://avatars3.githubusercontent.com/u/17510957?v=4","gravatar_id":"","url":"https://api.github.com/users/fuweid","html_url":"https://github.com/fuweid","followers_url":"https://api.github.com/users/fuweid/followers","following_url":"https://api.github.com/users/fuweid/following{/other_user}","gists_url":"https://api.github.com/users/fuweid/gists{/gist_id}","starred_url":"https://api.github.com/users/fuweid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fuweid/subscriptions","organizations_url":"https://api.github.com/users/fuweid/orgs","repos_url":"https://api.github.com/users/fuweid/repos","events_url":"https://api.github.com/users/fuweid/events{/privacy}","received_events_url":"https://api.github.com/users/fuweid/received_events","type":"User","site_admin":false},"body":"Signed-off-by: Wei Fu <fuweid89@gmail.com>\r\n\r\n<!-- \r\nPlease make sure you have read and understood the contributing guidelines;\r\nhttps://github.com/alibaba/pouch/blob/master/CONTRIBUTING.md -->\r\n\r\n### Ⅰ. Describe what this PR did\r\n\r\nRedesign container io in pouch. but Why?\r\n\r\nThe original design always uses `ringbuffer` to cache the data which causes streams lost data sometime. It makes the regression test unstable. \r\n\r\nIt also makes caller hard to touch data from containerd-shim. That is why we still miss the ReopenLog in CRI. I think we should fix that.\r\n\r\n#### design overview\r\n\r\n![pouchcontainer io](https://user-images.githubusercontent.com/17510957/47630439-c3f6ec80-db7b-11e8-8800-0b0fa9e84779.png)\r\n\r\nEach container/process will hold streams struct to handle the io stream. The struct is like:\r\n\r\n```\r\n// Stream is used to handle container IO.\r\ntype Stream struct {\r\n        sync.WaitGroup\r\n        stdin          io.ReadCloser\r\n        stdinPipe      io.WriteCloser\r\n        stdout, stderr *multiWriter\r\n}\r\n```\r\n\r\nIn the stream struct, both the `stdout` and `stderr` are the multiple writer's hub. It means that the data from stdout/stderr of process will have more copies. For example, when user use `run` to start container, the container's output data will have two copies. One is for the terminal side, the other one is for container's log, such as json-file by default.\r\n\r\nBut for the `stdin`, we don't need the hub like `stdout/stderr`, because the input of process is only one. Any attach requests can send the data to the process in container. So we exports the `stdinPipe` to allow different attach requests to touch the same input channel.\r\n\r\nBased on this, the stream acts like bridge to connect attach request and stream of process in container. If the user wants to attach running container, just adds hijack/stream into the output hub and attach it to the `stdinPipe`. The stream can provides more flexible than before.\r\n\r\nBefore this change, the CRI struggles to integrating with Container Mgr. Why? because CRI component doesn't know the stream has been finished. Always use dead loop to check the `Exec` status. It's not good patten.\r\n\r\n#### why add logdriver/crilog into the writer hub?\r\n\r\n![pouchcontainer io 1](https://user-images.githubusercontent.com/17510957/47630979-c9a20180-db7e-11e8-9eb1-9243a4b671c6.png)\r\n\r\nBoth logdriver and crilog don't act like `io.Writer`. It always add meta data for the raw data. Adding the partial label is one of examples for the acting way of logdriver. In order to avoid to add duplicate code for each driver, we use `LogCopier` to handle this.\r\n\r\nThere is a little bit different between `crilog` and `logdriver`. The `crilog` has `ReopenLog` request. It means that it will add new crilog and close previous one. \r\n\r\nIn current design, we might have duplicate data in the crilog. Because we close previous, the writer-hub might write something into that. I think it's ok right now.\r\n\r\n#### What is the CloseIO and `StdinOnce`?\r\n\r\nThe contained-shim will open fifo twice for reading and writing. For the writing mode, the shim doesn't close stdin fifo until the client calls `CloseIO`. In some case, the pouch daemon might be crash before finishing the input. If shim doesn't hold writing mode fifo, the process in container will consider that it is EOF signal and exit. \r\n\r\nBased on this case, if the client sends EOF signal to input channel, the pouchd should send the CloseIO to shim to let the process exit.\r\n\r\n`StdinOnce` in container's config is used by attach request. If the `StdinOnce` is true, when one attach request finishes stream copy, the pouchd will closes the input of process. So other attach requests to the same container will be stopped.\r\n\r\nIf the user wants `StdinOnce`, it should set it to true during creating container.\r\n \r\n> NOTE: doc link is [here](https://docs.google.com/presentation/d/1TYC_W_uNKvmszKPhEqKXsbQXRKtiyAES3ulfaTsdhiM/edit?usp=sharing).\r\n\r\n### Ⅱ. Does this pull request fix one issue?\r\n<!--If that, add \"fixes #xxxx\" below in the next line, for example, fixes #15. Otherwise, add \"NONE\" -->\r\n\r\nNONE\r\n\r\n### Ⅲ. Why don't you add test cases (unit test/integration test)? (你真的觉得不需要加测试吗？)\r\n\r\nAdded it.\r\n\r\n### Ⅳ. Describe how to verify it\r\n\r\nWait for CI.\r\n\r\n\r\n### Ⅴ. Special notes for reviews\r\n\r\nI remove the `non-blocking` feature in this change and will add it in next patch.","created_at":"2018-10-28T10:08:26Z","updated_at":"2018-10-29T09:18:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5de8a002f5a26dc8b6c96fd83feaaa3fce484b52","assignee":null,"assignees":[],"requested_reviewers":[{"login":"YaoZengzeng","id":8636562,"node_id":"MDQ6VXNlcjg2MzY1NjI=","avatar_url":"https://avatars1.githubusercontent.com/u/8636562?v=4","gravatar_id":"","url":"https://api.github.com/users/YaoZengzeng","html_url":"https://github.com/YaoZengzeng","followers_url":"https://api.github.com/users/YaoZengzeng/followers","following_url":"https://api.github.com/users/YaoZengzeng/following{/other_user}","gists_url":"https://api.github.com/users/YaoZengzeng/gists{/gist_id}","starred_url":"https://api.github.com/users/YaoZengzeng/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/YaoZengzeng/subscriptions","organizations_url":"https://api.github.com/users/YaoZengzeng/orgs","repos_url":"https://api.github.com/users/YaoZengzeng/repos","events_url":"https://api.github.com/users/YaoZengzeng/events{/privacy}","received_events_url":"https://api.github.com/users/YaoZengzeng/received_events","type":"User","site_admin":false},{"login":"Ace-Tang","id":10334997,"node_id":"MDQ6VXNlcjEwMzM0OTk3","avatar_url":"https://avatars0.githubusercontent.com/u/10334997?v=4","gravatar_id":"","url":"https://api.github.com/users/Ace-Tang","html_url":"https://github.com/Ace-Tang","followers_url":"https://api.github.com/users/Ace-Tang/followers","following_url":"https://api.github.com/users/Ace-Tang/following{/other_user}","gists_url":"https://api.github.com/users/Ace-Tang/gists{/gist_id}","starred_url":"https://api.github.com/users/Ace-Tang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ace-Tang/subscriptions","organizations_url":"https://api.github.com/users/Ace-Tang/orgs","repos_url":"https://api.github.com/users/Ace-Tang/repos","events_url":"https://api.github.com/users/Ace-Tang/events{/privacy}","received_events_url":"https://api.github.com/users/Ace-Tang/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":722351185,"node_id":"MDU6TGFiZWw3MjIzNTExODU=","url":"https://api.github.com/repos/alibaba/pouch/labels/kind/design","name":"kind/design","color":"c2e0c6","default":false},{"id":743028221,"node_id":"MDU6TGFiZWw3NDMwMjgyMjE=","url":"https://api.github.com/repos/alibaba/pouch/labels/kind/refactor","name":"kind/refactor","color":"fbca04","default":false},{"id":722355711,"node_id":"MDU6TGFiZWw3MjIzNTU3MTE=","url":"https://api.github.com/repos/alibaba/pouch/labels/size/XXL","name":"size/XXL","color":"cc3d73","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/alibaba/pouch/pulls/2375/commits","review_comments_url":"https://api.github.com/repos/alibaba/pouch/pulls/2375/comments","review_comment_url":"https://api.github.com/repos/alibaba/pouch/pulls/comments{/number}","comments_url":"https://api.github.com/repos/alibaba/pouch/issues/2375/comments","statuses_url":"https://api.github.com/repos/alibaba/pouch/statuses/77019b6b4800d1953df51dc5fd5f4ae61801fa77","head":{"label":"fuweid:refactor_stream_io","ref":"refactor_stream_io","sha":"77019b6b4800d1953df51dc5fd5f4ae61801fa77","user":{"login":"fuweid","id":17510957,"node_id":"MDQ6VXNlcjE3NTEwOTU3","avatar_url":"https://avatars3.githubusercontent.com/u/17510957?v=4","gravatar_id":"","url":"https://api.github.com/users/fuweid","html_url":"https://github.com/fuweid","followers_url":"https://api.github.com/users/fuweid/followers","following_url":"https://api.github.com/users/fuweid/following{/other_user}","gists_url":"https://api.github.com/users/fuweid/gists{/gist_id}","starred_url":"https://api.github.com/users/fuweid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fuweid/subscriptions","organizations_url":"https://api.github.com/users/fuweid/orgs","repos_url":"https://api.github.com/users/fuweid/repos","events_url":"https://api.github.com/users/fuweid/events{/privacy}","received_events_url":"https://api.github.com/users/fuweid/received_events","type":"User","site_admin":false},"repo":{"id":143372593,"node_id":"MDEwOlJlcG9zaXRvcnkxNDMzNzI1OTM=","name":"pouch","full_name":"fuweid/pouch","private":false,"owner":{"login":"fuweid","id":17510957,"node_id":"MDQ6VXNlcjE3NTEwOTU3","avatar_url":"https://avatars3.githubusercontent.com/u/17510957?v=4","gravatar_id":"","url":"https://api.github.com/users/fuweid","html_url":"https://github.com/fuweid","followers_url":"https://api.github.com/users/fuweid/followers","following_url":"https://api.github.com/users/fuweid/following{/other_user}","gists_url":"https://api.github.com/users/fuweid/gists{/gist_id}","starred_url":"https://api.github.com/users/fuweid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fuweid/subscriptions","organizations_url":"https://api.github.com/users/fuweid/orgs","repos_url":"https://api.github.com/users/fuweid/repos","events_url":"https://api.github.com/users/fuweid/events{/privacy}","received_events_url":"https://api.github.com/users/fuweid/received_events","type":"User","site_admin":false},"html_url":"https://github.com/fuweid/pouch","description":"An Efficient Enterprise-class Rich Container Engine","fork":true,"url":"https://api.github.com/repos/fuweid/pouch","forks_url":"https://api.github.com/repos/fuweid/pouch/forks","keys_url":"https://api.github.com/repos/fuweid/pouch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fuweid/pouch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fuweid/pouch/teams","hooks_url":"https://api.github.com/repos/fuweid/pouch/hooks","issue_events_url":"https://api.github.com/repos/fuweid/pouch/issues/events{/number}","events_url":"https://api.github.com/repos/fuweid/pouch/events","assignees_url":"https://api.github.com/repos/fuweid/pouch/assignees{/user}","branches_url":"https://api.github.com/repos/fuweid/pouch/branches{/branch}","tags_url":"https://api.github.com/repos/fuweid/pouch/tags","blobs_url":"https://api.github.com/repos/fuweid/pouch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fuweid/pouch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fuweid/pouch/git/refs{/sha}","trees_url":"https://api.github.com/repos/fuweid/pouch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fuweid/pouch/statuses/{sha}","languages_url":"https://api.github.com/repos/fuweid/pouch/languages","stargazers_url":"https://api.github.com/repos/fuweid/pouch/stargazers","contributors_url":"https://api.github.com/repos/fuweid/pouch/contributors","subscribers_url":"https://api.github.com/repos/fuweid/pouch/subscribers","subscription_url":"https://api.github.com/repos/fuweid/pouch/subscription","commits_url":"https://api.github.com/repos/fuweid/pouch/commits{/sha}","git_commits_url":"https://api.github.com/repos/fuweid/pouch/git/commits{/sha}","comments_url":"https://api.github.com/repos/fuweid/pouch/comments{/number}","issue_comment_url":"https://api.github.com/repos/fuweid/pouch/issues/comments{/number}","contents_url":"https://api.github.com/repos/fuweid/pouch/contents/{+path}","compare_url":"https://api.github.com/repos/fuweid/pouch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fuweid/pouch/merges","archive_url":"https://api.github.com/repos/fuweid/pouch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fuweid/pouch/downloads","issues_url":"https://api.github.com/repos/fuweid/pouch/issues{/number}","pulls_url":"https://api.github.com/repos/fuweid/pouch/pulls{/number}","milestones_url":"https://api.github.com/repos/fuweid/pouch/milestones{/number}","notifications_url":"https://api.github.com/repos/fuweid/pouch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fuweid/pouch/labels{/name}","releases_url":"https://api.github.com/repos/fuweid/pouch/releases{/id}","deployments_url":"https://api.github.com/repos/fuweid/pouch/deployments","created_at":"2018-08-03T03:23:54Z","updated_at":"2018-10-25T09:56:24Z","pushed_at":"2018-10-29T08:43:51Z","git_url":"git://github.com/fuweid/pouch.git","ssh_url":"git@github.com:fuweid/pouch.git","clone_url":"https://github.com/fuweid/pouch.git","svn_url":"https://github.com/fuweid/pouch","homepage":"https://pouchcontainer.io","size":20639,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"alibaba:master","ref":"master","sha":"17eb976b43e83fbfdc40cc3dc000564c1d929be0","user":{"login":"alibaba","id":1961952,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE5NjE5NTI=","avatar_url":"https://avatars1.githubusercontent.com/u/1961952?v=4","gravatar_id":"","url":"https://api.github.com/users/alibaba","html_url":"https://github.com/alibaba","followers_url":"https://api.github.com/users/alibaba/followers","following_url":"https://api.github.com/users/alibaba/following{/other_user}","gists_url":"https://api.github.com/users/alibaba/gists{/gist_id}","starred_url":"https://api.github.com/users/alibaba/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alibaba/subscriptions","organizations_url":"https://api.github.com/users/alibaba/orgs","repos_url":"https://api.github.com/users/alibaba/repos","events_url":"https://api.github.com/users/alibaba/events{/privacy}","received_events_url":"https://api.github.com/users/alibaba/received_events","type":"Organization","site_admin":false},"repo":{"id":102555965,"node_id":"MDEwOlJlcG9zaXRvcnkxMDI1NTU5NjU=","name":"pouch","full_name":"alibaba/pouch","private":false,"owner":{"login":"alibaba","id":1961952,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE5NjE5NTI=","avatar_url":"https://avatars1.githubusercontent.com/u/1961952?v=4","gravatar_id":"","url":"https://api.github.com/users/alibaba","html_url":"https://github.com/alibaba","followers_url":"https://api.github.com/users/alibaba/followers","following_url":"https://api.github.com/users/alibaba/following{/other_user}","gists_url":"https://api.github.com/users/alibaba/gists{/gist_id}","starred_url":"https://api.github.com/users/alibaba/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alibaba/subscriptions","organizations_url":"https://api.github.com/users/alibaba/orgs","repos_url":"https://api.github.com/users/alibaba/repos","events_url":"https://api.github.com/users/alibaba/events{/privacy}","received_events_url":"https://api.github.com/users/alibaba/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/alibaba/pouch","description":"An Efficient Enterprise-class Rich Container Engine","fork":false,"url":"https://api.github.com/repos/alibaba/pouch","forks_url":"https://api.github.com/repos/alibaba/pouch/forks","keys_url":"https://api.github.com/repos/alibaba/pouch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/alibaba/pouch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/alibaba/pouch/teams","hooks_url":"https://api.github.com/repos/alibaba/pouch/hooks","issue_events_url":"https://api.github.com/repos/alibaba/pouch/issues/events{/number}","events_url":"https://api.github.com/repos/alibaba/pouch/events","assignees_url":"https://api.github.com/repos/alibaba/pouch/assignees{/user}","branches_url":"https://api.github.com/repos/alibaba/pouch/branches{/branch}","tags_url":"https://api.github.com/repos/alibaba/pouch/tags","blobs_url":"https://api.github.com/repos/alibaba/pouch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/alibaba/pouch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/alibaba/pouch/git/refs{/sha}","trees_url":"https://api.github.com/repos/alibaba/pouch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/alibaba/pouch/statuses/{sha}","languages_url":"https://api.github.com/repos/alibaba/pouch/languages","stargazers_url":"https://api.github.com/repos/alibaba/pouch/stargazers","contributors_url":"https://api.github.com/repos/alibaba/pouch/contributors","subscribers_url":"https://api.github.com/repos/alibaba/pouch/subscribers","subscription_url":"https://api.github.com/repos/alibaba/pouch/subscription","commits_url":"https://api.github.com/repos/alibaba/pouch/commits{/sha}","git_commits_url":"https://api.github.com/repos/alibaba/pouch/git/commits{/sha}","comments_url":"https://api.github.com/repos/alibaba/pouch/comments{/number}","issue_comment_url":"https://api.github.com/repos/alibaba/pouch/issues/comments{/number}","contents_url":"https://api.github.com/repos/alibaba/pouch/contents/{+path}","compare_url":"https://api.github.com/repos/alibaba/pouch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/alibaba/pouch/merges","archive_url":"https://api.github.com/repos/alibaba/pouch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/alibaba/pouch/downloads","issues_url":"https://api.github.com/repos/alibaba/pouch/issues{/number}","pulls_url":"https://api.github.com/repos/alibaba/pouch/pulls{/number}","milestones_url":"https://api.github.com/repos/alibaba/pouch/milestones{/number}","notifications_url":"https://api.github.com/repos/alibaba/pouch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/alibaba/pouch/labels{/name}","releases_url":"https://api.github.com/repos/alibaba/pouch/releases{/id}","deployments_url":"https://api.github.com/repos/alibaba/pouch/deployments","created_at":"2017-09-06T03:01:51Z","updated_at":"2018-10-29T08:07:28Z","pushed_at":"2018-10-29T09:13:02Z","git_url":"git://github.com/alibaba/pouch.git","ssh_url":"git@github.com:alibaba/pouch.git","clone_url":"https://github.com/alibaba/pouch.git","svn_url":"https://github.com/alibaba/pouch","homepage":"https://pouchcontainer.io","size":20598,"stargazers_count":3428,"watchers_count":3428,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":837,"mirror_url":null,"archived":false,"open_issues_count":156,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":837,"open_issues":156,"watchers":3428,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/alibaba/pouch/pulls/2375"},"html":{"href":"https://github.com/alibaba/pouch/pull/2375"},"issue":{"href":"https://api.github.com/repos/alibaba/pouch/issues/2375"},"comments":{"href":"https://api.github.com/repos/alibaba/pouch/issues/2375/comments"},"review_comments":{"href":"https://api.github.com/repos/alibaba/pouch/pulls/2375/comments"},"review_comment":{"href":"https://api.github.com/repos/alibaba/pouch/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/alibaba/pouch/pulls/2375/commits"},"statuses":{"href":"https://api.github.com/repos/alibaba/pouch/statuses/77019b6b4800d1953df51dc5fd5f4ae61801fa77"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"Starnop"}}