Skip to content

Conversation

@MikelAlejoBR
Copy link

@MikelAlejoBR MikelAlejoBR commented Dec 23, 2025

In order to be able to debug the operator live in the local cluster, we need the binary to be executed with Delve instead, and we need it to be built without any code optimizations or minimization so that the breakpoints work.

For that purpose, new Dockerfiles are added which can build the images that way, and the corresponding Make targets make it easy to kick off the whole process with a single command.

The Makefile targets also enable the "toolchain-e2e" repository to easily build the "debug" images.

Related PRs

Jira ticket

[SANDBOX-1561]

Summary by CodeRabbit

  • New Features

    • Debug-enabled container images exposing a remote debugger on port 50000 for operator and webhook components
    • Startup now conditionally launches the operator under the debugger when debug mode is enabled
  • Chores

    • Added debug-focused build and image targets to streamline creating and publishing debug-ready artifacts
    • Added convenience build targets and packaging steps to produce debug-capable binaries and images

✏️ Tip: You can customize this high-level summary in your review settings.

@openshift-ci openshift-ci bot requested review from rsoaresd and xcoulon December 23, 2025 15:03
@openshift-ci
Copy link

openshift-ci bot commented Dec 23, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: MikelAlejoBR
Once this PR has been reviewed and has the lgtm label, please assign fbm3307 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai
Copy link

coderabbitai bot commented Dec 23, 2025

Walkthrough

Adds Delve-based debugging: two debug Dockerfiles, a build target producing non-optimized debug binaries, entrypoint logic to launch the operator under Delve when enabled, and Make targets to build/push debug images (debugger exposed on port 50000).

Changes

Cohort / File(s) Summary
Debug Dockerfiles
build/Dockerfile.debug, build/Dockerfile.webhook.debug
New multi-stage Dockerfiles that install a specific Go toolchain in a build stage, compile Delve into /tmp/bin, copy Delve into a ubi-minimal final image, set debug env vars (e.g., DEBUG_MODE, USER_UID, USER_NAME, LANG), create a non-root user, copy operator binaries, set ENTRYPOINT, and expose port 50000.
Entrypoint script
build/bin/entrypoint
Conditional launch: if DEBUG_MODE is set, start Delve in headless mode to run the operator (forwarding args); otherwise exec the operator directly.
Go build targets
make/go.mk
Adds build-debug phony target to produce debug-friendly member-operator and member-operator-webhook binaries with -gcflags "all=-N -l" and version ldflags, placed into $(OUT_DIR)/bin/.
Image build & push targets
make/podman.mk
Adds podman-image-debug and podman-push-debug targets (and PHONYs) to build and push the Delve-enabled images using host GOLANG_VERSION; expands namespace warning messaging.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Dev as Developer
  participant Container as Container / Entrypoint
  participant Delve as Delve (dlv)
  participant Operator as member-operator

  Dev->>Container: start container (ENV: DEBUG_MODE set or unset)
  alt DEBUG_MODE set
    Container->>Delve: exec dlv --headless --listen=:50000 --accept-multiclient --api-version=2 -- ./member-operator +args
    Delve->>Operator: spawn operator (debug-friendly build)
  else DEBUG_MODE empty
    Container->>Operator: exec ./member-operator +args
  end
  Note over Delve,Operator: Port 50000 exposed for debugger connection
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hop into containers, twitching every byte,
Delve on my shoulder, I peep through stack and flight,
Port five-oh-oh-oh waits, a tunnel soft and deep,
I nibble at nils and race where goroutines sleep,
Debug carrots crunch — a rabbit’s gleeful bite.

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: new Makefile targets for building the operator in debug mode with Delve support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc412ad and cde5155.

📒 Files selected for processing (5)
  • build/Dockerfile.debug
  • build/Dockerfile.webhook.debug
  • build/bin/entrypoint
  • make/go.mk
  • make/podman.mk
🚧 Files skipped from review as they are similar to previous changes (2)
  • make/go.mk
  • build/Dockerfile.webhook.debug
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: MikelAlejoBR
Repo: codeready-toolchain/member-operator PR: 720
File: build/Dockerfile.debug:24-25
Timestamp: 2026-01-02T20:13:02.289Z
Learning: For debug builds in the member-operator repository, using `latest` for Delve installation is acceptable. The team prefers to keep Delve up-to-date in debug images and will only pin a specific version if compatibility issues with the Golang version arise.
📚 Learning: 2026-01-02T20:13:02.289Z
Learnt from: MikelAlejoBR
Repo: codeready-toolchain/member-operator PR: 720
File: build/Dockerfile.debug:24-25
Timestamp: 2026-01-02T20:13:02.289Z
Learning: For debug builds in the member-operator repository, using `latest` for Delve installation is acceptable. The team prefers to keep Delve up-to-date in debug images and will only pin a specific version if compatibility issues with the Golang version arise.

Applied to files:

  • build/bin/entrypoint
  • build/Dockerfile.debug
  • make/podman.mk
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build & push operator bundles & dashboard image for e2e tests
🔇 Additional comments (3)
build/bin/entrypoint (1)

12-17: LGTM! Debug mode entrypoint logic is correct.

The conditional execution path properly handles both debug and normal modes. The exec keyword ensures proper signal handling in both branches, and the Delve flags are appropriate for remote headless debugging.

make/podman.mk (2)

27-31: LGTM! Debug push target follows established patterns.

The podman-push-debug target correctly mirrors the structure of the existing podman-push target, with appropriate dependencies on namespace validation and debug image building. Both operator and webhook images are pushed consistently.


15-19: The Go version extraction using go version | awk '{print $3}' works correctly and is reliable. Verification confirms that the command reliably extracts the version string in the expected format (e.g., "go1.25.1"), and the constructed URLs follow the official Go download URL pattern. The Dockerfiles properly handle the 302 redirect from go.dev/dl to Google's CDN using the curl --location flag, so this approach functions as intended across different Go versions.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (1)
make/podman.mk (1)

15-19: Consider more robust Go version extraction.

The current approach uses go version | awk '{print $$3}' to extract the Go version. While this works for the standard output format, it's fragile and lacks error handling.

🔎 More robust version extraction
-podman-image-debug: build-debug
-	$(Q) podman build --platform ${IMAGE_PLATFORM} --build-arg GOLANG_VERSION="$$(go version | awk '{print $$3}')" --file build/Dockerfile.debug --tag ${IMAGE} .
-	$(Q) podman build --platform ${IMAGE_PLATFORM} --build-arg GOLANG_VERSION="$$(go version | awk '{print $$3}')" --file build/Dockerfile.webhook.debug --tag ${WEBHOOK_IMAGE} .
+GOLANG_VERSION := $(shell go version | awk '{print $$3}' || echo "go1.21.0")
+
+podman-image-debug: build-debug
+	$(Q) podman build --platform ${IMAGE_PLATFORM} --build-arg GOLANG_VERSION="${GOLANG_VERSION}" --file build/Dockerfile.debug --tag ${IMAGE} .
+	$(Q) podman build --platform ${IMAGE_PLATFORM} --build-arg GOLANG_VERSION="${GOLANG_VERSION}" --file build/Dockerfile.webhook.debug --tag ${WEBHOOK_IMAGE} .

This approach:

  • Extracts the version once and reuses it
  • Provides a fallback if the command fails
  • Makes the version visible and easier to override if needed
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f4a5d0 and 22c9fee.

📒 Files selected for processing (5)
  • build/Dockerfile.debug
  • build/Dockerfile.webhook.debug
  • build/bin/entrypoint
  • make/go.mk
  • make/podman.mk
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build & push operator bundles & dashboard image for e2e tests

@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.12%. Comparing base (e048e8f) to head (721cd5c).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #720   +/-   ##
=======================================
  Coverage   63.12%   63.12%           
=======================================
  Files          48       48           
  Lines        3604     3604           
=======================================
  Hits         2275     2275           
  Misses       1181     1181           
  Partials      148      148           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@MikelAlejoBR MikelAlejoBR force-pushed the SANDBOX-1561-debug-sandbox-resources branch from 22c9fee to 917e1b2 Compare January 2, 2026 20:03
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
build/Dockerfile.debug (1)

24-25: Pin the Delve version for reproducibility.

This concern was raised in a previous review. Using @latest makes builds non-reproducible.

build/Dockerfile.webhook.debug (1)

24-25: Pin the Delve version for reproducibility.

This concern was raised in a previous review. Use the same pinned version as build/Dockerfile.debug for consistency.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22c9fee and 917e1b2.

📒 Files selected for processing (5)
  • build/Dockerfile.debug
  • build/Dockerfile.webhook.debug
  • build/bin/entrypoint
  • make/go.mk
  • make/podman.mk
🚧 Files skipped from review as they are similar to previous changes (3)
  • build/bin/entrypoint
  • make/go.mk
  • make/podman.mk
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build & push operator bundles & dashboard image for e2e tests
🔇 Additional comments (2)
build/Dockerfile.debug (1)

27-55: Final stage looks good.

The multi-stage build correctly:

  • Uses ubi-minimal for a smaller image
  • Sets up a non-root user (UID 1001)
  • Copies only the necessary artifacts (operator binary, Delve, entrypoint scripts)
  • Exposes the debug port 50000
build/Dockerfile.webhook.debug (1)

27-55: Final stage is properly configured for webhook debugging.

The configuration mirrors build/Dockerfile.debug appropriately, with webhook-specific paths (member-operator-webhook binary and user).

@MikelAlejoBR MikelAlejoBR force-pushed the SANDBOX-1561-debug-sandbox-resources branch from 917e1b2 to fc412ad Compare January 2, 2026 20:17
In order to be able to debug the operator live in the local cluster, we
need the binary to be executed with Delve instead, and we need it to be
built without any code optimizations or minimization so that the
breakpoints work.

For that purpose, new Dockerfiles are added which can build the images
that way, and the corresponding Make targets make it easy to kick off
the whole process with a single command.

The Makefile targets also enable the "toolchain-e2e" repository to
easily build the "debug" images.

SANDBOX-1561
@MikelAlejoBR MikelAlejoBR force-pushed the SANDBOX-1561-debug-sandbox-resources branch from 7952b4c to cde5155 Compare January 6, 2026 23:04
Copy link
Contributor

@xcoulon xcoulon left a comment

Choose a reason for hiding this comment

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

Nice!
Sorry if I'm late in the game, but how can we enable/switch to the debug build?
Also, do we need an extra service and route to connect to the debug port?

@MikelAlejoBR
Copy link
Author

No worries at all 😄

These changes enable deploying this, the host operator and the registration service with debuggers listening by issuing a make dev-deploy-e2e-local-debug command.

You can also individually build and push every operator with the make podman-push-debug target.

Also, do we need an extra service and route to connect to the debug port?

In principle I have been playing with the port-forward command to expose the debugging port and connect the IDEs to it, since it seems the most simple solution, but I am not opposed to deploying some simple services that expose the port permanently... especially because all this is supposed to be used locally, and we'd be fine with having those ports accessible for easier interaction with the services and programs.

@xcoulon
Copy link
Contributor

xcoulon commented Jan 7, 2026

No worries at all 😄

These changes enable deploying this, the host operator and the registration service with debuggers listening by issuing a make dev-deploy-e2e-local-debug command.

You can also individually build and push every operator with the make podman-push-debug target.

Nice!

Also, do we need an extra service and route to connect to the debug port?

In principle I have been playing with the port-forward command to expose the debugging port and connect the IDEs to it, since it seems the most simple solution, but I am not opposed to deploying some simple services that expose the port permanently... especially because all this is supposed to be used locally, and we'd be fine with having those ports accessible for easier interaction with the services and programs.

Ah, I assume this works with OpenShift Local, but probably not with a temp cluster on AWS? 🤔
I have to admit, I haven't tried port-forwarding for a while

@MikelAlejoBR
Copy link
Author

Ah, I assume this works with OpenShift Local, but probably not with a temp cluster on AWS? 🤔
I have to admit, I haven't tried port-forwarding for a while

I only had local development in mind, but surely I think we can make it work in a temp cluster too. In fact in the beginning I was creating services for everything but I ended up discarding that because I thought that they weren't needed for local dev... I might present this thing first and if everybody likes it and wants to go forward I can go ahead and extend it for temp clusters too, if that sounds okay!

@xcoulon
Copy link
Contributor

xcoulon commented Jan 7, 2026

Ah, I assume this works with OpenShift Local, but probably not with a temp cluster on AWS? 🤔
I have to admit, I haven't tried port-forwarding for a while

I only had local development in mind, but surely I think we can make it work in a temp cluster too. In fact in the beginning I was creating services for everything but I ended up discarding that because I thought that they weren't needed for local dev... I might present this thing first and if everybody likes it and wants to go forward I can go ahead and extend it for temp clusters too, if that sounds okay!

looks good, let's focus on OpenShift Local for now ;)

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@MikelAlejoBR
Copy link
Author

Closing in favor of #721.

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.

3 participants