Skip to content

feat(byoo-perf): deploy the authentic collector and wire run/cleanup - #623

Open
shobham-nv wants to merge 2 commits into
mainfrom
shobham/418-byoo-perf-deploy
Open

feat(byoo-perf): deploy the authentic collector and wire run/cleanup#623
shobham-nv wants to merge 2 commits into
mainfrom
shobham/418-byoo-perf-deploy

Conversation

@shobham-nv

@shobham-nv shobham-nv commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

TL;DR

Adds the deployment milestone to the BYOO collector perf suite. run now renders the production workload shape via icms-translate, validates it, deploys the authentic collector to a cluster (k3d or remote) behind a harness OTLP Service, waits for readiness, and tears it down; cleanup removes what the suite created. Load generation and measurement land in a later milestone.

Additional Details

  • pkg/deploy (new): a Kubernetes client that applies the rendered bench pod plus a harness ClusterIP OTLP Service, waits for pod readiness (failing fast on CrashLoopBackOff/ImagePullBackOff/config errors instead of blocking to timeout), and cleans up scoped by the app.kubernetes.io/part-of=byoo-perf label so it never deletes unrelated resources. Repeatable deploys replace existing objects. The harness Service gives load generators a stable in-cluster address regardless of shape; for the container shape (a localhost sidecar in production) it is harness-only and never alters the collector spec under test.
  • cmd/perf: the previously-stubbed cobra run and cleanup commands are implemented against pkg/deploy, with per-shape namespaces (byoo-perf-container / byoo-perf-helm) so both shapes can be deployed without colliding, and --retain to keep resources for inspection.
  • go.mod: adds k8s.io/client-go, pinned to v0.34.2 via replace, mirroring the shared lib's convention.
  • The suite is still the standalone GOWORK=off module wired into the required perf CI job (from feat(byoo-perf): add scaffolding, translation-driven rendering, and validation #422), so these tests run on every change to this subtree.

For the Reviewer

  • pkg/deploy/deploy.go — the deploy/wait/cleanup logic and the label-scoped teardown.
  • cmd/perf/main.gorunRun/runCleanup and per-shape namespacing.
  • Note: run validates all selectors before it ever contacts a cluster, which keeps the new CLI tests hermetic.

For QA

  • make perf-test (build + vet + test, GOWORK=off) passes locally; pkg/deploy is unit-tested against a fake clientset (namespace idempotency, pod+service creation, repeatable deploys, ready/crash-loop paths, label-scoped cleanup).
  • Full cluster runs (perf run against k3d/remote) exercise real deployment; unit tests do not require a cluster.

Issues

Relates to #416
Closes #418

Checklist

  • I am familiar with the Contributing Guidelines.
  • I have signed off my commits for Developer Certificate of Origin (DCO) compliance.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

Summary by CodeRabbit

  • New Features
    • Added performance-suite commands to render, deploy, monitor, and clean up OpenTelemetry Collector workloads.
    • Added configurable cluster access, readiness timeouts, retention settings, and isolated namespaces for multiple shapes.
    • Added repeatable deployments and targeted cleanup of suite-created resources.
  • Documentation
    • Updated performance-suite guidance for available commands and deployment workflows.
  • Chores
    • Updated the BYOO OpenTelemetry Collector version to 0.157.8.

Add the deployment milestone for the BYOO collector perf suite: render the
production workload shape, deploy the authentic collector to a cluster, wait
for it to become ready, and tear it back down. Load generation and measurement
land in a later milestone.

- pkg/deploy: Kubernetes client that applies the rendered bench pod plus a
  harness ClusterIP OTLP Service, waits for pod readiness (failing fast on
  crash/image-pull loops), and cleans up scoped by the suite's part-of label
  so it never touches unrelated resources. Repeatable deploys replace existing
  objects. Unit-tested against a fake clientset.
- cmd/perf: implement the cobra run and cleanup commands (previously stubs)
  against pkg/deploy, with per-shape namespaces so container and helm shapes
  never collide, and --retain to keep resources for inspection.
- cmd/perf tests: run/cleanup flag defaults, hermetic invalid-selector checks
  (validation happens before any cluster access), and namespaceForShape.
- go.mod: add k8s.io/client-go (pinned to v0.34.2 via replace, mirroring the
  shared lib's convention).
- README: document run and cleanup.
- VERSION: bump 0.157.6 -> 0.157.7 for the collector-dir change.

Relates to #416. Closes #418.

Signed-off-by: shobham <shobham@nvidia.com>
@shobham-nv
shobham-nv requested a review from a team as a code owner August 3, 2026 06:17
@shobham-nv
shobham-nv requested a review from vrv3814 August 3, 2026 06:17
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2dc65281-1ad6-46d6-8b97-7b67818ee478

📥 Commits

Reviewing files that changed from the base of the PR and between f5022a5 and abb1df5.

📒 Files selected for processing (1)
  • src/compute-plane-services/byoo-otel-collector/VERSION
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/compute-plane-services/byoo-otel-collector/VERSION

📝 Walkthrough

Walkthrough

The performance suite now deploys authentic BYOO OpenTelemetry Collector workloads to Kubernetes, waits for readiness, reports endpoints, and cleans up suite-owned resources. The CLI supports cluster configuration, shape-specific namespaces, retention, and cleanup commands. Documentation and the collector version were updated.

Changes

BYOO performance deployment

Layer / File(s) Summary
Kubernetes deployment lifecycle
src/compute-plane-services/byoo-otel-collector/perf/pkg/deploy/*, src/compute-plane-services/byoo-otel-collector/perf/go.mod
Added Kubernetes client creation, namespace management, repeatable pod and Service deployment, readiness polling, endpoint construction, terminal failure reporting, and label-scoped cleanup. Added tests for deployment, readiness, idempotency, and cleanup.
Performance CLI workflow
src/compute-plane-services/byoo-otel-collector/perf/cmd/perf/*, src/compute-plane-services/byoo-otel-collector/perf/README.md, src/compute-plane-services/byoo-otel-collector/VERSION
Implemented run and cleanup, including validation, cluster flags, readiness timeout, retention, endpoint reporting, and multi-shape namespace isolation. Updated tests, documentation, and the collector version.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant PerfCLI
  participant Renderer
  participant DeployClient
  participant KubernetesCluster
  Operator->>PerfCLI: Run selected shape
  PerfCLI->>Renderer: Render and validate workload
  PerfCLI->>DeployClient: Deploy workload
  DeployClient->>KubernetesCluster: Create or replace resources
  PerfCLI->>DeployClient: Wait for readiness
  DeployClient-->>Operator: Report in-cluster endpoints
  PerfCLI->>DeployClient: Cleanup unless retention is enabled
Loading

Suggested reviewers: vrv3814

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR covers deployment, isolation, readiness, cleanup, retention, and tests, but does not implement image handling, k3d provisioning, or provenance recording required by #418. Implement or explicitly defer the missing #418 requirements for k3d provisioning, collector image selection/build/import, provenance recording, and corresponding tests.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title uses valid Conventional Commits syntax and accurately describes the deployment and run/cleanup feature.
Out of Scope Changes check ✅ Passed The code, tests, dependency updates, documentation, and version bump support the BYOO performance-suite deployment objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch shobham/418-byoo-perf-deploy
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch shobham/418-byoo-perf-deploy

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/compute-plane-services/byoo-otel-collector/perf/pkg/deploy/deploy.go (1)

243-271: 🧹 Nitpick | 🔵 Trivial

Cleanup never removes the namespace itself.

Cleanup deletes suite-labeled pods and Services but leaves the namespace in place. Over repeated runs, namespaces created by EnsureNamespace accumulate. Confirm this is intentional (e.g., to avoid slow namespace termination) or consider deleting the namespace when it was created by this suite and is now empty.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/compute-plane-services/byoo-otel-collector/perf/pkg/deploy/deploy.go`
around lines 243 - 271, Update Client.Cleanup to remove the suite-created
namespace after deleting its labeled pods and services, using the existing
ownership/creation tracking from EnsureNamespace. Delete the namespace only when
this suite created it and cleanup completed successfully, while preserving the
current behavior for pre-existing namespaces and propagating non-NotFound
deletion errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/compute-plane-services/byoo-otel-collector/perf/cmd/perf/main.go`:
- Around line 208-220: Update the deployment flow around client.Deploy and
client.WaitPodReady to clean up resources whenever either operation fails and
cfg.retain is false. On Deploy errors, invoke client.Cleanup before returning;
on readiness errors, preserve the original failure while also reporting any
cleanup failure instead of discarding it, using an appropriate combined error.

In `@src/compute-plane-services/byoo-otel-collector/perf/pkg/deploy/deploy.go`:
- Around line 173-190: Update applyPod to wrap errors returned by waitPodDeleted
with context identifying the pod deletion wait, and update the waitPodDeleted
poll function to wrap the underlying Kubernetes error before returning it. Use
Go %w wrapping at both points while preserving the existing error propagation
behavior.

---

Nitpick comments:
In `@src/compute-plane-services/byoo-otel-collector/perf/pkg/deploy/deploy.go`:
- Around line 243-271: Update Client.Cleanup to remove the suite-created
namespace after deleting its labeled pods and services, using the existing
ownership/creation tracking from EnsureNamespace. Delete the namespace only when
this suite created it and cleanup completed successfully, while preserving the
current behavior for pre-existing namespaces and propagating non-NotFound
deletion errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 221f0fa3-ce78-4b69-95ad-e3eafec641c7

📥 Commits

Reviewing files that changed from the base of the PR and between 7886526 and f5022a5.

⛔ Files ignored due to path filters (1)
  • src/compute-plane-services/byoo-otel-collector/perf/go.sum is excluded by !**/*.sum
📒 Files selected for processing (7)
  • src/compute-plane-services/byoo-otel-collector/VERSION
  • src/compute-plane-services/byoo-otel-collector/perf/README.md
  • src/compute-plane-services/byoo-otel-collector/perf/cmd/perf/main.go
  • src/compute-plane-services/byoo-otel-collector/perf/cmd/perf/main_test.go
  • src/compute-plane-services/byoo-otel-collector/perf/go.mod
  • src/compute-plane-services/byoo-otel-collector/perf/pkg/deploy/deploy.go
  • src/compute-plane-services/byoo-otel-collector/perf/pkg/deploy/deploy_test.go

Comment on lines +208 to +220
fmt.Fprintf(stdout, "[%s] deploying to namespace %q ...\n", shape, ns)
dep, err := client.Deploy(ctx, ns, res)
if err != nil {
return fmt.Errorf("deploy %s: %w", shape, err)
}

fmt.Fprintf(stdout, "[%s] waiting up to %s for collector pod %q to become ready ...\n", shape, cfg.readyTimeout, dep.PodName)
if err := client.WaitPodReady(ctx, ns, dep.PodName, cfg.readyTimeout); err != nil {
if !cfg.retain {
_ = client.Cleanup(ctx, ns)
}
return fmt.Errorf("collector did not become ready for %s shape: %w", shape, err)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Deploy failures leave resources behind despite the documented cleanup contract.

The README and PR description promise cleanup "unless --retain is set." At line 210, if client.Deploy fails (for example, the pod is created but the Service creation fails), the function returns immediately without calling client.Cleanup. Only the WaitPodReady failure branch performs cleanup. Add the same conditional cleanup on the Deploy error path.

Separately, at line 217 the cleanup error is discarded (_ = client.Cleanup(...)). If cleanup itself fails, the user only sees the original readiness error and has no indication that the namespace still holds stale resources. Report the cleanup failure alongside the original error.

🛠️ Proposed fix for both cleanup gaps
 		fmt.Fprintf(stdout, "[%s] deploying to namespace %q ...\n", shape, ns)
 		dep, err := client.Deploy(ctx, ns, res)
 		if err != nil {
+			if !cfg.retain {
+				_ = client.Cleanup(ctx, ns)
+			}
 			return fmt.Errorf("deploy %s: %w", shape, err)
 		}

 		fmt.Fprintf(stdout, "[%s] waiting up to %s for collector pod %q to become ready ...\n", shape, cfg.readyTimeout, dep.PodName)
 		if err := client.WaitPodReady(ctx, ns, dep.PodName, cfg.readyTimeout); err != nil {
-			if !cfg.retain {
-				_ = client.Cleanup(ctx, ns)
-			}
+			if !cfg.retain {
+				if cerr := client.Cleanup(ctx, ns); cerr != nil {
+					fmt.Fprintf(stdout, "[%s] warning: cleanup of namespace %q failed: %v\n", shape, ns, cerr)
+				}
+			}
 			return fmt.Errorf("collector did not become ready for %s shape: %w", shape, err)
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/compute-plane-services/byoo-otel-collector/perf/cmd/perf/main.go` around
lines 208 - 220, Update the deployment flow around client.Deploy and
client.WaitPodReady to clean up resources whenever either operation fails and
cfg.retain is false. On Deploy errors, invoke client.Cleanup before returning;
on readiness errors, preserve the original failure while also reporting any
cleanup failure instead of discarding it, using an appropriate combined error.

Comment on lines +173 to +190
func (c *Client) applyPod(ctx context.Context, namespace string, pod *corev1.Pod) error {
pods := c.cs.CoreV1().Pods(namespace)
err := pods.Delete(ctx, pod.Name, metav1.DeleteOptions{})
if err != nil && !k8serrors.IsNotFound(err) {
return fmt.Errorf("delete existing pod %q: %w", pod.Name, err)
}
if err == nil {
// Wait for the old pod to be fully gone before recreating it, so the
// create does not race with the deletion.
if werr := c.waitPodDeleted(ctx, namespace, pod.Name, 60*time.Second); werr != nil {
return werr
}
}
if _, err := pods.Create(ctx, pod, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("create pod %q: %w", pod.Name, err)
}
return nil
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Wrap the pod-deletion-wait error with context.

At line 183, waitPodDeleted returns its error unchanged. The error from waitPodDeleted itself is also unwrapped (return false, err inside its poll function at line 237). When this error reaches Deploy and then runRun, the caller only sees the raw Kubernetes client error with no indication that it happened while waiting for the old pod to terminate. Add context at both points so failures are traceable.

As per path instructions, "Check Go error wrapping (%w)... " for src/**/*.go changes.

🩹 Proposed fix to add context to the deletion-wait error path
 	if err == nil {
 		// Wait for the old pod to be fully gone before recreating it, so the
 		// create does not race with the deletion.
 		if werr := c.waitPodDeleted(ctx, namespace, pod.Name, 60*time.Second); werr != nil {
-			return werr
+			return fmt.Errorf("wait for pod %q deletion: %w", pod.Name, werr)
 		}
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/compute-plane-services/byoo-otel-collector/perf/pkg/deploy/deploy.go`
around lines 173 - 190, Update applyPod to wrap errors returned by
waitPodDeleted with context identifying the pod deletion wait, and update the
waitPodDeleted poll function to wrap the underlying Kubernetes error before
returning it. Use Go %w wrapping at both points while preserving the existing
error propagation behavior.

Source: Path instructions

main advanced to 0.157.7 (matching the value this branch had picked), so the
version-guard saw VERSION unchanged against main while perf/ files changed.
Bump to 0.157.8 so the guard sees the update.

Relates to #416. Closes #418.

Signed-off-by: shobham <shobham@nvidia.com>
fmt.Fprintf(stdout, "[%s] deploying to namespace %q ...\n", shape, ns)
dep, err := client.Deploy(ctx, ns, res)
if err != nil {
return fmt.Errorf("deploy %s: %w", shape, err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When Deploy fails after creating the Pod (for example, because Service creation is rejected), this returns before the normal cleanup path and leaves suite resources behind even though --retain is false. Please attempt client.Cleanup(ctx, ns) before returning on deploy failure, and preserve both errors (for example with errors.Join) so a cleanup failure is not silently discarded. Add a test that makes the Service create fail after Pod creation and verifies the Pod is removed.

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.

byoo-perf-suite: Add collector deployment and image handling for k3d and remote modes

2 participants