Skip to content

Commit 2d31297

Browse files
committed
e2e: add upgrade test for gossip
1 parent 8c31a41 commit 2d31297

4 files changed

Lines changed: 216 additions & 144 deletions

File tree

tests/e2e/kubetest2-kops/deployer/common.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,13 @@ func (d *deployer) defaultClusterName() (string, error) {
389389
suffix = dnsDomain
390390
}
391391
case "azure":
392-
// Azure uses --dns=none and the domain is not needed
393-
suffix = ""
392+
// Default --dns=none; opt into gossip via a k8s.local KOPS_DNS_DOMAIN.
393+
domain := os.Getenv("KOPS_DNS_DOMAIN")
394+
if domain == "k8s.local" || strings.HasSuffix(domain, ".k8s.local") {
395+
suffix = dnsDomain
396+
} else {
397+
suffix = ""
398+
}
394399
default:
395400
suffix = "k8s.local"
396401
}

tests/e2e/scenarios/lib/upgrade.sh

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2026 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+
# kops-upgrade runs an A->B kops upgrade test. Source after lib/common.sh.
18+
# Caller passes the create-args string; sets KOPS_VERSION_{A,B} and K8S_VERSION_{A,B}.
19+
function kops-upgrade() {
20+
local create_args="$1"
21+
22+
if [ -z "${KOPS_VERSION_A-}" ] || [ -z "${K8S_VERSION_A-}" ] || [ -z "${KOPS_VERSION_B-}" ] || [ -z "${K8S_VERSION_B-}" ]; then
23+
>&2 echo "must set all of KOPS_VERSION_A, K8S_VERSION_A, KOPS_VERSION_B, K8S_VERSION_B env vars"
24+
exit 1
25+
fi
26+
27+
TEST_PACKAGE_VERSION="${K8S_VERSION_B}"
28+
29+
if [[ "$K8S_VERSION_A" == "latest" ]]; then
30+
K8S_VERSION_A=$(curl -L https://dl.k8s.io/release/latest.txt)
31+
fi
32+
if [[ "$K8S_VERSION_B" == "latest" ]]; then
33+
K8S_VERSION_B=$(curl -L https://dl.k8s.io/release/latest.txt)
34+
TEST_PACKAGE_MARKER="latest.txt"
35+
fi
36+
if [[ "$K8S_VERSION_A" == "stable" ]]; then
37+
K8S_VERSION_A=$(curl -L https://dl.k8s.io/release/stable.txt)
38+
fi
39+
if [[ "$K8S_VERSION_B" == "stable" ]]; then
40+
K8S_VERSION_B=$(curl -L https://dl.k8s.io/release/stable.txt)
41+
TEST_PACKAGE_MARKER="stable.txt"
42+
fi
43+
if [[ "$K8S_VERSION_A" == "ci" ]]; then
44+
K8S_VERSION_A=https://storage.googleapis.com/k8s-release-dev/ci/$(curl https://storage.googleapis.com/k8s-release-dev/ci/latest.txt)
45+
fi
46+
if [[ "$K8S_VERSION_B" == "ci" ]]; then
47+
K8S_VERSION_B=https://storage.googleapis.com/k8s-release-dev/ci/$(curl https://storage.googleapis.com/k8s-release-dev/ci/latest.txt)
48+
TEST_PACKAGE_MARKER="latest.txt"
49+
TEST_PACKAGE_DIR="ci"
50+
TEST_PACKAGE_URL="https://storage.googleapis.com/k8s-release-dev"
51+
fi
52+
53+
export KOPS_BASE_URL
54+
55+
echo "Cleaning up any leaked resources from previous cluster"
56+
# For KOPS_VERSION_B, the value "latest" means build of the tree
57+
if [[ "${KOPS_VERSION_B}" == "latest" ]]; then
58+
kops-acquire-latest
59+
KOPS_BASE_URL_B="${KOPS_BASE_URL}"
60+
KOPS_B="${KOPS}"
61+
else
62+
KOPS_BASE_URL=$(kops-base-from-marker "${KOPS_VERSION_B}")
63+
KOPS_BASE_URL_B="${KOPS_BASE_URL}"
64+
KOPS_B=$(kops-download-from-base)
65+
CHANNELS=$(kops-channels-download-from-base)
66+
fi
67+
68+
${KUBETEST2} \
69+
--down \
70+
--kops-binary-path="${KOPS_B}" || echo "kubetest2 down failed"
71+
72+
# First kOps version may be a released version. If so, it is prefixed with v
73+
if [[ "${KOPS_VERSION_A:0:1}" == "v" ]]; then
74+
KOPS_BASE_URL=""
75+
KOPS_A=$(kops-download-release "$KOPS_VERSION_A")
76+
KOPS="${KOPS_A}"
77+
else
78+
KOPS_BASE_URL=$(kops-base-from-marker "${KOPS_VERSION_A}")
79+
KOPS_A=$(kops-download-from-base)
80+
KOPS="${KOPS_A}"
81+
fi
82+
83+
# TODO: Switch scripts to use KOPS_CONTROL_PLANE_COUNT
84+
if [[ -n "${KOPS_CONTROL_PLANE_SIZE:-}" ]]; then
85+
echo "Recognized (deprecated) KOPS_CONTROL_PLANE_SIZE=${KOPS_CONTROL_PLANE_SIZE}, please set KOPS_CONTROL_PLANE_COUNT instead"
86+
KOPS_CONTROL_PLANE_COUNT=${KOPS_CONTROL_PLANE_SIZE}
87+
fi
88+
89+
# Note that we use --control-plane-size, even though it is deprecated, because we have to support old versions
90+
# in the upgrade test.
91+
${KUBETEST2} \
92+
--up \
93+
--env-file="${WORKSPACE}/env" \
94+
--kops-binary-path="${KOPS_A}" \
95+
--kubernetes-version="${K8S_VERSION_A}" \
96+
--control-plane-size="${KOPS_CONTROL_PLANE_COUNT:-1}" \
97+
--template-path="${KOPS_TEMPLATE:-}" \
98+
--create-args="${create_args}"
99+
100+
# Source the env file to get exported variables, in particular CLUSTER_NAME and KOPS_STATE_STORE
101+
# shellcheck disable=SC1091
102+
. "${WORKSPACE}/env"
103+
export CLUSTER_NAME KOPS_STATE_STORE
104+
105+
# Export kubeconfig-a
106+
KUBECONFIG_A=$(mktemp -t kops.XXXXXXXXX)
107+
"${KOPS_A}" export kubecfg --name "${CLUSTER_NAME}" --admin --kubeconfig "${KUBECONFIG_A}"
108+
109+
# Verify kubeconfig-a
110+
kubectl get nodes -owide --kubeconfig="${KUBECONFIG_A}"
111+
112+
KOPS_BASE_URL="${KOPS_BASE_URL_B}"
113+
114+
KOPS="${KOPS_B}"
115+
116+
"${KOPS_B}" edit cluster "${CLUSTER_NAME}" "--set=cluster.spec.kubernetesVersion=${K8S_VERSION_B}"
117+
118+
# Preview changes
119+
"${KOPS_B}" reconcile cluster --allow-kops-downgrade
120+
121+
# Apply changes
122+
"${KOPS_B}" reconcile cluster --allow-kops-downgrade --yes
123+
124+
# Verify no additional changes
125+
"${KOPS_B}" update cluster
126+
127+
"${KOPS_B}" validate cluster
128+
129+
# Verify kubeconfig-a still works
130+
kubectl get nodes -owide --kubeconfig="${KUBECONFIG_A}"
131+
132+
cp "${KOPS_B}" "${WORKSPACE}/kops"
133+
export PATH="${WORKSPACE}:${PATH}"
134+
135+
"${KOPS_B}" export kubecfg --name "${CLUSTER_NAME}" --admin
136+
137+
if [[ -n ${KOPS_SKIP_E2E:-} ]]; then
138+
return 0
139+
fi
140+
141+
local test_package_args="--parallel 25"
142+
143+
if [[ -n ${TEST_PACKAGE_MARKER-} ]]; then
144+
test_package_args+=" --test-package-marker=${TEST_PACKAGE_MARKER}"
145+
if [[ -n ${TEST_PACKAGE_DIR-} ]]; then
146+
test_package_args+=" --test-package-dir=${TEST_PACKAGE_DIR-}"
147+
fi
148+
if [[ -n ${TEST_PACKAGE_BUCKET-} ]]; then
149+
test_package_args+=" --test-package-url=${TEST_PACKAGE_URL-}"
150+
fi
151+
else
152+
test_package_args+=" --test-package-version=${TEST_PACKAGE_VERSION}"
153+
fi
154+
155+
# shellcheck disable=SC2086
156+
${KUBETEST2} \
157+
--cloud-provider="${CLOUD_PROVIDER}" \
158+
--kops-binary-path="${KOPS}" \
159+
--test=kops \
160+
-- \
161+
$test_package_args \
162+
--parallel 25
163+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2026 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+
# Like upgrade-ab, but on a gossip cluster — exercises hybrid worker bootstrap (#18245).
18+
19+
REPO_ROOT=$(git rev-parse --show-toplevel);
20+
21+
# k8s.local suffix triggers gossip mode across all clouds.
22+
export KOPS_DNS_DOMAIN="${KOPS_DNS_DOMAIN:-k8s.local}"
23+
if [[ "${KOPS_DNS_DOMAIN}" != "k8s.local" && "${KOPS_DNS_DOMAIN}" != *.k8s.local ]]; then
24+
>&2 echo "KOPS_DNS_DOMAIN must be (or end in) k8s.local for gossip; got ${KOPS_DNS_DOMAIN}"
25+
exit 1
26+
fi
27+
28+
source "${REPO_ROOT}"/tests/e2e/scenarios/lib/common.sh
29+
source "${REPO_ROOT}"/tests/e2e/scenarios/lib/upgrade.sh
30+
31+
# Plain clusters only; the many-addons template is AWS-specific.
32+
unset KOPS_TEMPLATE
33+
34+
# Hybrid bootstrap (#18245) needs an NLB on AWS, any LB elsewhere.
35+
case "${CLOUD_PROVIDER}" in
36+
aws)
37+
lb_args="--api-loadbalancer-type=public --api-loadbalancer-class=network"
38+
;;
39+
*)
40+
lb_args="--api-loadbalancer-type=public"
41+
;;
42+
esac
43+
44+
kops-upgrade "--networking cilium --dns=private ${lb_args} ${KOPS_EXTRA_FLAGS:-}"

tests/e2e/scenarios/upgrade-ab/run-test.sh

Lines changed: 2 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -16,146 +16,6 @@
1616

1717
REPO_ROOT=$(git rev-parse --show-toplevel);
1818
source "${REPO_ROOT}"/tests/e2e/scenarios/lib/common.sh
19+
source "${REPO_ROOT}"/tests/e2e/scenarios/lib/upgrade.sh
1920

20-
if [ -z "${KOPS_VERSION_A-}" ] || [ -z "${K8S_VERSION_A-}" ] || [ -z "${KOPS_VERSION_B-}" ] || [ -z "${K8S_VERSION_B-}" ]; then
21-
>&2 echo "must set all of KOPS_VERSION_A, K8S_VERSION_A, KOPS_VERSION_B, K8S_VERSION_B env vars"
22-
exit 1
23-
fi
24-
25-
TEST_PACKAGE_VERSION="${K8S_VERSION_B}"
26-
27-
if [[ "$K8S_VERSION_A" == "latest" ]]; then
28-
K8S_VERSION_A=$(curl -L https://dl.k8s.io/release/latest.txt)
29-
fi
30-
if [[ "$K8S_VERSION_B" == "latest" ]]; then
31-
K8S_VERSION_B=$(curl -L https://dl.k8s.io/release/latest.txt)
32-
TEST_PACKAGE_MARKER="latest.txt"
33-
fi
34-
if [[ "$K8S_VERSION_A" == "stable" ]]; then
35-
K8S_VERSION_A=$(curl -L https://dl.k8s.io/release/stable.txt)
36-
fi
37-
if [[ "$K8S_VERSION_B" == "stable" ]]; then
38-
K8S_VERSION_B=$(curl -L https://dl.k8s.io/release/stable.txt)
39-
TEST_PACKAGE_MARKER="stable.txt"
40-
fi
41-
if [[ "$K8S_VERSION_A" == "ci" ]]; then
42-
K8S_VERSION_A=https://storage.googleapis.com/k8s-release-dev/ci/$(curl https://storage.googleapis.com/k8s-release-dev/ci/latest.txt)
43-
fi
44-
if [[ "$K8S_VERSION_B" == "ci" ]]; then
45-
K8S_VERSION_B=https://storage.googleapis.com/k8s-release-dev/ci/$(curl https://storage.googleapis.com/k8s-release-dev/ci/latest.txt)
46-
TEST_PACKAGE_MARKER="latest.txt"
47-
TEST_PACKAGE_DIR="ci"
48-
TEST_PACKAGE_URL="https://storage.googleapis.com/k8s-release-dev"
49-
fi
50-
51-
export KOPS_BASE_URL
52-
53-
echo "Cleaning up any leaked resources from previous cluster"
54-
# For KOPS_VERSION_B, the value "latest" means build of the tree
55-
if [[ "${KOPS_VERSION_B}" == "latest" ]]; then
56-
kops-acquire-latest
57-
KOPS_BASE_URL_B="${KOPS_BASE_URL}"
58-
KOPS_B="${KOPS}"
59-
else
60-
KOPS_BASE_URL=$(kops-base-from-marker "${KOPS_VERSION_B}")
61-
KOPS_BASE_URL_B="${KOPS_BASE_URL}"
62-
KOPS_B=$(kops-download-from-base)
63-
CHANNELS=$(kops-channels-download-from-base)
64-
fi
65-
66-
${KUBETEST2} \
67-
--down \
68-
--kops-binary-path="${KOPS_B}" || echo "kubetest2 down failed"
69-
70-
# First kOps version may be a released version. If so, it is prefixed with v
71-
if [[ "${KOPS_VERSION_A:0:1}" == "v" ]]; then
72-
KOPS_BASE_URL=""
73-
KOPS_A=$(kops-download-release "$KOPS_VERSION_A")
74-
KOPS="${KOPS_A}"
75-
else
76-
KOPS_BASE_URL=$(kops-base-from-marker "${KOPS_VERSION_A}")
77-
KOPS_A=$(kops-download-from-base)
78-
KOPS="${KOPS_A}"
79-
fi
80-
81-
# TODO: Switch scripts to use KOPS_CONTROL_PLANE_COUNT
82-
if [[ -n "${KOPS_CONTROL_PLANE_SIZE:-}" ]]; then
83-
echo "Recognized (deprecated) KOPS_CONTROL_PLANE_SIZE=${KOPS_CONTROL_PLANE_SIZE}, please set KOPS_CONTROL_PLANE_COUNT instead"
84-
KOPS_CONTROL_PLANE_COUNT=${KOPS_CONTROL_PLANE_SIZE}
85-
fi
86-
87-
# Note that we use --control-plane-size, even though it is deprecated, because we have to support old versions
88-
# in the upgrade test.
89-
${KUBETEST2} \
90-
--up \
91-
--env-file="${WORKSPACE}/env" \
92-
--kops-binary-path="${KOPS_A}" \
93-
--kubernetes-version="${K8S_VERSION_A}" \
94-
--control-plane-size="${KOPS_CONTROL_PLANE_COUNT:-1}" \
95-
--template-path="${KOPS_TEMPLATE:-}" \
96-
--create-args="--networking calico ${KOPS_EXTRA_FLAGS:-}"
97-
98-
# Source the env file to get exported variables, in particular CLUSTER_NAME and KOPS_STATE_STORE
99-
# shellcheck disable=SC1091
100-
. "${WORKSPACE}/env"
101-
export CLUSTER_NAME KOPS_STATE_STORE
102-
103-
# Export kubeconfig-a
104-
KUBECONFIG_A=$(mktemp -t kops.XXXXXXXXX)
105-
"${KOPS_A}" export kubecfg --name "${CLUSTER_NAME}" --admin --kubeconfig "${KUBECONFIG_A}"
106-
107-
# Verify kubeconfig-a
108-
kubectl get nodes -owide --kubeconfig="${KUBECONFIG_A}"
109-
110-
KOPS_BASE_URL="${KOPS_BASE_URL_B}"
111-
112-
KOPS="${KOPS_B}"
113-
114-
"${KOPS_B}" edit cluster "${CLUSTER_NAME}" "--set=cluster.spec.kubernetesVersion=${K8S_VERSION_B}"
115-
116-
# Preview changes
117-
"${KOPS_B}" reconcile cluster --allow-kops-downgrade
118-
119-
# Apply changes
120-
"${KOPS_B}" reconcile cluster --allow-kops-downgrade --yes
121-
122-
# Verify no additional changes
123-
"${KOPS_B}" update cluster
124-
125-
"${KOPS_B}" validate cluster
126-
127-
# Verify kubeconfig-a still works
128-
kubectl get nodes -owide --kubeconfig="${KUBECONFIG_A}"
129-
130-
cp "${KOPS_B}" "${WORKSPACE}/kops"
131-
export PATH="${WORKSPACE}:${PATH}"
132-
133-
"${KOPS_B}" export kubecfg --name "${CLUSTER_NAME}" --admin
134-
135-
if [[ -n ${KOPS_SKIP_E2E:-} ]]; then
136-
exit
137-
fi
138-
139-
140-
test_package_args="--parallel 25"
141-
142-
if [[ -n ${TEST_PACKAGE_MARKER-} ]]; then
143-
test_package_args+=" --test-package-marker=${TEST_PACKAGE_MARKER}"
144-
if [[ -n ${TEST_PACKAGE_DIR-} ]]; then
145-
test_package_args+=" --test-package-dir=${TEST_PACKAGE_DIR-}"
146-
fi
147-
if [[ -n ${TEST_PACKAGE_BUCKET-} ]]; then
148-
test_package_args+=" --test-package-url=${TEST_PACKAGE_URL-}"
149-
fi
150-
else
151-
test_package_args+=" --test-package-version=${TEST_PACKAGE_VERSION}"
152-
fi
153-
154-
# shellcheck disable=SC2086
155-
${KUBETEST2} \
156-
--cloud-provider="${CLOUD_PROVIDER}" \
157-
--kops-binary-path="${KOPS}" \
158-
--test=kops \
159-
-- \
160-
$test_package_args \
161-
--parallel 25
21+
kops-upgrade "--networking calico ${KOPS_EXTRA_FLAGS:-}"

0 commit comments

Comments
 (0)