common.sh 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. #!/usr/bin/env bash
  2. # Copyright 2017 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. # Common utilities for kube-up/kube-down
  16. set -o errexit
  17. set -o nounset
  18. set -o pipefail
  19. KUBE_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)
  20. DEFAULT_KUBECONFIG="${HOME:-.}/.kube/config"
  21. source "${KUBE_ROOT}/hack/lib/util.sh"
  22. # KUBE_RELEASE_VERSION_REGEX matches things like "v1.2.3" or "v1.2.3-alpha.4"
  23. #
  24. # NOTE This must match the version_regex in build/common.sh
  25. # kube::release::parse_and_validate_release_version()
  26. #
  27. # KUBE_RELEASE_VERSION_REGEX is used in hack/get-build.sh and cluster/gce/util.sh and KUBE_RELEASE_VERSION_DASHED_REGEX is used in cluster/gce/util.sh,
  28. # make sure to remove these vars when not used anymore
  29. export KUBE_RELEASE_VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-([a-zA-Z0-9]+)\\.(0|[1-9][0-9]*))?$"
  30. export KUBE_RELEASE_VERSION_DASHED_REGEX="v(0|[1-9][0-9]*)-(0|[1-9][0-9]*)-(0|[1-9][0-9]*)(-([a-zA-Z0-9]+)-(0|[1-9][0-9]*))?"
  31. # KUBE_CI_VERSION_REGEX matches things like "v1.2.3-alpha.4.56+abcdefg" This
  32. #
  33. # NOTE This must match the version_regex in build/common.sh
  34. # kube::release::parse_and_validate_ci_version()
  35. #
  36. # TODO: KUBE_CI_VERSION_REGEX is used in hack/get-build.sh and KUBE_CI_VERSION_DASHED_REGEX is used in cluster/gce/util.sh,
  37. # make sure to remove these vars when not used anymore
  38. export KUBE_CI_VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)-([a-zA-Z0-9]+)\\.(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*)\\+[-0-9a-z]*)?$"
  39. export KUBE_CI_VERSION_DASHED_REGEX="^v(0|[1-9][0-9]*)-(0|[1-9][0-9]*)-(0|[1-9][0-9]*)-([a-zA-Z0-9]+)-(0|[1-9][0-9]*)(-(0|[1-9][0-9]*)\\+[-0-9a-z]*)?"
  40. # Generate kubeconfig data for the created cluster.
  41. # Assumed vars:
  42. # KUBE_USER
  43. # KUBE_PASSWORD
  44. # KUBE_MASTER_IP
  45. # KUBECONFIG
  46. # CONTEXT
  47. #
  48. # If the apiserver supports bearer auth, also provide:
  49. # KUBE_BEARER_TOKEN
  50. #
  51. # If the kubeconfig context being created should NOT be set as the current context
  52. # SECONDARY_KUBECONFIG=true
  53. #
  54. # To explicitly name the context being created, use OVERRIDE_CONTEXT
  55. #
  56. # The following can be omitted for --insecure-skip-tls-verify
  57. # KUBE_CERT
  58. # KUBE_KEY
  59. # CA_CERT
  60. function create-kubeconfig() {
  61. KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
  62. local kubectl="${KUBE_ROOT}/cluster/kubectl.sh"
  63. SECONDARY_KUBECONFIG=${SECONDARY_KUBECONFIG:-}
  64. OVERRIDE_CONTEXT=${OVERRIDE_CONTEXT:-}
  65. if [[ "$OVERRIDE_CONTEXT" != "" ]];then
  66. CONTEXT=$OVERRIDE_CONTEXT
  67. fi
  68. # KUBECONFIG determines the file we write to, but it may not exist yet
  69. OLD_IFS=$IFS
  70. IFS=':'
  71. for cfg in ${KUBECONFIG} ; do
  72. if [[ ! -e "${cfg}" ]]; then
  73. mkdir -p "$(dirname "${cfg}")"
  74. touch "${cfg}"
  75. fi
  76. done
  77. IFS=$OLD_IFS
  78. local cluster_args=(
  79. "--server=${KUBE_SERVER:-https://${KUBE_MASTER_IP}}"
  80. )
  81. if [[ -z "${CA_CERT:-}" ]]; then
  82. cluster_args+=("--insecure-skip-tls-verify=true")
  83. else
  84. cluster_args+=(
  85. "--certificate-authority=${CA_CERT}"
  86. "--embed-certs=true"
  87. )
  88. fi
  89. local user_args=()
  90. if [[ -n "${KUBE_BEARER_TOKEN:-}" ]]; then
  91. user_args+=(
  92. "--token=${KUBE_BEARER_TOKEN}"
  93. )
  94. elif [[ -n "${KUBE_USER:-}" && -n "${KUBE_PASSWORD:-}" ]]; then
  95. user_args+=(
  96. "--username=${KUBE_USER}"
  97. "--password=${KUBE_PASSWORD}"
  98. )
  99. fi
  100. if [[ -n "${KUBE_CERT:-}" && -n "${KUBE_KEY:-}" ]]; then
  101. user_args+=(
  102. "--client-certificate=${KUBE_CERT}"
  103. "--client-key=${KUBE_KEY}"
  104. "--embed-certs=true"
  105. )
  106. fi
  107. KUBECONFIG="${KUBECONFIG}" "${kubectl}" config set-cluster "${CONTEXT}" "${cluster_args[@]}"
  108. if [[ -n "${user_args[*]:-}" ]]; then
  109. KUBECONFIG="${KUBECONFIG}" "${kubectl}" config set-credentials "${CONTEXT}" "${user_args[@]}"
  110. fi
  111. KUBECONFIG="${KUBECONFIG}" "${kubectl}" config set-context "${CONTEXT}" --cluster="${CONTEXT}" --user="${CONTEXT}"
  112. if [[ "${SECONDARY_KUBECONFIG}" != "true" ]];then
  113. KUBECONFIG="${KUBECONFIG}" "${kubectl}" config use-context "${CONTEXT}" --cluster="${CONTEXT}"
  114. fi
  115. # If we have a bearer token, also create a credential entry with basic auth
  116. # so that it is easy to discover the basic auth password for your cluster
  117. # to use in a web browser.
  118. if [[ -n "${KUBE_BEARER_TOKEN:-}" && -n "${KUBE_USER:-}" && -n "${KUBE_PASSWORD:-}" ]]; then
  119. KUBECONFIG="${KUBECONFIG}" "${kubectl}" config set-credentials "${CONTEXT}-basic-auth" "--username=${KUBE_USER}" "--password=${KUBE_PASSWORD}"
  120. fi
  121. echo "Wrote config for ${CONTEXT} to ${KUBECONFIG}"
  122. }
  123. # Clear kubeconfig data for a context
  124. # Assumed vars:
  125. # KUBECONFIG
  126. # CONTEXT
  127. #
  128. # To explicitly name the context being removed, use OVERRIDE_CONTEXT
  129. function clear-kubeconfig() {
  130. export KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
  131. OVERRIDE_CONTEXT=${OVERRIDE_CONTEXT:-}
  132. if [[ "$OVERRIDE_CONTEXT" != "" ]];then
  133. CONTEXT=$OVERRIDE_CONTEXT
  134. fi
  135. local kubectl="${KUBE_ROOT}/cluster/kubectl.sh"
  136. # Unset the current-context before we delete it, as otherwise kubectl errors.
  137. local cc
  138. cc=$("${kubectl}" config view -o jsonpath='{.current-context}')
  139. if [[ "${cc}" == "${CONTEXT}" ]]; then
  140. "${kubectl}" config unset current-context
  141. fi
  142. "${kubectl}" config unset "clusters.${CONTEXT}"
  143. "${kubectl}" config unset "users.${CONTEXT}"
  144. "${kubectl}" config unset "users.${CONTEXT}-basic-auth"
  145. "${kubectl}" config unset "contexts.${CONTEXT}"
  146. echo "Cleared config for ${CONTEXT} from ${KUBECONFIG}"
  147. }
  148. # Gets username, password for the current-context in kubeconfig, if they exist.
  149. # Assumed vars:
  150. # KUBECONFIG # if unset, defaults to global
  151. # KUBE_CONTEXT # if unset, defaults to current-context
  152. #
  153. # Vars set:
  154. # KUBE_USER
  155. # KUBE_PASSWORD
  156. #
  157. # KUBE_USER,KUBE_PASSWORD will be empty if no current-context is set, or
  158. # the current-context user does not exist or contain basicauth entries.
  159. function get-kubeconfig-basicauth() {
  160. export KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
  161. local cc
  162. cc=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.current-context}")
  163. if [[ -n "${KUBE_CONTEXT:-}" ]]; then
  164. cc="${KUBE_CONTEXT}"
  165. fi
  166. local user
  167. user=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.contexts[?(@.name == \"${cc}\")].context.user}")
  168. get-kubeconfig-user-basicauth "${user}"
  169. if [[ -z "${KUBE_USER:-}" || -z "${KUBE_PASSWORD:-}" ]]; then
  170. # kube-up stores username/password in a an additional kubeconfig section
  171. # suffixed with "-basic-auth". Cloudproviders like GKE store in directly
  172. # in the top level section along with the other credential information.
  173. # TODO: Handle this uniformly, either get rid of "basic-auth" or
  174. # consolidate its usage into a function across scripts in cluster/
  175. get-kubeconfig-user-basicauth "${user}-basic-auth"
  176. fi
  177. }
  178. # Sets KUBE_USER and KUBE_PASSWORD to the username and password specified in
  179. # the kubeconfig section corresponding to $1.
  180. #
  181. # Args:
  182. # $1 kubeconfig section to look for basic auth (eg: user or user-basic-auth).
  183. # Assumed vars:
  184. # KUBE_ROOT
  185. # Vars set:
  186. # KUBE_USER
  187. # KUBE_PASSWORD
  188. function get-kubeconfig-user-basicauth() {
  189. KUBE_USER=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.users[?(@.name == \"$1\")].user.username}")
  190. KUBE_PASSWORD=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.users[?(@.name == \"$1\")].user.password}")
  191. }
  192. # Generate basic auth user and password.
  193. # Vars set:
  194. # KUBE_USER
  195. # KUBE_PASSWORD
  196. function gen-kube-basicauth() {
  197. KUBE_USER='admin'
  198. KUBE_PASSWORD=$(python -c 'import string,random; print("".join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16)))')
  199. }
  200. # Get the bearer token for the current-context in kubeconfig if one exists.
  201. # Assumed vars:
  202. # KUBECONFIG # if unset, defaults to global
  203. # KUBE_CONTEXT # if unset, defaults to current-context
  204. #
  205. # Vars set:
  206. # KUBE_BEARER_TOKEN
  207. #
  208. # KUBE_BEARER_TOKEN will be empty if no current-context is set, or the
  209. # current-context user does not exist or contain a bearer token entry.
  210. function get-kubeconfig-bearertoken() {
  211. export KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
  212. local cc
  213. cc=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.current-context}")
  214. if [[ -n "${KUBE_CONTEXT:-}" ]]; then
  215. cc="${KUBE_CONTEXT}"
  216. fi
  217. local user
  218. user=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.contexts[?(@.name == \"${cc}\")].context.user}")
  219. KUBE_BEARER_TOKEN=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.users[?(@.name == \"${user}\")].user.token}")
  220. }
  221. # Generate bearer token.
  222. #
  223. # Vars set:
  224. # KUBE_BEARER_TOKEN
  225. function gen-kube-bearertoken() {
  226. KUBE_BEARER_TOKEN=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)
  227. }
  228. function load-or-gen-kube-basicauth() {
  229. if [[ -n "${KUBE_CONTEXT:-}" ]]; then
  230. get-kubeconfig-basicauth
  231. fi
  232. if [[ -z "${KUBE_USER:-}" || -z "${KUBE_PASSWORD:-}" ]]; then
  233. gen-kube-basicauth
  234. fi
  235. # Make sure they don't contain any funny characters.
  236. if ! [[ "${KUBE_USER}" =~ ^[-._@a-zA-Z0-9]+$ ]]; then
  237. echo "Bad KUBE_USER string."
  238. exit 1
  239. fi
  240. if ! [[ "${KUBE_PASSWORD}" =~ ^[-._@#%/a-zA-Z0-9]+$ ]]; then
  241. echo "Bad KUBE_PASSWORD string."
  242. exit 1
  243. fi
  244. }
  245. # Sets KUBE_VERSION variable to the proper version number (e.g. "v1.0.6",
  246. # "v1.2.0-alpha.1.881+376438b69c7612") or a version' publication of the form
  247. # <path>/<version> (e.g. "release/stable",' "ci/latest-1").
  248. #
  249. # See the docs on getting builds for more information about version
  250. # publication.
  251. #
  252. # Args:
  253. # $1 version string from command line
  254. # Vars set and exported for external reference:
  255. # KUBE_VERSION
  256. function set_binary_version() {
  257. if [[ "${1}" =~ "/" ]]; then
  258. IFS='/' read -r -a path <<< "${1}"
  259. if [[ "${path[0]}" == "release" ]]; then
  260. KUBE_VERSION=$(gsutil cat "gs://kubernetes-release/${1}.txt")
  261. else
  262. KUBE_VERSION=$(gsutil cat "gs://kubernetes-release-dev/${1}.txt")
  263. fi
  264. else
  265. KUBE_VERSION=${1}
  266. fi
  267. export KUBE_VERSION
  268. }
  269. # Search for the specified tarball in the various known output locations,
  270. # echoing the location if found.
  271. #
  272. # Assumed vars:
  273. # KUBE_ROOT
  274. #
  275. # Args:
  276. # $1 name of tarball to search for
  277. function find-tar() {
  278. local -r tarball=$1
  279. locations=(
  280. "${KUBE_ROOT}/node/${tarball}"
  281. "${KUBE_ROOT}/server/${tarball}"
  282. "${KUBE_ROOT}/_output/release-tars/${tarball}"
  283. "${KUBE_ROOT}/bazel-bin/build/release-tars/${tarball}"
  284. )
  285. location=$( (ls -t "${locations[@]}" 2>/dev/null || true) | head -1 )
  286. if [[ ! -f "${location}" ]]; then
  287. echo "!!! Cannot find ${tarball}" >&2
  288. exit 1
  289. fi
  290. echo "${location}"
  291. }
  292. # Verify and find the various tar files that we are going to use on the server.
  293. #
  294. # Assumed vars:
  295. # KUBE_ROOT
  296. # Vars set and exported:
  297. # NODE_BINARY_TAR
  298. # SERVER_BINARY_TAR
  299. # KUBE_MANIFESTS_TAR
  300. function find-release-tars() {
  301. SERVER_BINARY_TAR=$(find-tar kubernetes-server-linux-amd64.tar.gz)
  302. if [[ -z "${SERVER_BINARY_TAR}" ]]; then
  303. exit 1
  304. fi
  305. export SERVER_BINARY_TAR
  306. local find_result
  307. if [[ "${NUM_WINDOWS_NODES}" -gt "0" ]]; then
  308. if NODE_BINARY_TAR=$(find-tar kubernetes-node-windows-amd64.tar.gz); then
  309. find_result=0
  310. else
  311. find_result=1
  312. fi
  313. export NODE_BINARY_TAR
  314. fi
  315. # This tarball is used by GCI, Ubuntu Trusty, and Container Linux.
  316. KUBE_MANIFESTS_TAR=
  317. if [[ "${MASTER_OS_DISTRIBUTION:-}" == "trusty" || "${MASTER_OS_DISTRIBUTION:-}" == "gci" || "${MASTER_OS_DISTRIBUTION:-}" == "ubuntu" ]] || \
  318. [[ "${NODE_OS_DISTRIBUTION:-}" == "trusty" || "${NODE_OS_DISTRIBUTION:-}" == "gci" || "${NODE_OS_DISTRIBUTION:-}" == "ubuntu" || "${NODE_OS_DISTRIBUTION:-}" == "custom" ]] ; then
  319. if KUBE_MANIFESTS_TAR=$(find-tar kubernetes-manifests.tar.gz); then
  320. find_result=0
  321. else
  322. find_result=1
  323. fi
  324. export KUBE_MANIFESTS_TAR
  325. fi
  326. # the function result is used in function `verify-release-tars`
  327. if [[ $find_result == 0 ]]; then
  328. return 0
  329. else
  330. return 1
  331. fi
  332. }
  333. # Run the cfssl command to generates certificate files for etcd service, the
  334. # certificate files will save in $1 directory.
  335. #
  336. # Optional vars:
  337. # GEN_ETCD_CA_CERT (CA cert encode with base64 and ZIP compression)
  338. # GEN_ETCD_CA_KEY (CA key encode with base64)
  339. # ca_cert (require when GEN_ETCD_CA_CERT and GEN_ETCD_CA_KEY is set)
  340. # ca_key (require when GEN_ETCD_CA_CERT and GEN_ETCD_CA_KEY is set)
  341. # If GEN_ETCD_CA_CERT or GEN_ETCD_CA_KEY is not specified, it will generates certs for CA.
  342. #
  343. # Args:
  344. # $1 (the directory that certificate files to save)
  345. # $2 (the ip of etcd member)
  346. # $3 (the type of etcd certificates, must be one of client, server, peer)
  347. # $4 (the prefix of the certificate filename, default is $3)
  348. function generate-etcd-cert() {
  349. local cert_dir=${1}
  350. local member_ip=${2}
  351. local type_cert=${3}
  352. local prefix=${4:-"${type_cert}"}
  353. local GEN_ETCD_CA_CERT=${GEN_ETCD_CA_CERT:-}
  354. local GEN_ETCD_CA_KEY=${GEN_ETCD_CA_KEY:-}
  355. mkdir -p "${cert_dir}"
  356. pushd "${cert_dir}"
  357. kube::util::ensure-cfssl .
  358. if [ ! -r "ca-config.json" ]; then
  359. cat >ca-config.json <<EOF
  360. {
  361. "signing": {
  362. "default": {
  363. "expiry": "43800h"
  364. },
  365. "profiles": {
  366. "server": {
  367. "expiry": "43800h",
  368. "usages": [
  369. "signing",
  370. "key encipherment",
  371. "server auth",
  372. "client auth"
  373. ]
  374. },
  375. "client": {
  376. "expiry": "43800h",
  377. "usages": [
  378. "signing",
  379. "key encipherment",
  380. "client auth"
  381. ]
  382. },
  383. "peer": {
  384. "expiry": "43800h",
  385. "usages": [
  386. "signing",
  387. "key encipherment",
  388. "server auth",
  389. "client auth"
  390. ]
  391. }
  392. }
  393. }
  394. }
  395. EOF
  396. fi
  397. if [ ! -r "ca-csr.json" ]; then
  398. cat >ca-csr.json <<EOF
  399. {
  400. "CN": "Kubernetes",
  401. "key": {
  402. "algo": "ecdsa",
  403. "size": 256
  404. },
  405. "names": [
  406. {
  407. "C": "US",
  408. "L": "CA",
  409. "O": "kubernetes.io"
  410. }
  411. ]
  412. }
  413. EOF
  414. fi
  415. if [[ -n "${GEN_ETCD_CA_CERT}" && -n "${GEN_ETCD_CA_KEY}" ]]; then
  416. # ca_cert and ca_key are optional external vars supplied in cluster/gce/util.sh,
  417. # so it's ok to disable shellcheck here
  418. # shellcheck disable=SC2154
  419. echo "${ca_cert}" | base64 --decode | gunzip > ca.pem
  420. # shellcheck disable=SC2154
  421. echo "${ca_key}" | base64 --decode > ca-key.pem
  422. fi
  423. if [[ ! -r "ca.pem" || ! -r "ca-key.pem" ]]; then
  424. ${CFSSL_BIN} gencert -initca ca-csr.json | ${CFSSLJSON_BIN} -bare ca -
  425. fi
  426. case "${type_cert}" in
  427. client)
  428. echo "Generate client certificates..."
  429. echo '{"CN":"client","hosts":["*"],"key":{"algo":"ecdsa","size":256}}' \
  430. | ${CFSSL_BIN} gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client - \
  431. | ${CFSSLJSON_BIN} -bare "${prefix}"
  432. ;;
  433. server)
  434. echo "Generate server certificates..."
  435. echo '{"CN":"'"${member_ip}"'","hosts":[""],"key":{"algo":"ecdsa","size":256}}' \
  436. | ${CFSSL_BIN} gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server -hostname="${member_ip},127.0.0.1" - \
  437. | ${CFSSLJSON_BIN} -bare "${prefix}"
  438. ;;
  439. peer)
  440. echo "Generate peer certificates..."
  441. echo '{"CN":"'"${member_ip}"'","hosts":[""],"key":{"algo":"ecdsa","size":256}}' \
  442. | ${CFSSL_BIN} gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer -hostname="${member_ip},127.0.0.1" - \
  443. | ${CFSSLJSON_BIN} -bare "${prefix}"
  444. ;;
  445. *)
  446. echo "Unknow, unsupported etcd certs type: ${type_cert}" >&2
  447. echo "Supported type: client, server, peer" >&2
  448. exit 2
  449. esac
  450. # the popd will access `directory stack`, no `real` parameters is actually needed
  451. # shellcheck disable=SC2119
  452. popd
  453. }
  454. # Check whether required binaries exist, prompting to download
  455. # if missing.
  456. # If KUBERNETES_SKIP_CONFIRM is set to y, we'll automatically download binaries
  457. # without prompting.
  458. function verify-kube-binaries() {
  459. if ! "${KUBE_ROOT}/cluster/kubectl.sh" version --client >&/dev/null; then
  460. echo "!!! kubectl appears to be broken or missing"
  461. download-release-binaries
  462. fi
  463. }
  464. # Check whether required release artifacts exist, prompting to download
  465. # if missing.
  466. # If KUBERNETES_SKIP_CONFIRM is set to y, we'll automatically download binaries
  467. # without prompting.
  468. function verify-release-tars() {
  469. if ! find-release-tars; then
  470. download-release-binaries
  471. fi
  472. }
  473. # Download release artifacts.
  474. function download-release-binaries() {
  475. get_binaries_script="${KUBE_ROOT}/cluster/get-kube-binaries.sh"
  476. local resp="y"
  477. if [[ ! "${KUBERNETES_SKIP_CONFIRM:-n}" =~ ^[yY]$ ]]; then
  478. echo "Required release artifacts appear to be missing. Do you wish to download them? [Y/n]"
  479. read -r resp
  480. fi
  481. if [[ "${resp}" =~ ^[nN]$ ]]; then
  482. echo "You must download release artifacts to continue. You can use "
  483. echo " ${get_binaries_script}"
  484. echo "to do this for your automatically."
  485. exit 1
  486. fi
  487. "${get_binaries_script}"
  488. }
  489. # Run pushd without stack output
  490. function pushd() {
  491. command pushd "$@" > /dev/null
  492. }
  493. # Run popd without stack output
  494. # the popd will access `directory stack`, no `real` parameters is actually needed
  495. # shellcheck disable=SC2120
  496. function popd() {
  497. command popd "$@" > /dev/null
  498. }