diff --git a/build/Dockerfile.debug b/build/Dockerfile.debug new file mode 100644 index 00000000..56abab4b --- /dev/null +++ b/build/Dockerfile.debug @@ -0,0 +1,53 @@ +# Compile Delve in an intermediate step. +FROM registry.access.redhat.com/ubi8/ubi:latest AS delve-builder + +# The Golang version must be provided as a build arguments, which will ensure +# that Delve gets built with the same version the operator's binary gets built +# with, to avoid any discrepancies. +ARG GOLANG_VERSION + +# Install Tar to be able to extract Golang. +RUN yum install --assumeyes \ + tar \ + && yum clean all + +# Download and extract Golang. +RUN curl --location --output "${GOLANG_VERSION}.linux-amd64.tar.gz" "https://go.dev/dl/${GOLANG_VERSION}.linux-amd64.tar.gz" \ + && tar --directory /usr/local --extract --file "${GOLANG_VERSION}.linux-amd64.tar.gz" \ + && rm --force "${GOLANG_VERSION}.linux-amd64.tar.gz" + +# Put Golang in the path so that we can Delve with it. +ENV PATH=$PATH:/usr/local/go/bin + +# Build Delve and leave it in a temporary directory. +RUN GOBIN=/tmp/bin go install github.com/go-delve/delve/cmd/dlv@latest + +# Build the operator as normal. +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest + +LABEL maintainer = "KubeSaw " +LABEL author = "KubeSaw " + +# Ensure that the "DEBUG_MODE" is enabled so that the binary executes with +# Delve. +ENV DEBUG_MODE=true \ + OPERATOR=/usr/local/bin/member-operator \ + USER_UID=1001 \ + USER_NAME=member-operator \ + LANG=en_US.utf8 + +# Install the operator binary in the image. +COPY build/_output/bin/member-operator ${OPERATOR} + +COPY build/bin /usr/local/bin +RUN /usr/local/bin/user_setup + +# Copy Delve to the image so that we can execute the operator with it. +COPY --from=delve-builder /tmp/bin/dlv /usr/local/bin/dlv + +ENTRYPOINT ["/usr/local/bin/entrypoint"] + +# Expose the debugger's port. +EXPOSE 50000 + +USER ${USER_UID} diff --git a/build/Dockerfile.webhook.debug b/build/Dockerfile.webhook.debug new file mode 100644 index 00000000..c7139edb --- /dev/null +++ b/build/Dockerfile.webhook.debug @@ -0,0 +1,53 @@ +# Compile Delve in an intermediate step. +FROM registry.access.redhat.com/ubi8/ubi:latest AS delve-builder + +# The Golang version must be provided as a build arguments, which will ensure +# that Delve gets built with the same version the operator's binary gets built +# with, to avoid any discrepancies. +ARG GOLANG_VERSION + +# Install Tar to be able to extract Golang. +RUN yum install --assumeyes \ + tar \ + && yum clean all + +# Download and extract Golang. +RUN curl --location --output "${GOLANG_VERSION}.linux-amd64.tar.gz" "https://go.dev/dl/${GOLANG_VERSION}.linux-amd64.tar.gz" \ + && tar --directory /usr/local --extract --file "${GOLANG_VERSION}.linux-amd64.tar.gz" \ + && rm --force "${GOLANG_VERSION}.linux-amd64.tar.gz" + +# Put Golang in the path so that we can Delve with it. +ENV PATH=$PATH:/usr/local/go/bin + +# Build Delve and leave it in a temporary directory. +RUN GOBIN=/tmp/bin go install github.com/go-delve/delve/cmd/dlv@latest + +# Build the operator as normal. +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest + +LABEL maintainer = "KubeSaw " +LABEL author = "KubeSaw " + +# Ensure that the "DEBUG_MODE" is enabled so that the binary executes with +# Delve. +ENV DEBUG_MODE=true \ + WEBHOOK=/usr/local/bin/member-operator-webhook \ + USER_UID=1001 \ + USER_NAME=member-operator-webhook \ + LANG=en_US.utf8 + +# Install the operator binary in the image. +COPY build/_output/bin/member-operator-webhook ${WEBHOOK} + +COPY build/bin /usr/local/bin +RUN /usr/local/bin/user_setup + +# Copy Delve to the image so that we can execute the operator with it. +COPY --from=delve-builder /tmp/bin/dlv /usr/local/bin/dlv + +ENTRYPOINT ["/usr/local/bin/entrypoint"] + +# Expose the debugger's port. +EXPOSE 50000 + +USER ${USER_UID} diff --git a/build/bin/entrypoint b/build/bin/entrypoint index e23fa717..28c06f97 100755 --- a/build/bin/entrypoint +++ b/build/bin/entrypoint @@ -9,4 +9,9 @@ if ! whoami &>/dev/null; then fi fi -exec ${OPERATOR} $@ +if [ -n "${DEBUG_MODE}" ] +then + exec /usr/local/bin/dlv --listen=:50000 --headless --continue --api-version=2 --accept-multiclient exec "${OPERATOR}" "$@" +else + exec ${OPERATOR} "$@" +fi diff --git a/make/go.mk b/make/go.mk index c905ce41..05a40247 100644 --- a/make/go.mk +++ b/make/go.mk @@ -23,6 +23,25 @@ $(OUT_DIR)/operator: -o $(OUT_DIR)/bin/member-operator-webhook \ cmd/webhook/main.go +.PHONY: build-debug +## Build the operator's image with Delve on it so that it is ready to attach a +## debugger to it. +build-debug: + @echo "building member-operator in ${GO_PACKAGE_PATH}" + $(Q)go version + $(Q)CGO_ENABLED=0 GOARCH=${goarch} GOOS=linux \ + go build ${V_FLAG} \ + -gcflags "all=-N -l" \ + -ldflags "-X ${GO_PACKAGE_PATH}/version.Commit=${GIT_COMMIT_ID} -X ${GO_PACKAGE_PATH}/version.BuildTime=${BUILD_TIME}" \ + -o $(OUT_DIR)/bin/member-operator \ + ./cmd/main.go + $(Q)CGO_ENABLED=0 GOARCH=${goarch} GOOS=linux \ + go build ${V_FLAG} \ + -gcflags "all=-N -l" \ + -ldflags "-X ${GO_PACKAGE_PATH}/version.Commit=${GIT_COMMIT_ID} -X ${GO_PACKAGE_PATH}/version.BuildTime=${BUILD_TIME}" \ + -o $(OUT_DIR)/bin/member-operator-webhook \ + cmd/webhook/main.go + .PHONY: vendor vendor: $(Q)go mod vendor diff --git a/make/podman.mk b/make/podman.mk index e637e7bc..a6c00d7f 100644 --- a/make/podman.mk +++ b/make/podman.mk @@ -12,12 +12,24 @@ podman-image: build $(Q)podman build --platform ${IMAGE_PLATFORM} -f build/Dockerfile -t ${IMAGE} . $(Q)podman build --platform ${IMAGE_PLATFORM} -f build/Dockerfile.webhook -t ${WEBHOOK_IMAGE} . +## Build the operator's image with Delve on it so that it is ready to attach a +## debugger to it. +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} . + .PHONY: podman-push ## Push the binary image to quay.io registry podman-push: check-namespace podman-image $(Q)podman push ${IMAGE} $(Q)podman push ${WEBHOOK_IMAGE} +.PHONY: podman-push-debug +## Push the image with the debugger in it to the repository. +podman-push-debug: check-namespace podman-image-debug + $(Q)podman push ${IMAGE} + $(Q)podman push ${WEBHOOK_IMAGE} + .PHONY: check-namespace check-namespace: ifeq ($(QUAY_NAMESPACE),${GO_PACKAGE_ORG_NAME})