diff --git a/tests/scripts/stub/kubectl b/tests/scripts/stub/kubectl index 4859f10..3670464 100755 --- a/tests/scripts/stub/kubectl +++ b/tests/scripts/stub/kubectl @@ -25,6 +25,17 @@ done case "$args" in *" get crd helmcharts.helm.cattle.io "*) ;; + *" crd/"*) + if [ -s "$WORK_DIR/crds-appear-after" ]; then + left="$(cat "$WORK_DIR/crds-appear-after")" + echo $((left - 1)) >"$WORK_DIR/crds-appear-after" + if [ "$left" -gt 0 ]; then + crd="$(printf '%s' "$args" | sed -n 's#.* crd/\([^ ]*\).*#\1#p')" + echo "Error from server (NotFound): customresourcedefinitions.apiextensions.k8s.io \"$crd\" not found" >&2 + exit 1 + fi + fi + ;; *" apply --server-side "*) if [ -n "$file" ]; then cat "$file" >>"$WORK_DIR/server-side-applied"; fi ;; *" apply -f - "*) cat >"$WORK_DIR/applied" ;; *" get service traefik "*'{.spec.type}'*) diff --git a/tests/scripts/traefik_install_test.sh b/tests/scripts/traefik_install_test.sh index 379f038..b6dda4f 100644 --- a/tests/scripts/traefik_install_test.sh +++ b/tests/scripts/traefik_install_test.sh @@ -436,6 +436,13 @@ test_traefik_already_on_the_image_pulls_nothing() { assert_not_contains "$(cat "$WORK_DIR/calls")" "run traefik-pull" } +test_gateway_api_crds_k3s_has_yet_to_create_are_waited_for() { + echo helmchart.helm.cattle.io/gateway-api-crd >"$WORK_DIR/helmcharts-gateway-api-crd" + echo 1 >"$WORK_DIR/crds-appear-after" + run_install install_traefik + assert_contains "$(cat "$WORK_DIR/calls")" "wait --for=condition=Established crd/gatewayclasses.gateway.networking.k8s.io" +} + test_a_first_install_pulls_nothing() { run_install install_traefik assert_not_contains "$(cat "$WORK_DIR/calls")" "run traefik-pull" diff --git a/utils/install_traefik.sh b/utils/install_traefik.sh index 7d848a9..3ea8a96 100644 --- a/utils/install_traefik.sh +++ b/utils/install_traefik.sh @@ -39,7 +39,7 @@ carry_over_ingress_nginx_ports() { install_traefik() { local ports_env="${1:-$PANEL_DIR/overlays/config/traefik-config.env}" - local minor http_port https_port crd binding nginx crds_values left_out held object + local minor http_port https_port crd binding nginx crds_values left_out held object deadline local -a kc=() handed=() [ -n "${KUBECONFIG:-}" ] && kc=(--kubeconfig="$KUBECONFIG") @@ -94,8 +94,18 @@ install_traefik() { meta.helm.sh/release-name=gateway-api-crd meta.helm.sh/release-namespace=kube-system || return 1 fi + # k3s's gateway-api-crd release can still be on its way, and kubectl wait + # gives up at once on a CRD that doesn't exist yet. + deadline=$((SECONDS + 300)) for crd in gatewayclasses.gateway.networking.k8s.io gateways.gateway.networking.k8s.io \ httproutes.gateway.networking.k8s.io middlewares.traefik.io; do + until kubectl "${kc[@]}" get "crd/$crd" >/dev/null 2>&1; do + if [ "$SECONDS" -ge "$deadline" ]; then + err "CRD $crd was never created" + return 1 + fi + sleep 2 + done if ! output_redirect kubectl "${kc[@]}" wait --for=condition=Established "crd/$crd" --timeout=120s; then err "CRD $crd never became established" return 1