Skip to content

feat(scripts): add shared Kind, compose, and KubeVirt helpers - #48

Open
jenniferubah wants to merge 3 commits into
dcm-project:mainfrom
jenniferubah:add-setup-scripts
Open

feat(scripts): add shared Kind, compose, and KubeVirt helpers#48
jenniferubah wants to merge 3 commits into
dcm-project:mainfrom
jenniferubah:add-setup-scripts

Conversation

@jenniferubah

@jenniferubah jenniferubah commented Sep 3, 2026

Copy link
Copy Markdown

Summary

Extract shared local-dev scripts for control-plane and environment-agent compose + Kind workflows into utilities.

  • scripts/kind/: connect Kind to compose networks, rewrite kubeconfig for https://kubernetes:6443, optional kind-local.yaml for in-cluster NodePorts
  • scripts/compose/: network-teardown.sh (disconnect / remove) for compose networks with external members
  • scripts/kubevirt/: install KubeVirt on the current kubectl context

Related Jira Issue

Assisted-By: Cursor AI

Assisted-By: Cursor AI

Signed-off-by: Jennifer Ubah <cju.cipher@gmail.com>
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add shared Kind, Compose, and KubeVirt development helpers

✨ Enhancement 📝 Documentation ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Adds reusable Kind-to-compose networking and kubeconfig helpers for local development.
• Adds compose teardown and context-aware KubeVirt installation utilities.
• Documents usage and expands ShellCheck coverage for new script directories.
Diagram

graph TD
  Consumer["Consumer workflow"] --> Kind["Kind helpers"] --> Context["kubectl context"]
  Kind --> Runtime["Container runtime"] --> Network["Compose network"] --> Node["Kind node"]
  Consumer --> Teardown["Compose teardown"] --> Network
  Consumer --> KubeVirt["KubeVirt installer"] --> Context
Loading
High-Level Assessment

Centralizing these low-dependency workflows as documented shell utilities is appropriate for reuse across consumer repositories. Duplicating scripts would increase drift, while packaging them as a dedicated CLI would add unnecessary distribution and maintenance overhead for straightforward local-development orchestration.

Files changed (14) +563 / -4

Enhancement (6) +345 / -0
network-teardown.shAdd Docker and Podman compose network teardown +116/-0

Add Docker and Podman compose network teardown

• Adds commands to disconnect containers from selected compose networks and remove those networks after compose shutdown. Supports runtime auto-detection, configurable network lists, and best-effort cleanup.

scripts/compose/network-teardown.sh

kind-connect.shConnect a Kind node to a compose network +28/-0

Connect a Kind node to a compose network

• Resolves the active Kind control-plane node and attaches it to a required compose network. Adds an idempotent connection check and configurable Kubernetes network alias.

scripts/kind/kind-connect.sh

kind-disconnect.shDisconnect Kind nodes before compose teardown +48/-0

Disconnect Kind nodes before compose teardown

• Detaches the active Kind control-plane node from configured compose networks when present. Gracefully exits when no compatible context, runtime, node, or network is available.

scripts/kind/kind-disconnect.sh

kind-env.shAdd shared Kind context and runtime resolution +80/-0

Add shared Kind context and runtime resolution

• Provides sourced functions for deriving the Kind node from the current kubectl context. Detects the Docker or Podman runtime that can access both the node and compose network, with actionable diagnostics.

scripts/kind/kind-env.sh

kubeconfig-for-compose.shGenerate a compose-accessible Kind kubeconfig +49/-0

Generate a compose-accessible Kind kubeconfig

• Exports the active Kind context into a configurable output path and rewrites the API endpoint to the compose-visible Kubernetes alias. Includes safeguards for sudo usage, unwritable paths, and conflicting directories.

scripts/kind/kubeconfig-for-compose.sh

install-kubevirt.shInstall and await KubeVirt on the selected cluster +24/-0

Install and await KubeVirt on the selected cluster

• Applies versioned KubeVirt operator and custom-resource manifests to a selected kubectl context. Waits up to five minutes for the KubeVirt deployment to report availability.

scripts/kubevirt/install-kubevirt.sh

Documentation (6) +204 / -3
shell-conventions.mdcDocument sourced-library conventions and expanded lint scope +2/-1

Document sourced-library conventions and expanded lint scope

• Clarifies that sourced shell libraries use a ShellCheck directive instead of a shebang. Expands the documented ShellCheck command to cover all new utility directories.

.cursor/rules/shell-conventions.mdc

CLAUDE.mdDocument shared local-development script directories +11/-1

Document shared local-development script directories

• Adds the Kind, compose, and KubeVirt utility locations and their responsibilities. Updates local ShellCheck guidance to include the new directories.

CLAUDE.md

README.mdPublish local-development helper documentation +14/-1

Publish local-development helper documentation

• Adds the new utility directories to the repository overview and provides links to their detailed usage guides. Updates the documented ShellCheck command accordingly.

README.md

README.mdDocument compose network teardown workflow +56/-0

Document compose network teardown workflow

• Explains the required disconnect-before-down and remove-after-down sequence. Documents supported environment variables and consumer Makefile integration.

scripts/compose/README.md

README.mdDocument Kind and compose integration helpers +101/-0

Document Kind and compose integration helpers

• Describes prerequisites, cluster creation, helper scripts, configuration variables, usage examples, Makefile integration, and troubleshooting for shared Kind workflows.

scripts/kind/README.md

README.mdDocument context-aware KubeVirt installation +20/-0

Document context-aware KubeVirt installation

• Explains how to install KubeVirt on the current or explicitly selected kubectl context and documents the configurable release version.

scripts/kubevirt/README.md

Other (2) +14 / -1
MakefileLint all new shell utility directories +1/-1

Lint all new shell utility directories

• Extends the lint target so ShellCheck validates Kind, compose, and KubeVirt scripts.

Makefile

kind-local.yamlAdd local NodePort mappings for Kind +13/-0

Add local NodePort mappings for Kind

• Defines a single-control-plane Kind cluster configuration exposing agent port 30081 and NATS port 30422 on localhost.

scripts/kind/kind-local.yaml

@qodo-code-review

qodo-code-review Bot commented Sep 3, 2026

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Remediation recommended

1. KubeVirt CRD readiness race ✓ Resolved 🐞 Bug ☼ Reliability
Description
The installer applies the KubeVirt custom resource immediately after creating the operator
resources, without waiting for its CRDs to become established. If API discovery has not observed the
CRD yet, the second kubectl apply fails under set -e and aborts the installation before its
availability wait.
Code

scripts/kubevirt/install-kubevirt.sh[R19-20]

+kubectl --context "${KUBE_CONTEXT}" apply -f "https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-operator.yaml"
+kubectl --context "${KUBE_CONTEXT}" apply -f "https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-cr.yaml"
Evidence
The operator and custom-resource manifests are applied consecutively under set -e; the only
readiness wait is after both commands, leaving no synchronization point for CRD establishment.

scripts/kubevirt/install-kubevirt.sh[1-3]
scripts/kubevirt/install-kubevirt.sh[18-23]

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

## Issue description
The KubeVirt custom resource can be submitted before the operator manifest's CRDs are established. Add an explicit CRD establishment wait between the two apply operations.

## Issue Context
The current availability wait occurs only after the custom resource is applied, so it cannot handle failure during resource creation.

## Fix Focus Areas
- scripts/kubevirt/install-kubevirt.sh[19-23]

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


2. Kubeconfig credentials world-readable ✓ Resolved 🐞 Bug ⛨ Security
Description
kubeconfig-for-compose.sh flattens cluster credentials into the generated kubeconfig and then sets
mode 0644. Other local users can read the client credentials and use them to access the selected
cluster.
Code

scripts/kind/kubeconfig-for-compose.sh[47]

+chmod 644 "${OUT_FILE}"
Evidence
The script writes the flattened current-context kubeconfig to disk and immediately applies mode
0644, granting every local user read access.

scripts/kind/kubeconfig-for-compose.sh[44-47]

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

## Issue description
The generated flattened kubeconfig contains cluster authentication material but is explicitly made world-readable. Restrict the file to its owner, including during initial creation.

## Issue Context
Use a restrictive umask or secure temporary file before writing, and leave the final kubeconfig at mode `0600`.

## Fix Focus Areas
- scripts/kind/kubeconfig-for-compose.sh[44-47]

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


3. Disconnect failures report success ✓ Resolved 🐞 Bug ☼ Reliability
Description
Both container-engine branches discard every network-disconnect error with || true, so
disconnect can exit successfully while external containers remain attached. The following `compose
down` can consequently fail even though its prerequisite reported success.
Code

scripts/compose/network-teardown.sh[R65-67]

+				echo "Disconnecting ${container} from ${network}"
+				podman network disconnect -f "${network}" "${container}" 2>/dev/null || true
+			done < <(podman ps -a --filter "network=${network}" -q 2>/dev/null)
Evidence
The documented sequence requires containers to be detached before compose shutdown, but both Podman
and Docker disconnect commands unconditionally suppress failures.

scripts/compose/network-teardown.sh[63-76]
scripts/compose/README.md[8-13]
scripts/compose/README.md[20-28]

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

## Issue description
The mandatory pre-teardown disconnect operation suppresses all disconnect failures. Track failures and return a nonzero status after processing the networks, while retaining best-effort behavior only for the documented `remove` command.

## Issue Context
The README requires `disconnect` before `compose down` and describes only removal as best-effort.

## Fix Focus Areas
- scripts/compose/network-teardown.sh[63-76]
- scripts/compose/README.md[8-13]

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


View medium (2)
4. Unusable Podman masks Docker ✓ Resolved 🐞 Bug ☼ Reliability
Description
pick_engine selects the first installed executable without checking whether its daemon or target
networks are accessible. On systems with unusable Podman and working Docker, teardown selects Podman
and silently skips the Docker networks instead of performing the requested operation.
Code

scripts/compose/network-teardown.sh[R37-40]

+	for candidate in podman docker; do
+		if command -v "${candidate}" >/dev/null 2>&1; then
+			CONTAINER_ENGINE="${candidate}"
+			return 0
Evidence
Compose teardown chooses Podman solely through command -v; subsequent Podman network checks
suppress errors and skip work. By contrast, the accompanying Kind helper probes both runtime objects
before selecting an engine.

scripts/compose/network-teardown.sh[29-44]
scripts/compose/network-teardown.sh[59-67]
scripts/compose/network-teardown.sh[88-92]
scripts/kind/kind-env.sh[40-59]

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

## Issue description
Automatic detection prefers an installed but unusable Podman over a working Docker installation. Select an engine only after a successful runtime/network probe.

## Issue Context
The Kind helper already demonstrates runtime selection that verifies access to the relevant node and network rather than checking executable presence alone.

## Fix Focus Areas
- scripts/compose/network-teardown.sh[29-44]
- scripts/kind/kind-env.sh[40-59]

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


5. Existing connection skips alias ✓ Resolved 🐞 Bug ≡ Correctness
Description
kind-connect.sh exits whenever the Kind node is already attached to the network without verifying
that the requested kubernetes alias exists. A manually connected node or a changed
KIND_NETWORK_ALIAS therefore remains unreachable through the hostname written into the compose
kubeconfig.
Code

scripts/kind/kind-connect.sh[R20-23]

+if "${CONTAINER_ENGINE}" inspect "${KIND_NODE}" --format '{{range $k, $v := .NetworkSettings.Networks}}{{$k}} {{end}}' \
+	| grep -qw "${COMPOSE_NETWORK}"; then
+	echo "Kind node already connected to '${COMPOSE_NETWORK}'."
+	exit 0
Evidence
The connection check only searches attached network names before exiting, while the kubeconfig
substitutes the alias as its server hostname and the documentation states that the alias must match
the API certificate SAN.

scripts/kind/kind-connect.sh[16-27]
scripts/kind/kubeconfig-for-compose.sh[44-46]
scripts/kind/README.md[98-101]

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

## Issue description
An existing network attachment is treated as complete even when it lacks the requested alias. Inspect the attachment's aliases and repair or recreate it when the expected alias is absent.

## Issue Context
The generated kubeconfig uses `KIND_NETWORK_ALIAS` as its API hostname, so network membership alone is insufficient.

## Fix Focus Areas
- scripts/kind/kind-connect.sh[16-27]
- scripts/kind/kubeconfig-for-compose.sh[11-11]

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


Grey Divider

Context sources
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Compliance rules (platform): 2 rules
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 17/18, lines 567/200; both must reach the floor). Router rationale: This adds several independent, behavior-heavy shell workflows for container networking, kubeconfig rewriting, Kind detection, and cluster-wide KubeVirt installation, creating a high density of easy-to-miss defects across multiple paths.

Grey Divider

Tip of the day
💡 Did you know, you can add REVIEW.md to your repo root and Qodo follows it on every PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread scripts/kind/kubeconfig-for-compose.sh Outdated
Comment thread scripts/kind/kind-connect.sh Outdated
Comment thread scripts/compose/network-teardown.sh Outdated
Comment thread scripts/compose/network-teardown.sh
Comment thread scripts/kubevirt/install-kubevirt.sh
Assisted-By: Cursor AI

Signed-off-by: Jennifer Ubah <cju.cipher@gmail.com>
Assisted-By: Cursor AI

Signed-off-by: Jennifer Ubah <cju.cipher@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant