123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906 |
- #!/bin/bash
- # Copyright 2015 The Kubernetes Authors.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- # Common utilites for kube-up/kube-down
- set -o errexit
- set -o nounset
- set -o pipefail
- KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
- DEFAULT_KUBECONFIG="${HOME}/.kube/config"
- source "${KUBE_ROOT}/cluster/lib/util.sh"
- source "${KUBE_ROOT}/cluster/lib/logging.sh"
- # KUBE_RELEASE_VERSION_REGEX matches things like "v1.2.3" or "v1.2.3-alpha.4"
- #
- # NOTE This must match the version_regex in build/common.sh
- # kube::release::parse_and_validate_release_version()
- KUBE_RELEASE_VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-(beta|alpha)\\.(0|[1-9][0-9]*))?$"
- KUBE_RELEASE_VERSION_DASHED_REGEX="v(0|[1-9][0-9]*)-(0|[1-9][0-9]*)-(0|[1-9][0-9]*)(-(beta|alpha)-(0|[1-9][0-9]*))?"
- # KUBE_CI_VERSION_REGEX matches things like "v1.2.3-alpha.4.56+abcdefg" This
- #
- # NOTE This must match the version_regex in build/common.sh
- # kube::release::parse_and_validate_ci_version()
- KUBE_CI_VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)-(beta|alpha)\\.(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*)\\+[-0-9a-z]*)?$"
- KUBE_CI_VERSION_DASHED_REGEX="^v(0|[1-9][0-9]*)-(0|[1-9][0-9]*)-(0|[1-9][0-9]*)-(beta|alpha)-(0|[1-9][0-9]*)(-(0|[1-9][0-9]*)\\+[-0-9a-z]*)?"
- # Generate kubeconfig data for the created cluster.
- # Assumed vars:
- # KUBE_USER
- # KUBE_PASSWORD
- # KUBE_MASTER_IP
- # KUBECONFIG
- # CONTEXT
- #
- # If the apiserver supports bearer auth, also provide:
- # KUBE_BEARER_TOKEN
- #
- # If the kubeconfig context being created should NOT be set as the current context
- # SECONDARY_KUBECONFIG=true
- #
- # To explicitly name the context being created, use OVERRIDE_CONTEXT
- #
- # The following can be omitted for --insecure-skip-tls-verify
- # KUBE_CERT
- # KUBE_KEY
- # CA_CERT
- function create-kubeconfig() {
- KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
- local kubectl="${KUBE_ROOT}/cluster/kubectl.sh"
- SECONDARY_KUBECONFIG=${SECONDARY_KUBECONFIG:-}
- OVERRIDE_CONTEXT=${OVERRIDE_CONTEXT:-}
- if [[ "$OVERRIDE_CONTEXT" != "" ]];then
- CONTEXT=$OVERRIDE_CONTEXT
- fi
- # KUBECONFIG determines the file we write to, but it may not exist yet
- if [[ ! -e "${KUBECONFIG}" ]]; then
- mkdir -p $(dirname "${KUBECONFIG}")
- touch "${KUBECONFIG}"
- fi
- local cluster_args=(
- "--server=${KUBE_SERVER:-https://${KUBE_MASTER_IP}}"
- )
- if [[ -z "${CA_CERT:-}" ]]; then
- cluster_args+=("--insecure-skip-tls-verify=true")
- else
- cluster_args+=(
- "--certificate-authority=${CA_CERT}"
- "--embed-certs=true"
- )
- fi
- local user_args=()
- if [[ ! -z "${KUBE_BEARER_TOKEN:-}" ]]; then
- user_args+=(
- "--token=${KUBE_BEARER_TOKEN}"
- )
- elif [[ ! -z "${KUBE_USER:-}" && ! -z "${KUBE_PASSWORD:-}" ]]; then
- user_args+=(
- "--username=${KUBE_USER}"
- "--password=${KUBE_PASSWORD}"
- )
- fi
- if [[ ! -z "${KUBE_CERT:-}" && ! -z "${KUBE_KEY:-}" ]]; then
- user_args+=(
- "--client-certificate=${KUBE_CERT}"
- "--client-key=${KUBE_KEY}"
- "--embed-certs=true"
- )
- fi
- KUBECONFIG="${KUBECONFIG}" "${kubectl}" config set-cluster "${CONTEXT}" "${cluster_args[@]}"
- if [[ -n "${user_args[@]:-}" ]]; then
- KUBECONFIG="${KUBECONFIG}" "${kubectl}" config set-credentials "${CONTEXT}" "${user_args[@]}"
- fi
- KUBECONFIG="${KUBECONFIG}" "${kubectl}" config set-context "${CONTEXT}" --cluster="${CONTEXT}" --user="${CONTEXT}"
- if [[ "${SECONDARY_KUBECONFIG}" != "true" ]];then
- KUBECONFIG="${KUBECONFIG}" "${kubectl}" config use-context "${CONTEXT}" --cluster="${CONTEXT}"
- fi
- # If we have a bearer token, also create a credential entry with basic auth
- # so that it is easy to discover the basic auth password for your cluster
- # to use in a web browser.
- if [[ ! -z "${KUBE_BEARER_TOKEN:-}" && ! -z "${KUBE_USER:-}" && ! -z "${KUBE_PASSWORD:-}" ]]; then
- KUBECONFIG="${KUBECONFIG}" "${kubectl}" config set-credentials "${CONTEXT}-basic-auth" "--username=${KUBE_USER}" "--password=${KUBE_PASSWORD}"
- fi
- echo "Wrote config for ${CONTEXT} to ${KUBECONFIG}"
- }
- # Clear kubeconfig data for a context
- # Assumed vars:
- # KUBECONFIG
- # CONTEXT
- #
- # To explicitly name the context being removed, use OVERRIDE_CONTEXT
- function clear-kubeconfig() {
- export KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
- OVERRIDE_CONTEXT=${OVERRIDE_CONTEXT:-}
- if [[ "$OVERRIDE_CONTEXT" != "" ]];then
- CONTEXT=$OVERRIDE_CONTEXT
- fi
- local kubectl="${KUBE_ROOT}/cluster/kubectl.sh"
- "${kubectl}" config unset "clusters.${CONTEXT}"
- "${kubectl}" config unset "users.${CONTEXT}"
- "${kubectl}" config unset "users.${CONTEXT}-basic-auth"
- "${kubectl}" config unset "contexts.${CONTEXT}"
- local cc=$("${kubectl}" config view -o jsonpath='{.current-context}')
- if [[ "${cc}" == "${CONTEXT}" ]]; then
- "${kubectl}" config unset current-context
- fi
- echo "Cleared config for ${CONTEXT} from ${KUBECONFIG}"
- }
- # Creates a kubeconfig file with the credentials for only the current-context
- # cluster. This is used by federation to create secrets in test setup.
- function create-kubeconfig-for-federation() {
- if [[ "${FEDERATION:-}" == "true" ]]; then
- echo "creating kubeconfig for federation secret"
- local kubectl="${KUBE_ROOT}/cluster/kubectl.sh"
- local cc=$("${kubectl}" config view -o jsonpath='{.current-context}')
- KUBECONFIG_DIR=$(dirname ${KUBECONFIG:-$DEFAULT_KUBECONFIG})
- KUBECONFIG_PATH="${KUBECONFIG_DIR}/federation/kubernetes-apiserver/${cc}"
- mkdir -p "${KUBECONFIG_PATH}"
- "${kubectl}" config view --minify --flatten > "${KUBECONFIG_PATH}/kubeconfig"
- fi
- }
- function tear_down_alive_resources() {
- local kubectl="${KUBE_ROOT}/cluster/kubectl.sh"
- "${kubectl}" delete rc --all || true
- "${kubectl}" delete pods --all || true
- "${kubectl}" delete svc --all || true
- "${kubectl}" delete pvc --all || true
- }
- # Gets username, password for the current-context in kubeconfig, if they exist.
- # Assumed vars:
- # KUBECONFIG # if unset, defaults to global
- # KUBE_CONTEXT # if unset, defaults to current-context
- #
- # Vars set:
- # KUBE_USER
- # KUBE_PASSWORD
- #
- # KUBE_USER,KUBE_PASSWORD will be empty if no current-context is set, or
- # the current-context user does not exist or contain basicauth entries.
- function get-kubeconfig-basicauth() {
- export KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
- local cc=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.current-context}")
- if [[ ! -z "${KUBE_CONTEXT:-}" ]]; then
- cc="${KUBE_CONTEXT}"
- fi
- local user=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.contexts[?(@.name == \"${cc}\")].context.user}")
- KUBE_USER=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.users[?(@.name == \"${user}\")].user.username}")
- KUBE_PASSWORD=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.users[?(@.name == \"${user}\")].user.password}")
- }
- # Generate basic auth user and password.
- # Vars set:
- # KUBE_USER
- # KUBE_PASSWORD
- function gen-kube-basicauth() {
- KUBE_USER=admin
- KUBE_PASSWORD=$(python -c 'import string,random; print("".join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16)))')
- }
- # Get the bearer token for the current-context in kubeconfig if one exists.
- # Assumed vars:
- # KUBECONFIG # if unset, defaults to global
- # KUBE_CONTEXT # if unset, defaults to current-context
- #
- # Vars set:
- # KUBE_BEARER_TOKEN
- #
- # KUBE_BEARER_TOKEN will be empty if no current-context is set, or the
- # current-context user does not exist or contain a bearer token entry.
- function get-kubeconfig-bearertoken() {
- export KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
- local cc=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.current-context}")
- if [[ ! -z "${KUBE_CONTEXT:-}" ]]; then
- cc="${KUBE_CONTEXT}"
- fi
- local user=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.contexts[?(@.name == \"${cc}\")].context.user}")
- KUBE_BEARER_TOKEN=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.users[?(@.name == \"${user}\")].user.token}")
- }
- # Generate bearer token.
- #
- # Vars set:
- # KUBE_BEARER_TOKEN
- function gen-kube-bearertoken() {
- 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)
- }
- # Generate uid
- # This function only works on systems with python. It generates a time based
- # UID instead of a UUID because GCE has a name length limit.
- #
- # Vars set:
- # KUBE_UID
- function gen-uid {
- KUBE_UID=$(python -c 'import uuid; print(uuid.uuid1().fields[0])')
- }
- function load-or-gen-kube-basicauth() {
- if [[ ! -z "${KUBE_CONTEXT:-}" ]]; then
- get-kubeconfig-basicauth
- fi
- if [[ -z "${KUBE_USER:-}" || -z "${KUBE_PASSWORD:-}" ]]; then
- gen-kube-basicauth
- fi
- # Make sure they don't contain any funny characters.
- if ! [[ "${KUBE_USER}" =~ ^[-._@a-zA-Z0-9]+$ ]]; then
- echo "Bad KUBE_USER string."
- exit 1
- fi
- if ! [[ "${KUBE_PASSWORD}" =~ ^[-._@#%/a-zA-Z0-9]+$ ]]; then
- echo "Bad KUBE_PASSWORD string."
- exit 1
- fi
- }
- function load-or-gen-kube-bearertoken() {
- if [[ ! -z "${KUBE_CONTEXT:-}" ]]; then
- get-kubeconfig-bearertoken
- fi
- if [[ -z "${KUBE_BEARER_TOKEN:-}" ]]; then
- gen-kube-bearertoken
- fi
- }
- # Get the master IP for the current-context in kubeconfig if one exists.
- #
- # Assumed vars:
- # KUBECONFIG # if unset, defaults to global
- # KUBE_CONTEXT # if unset, defaults to current-context
- #
- # Vars set:
- # KUBE_MASTER_URL
- #
- # KUBE_MASTER_URL will be empty if no current-context is set, or the
- # current-context user does not exist or contain a server entry.
- function detect-master-from-kubeconfig() {
- export KUBECONFIG=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
- local cc=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.current-context}")
- if [[ ! -z "${KUBE_CONTEXT:-}" ]]; then
- cc="${KUBE_CONTEXT}"
- fi
- local cluster=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.contexts[?(@.name == \"${cc}\")].context.cluster}")
- KUBE_MASTER_URL=$("${KUBE_ROOT}/cluster/kubectl.sh" config view -o jsonpath="{.clusters[?(@.name == \"${cluster}\")].cluster.server}")
- }
- # Sets KUBE_VERSION variable to the proper version number (e.g. "v1.0.6",
- # "v1.2.0-alpha.1.881+376438b69c7612") or a version' publication of the form
- # <path>/<version> (e.g. "release/stable",' "ci/latest-1").
- #
- # See the docs on getting builds for more information about version
- # publication.
- #
- # Args:
- # $1 version string from command line
- # Vars set:
- # KUBE_VERSION
- function set_binary_version() {
- if [[ "${1}" =~ "/" ]]; then
- IFS='/' read -a path <<< "${1}"
- if [[ "${path[0]}" == "release" ]]; then
- KUBE_VERSION=$(gsutil cat "gs://kubernetes-release/${1}.txt")
- else
- KUBE_VERSION=$(gsutil cat "gs://kubernetes-release-dev/${1}.txt")
- fi
- else
- KUBE_VERSION=${1}
- fi
- }
- # Figure out which binary use on the server and assure it is available.
- # If KUBE_VERSION is specified use binaries specified by it, otherwise
- # use local dev binaries.
- #
- # Assumed vars:
- # KUBE_VERSION
- # KUBE_RELEASE_VERSION_REGEX
- # KUBE_CI_VERSION_REGEX
- # Vars set:
- # KUBE_TAR_HASH
- # SERVER_BINARY_TAR_URL
- # SERVER_BINARY_TAR_HASH
- # SALT_TAR_URL
- # SALT_TAR_HASH
- function tars_from_version() {
- if [[ -z "${KUBE_VERSION-}" ]]; then
- find-release-tars
- upload-server-tars
- elif [[ ${KUBE_VERSION} =~ ${KUBE_RELEASE_VERSION_REGEX} ]]; then
- SERVER_BINARY_TAR_URL="https://storage.googleapis.com/kubernetes-release/release/${KUBE_VERSION}/kubernetes-server-linux-amd64.tar.gz"
- SALT_TAR_URL="https://storage.googleapis.com/kubernetes-release/release/${KUBE_VERSION}/kubernetes-salt.tar.gz"
- # TODO: Clean this up.
- KUBE_MANIFESTS_TAR_URL="${SERVER_BINARY_TAR_URL/server-linux-amd64/manifests}"
- KUBE_MANIFESTS_TAR_HASH=$(curl ${KUBE_MANIFESTS_TAR_URL} | sha1sum | awk '{print $1}')
- elif [[ ${KUBE_VERSION} =~ ${KUBE_CI_VERSION_REGEX} ]]; then
- SERVER_BINARY_TAR_URL="https://storage.googleapis.com/kubernetes-release-dev/ci/${KUBE_VERSION}/kubernetes-server-linux-amd64.tar.gz"
- SALT_TAR_URL="https://storage.googleapis.com/kubernetes-release-dev/ci/${KUBE_VERSION}/kubernetes-salt.tar.gz"
- # TODO: Clean this up.
- KUBE_MANIFESTS_TAR_URL="${SERVER_BINARY_TAR_URL/server-linux-amd64/manifests}"
- KUBE_MANIFESTS_TAR_HASH=$(curl ${KUBE_MANIFESTS_TAR_URL} | sha1sum | awk '{print $1}')
- else
- echo "Version doesn't match regexp" >&2
- exit 1
- fi
- if ! SERVER_BINARY_TAR_HASH=$(curl -Ss --fail "${SERVER_BINARY_TAR_URL}.sha1"); then
- echo "Failure trying to curl release .sha1"
- fi
- if ! SALT_TAR_HASH=$(curl -Ss --fail "${SALT_TAR_URL}.sha1"); then
- echo "Failure trying to curl Salt tar .sha1"
- fi
- if ! curl -Ss --head "${SERVER_BINARY_TAR_URL}" >&/dev/null; then
- echo "Can't find release at ${SERVER_BINARY_TAR_URL}" >&2
- exit 1
- fi
- if ! curl -Ss --head "${SALT_TAR_URL}" >&/dev/null; then
- echo "Can't find Salt tar at ${SALT_TAR_URL}" >&2
- exit 1
- fi
- }
- # Verify and find the various tar files that we are going to use on the server.
- #
- # Assumed vars:
- # KUBE_ROOT
- # Vars set:
- # SERVER_BINARY_TAR
- # SALT_TAR
- # KUBE_MANIFESTS_TAR
- function find-release-tars() {
- SERVER_BINARY_TAR="${KUBE_ROOT}/server/kubernetes-server-linux-amd64.tar.gz"
- if [[ ! -f "${SERVER_BINARY_TAR}" ]]; then
- SERVER_BINARY_TAR="${KUBE_ROOT}/_output/release-tars/kubernetes-server-linux-amd64.tar.gz"
- fi
- if [[ ! -f "${SERVER_BINARY_TAR}" ]]; then
- echo "!!! Cannot find kubernetes-server-linux-amd64.tar.gz" >&2
- exit 1
- fi
- SALT_TAR="${KUBE_ROOT}/server/kubernetes-salt.tar.gz"
- if [[ ! -f "${SALT_TAR}" ]]; then
- SALT_TAR="${KUBE_ROOT}/_output/release-tars/kubernetes-salt.tar.gz"
- fi
- if [[ ! -f "${SALT_TAR}" ]]; then
- echo "!!! Cannot find kubernetes-salt.tar.gz" >&2
- exit 1
- fi
- # This tarball is used by GCI, Ubuntu Trusty, and CoreOS.
- KUBE_MANIFESTS_TAR=
- if [[ "${MASTER_OS_DISTRIBUTION:-}" == "trusty" || "${MASTER_OS_DISTRIBUTION:-}" == "gci" || "${MASTER_OS_DISTRIBUTION:-}" == "coreos" ]] || \
- [[ "${NODE_OS_DISTRIBUTION:-}" == "trusty" || "${NODE_OS_DISTRIBUTION:-}" == "gci" || "${NODE_OS_DISTRIBUTION:-}" == "coreos" ]] ; then
- KUBE_MANIFESTS_TAR="${KUBE_ROOT}/server/kubernetes-manifests.tar.gz"
- if [[ ! -f "${KUBE_MANIFESTS_TAR}" ]]; then
- KUBE_MANIFESTS_TAR="${KUBE_ROOT}/_output/release-tars/kubernetes-manifests.tar.gz"
- fi
- if [[ ! -f "${KUBE_MANIFESTS_TAR}" ]]; then
- echo "!!! Cannot find kubernetes-manifests.tar.gz" >&2
- exit 1
- fi
- fi
- }
- # Discover the git version of the current build package
- #
- # Assumed vars:
- # KUBE_ROOT
- # Vars set:
- # KUBE_GIT_VERSION
- function find-release-version() {
- KUBE_GIT_VERSION=""
- if [[ -f "${KUBE_ROOT}/version" ]]; then
- KUBE_GIT_VERSION="$(cat ${KUBE_ROOT}/version)"
- fi
- if [[ -f "${KUBE_ROOT}/_output/release-stage/full/kubernetes/version" ]]; then
- KUBE_GIT_VERSION="$(cat ${KUBE_ROOT}/_output/release-stage/full/kubernetes/version)"
- fi
- if [[ -z "${KUBE_GIT_VERSION}" ]]; then
- echo "!!! Cannot find release version"
- exit 1
- fi
- }
- function stage-images() {
- find-release-version
- find-release-tars
- KUBE_IMAGE_TAG="$(echo """${KUBE_GIT_VERSION}""" | sed 's/+/-/g')"
- local docker_wrapped_binaries=(
- "kube-apiserver"
- "kube-controller-manager"
- "kube-scheduler"
- "kube-proxy"
- )
- local docker_cmd=("docker")
- if [[ "${KUBE_DOCKER_REGISTRY}" == "gcr.io/"* ]]; then
- local docker_push_cmd=("gcloud" "docker")
- else
- local docker_push_cmd=("${docker_cmd[@]}")
- fi
- local temp_dir="$(mktemp -d -t 'kube-server-XXXX')"
- tar xzfv "${SERVER_BINARY_TAR}" -C "${temp_dir}" &> /dev/null
- for binary in "${docker_wrapped_binaries[@]}"; do
- local docker_tag="$(cat ${temp_dir}/kubernetes/server/bin/${binary}.docker_tag)"
- (
- "${docker_cmd[@]}" load -i "${temp_dir}/kubernetes/server/bin/${binary}.tar"
- "${docker_cmd[@]}" tag -f "gcr.io/google_containers/${binary}:${docker_tag}" "${KUBE_DOCKER_REGISTRY}/${binary}:${KUBE_IMAGE_TAG}"
- "${docker_push_cmd[@]}" push "${KUBE_DOCKER_REGISTRY}/${binary}:${KUBE_IMAGE_TAG}"
- ) &> "${temp_dir}/${binary}-push.log" &
- done
- kube::util::wait-for-jobs || {
- kube::log::error "unable to push images. see ${temp_dir}/*.log for more info."
- return 1
- }
- rm -rf "${temp_dir}"
- return 0
- }
- # Quote something appropriate for a yaml string.
- #
- # TODO(zmerlynn): Note that this function doesn't so much "quote" as
- # "strip out quotes", and we really should be using a YAML library for
- # this, but PyYAML isn't shipped by default, and *rant rant rant ... SIGH*
- function yaml-quote {
- echo "'$(echo "${@:-}" | sed -e "s/'/''/g")'"
- }
- # Builds the RUNTIME_CONFIG var from other feature enable options (such as
- # features in alpha)
- function build-runtime-config() {
- # There is nothing to do here for now. Just using this function as a placeholder.
- :
- }
- # Writes the cluster name into a temporary file.
- # Assumed vars
- # CLUSTER_NAME
- function write-cluster-name {
- cat >"${KUBE_TEMP}/cluster-name.txt" << EOF
- ${CLUSTER_NAME}
- EOF
- }
- function write-master-env {
- # If the user requested that the master be part of the cluster, set the
- # environment variable to program the master kubelet to register itself.
- if [[ "${REGISTER_MASTER_KUBELET:-}" == "true" ]]; then
- KUBELET_APISERVER="${MASTER_NAME}"
- fi
- build-kube-env true "${KUBE_TEMP}/master-kube-env.yaml"
- }
- function write-node-env {
- build-kube-env false "${KUBE_TEMP}/node-kube-env.yaml"
- }
- # $1: if 'true', we're building a master yaml, else a node
- function build-kube-env {
- local master=$1
- local file=$2
- local server_binary_tar_url=$SERVER_BINARY_TAR_URL
- local salt_tar_url=$SALT_TAR_URL
- local kube_manifests_tar_url="${KUBE_MANIFESTS_TAR_URL:-}"
- if [[ "${master}" == "true" && "${MASTER_OS_DISTRIBUTION}" == "coreos" ]] || \
- [[ "${master}" == "false" && "${NODE_OS_DISTRIBUTION}" == "coreos" ]] ; then
- # TODO: Support fallback .tar.gz settings on CoreOS
- server_binary_tar_url=$(split_csv "${SERVER_BINARY_TAR_URL}")
- salt_tar_url=$(split_csv "${SALT_TAR_URL}")
- kube_manifests_tar_url=$(split_csv "${KUBE_MANIFESTS_TAR_URL}")
- fi
- build-runtime-config
- gen-uid
- rm -f ${file}
- cat >$file <<EOF
- ENV_TIMESTAMP: $(yaml-quote $(date -u +%Y-%m-%dT%T%z))
- INSTANCE_PREFIX: $(yaml-quote ${INSTANCE_PREFIX})
- NODE_INSTANCE_PREFIX: $(yaml-quote ${NODE_INSTANCE_PREFIX})
- NODE_TAGS: $(yaml-quote ${NODE_TAGS:-})
- CLUSTER_IP_RANGE: $(yaml-quote ${CLUSTER_IP_RANGE:-10.244.0.0/16})
- SERVER_BINARY_TAR_URL: $(yaml-quote ${server_binary_tar_url})
- SERVER_BINARY_TAR_HASH: $(yaml-quote ${SERVER_BINARY_TAR_HASH})
- SALT_TAR_URL: $(yaml-quote ${salt_tar_url})
- SALT_TAR_HASH: $(yaml-quote ${SALT_TAR_HASH})
- SERVICE_CLUSTER_IP_RANGE: $(yaml-quote ${SERVICE_CLUSTER_IP_RANGE})
- KUBERNETES_MASTER_NAME: $(yaml-quote ${MASTER_NAME})
- ALLOCATE_NODE_CIDRS: $(yaml-quote ${ALLOCATE_NODE_CIDRS:-false})
- ENABLE_CLUSTER_MONITORING: $(yaml-quote ${ENABLE_CLUSTER_MONITORING:-none})
- DOCKER_REGISTRY_MIRROR_URL: $(yaml-quote ${DOCKER_REGISTRY_MIRROR_URL:-})
- ENABLE_L7_LOADBALANCING: $(yaml-quote ${ENABLE_L7_LOADBALANCING:-none})
- ENABLE_CLUSTER_LOGGING: $(yaml-quote ${ENABLE_CLUSTER_LOGGING:-false})
- ENABLE_CLUSTER_UI: $(yaml-quote ${ENABLE_CLUSTER_UI:-false})
- ENABLE_NODE_PROBLEM_DETECTOR: $(yaml-quote ${ENABLE_NODE_PROBLEM_DETECTOR:-false})
- ENABLE_NODE_LOGGING: $(yaml-quote ${ENABLE_NODE_LOGGING:-false})
- ENABLE_RESCHEDULER: $(yaml-quote ${ENABLE_RESCHEDULER:-false})
- LOGGING_DESTINATION: $(yaml-quote ${LOGGING_DESTINATION:-})
- ELASTICSEARCH_LOGGING_REPLICAS: $(yaml-quote ${ELASTICSEARCH_LOGGING_REPLICAS:-})
- ENABLE_CLUSTER_DNS: $(yaml-quote ${ENABLE_CLUSTER_DNS:-false})
- ENABLE_CLUSTER_REGISTRY: $(yaml-quote ${ENABLE_CLUSTER_REGISTRY:-false})
- CLUSTER_REGISTRY_DISK: $(yaml-quote ${CLUSTER_REGISTRY_DISK:-})
- CLUSTER_REGISTRY_DISK_SIZE: $(yaml-quote ${CLUSTER_REGISTRY_DISK_SIZE:-})
- DNS_REPLICAS: $(yaml-quote ${DNS_REPLICAS:-})
- DNS_SERVER_IP: $(yaml-quote ${DNS_SERVER_IP:-})
- DNS_DOMAIN: $(yaml-quote ${DNS_DOMAIN:-})
- KUBELET_TOKEN: $(yaml-quote ${KUBELET_TOKEN:-})
- KUBE_PROXY_TOKEN: $(yaml-quote ${KUBE_PROXY_TOKEN:-})
- ADMISSION_CONTROL: $(yaml-quote ${ADMISSION_CONTROL:-})
- MASTER_IP_RANGE: $(yaml-quote ${MASTER_IP_RANGE})
- RUNTIME_CONFIG: $(yaml-quote ${RUNTIME_CONFIG})
- CA_CERT: $(yaml-quote ${CA_CERT_BASE64:-})
- KUBELET_CERT: $(yaml-quote ${KUBELET_CERT_BASE64:-})
- KUBELET_KEY: $(yaml-quote ${KUBELET_KEY_BASE64:-})
- NETWORK_PROVIDER: $(yaml-quote ${NETWORK_PROVIDER:-})
- NETWORK_POLICY_PROVIDER: $(yaml-quote ${NETWORK_POLICY_PROVIDER:-})
- PREPULL_E2E_IMAGES: $(yaml-quote ${PREPULL_E2E_IMAGES:-})
- HAIRPIN_MODE: $(yaml-quote ${HAIRPIN_MODE:-})
- OPENCONTRAIL_TAG: $(yaml-quote ${OPENCONTRAIL_TAG:-})
- OPENCONTRAIL_KUBERNETES_TAG: $(yaml-quote ${OPENCONTRAIL_KUBERNETES_TAG:-})
- OPENCONTRAIL_PUBLIC_SUBNET: $(yaml-quote ${OPENCONTRAIL_PUBLIC_SUBNET:-})
- E2E_STORAGE_TEST_ENVIRONMENT: $(yaml-quote ${E2E_STORAGE_TEST_ENVIRONMENT:-})
- KUBE_IMAGE_TAG: $(yaml-quote ${KUBE_IMAGE_TAG:-})
- KUBE_DOCKER_REGISTRY: $(yaml-quote ${KUBE_DOCKER_REGISTRY:-})
- KUBE_ADDON_REGISTRY: $(yaml-quote ${KUBE_ADDON_REGISTRY:-})
- MULTIZONE: $(yaml-quote ${MULTIZONE:-})
- NON_MASQUERADE_CIDR: $(yaml-quote ${NON_MASQUERADE_CIDR:-})
- KUBE_UID: $(yaml-quote ${KUBE_UID:-})
- EOF
- if [ -n "${KUBELET_PORT:-}" ]; then
- cat >>$file <<EOF
- KUBELET_PORT: $(yaml-quote ${KUBELET_PORT})
- EOF
- fi
- if [ -n "${KUBE_APISERVER_REQUEST_TIMEOUT:-}" ]; then
- cat >>$file <<EOF
- KUBE_APISERVER_REQUEST_TIMEOUT: $(yaml-quote ${KUBE_APISERVER_REQUEST_TIMEOUT})
- EOF
- fi
- if [ -n "${TERMINATED_POD_GC_THRESHOLD:-}" ]; then
- cat >>$file <<EOF
- TERMINATED_POD_GC_THRESHOLD: $(yaml-quote ${TERMINATED_POD_GC_THRESHOLD})
- EOF
- fi
- if [[ "${master}" == "true" && ("${MASTER_OS_DISTRIBUTION}" == "trusty" || "${MASTER_OS_DISTRIBUTION}" == "gci" || "${MASTER_OS_DISTRIBUTION}" == "coreos") ]] || \
- [[ "${master}" == "false" && ("${NODE_OS_DISTRIBUTION}" == "trusty" || "${NODE_OS_DISTRIBUTION}" == "gci" || "${NODE_OS_DISTRIBUTION}" == "coreos") ]] ; then
- cat >>$file <<EOF
- KUBE_MANIFESTS_TAR_URL: $(yaml-quote ${kube_manifests_tar_url})
- KUBE_MANIFESTS_TAR_HASH: $(yaml-quote ${KUBE_MANIFESTS_TAR_HASH})
- EOF
- fi
- if [ -n "${TEST_CLUSTER:-}" ]; then
- cat >>$file <<EOF
- TEST_CLUSTER: $(yaml-quote ${TEST_CLUSTER})
- EOF
- fi
- if [ -n "${KUBELET_TEST_ARGS:-}" ]; then
- cat >>$file <<EOF
- KUBELET_TEST_ARGS: $(yaml-quote ${KUBELET_TEST_ARGS})
- EOF
- fi
- if [ -n "${KUBELET_TEST_LOG_LEVEL:-}" ]; then
- cat >>$file <<EOF
- KUBELET_TEST_LOG_LEVEL: $(yaml-quote ${KUBELET_TEST_LOG_LEVEL})
- EOF
- fi
- if [ -n "${DOCKER_TEST_LOG_LEVEL:-}" ]; then
- cat >>$file <<EOF
- DOCKER_TEST_LOG_LEVEL: $(yaml-quote ${DOCKER_TEST_LOG_LEVEL})
- EOF
- fi
- if [ -n "${ENABLE_CUSTOM_METRICS:-}" ]; then
- cat >>$file <<EOF
- ENABLE_CUSTOM_METRICS: $(yaml-quote ${ENABLE_CUSTOM_METRICS})
- EOF
- fi
- if [ -n "${FEATURE_GATES:-}" ]; then
- cat >>$file <<EOF
- FEATURE_GATES: $(yaml-quote ${FEATURE_GATES})
- EOF
- fi
- if [[ "${master}" == "true" ]]; then
- # Master-only env vars.
- cat >>$file <<EOF
- KUBERNETES_MASTER: $(yaml-quote "true")
- KUBE_USER: $(yaml-quote ${KUBE_USER})
- KUBE_PASSWORD: $(yaml-quote ${KUBE_PASSWORD})
- KUBE_BEARER_TOKEN: $(yaml-quote ${KUBE_BEARER_TOKEN})
- MASTER_CERT: $(yaml-quote ${MASTER_CERT_BASE64:-})
- MASTER_KEY: $(yaml-quote ${MASTER_KEY_BASE64:-})
- KUBECFG_CERT: $(yaml-quote ${KUBECFG_CERT_BASE64:-})
- KUBECFG_KEY: $(yaml-quote ${KUBECFG_KEY_BASE64:-})
- KUBELET_APISERVER: $(yaml-quote ${KUBELET_APISERVER:-})
- ENABLE_MANIFEST_URL: $(yaml-quote ${ENABLE_MANIFEST_URL:-false})
- MANIFEST_URL: $(yaml-quote ${MANIFEST_URL:-})
- MANIFEST_URL_HEADER: $(yaml-quote ${MANIFEST_URL_HEADER:-})
- NUM_NODES: $(yaml-quote ${NUM_NODES})
- STORAGE_BACKEND: $(yaml-quote ${STORAGE_BACKEND:-})
- ENABLE_GARBAGE_COLLECTOR: $(yaml-quote ${ENABLE_GARBAGE_COLLECTOR:-})
- EOF
- if [ -n "${TEST_ETCD_VERSION:-}" ]; then
- cat >>$file <<EOF
- TEST_ETCD_VERSION: $(yaml-quote ${TEST_ETCD_VERSION})
- EOF
- fi
- if [ -n "${APISERVER_TEST_ARGS:-}" ]; then
- cat >>$file <<EOF
- APISERVER_TEST_ARGS: $(yaml-quote ${APISERVER_TEST_ARGS})
- EOF
- fi
- if [ -n "${APISERVER_TEST_LOG_LEVEL:-}" ]; then
- cat >>$file <<EOF
- APISERVER_TEST_LOG_LEVEL: $(yaml-quote ${APISERVER_TEST_LOG_LEVEL})
- EOF
- fi
- if [ -n "${CONTROLLER_MANAGER_TEST_ARGS:-}" ]; then
- cat >>$file <<EOF
- CONTROLLER_MANAGER_TEST_ARGS: $(yaml-quote ${CONTROLLER_MANAGER_TEST_ARGS})
- EOF
- fi
- if [ -n "${CONTROLLER_MANAGER_TEST_LOG_LEVEL:-}" ]; then
- cat >>$file <<EOF
- CONTROLLER_MANAGER_TEST_LOG_LEVEL: $(yaml-quote ${CONTROLLER_MANAGER_TEST_LOG_LEVEL})
- EOF
- fi
- if [ -n "${SCHEDULER_TEST_ARGS:-}" ]; then
- cat >>$file <<EOF
- SCHEDULER_TEST_ARGS: $(yaml-quote ${SCHEDULER_TEST_ARGS})
- EOF
- fi
- if [ -n "${SCHEDULER_TEST_LOG_LEVEL:-}" ]; then
- cat >>$file <<EOF
- SCHEDULER_TEST_LOG_LEVEL: $(yaml-quote ${SCHEDULER_TEST_LOG_LEVEL})
- EOF
- fi
- if [ -n "${INITIAL_ETCD_CLUSTER:-}" ]; then
- cat >>$file <<EOF
- INITIAL_ETCD_CLUSTER: $(yaml-quote ${INITIAL_ETCD_CLUSTER})
- EOF
- fi
- else
- # Node-only env vars.
- cat >>$file <<EOF
- KUBERNETES_MASTER: $(yaml-quote "false")
- ZONE: $(yaml-quote ${ZONE})
- EXTRA_DOCKER_OPTS: $(yaml-quote ${EXTRA_DOCKER_OPTS:-})
- EOF
- if [ -n "${KUBEPROXY_TEST_ARGS:-}" ]; then
- cat >>$file <<EOF
- KUBEPROXY_TEST_ARGS: $(yaml-quote ${KUBEPROXY_TEST_ARGS})
- EOF
- fi
- if [ -n "${KUBEPROXY_TEST_LOG_LEVEL:-}" ]; then
- cat >>$file <<EOF
- KUBEPROXY_TEST_LOG_LEVEL: $(yaml-quote ${KUBEPROXY_TEST_LOG_LEVEL})
- EOF
- fi
- fi
- if [ -n "${NODE_LABELS:-}" ]; then
- cat >>$file <<EOF
- NODE_LABELS: $(yaml-quote ${NODE_LABELS})
- EOF
- fi
- if [ -n "${EVICTION_HARD:-}" ]; then
- cat >>$file <<EOF
- EVICTION_HARD: $(yaml-quote ${EVICTION_HARD})
- EOF
- fi
- if [[ "${master}" == "true" && "${MASTER_OS_DISTRIBUTION}" == "coreos" ]] || \
- [[ "${master}" == "false" && "${NODE_OS_DISTRIBUTION}" == "coreos" ]]; then
- # CoreOS-only env vars. TODO(yifan): Make them available on other distros.
- cat >>$file <<EOF
- KUBERNETES_CONTAINER_RUNTIME: $(yaml-quote ${CONTAINER_RUNTIME:-rkt})
- RKT_VERSION: $(yaml-quote ${RKT_VERSION:-})
- RKT_PATH: $(yaml-quote ${RKT_PATH:-})
- RKT_STAGE1_IMAGE: $(yaml-quote ${RKT_STAGE1_IMAGE:-})
- KUBERNETES_CONFIGURE_CBR0: $(yaml-quote ${KUBERNETES_CONFIGURE_CBR0:-true})
- EOF
- fi
- if [[ "${ENABLE_CLUSTER_AUTOSCALER}" == "true" ]]; then
- cat >>$file <<EOF
- ENABLE_CLUSTER_AUTOSCALER: $(yaml-quote ${ENABLE_CLUSTER_AUTOSCALER})
- AUTOSCALER_MIG_CONFIG: $(yaml-quote ${AUTOSCALER_MIG_CONFIG})
- EOF
- fi
- # Federation specific environment variables.
- if [[ -n "${FEDERATION:-}" ]]; then
- cat >>$file <<EOF
- FEDERATION: $(yaml-quote ${FEDERATION})
- EOF
- fi
- if [ -n "${FEDERATIONS_DOMAIN_MAP:-}" ]; then
- cat >>$file <<EOF
- FEDERATIONS_DOMAIN_MAP: $(yaml-quote ${FEDERATIONS_DOMAIN_MAP})
- EOF
- fi
- if [ -n "${FEDERATION_NAME:-}" ]; then
- cat >>$file <<EOF
- FEDERATION_NAME: $(yaml-quote ${FEDERATION_NAME})
- EOF
- fi
- if [ -n "${DNS_ZONE_NAME:-}" ]; then
- cat >>$file <<EOF
- DNS_ZONE_NAME: $(yaml-quote ${DNS_ZONE_NAME})
- EOF
- fi
- if [ -n "${SCHEDULING_ALGORITHM_PROVIDER:-}" ]; then
- cat >>$file <<EOF
- SCHEDULING_ALGORITHM_PROVIDER: $(yaml-quote ${SCHEDULING_ALGORITHM_PROVIDER})
- EOF
- fi
- }
- function sha1sum-file() {
- if which shasum >/dev/null 2>&1; then
- shasum -a1 "$1" | awk '{ print $1 }'
- else
- sha1sum "$1" | awk '{ print $1 }'
- fi
- }
- # Create certificate pairs for the cluster.
- # $1: The public IP for the master.
- #
- # These are used for static cert distribution (e.g. static clustering) at
- # cluster creation time. This will be obsoleted once we implement dynamic
- # clustering.
- #
- # The following certificate pairs are created:
- #
- # - ca (the cluster's certificate authority)
- # - server
- # - kubelet
- # - kubecfg (for kubectl)
- #
- # TODO(roberthbailey): Replace easyrsa with a simple Go program to generate
- # the certs that we need.
- #
- # Assumed vars
- # KUBE_TEMP
- # MASTER_NAME
- #
- # Vars set:
- # CERT_DIR
- # CA_CERT_BASE64
- # MASTER_CERT_BASE64
- # MASTER_KEY_BASE64
- # KUBELET_CERT_BASE64
- # KUBELET_KEY_BASE64
- # KUBECFG_CERT_BASE64
- # KUBECFG_KEY_BASE64
- function create-certs {
- local -r primary_cn="${1}"
- # Determine extra certificate names for master
- local octets=($(echo "${SERVICE_CLUSTER_IP_RANGE}" | sed -e 's|/.*||' -e 's/\./ /g'))
- ((octets[3]+=1))
- local -r service_ip=$(echo "${octets[*]}" | sed 's/ /./g')
- local sans=""
- for extra in $@; do
- if [[ -n "${extra}" ]]; then
- sans="${sans}IP:${extra},"
- fi
- done
- sans="${sans}IP:${service_ip},DNS:kubernetes,DNS:kubernetes.default,DNS:kubernetes.default.svc,DNS:kubernetes.default.svc.${DNS_DOMAIN},DNS:${MASTER_NAME}"
- echo "Generating certs for alternate-names: ${sans}"
- PRIMARY_CN="${primary_cn}" SANS="${sans}" generate-certs
- CERT_DIR="${KUBE_TEMP}/easy-rsa-master/easyrsa3"
- # By default, linux wraps base64 output every 76 cols, so we use 'tr -d' to remove whitespaces.
- # Note 'base64 -w0' doesn't work on Mac OS X, which has different flags.
- CA_CERT_BASE64=$(cat "${CERT_DIR}/pki/ca.crt" | base64 | tr -d '\r\n')
- MASTER_CERT_BASE64=$(cat "${CERT_DIR}/pki/issued/${MASTER_NAME}.crt" | base64 | tr -d '\r\n')
- MASTER_KEY_BASE64=$(cat "${CERT_DIR}/pki/private/${MASTER_NAME}.key" | base64 | tr -d '\r\n')
- KUBELET_CERT_BASE64=$(cat "${CERT_DIR}/pki/issued/kubelet.crt" | base64 | tr -d '\r\n')
- KUBELET_KEY_BASE64=$(cat "${CERT_DIR}/pki/private/kubelet.key" | base64 | tr -d '\r\n')
- KUBECFG_CERT_BASE64=$(cat "${CERT_DIR}/pki/issued/kubecfg.crt" | base64 | tr -d '\r\n')
- KUBECFG_KEY_BASE64=$(cat "${CERT_DIR}/pki/private/kubecfg.key" | base64 | tr -d '\r\n')
- }
- # Runs the easy RSA commands to generate certificate files.
- # The generated files are at ${KUBE_TEMP}/easy-rsa-master/easyrsa3
- #
- # Assumed vars
- # KUBE_TEMP
- # MASTER_NAME
- # PRIMARY_CN: Primary canonical name
- # SANS: Subject alternate names
- #
- #
- function generate-certs {
- local -r cert_create_debug_output=$(mktemp "${KUBE_TEMP}/cert_create_debug_output.XXX")
- # Note: This was heavily cribbed from make-ca-cert.sh
- (set -x
- cd "${KUBE_TEMP}"
- curl -L -O --connect-timeout 20 --retry 6 --retry-delay 2 https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz
- tar xzf easy-rsa.tar.gz
- cd easy-rsa-master/easyrsa3
- ./easyrsa init-pki
- ./easyrsa --batch "--req-cn=${PRIMARY_CN}@$(date +%s)" build-ca nopass
- ./easyrsa --subject-alt-name="${SANS}" build-server-full "${MASTER_NAME}" nopass
- ./easyrsa build-client-full kubelet nopass
- ./easyrsa build-client-full kubecfg nopass) &>${cert_create_debug_output} || {
- # If there was an error in the subshell, just die.
- # TODO(roberthbailey): add better error handling here
- cat "${cert_create_debug_output}" >&2
- echo "=== Failed to generate certificates: Aborting ===" >&2
- exit 2
- }
- }
- #
- # Using provided master env, extracts value from provided key.
- #
- # Args:
- # $1 master env (kube-env of master; result of calling get-master-env)
- # $2 env key to use
- function get-env-val() {
- local match=`(echo "${1}" | grep ${2}) || echo ""`
- if [[ -z ${match} ]]; then
- echo ""
- fi
- echo ${match} | cut -d : -f 2 | cut -d \' -f 2
- }
- # Load the master env by calling get-master-env, and extract important values
- function parse-master-env() {
- # Get required master env vars
- local master_env=$(get-master-env)
- KUBELET_TOKEN=$(get-env-val "${master_env}" "KUBELET_TOKEN")
- KUBE_PROXY_TOKEN=$(get-env-val "${master_env}" "KUBE_PROXY_TOKEN")
- CA_CERT_BASE64=$(get-env-val "${master_env}" "CA_CERT")
- EXTRA_DOCKER_OPTS=$(get-env-val "${master_env}" "EXTRA_DOCKER_OPTS")
- KUBELET_CERT_BASE64=$(get-env-val "${master_env}" "KUBELET_CERT")
- KUBELET_KEY_BASE64=$(get-env-val "${master_env}" "KUBELET_KEY")
- }
|