test-update-storage-objects.sh 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #!/usr/bin/env bash
  2. # Copyright 2014 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 test cluster/update-storage-objects.sh works as expected.
  16. set -o errexit
  17. set -o nounset
  18. set -o pipefail
  19. KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
  20. source "${KUBE_ROOT}/hack/lib/init.sh"
  21. # The api version in which objects are currently stored in etcd.
  22. KUBE_OLD_API_VERSION=${KUBE_OLD_API_VERSION:-"v1"}
  23. # The api version in which our etcd objects should be converted to.
  24. # The new api version
  25. KUBE_NEW_API_VERSION=${KUBE_NEW_API_VERSION:-"v1"}
  26. KUBE_OLD_STORAGE_VERSIONS=${KUBE_OLD_STORAGE_VERSIONS:-""}
  27. KUBE_NEW_STORAGE_VERSIONS=${KUBE_NEW_STORAGE_VERSIONS:-""}
  28. KUBE_STORAGE_MEDIA_TYPE_JSON="application/json"
  29. KUBE_STORAGE_MEDIA_TYPE_PROTOBUF="application/vnd.kubernetes.protobuf"
  30. ETCD_HOST=${ETCD_HOST:-127.0.0.1}
  31. ETCD_PORT=${ETCD_PORT:-2379}
  32. ETCD_PREFIX=${ETCD_PREFIX:-randomPrefix}
  33. API_PORT=${API_PORT:-8080}
  34. API_HOST=${API_HOST:-127.0.0.1}
  35. RUNTIME_CONFIG=""
  36. ETCDCTL=$(which etcdctl)
  37. KUBECTL="${KUBE_OUTPUT_HOSTBIN}/kubectl"
  38. UPDATE_ETCD_OBJECTS_SCRIPT="${KUBE_ROOT}/cluster/update-storage-objects.sh"
  39. DISABLE_ADMISSION_PLUGINS="ServiceAccount,NamespaceLifecycle,LimitRanger,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PersistentVolumeLabel,DefaultStorageClass,StorageObjectInUseProtection"
  40. function startApiServer() {
  41. local storage_versions=${1:-""}
  42. local storage_media_type=${2:-""}
  43. kube::log::status "Starting kube-apiserver with..."
  44. kube::log::status " storage-media-type: ${storage_media_type}"
  45. kube::log::status " runtime-config: ${RUNTIME_CONFIG}"
  46. kube::log::status " storage-version overrides: ${storage_versions}"
  47. "${KUBE_OUTPUT_HOSTBIN}/kube-apiserver" \
  48. --insecure-bind-address="${API_HOST}" \
  49. --bind-address="${API_HOST}" \
  50. --insecure-port="${API_PORT}" \
  51. --storage-backend="etcd3" \
  52. --etcd-servers="http://${ETCD_HOST}:${ETCD_PORT}" \
  53. --etcd-prefix="/${ETCD_PREFIX}" \
  54. --runtime-config="${RUNTIME_CONFIG}" \
  55. --disable-admission-plugins="${DISABLE_ADMISSION_PLUGINS}" \
  56. --cert-dir="${TMPDIR:-/tmp/}" \
  57. --service-cluster-ip-range="10.0.0.0/24" \
  58. --storage-versions="${storage_versions}" \
  59. --storage-media-type="${storage_media_type}" 1>&2 &
  60. APISERVER_PID=$!
  61. # url, prefix, wait, times
  62. kube::util::wait_for_url "http://${API_HOST}:${API_PORT}/healthz" "apiserver: " 1 120
  63. }
  64. function killApiServer() {
  65. kube::log::status "Killing api server"
  66. if [[ -n ${APISERVER_PID-} ]]; then
  67. kill ${APISERVER_PID} 1>&2 2>/dev/null
  68. wait ${APISERVER_PID} || true
  69. kube::log::status "api server exited"
  70. fi
  71. unset APISERVER_PID
  72. }
  73. function cleanup() {
  74. killApiServer
  75. kube::etcd::cleanup
  76. kube::log::status "Clean up complete"
  77. }
  78. trap cleanup EXIT SIGINT
  79. make -C "${KUBE_ROOT}" WHAT=cmd/kube-apiserver
  80. kube::etcd::start
  81. echo "${ETCD_VERSION}" > "${ETCD_DIR}/version.txt"
  82. ### BEGIN TEST DEFINITION CUSTOMIZATION ###
  83. # source_file,resource,namespace,name,old_version,new_version
  84. tests=(
  85. "test/e2e/testing-manifests/rbd-storage-class.yaml,storageclasses,,slow,v1beta1,v1"
  86. )
  87. KUBE_OLD_API_VERSION="networking.k8s.io/v1,storage.k8s.io/v1beta1,extensions/v1beta1"
  88. KUBE_NEW_API_VERSION="networking.k8s.io/v1,storage.k8s.io/v1beta1,storage.k8s.io/v1,extensions/v1beta1,policy/v1beta1"
  89. KUBE_OLD_STORAGE_VERSIONS="storage.k8s.io/v1beta1"
  90. KUBE_NEW_STORAGE_VERSIONS="storage.k8s.io/v1beta1,storage.k8s.io/v1"
  91. ### END TEST DEFINITION CUSTOMIZATION ###
  92. #######################################################
  93. # Step 1: Start a server which supports both the old and new api versions,
  94. # but KUBE_OLD_API_VERSION is the latest (storage) version.
  95. # Additionally use KUBE_STORAGE_MEDIA_TYPE_JSON for storage encoding.
  96. #######################################################
  97. RUNTIME_CONFIG="api/all=false,api/v1=true,apiregistration.k8s.io/v1=true,${KUBE_OLD_API_VERSION}=true,${KUBE_NEW_API_VERSION}=true"
  98. startApiServer ${KUBE_OLD_STORAGE_VERSIONS} ${KUBE_STORAGE_MEDIA_TYPE_JSON}
  99. # Create object(s)
  100. for test in "${tests[@]}"; do
  101. IFS=',' read -ra test_data <<<"$test"
  102. source_file=${test_data[0]}
  103. kube::log::status "Creating ${source_file}"
  104. ${KUBECTL} create -f "${KUBE_ROOT}/${source_file}"
  105. # Verify that the storage version is the old version
  106. resource=${test_data[1]}
  107. namespace=${test_data[2]}
  108. name=${test_data[3]}
  109. old_storage_version=${test_data[4]}
  110. if [ -n "${namespace}" ]; then
  111. namespace="${namespace}/"
  112. fi
  113. kube::log::status "Verifying ${resource}/${namespace}${name} has storage version ${old_storage_version} in etcd"
  114. ETCDCTL_API=3 ${ETCDCTL} --endpoints="http://${ETCD_HOST}:${ETCD_PORT}" get "/${ETCD_PREFIX}/${resource}/${namespace}${name}" | grep "${old_storage_version}"
  115. done
  116. killApiServer
  117. #######################################################
  118. # Step 2: Start a server which supports both the old and new api versions,
  119. # but KUBE_NEW_API_VERSION is the latest (storage) version.
  120. # Still use KUBE_STORAGE_MEDIA_TYPE_JSON for storage encoding.
  121. #######################################################
  122. RUNTIME_CONFIG="api/all=false,api/v1=true,apiregistration.k8s.io/v1=true,${KUBE_OLD_API_VERSION}=true,${KUBE_NEW_API_VERSION}=true"
  123. startApiServer ${KUBE_NEW_STORAGE_VERSIONS} ${KUBE_STORAGE_MEDIA_TYPE_JSON}
  124. # Update etcd objects, so that will now be stored in the new api version.
  125. kube::log::status "Updating storage versions in etcd"
  126. ${UPDATE_ETCD_OBJECTS_SCRIPT}
  127. # Verify that the storage version was changed in etcd
  128. for test in "${tests[@]}"; do
  129. IFS=',' read -ra test_data <<<"$test"
  130. resource=${test_data[1]}
  131. namespace=${test_data[2]}
  132. name=${test_data[3]}
  133. new_storage_version=${test_data[5]}
  134. if [ -n "${namespace}" ]; then
  135. namespace="${namespace}/"
  136. fi
  137. kube::log::status "Verifying ${resource}/${namespace}${name} has updated storage version ${new_storage_version} in etcd"
  138. ETCDCTL_API=3 ${ETCDCTL} --endpoints="http://${ETCD_HOST}:${ETCD_PORT}" get "/${ETCD_PREFIX}/${resource}/${namespace}${name}" | grep "${new_storage_version}"
  139. done
  140. killApiServer
  141. #######################################################
  142. # Step 3 : Start a server which supports only the new api version.
  143. # However, change storage encoding to KUBE_STORAGE_MEDIA_TYPE_PROTOBUF.
  144. #######################################################
  145. RUNTIME_CONFIG="api/all=false,api/v1=true,apiregistration.k8s.io/v1=true,${KUBE_NEW_API_VERSION}=true"
  146. # This seems to reduce flakiness.
  147. sleep 1
  148. startApiServer ${KUBE_NEW_STORAGE_VERSIONS} ${KUBE_STORAGE_MEDIA_TYPE_PROTOBUF}
  149. for test in "${tests[@]}"; do
  150. IFS=',' read -ra test_data <<<"$test"
  151. resource=${test_data[1]}
  152. namespace=${test_data[2]}
  153. name=${test_data[3]}
  154. namespace_flag=""
  155. # Verify that the server is able to read the object.
  156. if [ -n "${namespace}" ]; then
  157. namespace_flag="--namespace=${namespace}"
  158. namespace="${namespace}/"
  159. fi
  160. kube::log::status "Verifying we can retrieve ${resource}/${namespace}${name} via kubectl"
  161. # We have to remove the cached discovery information about the old version; otherwise,
  162. # the 'kubectl get' will use that and fail to find the resource.
  163. rm -rf "${HOME}/.kube/cache/discovery/localhost_8080/${KUBE_OLD_STORAGE_VERSIONS}"
  164. ${KUBECTL} get "${namespace_flag}" "${resource}/${name}"
  165. done
  166. killApiServer