2019-10-01 10:01:16 -07:00
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
# Copyright 2018 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.
|
|
|
|
|
|
|
|
|
|
|
|
# hack script for running a kind e2e
|
|
|
|
|
|
# must be run with a kubernetes checkout in $PWD (IE from the checkout)
|
|
|
|
|
|
# Usage: SKIP="ginkgo skip regex" FOCUS="ginkgo focus regex" kind-e2e.sh
|
|
|
|
|
|
|
2019-10-01 10:13:53 -07:00
|
|
|
|
set -o errexit -o nounset -o xtrace
|
2019-10-01 10:01:16 -07:00
|
|
|
|
|
|
|
|
|
|
# Settings:
|
|
|
|
|
|
# SKIP: ginkgo skip regex
|
|
|
|
|
|
# FOCUS: ginkgo focus regex
|
2024-04-16 17:05:19 +02:00
|
|
|
|
# LABEL_FILTER: ginkgo label query for selecting tests (see "Spec Labels" in https://onsi.github.io/ginkgo/#filtering-specs)
|
|
|
|
|
|
#
|
|
|
|
|
|
# The default is to focus on conformance tests. Serial tests get skipped when
|
|
|
|
|
|
# parallel testing is enabled. Using LABEL_FILTER instead of combining SKIP and
|
|
|
|
|
|
# FOCUS is recommended (more expressive, easier to read than regexp).
|
|
|
|
|
|
#
|
2022-12-14 15:28:23 +01:00
|
|
|
|
# FEATURE_GATES:
|
|
|
|
|
|
# JSON or YAML encoding of a string/bool map: {"FeatureGateA": true, "FeatureGateB": false}
|
|
|
|
|
|
# Enables or disables feature gates in the entire cluster.
|
|
|
|
|
|
# Cannot be used when GA_ONLY=true.
|
|
|
|
|
|
# RUNTIME_CONFIG:
|
|
|
|
|
|
# JSON or YAML encoding of a string/string (!) map: {"apia.example.com/v1alpha1": "true", "apib.example.com/v1beta1": "false"}
|
|
|
|
|
|
# Enables API groups in the apiserver via --runtime-config.
|
|
|
|
|
|
# Cannot be used when GA_ONLY=true.
|
2019-10-01 10:01:16 -07:00
|
|
|
|
|
2020-05-30 09:03:41 -07:00
|
|
|
|
# cleanup logic for cleanup on exit
|
|
|
|
|
|
CLEANED_UP=false
|
2019-10-01 10:01:16 -07:00
|
|
|
|
cleanup() {
|
2020-05-30 09:03:41 -07:00
|
|
|
|
if [ "$CLEANED_UP" = "true" ]; then
|
|
|
|
|
|
return
|
|
|
|
|
|
fi
|
2019-10-02 21:10:14 -07:00
|
|
|
|
# KIND_CREATE_ATTEMPTED is true once we: kind create
|
|
|
|
|
|
if [ "${KIND_CREATE_ATTEMPTED:-}" = true ]; then
|
2022-05-12 11:02:14 -07:00
|
|
|
|
kind "export" logs "${ARTIFACTS}" || true
|
2019-10-01 10:01:16 -07:00
|
|
|
|
kind delete cluster || true
|
|
|
|
|
|
fi
|
|
|
|
|
|
rm -f _output/bin/e2e.test || true
|
|
|
|
|
|
# remove our tempdir, this needs to be last, or it will prevent kind delete
|
2020-05-30 09:03:41 -07:00
|
|
|
|
if [ -n "${TMP_DIR:-}" ]; then
|
|
|
|
|
|
rm -rf "${TMP_DIR:?}"
|
|
|
|
|
|
fi
|
|
|
|
|
|
CLEANED_UP=true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# setup signal handlers
|
2022-12-15 11:43:50 -08:00
|
|
|
|
# shellcheck disable=SC2317 # this is not unreachable code
|
2020-05-30 09:03:41 -07:00
|
|
|
|
signal_handler() {
|
|
|
|
|
|
if [ -n "${GINKGO_PID:-}" ]; then
|
|
|
|
|
|
kill -TERM "$GINKGO_PID" || true
|
|
|
|
|
|
fi
|
|
|
|
|
|
cleanup
|
2019-10-01 10:01:16 -07:00
|
|
|
|
}
|
2020-05-30 09:03:41 -07:00
|
|
|
|
trap signal_handler INT TERM
|
2019-10-01 10:01:16 -07:00
|
|
|
|
|
|
|
|
|
|
# build kubernetes / node image, e2e binaries
|
|
|
|
|
|
build() {
|
|
|
|
|
|
# build the node image w/ kubernetes
|
2020-02-26 01:27:18 -08:00
|
|
|
|
kind build node-image -v 1
|
2022-04-18 11:15:28 +08:00
|
|
|
|
# Ginkgo v1 is used by Kubernetes 1.24 and earlier, fallback if v2 is not available.
|
|
|
|
|
|
GINKGO_SRC_DIR="vendor/github.com/onsi/ginkgo/v2/ginkgo"
|
|
|
|
|
|
if [ ! -d "$GINKGO_SRC_DIR" ]; then
|
|
|
|
|
|
GINKGO_SRC_DIR="vendor/github.com/onsi/ginkgo/ginkgo"
|
|
|
|
|
|
fi
|
2019-10-01 10:01:16 -07:00
|
|
|
|
# make sure we have e2e requirements
|
2022-04-21 09:22:55 +02:00
|
|
|
|
make all WHAT="cmd/kubectl test/e2e/e2e.test ${GINKGO_SRC_DIR}"
|
2023-08-13 23:58:02 +00:00
|
|
|
|
|
2023-08-14 04:21:02 -04:00
|
|
|
|
# Ensure the built kubectl is used instead of system
|
2023-08-13 23:58:02 +00:00
|
|
|
|
export PATH="${PWD}/_output/bin:$PATH"
|
2019-10-01 10:01:16 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-30 04:47:46 -07:00
|
|
|
|
check_structured_log_support() {
|
2021-07-25 06:20:27 -07:00
|
|
|
|
case "${KUBE_VERSION}" in
|
|
|
|
|
|
v1.1[0-8].*)
|
2021-07-30 04:47:46 -07:00
|
|
|
|
echo "$1 is only supported on versions >= v1.19, got ${KUBE_VERSION}"
|
2021-07-25 06:20:27 -07:00
|
|
|
|
exit 1
|
|
|
|
|
|
;;
|
|
|
|
|
|
esac
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-01 10:01:16 -07:00
|
|
|
|
# up a cluster with kind
|
|
|
|
|
|
create_cluster() {
|
2021-03-19 16:08:15 -07:00
|
|
|
|
# Grab the version of the cluster we're about to start
|
|
|
|
|
|
KUBE_VERSION="$(docker run --rm --entrypoint=cat "kindest/node:latest" /kind/version)"
|
|
|
|
|
|
|
|
|
|
|
|
# Default Log level for all components in test clusters
|
|
|
|
|
|
KIND_CLUSTER_LOG_LEVEL=${KIND_CLUSTER_LOG_LEVEL:-4}
|
|
|
|
|
|
|
|
|
|
|
|
# potentially enable --logging-format
|
2021-07-30 04:47:46 -07:00
|
|
|
|
CLUSTER_LOG_FORMAT=${CLUSTER_LOG_FORMAT:-}
|
2021-07-20 14:45:31 +05:30
|
|
|
|
scheduler_extra_args=" \"v\": \"${KIND_CLUSTER_LOG_LEVEL}\""
|
2021-07-25 06:20:27 -07:00
|
|
|
|
controllerManager_extra_args=" \"v\": \"${KIND_CLUSTER_LOG_LEVEL}\""
|
|
|
|
|
|
apiServer_extra_args=" \"v\": \"${KIND_CLUSTER_LOG_LEVEL}\""
|
2021-07-27 04:05:26 -07:00
|
|
|
|
if [ -n "$CLUSTER_LOG_FORMAT" ]; then
|
2021-07-30 04:47:46 -07:00
|
|
|
|
check_structured_log_support "CLUSTER_LOG_FORMAT"
|
2021-07-27 04:05:26 -07:00
|
|
|
|
scheduler_extra_args="${scheduler_extra_args}
|
|
|
|
|
|
\"logging-format\": \"${CLUSTER_LOG_FORMAT}\""
|
|
|
|
|
|
controllerManager_extra_args="${controllerManager_extra_args}
|
|
|
|
|
|
\"logging-format\": \"${CLUSTER_LOG_FORMAT}\""
|
2021-07-25 06:20:27 -07:00
|
|
|
|
apiServer_extra_args="${apiServer_extra_args}
|
2021-07-27 04:05:26 -07:00
|
|
|
|
\"logging-format\": \"${CLUSTER_LOG_FORMAT}\""
|
2021-07-20 14:45:31 +05:30
|
|
|
|
fi
|
2024-11-02 18:03:39 -03:00
|
|
|
|
kubelet_extra_args=" \"v\": \"${KIND_CLUSTER_LOG_LEVEL}\"
|
|
|
|
|
|
\"container-log-max-files\": \"10\"
|
2024-11-03 08:39:18 -03:00
|
|
|
|
\"container-log-max-size\": \"100Mi\""
|
2021-07-30 04:47:46 -07:00
|
|
|
|
KUBELET_LOG_FORMAT=${KUBELET_LOG_FORMAT:-$CLUSTER_LOG_FORMAT}
|
|
|
|
|
|
if [ -n "$KUBELET_LOG_FORMAT" ]; then
|
|
|
|
|
|
check_structured_log_support "KUBECTL_LOG_FORMAT"
|
|
|
|
|
|
kubelet_extra_args="${kubelet_extra_args}
|
|
|
|
|
|
\"logging-format\": \"${KUBELET_LOG_FORMAT}\""
|
|
|
|
|
|
fi
|
2021-07-20 14:45:31 +05:30
|
|
|
|
|
2022-12-14 15:28:23 +01:00
|
|
|
|
# JSON or YAML map injected into featureGates config
|
|
|
|
|
|
feature_gates="${FEATURE_GATES:-{\}}"
|
|
|
|
|
|
# --runtime-config argument value passed to the API server, again as a map
|
|
|
|
|
|
runtime_config="${RUNTIME_CONFIG:-{\}}"
|
2020-03-01 03:00:16 +00:00
|
|
|
|
|
2019-10-01 10:01:16 -07:00
|
|
|
|
# create the config file
|
|
|
|
|
|
cat <<EOF > "${ARTIFACTS}/kind-config.yaml"
|
|
|
|
|
|
# config for 1 control plane node and 2 workers (necessary for conformance)
|
|
|
|
|
|
kind: Cluster
|
2020-03-01 03:00:16 +00:00
|
|
|
|
apiVersion: kind.x-k8s.io/v1alpha4
|
2019-10-01 10:01:16 -07:00
|
|
|
|
networking:
|
|
|
|
|
|
ipFamily: ${IP_FAMILY:-ipv4}
|
2020-10-06 09:48:12 +02:00
|
|
|
|
kubeProxyMode: ${KUBE_PROXY_MODE:-iptables}
|
2023-04-18 13:02:12 -07:00
|
|
|
|
# don't pass through host search paths
|
|
|
|
|
|
# TODO: possibly a reasonable default in the future for kind ...
|
|
|
|
|
|
dnsSearch: []
|
2019-10-01 10:01:16 -07:00
|
|
|
|
nodes:
|
|
|
|
|
|
- role: control-plane
|
|
|
|
|
|
- role: worker
|
|
|
|
|
|
- role: worker
|
2020-03-01 03:00:16 +00:00
|
|
|
|
featureGates: ${feature_gates}
|
2020-08-26 15:20:24 -07:00
|
|
|
|
runtimeConfig: ${runtime_config}
|
2020-03-01 03:00:16 +00:00
|
|
|
|
kubeadmConfigPatches:
|
|
|
|
|
|
- |
|
|
|
|
|
|
kind: ClusterConfiguration
|
|
|
|
|
|
metadata:
|
|
|
|
|
|
name: config
|
|
|
|
|
|
apiServer:
|
|
|
|
|
|
extraArgs:
|
2021-07-25 06:20:27 -07:00
|
|
|
|
${apiServer_extra_args}
|
2020-07-25 23:50:54 +02:00
|
|
|
|
controllerManager:
|
|
|
|
|
|
extraArgs:
|
2021-07-25 06:20:27 -07:00
|
|
|
|
${controllerManager_extra_args}
|
2020-07-25 23:50:54 +02:00
|
|
|
|
scheduler:
|
|
|
|
|
|
extraArgs:
|
2021-07-20 14:45:31 +05:30
|
|
|
|
${scheduler_extra_args}
|
2020-07-25 23:50:54 +02:00
|
|
|
|
---
|
|
|
|
|
|
kind: InitConfiguration
|
|
|
|
|
|
nodeRegistration:
|
|
|
|
|
|
kubeletExtraArgs:
|
2021-03-19 16:08:15 -07:00
|
|
|
|
${kubelet_extra_args}
|
2020-07-25 23:50:54 +02:00
|
|
|
|
---
|
|
|
|
|
|
kind: JoinConfiguration
|
|
|
|
|
|
nodeRegistration:
|
|
|
|
|
|
kubeletExtraArgs:
|
2021-03-19 16:08:15 -07:00
|
|
|
|
${kubelet_extra_args}
|
2019-10-01 10:01:16 -07:00
|
|
|
|
EOF
|
2019-10-01 10:15:08 -07:00
|
|
|
|
# NOTE: must match the number of workers above
|
|
|
|
|
|
NUM_NODES=2
|
2019-10-01 10:01:16 -07:00
|
|
|
|
# actually create the cluster
|
|
|
|
|
|
# TODO(BenTheElder): settle on verbosity for this script
|
2019-10-02 21:10:14 -07:00
|
|
|
|
KIND_CREATE_ATTEMPTED=true
|
2019-10-01 10:01:16 -07:00
|
|
|
|
kind create cluster \
|
|
|
|
|
|
--image=kindest/node:latest \
|
|
|
|
|
|
--retain \
|
|
|
|
|
|
--wait=1m \
|
|
|
|
|
|
-v=3 \
|
|
|
|
|
|
"--config=${ARTIFACTS}/kind-config.yaml"
|
2020-07-25 23:50:54 +02:00
|
|
|
|
|
2023-01-31 14:39:54 -05:00
|
|
|
|
# debug cluster version
|
|
|
|
|
|
kubectl version
|
|
|
|
|
|
|
2020-07-25 23:50:54 +02:00
|
|
|
|
# Patch kube-proxy to set the verbosity level
|
|
|
|
|
|
kubectl patch -n kube-system daemonset/kube-proxy \
|
2020-07-28 13:03:08 -07:00
|
|
|
|
--type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/command/-", "value": "--v='"${KIND_CLUSTER_LOG_LEVEL}"'" }]'
|
2019-10-01 10:01:16 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# run e2es with ginkgo-e2e.sh
|
|
|
|
|
|
run_tests() {
|
|
|
|
|
|
# IPv6 clusters need some CoreDNS changes in order to work in k8s CI:
|
|
|
|
|
|
# 1. k8s CI doesn´t offer IPv6 connectivity, so CoreDNS should be configured
|
|
|
|
|
|
# to work in an offline environment:
|
|
|
|
|
|
# https://github.com/coredns/coredns/issues/2494#issuecomment-457215452
|
|
|
|
|
|
# 2. k8s CI adds following domains to resolv.conf search field:
|
|
|
|
|
|
# c.k8s-prow-builds.internal google.internal.
|
|
|
|
|
|
# CoreDNS should handle those domains and answer with NXDOMAIN instead of SERVFAIL
|
|
|
|
|
|
# otherwise pods stops trying to resolve the domain.
|
|
|
|
|
|
if [ "${IP_FAMILY:-ipv4}" = "ipv6" ]; then
|
|
|
|
|
|
# Get the current config
|
|
|
|
|
|
original_coredns=$(kubectl get -oyaml -n=kube-system configmap/coredns)
|
|
|
|
|
|
echo "Original CoreDNS config:"
|
|
|
|
|
|
echo "${original_coredns}"
|
|
|
|
|
|
# Patch it
|
|
|
|
|
|
fixed_coredns=$(
|
|
|
|
|
|
printf '%s' "${original_coredns}" | sed \
|
|
|
|
|
|
-e 's/^.*kubernetes cluster\.local/& internal/' \
|
|
|
|
|
|
-e '/^.*upstream$/d' \
|
|
|
|
|
|
-e '/^.*fallthrough.*$/d' \
|
|
|
|
|
|
-e '/^.*forward . \/etc\/resolv.conf$/d' \
|
|
|
|
|
|
-e '/^.*loop$/d' \
|
|
|
|
|
|
)
|
|
|
|
|
|
echo "Patched CoreDNS config:"
|
|
|
|
|
|
echo "${fixed_coredns}"
|
|
|
|
|
|
printf '%s' "${fixed_coredns}" | kubectl apply -f -
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
2024-04-16 17:05:19 +02:00
|
|
|
|
# ginkgo regexes and label filter
|
2019-10-01 10:01:16 -07:00
|
|
|
|
SKIP="${SKIP:-}"
|
2024-04-16 17:05:19 +02:00
|
|
|
|
FOCUS="${FOCUS:-}"
|
|
|
|
|
|
LABEL_FILTER="${LABEL_FILTER:-}"
|
|
|
|
|
|
if [ -z "${FOCUS}" ] && [ -z "${LABEL_FILTER}" ]; then
|
|
|
|
|
|
FOCUS="\\[Conformance\\]"
|
|
|
|
|
|
fi
|
2019-10-01 10:01:16 -07:00
|
|
|
|
# if we set PARALLEL=true, skip serial tests set --ginkgo-parallel
|
|
|
|
|
|
if [ "${PARALLEL:-false}" = "true" ]; then
|
|
|
|
|
|
export GINKGO_PARALLEL=y
|
|
|
|
|
|
if [ -z "${SKIP}" ]; then
|
|
|
|
|
|
SKIP="\\[Serial\\]"
|
|
|
|
|
|
else
|
|
|
|
|
|
SKIP="\\[Serial\\]|${SKIP}"
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# setting this env prevents ginkgo e2e from trying to run provider setup
|
2019-10-07 16:55:16 -07:00
|
|
|
|
export KUBERNETES_CONFORMANCE_TEST='y'
|
2019-12-14 12:56:30 -08:00
|
|
|
|
# setting these is required to make RuntimeClass tests work ... :/
|
2019-10-02 22:44:41 -07:00
|
|
|
|
export KUBE_CONTAINER_RUNTIME=remote
|
|
|
|
|
|
export KUBE_CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock
|
|
|
|
|
|
export KUBE_CONTAINER_RUNTIME_NAME=containerd
|
2020-05-30 09:03:41 -07:00
|
|
|
|
# ginkgo can take forever to exit, so we run it in the background and save the
|
|
|
|
|
|
# PID, bash will not run traps while waiting on a process, but it will while
|
|
|
|
|
|
# running a builtin like `wait`, saving the PID also allows us to forward the
|
|
|
|
|
|
# interrupt
|
2019-10-01 10:01:16 -07:00
|
|
|
|
./hack/ginkgo-e2e.sh \
|
|
|
|
|
|
'--provider=skeleton' "--num-nodes=${NUM_NODES}" \
|
2024-04-16 17:05:19 +02:00
|
|
|
|
"--ginkgo.focus=${FOCUS}" "--ginkgo.skip=${SKIP}" "--ginkgo.label-filter=${LABEL_FILTER}" \
|
2020-05-30 09:03:41 -07:00
|
|
|
|
"--report-dir=${ARTIFACTS}" '--disable-log-dump=true' &
|
|
|
|
|
|
GINKGO_PID=$!
|
|
|
|
|
|
wait "$GINKGO_PID"
|
2019-10-01 10:01:16 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
main() {
|
|
|
|
|
|
# create temp dir and setup cleanup
|
|
|
|
|
|
TMP_DIR=$(mktemp -d)
|
|
|
|
|
|
|
|
|
|
|
|
# ensure artifacts (results) directory exists when not in CI
|
|
|
|
|
|
export ARTIFACTS="${ARTIFACTS:-${PWD}/_artifacts}"
|
|
|
|
|
|
mkdir -p "${ARTIFACTS}"
|
|
|
|
|
|
|
2019-10-30 11:03:16 -07:00
|
|
|
|
# export the KUBECONFIG to a unique path for testing
|
|
|
|
|
|
KUBECONFIG="${HOME}/.kube/kind-test-config"
|
|
|
|
|
|
export KUBECONFIG
|
|
|
|
|
|
echo "exported KUBECONFIG=${KUBECONFIG}"
|
|
|
|
|
|
|
2019-10-21 16:10:37 -07:00
|
|
|
|
# debug kind version
|
|
|
|
|
|
kind version
|
|
|
|
|
|
|
2019-10-01 10:01:16 -07:00
|
|
|
|
# build kubernetes
|
2021-03-15 22:32:25 -07:00
|
|
|
|
build
|
2019-10-01 10:01:16 -07:00
|
|
|
|
# in CI attempt to release some memory after building
|
2019-10-01 10:47:37 -07:00
|
|
|
|
if [ -n "${KUBETEST_IN_DOCKER:-}" ]; then
|
2019-10-01 10:01:16 -07:00
|
|
|
|
sync || true
|
|
|
|
|
|
echo 1 > /proc/sys/vm/drop_caches || true
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# create the cluster and run tests
|
2020-05-30 09:44:57 -07:00
|
|
|
|
res=0
|
|
|
|
|
|
create_cluster || res=$?
|
|
|
|
|
|
run_tests || res=$?
|
|
|
|
|
|
cleanup || res=$?
|
|
|
|
|
|
exit $res
|
2019-10-01 10:01:16 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
main
|