blob: 7dc080fb91c23cdf71a025bc61c4f98e54256dfb [file]
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# Generates cloud-config files, loads the CCM image into kind, deploys
# deployment.yaml and waits until all nodes are initialized.
set -euo pipefail
source "$(dirname "${BASH_SOURCE[0]}")/env.sh"
source "${E2E_ROOT}/lib/log.sh"
# shellcheck source=/dev/null
source "${E2E_OUT}/keys.env" 2>/dev/null || die "missing ${E2E_OUT}/keys.env — run 10-simulator-up.sh first"
# The CCM pod must reach the simulator via its IP on the shared docker
# network: pods cannot resolve docker's embedded DNS, and host.docker.internal
# does not exist on Linux.
sim_ip="$(docker inspect -f "{{(index .NetworkSettings.Networks \"${E2E_NET}\").IPAddress}}" "$SIM_NAME")"
[[ -n "$sim_ip" ]] || die "could not determine simulator IP on ${E2E_NET}"
# PROJECT_ID is optional; 50-topology-vpc.sh re-runs this script with it set.
project_line=""
if [[ -n "${E2E_PROJECT_ID:-}" ]]; then
project_line="project-id = ${E2E_PROJECT_ID}"
fi
# In-cluster and host-process configs differ only in api-url.
cat >"${E2E_OUT}/cloud-config" <<EOF
[Global]
api-url = http://${sim_ip}:8080/client/api
api-key = ${CS_API_KEY}
secret-key = ${CS_SECRET_KEY}
zone = ${ZONE_NAME}
region = ${E2E_REGION}
${project_line}
EOF
sed "s|http://${sim_ip}:8080|http://localhost:${SIM_HOST_PORT}|" \
"${E2E_OUT}/cloud-config" >"${E2E_OUT}/cloud-config-host"
chmod 600 "${E2E_OUT}/cloud-config" "${E2E_OUT}/cloud-config-host"
# Rebuild unless the image was supplied from outside. Reusing whatever happens to
# carry the tag would silently test a stale binary after the checkout changes.
if [[ "$CCM_IMAGE_PREBUILT" == "true" ]]; then
docker image inspect "$CCM_IMAGE" >/dev/null 2>&1 ||
die "CCM_IMAGE_PREBUILT=true but ${CCM_IMAGE} is not loaded"
log "using prebuilt ${CCM_IMAGE}"
else
log "building ${CCM_IMAGE} from ${REPO_ROOT}"
docker build -t "$CCM_IMAGE" "$REPO_ROOT"
fi
kind load docker-image "$CCM_IMAGE" --name "$KIND_CLUSTER"
kubectl -n kube-system create secret generic cloudstack-secret \
--from-file=cloud-config="${E2E_OUT}/cloud-config" \
--dry-run=client -o yaml | kubectl apply -f -
# Adjust the stock manifest for e2e before applying it: local image, no leader
# election (single replica, faster startup), verbose logs, and enough CPU that
# informer startup is not throttled on shared runners. Applying it unchanged
# first would start the released image, which can keep running for its whole
# 30s grace period and reconcile the test Services next to the build under test.
kubectl create --dry-run=client -o json -f "${REPO_ROOT}/deployment.yaml" |
jq -s --arg image "$CCM_IMAGE" '{apiVersion: "v1", kind: "List", items: map(
if .kind != "Deployment" then . else
.spec.template.spec.containers[0] |= (
.image = $image
| .imagePullPolicy = "Never"
| .args = ["--cloud-provider=external-cloudstack", "--cloud-config=/config/cloud-config",
"--leader-elect=false", "--v=4"]
| .resources = {requests: {cpu: "100m", memory: "128Mi"}, limits: {cpu: "1", memory: "512Mi"}})
end)}' |
kubectl apply -f -
kubectl -n kube-system rollout status deployment/cloud-controller-manager --timeout=180s
nodes_initialized() {
local taints
taints="$(kubectl get nodes -o jsonpath='{.items[*].spec.taints[?(@.key=="node.cloudprovider.kubernetes.io/uninitialized")].key}')"
[[ -z "$taints" ]]
}
# If this times out, check the CCM log for
# 'provided node ip for node ... is not valid': it means the CloudStack VM's
# NIC IP does not match the kind node's docker IP.
wait_for 300 5 "all nodes initialized by the CCM" nodes_initialized
log "CCM deployed and all nodes initialized"
kubectl get nodes -o wide >&2