update-storage-objects.sh 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #!/usr/bin/env bash
  2. # Copyright 2015 The Kubernetes Authors.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. # Script to update etcd objects as per the latest API Version.
  16. # This just reads all objects and then writes them back as is to ensure that
  17. # they are written using the latest API version.
  18. #
  19. # Steps to use this script to upgrade the cluster to a new version:
  20. # https://kubernetes.io/docs/tasks/administer-cluster/cluster-management/#upgrading-to-a-different-api-version
  21. set -o errexit
  22. set -o nounset
  23. set -o pipefail
  24. KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
  25. source "${KUBE_ROOT}/hack/lib/init.sh"
  26. KUBECTL="${KUBE_OUTPUT_HOSTBIN}/kubectl"
  27. # List of resources to be updated.
  28. # TODO: Get this list of resources from server once
  29. # http://issue.k8s.io/2057 is fixed.
  30. declare -a resources=(
  31. "endpoints"
  32. "events"
  33. "limitranges"
  34. "namespaces"
  35. "nodes"
  36. "pods"
  37. "persistentvolumes"
  38. "persistentvolumeclaims"
  39. "replicationcontrollers"
  40. "resourcequotas"
  41. "secrets"
  42. "services"
  43. "jobs"
  44. "horizontalpodautoscalers"
  45. "storageclasses"
  46. "roles.rbac.authorization.k8s.io"
  47. "rolebindings.rbac.authorization.k8s.io"
  48. "clusterroles.rbac.authorization.k8s.io"
  49. "clusterrolebindings.rbac.authorization.k8s.io"
  50. "networkpolicies.networking.k8s.io"
  51. "ingresses.networking.k8s.io"
  52. )
  53. # Find all the namespaces.
  54. IFS=" " read -r -a namespaces <<< "$("${KUBECTL}" get namespaces -o go-template="{{range.items}}{{.metadata.name}} {{end}}")"
  55. if [ -z "${namespaces:-}" ]
  56. then
  57. echo "Unexpected: No namespace found. Nothing to do."
  58. exit 1
  59. fi
  60. all_failed=1
  61. for resource in "${resources[@]}"
  62. do
  63. for namespace in "${namespaces[@]}"
  64. do
  65. # If get fails, assume it's because the resource hasn't been installed in the apiserver.
  66. # TODO hopefully we can remove this once we use dynamic discovery of gettable/updateable
  67. # resources.
  68. set +e
  69. IFS=" " read -r -a instances <<< "$("${KUBECTL}" get "${resource}" --namespace="${namespace}" -o go-template="{{range.items}}{{.metadata.name}} {{end}}")"
  70. result=$?
  71. set -e
  72. if [[ "${all_failed}" -eq 1 && "${result}" -eq 0 ]]; then
  73. all_failed=0
  74. fi
  75. # Nothing to do if there is no instance of that resource.
  76. if [[ -z "${instances:-}" ]]
  77. then
  78. continue
  79. fi
  80. for instance in "${instances[@]}"
  81. do
  82. # Read and then write it back as is.
  83. # Update can fail if the object was updated after we fetched the
  84. # object, but before we could update it. We, hence, try the update
  85. # operation multiple times. But 5 continuous failures indicate some other
  86. # problem.
  87. success=0
  88. for (( tries=0; tries<5; ++tries ))
  89. do
  90. filename="/tmp/k8s-${namespace}-${resource}-${instance}.json"
  91. ( "${KUBECTL}" get "${resource}" "${instance}" --namespace="${namespace}" -o json > "${filename}" ) || true
  92. if [[ ! -s "${filename}" ]]
  93. then
  94. # This happens when the instance has been deleted. We can hence ignore
  95. # this instance.
  96. echo "Looks like ${instance} got deleted. Ignoring it"
  97. success=1
  98. break
  99. fi
  100. output=$("${KUBECTL}" replace -f "${filename}" --namespace="${namespace}") || true
  101. rm "${filename}"
  102. if [ -n "${output:-}" ]
  103. then
  104. success=1
  105. break
  106. fi
  107. done
  108. if [[ "${success}" -eq 0 ]]
  109. then
  110. echo "Error: failed to update ${resource}/${instance} in ${namespace} namespace after 5 tries"
  111. exit 1
  112. fi
  113. done
  114. if [[ "${resource}" == "namespaces" ]] || [[ "${resource}" == "nodes" ]]
  115. then
  116. # These resources are namespace agnostic. No need to update them for every
  117. # namespace.
  118. break
  119. fi
  120. done
  121. done
  122. if [[ "${all_failed}" -eq 1 ]]; then
  123. echo "kubectl get failed for all resources"
  124. exit 1
  125. fi
  126. echo "All objects updated successfully!!"
  127. exit 0