get-kube-binaries.sh 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #!/usr/bin/env bash
  2. # Copyright 2016 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. # This script downloads and installs the Kubernetes client and server
  16. # (and optionally test) binaries,
  17. # It is intended to be called from an extracted Kubernetes release tarball.
  18. #
  19. # We automatically choose the correct client binaries to download.
  20. #
  21. # Options:
  22. # Set KUBERNETES_SERVER_ARCH to choose the server (Kubernetes cluster)
  23. # architecture to download:
  24. # * amd64 [default]
  25. # * arm
  26. # * arm64
  27. # * ppc64le
  28. # * s390x
  29. #
  30. # Set KUBERNETES_CLIENT_OS to choose the client OS to download:
  31. # * current OS [default]
  32. # * linux
  33. # * darwin
  34. # * windows
  35. #
  36. # Set KUBERNETES_CLIENT_ARCH to choose the client architecture to download:
  37. # * current architecture [default]
  38. # * amd64
  39. # * arm
  40. # * arm64
  41. # * ppc64le
  42. # * s390x
  43. # * windows
  44. #
  45. # Set KUBERNETES_SKIP_CONFIRM to skip the installation confirmation prompt.
  46. # Set KUBERNETES_RELEASE_URL to choose where to download binaries from.
  47. # (Defaults to https://storage.googleapis.com/kubernetes-release/release).
  48. # Set KUBERNETES_DOWNLOAD_TESTS to additionally download and extract the test
  49. # binaries tarball.
  50. set -o errexit
  51. set -o nounset
  52. set -o pipefail
  53. KUBE_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
  54. KUBERNETES_RELEASE_URL="${KUBERNETES_RELEASE_URL:-https://dl.k8s.io}"
  55. function detect_kube_release() {
  56. if [[ -n "${KUBE_VERSION:-}" ]]; then
  57. return 0 # Allow caller to explicitly set version
  58. fi
  59. if [[ ! -e "${KUBE_ROOT}/version" ]]; then
  60. echo "Can't determine Kubernetes release." >&2
  61. echo "${BASH_SOURCE[0]} should only be run from a prebuilt Kubernetes release." >&2
  62. echo "Did you mean to use get-kube.sh instead?" >&2
  63. exit 1
  64. fi
  65. KUBE_VERSION=$(cat "${KUBE_ROOT}/version")
  66. }
  67. function detect_client_info() {
  68. if [ -n "${KUBERNETES_CLIENT_OS-}" ]; then
  69. CLIENT_PLATFORM="${KUBERNETES_CLIENT_OS}"
  70. else
  71. local kernel
  72. kernel="$(uname -s)"
  73. case "${kernel}" in
  74. Darwin)
  75. CLIENT_PLATFORM="darwin"
  76. ;;
  77. Linux)
  78. CLIENT_PLATFORM="linux"
  79. ;;
  80. *)
  81. echo "Unknown, unsupported platform: ${kernel}." >&2
  82. echo "Supported platforms: Linux, Darwin." >&2
  83. echo "Bailing out." >&2
  84. exit 2
  85. esac
  86. fi
  87. if [ -n "${KUBERNETES_CLIENT_ARCH-}" ]; then
  88. CLIENT_ARCH="${KUBERNETES_CLIENT_ARCH}"
  89. else
  90. # TODO: migrate the kube::util::host_platform function out of hack/lib and
  91. # use it here.
  92. local machine
  93. machine="$(uname -m)"
  94. case "${machine}" in
  95. x86_64*|i?86_64*|amd64*)
  96. CLIENT_ARCH="amd64"
  97. ;;
  98. aarch64*|arm64*)
  99. CLIENT_ARCH="arm64"
  100. ;;
  101. arm*)
  102. CLIENT_ARCH="arm"
  103. ;;
  104. i?86*)
  105. CLIENT_ARCH="386"
  106. ;;
  107. s390x*)
  108. CLIENT_ARCH="s390x"
  109. ;;
  110. *)
  111. echo "Unknown, unsupported architecture (${machine})." >&2
  112. echo "Supported architectures x86_64, i686, arm, arm64, s390x." >&2
  113. echo "Bailing out." >&2
  114. exit 3
  115. ;;
  116. esac
  117. fi
  118. }
  119. function md5sum_file() {
  120. if which md5 >/dev/null 2>&1; then
  121. md5 -q "$1"
  122. else
  123. md5sum "$1" | awk '{ print $1 }'
  124. fi
  125. }
  126. function sha1sum_file() {
  127. if which sha1sum >/dev/null 2>&1; then
  128. sha1sum "$1" | awk '{ print $1 }'
  129. else
  130. shasum -a1 "$1" | awk '{ print $1 }'
  131. fi
  132. }
  133. function download_tarball() {
  134. local -r download_path="$1"
  135. local -r file="$2"
  136. local trace_on="off"
  137. if [[ -o xtrace ]]; then
  138. trace_on="on"
  139. set +x
  140. fi
  141. url="${DOWNLOAD_URL_PREFIX}/${file}"
  142. mkdir -p "${download_path}"
  143. if [[ $(which curl) ]]; then
  144. # if the url belongs to GCS API we should use oauth2_token in the headers
  145. curl_headers=""
  146. if { [[ "${KUBERNETES_PROVIDER:-gce}" == "gce" ]] || [[ "${KUBERNETES_PROVIDER}" == "gke" ]] ; } &&
  147. [[ "$url" =~ ^https://storage.googleapis.com.* ]]; then
  148. curl_headers="Authorization: Bearer $(gcloud auth print-access-token)"
  149. fi
  150. curl ${curl_headers:+-H "${curl_headers}"} -fL --retry 3 --keepalive-time 2 "${url}" -o "${download_path}/${file}"
  151. elif [[ $(which wget) ]]; then
  152. wget "${url}" -O "${download_path}/${file}"
  153. else
  154. echo "Couldn't find curl or wget. Bailing out." >&2
  155. exit 4
  156. fi
  157. echo
  158. local md5sum sha1sum
  159. md5sum=$(md5sum_file "${download_path}/${file}")
  160. echo "md5sum(${file})=${md5sum}"
  161. sha1sum=$(sha1sum_file "${download_path}/${file}")
  162. echo "sha1sum(${file})=${sha1sum}"
  163. echo
  164. # TODO: add actual verification
  165. if [[ "${trace_on}" == "on" ]]; then
  166. set -x
  167. fi
  168. }
  169. function extract_arch_tarball() {
  170. local -r tarfile="$1"
  171. local -r platform="$2"
  172. local -r arch="$3"
  173. platforms_dir="${KUBE_ROOT}/platforms/${platform}/${arch}"
  174. echo "Extracting ${tarfile} into ${platforms_dir}"
  175. mkdir -p "${platforms_dir}"
  176. # Tarball looks like kubernetes/{client,server,test}/bin/BINARY"
  177. tar -xzf "${tarfile}" --strip-components 3 -C "${platforms_dir}"
  178. }
  179. detect_kube_release
  180. DOWNLOAD_URL_PREFIX="${KUBERNETES_RELEASE_URL}/${KUBE_VERSION}"
  181. SERVER_PLATFORM="linux"
  182. SERVER_ARCH="${KUBERNETES_SERVER_ARCH:-amd64}"
  183. SERVER_TAR="kubernetes-server-${SERVER_PLATFORM}-${SERVER_ARCH}.tar.gz"
  184. if [[ -n "${KUBERNETES_NODE_PLATFORM-}" || -n "${KUBERNETES_NODE_ARCH-}" ]]; then
  185. NODE_PLATFORM="${KUBERNETES_NODE_PLATFORM:-${SERVER_PLATFORM}}"
  186. NODE_ARCH="${KUBERNETES_NODE_ARCH:-${SERVER_ARCH}}"
  187. NODE_TAR="kubernetes-node-${NODE_PLATFORM}-${NODE_ARCH}.tar.gz"
  188. fi
  189. detect_client_info
  190. CLIENT_TAR="kubernetes-client-${CLIENT_PLATFORM}-${CLIENT_ARCH}.tar.gz"
  191. echo "Kubernetes release: ${KUBE_VERSION}"
  192. echo "Server: ${SERVER_PLATFORM}/${SERVER_ARCH} (to override, set KUBERNETES_SERVER_ARCH)"
  193. printf "Client: %s/%s" "${CLIENT_PLATFORM}" "${CLIENT_ARCH}"
  194. if [ -z "${KUBERNETES_CLIENT_OS-}" ] && [ -z "${KUBERNETES_CLIENT_ARCH-}" ]; then
  195. printf " (autodetected)"
  196. fi
  197. echo " (to override, set KUBERNETES_CLIENT_OS and/or KUBERNETES_CLIENT_ARCH)"
  198. echo
  199. echo "Will download ${SERVER_TAR} from ${DOWNLOAD_URL_PREFIX}"
  200. echo "Will download and extract ${CLIENT_TAR} from ${DOWNLOAD_URL_PREFIX}"
  201. DOWNLOAD_NODE_TAR=false
  202. if [[ -n "${NODE_TAR:-}" ]]; then
  203. DOWNLOAD_NODE_TAR=true
  204. echo "Will download and extract ${NODE_TAR} from ${DOWNLOAD_URL_PREFIX}"
  205. fi
  206. DOWNLOAD_TESTS_TAR=false
  207. if [[ -n "${KUBERNETES_DOWNLOAD_TESTS-}" ]]; then
  208. DOWNLOAD_TESTS_TAR=true
  209. echo "Will download and extract kubernetes-test tarball(s) from ${DOWNLOAD_URL_PREFIX}"
  210. fi
  211. if [[ -z "${KUBERNETES_SKIP_CONFIRM-}" ]]; then
  212. echo "Is this ok? [Y]/n"
  213. read -r confirm
  214. if [[ "${confirm}" =~ ^[nN]$ ]]; then
  215. echo "Aborting."
  216. exit 1
  217. fi
  218. fi
  219. download_tarball "${KUBE_ROOT}/server" "${SERVER_TAR}"
  220. if "${DOWNLOAD_NODE_TAR}"; then
  221. download_tarball "${KUBE_ROOT}/node" "${NODE_TAR}"
  222. fi
  223. download_tarball "${KUBE_ROOT}/client" "${CLIENT_TAR}"
  224. extract_arch_tarball "${KUBE_ROOT}/client/${CLIENT_TAR}" "${CLIENT_PLATFORM}" "${CLIENT_ARCH}"
  225. ln -s "${KUBE_ROOT}/platforms/${CLIENT_PLATFORM}/${CLIENT_ARCH}" "${KUBE_ROOT}/client/bin"
  226. echo "Add '${KUBE_ROOT}/client/bin' to your PATH to use newly-installed binaries."
  227. if "${DOWNLOAD_TESTS_TAR}"; then
  228. TESTS_PORTABLE_TAR="kubernetes-test-portable.tar.gz"
  229. download_tarball "${KUBE_ROOT}/test" "${TESTS_PORTABLE_TAR}" || true
  230. if [[ -f "${KUBE_ROOT}/test/${TESTS_PORTABLE_TAR}" ]]; then
  231. echo "Extracting ${TESTS_PORTABLE_TAR} into ${KUBE_ROOT}"
  232. # Strip leading "kubernetes/"
  233. tar -xzf "${KUBE_ROOT}/test/${TESTS_PORTABLE_TAR}" --strip-components 1 -C "${KUBE_ROOT}"
  234. # Next, download platform-specific test tarballs for all relevant platforms
  235. TEST_PLATFORM_TUPLES=(
  236. "${CLIENT_PLATFORM}/${CLIENT_ARCH}"
  237. "${SERVER_PLATFORM}/${SERVER_ARCH}"
  238. )
  239. if [[ -n "${NODE_PLATFORM:-}" && -n "${NODE_ARCH:-}" ]]; then
  240. TEST_PLATFORM_TUPLES+=("${NODE_PLATFORM}/${NODE_ARCH}")
  241. fi
  242. # Loop over only the unique tuples
  243. for TUPLE in $(printf "%s\n" "${TEST_PLATFORM_TUPLES[@]}" | sort -u); do
  244. OS=$(echo "${TUPLE}" | cut -d/ -f1)
  245. ARCH=$(echo "${TUPLE}" | cut -d/ -f2)
  246. TEST_PLATFORM_TAR="kubernetes-test-${OS}-${ARCH}.tar.gz"
  247. download_tarball "${KUBE_ROOT}/test" "${TEST_PLATFORM_TAR}"
  248. extract_arch_tarball "${KUBE_ROOT}/test/${TEST_PLATFORM_TAR}" "${OS}" "${ARCH}"
  249. done
  250. else
  251. echo "Failed to download portable test tarball, falling back to mondo test tarball."
  252. TESTS_MONDO_TAR="kubernetes-test.tar.gz"
  253. download_tarball "${KUBE_ROOT}/test" "${TESTS_MONDO_TAR}"
  254. echo "Extracting ${TESTS_MONDO_TAR} into ${KUBE_ROOT}"
  255. # Strip leading "kubernetes/"
  256. tar -xzf "${KUBE_ROOT}/test/${TESTS_MONDO_TAR}" --strip-components 1 -C "${KUBE_ROOT}"
  257. fi
  258. fi