diff --git a/scripts/lib/install-client-helm.sh b/scripts/lib/install-client-helm.sh index 423ef36..f1f5eb9 100644 --- a/scripts/lib/install-client-helm.sh +++ b/scripts/lib/install-client-helm.sh @@ -336,21 +336,21 @@ install_client_helm() { # decide. The same clientId is a normal re-run/upgrade and passes through. # Check ANY namespace: a fresh install lands in `tracebloc`, but an install # from an older installer version may be in a different namespace. Enumerate - # client-chart releases and read each clientId. jq is already used elsewhere - # in the installer; if it's somehow absent, fall back to the `tracebloc` ns. + # client-chart releases WITHOUT jq — jq is not a guaranteed prerequisite here, + # and a jq-only enumeration whose fallback checked a single namespace would miss + # an older release under the fixed `tracebloc` namespace once the minted slug + # differs, forking a second release. helm's NAME/NAMESPACE are the first two + # columns and never contain whitespace, and the CHART column matches + # `client-` — the same jq-free parse _chart_version uses. local existing_id="" existing_ns="" _gvf _rel _ns _id _gvf="$(mktemp)" - if has jq; then - while IFS=$'\t' read -r _rel _ns; do - [[ -z "$_rel" ]] && continue - if helm get values "$_rel" -n "$_ns" > "$_gvf" 2>/dev/null; then - _id="$(_extract_yaml_value "$_gvf" clientId)" - [[ -n "$_id" ]] && { existing_id="$_id"; existing_ns="$_ns"; break; } - fi - done < <(helm list -A -o json 2>/dev/null | jq -r '.[] | select((.chart // "") | startswith("client-")) | "\(.name)\t\(.namespace)"') - elif helm get values "$TB_NAMESPACE" -n "$TB_NAMESPACE" > "$_gvf" 2>/dev/null; then - existing_id="$(_extract_yaml_value "$_gvf" clientId)"; existing_ns="$TB_NAMESPACE" - fi + while read -r _rel _ns; do + [[ -z "$_rel" ]] && continue + if helm get values "$_rel" -n "$_ns" > "$_gvf" 2>/dev/null; then + _id="$(_extract_yaml_value "$_gvf" clientId)" + [[ -n "$_id" ]] && { existing_id="$_id"; existing_ns="$_ns"; break; } + fi + done < <(helm list -A 2>/dev/null | awk '/[[:space:]]client-[0-9]/ { print $1, $2 }') rm -f "$_gvf" if [[ -n "$existing_id" && "$existing_id" != "$TB_CLIENT_ID" ]]; then echo "" diff --git a/scripts/manifest.sha256 b/scripts/manifest.sha256 index e3886c5..f82394a 100644 --- a/scripts/manifest.sha256 +++ b/scripts/manifest.sha256 @@ -8,7 +8,7 @@ fd8d37d698c242ab081095625aa430bb91971db646e35393a02bbadd41325898 scripts/lib/gp 2e64a2c47bdd14c861f8b5e86b06d1dfe4eb349ea6f76d9d22ecf3bb1ec12e04 scripts/lib/setup-linux.sh dd2e1f517b0f6bb665eacebfb7885c6a81443f69c2ebc772433a6baed53c7a8e scripts/lib/cluster.sh 5de1afac8b1062a7f8d0691b46ad39ccdc2287e0e422b53c48628ecfd47d852e scripts/lib/gpu-plugins.sh -b469e666eb1c0c90c46540f5242456ddcc0bd7bca372cef0fcb8e8390ab94c84 scripts/lib/install-client-helm.sh +a9ce18716756c113b750edcc45cca894bde81d234a4320cfb4655a266bdb070b scripts/lib/install-client-helm.sh c5e0ed7aab268c91a131f09d753998cd5a2836a315b8d51428926f82387ad632 scripts/lib/install-cli.sh d596c1f048cf9b40d5d4aaf57aca3846fa21af9a5ac083fb7e507fb6b78a8790 scripts/lib/provision.sh 58bd83c06ca16e1d9346700a3f6bcafc67f20130f0bc1f160d2faedab19fd2cf scripts/lib/summary.sh diff --git a/scripts/tests/install-client-helm.bats b/scripts/tests/install-client-helm.bats index f2026c6..b6a25d0 100644 --- a/scripts/tests/install-client-helm.bats +++ b/scripts/tests/install-client-helm.bats @@ -314,7 +314,11 @@ setup() { _ensure_helm_runnable() { :; } # an existing release reports a different clientId -> must block before upgrade helm() { - if [ "$1" = list ]; then echo '[{"name":"oldrel","namespace":"default","chart":"client-1.4.3"}]'; return 0; fi + if [ "$1" = list ]; then + printf '%s\n' 'NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION' \ + 'oldrel default 1 2026-01-01 deployed client-1.4.3 1.4.3' + return 0 + fi if [ "$1" = get ] && [ "$2" = values ]; then echo 'clientId: "otherclient"'; return 0; fi record "helm $*"; return 0 } @@ -333,7 +337,11 @@ setup() { _ensure_release_dirs() { :; } _ensure_helm_runnable() { :; } helm() { - if [ "$1" = list ]; then echo '[{"name":"tracebloc","namespace":"tracebloc","chart":"client-1.4.3"}]'; return 0; fi + if [ "$1" = list ]; then + printf '%s\n' 'NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION' \ + 'tracebloc tracebloc 1 2026-01-01 deployed client-1.4.3 1.4.3' + return 0 + fi if [ "$1" = get ] && [ "$2" = values ]; then echo 'clientId: "sameid"'; return 0; fi record "helm $*"; return 0 } @@ -354,7 +362,40 @@ setup() { # existing release in place, NOT fork a second one under 'acme-corp'. export TB_NAMESPACE=acme-corp helm() { - if [ "$1" = list ]; then echo '[{"name":"tracebloc","namespace":"tracebloc","chart":"client-1.4.3"}]'; return 0; fi + if [ "$1" = list ]; then + printf '%s\n' 'NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION' \ + 'tracebloc tracebloc 1 2026-01-01 deployed client-1.4.3 1.4.3' + return 0 + fi + if [ "$1" = get ] && [ "$2" = values ]; then echo 'clientId: "sameid"'; return 0; fi + record "helm $*"; return 0 + } + verify_credentials() { printf valid; } + run install_client_helm <<< $'sameid\nmypw' + [ "$status" -eq 0 ] + run mock_calls + [[ "$output" == *"helm upgrade --install tracebloc"* ]] # reused existing namespace + [[ "$output" != *"acme-corp"* ]] # no second release forked +} + +@test "install_client_helm: different-namespace reconcile works WITHOUT jq (Bugbot #284)" { + HOST_DATA_DIR="$BATS_TEST_TMPDIR/data"; mkdir -p "$HOST_DATA_DIR" + _ensure_tracebloc_dirs() { :; } + _ensure_release_dirs() { :; } + _ensure_helm_runnable() { :; } + # Regression for the 2nd Bugbot finding on #284: the guard must enumerate ALL + # namespaces without jq. On a jq-less host the old fallback only checked the + # minted slug namespace, missed the existing `tracebloc` release, and forked a + # second release under the slug. Report jq absent + feed only tabular `helm + # list` output — the guard must still find `tracebloc` and upgrade it in place. + has() { [ "$1" = jq ] && return 1; command -v "$1" >/dev/null 2>&1; } + export TB_NAMESPACE=acme-corp + helm() { + if [ "$1" = list ]; then + printf '%s\n' 'NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION' \ + 'tracebloc tracebloc 1 2026-01-01 deployed client-1.4.3 1.4.3' + return 0 + fi if [ "$1" = get ] && [ "$2" = values ]; then echo 'clientId: "sameid"'; return 0; fi record "helm $*"; return 0 }