{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/comments/28992076","id":28992076,"diff_hunk":"@@ -0,0 +1,142 @@\n+#!/bin/bash\n+\n+# Copyright 2015 Google Inc. All rights reserved.\n+#\n+# Licensed under the Apache License, Version 2.0 (the \"License\");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+#     http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+\n+# Monitors node configuration data from the metadata server and runs node\n+# upgrades when they change.\n+\n+# Settings\n+# POLL_INTERVAL is how frequently to issue curl requests after a failed curl.\n+readonly POLL_INTERVAL=10\n+# CACHE_DIR is where metadata files are saved once they've been curled.\n+readonly CACHE_DIR=\"metadata-cache\"\n+# *_EXT denote the role of a saved metadata file.\n+readonly CACHE_EXT=\"cache\"\n+readonly LATEST_EXT=\"latest\"\n+# WATCH_KEYS are the metadata keys for which, if any of their values change, a\n+# node upgrade is performed.\n+readonly WATCH_KEYS=(\"kube-env\" \"startup-script\")\n+\n+# get-metadata curls all keys in WATCH_KEYS from the metadata server, retrying\n+# until success, and saves them in CACHE_DIR named by the key and the provided\n+# extension.\n+#\n+# Assumed vars:\n+#   WATCH_KEYS\n+#   CACHE_DIR\n+#   POLL_INTERVAL\n+#\n+# Args:\n+#  $1 -- extension to use for files (e.g. CACHE_EXT or LATEST_EXT)\n+function get-metadata() {\n+\tlocal ext=\"${1}\"\n+\techo \"$(date) Attempting to get metadata.\"\n+\tfor k in \"${WATCH_KEYS[@]}\"; do\n+\t\techo \"$(date) Attempting to get metadata with key '${k}'.\"\n+\t\tlocal code=404\n+\t\tlocal cache_file=\"${CACHE_DIR}/${k}.${ext}\"\n+\t\tuntil [[ ${code} -eq 200 ]]; do","path":"cluster/saltbase/salt/node-upgrade-gcp/node-upgrade-gcp.sh","position":50,"original_position":50,"commit_id":"ae145558605153d6f356a0eede1a2438743f4e24","original_commit_id":"ae145558605153d6f356a0eede1a2438743f4e24","user":{"login":"zmerlynn","id":4942464,"avatar_url":"https://avatars.githubusercontent.com/u/4942464?v=3","gravatar_id":"","url":"https://api.github.com/users/zmerlynn","html_url":"https://github.com/zmerlynn","followers_url":"https://api.github.com/users/zmerlynn/followers","following_url":"https://api.github.com/users/zmerlynn/following{/other_user}","gists_url":"https://api.github.com/users/zmerlynn/gists{/gist_id}","starred_url":"https://api.github.com/users/zmerlynn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmerlynn/subscriptions","organizations_url":"https://api.github.com/users/zmerlynn/orgs","repos_url":"https://api.github.com/users/zmerlynn/repos","events_url":"https://api.github.com/users/zmerlynn/events{/privacy}","received_events_url":"https://api.github.com/users/zmerlynn/received_events","type":"User","site_admin":false},"body":"I don't understand the complexity of this loop, or bothering to explicity write the code. Is there any advantage to this over what we do elsewhere, which would just collapse this loop to:\r\n```\r\nuntil curl --fail --silent -H 'Metadata-Flavor: Google' \"http://metadata/computeMetadata/v1/instance/attributes/${k}\"; do sleep ${POLL_INTERVAL}; done\r\n```\r\n?","created_at":"2015-04-23T18:54:24Z","updated_at":"2015-04-23T18:54:24Z","html_url":"https://github.com/GoogleCloudPlatform/kubernetes/pull/7233#discussion_r28992076","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/7233","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/comments/28992076"},"html":{"href":"https://github.com/GoogleCloudPlatform/kubernetes/pull/7233#discussion_r28992076"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/7233"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/7233","id":33980601,"html_url":"https://github.com/GoogleCloudPlatform/kubernetes/pull/7233","diff_url":"https://github.com/GoogleCloudPlatform/kubernetes/pull/7233.diff","patch_url":"https://github.com/GoogleCloudPlatform/kubernetes/pull/7233.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/7233","number":7233,"state":"open","locked":false,"title":"Node upgrade daemon.","user":{"login":"mbforbes","id":1170062,"avatar_url":"https://avatars.githubusercontent.com/u/1170062?v=3","gravatar_id":"","url":"https://api.github.com/users/mbforbes","html_url":"https://github.com/mbforbes","followers_url":"https://api.github.com/users/mbforbes/followers","following_url":"https://api.github.com/users/mbforbes/following{/other_user}","gists_url":"https://api.github.com/users/mbforbes/gists{/gist_id}","starred_url":"https://api.github.com/users/mbforbes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbforbes/subscriptions","organizations_url":"https://api.github.com/users/mbforbes/orgs","repos_url":"https://api.github.com/users/mbforbes/repos","events_url":"https://api.github.com/users/mbforbes/events{/privacy}","received_events_url":"https://api.github.com/users/mbforbes/received_events","type":"User","site_admin":false},"body":"Give a node upgrade must make changes to the node's system, including the kubernetes binaries, it must happen outside of the kubelet itself. Thus, there seem to be two options for doing this:\r\n\r\n0. SSH into the node and run commands that way (affectionately known as _\"blasting bash\"_). This is what we have currently. \r\n\r\n0. Have a daemon running on the node that looks for a trigger to upgrade from some authority. This is what this PR implements, but only for GCE and using the metadata server.\r\n\r\nIn the long term, this should:\r\n- be version-aware (don't try to upgrade across unsupported config changes, like Docker or OS)\r\n- be a Go program\r\n- have a versioned API (both incoming [e.g. upgrade policy] and outgoing [upgrade status])\r\n- be able to upgrade itself\r\n- be provider agnostic\r\n\r\nPlease be careful merging this; I suspect this will be controversial as it's a nontrivial change to node behavior, so my hope was to send this PR out se we could begin throwing chairs around the room.\r\n\r\nThis implements #6099, a basic node upgrade mechanism without any nice-to-haves.","created_at":"2015-04-23T18:01:10Z","updated_at":"2015-04-23T18:54:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5880cc3aee3497b620870647474761fed1506c22","assignee":{"login":"zmerlynn","id":4942464,"avatar_url":"https://avatars.githubusercontent.com/u/4942464?v=3","gravatar_id":"","url":"https://api.github.com/users/zmerlynn","html_url":"https://github.com/zmerlynn","followers_url":"https://api.github.com/users/zmerlynn/followers","following_url":"https://api.github.com/users/zmerlynn/following{/other_user}","gists_url":"https://api.github.com/users/zmerlynn/gists{/gist_id}","starred_url":"https://api.github.com/users/zmerlynn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmerlynn/subscriptions","organizations_url":"https://api.github.com/users/zmerlynn/orgs","repos_url":"https://api.github.com/users/zmerlynn/repos","events_url":"https://api.github.com/users/zmerlynn/events{/privacy}","received_events_url":"https://api.github.com/users/zmerlynn/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/milestones/6","html_url":"https://github.com/GoogleCloudPlatform/kubernetes/milestones/v1.0","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/milestones/6/labels","id":969317,"number":6,"title":"v1.0","description":"Issues that need to be resolved for v1.0 of Kubernetes.","creator":{"login":"goltermann","id":9358478,"avatar_url":"https://avatars.githubusercontent.com/u/9358478?v=3","gravatar_id":"","url":"https://api.github.com/users/goltermann","html_url":"https://github.com/goltermann","followers_url":"https://api.github.com/users/goltermann/followers","following_url":"https://api.github.com/users/goltermann/following{/other_user}","gists_url":"https://api.github.com/users/goltermann/gists{/gist_id}","starred_url":"https://api.github.com/users/goltermann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/goltermann/subscriptions","organizations_url":"https://api.github.com/users/goltermann/orgs","repos_url":"https://api.github.com/users/goltermann/repos","events_url":"https://api.github.com/users/goltermann/events{/privacy}","received_events_url":"https://api.github.com/users/goltermann/received_events","type":"User","site_admin":false},"open_issues":114,"closed_issues":211,"state":"open","created_at":"2015-02-06T20:27:16Z","updated_at":"2015-04-23T18:45:01Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/7233/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/7233/comments","review_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/7233/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/statuses/ae145558605153d6f356a0eede1a2438743f4e24","head":{"label":"mbforbes:upgradeDaemon","ref":"upgradeDaemon","sha":"ae145558605153d6f356a0eede1a2438743f4e24","user":{"login":"mbforbes","id":1170062,"avatar_url":"https://avatars.githubusercontent.com/u/1170062?v=3","gravatar_id":"","url":"https://api.github.com/users/mbforbes","html_url":"https://github.com/mbforbes","followers_url":"https://api.github.com/users/mbforbes/followers","following_url":"https://api.github.com/users/mbforbes/following{/other_user}","gists_url":"https://api.github.com/users/mbforbes/gists{/gist_id}","starred_url":"https://api.github.com/users/mbforbes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbforbes/subscriptions","organizations_url":"https://api.github.com/users/mbforbes/orgs","repos_url":"https://api.github.com/users/mbforbes/repos","events_url":"https://api.github.com/users/mbforbes/events{/privacy}","received_events_url":"https://api.github.com/users/mbforbes/received_events","type":"User","site_admin":false},"repo":{"id":23891576,"name":"kubernetes","full_name":"mbforbes/kubernetes","owner":{"login":"mbforbes","id":1170062,"avatar_url":"https://avatars.githubusercontent.com/u/1170062?v=3","gravatar_id":"","url":"https://api.github.com/users/mbforbes","html_url":"https://github.com/mbforbes","followers_url":"https://api.github.com/users/mbforbes/followers","following_url":"https://api.github.com/users/mbforbes/following{/other_user}","gists_url":"https://api.github.com/users/mbforbes/gists{/gist_id}","starred_url":"https://api.github.com/users/mbforbes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbforbes/subscriptions","organizations_url":"https://api.github.com/users/mbforbes/orgs","repos_url":"https://api.github.com/users/mbforbes/repos","events_url":"https://api.github.com/users/mbforbes/events{/privacy}","received_events_url":"https://api.github.com/users/mbforbes/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mbforbes/kubernetes","description":"Container Cluster Manager","fork":true,"url":"https://api.github.com/repos/mbforbes/kubernetes","forks_url":"https://api.github.com/repos/mbforbes/kubernetes/forks","keys_url":"https://api.github.com/repos/mbforbes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mbforbes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mbforbes/kubernetes/teams","hooks_url":"https://api.github.com/repos/mbforbes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/mbforbes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/mbforbes/kubernetes/events","assignees_url":"https://api.github.com/repos/mbforbes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/mbforbes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/mbforbes/kubernetes/tags","blobs_url":"https://api.github.com/repos/mbforbes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mbforbes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mbforbes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/mbforbes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mbforbes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/mbforbes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/mbforbes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/mbforbes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/mbforbes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/mbforbes/kubernetes/subscription","commits_url":"https://api.github.com/repos/mbforbes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/mbforbes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/mbforbes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/mbforbes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/mbforbes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/mbforbes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mbforbes/kubernetes/merges","archive_url":"https://api.github.com/repos/mbforbes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mbforbes/kubernetes/downloads","issues_url":"https://api.github.com/repos/mbforbes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/mbforbes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/mbforbes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/mbforbes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mbforbes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/mbforbes/kubernetes/releases{/id}","created_at":"2014-09-10T20:45:41Z","updated_at":"2015-04-01T21:20:20Z","pushed_at":"2015-04-23T17:54:46Z","git_url":"git://github.com/mbforbes/kubernetes.git","ssh_url":"git@github.com:mbforbes/kubernetes.git","clone_url":"https://github.com/mbforbes/kubernetes.git","svn_url":"https://github.com/mbforbes/kubernetes","homepage":null,"size":46942,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"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":"GoogleCloudPlatform:master","ref":"master","sha":"f9156c281a7e0831308ed11eeb05627f19568ca3","user":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"GoogleCloudPlatform/kubernetes","owner":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GoogleCloudPlatform/kubernetes","description":"Container Cluster Manager from Google","fork":false,"url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes","forks_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/forks","keys_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/teams","hooks_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/events","assignees_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/tags","blobs_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/languages","stargazers_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/subscription","commits_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/merges","archive_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/downloads","issues_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/releases{/id}","created_at":"2014-06-06T22:56:04Z","updated_at":"2015-04-23T18:52:31Z","pushed_at":"2015-04-23T18:53:55Z","git_url":"git://github.com/GoogleCloudPlatform/kubernetes.git","ssh_url":"git@github.com:GoogleCloudPlatform/kubernetes.git","clone_url":"https://github.com/GoogleCloudPlatform/kubernetes.git","svn_url":"https://github.com/GoogleCloudPlatform/kubernetes","homepage":"http://kubernetes.io","size":197654,"stargazers_count":7289,"watchers_count":7289,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1451,"mirror_url":null,"open_issues_count":932,"forks":1451,"open_issues":932,"watchers":7289,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/7233"},"html":{"href":"https://github.com/GoogleCloudPlatform/kubernetes/pull/7233"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/7233"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/7233/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/7233/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/7233/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/statuses/ae145558605153d6f356a0eede1a2438743f4e24"}}}}