Browse Source

feat: introduce tilt into the development process (#2966)

Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
Gergely Brautigam 2 years ago
parent
commit
0bbfb1b954
5 changed files with 147 additions and 0 deletions
  1. 25 0
      Makefile
  2. 93 0
      Tiltfile
  3. 12 0
      docs/contributing/devguide.md
  4. 12 0
      tilt.debug.dockerfile
  5. 5 0
      tilt.dockerfile

+ 25 - 0
Makefile

@@ -154,6 +154,9 @@ crds.install: generate ## Install CRDs into a cluster. This is for convenience
 crds.uninstall: ## Uninstall CRDs from a cluster. This is for convenience
 	kubectl delete -f $(BUNDLE_DIR)
 
+tilt-up: tilt manifests ## Generates the local manifests that tilt will use to deploy the controller's objects.
+	$(LOCALBIN)/tilt up
+
 # ====================================================================================
 # Helm Chart
 
@@ -293,18 +296,34 @@ clean:  ## Clean bins
 # ====================================================================================
 # Build Dependencies
 
+ifeq ($(OS),Windows_NT)     # is Windows_NT on XP, 2000, 7, Vista, 10...
+    detected_OS := windows
+    arch := x86_64
+else
+    detected_OS := $(shell uname -s)
+    arch := $(shell uname -m)
+    ifeq ($(detected_OS),Darwin)
+    	detected_OS := mac
+    endif
+    ifeq ($(detected_OS),Linux)
+    	detected_OS := linux
+    endif
+endif
+
 ## Location to install dependencies to
 LOCALBIN ?= $(shell pwd)/bin
 $(LOCALBIN):
 	mkdir -p $(LOCALBIN)
 
 ## Tool Binaries
+TILT ?= $(LOCALBIN)/tilt
 ENVTEST ?= $(LOCALBIN)/setup-envtest
 GOLANGCI_LINT ?= $(LOCALBIN)/golangci-lint
 
 ## Tool Versions
 GOLANGCI_VERSION := 1.54.2
 KUBERNETES_VERSION := 1.28.x
+TILT_VERSION := 0.33.10
 
 .PHONY: envtest
 envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
@@ -317,3 +336,9 @@ golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
 $(GOLANGCI_LINT): $(LOCALBIN)
 	test -s $(LOCALBIN)/golangci-lint && $(LOCALBIN)/golangci-lint version --format short | grep -q $(GOLANGCI_VERSION) || \
 	curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(LOCALBIN) v$(GOLANGCI_VERSION)
+
+.PHONY: tilt
+.PHONY: $(TILT)
+tilt: $(TILT) ## Download tilt locally if necessary. Architecture is locked at x86_64.
+$(TILT): $(LOCALBIN)
+	test -s $(LOCALBIN)/tilt || curl -fsSL https://github.com/tilt-dev/tilt/releases/download/v$(TILT_VERSION)/tilt.$(TILT_VERSION).$(detected_OS).$(arch).tar.gz | tar -xz -C $(LOCALBIN) tilt

+ 93 - 0
Tiltfile

@@ -0,0 +1,93 @@
+# -*- mode: Python -*-
+
+kubectl_cmd = "kubectl"
+
+# verify kubectl command exists
+if str(local("command -v " + kubectl_cmd + " || true", quiet = True)) == "":
+    fail("Required command '" + kubectl_cmd + "' not found in PATH")
+
+# set defaults
+settings = {
+    "debug": {
+        "enabled": False,
+    },
+}
+
+# merge default settings with user defined settings
+tilt_file = "./tilt-settings.yaml" if os.path.exists("./tilt-settings.yaml") else "./tilt-settings.json"
+settings.update(read_yaml(
+    tilt_file,
+    default = {},
+))
+# set up the development environment
+
+# Update the root security group. Tilt requires root access to update the
+# running process.
+objects = decode_yaml_stream(read_file('bin/deploy/manifests/external-secrets.yaml'))
+for o in objects:
+    if o.get('kind') == 'Deployment' and o.get('metadata').get('name') in ['external-secrets-cert-controller', 'external-secrets', 'external-secrets-webhook']:
+        o['spec']['template']['spec']['securityContext'] = {'runAsNonRoot': False}
+        o['spec']['template']['spec']['imagePullPolicy'] = 'Always'
+        if settings.get('debug').get('enabled') and o.get('metadata').get('name') == 'external-secrets':
+            o['spec']['template']['spec']['containers'][0]['ports'] = [{'containerPort': 30000}]
+
+
+updated_install = encode_yaml_stream(objects)
+
+# Apply the updated yaml to the cluster.
+k8s_yaml(updated_install, allow_duplicates = True)
+
+load('ext://restart_process', 'docker_build_with_restart')
+
+# enable hot reloading by doing the following:
+# - locally build the whole project
+# - create a docker imagine using tilt's hot-swap wrapper
+# - push that container to the local tilt registry
+# Once done, rebuilding now should be a lot faster since only the relevant
+# binary is rebuilt and the hot swat wrapper takes care of the rest.
+gcflags = ''
+if settings.get('debug').get('enabled'):
+    gcflags = '-N -l'
+
+local_resource(
+    'external-secret-binary',
+    "CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags '{gcflags}' -v -o bin/external-secrets ./".format(gcflags=gcflags),
+    deps = [
+        "main.go",
+        "go.mod",
+        "go.sum",
+        "apis",
+        "cmd",
+        "pkg",
+    ],
+)
+
+
+# Build the docker image for our controller. We use a specific Dockerfile
+# since tilt can't run on a scratch container.
+# `only` here is important, otherwise, the container will get updated
+# on _any_ file change. We only want to monitor the binary.
+# If debugging is enabled, we switch to a different docker file using
+# the delve port.
+entrypoint = ['/external-secrets']
+dockerfile = 'tilt.dockerfile'
+if settings.get('debug').get('enabled'):
+    k8s_resource('external-secrets', port_forwards=[
+        port_forward(30000, 30000, 'debugger'),
+    ])
+    entrypoint = ['/dlv', '--listen=:30000', '--api-version=2', '--continue=true', '--accept-multiclient=true', '--headless=true', 'exec', '/external-secrets', '--']
+    dockerfile = 'tilt.debug.dockerfile'
+
+
+docker_build_with_restart(
+    'ghcr.io/external-secrets/external-secrets',
+    '.',
+    dockerfile = dockerfile,
+    entrypoint = entrypoint,
+    only=[
+      './bin',
+    ],
+    live_update = [
+        sync('./bin/external-secrets', '/external-secrets'),
+    ],
+)

+ 12 - 0
docs/contributing/devguide.md

@@ -40,6 +40,18 @@ Build the documentation:
 make docs
 ```
 
+## Using Tilt
+
+[Tilt](https://tilt.dev) can be used to develop external-secrets. Tilt will hot-reload changes to the code and replace
+the running binary in the container using a process manager of its own.
+
+To run tilt, download the utility for your operating system and run `make tilt-up`. This will do two things:
+- downloads tilt for the current OS and ARCH under `bin/tilt`
+- make manifest files of your current changes and place them under `./bin/deploy/manifests/external-secrets.yaml`
+- run tilt with `tilt run`
+
+Hit `space` and you can observe all the pods starting up and track their output in the tilt UI.
+
 ## Installing
 
 To install the External Secret Operator into a Kubernetes Cluster run:

+ 12 - 0
tilt.debug.dockerfile

@@ -0,0 +1,12 @@
+FROM golang:1.20.1
+WORKDIR /
+COPY ./bin/external-secrets /external-secrets
+
+RUN go install github.com/go-delve/delve/cmd/dlv@latest
+RUN chmod +x /go/bin/dlv
+RUN mv /go/bin/dlv /
+
+EXPOSE 30000
+
+# dlv --listen=:30000 --api-version=2 --headless=true exec /app/build/api
+ENTRYPOINT ["/dlv", "--listen=:30000", "--api-version=2", "--headless=true", "--continue=true", "--accept-multiclient=true", "exec", "/external-secrets", "--"]

+ 5 - 0
tilt.dockerfile

@@ -0,0 +1,5 @@
+FROM alpine
+WORKDIR /
+COPY ./bin/external-secrets /external-secrets
+
+ENTRYPOINT ["/external-secrets"]