{"action":"created","comment":{"url":"https://api.github.com/repos/weaveworks/weave/pulls/comments/56503221","id":56503221,"diff_hunk":"@@ -0,0 +1,158 @@\n+package plugin\n+\n+import (\n+\t\"crypto/rand\"\n+\t\"encoding/json\"\n+\t\"fmt\"\n+\n+\t\"github.com/appc/cni/pkg/ipam\"\n+\t\"github.com/appc/cni/pkg/skel\"\n+\t\"github.com/appc/cni/pkg/types\"\n+\t\"github.com/vishvananda/netlink\"\n+\t\"github.com/vishvananda/netns\"\n+\tweaveapi \"github.com/weaveworks/weave/api\"\n+\t\"github.com/weaveworks/weave/common\"\n+\tipamplugin \"github.com/weaveworks/weave/plugin/ipam\"\n+)\n+\n+type CNIPlugin struct {\n+\tweave *weaveapi.Client\n+}\n+\n+func NewCNIPlugin(weave *weaveapi.Client) *CNIPlugin {\n+\treturn &CNIPlugin{weave: weave}\n+}\n+\n+func loadNetConf(bytes []byte) (*NetConf, error) {\n+\tn := &NetConf{\n+\t\tBrName: \"weave\",\n+\t}\n+\tif err := json.Unmarshal(bytes, n); err != nil {\n+\t\treturn nil, errorf(\"failed to load netconf: %v\", err)\n+\t}\n+\treturn n, nil\n+}\n+\n+func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error {\n+\tconf, err := loadNetConf(args.StdinData)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tif conf.IsGW {\n+\t\treturn errorf(\"Gateway functionality not supported\")\n+\t}\n+\tif conf.IPMasq {\n+\t\treturn errorf(\"IP Masquerading functionality not supported\")\n+\t}\n+\n+\tns, err := netns.GetFromPath(args.Netns)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tdefer ns.Close()\n+\n+\tid := args.ContainerID\n+\tif len(id) < 5 {\n+\t\tdata := make([]byte, 5)\n+\t\t_, err := rand.Reader.Read(data)\n+\t\tif err != nil {\n+\t\t\treturn err\n+\t\t}\n+\t\tid = fmt.Sprintf(\"%x\", data)\n+\t}\n+\n+\tlocal, err := createAndAttach(id, conf.BrName, conf.MTU)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tcleanup := func(err error) error {\n+\t\tnetlink.LinkDel(local)\n+\t\treturn err\n+\t}\n+\tguest, err := netlink.LinkByName(local.PeerName)\n+\tif err != nil {\n+\t\treturn cleanup(err)\n+\t}\n+\tif err = netlink.LinkSetNsFd(guest, int(ns)); err != nil {\n+\t\treturn cleanup(errorf(\"failed to move veth to container netns: %s\", err))\n+\t}\n+\n+\tif err := netlink.LinkSetUp(local); err != nil {\n+\t\treturn cleanup(errorf(\"unable to bring veth up: %s\", err))\n+\t}\n+\n+\tvar result *types.Result\n+\t// Default IPAM is Weave's own\n+\tif conf.IPAM.Type == \"\" {\n+\t\tresult, err = ipamplugin.NewIpam(c.weave).Allocate(args)\n+\t} else {\n+\t\tresult, err = ipam.ExecAdd(conf.IPAM.Type, args.StdinData)\n+\t}\n+\tif err != nil {\n+\t\treturn cleanup(errorf(\"unable to allocate IP address: %s\", err))\n+\t}\n+\tif result.IP4 == nil {\n+\t\treturn cleanup(errorf(\"IPAM plugin failed to allocate IP address\"))\n+\t}\n+\n+\terr = common.WithNetNS(ns, func() error {\n+\t\tguest, err := netlink.LinkByName(local.PeerName)\n+\t\tif err != nil {\n+\t\t\treturn cleanup(err)","path":"plugin/net/cni.go","position":null,"original_position":103,"commit_id":"7c7cf687f9dc27979bb8f7cfe5431016313054ec","original_commit_id":"42ff61f97c05cc5e9ac231ffa0ef9badfd09df1a","user":{"login":"awh","id":1504438,"avatar_url":"https://avatars.githubusercontent.com/u/1504438?v=3","gravatar_id":"","url":"https://api.github.com/users/awh","html_url":"https://github.com/awh","followers_url":"https://api.github.com/users/awh/followers","following_url":"https://api.github.com/users/awh/following{/other_user}","gists_url":"https://api.github.com/users/awh/gists{/gist_id}","starred_url":"https://api.github.com/users/awh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/awh/subscriptions","organizations_url":"https://api.github.com/users/awh/orgs","repos_url":"https://api.github.com/users/awh/repos","events_url":"https://api.github.com/users/awh/events{/privacy}","received_events_url":"https://api.github.com/users/awh/received_events","type":"User","site_admin":false},"body":"I think we can just `return err` here as we do in the next conditional as we're cleaning up any err return from WithNetNS","created_at":"2016-03-17T13:32:08Z","updated_at":"2016-03-17T13:32:08Z","html_url":"https://github.com/weaveworks/weave/pull/2030#discussion_r56503221","pull_request_url":"https://api.github.com/repos/weaveworks/weave/pulls/2030","_links":{"self":{"href":"https://api.github.com/repos/weaveworks/weave/pulls/comments/56503221"},"html":{"href":"https://github.com/weaveworks/weave/pull/2030#discussion_r56503221"},"pull_request":{"href":"https://api.github.com/repos/weaveworks/weave/pulls/2030"}}},"pull_request":{"url":"https://api.github.com/repos/weaveworks/weave/pulls/2030","id":62100740,"html_url":"https://github.com/weaveworks/weave/pull/2030","diff_url":"https://github.com/weaveworks/weave/pull/2030.diff","patch_url":"https://github.com/weaveworks/weave/pull/2030.patch","issue_url":"https://api.github.com/repos/weaveworks/weave/issues/2030","number":2030,"state":"open","locked":false,"title":"Implement CNI plugin","user":{"login":"bboreham","id":8125524,"avatar_url":"https://avatars.githubusercontent.com/u/8125524?v=3","gravatar_id":"","url":"https://api.github.com/users/bboreham","html_url":"https://github.com/bboreham","followers_url":"https://api.github.com/users/bboreham/followers","following_url":"https://api.github.com/users/bboreham/following{/other_user}","gists_url":"https://api.github.com/users/bboreham/gists{/gist_id}","starred_url":"https://api.github.com/users/bboreham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bboreham/subscriptions","organizations_url":"https://api.github.com/users/bboreham/orgs","repos_url":"https://api.github.com/users/bboreham/repos","events_url":"https://api.github.com/users/bboreham/events{/privacy}","received_events_url":"https://api.github.com/users/bboreham/received_events","type":"User","site_admin":false},"body":"Fixes #1991 and #1992.\r\n\r\n[CNI](https://github.com/appc/cni#cni---the-container-network-interface) expects to call an executable, which you name in your `/etc/cni/net.d/somenetwork.conf` file.  By default it looks in `/opt/cni/bin`\r\n\r\nFor the Weave plugin, `weave setup` creates a couple of scripts in `/opt/cni/bin` which run the plugin container with the necessary arguments, and also creates a configuration file `/etc/cni/net.d/10-weave.conf`.\r\n\r\nIf you do not configure an IPAM `type` in the configuration, the Weave CNI network plugin will call Weave IPAM directly.\r\n\r\nIf you don't want the overhead of a container execution on every plugin operation you can also use the Weave plugin executable directly, renamed:\r\n\r\n- If you name it `weave-net` it acts as a CNI network plugin.\r\n- If you name it `weave-ipam` it acts as a CNI IPAM plugin.\r\n","created_at":"2016-03-08T16:56:12Z","updated_at":"2016-03-17T13:32:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fe1d8f1b7421720474c42466a0eb849786237edc","assignee":{"login":"awh","id":1504438,"avatar_url":"https://avatars.githubusercontent.com/u/1504438?v=3","gravatar_id":"","url":"https://api.github.com/users/awh","html_url":"https://github.com/awh","followers_url":"https://api.github.com/users/awh/followers","following_url":"https://api.github.com/users/awh/following{/other_user}","gists_url":"https://api.github.com/users/awh/gists{/gist_id}","starred_url":"https://api.github.com/users/awh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/awh/subscriptions","organizations_url":"https://api.github.com/users/awh/orgs","repos_url":"https://api.github.com/users/awh/repos","events_url":"https://api.github.com/users/awh/events{/privacy}","received_events_url":"https://api.github.com/users/awh/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/weaveworks/weave/milestones/22","html_url":"https://github.com/weaveworks/weave/milestones/1.5.0","labels_url":"https://api.github.com/repos/weaveworks/weave/milestones/22/labels","id":1417778,"number":22,"title":"1.5.0","description":"","creator":{"login":"awh","id":1504438,"avatar_url":"https://avatars.githubusercontent.com/u/1504438?v=3","gravatar_id":"","url":"https://api.github.com/users/awh","html_url":"https://github.com/awh","followers_url":"https://api.github.com/users/awh/followers","following_url":"https://api.github.com/users/awh/following{/other_user}","gists_url":"https://api.github.com/users/awh/gists{/gist_id}","starred_url":"https://api.github.com/users/awh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/awh/subscriptions","organizations_url":"https://api.github.com/users/awh/orgs","repos_url":"https://api.github.com/users/awh/repos","events_url":"https://api.github.com/users/awh/events{/privacy}","received_events_url":"https://api.github.com/users/awh/received_events","type":"User","site_admin":false},"open_issues":10,"closed_issues":87,"state":"open","created_at":"2015-11-18T13:00:50Z","updated_at":"2016-03-17T11:50:09Z","due_on":"2016-03-28T23:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/weaveworks/weave/pulls/2030/commits","review_comments_url":"https://api.github.com/repos/weaveworks/weave/pulls/2030/comments","review_comment_url":"https://api.github.com/repos/weaveworks/weave/pulls/comments{/number}","comments_url":"https://api.github.com/repos/weaveworks/weave/issues/2030/comments","statuses_url":"https://api.github.com/repos/weaveworks/weave/statuses/7c7cf687f9dc27979bb8f7cfe5431016313054ec","head":{"label":"weaveworks:issues/1992-cni-plugin","ref":"issues/1992-cni-plugin","sha":"7c7cf687f9dc27979bb8f7cfe5431016313054ec","user":{"login":"weaveworks","id":9976052,"avatar_url":"https://avatars.githubusercontent.com/u/9976052?v=3","gravatar_id":"","url":"https://api.github.com/users/weaveworks","html_url":"https://github.com/weaveworks","followers_url":"https://api.github.com/users/weaveworks/followers","following_url":"https://api.github.com/users/weaveworks/following{/other_user}","gists_url":"https://api.github.com/users/weaveworks/gists{/gist_id}","starred_url":"https://api.github.com/users/weaveworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weaveworks/subscriptions","organizations_url":"https://api.github.com/users/weaveworks/orgs","repos_url":"https://api.github.com/users/weaveworks/repos","events_url":"https://api.github.com/users/weaveworks/events{/privacy}","received_events_url":"https://api.github.com/users/weaveworks/received_events","type":"Organization","site_admin":false},"repo":{"id":23059575,"name":"weave","full_name":"weaveworks/weave","owner":{"login":"weaveworks","id":9976052,"avatar_url":"https://avatars.githubusercontent.com/u/9976052?v=3","gravatar_id":"","url":"https://api.github.com/users/weaveworks","html_url":"https://github.com/weaveworks","followers_url":"https://api.github.com/users/weaveworks/followers","following_url":"https://api.github.com/users/weaveworks/following{/other_user}","gists_url":"https://api.github.com/users/weaveworks/gists{/gist_id}","starred_url":"https://api.github.com/users/weaveworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weaveworks/subscriptions","organizations_url":"https://api.github.com/users/weaveworks/orgs","repos_url":"https://api.github.com/users/weaveworks/repos","events_url":"https://api.github.com/users/weaveworks/events{/privacy}","received_events_url":"https://api.github.com/users/weaveworks/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/weaveworks/weave","description":"Simple, resilient multi-host Docker networking","fork":false,"url":"https://api.github.com/repos/weaveworks/weave","forks_url":"https://api.github.com/repos/weaveworks/weave/forks","keys_url":"https://api.github.com/repos/weaveworks/weave/keys{/key_id}","collaborators_url":"https://api.github.com/repos/weaveworks/weave/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/weaveworks/weave/teams","hooks_url":"https://api.github.com/repos/weaveworks/weave/hooks","issue_events_url":"https://api.github.com/repos/weaveworks/weave/issues/events{/number}","events_url":"https://api.github.com/repos/weaveworks/weave/events","assignees_url":"https://api.github.com/repos/weaveworks/weave/assignees{/user}","branches_url":"https://api.github.com/repos/weaveworks/weave/branches{/branch}","tags_url":"https://api.github.com/repos/weaveworks/weave/tags","blobs_url":"https://api.github.com/repos/weaveworks/weave/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/weaveworks/weave/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/weaveworks/weave/git/refs{/sha}","trees_url":"https://api.github.com/repos/weaveworks/weave/git/trees{/sha}","statuses_url":"https://api.github.com/repos/weaveworks/weave/statuses/{sha}","languages_url":"https://api.github.com/repos/weaveworks/weave/languages","stargazers_url":"https://api.github.com/repos/weaveworks/weave/stargazers","contributors_url":"https://api.github.com/repos/weaveworks/weave/contributors","subscribers_url":"https://api.github.com/repos/weaveworks/weave/subscribers","subscription_url":"https://api.github.com/repos/weaveworks/weave/subscription","commits_url":"https://api.github.com/repos/weaveworks/weave/commits{/sha}","git_commits_url":"https://api.github.com/repos/weaveworks/weave/git/commits{/sha}","comments_url":"https://api.github.com/repos/weaveworks/weave/comments{/number}","issue_comment_url":"https://api.github.com/repos/weaveworks/weave/issues/comments{/number}","contents_url":"https://api.github.com/repos/weaveworks/weave/contents/{+path}","compare_url":"https://api.github.com/repos/weaveworks/weave/compare/{base}...{head}","merges_url":"https://api.github.com/repos/weaveworks/weave/merges","archive_url":"https://api.github.com/repos/weaveworks/weave/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/weaveworks/weave/downloads","issues_url":"https://api.github.com/repos/weaveworks/weave/issues{/number}","pulls_url":"https://api.github.com/repos/weaveworks/weave/pulls{/number}","milestones_url":"https://api.github.com/repos/weaveworks/weave/milestones{/number}","notifications_url":"https://api.github.com/repos/weaveworks/weave/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/weaveworks/weave/labels{/name}","releases_url":"https://api.github.com/repos/weaveworks/weave/releases{/id}","deployments_url":"https://api.github.com/repos/weaveworks/weave/deployments","created_at":"2014-08-18T05:19:07Z","updated_at":"2016-03-17T09:45:27Z","pushed_at":"2016-03-17T12:42:04Z","git_url":"git://github.com/weaveworks/weave.git","ssh_url":"git@github.com:weaveworks/weave.git","clone_url":"https://github.com/weaveworks/weave.git","svn_url":"https://github.com/weaveworks/weave","homepage":"http://weave.works","size":12074,"stargazers_count":4094,"watchers_count":4094,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":261,"mirror_url":null,"open_issues_count":232,"forks":261,"open_issues":232,"watchers":4094,"default_branch":"master"}},"base":{"label":"weaveworks:master","ref":"master","sha":"b86e6412fa908cd9e0ac9803b3d49c70ec3e386c","user":{"login":"weaveworks","id":9976052,"avatar_url":"https://avatars.githubusercontent.com/u/9976052?v=3","gravatar_id":"","url":"https://api.github.com/users/weaveworks","html_url":"https://github.com/weaveworks","followers_url":"https://api.github.com/users/weaveworks/followers","following_url":"https://api.github.com/users/weaveworks/following{/other_user}","gists_url":"https://api.github.com/users/weaveworks/gists{/gist_id}","starred_url":"https://api.github.com/users/weaveworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weaveworks/subscriptions","organizations_url":"https://api.github.com/users/weaveworks/orgs","repos_url":"https://api.github.com/users/weaveworks/repos","events_url":"https://api.github.com/users/weaveworks/events{/privacy}","received_events_url":"https://api.github.com/users/weaveworks/received_events","type":"Organization","site_admin":false},"repo":{"id":23059575,"name":"weave","full_name":"weaveworks/weave","owner":{"login":"weaveworks","id":9976052,"avatar_url":"https://avatars.githubusercontent.com/u/9976052?v=3","gravatar_id":"","url":"https://api.github.com/users/weaveworks","html_url":"https://github.com/weaveworks","followers_url":"https://api.github.com/users/weaveworks/followers","following_url":"https://api.github.com/users/weaveworks/following{/other_user}","gists_url":"https://api.github.com/users/weaveworks/gists{/gist_id}","starred_url":"https://api.github.com/users/weaveworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weaveworks/subscriptions","organizations_url":"https://api.github.com/users/weaveworks/orgs","repos_url":"https://api.github.com/users/weaveworks/repos","events_url":"https://api.github.com/users/weaveworks/events{/privacy}","received_events_url":"https://api.github.com/users/weaveworks/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/weaveworks/weave","description":"Simple, resilient multi-host Docker networking","fork":false,"url":"https://api.github.com/repos/weaveworks/weave","forks_url":"https://api.github.com/repos/weaveworks/weave/forks","keys_url":"https://api.github.com/repos/weaveworks/weave/keys{/key_id}","collaborators_url":"https://api.github.com/repos/weaveworks/weave/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/weaveworks/weave/teams","hooks_url":"https://api.github.com/repos/weaveworks/weave/hooks","issue_events_url":"https://api.github.com/repos/weaveworks/weave/issues/events{/number}","events_url":"https://api.github.com/repos/weaveworks/weave/events","assignees_url":"https://api.github.com/repos/weaveworks/weave/assignees{/user}","branches_url":"https://api.github.com/repos/weaveworks/weave/branches{/branch}","tags_url":"https://api.github.com/repos/weaveworks/weave/tags","blobs_url":"https://api.github.com/repos/weaveworks/weave/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/weaveworks/weave/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/weaveworks/weave/git/refs{/sha}","trees_url":"https://api.github.com/repos/weaveworks/weave/git/trees{/sha}","statuses_url":"https://api.github.com/repos/weaveworks/weave/statuses/{sha}","languages_url":"https://api.github.com/repos/weaveworks/weave/languages","stargazers_url":"https://api.github.com/repos/weaveworks/weave/stargazers","contributors_url":"https://api.github.com/repos/weaveworks/weave/contributors","subscribers_url":"https://api.github.com/repos/weaveworks/weave/subscribers","subscription_url":"https://api.github.com/repos/weaveworks/weave/subscription","commits_url":"https://api.github.com/repos/weaveworks/weave/commits{/sha}","git_commits_url":"https://api.github.com/repos/weaveworks/weave/git/commits{/sha}","comments_url":"https://api.github.com/repos/weaveworks/weave/comments{/number}","issue_comment_url":"https://api.github.com/repos/weaveworks/weave/issues/comments{/number}","contents_url":"https://api.github.com/repos/weaveworks/weave/contents/{+path}","compare_url":"https://api.github.com/repos/weaveworks/weave/compare/{base}...{head}","merges_url":"https://api.github.com/repos/weaveworks/weave/merges","archive_url":"https://api.github.com/repos/weaveworks/weave/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/weaveworks/weave/downloads","issues_url":"https://api.github.com/repos/weaveworks/weave/issues{/number}","pulls_url":"https://api.github.com/repos/weaveworks/weave/pulls{/number}","milestones_url":"https://api.github.com/repos/weaveworks/weave/milestones{/number}","notifications_url":"https://api.github.com/repos/weaveworks/weave/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/weaveworks/weave/labels{/name}","releases_url":"https://api.github.com/repos/weaveworks/weave/releases{/id}","deployments_url":"https://api.github.com/repos/weaveworks/weave/deployments","created_at":"2014-08-18T05:19:07Z","updated_at":"2016-03-17T09:45:27Z","pushed_at":"2016-03-17T12:42:04Z","git_url":"git://github.com/weaveworks/weave.git","ssh_url":"git@github.com:weaveworks/weave.git","clone_url":"https://github.com/weaveworks/weave.git","svn_url":"https://github.com/weaveworks/weave","homepage":"http://weave.works","size":12074,"stargazers_count":4094,"watchers_count":4094,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":261,"mirror_url":null,"open_issues_count":232,"forks":261,"open_issues":232,"watchers":4094,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/weaveworks/weave/pulls/2030"},"html":{"href":"https://github.com/weaveworks/weave/pull/2030"},"issue":{"href":"https://api.github.com/repos/weaveworks/weave/issues/2030"},"comments":{"href":"https://api.github.com/repos/weaveworks/weave/issues/2030/comments"},"review_comments":{"href":"https://api.github.com/repos/weaveworks/weave/pulls/2030/comments"},"review_comment":{"href":"https://api.github.com/repos/weaveworks/weave/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/weaveworks/weave/pulls/2030/commits"},"statuses":{"href":"https://api.github.com/repos/weaveworks/weave/statuses/7c7cf687f9dc27979bb8f7cfe5431016313054ec"}}}}