diff --git a/README.adoc b/README.adoc index ebde4184a..304112c09 100644 --- a/README.adoc +++ b/README.adoc @@ -151,6 +151,14 @@ All e2e resources (host operator, member operator, registration-service, CRDs, e * `make dev-deploy-e2e-local` - deploys the same resources as `make test-e2e-local` in dev environment but doesn't run tests. +* `make dev-deploy-e2e-local-debug` - deploys the same resources as `make test-e2e-local` in the local OpenShift +instance, but builds the services and the operators without any code optimizations. It also ships Delve in the images, +and launches those services with it, which leaves the debugger listening on port `50000`. Then, you can simply `oc +port-forward ${POD} 50000:50000` and connect to them with your favorite IDE. The services that are built like that are: +** The registration service. +** The host operator controller manager. +** The member operator controller manager. + * `make dev-deploy-e2e` - deploys the same resources as `make test-e2e` in dev environment but doesn't run tests. * `make deploy-single-member-e2e-latest` - deploys the same resources (using the latest and greatest images of Toolchain operators) as `make test-e2e` but with only one member and doesn't run tests. diff --git a/make/dev.mk b/make/dev.mk index a9b4f5673..af6fe5d6f 100644 --- a/make/dev.mk +++ b/make/dev.mk @@ -39,6 +39,51 @@ setup-dev-sso: .PHONY: dev-deploy-e2e-local dev-deploy-e2e-local: deploy-e2e-local-to-dev-namespaces print-reg-service-link +# Builds the services' and operators' images with the debugger in it, so that +# then an IDE can be connected to them. Since the targets down the line use +# the default namespaces, we can use them to patch the required CRs in order +# to launch the binaries with Delve. +.ONESHELL: +.PHONY: dev-deploy-e2e-local-debug +dev-deploy-e2e-local-debug: export DEBUG_MODE=true +dev-deploy-e2e-local-debug: + $(MAKE) dev-deploy-e2e-local + + # Get the CSVs for the host and member operators, in order to be able to + # patch them. + HOST_CSV_NAME=$$(oc get --namespace="${DEFAULT_HOST_NS}" --output name ClusterServiceVersion) + MEMBER_CSV_NAME=$$(oc get --namespace="${DEFAULT_MEMBER_NS}" --output name ClusterServiceVersion) + + # Patch the host operator indicating which command the registration + # service should be run with. The command simply adds an environment + # variable to the operator which then makes sure that the registration + # service is run with Delve, in case the user wants to connect to it. + if ! oc get "${HOST_CSV_NAME}" --output jsonpath="{.spec.install.spec.deployments[0].spec.template.spec.containers[1].env}" | grep -q "REGISTRATION_SERVICE_COMMAND"; then \ + oc patch --namespace="${DEFAULT_HOST_NS}" "$${HOST_CSV_NAME}" --type='json' --patch='[{"op": "add", "path": "/spec/install/spec/deployments/0/spec/template/spec/containers/1/env/-", "value": {"name": "REGISTRATION_SERVICE_COMMAND", "value": "[\"dlv\", \"--listen=:50000\", \"--headless\", \"--continue\", \"--api-version=2\", \"--accept-multiclient\", \"exec\", \"/usr/local/bin/registration-service\"]"}}]' + + # Wait for the registration service's command to have the "dlv" bit, and the rollout for its deployment to be + # complete. + @echo "Waiting for the registration service's deployment to get updated..." + oc wait --namespace="${DEFAULT_HOST_NS}" --timeout=3m --for=jsonpath='{.spec.template.spec.containers[0].command[0]}'="dlv" "deployment/registration-service" + oc rollout status --namespace="${DEFAULT_HOST_NS}" --timeout=3m deployment/registration-service + fi + + # Reduce the registration service's replicas to 1, in order to facilitate + # the port forwarding and debugging of the service. + oc patch --namespace="${DEFAULT_HOST_NS}" ToolchainConfig config --type='merge' --patch='{"spec":{"host":{"registrationService":{"replicas":1}}}}' + @echo "Waiting for the registration service to get scaled to 1 replicas..." + oc wait --namespace="${DEFAULT_HOST_NS}" --timeout=3m --for=jsonpath='{.spec.replicas}'="1" "deployment/registration-service" + + # Patch the host-operator and member-operator CSVs to make them run with + # Delve. + oc patch --namespace="${DEFAULT_HOST_NS}" "$${HOST_CSV_NAME}" --type='json' --patch='[{"op": "replace", "path": "/spec/install/spec/deployments/0/spec/template/spec/containers/1/args", "value": []}, {"op": "replace", "path": "/spec/install/spec/deployments/0/spec/template/spec/containers/1/command", "value": ["dlv", "--listen=:50000", "--headless", "--continue", "--api-version=2", "--accept-multiclient", "exec", "/usr/local/bin/host-operator", "--", "--health-probe-bind-address=:8081", "--metrics-bind-address=127.0.0.1:8080", "--leader-elect"]}]' + @echo "Waiting for the host operator to be ready..." + oc wait --namespace "${DEFAULT_HOST_NS}" "$${HOST_CSV_NAME}" --for=jsonpath='{.status.phase}'=Succeeded --timeout=300s + + oc patch --namespace="${DEFAULT_MEMBER_NS}" "$${MEMBER_CSV_NAME}" --type='json' --patch='[{"op": "replace", "path": "/spec/install/spec/deployments/0/spec/template/spec/containers/0/args", "value": []}, {"op": "replace", "path": "/spec/install/spec/deployments/0/spec/template/spec/containers/0/command", "value": ["dlv", "--listen=:50000", "--headless", "--continue", "--api-version=2", "--accept-multiclient", "exec", "/usr/local/bin/member-operator", "--", "--health-probe-bind-address=:8081", "--metrics-bind-address=127.0.0.1:8080", "--leader-elect"]}]' + @echo "Waiting for the member operator to be ready..." + oc wait --namespace "${DEFAULT_HOST_NS}" "$${HOST_CSV_NAME}" --for=jsonpath='{.status.phase}'=Succeeded --timeout=300s + .PHONY: dev-deploy-e2e-local-two-members dev-deploy-e2e-local-two-members: deploy-e2e-local-to-dev-namespaces-two-members print-reg-service-link diff --git a/make/test.mk b/make/test.mk index c1653eb55..c2b90b024 100644 --- a/make/test.mk +++ b/make/test.mk @@ -331,6 +331,11 @@ ifneq (${FORCED_TAG},"") $(eval FORCED_TAG_PARAM = -ft ${FORCED_TAG}) endif endif +ifneq (${DEBUG_MODE},"") + ifneq (${DEBUG_MODE},) + $(eval DEBUG_MODE_PARAM = -dm ${DEBUG_MODE}) + endif +endif ifeq ($(DEPLOY_LATEST),true) @echo "Installing latest version of the member-operator in namespace ${MEMBER_NS}" ${KSCTL_BIN_DIR}ksctl adm install-operator member --kubeconfig "$(or ${KUBECONFIG}, ${HOME}/.kube/config)" --namespace ${MEMBER_NS} ${KSCTL_INSTALL_TIMEOUT_PARAM} -y @@ -340,7 +345,7 @@ ifeq ($(DEPLOY_LATEST),true) endif else @echo "Installing specific version of the member-operator" - scripts/ci/manage-member-operator.sh -po ${PUBLISH_OPERATOR} -io ${INSTALL_OPERATOR} -mn ${MEMBER_NS} ${MEMBER_REPO_PATH_PARAM} -qn ${QUAY_NAMESPACE} -ds ${DATE_SUFFIX} ${MEMBER_NS_2_PARAM} ${FORCED_TAG_PARAM} + scripts/ci/manage-member-operator.sh -po ${PUBLISH_OPERATOR} -io ${INSTALL_OPERATOR} -mn ${MEMBER_NS} ${MEMBER_REPO_PATH_PARAM} -qn ${QUAY_NAMESPACE} -ds ${DATE_SUFFIX} ${MEMBER_NS_2_PARAM} ${FORCED_TAG_PARAM} ${DEBUG_MODE_PARAM} endif .PHONY: get-and-publish-host-operator @@ -360,12 +365,17 @@ ifneq (${FORCED_TAG},"") $(eval FORCED_TAG_PARAM = -ft ${FORCED_TAG}) endif endif +ifneq (${DEBUG_MODE},"") + ifneq (${DEBUG_MODE},) + $(eval DEBUG_MODE_PARAM = -dm ${DEBUG_MODE}) + endif +endif ifeq ($(DEPLOY_LATEST),true) @echo "Installing latest version of the host-operator" ${KSCTL_BIN_DIR}ksctl adm install-operator host --kubeconfig "$(or ${KUBECONFIG}, ${HOME}/.kube/config)" --namespace ${HOST_NS} ${KSCTL_INSTALL_TIMEOUT_PARAM} -y else @echo "Installing specific version of the host-operator" - scripts/ci/manage-host-operator.sh -po ${PUBLISH_OPERATOR} -io ${INSTALL_OPERATOR} -hn ${HOST_NS} ${HOST_REPO_PATH_PARAM} -ds ${DATE_SUFFIX} -qn ${QUAY_NAMESPACE} ${REG_REPO_PATH_PARAM} ${FORCED_TAG_PARAM} + scripts/ci/manage-host-operator.sh -po ${PUBLISH_OPERATOR} -io ${INSTALL_OPERATOR} -hn ${HOST_NS} ${HOST_REPO_PATH_PARAM} -ds ${DATE_SUFFIX} -qn ${QUAY_NAMESPACE} ${REG_REPO_PATH_PARAM} ${FORCED_TAG_PARAM} ${DEBUG_MODE_PARAM} endif ########################################################### diff --git a/scripts/ci/manage-host-operator.sh b/scripts/ci/manage-host-operator.sh index 8918356c5..c18ab3462 100755 --- a/scripts/ci/manage-host-operator.sh +++ b/scripts/ci/manage-host-operator.sh @@ -11,6 +11,7 @@ user_help () { echo "-rr, --reg-repo-path Path to the registation service repo" echo "-ds, --date-suffix Date suffix to be added to some resources that are created" echo "-ft, --forced-tag Forces a tag to be set to all built images. In the case deployment the tag is used for index image in the created CatalogSource" + echo "-dm, --debug-mode Builds and pushes the operator to quay, including a Delve debugger to be able to launch the operator with it" echo "-h, --help To show this help text" echo "" exit 0 @@ -68,6 +69,11 @@ read_arguments() { FORCED_TAG=$1 shift ;; + -dm|--debug-mode) + shift + DEBUG_MODE=$1 + shift + ;; *) echo "$1 is not a recognized flag!" >> /dev/stderr user_help @@ -96,7 +102,7 @@ if [[ -n "${CI}${REG_REPO_PATH}${HOST_REPO_PATH}" ]] && [[ $(echo ${REPO_NAME} | set_tags if [[ ${PUBLISH_OPERATOR} == "true" ]]; then - push_image + push_image "${DEBUG_MODE}" REG_SERV_IMAGE_LOC=${IMAGE_LOC} REG_REPO_PATH=${REPOSITORY_PATH} fi @@ -108,7 +114,7 @@ if [[ -n "${CI}${REG_REPO_PATH}${HOST_REPO_PATH}" ]] && [[ $(echo ${REPO_NAME} | set_tags if [[ ${PUBLISH_OPERATOR} == "true" ]]; then - push_image + push_image "${DEBUG_MODE}" OPERATOR_IMAGE_LOC=${IMAGE_LOC} make -C ${REPOSITORY_PATH} publish-current-bundle INDEX_IMAGE_TAG=${BUNDLE_AND_INDEX_TAG} BUNDLE_TAG=${BUNDLE_AND_INDEX_TAG} QUAY_NAMESPACE=${QUAY_NAMESPACE} OTHER_REPO_PATH=${REG_REPO_PATH} OTHER_REPO_IMAGE_LOC=${REG_SERV_IMAGE_LOC} IMAGE=${OPERATOR_IMAGE_LOC} fi diff --git a/scripts/ci/manage-member-operator.sh b/scripts/ci/manage-member-operator.sh index 51584903f..b678775fe 100755 --- a/scripts/ci/manage-member-operator.sh +++ b/scripts/ci/manage-member-operator.sh @@ -11,6 +11,7 @@ user_help () { echo "-mr, --member-repo-path Path to the member operator repo" echo "-ds, --date-suffix Date suffix to be added to some resources that are created" echo "-ft, --forced-tag Forces a tag to be set to all built images. In the case deployment the tag is used for index image in the created CatalogSource" + echo "-dm, --debug-mode Builds and pushes the operator to quay, including a Delve debugger to be able to launch the operator with it" echo "-h, --help To show this help text" echo "" exit 0 @@ -67,6 +68,11 @@ read_arguments() { FORCED_TAG=$1 shift ;; + -dm|--debug-mode) + shift + DEBUG_MODE=$1 + shift + ;; *) echo "$1 is not a recognized flag!" >> /dev/stderr user_help @@ -95,7 +101,7 @@ if [[ -n "${CI}${MEMBER_REPO_PATH}" ]] && [[ $(echo ${REPO_NAME} | sed 's/"//g') set_tags if [[ ${PUBLISH_OPERATOR} == "true" ]]; then - push_image + push_image "${DEBUG_MODE}" OPERATOR_IMAGE_LOC=${IMAGE_LOC} make -C ${REPOSITORY_PATH} publish-current-bundle INDEX_IMAGE_TAG=${BUNDLE_AND_INDEX_TAG} BUNDLE_TAG=${BUNDLE_AND_INDEX_TAG} QUAY_NAMESPACE=${QUAY_NAMESPACE} IMAGE=${OPERATOR_IMAGE_LOC} diff --git a/scripts/ci/manage-operator.sh b/scripts/ci/manage-operator.sh index cb64a69f4..926c4ce3f 100755 --- a/scripts/ci/manage-operator.sh +++ b/scripts/ci/manage-operator.sh @@ -45,11 +45,21 @@ set_tags() { } push_image() { + # When the "${DEBUG_MODE}" argument is passed, we instruct Make to push + # the "debug" images with Delve on them. + if [[ $1 == "true" ]]; then + DEBUG_MODE_SUFFIX="-debug" + else + DEBUG_MODE_SUFFIX="" + fi + + # Set a default image builder in case none has been specified. + IMAGE_BUILDER="${IMAGE_BUILDER:-podman}" + GIT_COMMIT_ID=$(git --git-dir=${REPOSITORY_PATH}/.git --work-tree=${REPOSITORY_PATH} rev-parse --short HEAD) IMAGE_LOC=quay.io/codeready-toolchain/${REPOSITORY_NAME}:${GIT_COMMIT_ID} if is_provided_or_paired; then - IMAGE_BUILDER=${IMAGE_BUILDER:-"podman"} - make -C ${REPOSITORY_PATH} ${IMAGE_BUILDER}-push QUAY_NAMESPACE=${QUAY_NAMESPACE} IMAGE_TAG=${TAGS} + make -C ${REPOSITORY_PATH} ${IMAGE_BUILDER}-push${DEBUG_MODE_SUFFIX} QUAY_NAMESPACE=${QUAY_NAMESPACE} IMAGE_TAG=${TAGS} IMAGE_LOC=quay.io/${QUAY_NAMESPACE}/${REPOSITORY_NAME}:${TAGS} fi }