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