k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/hack/make-rules/test-e2e-node.sh (about)

     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  KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/../..
    18  source "${KUBE_ROOT}/hack/lib/init.sh"
    19  
    20  kube::golang::setup_env
    21  kube::golang::setup_gomaxprocs
    22  
    23  # start the cache mutation detector by default so that cache mutators will be found
    24  KUBE_CACHE_MUTATION_DETECTOR="${KUBE_CACHE_MUTATION_DETECTOR:-true}"
    25  export KUBE_CACHE_MUTATION_DETECTOR
    26  
    27  # panic the server on watch decode errors since they are considered coder mistakes
    28  KUBE_PANIC_WATCH_DECODE_ERROR="${KUBE_PANIC_WATCH_DECODE_ERROR:-true}"
    29  export KUBE_PANIC_WATCH_DECODE_ERROR
    30  
    31  focus=${FOCUS:-""}
    32  skip=${SKIP-"\[Flaky\]|\[Slow\]|\[Serial\]"}
    33  # The number of tests that can run in parallel depends on what tests
    34  # are running and on the size of the node. Too many, and tests will
    35  # fail due to resource contention. 8 is a reasonable default for a
    36  # e2-standard-2 node.
    37  # Currently, parallelism only affects when REMOTE=true. For local test,
    38  # ginkgo default parallelism (cores - 1) is used.
    39  parallelism=${PARALLELISM:-8}
    40  artifacts="${ARTIFACTS:-"/tmp/_artifacts/$(date +%y%m%dT%H%M%S)"}"
    41  remote=${REMOTE:-"false"}
    42  remote_mode=${REMOTE_MODE:-"gce"}
    43  container_runtime_endpoint=${CONTAINER_RUNTIME_ENDPOINT:-"unix:///run/containerd/containerd.sock"}
    44  image_service_endpoint=${IMAGE_SERVICE_ENDPOINT:-""}
    45  run_until_failure=${RUN_UNTIL_FAILURE:-"false"}
    46  test_args=${TEST_ARGS:-""}
    47  timeout_arg=""
    48  system_spec_name=${SYSTEM_SPEC_NAME:-}
    49  extra_envs=${EXTRA_ENVS:-}
    50  runtime_config=${RUNTIME_CONFIG:-}
    51  ssh_user=${SSH_USER:-"${USER}"}
    52  ssh_key=${SSH_KEY:-}
    53  ssh_options=${SSH_OPTIONS:-}
    54  kubelet_config_file=${KUBELET_CONFIG_FILE:-"test/e2e_node/jenkins/default-kubelet-config.yaml"}
    55  
    56  # If set, the command executed will be:
    57  # - `dlv exec` if set to "delve"
    58  # - `gdb` if set to "gdb"
    59  # NOTE: for this to work the e2e_node.test binary has to be compiled with DBG=1.
    60  #
    61  # The name of this variable is the same as in ginkgo-e2e.sh.
    62  debug_tool=${E2E_TEST_DEBUG_TOOL:-}
    63  if [ "${remote}" = true ] && [ -n "${debug_tool}" ]; then
    64      echo "Support for E2E_TEST_DEBUG_TOOL=${debug_tool} is only implemented for REMOTE=false."
    65      exit 1
    66  fi
    67  
    68  # Parse the flags to pass to ginkgo
    69  ginkgoflags="-timeout=24h"
    70  if [[ ${parallelism} -gt 1 ]]; then
    71    ginkgoflags="${ginkgoflags} -nodes=${parallelism} "
    72  fi
    73  
    74  if [[ ${focus} != "" ]]; then
    75    ginkgoflags="${ginkgoflags} -focus=\"${focus}\" "
    76  fi
    77  
    78  if [[ ${skip} != "" ]]; then
    79    ginkgoflags="${ginkgoflags} -skip=\"${skip}\" "
    80  fi
    81  
    82  if [[ ${run_until_failure} == "true" ]]; then
    83    ginkgoflags="${ginkgoflags} --until-it-fails=true "
    84  fi
    85  
    86  # Setup the directory to copy test artifacts (logs, junit.xml, etc) from remote host to local host
    87  if [ ! -d "${artifacts}" ]; then
    88    echo "Creating artifacts directory at ${artifacts}"
    89    mkdir -p "${artifacts}"
    90  fi
    91  echo "Test artifacts will be written to ${artifacts}"
    92  
    93  if [[ -n ${container_runtime_endpoint} ]] ; then
    94    test_args="--container-runtime-endpoint=${container_runtime_endpoint} ${test_args}"
    95  fi
    96  if [[ -n ${image_service_endpoint} ]] ; then
    97    test_args="--image-service-endpoint=${image_service_endpoint} ${test_args}"
    98  fi
    99  
   100  if [[ "${test_args}" != *"prepull-images"* ]]; then
   101    test_args="--prepull-images=${PREPULL_IMAGES:-false}  ${test_args}"
   102  fi
   103  
   104  if [ "${remote}" = true ] && [ "${remote_mode}" = gce ] ; then
   105    # The following options are only valid in remote GCE run.
   106    images=${IMAGES:-""}
   107    hosts=${HOSTS:-""}
   108    image_project=${IMAGE_PROJECT:-"cos-cloud"}
   109    metadata=${INSTANCE_METADATA:-""}
   110    gubernator=${GUBERNATOR:-"false"}
   111    instance_type=${INSTANCE_TYPE:-""}
   112    node_env="${NODE_ENV:-""}"
   113    image_config_file=${IMAGE_CONFIG_FILE:-""}
   114    image_config_dir=${IMAGE_CONFIG_DIR:-""}
   115    use_dockerized_build=${USE_DOCKERIZED_BUILD:-"false"}
   116    target_build_arch=${TARGET_BUILD_ARCH:-""}
   117    runtime_config=${RUNTIME_CONFIG:-""}
   118    if [[ ${hosts} == "" && ${images} == "" && ${image_config_file} == "" ]]; then
   119      gci_image=$(gcloud compute images list --project "${image_project}" \
   120      --no-standard-images --filter="name ~ 'cos-beta.*'" --format="table[no-heading](name)")
   121      images=${gci_image}
   122      metadata="user-data<${KUBE_ROOT}/test/e2e_node/jenkins/gci-init.yaml,gci-update-strategy=update_disabled"
   123    fi
   124    instance_prefix=${INSTANCE_PREFIX:-"test"}
   125    cleanup=${CLEANUP:-"true"}
   126    delete_instances=${DELETE_INSTANCES:-"false"}
   127    preemptible_instances=${PREEMPTIBLE_INSTANCES:-"false"}
   128    test_suite=${TEST_SUITE:-"default"}
   129    if [[ -n "${TIMEOUT:-}" ]] ; then
   130      timeout_arg="--test-timeout=${TIMEOUT}"
   131    fi
   132  
   133    # Get the compute zone
   134    zone=${ZONE:-"$(gcloud info --format='value(config.properties.compute.zone.value)')"}
   135    if [[ ${zone} == "" ]]; then
   136      echo "Could not find gcloud compute/zone when running: \`gcloud info --format='value(config.properties.compute.zone.value)'\`"
   137      exit 1
   138    fi
   139  
   140    # Get the compute project
   141    project=$(gcloud info --format='value(config.project)')
   142    if [[ ${project} == "" ]]; then
   143      echo "Could not find gcloud project when running: \`gcloud info --format='value(config.project)'\`"
   144      exit 1
   145    fi
   146  
   147    # Check if any of the images specified already have running instances.  If so reuse those instances
   148    # by moving the IMAGE to a HOST
   149    if [[ ${images} != "" ]]; then
   150    IFS=',' read -ra IM <<< "${images}"
   151         images=""
   152         for i in "${IM[@]}"; do
   153           if gcloud compute instances list --project="${project}" --filter="name:'${instance_prefix}-${i}' AND zone:'${zone}'" | grep "${i}"; then
   154             if [[ "${hosts}" != "" ]]; then
   155               hosts="${hosts},"
   156             fi
   157             echo "Reusing host ${instance_prefix}-${i}"
   158             hosts="${hosts}${instance_prefix}-${i}"
   159           else
   160             if [[ "${images}" != "" ]]; then
   161               images="${images},"
   162             fi
   163             images="${images}${i}"
   164           fi
   165         done
   166    fi
   167  
   168    # Use cluster.local as default dns-domain
   169    test_args='--dns-domain="'${KUBE_DNS_DOMAIN:-cluster.local}'" '${test_args}
   170    test_args='--kubelet-flags="--cluster-domain='${KUBE_DNS_DOMAIN:-cluster.local}'" '${test_args}
   171  
   172    # Output the configuration we will try to run
   173    echo "Running tests remotely using"
   174    echo "Project: ${project}"
   175    echo "Image Project: ${image_project}"
   176    echo "Compute/Zone: ${zone}"
   177    if [[ -n ${images} ]]; then
   178      echo "Images: ${images}"
   179    fi
   180    if [[ -n ${hosts} ]]; then
   181      echo "Hosts: ${hosts}"
   182    fi
   183    echo "Test Args: ${test_args}"
   184    echo "Ginkgo Flags: ${ginkgoflags}"
   185    if [[ -n ${metadata} ]]; then
   186      echo "Instance Metadata: ${metadata}"
   187    fi
   188    if [[ -n ${node_env} ]]; then
   189      echo "Node-env: \"${node_env}\""
   190    fi
   191    if [[ -n ${image_config_file} ]]; then
   192      echo "Image Config File: ${image_config_dir}/${image_config_file}"
   193    fi
   194    if [[ -n ${instance_type} ]]; then
   195      echo "Instance Type: ${instance_type}"
   196    fi
   197    echo "Kubelet Config File: ${kubelet_config_file}"
   198  
   199    # Invoke the runner
   200    go run test/e2e_node/runner/remote/run_remote.go  --vmodule=*=4 --ssh-env="gce" \
   201      --zone="${zone}" --project="${project}" --gubernator="${gubernator}" \
   202      --hosts="${hosts}" --images="${images}" --cleanup="${cleanup}" \
   203      --results-dir="${artifacts}" --ginkgo-flags="${ginkgoflags}" --runtime-config="${runtime_config}" \
   204      --image-project="${image_project}" --instance-name-prefix="${instance_prefix}" \
   205      --delete-instances="${delete_instances}" --test_args="${test_args}" --instance-metadata="${metadata}" \
   206      --image-config-file="${image_config_file}" --system-spec-name="${system_spec_name}" \
   207      --runtime-config="${runtime_config}" --preemptible-instances="${preemptible_instances}" \
   208      --ssh-user="${ssh_user}" --ssh-key="${ssh_key}" --ssh-options="${ssh_options}" \
   209      --image-config-dir="${image_config_dir}" --node-env="${node_env}" \
   210      --use-dockerized-build="${use_dockerized_build}" --instance-type="${instance_type}" \
   211      --target-build-arch="${target_build_arch}" \
   212      --extra-envs="${extra_envs}" --kubelet-config-file="${kubelet_config_file}"  --test-suite="${test_suite}" \
   213      "${timeout_arg}" \
   214      2>&1 | tee -i "${artifacts}/build-log.txt"
   215    exit $?
   216  
   217  elif [ "${remote}" = true ] && [ "${remote_mode}" = ssh ] ; then
   218    hosts=${HOSTS:-""}
   219    test_suite=${TEST_SUITE:-"default"}
   220    if [[ -n "${TIMEOUT:-}" ]] ; then
   221      timeout_arg="--test-timeout=${TIMEOUT}"
   222    fi
   223  
   224    # Use cluster.local as default dns-domain
   225    test_args='--dns-domain="'${KUBE_DNS_DOMAIN:-cluster.local}'" '${test_args}
   226    test_args='--kubelet-flags="--cluster-domain='${KUBE_DNS_DOMAIN:-cluster.local}'" '${test_args}
   227  
   228    # Invoke the runner
   229    go run test/e2e_node/runner/remote/run_remote.go  --mode="ssh" --vmodule=*=4 \
   230      --hosts="${hosts}" --results-dir="${artifacts}" --ginkgo-flags="${ginkgoflags}" \
   231      --test_args="${test_args}" --system-spec-name="${system_spec_name}" \
   232      --runtime-config="${runtime_config}" \
   233      --ssh-user="${ssh_user}" --ssh-key="${ssh_key}" --ssh-options="${ssh_options}" \
   234      --extra-envs="${extra_envs}" --test-suite="${test_suite}" \
   235      "${timeout_arg}" \
   236      2>&1 | tee -i "${artifacts}/build-log.txt"
   237    exit $?
   238  
   239  else
   240    # Refresh sudo credentials if needed
   241    if ping -c 1 -q metadata.google.internal &> /dev/null; then
   242      echo 'Running on GCE, not asking for sudo credentials'
   243    elif ping -c 1 -q 169.254.169.254 &> /dev/null; then
   244      echo 'Running on AWS, not asking for sudo credentials'
   245    elif sudo --non-interactive "$(which bash)" -c true 2> /dev/null; then
   246      # if we can run bash without a password, it's a pretty safe bet that either
   247      # we can run any command without a password, or that sudo credentials
   248      # are already cached - and they've just been re-cached
   249      echo 'No need to refresh sudo credentials'
   250    else
   251      echo 'Updating sudo credentials'
   252      sudo -v || exit 1
   253    fi
   254  
   255  
   256    # Use cluster.local as default dns-domain
   257    test_args='--dns-domain="'${KUBE_DNS_DOMAIN:-cluster.local}'" '${test_args}
   258    test_args='--kubelet-flags="--cluster-domain='${KUBE_DNS_DOMAIN:-cluster.local}'" '${test_args}
   259    # Test using the host the script was run on
   260    # Provided for backwards compatibility
   261    go run test/e2e_node/runner/local/run_local.go \
   262      --debug-tool="${debug_tool}" \
   263      --system-spec-name="${system_spec_name}" --extra-envs="${extra_envs}" \
   264      --ginkgo-flags="${ginkgoflags}" \
   265      --test-flags="--v 4 --report-dir=${artifacts} --node-name $(hostname) ${test_args}" \
   266      --runtime-config="${runtime_config}" \
   267      --kubelet-config-file="${kubelet_config_file}" \
   268      --build-dependencies=true 2>&1 | tee -i "${artifacts}/build-log.txt"
   269    exit $?
   270  fi