Skip to content

fix: harden shell scripts and fix db_copy loop bug#3159

Merged
openshift-merge-bot[bot] merged 4 commits into
mainfrom
fix/shell-script-smells
Jul 8, 2026
Merged

fix: harden shell scripts and fix db_copy loop bug#3159
openshift-merge-bot[bot] merged 4 commits into
mainfrom
fix/shell-script-smells

Conversation

@rhdh-bot

@rhdh-bot rhdh-bot commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

ShellCheck audit of repository shell scripts found no parse errors (including no "trailing ] outside test" issues), but manual review surfaced one functional bug and several hardening opportunities. This PR addresses all of them.

Critical fix: hack/db_copy.sh

The migration loop contained:

for db in "${allDB[@]}"; do
  db=${allDB["$db"]}   # bug: uses DB name as array index

allDB is a regular indexed array. Using a string like backstage_plugin_auth as a subscript causes bash to fall back to index 0, so every iteration copied backstage_plugin_app instead of the intended six Backstage plugin databases.

Fix: remove the erroneous reassignment; the for loop variable already holds the correct name.

Hardening: config/profile/rhdh/plugin-infra/plugin-infra.sh

  • Enable set -euo pipefail (was set -e only).
  • Replace [ ... == ... ] with [[ ... ]] for bash-native string/boolean comparisons.

Hardening: config/profile/rhdh/plugin-infra/gitops-secret-setup.sh

  • Enable set -euo pipefail.
  • Initialize selected_instance="" so set -u is safe when no ArgoCD instance exists.
  • Replace eval "$cmd" in createBackstageSecret with a command array — avoids shell metacharacter injection if secret values contain special characters.
  • Use ${VAR:-} for optional variables; quote ARGOCD_URL.
  • Adopt name() function style (consistent with other scripts).

Hardening: config/profile/rhdh/plugin-deps/tekton.yaml

Embedded Tekton step scripts updated:

Task step Change
flattener Remove unused ROOT/TARGET vars; add shebang + set -eu; fix [ ... == ... ][ ... = ... ]
build-manifests Add shebang + set -eu
build-gitops Add shebang + set -eu; quote paths/args; cd kustomize || exit

Analysis for reviewers

File Risk before Risk after
hack/db_copy.sh Data loss / wrong DB copied on every run after first DB name Each of 6 plugin DBs migrated correctly
gitops-secret-setup.sh eval could break or inject on unusual secret values Direct array invocation
plugin-infra.sh Unset vars silently expand to empty strings Fail-fast on unset vars
tekton.yaml Unquoted globs, silent cd failure Safer inline shell for CI pipelines

Scope: shell scripts and Tekton inline scripts only — no Go operator logic, CRDs, or bundle changes.

Validation run locally:

  • shellcheck -x -a on all changed .sh files — clean
  • bash -n syntax check — clean

Test plan

  • shellcheck -x -a hack/db_copy.sh config/profile/rhdh/plugin-infra/*.sh
  • Review gitops-secret-setup.sh array-based secret creation (no behavior change for normal values)
  • Confirm Tekton pipeline steps still render valid YAML (no indentation regressions)
  • Optional: dry-run hack/db_copy.sh loop logic — verify six distinct DB names are iterated

Made with Cursor

Correct a logic error in hack/db_copy.sh that caused every database
migration to target backstage_plugin_app, and apply shellcheck-driven
hardening across plugin-infra setup scripts and Tekton inline scripts.

Assisted-by: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
@rhdh-bot rhdh-bot requested a review from a team as a code owner July 7, 2026 18:34
@openshift-ci openshift-ci Bot requested review from subhashkhileri and zdrapela July 7, 2026 18:35
rhdh-bot and others added 3 commits July 7, 2026 15:44
Address SonarCloud warnings about camelCase function names introduced
during shell script hardening.

Assisted-by: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Use snake_case function names and bash [[ ]] conditionals throughout
gitops-secret-setup.sh; align plugin-infra.sh file test with [[ ]].

Assisted-by: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
@sonarqubecloud

sonarqubecloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

@Fortune-Ndlovu

Copy link
Copy Markdown
Member

/agentic_review

@rhdh-qodo-merge

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 18 rules

Grey Divider


Action required

1. ArgoCD lookup exits early 🐞 Bug ☼ Reliability
Description
In capture_argocd_url(), argocd_instances=$(oc get argocd ...) is unguarded while `set -euo
pipefail is enabled, so any non-zero exit from that oc` call will terminate the script before it
can take the “continue without ArgoCD support” path.
Code

config/profile/rhdh/plugin-infra/gitops-secret-setup.sh[R41-46]

+capture_argocd_url() {
  argocd_instances=$(oc get argocd -n "$ARGOCD_NAMESPACE" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')

-  if [ -z "$argocd_instances" ]; then
+  if [[ -z "$argocd_instances" ]]; then
      echo "No ArgoCD instances found in namespace $ARGOCD_NAMESPACE. Continuing without ArgoCD support"
  else
-    if [ "$use_default" == true ]; then
Relevance

⭐⭐⭐ High

Team accepted making commands/traps best-effort under set -euo pipefail to avoid unintended exits
(PRs #2870, #2645).

PR-#2870
PR-#2645
PR-#1325

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The file enables set -euo pipefail and then performs an unguarded command substitution to query
ArgoCD instances, followed immediately by logic that expects to handle an empty result and “continue
without ArgoCD support”; under -e, a non-zero exit in that substitution aborts before the
empty-result branch can run.

config/profile/rhdh/plugin-infra/gitops-secret-setup.sh[6-66]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`capture_argocd_url()` intends to continue when ArgoCD is unavailable, but with `set -euo pipefail` enabled, an unguarded failing `oc get argocd ...` inside command substitution can abort the script before the fallback logic runs.

## Issue Context
This script explicitly prints "Continuing without ArgoCD support" when it can't find instances; the `oc get argocd` call should therefore be treated as optional and handled without terminating the whole script.

## Fix Focus Areas
- config/profile/rhdh/plugin-infra/gitops-secret-setup.sh[41-66]

## Suggested change
Wrap the `oc get argocd ...` call with an explicit success check, e.g.:

- `if ! argocd_instances=$(oc get argocd ... 2>/dev/null); then`
 - print a message indicating ArgoCD support is being skipped
 - ensure `selected_instance` remains empty
 - `return 0`

Optionally apply the same pattern to the route lookup (`oc get route ...`) so a missing route does not hard-fail the entire setup when ArgoCD is meant to be optional.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread config/profile/rhdh/plugin-infra/gitops-secret-setup.sh

@Fortune-Ndlovu Fortune-Ndlovu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@openshift-ci openshift-ci Bot added the lgtm label Jul 8, 2026
@openshift-merge-bot openshift-merge-bot Bot merged commit 0858c38 into main Jul 8, 2026
10 checks passed
@openshift-merge-bot openshift-merge-bot Bot deleted the fix/shell-script-smells branch July 8, 2026 10:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants