sigs.k8s.io/cluster-api@v1.7.1/scripts/ci-e2e-lib.sh (about)

     1  #!/bin/bash
     2  
     3  # Copyright 2020 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  # capi:buildDockerImages builds all the required docker images, if not already present locally.
    18  capi:buildDockerImages () {
    19    # Configure provider images generation;
    20    # please ensure the generated image name matches image names used in the E2E_CONF_FILE;
    21    # also the same settings must be set in Makefile, docker-build-e2e target.
    22    ARCH="$(go env GOARCH)"
    23    export REGISTRY=gcr.io/k8s-staging-cluster-api
    24    export TAG=dev
    25    export ARCH
    26  
    27    ## Build all required docker image, if missing.
    28    ## Note: we check only for one image to exist, and assume that if one is missing all are missing.
    29    if [[ "$(docker images -q "$REGISTRY/cluster-api-controller-$ARCH:$TAG" 2> /dev/null)" == "" ]]; then
    30      echo "+ Building CAPI images and CAPD image"
    31      make docker-build-e2e
    32    else
    33      echo "+ CAPI images already present in the system, skipping make"
    34    fi
    35  }
    36  
    37  # k8s::prepareKindestImagesVariables defaults the environment variables KUBERNETES_VERSION_MANAGEMENT, KUBERNETES_VERSION,
    38  # KUBERNETES_VERSION_UPGRADE_TO, KUBERNETES_VERSION_UPGRADE_FROM and KUBERNETES_VERSION_LATEST_CI
    39  # depending on what is set in GINKGO_FOCUS.
    40  # Note: We do this to ensure that the kindest/node image gets built if it does
    41  # not already exist, e.g. for pre-releases, but only if necessary.
    42  k8s::prepareKindestImagesVariables() {
    43    # Always default KUBERNETES_VERSION_MANAGEMENT because we always create a management cluster out of it.
    44    if [[ -z "${KUBERNETES_VERSION_MANAGEMENT:-}" ]]; then
    45      KUBERNETES_VERSION_MANAGEMENT=$(grep KUBERNETES_VERSION_MANAGEMENT: < "$E2E_CONF_FILE" | awk -F'"' '{ print $2}')
    46      echo "Defaulting KUBERNETES_VERSION_MANAGEMENT to ${KUBERNETES_VERSION_MANAGEMENT} to trigger image build (because env var is not set)"
    47    fi
    48  
    49    if [[ ${GINKGO_FOCUS:-} == *"K8s-Install-ci-latest"* ]]; then
    50      # If the test focuses on [K8s-Install-ci-latest], only default KUBERNETES_VERSION_LATEST_CI
    51      # to the value in the e2e config and only if it is not set.
    52      # Note: We do this because we want to specify KUBERNETES_VERSION_LATEST_CI *only* in the e2e config.
    53      if [[ -z "${KUBERNETES_VERSION_LATEST_CI:-}" ]]; then
    54        KUBERNETES_VERSION_LATEST_CI=$(grep KUBERNETES_VERSION_LATEST_CI: < "$E2E_CONF_FILE" | awk -F'"' '{ print $2}')
    55        echo "Defaulting KUBERNETES_VERSION_LATEST_CI to ${KUBERNETES_VERSION_LATEST_CI} to trigger image build (because env var is not set)"
    56      fi
    57    elif [[ ${GINKGO_FOCUS:-} != *"K8s-Upgrade"* ]]; then
    58      # In any other case which is not [K8s-Upgrade], default KUBERNETES_VERSION if it is not set to make sure
    59      # the corresponding kindest/node image exists.
    60      if [[ -z "${KUBERNETES_VERSION:-}" ]]; then
    61        KUBERNETES_VERSION=$(grep KUBERNETES_VERSION: < "$E2E_CONF_FILE" | awk -F'"' '{ print $2}')
    62        echo "Defaulting KUBERNETES_VERSION to ${KUBERNETES_VERSION} to trigger image build (because env var is not set)"
    63      fi
    64    fi
    65  
    66    # Tests not focusing on [PR-Blocking], [K8s-Install] or [K8s-Install-ci-latest],
    67    # also run upgrade tests so default KUBERNETES_VERSION_UPGRADE_TO and KUBERNETES_VERSION_UPGRADE_FROM
    68    # to the value in the e2e config if they are not set.
    69    if [[ ${GINKGO_FOCUS:-} != *"PR-Blocking"* ]] && [[ ${GINKGO_FOCUS:-} != *"K8s-Install"* ]]; then
    70      if [[ -z "${KUBERNETES_VERSION_UPGRADE_TO:-}" ]]; then
    71        KUBERNETES_VERSION_UPGRADE_TO=$(grep KUBERNETES_VERSION_UPGRADE_TO: < "$E2E_CONF_FILE" | awk -F'"' '{ print $2}')
    72        echo "Defaulting KUBERNETES_VERSION_UPGRADE_TO to ${KUBERNETES_VERSION_UPGRADE_TO} to trigger image build (because env var is not set)"
    73      fi
    74      if [[ -z "${KUBERNETES_VERSION_UPGRADE_FROM:-}" ]]; then
    75        KUBERNETES_VERSION_UPGRADE_FROM=$(grep KUBERNETES_VERSION_UPGRADE_FROM: < "$E2E_CONF_FILE" | awk -F'"' '{ print $2}')
    76        echo "Defaulting KUBERNETES_VERSION_UPGRADE_FROM to ${KUBERNETES_VERSION_UPGRADE_FROM} to trigger image build (because env var is not set)"
    77      fi
    78    fi
    79  }
    80  
    81  # k8s::prepareKindestImages checks all the e2e test variables representing a Kubernetes version,
    82  # and makes sure a corresponding kindest/node image is available locally.
    83  k8s::prepareKindestImages() {
    84    if [ -n "${KUBERNETES_VERSION_MANAGEMENT:-}" ]; then
    85      k8s::resolveVersion "KUBERNETES_VERSION_MANAGEMENT" "$KUBERNETES_VERSION_MANAGEMENT"
    86      export KUBERNETES_VERSION_MANAGEMENT=$resolveVersion
    87  
    88      kind::prepareKindestImage "$resolveVersion"
    89    fi
    90  
    91    if [ -n "${KUBERNETES_VERSION:-}" ]; then
    92      k8s::resolveVersion "KUBERNETES_VERSION" "$KUBERNETES_VERSION"
    93      export KUBERNETES_VERSION=$resolveVersion
    94  
    95      kind::prepareKindestImage "$resolveVersion"
    96    fi
    97  
    98    if [ -n "${KUBERNETES_VERSION_UPGRADE_TO:-}" ]; then
    99      k8s::resolveVersion "KUBERNETES_VERSION_UPGRADE_TO" "$KUBERNETES_VERSION_UPGRADE_TO"
   100      export KUBERNETES_VERSION_UPGRADE_TO=$resolveVersion
   101  
   102      kind::prepareKindestImage "$resolveVersion"
   103    fi
   104  
   105    if [ -n "${KUBERNETES_VERSION_UPGRADE_FROM:-}" ]; then
   106      k8s::resolveVersion "KUBERNETES_VERSION_UPGRADE_FROM" "$KUBERNETES_VERSION_UPGRADE_FROM"
   107      export KUBERNETES_VERSION_UPGRADE_FROM=$resolveVersion
   108  
   109      kind::prepareKindestImage "$resolveVersion"
   110    fi
   111  
   112    if [ -n "${KUBERNETES_VERSION_LATEST_CI:-}" ]; then
   113      k8s::resolveVersion "KUBERNETES_VERSION_LATEST_CI" "$KUBERNETES_VERSION_LATEST_CI"
   114      export KUBERNETES_VERSION_LATEST_CI=$resolveVersion
   115  
   116      kind::prepareKindestImage "$resolveVersion"
   117    fi
   118  
   119    if [ -n "${BUILD_NODE_IMAGE_TAG:-}" ]; then
   120      k8s::resolveVersion "BUILD_NODE_IMAGE_TAG" "$BUILD_NODE_IMAGE_TAG"
   121      export BUILD_NODE_IMAGE_TAG=$resolveVersion
   122  
   123      kind::prepareKindestImage "$resolveVersion"
   124    fi
   125  }
   126  
   127  # k8s::resolveVersion resolves kubernetes version labels (e.g. latest) to the corresponding version numbers.
   128  # The result will be available in the resolveVersion variable which is accessible from the caller.
   129  #
   130  # NOTE: this can't be used for kindest/node images pulled from docker hub, given that there are not guarantees that
   131  # such images are generated in sync with the Kubernetes release process.
   132  k8s::resolveVersion() {
   133    local variableName=$1
   134    local version=$2
   135  
   136    resolveVersion=$version
   137    if [[ "$version" =~ ^v ]]; then
   138      echo "+ $variableName=\"$version\" already a version, no need to resolve"
   139      return
   140    fi
   141  
   142    if [[ "$version" =~ ^ci/ ]]; then
   143      resolveVersion=$(curl -LsS "http://dl.k8s.io/ci/${version#ci/}.txt")
   144    else
   145      resolveVersion=$(curl -LsS "http://dl.k8s.io/release/${version}.txt")
   146    fi
   147    echo "+ $variableName=\"$version\" resolved to \"$resolveVersion\""
   148  }
   149  
   150  # kind::prepareKindestImage check if a kindest/image exist, and if yes, pre-pull it; otherwise it builds
   151  # the kindest image locally
   152  kind::prepareKindestImage() {
   153    local version=$1
   154  
   155    # ALWAYS_BUILD_KIND_IMAGES will default to false if unset.
   156    ALWAYS_BUILD_KIND_IMAGES="${ALWAYS_BUILD_KIND_IMAGES:-"false"}"
   157  
   158    # Try to pre-pull the image
   159    kind::prepullImage "kindest/node:$version"
   160  
   161    # if pre-pull failed, or ALWAYS_BUILD_KIND_IMAGES is true build the images locally.
   162   if [[ "$retVal" != 0 ]] || [[ "$ALWAYS_BUILD_KIND_IMAGES" = "true" ]]; then
   163      echo "+ building image for Kuberentes $version locally. This is either because the image wasn't available in docker hub or ALWAYS_BUILD_KIND_IMAGES is set to true"
   164      kind::buildNodeImage "$version"
   165    fi
   166  }
   167  
   168  # kind::buildNodeImage builds a kindest/node images starting from Kubernetes sources.
   169  # the func expect an input parameter defining the image tag to be used.
   170  kind::buildNodeImage() {
   171    local version=$1
   172  
   173    # move to the Kubernetes repository.
   174    echo "KUBE_ROOT $GOPATH/src/k8s.io/kubernetes"
   175    cd "$GOPATH/src/k8s.io/kubernetes" || exit
   176  
   177    # checkouts the Kubernetes branch for the given version.
   178    k8s::checkoutBranch "$version"
   179  
   180    # sets the build version that will be applied by the Kubernetes build command called during kind build node-image.
   181    k8s::setBuildVersion "$version"
   182  
   183    # build the node image
   184    version="${version//+/_}"
   185    echo "+ Building kindest/node:$version"
   186    kind build node-image --image "kindest/node:$version"
   187  
   188    # move back to Cluster API
   189    cd "$REPO_ROOT" || exit
   190  }
   191  
   192  # k8s::checkoutBranch checkouts the Kubernetes branch for the given version.
   193  k8s::checkoutBranch() {
   194    local version=$1
   195    echo "+ Checkout branch for Kubernetes $version"
   196  
   197    # checkout the required tag/branch.
   198    local buildMetadata
   199    buildMetadata=$(echo "${version#v}" | awk '{split($0,a,"+"); print a[2]}')
   200    if [[ "$buildMetadata" == "" ]]; then
   201      # if there are no release metadata, it means we are looking for a Kubernetes version that
   202      # should be already been tagged.
   203      echo "+ checkout tag $version"
   204      git fetch --all --tags
   205      git checkout "tags/$version" -B "$version-branch"
   206    else
   207      # otherwise we are requiring a Kubernetes version that should be built from HEAD
   208      # of one of the existing branches
   209      echo "+ checking for existing branches"
   210      git fetch --all
   211  
   212      local major
   213      local minor
   214      major=$(echo "${version#v}" | awk '{split($0,a,"."); print a[1]}')
   215      minor=$(echo "${version#v}" | awk '{split($0,a,"."); print a[2]}')
   216  
   217      local releaseBranch
   218      releaseBranch="$(git branch -r | grep "release-$major.$minor$" || true)"
   219      if [[ "$releaseBranch" != "" ]]; then
   220        # if there is already a release branch for the required Kubernetes branch, use it
   221        echo "+ checkout $releaseBranch branch"
   222        git checkout "$releaseBranch" -B "release-$major.$minor"
   223      else
   224        # otherwise, we should build from the main branch, which is the branch for the next release
   225        # TODO(sbueringer) we can only change this to main after k/k has migrated to main
   226        echo "+ checkout master branch"
   227        git checkout master
   228      fi
   229    fi
   230  }
   231  
   232  # k8s::setBuildVersion sets the build version that will be applied by the Kubernetes build command.
   233  # the func expect an input parameter defining the version to be used.
   234  k8s::setBuildVersion() {
   235    local version=$1
   236    echo "+ Setting version for Kubernetes build to $version"
   237  
   238    local major
   239    local minor
   240    major=$(echo "${version#v}" | awk '{split($0,a,"."); print a[1]}')
   241    minor=$(echo "${version#v}" | awk '{split($0,a,"."); print a[2]}')
   242  
   243    cat > build-version << EOL
   244  export KUBE_GIT_MAJOR=$major
   245  export KUBE_GIT_MINOR=$minor
   246  export KUBE_GIT_VERSION=$version
   247  export KUBE_GIT_TREE_STATE=clean
   248  export KUBE_GIT_COMMIT=d34db33f
   249  EOL
   250  
   251    export KUBE_GIT_VERSION_FILE=$PWD/build-version
   252  }
   253  
   254  # kind:prepullAdditionalImages pre-pull all the additional (not Kindest/node) images that will be used in the e2e, thus making
   255  # the actual test run less sensible to the network speed.
   256  kind:prepullAdditionalImages () {
   257    # Pulling cert manager images so we can pre-load in kind nodes
   258    kind::prepullImage "quay.io/jetstack/cert-manager-cainjector:v1.14.4"
   259    kind::prepullImage "quay.io/jetstack/cert-manager-webhook:v1.14.4"
   260    kind::prepullImage "quay.io/jetstack/cert-manager-controller:v1.14.4"
   261  }
   262  
   263  # kind:prepullImage pre-pull a docker image if no already present locally.
   264  # The result will be available in the retVal value which is accessible from the caller.
   265  kind::prepullImage () {
   266    local image=$1
   267    image="${image//+/_}"
   268  
   269    retVal=0
   270    if [[ "$(docker images -q "$image" 2> /dev/null)" == "" ]]; then
   271      echo "+ Pulling $image"
   272      docker pull "$image" || retVal=$?
   273    else
   274      echo "+ image $image already present in the system, skipping pre-pull"
   275    fi
   276  }