From d96ad649e9d37029b73805ef4d5e11529c72151f Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Thu, 2 Jan 2025 21:25:18 +0100 Subject: [PATCH] Add support for remote debugging (#1048) --- .run/local debug.run.xml | 7 +++++++ README.md | 21 +++++++++++++++++++++ main.go | 14 ++++++++++++-- makefile | 14 +++++++++++++- 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 .run/local debug.run.xml diff --git a/.run/local debug.run.xml b/.run/local debug.run.xml new file mode 100644 index 000000000..5c41dce35 --- /dev/null +++ b/.run/local debug.run.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index e38727285..d54faece8 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,27 @@ This project uses [Go Modules](https://github.com/golang/go/wiki/Modules) for de After cloning the repository, you can build the project by running `make build`. +### Debugging + +We support remote debugging via [delve](https://github.com/go-delve/delve) via the make target `build-debug` and `run-debug`. + +To debug the plugin, proceed as follows: +1) Run `make build-debug` +2) Run `make run-debug` +3) Attach a remote debugger to the printed local address, e.g. `127.0.0.1:58772` from your IDE. +4) Copy the `TF_REATTACH_PROVIDERS='{...}'` env variable, that is printed by the delve debugger after attachment. +5) In a separate terminal prepend the `TF_REATTACH_PROVIDERS='{...}'` env variable to your `terraform ...` command + +Note that we use the delve options to wait for a debugger. This allows us to debug the complete +plugin lifecycle. + +Note for Goland users, there is a preconfigured remote debugger configuration called `local debug`. + +### Debugging Example + +The easiest way to play with the remote debugger setup is the bundled example project. +To use that run `make build-example-debug` and follow the steps above. + ### Local Environment You can spin up a local developer environment via [Docker Compose](https://docs.docker.com/compose/) by running `make local`. diff --git a/main.go b/main.go index 9281920b9..8369a6851 100644 --- a/main.go +++ b/main.go @@ -1,15 +1,25 @@ package main import ( + "flag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" "github.com/keycloak/terraform-provider-keycloak/provider" ) func main() { - plugin.Serve(&plugin.ServeOpts{ + + var debugMode bool + flag.BoolVar(&debugMode, "debug", false, "set to true to run the provider with support for debuggers like delve") + flag.Parse() + + opts := &plugin.ServeOpts{ ProviderFunc: func() *schema.Provider { return provider.KeycloakProvider(nil) }, - }) + Debug: debugMode, + // using local provider address for debugging: + ProviderAddr: "terraform.local/keycloak/keycloak", + } + plugin.Serve(opts) } diff --git a/makefile b/makefile index 0137b9807..5c38dedf2 100644 --- a/makefile +++ b/makefile @@ -9,12 +9,24 @@ VERSION=$$(git describe --tags) build: CGO_ENABLED=0 go build -trimpath -ldflags "-s -w -X main.version=$(VERSION)" -o terraform-provider-keycloak_$(VERSION) -build-example: build +build-debug: + # keep debug info in the binary + CGO_ENABLED=0 go build -gcflags "all=-N -l" -trimpath -ldflags " -X main.version=$(VERSION)" -o terraform-provider-keycloak_$(VERSION) + +prepare-example: mkdir -p example/.terraform/plugins/terraform.local/keycloak/keycloak/4.5.0/$(GOOS)_$(GOARCH) mkdir -p example/terraform.d/plugins/terraform.local/keycloak/keycloak/4.5.0/$(GOOS)_$(GOARCH) cp terraform-provider-keycloak_* example/.terraform/plugins/terraform.local/keycloak/keycloak/4.5.0/$(GOOS)_$(GOARCH)/ cp terraform-provider-keycloak_* example/terraform.d/plugins/terraform.local/keycloak/keycloak/4.5.0/$(GOOS)_$(GOARCH)/ +build-example: build prepare-example + +build-example-debug: build-debug prepare-example + +run-debug: + echo "Starting delve debugger listening on port 127.0.0.1:58772" + dlv exec --listen=:58772 --accept-multiclient --headless "./terraform-provider-keycloak_$(VERSION)" -- -debug + local: deps user-federation-example docker compose up --build -d ./scripts/wait-for-local-keycloak.sh