{"action":"created","comment":{"url":"https://api.github.com/repos/containers/libpod/pulls/comments/234066974","pull_request_review_id":175629313,"id":234066974,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzNDA2Njk3NA==","diff_hunk":"@@ -1076,3 +1078,144 @@ func (i *Image) Comment(ctx context.Context, manifestType string) (string, error\n \t}\n \treturn ociv1Img.History[0].Comment, nil\n }\n+\n+type TreeImage struct {\n+\tID       string\n+\tParentID string\n+\tRepoTags []string\n+\tSize     int64\n+}\n+\n+// Tree gets dependency list in tree format of the image\n+func (i *Image) Tree(ctx context.Context, imageName string) (*bytes.Buffer, error) {\n+\n+\tlayerMap, err := i.layerToImageMap(ctx)\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\tlayerMap, err = i.addImageToLayerInfo(ctx, layerMap)\n+\n+\trepoTag, err := i.MatchRepoTag(imageName)\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\t// Get the image top layer and then parse as per parent\n+\tlayer := i.TopLayer()\n+\tdependencyList := returnDependencyTree(layerMap, repoTag, layer)\n+\n+\tvar buffer bytes.Buffer\n+\tprintTree(&buffer, dependencyList)\n+\n+\treturn &buffer, err\n+}\n+\n+func printTree(buffer *bytes.Buffer, treeStack []TreeImage) {\n+\n+\tprefixSpace := 0\n+\tfor i := len(treeStack) - 1; i >= 0; i-- {\n+\t\tfor p := 0; p < prefixSpace; p++ {\n+\t\t\tbuffer.WriteString(fmt.Sprintf(\" \"))\n+\t\t}\n+\t\tbuffer.WriteString(fmt.Sprintf(\"└─ ID: %s  Tags: %s VirtualSize: %v\\n\",\n+\t\t\ttreeStack[i].ID[:12],\n+\t\t\ttreeStack[i].RepoTags,\n+\t\t\tunits.HumanSizeWithPrecision(float64(treeStack[i].Size), 4)),\n+\t\t)\n+\n+\t\tprefixSpace++\n+\t}\n+}\n+\n+func (i *Image) layerToImageMap(ctx context.Context) (map[string]*TreeImage, error) {\n+\tlayerMap := make(map[string]*TreeImage)\n+\tlayers, _ := i.imageruntime.store.Layers()\n+\tfor _, layer := range layers {\n+\t\texistingLayer, ok := layerMap[layer.ID]\n+\t\tif !ok {\n+\t\t\tlayerMap[layer.ID] = &TreeImage{\n+\t\t\t\tID:       layer.ID,\n+\t\t\t\tSize:     layer.CompressedSize,\n+\t\t\t\tParentID: layer.Parent,\n+\t\t\t}\n+\t\t} else {\n+\t\t\treturn nil, fmt.Errorf(\"duplicate %s layer found in image store\", existingLayer.ID)\n+\t\t}\n+\t}\n+\treturn layerMap, nil\n+}\n+\n+func (i *Image) addImageToLayerInfo(ctx context.Context, layerMap map[string]*TreeImage) (map[string]*TreeImage, error) {\n+\timages, err := i.imageruntime.GetImages()\n+\tif err != nil {\n+\t\treturn nil, errors.Wrapf(err, \"error getting images from store\")\n+\t}\n+\n+\tfor _, image := range images {\n+\n+\t\tlayerid := image.TopLayer()\n+\t\timgLayer, err := image.imageruntime.store.Layer(layerid)\n+\t\tif err != nil {\n+\t\t\treturn nil, err\n+\t\t}\n+\n+\t\tfor imgLayer != nil {\n+\t\t\texistingLayer, ok := layerMap[imgLayer.ID]\n+\t\t\tif !ok {\n+\t\t\t\treturn nil, fmt.Errorf(\"layer %s not found \", imgLayer.ID)\n+\t\t\t} else {\n+\t\t\t\tnames := image.Names()\n+\t\t\t\texistingLayer.RepoTags = append(existingLayer.RepoTags, names...)\n+\t\t\t}\n+\t\t\timgLayer = image.getLayer(imgLayer.Parent)\n+\t\t}\n+\t}\n+\treturn layerMap, nil\n+}\n+\n+func (i *Image) getLayer(layerID string) *storage.Layer {\n+\tlayers, err := i.imageruntime.store.Layers()\n+\tif err != nil {\n+\t\treturn nil\n+\t}\n+\n+\tfor _, layer := range layers {\n+\t\tif layerID == layer.ID {\n+\t\t\treturn &layer\n+\t\t}\n+\t}\n+\treturn nil\n+}\n+\n+func returnDependencyTree(layerMap map[string]*TreeImage, repoTag string, layerID string) []TreeImage {\n+\tvar treeStack []TreeImage\n+\tprevious := TreeImage{}\n+\tlayerInfo, ok := layerMap[layerID]\n+\tfor ok {\n+\t\tappended := false","path":"libpod/image/image.go","position":120,"original_position":133,"commit_id":"479411606f1e64beb2ebd90122a96ee16cd2961a","original_commit_id":"5b7191d40b28f767cc3d6a44a4770885f377dd9b","user":{"login":"mtrmac","id":7052838,"node_id":"MDQ6VXNlcjcwNTI4Mzg=","avatar_url":"https://avatars2.githubusercontent.com/u/7052838?v=4","gravatar_id":"","url":"https://api.github.com/users/mtrmac","html_url":"https://github.com/mtrmac","followers_url":"https://api.github.com/users/mtrmac/followers","following_url":"https://api.github.com/users/mtrmac/following{/other_user}","gists_url":"https://api.github.com/users/mtrmac/gists{/gist_id}","starred_url":"https://api.github.com/users/mtrmac/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mtrmac/subscriptions","organizations_url":"https://api.github.com/users/mtrmac/orgs","repos_url":"https://api.github.com/users/mtrmac/repos","events_url":"https://api.github.com/users/mtrmac/events{/privacy}","received_events_url":"https://api.github.com/users/mtrmac/received_events","type":"User","site_admin":false},"body":"This does not look right — AFAICS on a name change, `appended` is set after appending the “old” name, but the `!appended` check could mean that the “new” name is never recorded.\r\n\r\nIIRC the old code was closer to correct, and the variable could have just been removed — but first the general semantics of this loop needs to be decided.","created_at":"2018-11-16T01:39:27Z","updated_at":"2018-11-16T01:39:27Z","html_url":"https://github.com/containers/libpod/pull/1642#discussion_r234066974","pull_request_url":"https://api.github.com/repos/containers/libpod/pulls/1642","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/containers/libpod/pulls/comments/234066974"},"html":{"href":"https://github.com/containers/libpod/pull/1642#discussion_r234066974"},"pull_request":{"href":"https://api.github.com/repos/containers/libpod/pulls/1642"}},"in_reply_to_id":232791166},"pull_request":{"url":"https://api.github.com/repos/containers/libpod/pulls/1642","id":222814032,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIyODE0MDMy","html_url":"https://github.com/containers/libpod/pull/1642","diff_url":"https://github.com/containers/libpod/pull/1642.diff","patch_url":"https://github.com/containers/libpod/pull/1642.patch","issue_url":"https://api.github.com/repos/containers/libpod/issues/1642","number":1642,"state":"open","locked":false,"title":"Tree implementation for podman images","user":{"login":"kunalkushwaha","id":2758433,"node_id":"MDQ6VXNlcjI3NTg0MzM=","avatar_url":"https://avatars0.githubusercontent.com/u/2758433?v=4","gravatar_id":"","url":"https://api.github.com/users/kunalkushwaha","html_url":"https://github.com/kunalkushwaha","followers_url":"https://api.github.com/users/kunalkushwaha/followers","following_url":"https://api.github.com/users/kunalkushwaha/following{/other_user}","gists_url":"https://api.github.com/users/kunalkushwaha/gists{/gist_id}","starred_url":"https://api.github.com/users/kunalkushwaha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kunalkushwaha/subscriptions","organizations_url":"https://api.github.com/users/kunalkushwaha/orgs","repos_url":"https://api.github.com/users/kunalkushwaha/repos","events_url":"https://api.github.com/users/kunalkushwaha/events{/privacy}","received_events_url":"https://api.github.com/users/kunalkushwaha/received_events","type":"User","site_admin":false},"body":"Signed-off-by: Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>","created_at":"2018-10-15T08:01:14Z","updated_at":"2018-11-16T01:39:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c414248efbe990145c097db8bc47bbebe0f2c17b","assignee":null,"assignees":[],"requested_reviewers":[{"login":"umohnani8","id":29377163,"node_id":"MDQ6VXNlcjI5Mzc3MTYz","avatar_url":"https://avatars0.githubusercontent.com/u/29377163?v=4","gravatar_id":"","url":"https://api.github.com/users/umohnani8","html_url":"https://github.com/umohnani8","followers_url":"https://api.github.com/users/umohnani8/followers","following_url":"https://api.github.com/users/umohnani8/following{/other_user}","gists_url":"https://api.github.com/users/umohnani8/gists{/gist_id}","starred_url":"https://api.github.com/users/umohnani8/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/umohnani8/subscriptions","organizations_url":"https://api.github.com/users/umohnani8/orgs","repos_url":"https://api.github.com/users/umohnani8/repos","events_url":"https://api.github.com/users/umohnani8/events{/privacy}","received_events_url":"https://api.github.com/users/umohnani8/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":1070348377,"node_id":"MDU6TGFiZWwxMDcwMzQ4Mzc3","url":"https://api.github.com/repos/containers/libpod/labels/approved","name":"approved","color":"0ffa16","default":false},{"id":1069153503,"node_id":"MDU6TGFiZWwxMDY5MTUzNTAz","url":"https://api.github.com/repos/containers/libpod/labels/size/L","name":"size/L","color":"ee9900","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/containers/libpod/pulls/1642/commits","review_comments_url":"https://api.github.com/repos/containers/libpod/pulls/1642/comments","review_comment_url":"https://api.github.com/repos/containers/libpod/pulls/comments{/number}","comments_url":"https://api.github.com/repos/containers/libpod/issues/1642/comments","statuses_url":"https://api.github.com/repos/containers/libpod/statuses/479411606f1e64beb2ebd90122a96ee16cd2961a","head":{"label":"kunalkushwaha:image-tree","ref":"image-tree","sha":"479411606f1e64beb2ebd90122a96ee16cd2961a","user":{"login":"kunalkushwaha","id":2758433,"node_id":"MDQ6VXNlcjI3NTg0MzM=","avatar_url":"https://avatars0.githubusercontent.com/u/2758433?v=4","gravatar_id":"","url":"https://api.github.com/users/kunalkushwaha","html_url":"https://github.com/kunalkushwaha","followers_url":"https://api.github.com/users/kunalkushwaha/followers","following_url":"https://api.github.com/users/kunalkushwaha/following{/other_user}","gists_url":"https://api.github.com/users/kunalkushwaha/gists{/gist_id}","starred_url":"https://api.github.com/users/kunalkushwaha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kunalkushwaha/subscriptions","organizations_url":"https://api.github.com/users/kunalkushwaha/orgs","repos_url":"https://api.github.com/users/kunalkushwaha/repos","events_url":"https://api.github.com/users/kunalkushwaha/events{/privacy}","received_events_url":"https://api.github.com/users/kunalkushwaha/received_events","type":"User","site_admin":false},"repo":{"id":145508880,"node_id":"MDEwOlJlcG9zaXRvcnkxNDU1MDg4ODA=","name":"libpod","full_name":"kunalkushwaha/libpod","private":false,"owner":{"login":"kunalkushwaha","id":2758433,"node_id":"MDQ6VXNlcjI3NTg0MzM=","avatar_url":"https://avatars0.githubusercontent.com/u/2758433?v=4","gravatar_id":"","url":"https://api.github.com/users/kunalkushwaha","html_url":"https://github.com/kunalkushwaha","followers_url":"https://api.github.com/users/kunalkushwaha/followers","following_url":"https://api.github.com/users/kunalkushwaha/following{/other_user}","gists_url":"https://api.github.com/users/kunalkushwaha/gists{/gist_id}","starred_url":"https://api.github.com/users/kunalkushwaha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kunalkushwaha/subscriptions","organizations_url":"https://api.github.com/users/kunalkushwaha/orgs","repos_url":"https://api.github.com/users/kunalkushwaha/repos","events_url":"https://api.github.com/users/kunalkushwaha/events{/privacy}","received_events_url":"https://api.github.com/users/kunalkushwaha/received_events","type":"User","site_admin":false},"html_url":"https://github.com/kunalkushwaha/libpod","description":"libpod is a library used to create container pods.","fork":true,"url":"https://api.github.com/repos/kunalkushwaha/libpod","forks_url":"https://api.github.com/repos/kunalkushwaha/libpod/forks","keys_url":"https://api.github.com/repos/kunalkushwaha/libpod/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kunalkushwaha/libpod/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kunalkushwaha/libpod/teams","hooks_url":"https://api.github.com/repos/kunalkushwaha/libpod/hooks","issue_events_url":"https://api.github.com/repos/kunalkushwaha/libpod/issues/events{/number}","events_url":"https://api.github.com/repos/kunalkushwaha/libpod/events","assignees_url":"https://api.github.com/repos/kunalkushwaha/libpod/assignees{/user}","branches_url":"https://api.github.com/repos/kunalkushwaha/libpod/branches{/branch}","tags_url":"https://api.github.com/repos/kunalkushwaha/libpod/tags","blobs_url":"https://api.github.com/repos/kunalkushwaha/libpod/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kunalkushwaha/libpod/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kunalkushwaha/libpod/git/refs{/sha}","trees_url":"https://api.github.com/repos/kunalkushwaha/libpod/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kunalkushwaha/libpod/statuses/{sha}","languages_url":"https://api.github.com/repos/kunalkushwaha/libpod/languages","stargazers_url":"https://api.github.com/repos/kunalkushwaha/libpod/stargazers","contributors_url":"https://api.github.com/repos/kunalkushwaha/libpod/contributors","subscribers_url":"https://api.github.com/repos/kunalkushwaha/libpod/subscribers","subscription_url":"https://api.github.com/repos/kunalkushwaha/libpod/subscription","commits_url":"https://api.github.com/repos/kunalkushwaha/libpod/commits{/sha}","git_commits_url":"https://api.github.com/repos/kunalkushwaha/libpod/git/commits{/sha}","comments_url":"https://api.github.com/repos/kunalkushwaha/libpod/comments{/number}","issue_comment_url":"https://api.github.com/repos/kunalkushwaha/libpod/issues/comments{/number}","contents_url":"https://api.github.com/repos/kunalkushwaha/libpod/contents/{+path}","compare_url":"https://api.github.com/repos/kunalkushwaha/libpod/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kunalkushwaha/libpod/merges","archive_url":"https://api.github.com/repos/kunalkushwaha/libpod/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kunalkushwaha/libpod/downloads","issues_url":"https://api.github.com/repos/kunalkushwaha/libpod/issues{/number}","pulls_url":"https://api.github.com/repos/kunalkushwaha/libpod/pulls{/number}","milestones_url":"https://api.github.com/repos/kunalkushwaha/libpod/milestones{/number}","notifications_url":"https://api.github.com/repos/kunalkushwaha/libpod/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kunalkushwaha/libpod/labels{/name}","releases_url":"https://api.github.com/repos/kunalkushwaha/libpod/releases{/id}","deployments_url":"https://api.github.com/repos/kunalkushwaha/libpod/deployments","created_at":"2018-08-21T05:01:56Z","updated_at":"2018-11-05T08:22:23Z","pushed_at":"2018-11-14T08:33:53Z","git_url":"git://github.com/kunalkushwaha/libpod.git","ssh_url":"git@github.com:kunalkushwaha/libpod.git","clone_url":"https://github.com/kunalkushwaha/libpod.git","svn_url":"https://github.com/kunalkushwaha/libpod","homepage":null,"size":16364,"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":"containers:master","ref":"master","sha":"12f3721c3459676cfc30eb01d393d96c594bede5","user":{"login":"containers","id":5874934,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU4NzQ5MzQ=","avatar_url":"https://avatars3.githubusercontent.com/u/5874934?v=4","gravatar_id":"","url":"https://api.github.com/users/containers","html_url":"https://github.com/containers","followers_url":"https://api.github.com/users/containers/followers","following_url":"https://api.github.com/users/containers/following{/other_user}","gists_url":"https://api.github.com/users/containers/gists{/gist_id}","starred_url":"https://api.github.com/users/containers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/containers/subscriptions","organizations_url":"https://api.github.com/users/containers/orgs","repos_url":"https://api.github.com/users/containers/repos","events_url":"https://api.github.com/users/containers/events{/privacy}","received_events_url":"https://api.github.com/users/containers/received_events","type":"Organization","site_admin":false},"repo":{"id":109145553,"node_id":"MDEwOlJlcG9zaXRvcnkxMDkxNDU1NTM=","name":"libpod","full_name":"containers/libpod","private":false,"owner":{"login":"containers","id":5874934,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU4NzQ5MzQ=","avatar_url":"https://avatars3.githubusercontent.com/u/5874934?v=4","gravatar_id":"","url":"https://api.github.com/users/containers","html_url":"https://github.com/containers","followers_url":"https://api.github.com/users/containers/followers","following_url":"https://api.github.com/users/containers/following{/other_user}","gists_url":"https://api.github.com/users/containers/gists{/gist_id}","starred_url":"https://api.github.com/users/containers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/containers/subscriptions","organizations_url":"https://api.github.com/users/containers/orgs","repos_url":"https://api.github.com/users/containers/repos","events_url":"https://api.github.com/users/containers/events{/privacy}","received_events_url":"https://api.github.com/users/containers/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/containers/libpod","description":"libpod is a library used to create container pods.","fork":false,"url":"https://api.github.com/repos/containers/libpod","forks_url":"https://api.github.com/repos/containers/libpod/forks","keys_url":"https://api.github.com/repos/containers/libpod/keys{/key_id}","collaborators_url":"https://api.github.com/repos/containers/libpod/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/containers/libpod/teams","hooks_url":"https://api.github.com/repos/containers/libpod/hooks","issue_events_url":"https://api.github.com/repos/containers/libpod/issues/events{/number}","events_url":"https://api.github.com/repos/containers/libpod/events","assignees_url":"https://api.github.com/repos/containers/libpod/assignees{/user}","branches_url":"https://api.github.com/repos/containers/libpod/branches{/branch}","tags_url":"https://api.github.com/repos/containers/libpod/tags","blobs_url":"https://api.github.com/repos/containers/libpod/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/containers/libpod/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/containers/libpod/git/refs{/sha}","trees_url":"https://api.github.com/repos/containers/libpod/git/trees{/sha}","statuses_url":"https://api.github.com/repos/containers/libpod/statuses/{sha}","languages_url":"https://api.github.com/repos/containers/libpod/languages","stargazers_url":"https://api.github.com/repos/containers/libpod/stargazers","contributors_url":"https://api.github.com/repos/containers/libpod/contributors","subscribers_url":"https://api.github.com/repos/containers/libpod/subscribers","subscription_url":"https://api.github.com/repos/containers/libpod/subscription","commits_url":"https://api.github.com/repos/containers/libpod/commits{/sha}","git_commits_url":"https://api.github.com/repos/containers/libpod/git/commits{/sha}","comments_url":"https://api.github.com/repos/containers/libpod/comments{/number}","issue_comment_url":"https://api.github.com/repos/containers/libpod/issues/comments{/number}","contents_url":"https://api.github.com/repos/containers/libpod/contents/{+path}","compare_url":"https://api.github.com/repos/containers/libpod/compare/{base}...{head}","merges_url":"https://api.github.com/repos/containers/libpod/merges","archive_url":"https://api.github.com/repos/containers/libpod/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/containers/libpod/downloads","issues_url":"https://api.github.com/repos/containers/libpod/issues{/number}","pulls_url":"https://api.github.com/repos/containers/libpod/pulls{/number}","milestones_url":"https://api.github.com/repos/containers/libpod/milestones{/number}","notifications_url":"https://api.github.com/repos/containers/libpod/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/containers/libpod/labels{/name}","releases_url":"https://api.github.com/repos/containers/libpod/releases{/id}","deployments_url":"https://api.github.com/repos/containers/libpod/deployments","created_at":"2017-11-01T15:01:27Z","updated_at":"2018-11-16T01:17:09Z","pushed_at":"2018-11-16T01:26:37Z","git_url":"git://github.com/containers/libpod.git","ssh_url":"git@github.com:containers/libpod.git","clone_url":"https://github.com/containers/libpod.git","svn_url":"https://github.com/containers/libpod","homepage":null,"size":16360,"stargazers_count":514,"watchers_count":514,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":95,"mirror_url":null,"archived":false,"open_issues_count":101,"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":95,"open_issues":101,"watchers":514,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/containers/libpod/pulls/1642"},"html":{"href":"https://github.com/containers/libpod/pull/1642"},"issue":{"href":"https://api.github.com/repos/containers/libpod/issues/1642"},"comments":{"href":"https://api.github.com/repos/containers/libpod/issues/1642/comments"},"review_comments":{"href":"https://api.github.com/repos/containers/libpod/pulls/1642/comments"},"review_comment":{"href":"https://api.github.com/repos/containers/libpod/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/containers/libpod/pulls/1642/commits"},"statuses":{"href":"https://api.github.com/repos/containers/libpod/statuses/479411606f1e64beb2ebd90122a96ee16cd2961a"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"mtrmac"}}