From 783680f350eb06d49a530f5b87e508a01321f5ee Mon Sep 17 00:00:00 2001 From: Brad House Date: Fri, 6 Nov 2026 21:17:59 +0000 Subject: [PATCH] CKS: fix the add-on scripts' download and option handling deploy-csi-driver falls back to downloading the CSI manifests when the node has no copy from the binaries ISO. Its download loop applied both files and exited after fetching only the first: for url in "${CSI_URLS[@]}"; do curl -sSL ${url} -o ${TARGET_DIR}/${filename} ... else kubectl apply -f /opt/csi/snapshot-crds.yaml kubectl apply -f /opt/csi/manifest.yaml # never downloaded exit 0 so manifest.yaml was never fetched and the apply always failed. The snapshot-crds.yaml it did leave behind then sent every later run down the "files already present" branch, which failed the same way. - deploy-csi-driver: download every file, then apply them the way the ISO path does (CRDs, wait, manifest). Treat the files as present only when both are there, so a node left with only snapshot-crds.yaml downloads again. deploy-csi-driver, deploy-provider and autoscale-kube-cluster also called curl without -f, so an HTTP error (a moved or missing URL) was saved as the manifest and applied, and the next run applied the saved file again instead of downloading. Their "$? -ne 0" checks could not report anything either: the scripts run under bash -e, so a failing curl ended the script before the check. - Use "curl -fsSL" inside the if, and download to a per-run temporary file (removed by an EXIT trap) that is moved into place only once it is complete, so a failed or interrupted download leaves no file that a later run would apply. autoscale-kube-cluster listed its disable option as "-d | --enable", so "--disable" was rejected as an unknown option ("-d" worked). Run with neither option, the unquoted [ $ENABLE == "true" ] failed with "unary operator expected" and fell through to deleting the autoscaler. Disable also failed when there was no autoscaler deployment to delete, so autoscaling could not be turned off after a failed enable. - Accept "--disable", quote the test, and refuse to run with neither -e nor -d. CloudStack always passes one of them, so its calls are unaffected. - Delete the deployment with --ignore-not-found. Signed-off-by: Brad House --- .../resources/script/autoscale-kube-cluster | 22 +++++++++++-------- .../main/resources/script/deploy-csi-driver | 15 +++++++------ .../src/main/resources/script/deploy-provider | 10 ++++----- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/plugins/integrations/kubernetes-service/src/main/resources/script/autoscale-kube-cluster b/plugins/integrations/kubernetes-service/src/main/resources/script/autoscale-kube-cluster index ac3fd8eab4ce..692815f3d09f 100755 --- a/plugins/integrations/kubernetes-service/src/main/resources/script/autoscale-kube-cluster +++ b/plugins/integrations/kubernetes-service/src/main/resources/script/autoscale-kube-cluster @@ -51,7 +51,7 @@ while [ -n "$1" ]; do ENABLE="true" shift 1 ;; - -d | --enable) + -d | --disable) ENABLE="false" shift 1 ;; @@ -69,7 +69,11 @@ while [ -n "$1" ]; do ;; esac done -if [ $ENABLE == "true" ] ; then +if [ -z "$ENABLE" ]; then + echo "ERROR: one of -e/--enable or -d/--disable is required. -h or --help for help" + exit 1 +fi +if [ "$ENABLE" == "true" ] ; then if [ -e /opt/autoscaler/autoscaler_tmpl.yaml ]; then sed -e "s//$ID/g" -e "s//$MINSIZE/g" -e "s//$MAXSIZE/g" /opt/autoscaler/autoscaler_tmpl.yaml > /opt/autoscaler/autoscaler_now.yaml /opt/bin/kubectl apply -f /opt/autoscaler/autoscaler_now.yaml @@ -78,16 +82,16 @@ if [ $ENABLE == "true" ] ; then mkdir -p /opt/autoscaler AUTOSCALER_URL="https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/cloudstack/examples/cluster-autoscaler-standard.yaml" autoscaler_conf_file="/opt/autoscaler/autoscaler_tmpl.yaml" - curl -sSL ${AUTOSCALER_URL} -o ${autoscaler_conf_file} - if [ $? -ne 0 ]; then + trap 'rm -f "$autoscaler_conf_file.tmp.$$"' EXIT + if ! curl -fsSL "$AUTOSCALER_URL" -o "$autoscaler_conf_file.tmp.$$"; then echo "Unable to connect to the internet to download the autoscaler deployment and image" exit 1 - else - sed -e "s//$ID/g" -e "s//$MINSIZE/g" -e "s//$MAXSIZE/g" /opt/autoscaler/autoscaler_tmpl.yaml > /opt/autoscaler/autoscaler_now.yaml - /opt/bin/kubectl apply -f /opt/autoscaler/autoscaler_now.yaml - exit 0 fi + mv -f "$autoscaler_conf_file.tmp.$$" "$autoscaler_conf_file" + sed -e "s//$ID/g" -e "s//$MINSIZE/g" -e "s//$MAXSIZE/g" /opt/autoscaler/autoscaler_tmpl.yaml > /opt/autoscaler/autoscaler_now.yaml + /opt/bin/kubectl apply -f /opt/autoscaler/autoscaler_now.yaml + exit 0 fi else - /opt/bin/kubectl delete deployment -n kube-system cluster-autoscaler + /opt/bin/kubectl delete deployment -n kube-system cluster-autoscaler --ignore-not-found fi diff --git a/plugins/integrations/kubernetes-service/src/main/resources/script/deploy-csi-driver b/plugins/integrations/kubernetes-service/src/main/resources/script/deploy-csi-driver index 69684fa32bd5..ac531d16fcd0 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/script/deploy-csi-driver +++ b/plugins/integrations/kubernetes-service/src/main/resources/script/deploy-csi-driver @@ -18,7 +18,7 @@ (/opt/bin/kubectl get pods -A | grep cloudstack-csi-controller) && exit 0 -if [ -e /opt/csi/snapshot-crds.yaml ]; then +if [ -e /opt/csi/snapshot-crds.yaml ] && [ -e /opt/csi/manifest.yaml ]; then /opt/bin/kubectl apply -f /opt/csi/snapshot-crds.yaml sleep 5 /opt/bin/kubectl apply -f /opt/csi/manifest.yaml @@ -30,17 +30,18 @@ else "https://github.com/cloudstack/cloudstack-csi-driver/releases/download/v3.0.0/snapshot-crds.yaml" "https://github.com/cloudstack/cloudstack-csi-driver/releases/download/v3.0.0/manifest.yaml" ) + trap 'rm -f "$TARGET_DIR"/*.tmp.$$' EXIT for url in "${CSI_URLS[@]}"; do filename=$(basename "$url") - curl -sSL ${url} -o ${TARGET_DIR}/${filename} - if [ $? -ne 0 ]; then + if ! curl -fsSL "$url" -o "$TARGET_DIR/$filename.tmp.$$"; then echo "Unable to connect to the internet to download the relevant files to install and setup CloudStack CSI driver" exit 1 - else - /opt/bin/kubectl apply -f /opt/csi/snapshot-crds.yaml - /opt/bin/kubectl apply -f /opt/csi/manifest.yaml - exit 0 fi + mv -f "$TARGET_DIR/$filename.tmp.$$" "$TARGET_DIR/$filename" done + /opt/bin/kubectl apply -f /opt/csi/snapshot-crds.yaml + sleep 5 + /opt/bin/kubectl apply -f /opt/csi/manifest.yaml + exit 0 fi diff --git a/plugins/integrations/kubernetes-service/src/main/resources/script/deploy-provider b/plugins/integrations/kubernetes-service/src/main/resources/script/deploy-provider index ce71e21072b6..df884eba7d46 100755 --- a/plugins/integrations/kubernetes-service/src/main/resources/script/deploy-provider +++ b/plugins/integrations/kubernetes-service/src/main/resources/script/deploy-provider @@ -25,12 +25,12 @@ else mkdir -p /opt/provider PROVIDER_URL="https://raw.githubusercontent.com/apache/cloudstack-kubernetes-provider/main/deployment.yaml" provider_conf_file="/opt/provider/provider.yaml" - curl -sSL ${PROVIDER_URL} -o ${provider_conf_file} - if [ $? -ne 0 ]; then + trap 'rm -f "$provider_conf_file.tmp.$$"' EXIT + if ! curl -fsSL "$PROVIDER_URL" -o "$provider_conf_file.tmp.$$"; then echo "Unable to connect to the internet to download the provider deployment and image" exit 1 - else - /opt/bin/kubectl apply -f /opt/provider/provider.yaml - exit 0 fi + mv -f "$provider_conf_file.tmp.$$" "$provider_conf_file" + /opt/bin/kubectl apply -f /opt/provider/provider.yaml + exit 0 fi