{"action":"created","comment":{"url":"https://api.github.com/repos/coreos/etcd/pulls/comments/31377721","id":31377721,"diff_hunk":"@@ -72,6 +72,18 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n \t\treturn\n \t}\n \n+\tif err := checkPeerVersionCompatibility(serverVersion(r.Header), minClusterVersion(r.Header)); err != nil {\n+\t\tlog.Printf(\"rafthttp: request ignored due to %v\", err)\n+\t\t// StatusForbidden has been used to forbid messages from removed member,","path":"rafthttp/http.go","position":6,"original_position":6,"commit_id":"0659cd4477815f3734cab1257d387edbd1d019f0","original_commit_id":"0659cd4477815f3734cab1257d387edbd1d019f0","user":{"login":"xiang90","id":4479947,"avatar_url":"https://avatars.githubusercontent.com/u/4479947?v=3","gravatar_id":"","url":"https://api.github.com/users/xiang90","html_url":"https://github.com/xiang90","followers_url":"https://api.github.com/users/xiang90/followers","following_url":"https://api.github.com/users/xiang90/following{/other_user}","gists_url":"https://api.github.com/users/xiang90/gists{/gist_id}","starred_url":"https://api.github.com/users/xiang90/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xiang90/subscriptions","organizations_url":"https://api.github.com/users/xiang90/orgs","repos_url":"https://api.github.com/users/xiang90/repos","events_url":"https://api.github.com/users/xiang90/events{/privacy}","received_events_url":"https://api.github.com/users/xiang90/received_events","type":"User","site_admin":false},"body":"hmm... i think we should still use statusForbidden... the other side can check the string. we need to define a const string error though.","created_at":"2015-05-30T04:39:36Z","updated_at":"2015-05-30T04:39:36Z","html_url":"https://github.com/coreos/etcd/pull/2889#discussion_r31377721","pull_request_url":"https://api.github.com/repos/coreos/etcd/pulls/2889","_links":{"self":{"href":"https://api.github.com/repos/coreos/etcd/pulls/comments/31377721"},"html":{"href":"https://github.com/coreos/etcd/pull/2889#discussion_r31377721"},"pull_request":{"href":"https://api.github.com/repos/coreos/etcd/pulls/2889"}}},"pull_request":{"url":"https://api.github.com/repos/coreos/etcd/pulls/2889","id":36551608,"html_url":"https://github.com/coreos/etcd/pull/2889","diff_url":"https://github.com/coreos/etcd/pull/2889.diff","patch_url":"https://github.com/coreos/etcd/pull/2889.patch","issue_url":"https://api.github.com/repos/coreos/etcd/issues/2889","number":2889,"state":"open","locked":false,"title":"wip rafthttp: version enforcement on rafthttp messages","user":{"login":"yichengq","id":2976232,"avatar_url":"https://avatars.githubusercontent.com/u/2976232?v=3","gravatar_id":"","url":"https://api.github.com/users/yichengq","html_url":"https://github.com/yichengq","followers_url":"https://api.github.com/users/yichengq/followers","following_url":"https://api.github.com/users/yichengq/following{/other_user}","gists_url":"https://api.github.com/users/yichengq/gists{/gist_id}","starred_url":"https://api.github.com/users/yichengq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yichengq/subscriptions","organizations_url":"https://api.github.com/users/yichengq/orgs","repos_url":"https://api.github.com/users/yichengq/repos","events_url":"https://api.github.com/users/yichengq/events{/privacy}","received_events_url":"https://api.github.com/users/yichengq/received_events","type":"User","site_admin":false},"body":"This PR sets etcd version and min cluster version in request header,\r\nand let server check version compatibility. rafthttp server\r\nwill reject any message from peer with incompatible version(too low\r\nversion or too high version), and print out warning logs.\r\n\r\nMoreover, it sets current cluster version in request header, and\r\nlet server print error log when cluster version is not in its valid\r\nrange.\r\n\r\nfor #2716 \r\n\r\nThe example output for incompatibile etcd members:\r\n```\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: request ignored due to remote version is too low (remote=2.1.0-alpha.0+git local=2.3.0-alpha.0+git)\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: request ignored due to remote version is too low (remote=2.1.0-alpha.0+git local=2.3.0-alpha.0+git)\r\n15:05:50 etcd1 | 2015/05/29 15:05:50 rafthttp: request sent was ignored due to version incompatiblity\r\n15:05:50 etcd1 | 2015/05/29 15:05:50 rafthttp: roundtripping error: incompatible version\r\n15:05:50 etcd1 | 2015/05/29 15:05:50 rafthttp: request sent was ignored due to version incompatiblity\r\n15:05:50 etcd1 | 2015/05/29 15:05:50 rafthttp: roundtripping error: incompatible version\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: request ignored due to remote version is too low (remote=2.1.0-alpha.0+git local=2.3.0-alpha.0+git)\r\n15:05:50 etcd2 | 2015/05/29 15:05:50 rafthttp: request sent was ignored due to version incompatiblity\r\n15:05:50 etcd2 | 2015/05/29 15:05:50 rafthttp: roundtripping error: incompatible version\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: request ignored due to remote version is too low (remote=2.1.0-alpha.0+git local=2.3.0-alpha.0+git)\r\n15:05:50 etcd2 | 2015/05/29 15:05:50 rafthttp: request sent was ignored due to version incompatiblity\r\n15:05:50 etcd2 | 2015/05/29 15:05:50 rafthttp: roundtripping error: incompatible version\r\n15:05:50 etcd1 | 2015/05/29 15:05:50 rafthttp: request ignored due to local version is too low (remote=2.3.0-alpha.0+git local=2.1.0-alpha.0+git)\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: request sent was ignored due to version incompatiblity\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: roundtripping error: incompatible version\r\n15:05:50 etcd2 | 2015/05/29 15:05:50 rafthttp: request ignored due to local version is too low (remote=2.3.0-alpha.0+git local=2.1.0-alpha.0+git)\r\n15:05:50 etcd1 | 2015/05/29 15:05:50 rafthttp: request ignored due to local version is too low (remote=2.3.0-alpha.0+git local=2.1.0-alpha.0+git)\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: request sent was ignored due to version incompatiblity\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: roundtripping error: incompatible version\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: request sent was ignored due to version incompatiblity\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: roundtripping error: incompatible version\r\n15:05:50 etcd2 | 2015/05/29 15:05:50 rafthttp: request ignored due to local version is too low (remote=2.3.0-alpha.0+git local=2.1.0-alpha.0+git)\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: request sent was ignored due to version incompatiblity\r\n15:05:50 etcd3 | 2015/05/29 15:05:50 rafthttp: roundtripping error: incompatible version\r\n```\r\n\r\nTODO:\r\n- [ ] add tests","created_at":"2015-05-29T22:44:11Z","updated_at":"2015-05-30T04:39:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a8f92149d5dfc83f0fe004d14c648e1ba29378a8","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/coreos/etcd/pulls/2889/commits","review_comments_url":"https://api.github.com/repos/coreos/etcd/pulls/2889/comments","review_comment_url":"https://api.github.com/repos/coreos/etcd/pulls/comments{/number}","comments_url":"https://api.github.com/repos/coreos/etcd/issues/2889/comments","statuses_url":"https://api.github.com/repos/coreos/etcd/statuses/0659cd4477815f3734cab1257d387edbd1d019f0","head":{"label":"yichengq:version-runtime-enforce","ref":"version-runtime-enforce","sha":"0659cd4477815f3734cab1257d387edbd1d019f0","user":{"login":"yichengq","id":2976232,"avatar_url":"https://avatars.githubusercontent.com/u/2976232?v=3","gravatar_id":"","url":"https://api.github.com/users/yichengq","html_url":"https://github.com/yichengq","followers_url":"https://api.github.com/users/yichengq/followers","following_url":"https://api.github.com/users/yichengq/following{/other_user}","gists_url":"https://api.github.com/users/yichengq/gists{/gist_id}","starred_url":"https://api.github.com/users/yichengq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yichengq/subscriptions","organizations_url":"https://api.github.com/users/yichengq/orgs","repos_url":"https://api.github.com/users/yichengq/repos","events_url":"https://api.github.com/users/yichengq/events{/privacy}","received_events_url":"https://api.github.com/users/yichengq/received_events","type":"User","site_admin":false},"repo":{"id":16744058,"name":"etcd","full_name":"yichengq/etcd","owner":{"login":"yichengq","id":2976232,"avatar_url":"https://avatars.githubusercontent.com/u/2976232?v=3","gravatar_id":"","url":"https://api.github.com/users/yichengq","html_url":"https://github.com/yichengq","followers_url":"https://api.github.com/users/yichengq/followers","following_url":"https://api.github.com/users/yichengq/following{/other_user}","gists_url":"https://api.github.com/users/yichengq/gists{/gist_id}","starred_url":"https://api.github.com/users/yichengq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yichengq/subscriptions","organizations_url":"https://api.github.com/users/yichengq/orgs","repos_url":"https://api.github.com/users/yichengq/repos","events_url":"https://api.github.com/users/yichengq/events{/privacy}","received_events_url":"https://api.github.com/users/yichengq/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/yichengq/etcd","description":"A highly-available key value store for shared configuration and service discovery","fork":true,"url":"https://api.github.com/repos/yichengq/etcd","forks_url":"https://api.github.com/repos/yichengq/etcd/forks","keys_url":"https://api.github.com/repos/yichengq/etcd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/yichengq/etcd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/yichengq/etcd/teams","hooks_url":"https://api.github.com/repos/yichengq/etcd/hooks","issue_events_url":"https://api.github.com/repos/yichengq/etcd/issues/events{/number}","events_url":"https://api.github.com/repos/yichengq/etcd/events","assignees_url":"https://api.github.com/repos/yichengq/etcd/assignees{/user}","branches_url":"https://api.github.com/repos/yichengq/etcd/branches{/branch}","tags_url":"https://api.github.com/repos/yichengq/etcd/tags","blobs_url":"https://api.github.com/repos/yichengq/etcd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/yichengq/etcd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/yichengq/etcd/git/refs{/sha}","trees_url":"https://api.github.com/repos/yichengq/etcd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/yichengq/etcd/statuses/{sha}","languages_url":"https://api.github.com/repos/yichengq/etcd/languages","stargazers_url":"https://api.github.com/repos/yichengq/etcd/stargazers","contributors_url":"https://api.github.com/repos/yichengq/etcd/contributors","subscribers_url":"https://api.github.com/repos/yichengq/etcd/subscribers","subscription_url":"https://api.github.com/repos/yichengq/etcd/subscription","commits_url":"https://api.github.com/repos/yichengq/etcd/commits{/sha}","git_commits_url":"https://api.github.com/repos/yichengq/etcd/git/commits{/sha}","comments_url":"https://api.github.com/repos/yichengq/etcd/comments{/number}","issue_comment_url":"https://api.github.com/repos/yichengq/etcd/issues/comments{/number}","contents_url":"https://api.github.com/repos/yichengq/etcd/contents/{+path}","compare_url":"https://api.github.com/repos/yichengq/etcd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/yichengq/etcd/merges","archive_url":"https://api.github.com/repos/yichengq/etcd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/yichengq/etcd/downloads","issues_url":"https://api.github.com/repos/yichengq/etcd/issues{/number}","pulls_url":"https://api.github.com/repos/yichengq/etcd/pulls{/number}","milestones_url":"https://api.github.com/repos/yichengq/etcd/milestones{/number}","notifications_url":"https://api.github.com/repos/yichengq/etcd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/yichengq/etcd/labels{/name}","releases_url":"https://api.github.com/repos/yichengq/etcd/releases{/id}","created_at":"2014-02-11T20:18:23Z","updated_at":"2015-02-12T19:42:08Z","pushed_at":"2015-05-29T22:40:07Z","git_url":"git://github.com/yichengq/etcd.git","ssh_url":"git@github.com:yichengq/etcd.git","clone_url":"https://github.com/yichengq/etcd.git","svn_url":"https://github.com/yichengq/etcd","homepage":"","size":18774,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"coreos:master","ref":"master","sha":"871107c65a3066cdbd0a08982369b77aa276745e","user":{"login":"coreos","id":3730757,"avatar_url":"https://avatars.githubusercontent.com/u/3730757?v=3","gravatar_id":"","url":"https://api.github.com/users/coreos","html_url":"https://github.com/coreos","followers_url":"https://api.github.com/users/coreos/followers","following_url":"https://api.github.com/users/coreos/following{/other_user}","gists_url":"https://api.github.com/users/coreos/gists{/gist_id}","starred_url":"https://api.github.com/users/coreos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coreos/subscriptions","organizations_url":"https://api.github.com/users/coreos/orgs","repos_url":"https://api.github.com/users/coreos/repos","events_url":"https://api.github.com/users/coreos/events{/privacy}","received_events_url":"https://api.github.com/users/coreos/received_events","type":"Organization","site_admin":false},"repo":{"id":11225014,"name":"etcd","full_name":"coreos/etcd","owner":{"login":"coreos","id":3730757,"avatar_url":"https://avatars.githubusercontent.com/u/3730757?v=3","gravatar_id":"","url":"https://api.github.com/users/coreos","html_url":"https://github.com/coreos","followers_url":"https://api.github.com/users/coreos/followers","following_url":"https://api.github.com/users/coreos/following{/other_user}","gists_url":"https://api.github.com/users/coreos/gists{/gist_id}","starred_url":"https://api.github.com/users/coreos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coreos/subscriptions","organizations_url":"https://api.github.com/users/coreos/orgs","repos_url":"https://api.github.com/users/coreos/repos","events_url":"https://api.github.com/users/coreos/events{/privacy}","received_events_url":"https://api.github.com/users/coreos/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/coreos/etcd","description":"A highly-available key-value store for shared configuration and service discovery","fork":false,"url":"https://api.github.com/repos/coreos/etcd","forks_url":"https://api.github.com/repos/coreos/etcd/forks","keys_url":"https://api.github.com/repos/coreos/etcd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/coreos/etcd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/coreos/etcd/teams","hooks_url":"https://api.github.com/repos/coreos/etcd/hooks","issue_events_url":"https://api.github.com/repos/coreos/etcd/issues/events{/number}","events_url":"https://api.github.com/repos/coreos/etcd/events","assignees_url":"https://api.github.com/repos/coreos/etcd/assignees{/user}","branches_url":"https://api.github.com/repos/coreos/etcd/branches{/branch}","tags_url":"https://api.github.com/repos/coreos/etcd/tags","blobs_url":"https://api.github.com/repos/coreos/etcd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/coreos/etcd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/coreos/etcd/git/refs{/sha}","trees_url":"https://api.github.com/repos/coreos/etcd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/coreos/etcd/statuses/{sha}","languages_url":"https://api.github.com/repos/coreos/etcd/languages","stargazers_url":"https://api.github.com/repos/coreos/etcd/stargazers","contributors_url":"https://api.github.com/repos/coreos/etcd/contributors","subscribers_url":"https://api.github.com/repos/coreos/etcd/subscribers","subscription_url":"https://api.github.com/repos/coreos/etcd/subscription","commits_url":"https://api.github.com/repos/coreos/etcd/commits{/sha}","git_commits_url":"https://api.github.com/repos/coreos/etcd/git/commits{/sha}","comments_url":"https://api.github.com/repos/coreos/etcd/comments{/number}","issue_comment_url":"https://api.github.com/repos/coreos/etcd/issues/comments{/number}","contents_url":"https://api.github.com/repos/coreos/etcd/contents/{+path}","compare_url":"https://api.github.com/repos/coreos/etcd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/coreos/etcd/merges","archive_url":"https://api.github.com/repos/coreos/etcd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/coreos/etcd/downloads","issues_url":"https://api.github.com/repos/coreos/etcd/issues{/number}","pulls_url":"https://api.github.com/repos/coreos/etcd/pulls{/number}","milestones_url":"https://api.github.com/repos/coreos/etcd/milestones{/number}","notifications_url":"https://api.github.com/repos/coreos/etcd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/coreos/etcd/labels{/name}","releases_url":"https://api.github.com/repos/coreos/etcd/releases{/id}","created_at":"2013-07-06T21:57:21Z","updated_at":"2015-05-29T15:17:24Z","pushed_at":"2015-05-30T01:51:39Z","git_url":"git://github.com/coreos/etcd.git","ssh_url":"git@github.com:coreos/etcd.git","clone_url":"https://github.com/coreos/etcd.git","svn_url":"https://github.com/coreos/etcd","homepage":"","size":35203,"stargazers_count":6554,"watchers_count":6554,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":847,"mirror_url":null,"open_issues_count":163,"forks":847,"open_issues":163,"watchers":6554,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/coreos/etcd/pulls/2889"},"html":{"href":"https://github.com/coreos/etcd/pull/2889"},"issue":{"href":"https://api.github.com/repos/coreos/etcd/issues/2889"},"comments":{"href":"https://api.github.com/repos/coreos/etcd/issues/2889/comments"},"review_comments":{"href":"https://api.github.com/repos/coreos/etcd/pulls/2889/comments"},"review_comment":{"href":"https://api.github.com/repos/coreos/etcd/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/coreos/etcd/pulls/2889/commits"},"statuses":{"href":"https://api.github.com/repos/coreos/etcd/statuses/0659cd4477815f3734cab1257d387edbd1d019f0"}}}}