{"action":"created","comment":{"url":"https://api.github.com/repos/kata-containers/agent/pulls/comments/170251284","pull_request_review_id":98911876,"id":170251284,"diff_hunk":"@@ -273,8 +277,134 @@ func getInterface(netHandle *netlink.Handle, link netlink.Link) *pb.Interface {\n // Routes //\n ////////////\n \n-func (s *sandbox) addRoute(netHandle *netlink.Handle, route *pb.Route) error {\n-\treturn s.updateRoute(netHandle, route, true)\n+//updateRoutes will take requestedRoutes and create netlink routes, with a goal of creating a final\n+// state which matches the requested routes.  In doing this, preesxisting non-loopback routes will be\n+// removed from the network.  If an error occurs, this function returns the list of routes in\n+// gRPC-route format at the time of failure\n+func (s *sandbox) updateRoutes(netHandle *netlink.Handle, requestedRoutes *pb.Routes) (resultingRoutes *pb.Routes, err error) {\n+\n+\tif netHandle == nil {\n+\t\tnetHandle, err = netlink.NewHandle()\n+\t\tif err != nil {\n+\t\t\treturn nil, err\n+\t\t}\n+\t\tdefer netHandle.Delete()\n+\t}\n+\n+\t//If we are returning an error, return the current routes on the system\n+\tdefer func() {\n+\t\tif err != nil {\n+\t\t\tresultingRoutes, _ = getCurrentRoutes(netHandle)\n+\t\t}\n+\t}()\n+\n+\t//\n+\t// First things first, let's blow away all the existing routes.  The updateRoutes function\n+\t// is designed to be declarative, so we will attempt to create state matching what is\n+\t// requested, and in the event that we fail to do so, will return the error and final state.\n+\t//\n+\n+\tinitRouteList, err := netHandle.RouteList(nil, netlink.FAMILY_ALL)\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\tfor _, initRoute := range initRouteList {\n+\t\t// don't delete routes associated with lo:\n+\t\tlink, _ := netHandle.LinkByIndex(initRoute.LinkIndex)\n+\t\tif link.Attrs().Name == \"lo\" || link.Attrs().Name == \"::1\" {\n+\t\t\tcontinue\n+\t\t}\n+\n+\t\terr = netHandle.RouteDel(&initRoute)\n+\t\tif err != nil {\n+\t\t\t//If there was an error deleting some of the initial routes,\n+\t\t\t//return the error and the current routes on the system via\n+\t\t\t//the defer function\n+\t\t\treturn\n+\t\t}\n+\t}\n+\n+\t//\n+\t// Set each of the requested routes\n+\t//\n+\t// First make sure we set the interfaces initial routes, as otherwise we\n+\t// won't be able to access the gateway\n+\tfor _, reqRoute := range requestedRoutes.Routes {\n+\t\tif reqRoute.Gateway == \"\" {\n+\t\t\terr = s.updateRoute(netHandle, reqRoute, true)\n+\t\t\tif err != nil {\n+\t\t\t\tagentLog.WithError(err).Error(\"update Route failed\")\n+\t\t\t\t//If there was an error setting the route, return the error\n+\t\t\t\t//and the current routes on the system via the defer func\n+\t\t\t\treturn\n+\t\t\t}\n+\n+\t\t}\n+\t}\n+\t// Take a second pass and apply the routes which include a gateway\n+\tfor _, reqRoute := range requestedRoutes.Routes {\n+\t\tif reqRoute.Gateway != \"\" {\n+\t\t\terr = s.updateRoute(netHandle, reqRoute, true)\n+\t\t\tif err != nil {\n+\t\t\t\tagentLog.WithError(err).Error(\"update Route failed\")\n+\t\t\t\t//If there was an error setting the route, return the\n+\t\t\t\t//error and the current routes on the system via defer\n+\t\t\t\treturn\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn requestedRoutes, err\n+}\n+\n+//getCurrentRoutes is a helper to gather existing routes in gRPC protocol format\n+func getCurrentRoutes(netHandle *netlink.Handle) (*pb.Routes, error) {\n+\n+\tif netHandle == nil {\n+\t\tnetHandle, err := netlink.NewHandle()\n+\t\tif err != nil {\n+\t\t\treturn nil, err\n+\t\t}\n+\t\tdefer netHandle.Delete()\n+\t}\n+\n+\tvar routes pb.Routes\n+\n+\tfinalRouteList, err := netHandle.RouteList(nil, netlink.FAMILY_ALL)\n+\tif err != nil {\n+\t\treturn &routes, err\n+\t}\n+\n+\tfor _, route := range finalRouteList {\n+\t\tvar r pb.Route\n+\t\tif route.Dst == nil {\n+\t\t\tr.Dest = \"\"\n+\t\t} else {\n+\t\t\tr.Dest = route.Dst.String()\n+\t\t}","path":"network.go","position":121,"original_position":121,"commit_id":"3e5b3e218cfd1f636d764b136a6d3f1cfedae6cb","original_commit_id":"3e5b3e218cfd1f636d764b136a6d3f1cfedae6cb","user":{"login":"WeiZhang555","id":1203611,"avatar_url":"https://avatars2.githubusercontent.com/u/1203611?v=4","gravatar_id":"","url":"https://api.github.com/users/WeiZhang555","html_url":"https://github.com/WeiZhang555","followers_url":"https://api.github.com/users/WeiZhang555/followers","following_url":"https://api.github.com/users/WeiZhang555/following{/other_user}","gists_url":"https://api.github.com/users/WeiZhang555/gists{/gist_id}","starred_url":"https://api.github.com/users/WeiZhang555/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WeiZhang555/subscriptions","organizations_url":"https://api.github.com/users/WeiZhang555/orgs","repos_url":"https://api.github.com/users/WeiZhang555/repos","events_url":"https://api.github.com/users/WeiZhang555/events{/privacy}","received_events_url":"https://api.github.com/users/WeiZhang555/received_events","type":"User","site_admin":false},"body":"No, the \"String()\" func is called only when \"route.Dst != nil\", so no panic will occur.","created_at":"2018-02-23T13:32:10Z","updated_at":"2018-02-23T13:48:05Z","html_url":"https://github.com/kata-containers/agent/pull/148#discussion_r170251284","pull_request_url":"https://api.github.com/repos/kata-containers/agent/pulls/148","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/kata-containers/agent/pulls/comments/170251284"},"html":{"href":"https://github.com/kata-containers/agent/pull/148#discussion_r170251284"},"pull_request":{"href":"https://api.github.com/repos/kata-containers/agent/pulls/148"}},"in_reply_to_id":170191454},"pull_request":{"url":"https://api.github.com/repos/kata-containers/agent/pulls/148","id":170390458,"html_url":"https://github.com/kata-containers/agent/pull/148","diff_url":"https://github.com/kata-containers/agent/pull/148.diff","patch_url":"https://github.com/kata-containers/agent/pull/148.patch","issue_url":"https://api.github.com/repos/kata-containers/agent/issues/148","number":148,"state":"open","locked":false,"title":"grpc: network: add UpdateRoutes","user":{"login":"egernst","id":20174683,"avatar_url":"https://avatars1.githubusercontent.com/u/20174683?v=4","gravatar_id":"","url":"https://api.github.com/users/egernst","html_url":"https://github.com/egernst","followers_url":"https://api.github.com/users/egernst/followers","following_url":"https://api.github.com/users/egernst/following{/other_user}","gists_url":"https://api.github.com/users/egernst/gists{/gist_id}","starred_url":"https://api.github.com/users/egernst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/egernst/subscriptions","organizations_url":"https://api.github.com/users/egernst/orgs","repos_url":"https://api.github.com/users/egernst/repos","events_url":"https://api.github.com/users/egernst/events{/privacy}","received_events_url":"https://api.github.com/users/egernst/received_events","type":"User","site_admin":false},"body":"To provide a true declarative interface, we\r\nintroduce an UpdateRoutes function to our agent protocol.\r\n\r\nThis function will clear out all existing routes and then attempt to\r\napply what has been passed over gRPC. In the event that a failure is\r\nobserved when applying routes, the error is logged, message is returned\r\nas well as the final state of the ip routes in the guest.\r\n\r\nThe routes structure in the gRPC prtocol was enhanced in order to\r\nprovide handling of Source and Scope fields, which are necessary to be\r\nable to apply functional fresh routes.\r\n\r\nSigned-off-by: Eric Ernst <eric.ernst@intel.com>","created_at":"2018-02-21T07:01:08Z","updated_at":"2018-02-23T13:48:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6ea7bcb09aa6e9628487083267888ed50e7912eb","assignee":{"login":"egernst","id":20174683,"avatar_url":"https://avatars1.githubusercontent.com/u/20174683?v=4","gravatar_id":"","url":"https://api.github.com/users/egernst","html_url":"https://github.com/egernst","followers_url":"https://api.github.com/users/egernst/followers","following_url":"https://api.github.com/users/egernst/following{/other_user}","gists_url":"https://api.github.com/users/egernst/gists{/gist_id}","starred_url":"https://api.github.com/users/egernst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/egernst/subscriptions","organizations_url":"https://api.github.com/users/egernst/orgs","repos_url":"https://api.github.com/users/egernst/repos","events_url":"https://api.github.com/users/egernst/events{/privacy}","received_events_url":"https://api.github.com/users/egernst/received_events","type":"User","site_admin":false},"assignees":[{"login":"egernst","id":20174683,"avatar_url":"https://avatars1.githubusercontent.com/u/20174683?v=4","gravatar_id":"","url":"https://api.github.com/users/egernst","html_url":"https://github.com/egernst","followers_url":"https://api.github.com/users/egernst/followers","following_url":"https://api.github.com/users/egernst/following{/other_user}","gists_url":"https://api.github.com/users/egernst/gists{/gist_id}","starred_url":"https://api.github.com/users/egernst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/egernst/subscriptions","organizations_url":"https://api.github.com/users/egernst/orgs","repos_url":"https://api.github.com/users/egernst/repos","events_url":"https://api.github.com/users/egernst/events{/privacy}","received_events_url":"https://api.github.com/users/egernst/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":834186873,"url":"https://api.github.com/repos/kata-containers/agent/labels/review","name":"review","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/kata-containers/agent/pulls/148/commits","review_comments_url":"https://api.github.com/repos/kata-containers/agent/pulls/148/comments","review_comment_url":"https://api.github.com/repos/kata-containers/agent/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kata-containers/agent/issues/148/comments","statuses_url":"https://api.github.com/repos/kata-containers/agent/statuses/3e5b3e218cfd1f636d764b136a6d3f1cfedae6cb","head":{"label":"egernst:update-routes","ref":"update-routes","sha":"3e5b3e218cfd1f636d764b136a6d3f1cfedae6cb","user":{"login":"egernst","id":20174683,"avatar_url":"https://avatars1.githubusercontent.com/u/20174683?v=4","gravatar_id":"","url":"https://api.github.com/users/egernst","html_url":"https://github.com/egernst","followers_url":"https://api.github.com/users/egernst/followers","following_url":"https://api.github.com/users/egernst/following{/other_user}","gists_url":"https://api.github.com/users/egernst/gists{/gist_id}","starred_url":"https://api.github.com/users/egernst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/egernst/subscriptions","organizations_url":"https://api.github.com/users/egernst/orgs","repos_url":"https://api.github.com/users/egernst/repos","events_url":"https://api.github.com/users/egernst/events{/privacy}","received_events_url":"https://api.github.com/users/egernst/received_events","type":"User","site_admin":false},"repo":{"id":119748705,"name":"agent-1","full_name":"egernst/agent-1","owner":{"login":"egernst","id":20174683,"avatar_url":"https://avatars1.githubusercontent.com/u/20174683?v=4","gravatar_id":"","url":"https://api.github.com/users/egernst","html_url":"https://github.com/egernst","followers_url":"https://api.github.com/users/egernst/followers","following_url":"https://api.github.com/users/egernst/following{/other_user}","gists_url":"https://api.github.com/users/egernst/gists{/gist_id}","starred_url":"https://api.github.com/users/egernst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/egernst/subscriptions","organizations_url":"https://api.github.com/users/egernst/orgs","repos_url":"https://api.github.com/users/egernst/repos","events_url":"https://api.github.com/users/egernst/events{/privacy}","received_events_url":"https://api.github.com/users/egernst/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/egernst/agent-1","description":"Virtual Machine agent for hardware virtualized containers","fork":true,"url":"https://api.github.com/repos/egernst/agent-1","forks_url":"https://api.github.com/repos/egernst/agent-1/forks","keys_url":"https://api.github.com/repos/egernst/agent-1/keys{/key_id}","collaborators_url":"https://api.github.com/repos/egernst/agent-1/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/egernst/agent-1/teams","hooks_url":"https://api.github.com/repos/egernst/agent-1/hooks","issue_events_url":"https://api.github.com/repos/egernst/agent-1/issues/events{/number}","events_url":"https://api.github.com/repos/egernst/agent-1/events","assignees_url":"https://api.github.com/repos/egernst/agent-1/assignees{/user}","branches_url":"https://api.github.com/repos/egernst/agent-1/branches{/branch}","tags_url":"https://api.github.com/repos/egernst/agent-1/tags","blobs_url":"https://api.github.com/repos/egernst/agent-1/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/egernst/agent-1/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/egernst/agent-1/git/refs{/sha}","trees_url":"https://api.github.com/repos/egernst/agent-1/git/trees{/sha}","statuses_url":"https://api.github.com/repos/egernst/agent-1/statuses/{sha}","languages_url":"https://api.github.com/repos/egernst/agent-1/languages","stargazers_url":"https://api.github.com/repos/egernst/agent-1/stargazers","contributors_url":"https://api.github.com/repos/egernst/agent-1/contributors","subscribers_url":"https://api.github.com/repos/egernst/agent-1/subscribers","subscription_url":"https://api.github.com/repos/egernst/agent-1/subscription","commits_url":"https://api.github.com/repos/egernst/agent-1/commits{/sha}","git_commits_url":"https://api.github.com/repos/egernst/agent-1/git/commits{/sha}","comments_url":"https://api.github.com/repos/egernst/agent-1/comments{/number}","issue_comment_url":"https://api.github.com/repos/egernst/agent-1/issues/comments{/number}","contents_url":"https://api.github.com/repos/egernst/agent-1/contents/{+path}","compare_url":"https://api.github.com/repos/egernst/agent-1/compare/{base}...{head}","merges_url":"https://api.github.com/repos/egernst/agent-1/merges","archive_url":"https://api.github.com/repos/egernst/agent-1/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/egernst/agent-1/downloads","issues_url":"https://api.github.com/repos/egernst/agent-1/issues{/number}","pulls_url":"https://api.github.com/repos/egernst/agent-1/pulls{/number}","milestones_url":"https://api.github.com/repos/egernst/agent-1/milestones{/number}","notifications_url":"https://api.github.com/repos/egernst/agent-1/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/egernst/agent-1/labels{/name}","releases_url":"https://api.github.com/repos/egernst/agent-1/releases{/id}","deployments_url":"https://api.github.com/repos/egernst/agent-1/deployments","created_at":"2018-01-31T21:56:56Z","updated_at":"2018-01-31T21:56:58Z","pushed_at":"2018-02-22T22:04:31Z","git_url":"git://github.com/egernst/agent-1.git","ssh_url":"git@github.com:egernst/agent-1.git","clone_url":"https://github.com/egernst/agent-1.git","svn_url":"https://github.com/egernst/agent-1","homepage":null,"size":4560,"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":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"kata-containers:master","ref":"master","sha":"71288bb098e8db50e7aeab9a34032ff557736c16","user":{"login":"kata-containers","id":33289952,"avatar_url":"https://avatars3.githubusercontent.com/u/33289952?v=4","gravatar_id":"","url":"https://api.github.com/users/kata-containers","html_url":"https://github.com/kata-containers","followers_url":"https://api.github.com/users/kata-containers/followers","following_url":"https://api.github.com/users/kata-containers/following{/other_user}","gists_url":"https://api.github.com/users/kata-containers/gists{/gist_id}","starred_url":"https://api.github.com/users/kata-containers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kata-containers/subscriptions","organizations_url":"https://api.github.com/users/kata-containers/orgs","repos_url":"https://api.github.com/users/kata-containers/repos","events_url":"https://api.github.com/users/kata-containers/events{/privacy}","received_events_url":"https://api.github.com/users/kata-containers/received_events","type":"Organization","site_admin":false},"repo":{"id":110538699,"name":"agent","full_name":"kata-containers/agent","owner":{"login":"kata-containers","id":33289952,"avatar_url":"https://avatars3.githubusercontent.com/u/33289952?v=4","gravatar_id":"","url":"https://api.github.com/users/kata-containers","html_url":"https://github.com/kata-containers","followers_url":"https://api.github.com/users/kata-containers/followers","following_url":"https://api.github.com/users/kata-containers/following{/other_user}","gists_url":"https://api.github.com/users/kata-containers/gists{/gist_id}","starred_url":"https://api.github.com/users/kata-containers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kata-containers/subscriptions","organizations_url":"https://api.github.com/users/kata-containers/orgs","repos_url":"https://api.github.com/users/kata-containers/repos","events_url":"https://api.github.com/users/kata-containers/events{/privacy}","received_events_url":"https://api.github.com/users/kata-containers/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kata-containers/agent","description":"Virtual Machine agent for hardware virtualized containers","fork":false,"url":"https://api.github.com/repos/kata-containers/agent","forks_url":"https://api.github.com/repos/kata-containers/agent/forks","keys_url":"https://api.github.com/repos/kata-containers/agent/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kata-containers/agent/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kata-containers/agent/teams","hooks_url":"https://api.github.com/repos/kata-containers/agent/hooks","issue_events_url":"https://api.github.com/repos/kata-containers/agent/issues/events{/number}","events_url":"https://api.github.com/repos/kata-containers/agent/events","assignees_url":"https://api.github.com/repos/kata-containers/agent/assignees{/user}","branches_url":"https://api.github.com/repos/kata-containers/agent/branches{/branch}","tags_url":"https://api.github.com/repos/kata-containers/agent/tags","blobs_url":"https://api.github.com/repos/kata-containers/agent/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kata-containers/agent/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kata-containers/agent/git/refs{/sha}","trees_url":"https://api.github.com/repos/kata-containers/agent/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kata-containers/agent/statuses/{sha}","languages_url":"https://api.github.com/repos/kata-containers/agent/languages","stargazers_url":"https://api.github.com/repos/kata-containers/agent/stargazers","contributors_url":"https://api.github.com/repos/kata-containers/agent/contributors","subscribers_url":"https://api.github.com/repos/kata-containers/agent/subscribers","subscription_url":"https://api.github.com/repos/kata-containers/agent/subscription","commits_url":"https://api.github.com/repos/kata-containers/agent/commits{/sha}","git_commits_url":"https://api.github.com/repos/kata-containers/agent/git/commits{/sha}","comments_url":"https://api.github.com/repos/kata-containers/agent/comments{/number}","issue_comment_url":"https://api.github.com/repos/kata-containers/agent/issues/comments{/number}","contents_url":"https://api.github.com/repos/kata-containers/agent/contents/{+path}","compare_url":"https://api.github.com/repos/kata-containers/agent/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kata-containers/agent/merges","archive_url":"https://api.github.com/repos/kata-containers/agent/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kata-containers/agent/downloads","issues_url":"https://api.github.com/repos/kata-containers/agent/issues{/number}","pulls_url":"https://api.github.com/repos/kata-containers/agent/pulls{/number}","milestones_url":"https://api.github.com/repos/kata-containers/agent/milestones{/number}","notifications_url":"https://api.github.com/repos/kata-containers/agent/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kata-containers/agent/labels{/name}","releases_url":"https://api.github.com/repos/kata-containers/agent/releases{/id}","deployments_url":"https://api.github.com/repos/kata-containers/agent/deployments","created_at":"2017-11-13T11:15:36Z","updated_at":"2018-02-21T16:01:27Z","pushed_at":"2018-02-23T09:54:05Z","git_url":"git://github.com/kata-containers/agent.git","ssh_url":"git@github.com:kata-containers/agent.git","clone_url":"https://github.com/kata-containers/agent.git","svn_url":"https://github.com/kata-containers/agent","homepage":null,"size":4554,"stargazers_count":91,"watchers_count":91,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":26,"mirror_url":null,"archived":false,"open_issues_count":28,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":26,"open_issues":28,"watchers":91,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kata-containers/agent/pulls/148"},"html":{"href":"https://github.com/kata-containers/agent/pull/148"},"issue":{"href":"https://api.github.com/repos/kata-containers/agent/issues/148"},"comments":{"href":"https://api.github.com/repos/kata-containers/agent/issues/148/comments"},"review_comments":{"href":"https://api.github.com/repos/kata-containers/agent/pulls/148/comments"},"review_comment":{"href":"https://api.github.com/repos/kata-containers/agent/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kata-containers/agent/pulls/148/commits"},"statuses":{"href":"https://api.github.com/repos/kata-containers/agent/statuses/3e5b3e218cfd1f636d764b136a6d3f1cfedae6cb"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"WeiZhang555"}}