Repository: rancher/fleet
Pull request #2966 (2024-10-21 08:31:40)

Update docs for testing Fleet in Rancher
This removes docs living in `docs` on this topic, as they are now obsolete, and expands `dev/README.md` to cover specific values to set when testing a custom Fleet build in Rancher.

Refers to #1640.


Patch:
diff --git a/charts/fleet/ci/debug-values.yaml b/charts/fleet/ci/debug-values.yaml
index f495e1f6..ab519706 100644
--- a/charts/fleet/ci/debug-values.yaml
+++ b/charts/fleet/ci/debug-values.yaml
@@ -25,6 +25,7 @@ metrics:
 debug: true
 debugLevel: 4
 propagateDebugSettingsToAgents: true
+disableSecurityContext: true
 
 cpuPprof:
   period: "60s"
diff --git a/charts/fleet/templates/deployment.yaml b/charts/fleet/templates/deployment.yaml
index 025eb071..f2c0d324 100644
--- a/charts/fleet/templates/deployment.yaml
+++ b/charts/fleet/templates/deployment.yaml
@@ -45,14 +45,6 @@ spec:
         - name: NO_PROXY
           value: {{ $.Values.noProxy }}
         {{- end }}
-        {{- if $.Values.cpuPprof }}
-        - name: FLEET_CPU_PPROF_DIR
-          value: /tmp/pprof/
-        {{- end }}
-        {{- if $.Values.cpuPprof }}
-        - name: FLEET_CPU_PPROF_PERIOD
-          value: {{ quote $.Values.cpuPprof.period }}
-        {{- end }}
         {{- if $.Values.leaderElection.leaseDuration }}
         - name: CATTLE_ELECTION_LEASE_DURATION
           value: {{$.Values.leaderElection.leaseDuration}}
@@ -101,7 +93,8 @@ spec:
         - --debug
         - --debug-level
         - {{ quote $.Values.debugLevel }}
-        {{- else }}
+        {{- end }}
+        {{- if not $.Values.disableSecurityContext }}
         securityContext:
           allowPrivilegeEscalation: false
           readOnlyRootFilesystem: true
@@ -113,10 +106,6 @@ spec:
         volumeMounts:
           - mountPath: /tmp
             name: tmp
-        {{- if $.Values.cpuPprof }}
-          - mountPath: /tmp/pprof
-            name: pprof
-        {{- end }}
       {{- if not $shard.id }} # Only deploy cleanup and agent management through sharding-less deployment
       - env:
         - name: NAMESPACE
@@ -161,7 +150,8 @@ spec:
         - --debug
         - --debug-level
         - {{ quote $.Values.debugLevel }}
-        {{- else }}
+        {{- end }}
+        {{- if not $.Values.disableSecurityContext }}
         securityContext:
           allowPrivilegeEscalation: false
           readOnlyRootFilesystem: true
@@ -206,7 +196,8 @@ spec:
         - --debug
         - --debug-level
         - {{ quote $.Values.debugLevel }}
-        {{- else }}
+        {{- end }}
+        {{- if not $.Values.disableSecurityContext }}
         securityContext:
           allowPrivilegeEscalation: false
           readOnlyRootFilesystem: true
@@ -219,9 +210,6 @@ spec:
       volumes:
         - name: tmp
           emptyDir: {}
-      {{- if $.Values.cpuPprof }}
-        - name: pprof {{ toYaml $.Values.cpuPprof.volumeConfiguration | nindent 10 }}
-      {{- end }}
 
       serviceAccountName: fleet-controller
       nodeSelector: {{ include "linux-node-selector" $shard.id | nindent 8 }}
@@ -241,7 +229,7 @@ spec:
       priorityClassName: "{{$.Values.priorityClassName}}"
       {{- end }}
 
-{{- if not $.Values.debug }}
+{{- if not $.Values.disableSecurityContext }}
       securityContext:
         runAsNonRoot: true
         runAsUser: 1000
diff --git a/charts/fleet/templates/deployment_gitjob.yaml b/charts/fleet/templates/deployment_gitjob.yaml
index 5c3df960..686608d1 100644
--- a/charts/fleet/templates/deployment_gitjob.yaml
+++ b/charts/fleet/templates/deployment_gitjob.yaml
@@ -93,7 +93,8 @@ spec:
           {{- if $.Values.debug }}
             - name: CATTLE_DEV_MODE
               value: "true"
-          {{- else }}
+          {{- end }}
+          {{- if not $.Values.disableSecurityContext }}
           securityContext:
             allowPrivilegeEscalation: false
             readOnlyRootFilesystem: true
@@ -122,7 +123,7 @@ spec:
       priorityClassName: "{{$.Values.priorityClassName}}"
       {{- end }}
 
-{{- if not $.Values.debug }}
+{{- if not $.Values.disableSecurityContext }}
       securityContext:
         runAsNonRoot: true
         runAsUser: 1000
diff --git a/charts/fleet/values.yaml b/charts/fleet/values.yaml
index b0d289c2..6e9d8744 100644
--- a/charts/fleet/values.yaml
+++ b/charts/fleet/values.yaml
@@ -84,15 +84,7 @@ metrics:
 debug: false
 debugLevel: 0
 propagateDebugSettingsToAgents: true
-
-## Optional CPU pprof configuration. Profiles are collected continuously and saved every period
-## Any valid volume configuration can be provided, the example below uses hostPath
-# cpuPprof:
-#   period: "60s"
-#   volumeConfiguration:
-#     hostPath:
-#       path: /tmp/pprof
-#       type: DirectoryOrCreate
+disableSecurityContext: false
 
 migrations:
   clusterRegistrationCleanup: true
diff --git a/dev/README.md b/dev/README.md
index 13919583..e9bba422 100644
--- a/dev/README.md
+++ b/dev/README.md
@@ -4,8 +4,8 @@ Instructions on writing useful, well-formatted log messages can be found [here](
 
 # Testing: Dev Scripts
 
-These scripts are used for running tests locally in k3d. Don't use these on
-production systems.
+These scripts are used for running tests locally in [k3d](https://github.com/rancher/k3d).
+Don't use these on production systems.
 
 ## Requirements
 
@@ -18,6 +18,14 @@ production systems.
 - kubectl
 - ...
 
+### For Mac users
+
+On Mac OS, Docker runs in a virtual machine. This means the network setup is more complicated.
+
+> If you are unsure about which method you would like use for tunneling to localhost, we recommend [ngrok](https://ngrok.com).
+
+More info [here](https://github.com/rancher/rancher/wiki/Setting-Up-Rancher-Development-Environment#ngrok).
+
 ## Running Tests on K3D
 
 These commands should set up k3d and the fleet standalone images for single
@@ -65,11 +73,37 @@ other existing Fleet chart versions.
 export CHARTS_BRANCH=<branch_created_in_previous_step>
 ```
 3. Ensuring you have access to a running cluster in which to install Rancher.
-
-4. Running script `dev/setup-rancher-with-dev-fleet`, which will install Rancher
+For instance, a set of k3d clusters (1 upstream + 1 downstream) can be created
+on your local machine through `dev/setup-k3ds`.
+
+4. Commenting out the pairs of lines (name + value) setting the following
+values for installing Rancher through Helm in script
+`dev/setup-rancher-with-dev-fleet`, to match the location and version of the
+Fleet build generated in step 1:
+* `--set extraEnv[0].name=CATTLE_FLEET_VERSION \` to use a custom Fleet version,
+otherwise Rancher will use the version pinned in its
+[settings](https://github.com/rancher/rancher/blob/main/build.yaml#L5).
+* `--set extraEnv[0].value=999.9.9+up9.9.9 \` to match the version from step 1.
+* `--set extraEnv[1].name=CATTLE_CHART_DEFAULT_URL \` to set a custom chart URL
+* `--set extraEnv[1].value=https://github.com/fleetrepoci/charts \`: this is the
+custom charts repository used in step 1 by default.
+Change it to a different URL if you have specified one in that step.
+* `--set extraEnv[2].name=CATTLE_CHART_DEFAULT_BRANCH \` to set a custom chart
+repo branch.
+* `--set extraEnv[2].value=$branch \`: this must match the branch name created
+in step 1.
+* `--set rancherImageTag=$tag \`: only needed for custom Rancher builds.
+If you have not built Rancher yourself, this is typically not needed and you
+can leave it commented out.
+
+5. Running script `dev/setup-rancher-with-dev-fleet`, which will install Rancher
 using Helm, including test Fleet charts generated earlier. Once it is done,
 single- or multi-cluster test suites can be run against an actual Rancher setup.
 
+This also enables use of the Rancher UI, after opening the URL output by Helm
+when installing the Rancher chart, then logging in using the `bootstrapPassword`
+set in that script.
+
 ## Configuration
 
 ### Running scripts manually
@@ -392,21 +426,6 @@ container image and simply re-used it. You can remove it yourself, either by
 
 This container image will have `act` in his name.
 
-#### Using `act` fails
-
-**Error: The runs.using key in action.yml must be one of: [composite docker node12 node16], got node20**
-
-[action-tmate](https://github.com/mxschmitt/action-tmate) was updated recently
-and switched the value of `runs.using` from `node16` in version
-[3.16](https://github.com/mxschmitt/action-tmate/blob/v3.16/action.yml) to
-`node20` in version
-[3.17](https://github.com/mxschmitt/action-tmate/blob/v3.17/action.yml#L7),
-which is not yet supported by `act`! But an issue for act with a [corresponding
-PR](https://github.com/nektos/act/pull/1988) already exists.
-
-A temporary workaround is to comment the step in the workflow file out which
-includes `tmate`.
-
 ## Monitoring
 
 This sections describes how to add a monitoring stack to your development
diff --git a/docs/performance.md b/docs/performance.md
index eed2610a..7fbadb6b 100644
--- a/docs/performance.md
+++ b/docs/performance.md
@@ -11,34 +11,4 @@ For example: you may encounter a pod with high compute usage, but that could be
 
 [http pprof](https://pkg.go.dev/net/http/pprof) handlers are enabled by default with all [default profiles](https://pkg.go.dev/runtime/pprof#Profile) under the `/debug/pprof` prefix.
 
-Additionally, it is possible to enable continuous CPU profiling for `fleetcontroller` to observe how CPU usage changes over time.
-
-Add the following extra Helm values:
-```yaml
-cpuPprof:
-  period: "60s"
-  volumeConfiguration:
-    hostPath:
-      path: /tmp/pprof
-      type: DirectoryOrCreate
-```
-
-Notes:
- - `period` is the pprof CPU period and can be changed with any other value
- - `volumeConfiguration` can be any valid volume configuration (not necessarily `hostPath`)
-
-Alternatively, use the following Helm commandline arguments:
-```
---set cpuPprof.period=60s \
---set cpuPprof.volumeConfiguration.hostPath.path=/tmp/pprof \
---set cpuPprof.volumeConfiguration.hostPath.type=DirectoryOrCreate \
-```
-
-If using `hostPath`, make sure that the target directory (`/tmp/pprof` in above examples) is writable.
-
-Profiles can be inspected with the [pprof tool](https://github.com/google/pprof), eg.:
-
-```sh
-pprof -http=localhost:5000 ./2022-11-04_19_47_18.pprof.fleetcontroller.samples.cpu.pb.gz
-```
-
+To collect profiling information continuously one can use https://github.com/rancherlabs/support-tools/tree/master/collection/rancher/v2.x/profile-collector
diff --git a/go.mod b/go.mod
index a890c7d5..42929d4d 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,6 @@ require (
 	github.com/go-playground/webhooks/v6 v6.4.0
 	github.com/gobwas/glob v0.2.3
 	github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
-	github.com/golang/mock v1.6.0
 	github.com/google/go-cmp v0.6.0
 	github.com/google/go-containerregistry v0.20.2
 	github.com/gorilla/mux v1.8.1
@@ -39,13 +38,13 @@ require (
 	github.com/prometheus/common v0.60.0
 	github.com/rancher/fleet/pkg/apis v0.10.0
 	github.com/rancher/lasso v0.0.0-20240924233157-8f384efc8813
-	github.com/rancher/wrangler/v3 v3.0.0
+	github.com/rancher/wrangler/v3 v3.0.1-rc.3
 	github.com/reugn/go-quartz v0.13.0
 	github.com/sirupsen/logrus v1.9.3
 	github.com/spf13/cobra v1.8.1
 	github.com/stretchr/testify v1.9.0
-	github.com/testcontainers/testcontainers-go v0.33.0
-	go.uber.org/mock v0.4.0
+	github.com/testcontainers/testcontainers-go v0.34.0
+	go.uber.org/mock v0.5.0
 	go.uber.org/zap v1.27.0
 	golang.org/x/crypto v0.28.0
 	golang.org/x/sync v0.8.0
@@ -101,7 +100,7 @@ require (
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
 	github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
-	github.com/cpuguy83/dockercfg v0.3.1 // indirect
+	github.com/cpuguy83/dockercfg v0.3.2 // indirect
 	github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
 	github.com/cyphar/filepath-securejoin v0.3.1 // indirect
 	github.com/distribution/reference v0.6.0 // indirect
@@ -249,7 +248,7 @@ require (
 	k8s.io/apiserver v0.31.1 // indirect
 	k8s.io/code-generator v0.31.1 // indirect
 	k8s.io/component-base v0.31.1 // indirect
-	k8s.io/gengo v0.0.0-20240310015720-9cff6334dab4 // indirect
+	k8s.io/gengo v0.0.0-20240826214909-a7b603a56eb7 // indirect
 	k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7 // indirect
 	oras.land/oras-go v1.2.5 // indirect
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
diff --git a/go.sum b/go.sum
index 575e4b48..03922c20 100644
--- a/go.sum
+++ b/go.sum
@@ -288,8 +288,8 @@ github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpS
 github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
 github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
 github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
-github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
-github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
+github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
+github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
 github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
 github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -427,7 +427,6 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
 github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
 github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
-github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
 github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -735,8 +734,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg
 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
 github.com/rancher/lasso v0.0.0-20240924233157-8f384efc8813 h1:V/LY8pUHZG9Kc+xEDWDOryOnCU6/Q+Lsr9QQEQnshpU=
 github.com/rancher/lasso v0.0.0-20240924233157-8f384efc8813/go.mod h1:IxgTBO55lziYhTEETyVKiT8/B5Rg92qYiRmcIIYoPgI=
-github.com/rancher/wrangler/v3 v3.0.0 h1:IHHCA+vrghJDPxjtLk4fmeSCFhNe9fFzLFj3m2B0YpA=
-github.com/rancher/wrangler/v3 v3.0.0/go.mod h1:Dfckuuq7MJk2JWVBDywRlZXMxEyPxHy4XqGrPEzu5Eg=
+github.com/rancher/wrangler/v3 v3.0.1-rc.3 h1:C2d1GoP500SEFARVcb6EpbcNaXH3i8Yu9fzAe/0n4C0=
+github.com/rancher/wrangler/v3 v3.0.1-rc.3/go.mod h1:gUPHS1ANs2NyByfeERHwkGiQ1rlIa8BpTJZtNSgMlZw=
 github.com/reugn/go-quartz v0.13.0 h1:0eMxvj28Qu1npIDdN9Mzg9hwyksGH6XJt4Cz0QB8EUk=
 github.com/reugn/go-quartz v0.13.0/go.mod h1:0ghKksELp8MJ4h84T203aTHRF3Kug5BrxEW3ErBvhzY=
 github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
@@ -791,8 +790,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
-github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8=
+github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
+github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
 github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
 github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
 github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
@@ -859,8 +858,8 @@ go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93V
 go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
-go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
+go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
+go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
 go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
 go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
@@ -1475,8 +1474,8 @@ k8s.io/code-generator v0.31.1 h1:GvkRZEP2g2UnB2QKT2Dgc/kYxIkDxCHENv2Q1itioVs=
 k8s.io/code-generator v0.31.1/go.mod h1:oL2ky46L48osNqqZAeOcWWy0S5BXj50vVdwOtTefqIs=
 k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8=
 k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w=
-k8s.io/gengo v0.0.0-20240310015720-9cff6334dab4 h1:v8TcVKY4HxDaiNH8xnHEEGfx80twQJL9cOQuhd55fcY=
-k8s.io/gengo v0.0.0-20240310015720-9cff6334dab4/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
+k8s.io/gengo v0.0.0-20240826214909-a7b603a56eb7 h1:HCbtr1pVu/ElMcTTs18KdMtH5y6f7PQvrjh1QZj3qCI=
+k8s.io/gengo v0.0.0-20240826214909-a7b603a56eb7/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7 h1:cErOOTkQ3JW19o4lo91fFurouhP8NcoBvb7CkvhZZpk=
 k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
 k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
diff --git a/internal/cmd/cli/deploy.go b/internal/cmd/cli/deploy.go
index be4334c5..7cb87e42 100644
--- a/internal/cmd/cli/deploy.go
+++ b/internal/cmd/cli/deploy.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/spf13/cobra"
 	"helm.sh/helm/v3/pkg/cli"
+	"helm.sh/helm/v3/pkg/release"
 	"k8s.io/apimachinery/pkg/runtime"
 
 	command "github.com/rancher/fleet/internal/cmd"
@@ -117,17 +118,12 @@ func (d *Deploy) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	if d.DryRun {
-		resources, err := helmdeployer.Template(ctx, bd.Name, manifest, bd.Spec.Options, d.KubeVersion)
+		rel, err := helmdeployer.Template(ctx, bd.Name, manifest, bd.Spec.Options, d.KubeVersion)
 		if err != nil {
 			return err
 		}
-		b, err = yaml.Marshal(resources)
-		if err != nil {
-			return err
-		}
-		cmd.Println(string(b))
 
-		return nil
+		return printRelease(cmd, rel)
 	}
 
 	cfg := ctrl.GetConfigOrDie()
@@ -159,17 +155,29 @@ func (d *Deploy) Run(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
-	release, err := deployer.Deploy(ctx, bd.Name, manifest, bd.Spec.Options)
+	rel, err := deployer.Deploy(ctx, bd.Name, manifest, bd.Spec.Options)
 	if err != nil {
 		return err
 	}
 
-	objects, err := helmdeployer.ReleaseToObjects(release)
+	return printRelease(cmd, rel)
+}
+
+func printRelease(cmd *cobra.Command, rel *release.Release) error {
+	resources, err := wyaml.ToObjects(bytes.NewBufferString(rel.Manifest))
 	if err != nil {
 		return err
 	}
 
-	b, err = yaml.Marshal(objects)
+	for _, h := range rel.Hooks {
+		hookResources, err := wyaml.ToObjects(bytes.NewBufferString(h.Manifest))
+		if err != nil {
+			return err
+		}
+		resources = append(resources, hookResources...)
+	}
+
+	b, err := yaml.Marshal(resources)
 	if err != nil {
 		return err
 	}
diff --git a/internal/cmd/cli/match/match.go b/internal/cmd/cli/match/match.go
index d877aa73..c6b5eebd 100644
--- a/internal/cmd/cli/match/match.go
+++ b/internal/cmd/cli/match/match.go
@@ -89,7 +89,12 @@ func printMatch(ctx context.Context, bundle *fleet.Bundle, target *fleet.BundleT
 
 	manifest := manifest.New(bundle.Spec.Resources)
 
-	objs, err := helmdeployer.Template(ctx, bundle.Name, manifest, opts, "")
+	rel, err := helmdeployer.Template(ctx, bundle.Name, manifest, opts, "")
+	if err != nil {
+		return err
+	}
+
+	objs, err := yaml.ToObjects(bytes.NewBufferString(rel.Manifest))
 	if err != nil {
 		return err
 	}
diff --git a/internal/cmd/controller/root.go b/internal/cmd/controller/root.go
index 1e49f07d..4e4c7906 100644
--- a/internal/cmd/controller/root.go
+++ b/internal/cmd/controller/root.go
@@ -2,30 +2,24 @@
 package controller
 
 import (
-	"context"
 	"flag"
 	"fmt"
 	"log"
 	"net/http"
 	"os"
-	"path"
-	"runtime/pprof"
 	"strconv"
-	"time"
 
 	"github.com/rancher/fleet/internal/cmd/controller/agentmanagement"
 	"github.com/rancher/fleet/internal/cmd/controller/gitops"
 
 	"github.com/spf13/cobra"
 
-	"k8s.io/apimachinery/pkg/util/wait"
 	ctrl "sigs.k8s.io/controller-runtime"
 	clog "sigs.k8s.io/controller-runtime/pkg/log"
 	"sigs.k8s.io/controller-runtime/pkg/log/zap"
 
 	command "github.com/rancher/fleet/internal/cmd"
 	"github.com/rancher/fleet/internal/cmd/controller/cleanup"
-	"github.com/rancher/fleet/pkg/durations"
 	"github.com/rancher/fleet/pkg/version"
 )
 
@@ -102,7 +96,6 @@ func (f *FleetController) Run(cmd *cobra.Command, args []string) error {
 		workersOpts.BundleDeployment = w
 	}
 
-	setupCpuPprof(ctx)
 	go func() {
 		log.Println(http.ListenAndServe("localhost:6060", nil)) // nolint:gosec // Debugging only
 	}()
@@ -139,46 +132,3 @@ func App() *cobra.Command {
 	)
 	return root
 }
-
-// setupCpuPprof starts a goroutine that captures a cpu pprof profile
-// into FLEET_CPU_PPROF_DIR every FLEET_CPU_PPROF_PERIOD
-func setupCpuPprof(ctx context.Context) {
-	if dir, ok := os.LookupEnv("FLEET_CPU_PPROF_DIR"); ok {
-		go func() {
-			var pprofCpuFile *os.File
-
-			period := durations.DefaultCpuPprofPeriod
-			if customPeriod, err := time.ParseDuration(os.Getenv("FLEET_CPU_PPROF_PERIOD")); err == nil {
-				period = customPeriod
-			}
-			wait.UntilWithContext(ctx, func(ctx context.Context) {
-				stopCpuPprof(pprofCpuFile)
-				pprofCpuFile = startCpuPprof(dir)
-			}, period)
-		}()
-	}
-}
-
-// stopCpuPprof concludes a cpu pprof capture, if any is ongoing
-func stopCpuPprof(f *os.File) {
-	pprof.StopCPUProfile()
-	if f != nil {
-		err := f.Close()
-		if err != nil {
-			log.Println("could not close CPU profile file ", err)
-		}
-	}
-}
-
-// startCpuPprof starts a pprof cpu capture into a timestamp-prefixed file in dir
-func startCpuPprof(dir string) *os.File {
-	name := time.Now().UTC().Format("2006-01-02_15_04_05") + ".pprof.fleetcontroller.samples.cpu.pb.gz"
-	f, err := os.Create(path.Join(dir, name))
-	if err != nil {
-		log.Println("could not create CPU profile: ", err)
-	}
-	if err := pprof.StartCPUProfile(f); err != nil {
-		log.Println("could not start CPU profile: ", err)
-	}
-	return f
-}
diff --git a/internal/helmdeployer/template.go b/internal/helmdeployer/template.go
index 4eef67da..907190f0 100644
--- a/internal/helmdeployer/template.go
+++ b/internal/helmdeployer/template.go
@@ -14,10 +14,9 @@ import (
 	"helm.sh/helm/v3/pkg/action"
 	"helm.sh/helm/v3/pkg/chartutil"
 	kubefake "helm.sh/helm/v3/pkg/kube/fake"
+	"helm.sh/helm/v3/pkg/release"
 	"helm.sh/helm/v3/pkg/storage"
 	"helm.sh/helm/v3/pkg/storage/driver"
-
-	"k8s.io/apimachinery/pkg/runtime"
 )
 
 var (
@@ -25,7 +24,7 @@ var (
 )
 
 // Template runs helm template and returns the resources as a list of objects, without applying them.
-func Template(ctx context.Context, bundleID string, manifest *manifest.Manifest, options fleet.BundleDeploymentOptions, kubeVersionString string) ([]runtime.Object, error) {
+func Template(ctx context.Context, bundleID string, manifest *manifest.Manifest, options fleet.BundleDeploymentOptions, kubeVersionString string) (*release.Release, error) {
 	h := &Helm{
 		globalCfg:    action.Configuration{},
 		useGlobalCfg: true,
@@ -52,10 +51,5 @@ func Template(ctx context.Context, bundleID string, manifest *manifest.Manifest,
 	h.globalCfg.Log = logrus.Infof
 	h.globalCfg.Releases = storage.Init(mem)
 
-	release, err := h.Deploy(ctx, bundleID, manifest, options)
-	if err != nil {
-		return nil, err
-	}
-
-	return ReleaseToObjects(release)
+	return h.Deploy(ctx, bundleID, manifest, options)
 }
diff --git a/internal/mocks/orastarget_mock.go b/internal/mocks/orastarget_mock.go
index 20e28370..d3cfef2b 100644
--- a/internal/mocks/orastarget_mock.go
+++ b/internal/mocks/orastarget_mock.go
@@ -9,7 +9,7 @@ import (
 	io "io"
 	reflect "reflect"
 
-	gomock "github.com/golang/mock/gomock"
+	gomock "go.uber.org/mock/gomock"
 	v1 "github.com/opencontainers/image-spec/specs-go/v1"
 )
 
diff --git a/pkg/apis/go.mod b/pkg/apis/go.mod
index 704a4e41..748f8131 100644
--- a/pkg/apis/go.mod
+++ b/pkg/apis/go.mod
@@ -1,11 +1,11 @@
 module github.com/rancher/fleet/pkg/apis
 
-go 1.23.0
+go 1.22.0
 
-toolchain go1.23.2
+toolchain go1.22.7
 
 require (
-	github.com/rancher/wrangler/v3 v3.0.0
+	github.com/rancher/wrangler/v3 v3.0.1-rc.3
 	k8s.io/api v0.31.1
 	k8s.io/apimachinery v0.31.1
 )
@@ -19,8 +19,8 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/x448/float16 v0.8.4 // indirect
-	golang.org/x/net v0.26.0 // indirect
-	golang.org/x/text v0.16.0 // indirect
+	golang.org/x/net v0.28.0 // indirect
+	golang.org/x/text v0.17.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	k8s.io/klog/v2 v2.130.1 // indirect
diff --git a/pkg/apis/go.sum b/pkg/apis/go.sum
index 19daab7f..375b5dbd 100644
--- a/pkg/apis/go.sum
+++ b/pkg/apis/go.sum
@@ -30,8 +30,8 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rancher/wrangler/v3 v3.0.0 h1:IHHCA+vrghJDPxjtLk4fmeSCFhNe9fFzLFj3m2B0YpA=
-github.com/rancher/wrangler/v3 v3.0.0/go.mod h1:Dfckuuq7MJk2JWVBDywRlZXMxEyPxHy4XqGrPEzu5Eg=
+github.com/rancher/wrangler/v3 v3.0.1-rc.3 h1:C2d1GoP500SEFARVcb6EpbcNaXH3i8Yu9fzAe/0n4C0=
+github.com/rancher/wrangler/v3 v3.0.1-rc.3/go.mod h1:gUPHS1ANs2NyByfeERHwkGiQ1rlIa8BpTJZtNSgMlZw=
 github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
 github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -53,8 +53,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
-golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -63,8 +63,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=


Test patch:
diff --git a/.github/workflows/e2e-nightly-ci.yml b/.github/workflows/e2e-nightly-ci.yml
index cd305f12..88b29c5b 100644
--- a/.github/workflows/e2e-nightly-ci.yml
+++ b/.github/workflows/e2e-nightly-ci.yml
@@ -56,12 +56,15 @@ jobs:
 
           DOCKER_BUILDKIT=1 docker build -f e2e/assets/gitrepo/Dockerfile.gitserver -t nginx-git:test --build-arg="passwd=$(openssl passwd foo)" e2e/assets/gitrepo
       -
-        name: Provision k3d Cluster
+        name: Install k3d
         run: curl --silent --fail https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=${{ env.SETUP_K3D_VERSION }} bash
+      -
+        name: Provision k3d Cluster
+        run: |
           k3d cluster create upstream --wait \
             --agents 1 \
             --network "nw01" \
-            --image docker.io/rancher/k3s:${{matrix.k3s.version}}
+            --image docker.io/rancher/k3s:${{matrix.k3s_version}}
       -
         name: Import Images Into k3d
         run: |
diff --git a/.github/workflows/e2e-test-fleet-in-rancher.yml b/.github/workflows/e2e-test-fleet-in-rancher.yml
index 46693b63..19941199 100644
--- a/.github/workflows/e2e-test-fleet-in-rancher.yml
+++ b/.github/workflows/e2e-test-fleet-in-rancher.yml
@@ -22,11 +22,6 @@ on:
       fleet_version:
         description: Fleet version to install in Rancher
         type: string
-      enable_tmate:
-        description: Enable debugging via tmate
-        required: false
-        default: false
-        type: boolean
   workflow_call:
     # Variables to set when calling this reusable workflow
     inputs:
@@ -153,14 +148,6 @@ jobs:
             --network "nw01" \
             --image docker.io/rancher/k3s:${{ env.SETUP_K3S_VERSION }}
 
-      -
-        name: Set Up Tmate Debug Session
-        if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.enable_tmate == 'true' }}
-        uses: mxschmitt/action-tmate@v3
-        timeout-minutes: 15
-        with:
-          limit-access-to-actor: true
-
       -
         name: Set up latest Rancher
         run: |
diff --git a/docs/testing_fleet_in_rancher.md b/docs/testing_fleet_in_rancher.md
deleted file mode 100644
index 43612823..00000000
--- a/docs/testing_fleet_in_rancher.md
+++ /dev/null
@@ -1,132 +0,0 @@
-## Fleet in Rancher
-
-All steps in this guide assume your current working directory is the root of the repository.
-Moreover, this guide was written for Unix-like developer environments, so you may need to modify some steps if you are using a non-Unix-like developer environment (i.e. Windows).
-
-### Step 1: Image Preparation
-
-We need to use a registry to store `fleet-agent` developer builds.
-Using a personal [DockerHub](https://hub.docker.com/) repository is usually a suitable choice.
-The full repository name must be `<your-choice>/fleet-agent`.
-
-Now, we need export an environment variable with your repository name as the value.
-This will be used when building, pushing, and deploying your agent.
-
-> Note: the value for this variable should not include `/fleet-agent`.
-> For example, if your full DockerHub repository name is `foobar/fleet-agent`, the value used below should be `foobar`.
-
-Export the new `AGENT_REPO` variable and use the aforementioned value.
-
-```
-export AGENT_REPO=<your-OCI-image-repository>
-```
-
-### Step 2: Local Cluster Access
-
-We need a local cluster to work with.
-For this guide, we will use [k3d](https://github.com/rancher/k3d).
-
-```sh
-k3d cluster create <NAME>
-```
-
-### Step 3: Generate as Needed
-
-If you have changed Go code, you may need to generate.
-
-```sh
-go generate
-```
-
-### Step 4: Running the Controller
-
-First, we need to run Rancher locally.
-You can use the [Rancher Wiki](https://github.com/rancher/rancher/wiki/Setting-Up-Rancher-2.0-Development-Environment) for information on how to do so.
-
-> If you are unsure about which method you would like use for tunneling to localhost, we recommend [ngrok](https://ngrok.com) or [tunnelware](https://github.com/StrongMonkey/tunnelware).
-
-Now, let's build and push your `fleet-agent` (`linux-amd64` image by default), if applicable.
-
-```sh
-(
-    dev/build-fleet
-    docker tag rancher/fleet-agent:dev $AGENT_REPO/fleet-agent:dev
-    docker push $AGENT_REPO/fleet-agent:dev
-)
-```
-
-In the Rancher Dashboard, navigate to the `fleet-controller` ConfigMap.
-This is likely located in a `cattle-fleet-*` or `fleet-*` namespace.
-Replace the existing agent-related fields with the following information:
-
-- your agent image and tag
-- the image pull policy to `Always` (for iterative development)
-
-Once the ConfigMap has been updated, edit the `fleet-controller` Deployment and scale down its `replicas` to `0`.
-With that change, we can now run the controller locally.
-
-```sh
-(
-    go fmt ./...
-    go run cmd/fleetcontroller/main.go
-)
-```
-
-**Optional:** you can test Rancher's `FleetWorkspaces` feature by moving Fleet clusters to another workspace in the "Continuous Delivery" section of the Rancher UI.
-You can create your own workspace using the API or the UI.
-Ensure that clusters are in an "Active" state after migration.
-
-### Step 5: Create GitRepo CR(s)
-
-The controller should be running in your terminal window/pane!
-You can now create [GitRepo](https://fleet.rancher.io/gitrepo-structure/) custom resource objects and test Fleet locally.
-
----
-
-## Fleet in Rancher - Using a Custom Fork
-
-If you need to test Fleet *during Rancher startup*, you may want to use a custom fork.
-The following steps can help you do so:
-
-1. Fork [rancher/fleet](https://github.com/rancher/fleet) and commit your changes to a branch of your choice
-2. Change image names and tags for the Helm chart(s) for your custom development image(s) accordingly
-3. Publish images corresponding to the names and tags changed in the Helm chart(s)
-4. Tag your **_fork_** with a [SemVer-compliant](https://semver.org/) tag that's "greater" than the Fleet chart tag in your chosen version of Rancher _(note: the exact tag name is not that important, but we want it to be "grater" just in case there's a collision for the "latest" version)_
-5. Fork [rancher/charts](https://github.com/rancher/charts) and update branch `dev-v2.x` with your changes to the `fleet`, `fleet-crd`, and `fleet-agent` packages
-6. You'll need to change the chart URL to your charts' `tgz` location (this may need to be self-hosted)
-7. Finally, commits those changes, execute `make charts` and commit those changes in a second commit
-8. Fork [rancher/rancher](https://github.com/rancher/rancher) and change the charts URL to point to your fork
-9. Start Rancher locally (instructions: [Rancher Wiki](https://github.com/rancher/rancher/wiki/Setting-Up-Rancher-2.0-Development-Environment)) and your fork's chart should be deployed
-
-## Advanced: Standalone Fleet (Obsolete How-to)
-
-Continuous Integration executes most [E2E tests](/e2e/) against Fleet Standalone. For developing purposes we recommend using our [dev scripts](#local-development-workflow-fleet-standalone---for-running-e2e-tests) instead of this how-to. We keep this part only for documental reasons.
-
-Build and push your `fleet-agent` (`linux-amd64` image by default), install your Fleet charts, and then replace the controller deployment with your local controller build.
-
-```sh
-(
-    go fmt ./...
-    REPO=$AGENT_REPO make agent-dev
-    docker push $AGENT_REPO/fleet-agent:dev
-    for i in cattle-fleet-system fleet-default fleet-local; do kubectl create namespace $i; done
-    helm install -n cattle-fleet-system fleet-crd ./charts/fleet-crd
-    helm install -n cattle-fleet-system fleet --set agentImage.repository=$AGENT_REPO/fleet-agent --set agentImage.imagePullPolicy=Always ./charts/fleet
-    kubectl delete deployment -n cattle-fleet-system fleet-controller
-    go run cmd/fleetcontroller/main.go
-)
-```
-
-Alternatively, if the agent's code has been unchanged, you can use the latest agent instead.
-We'll use the latest Git tag for this, and _assume_ it is available on DockerHub.
-
-```sh
-(
-    go fmt ./...
-    for i in cattle-fleet-system fleet-default fleet-local; do kubectl create namespace $i; done
-    helm install -n cattle-fleet-system fleet-crd ./charts/fleet-crd
-    helm install -n cattle-fleet-system fleet --set agentImage.tag=$(git tag --sort=taggerdate | tail -1) ./charts/fleet
-    kubectl delete deployment -n cattle-fleet-system fleet-controller
-    go run cmd/fleetcontroller/main.go
-)
-```
diff --git a/integrationtests/cli/apply/apply_online_test.go b/integrationtests/cli/apply/apply_online_test.go
index d0b34752..9f1d52fa 100644
--- a/integrationtests/cli/apply/apply_online_test.go
+++ b/integrationtests/cli/apply/apply_online_test.go
@@ -4,7 +4,7 @@
 package apply
 
 import (
-	"github.com/golang/mock/gomock"
+	"go.uber.org/mock/gomock"
 
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
diff --git a/integrationtests/cli/assets/bundledeployment/bd.yaml b/integrationtests/cli/assets/bundledeployment/bd.yaml
index da43ea7a..f75567ec 100644
--- a/integrationtests/cli/assets/bundledeployment/bd.yaml
+++ b/integrationtests/cli/assets/bundledeployment/bd.yaml
@@ -1,11 +1,11 @@
 ---
 apiVersion: fleet.cattle.io/v1alpha1
-content: H4sIAAAAAAAA/4SRMW/bMBCF9/6KA2eLtlygA7fCa7t6KTucpZNNhKII8iTEEPTfA5KRESdOsgjQ3Xv33gfOIlAcxtBQFOrfLBz2JJRoBteZc9VcMPD2kL7yir0Vm7RhciyUQG+OFKIZnIJpr12yKnjr1K6l2ATjOYt+A1NkyCvgCzJMFExnKILh+OrUjq+eFKD31jSYnNpNa85O1nKnHXp/i9ailvUvudNCO7FsHiMw9d4iU9yWcY/+G6BauyfjWgWHbPiLXrueGFtkVNoBFNxEVEXTe0slqloxbsIkSTUntCPV+5+p6GqfZ5DHNI8yDWBZvoCYivBD73KqpQ5Hy1X6uz/SWaIH73ch2+eC+fr7lwMocVmx1qVnzKR5dR/yWbkxWAVnO5zQylKksWNkCn/wRLZgp0v/lx8vAQAA//+su6S1jAIAAA==
+content: H4sIAK9MFmcAA51TPW/bMBDd/SsOmi05SoEO2oKsyRQgS5nhTJ0sItSRICmhgeH/Hn5YbhGgtduFgO7eu3fv8HTcAFSOvJmdJF918CMWAI75jS3GiWK1koYHdajliC7sHtPbfOCkq+0KjIBAHBIWrXol55XhDpZ7wWlGB79PENyTl07ZkEEPEMgHyC0IIwZYyKlBkQcV/JkpOHzYOAet1UpiYgpeVp27pm3uBMfmRVpUbdN+j9VKcJXXPG1vMBdoshrjQrtSntDeaLUV/K647+AxE5/RCp4oYI8BO8EA5RDJa+1VVKEiWa8GL8AESQYW1DO199+ShZV+PELzmuq+SQU4nf7J3lKof3RURHoacNahTl/Xxg+a6C9pGElP2VTW/5oDgLJQRqwW6Sfm6+TWNflrhmanOzhos0fdlFWlnn0g94R70uWI/xkQT25RklBKM/OtP8QlJS+F/VDYX6KCzCbkkK+nSXds/LgbjXnvwDqqFfuAWm/zx2wPDntKWJ2NnWmDMR3s0f0KkDcT1caSw2Dc2Xd83zanzScIJmgxDgQAAA==
 kind: Content
 metadata:
   creationTimestamp: null
-  name: s-ee0480cffe0c0da150814f6844d7c5bc49cc05c158c5ba1efe9a45142f36e
-sha256sum: ee0480cffe0c0da150814f6844d7c5bc49cc05c158c5ba1efe9a45142f36eebc
+  name: s-eaab4652f067cb4cbb2498af40082a70b5bf089873703a72b6895e53daaf0dac
+sha256sum: eaab4652f067cb4cbb2498af40082a70b5bf089873703a72b6895e53daaf0dac
 
 ---
 apiVersion: fleet.cattle.io/v1alpha1
@@ -22,14 +22,14 @@ metadata:
   name: testbundle-simple-chart
   namespace: cluster-fleet-local-local-1a3d67d0a899
 spec:
-  deploymentID: s-ee0480cffe0c0da150814f6844d7c5bc49cc05c158c5ba1efe9a45142f36e:c32e813ecbf48f56833aa2267cd3d8758eecc94f9948fb0dea510147a57760b5
+  deploymentID: s-eaab4652f067cb4cbb2498af40082a70b5bf089873703a72b6895e53daaf0dac:c32e813ecbf48f56833aa2267cd3d8758eecc94f9948fb0dea510147a57760b5
   options:
     helm:
       chart: config-chart
       values:
         name: example-value
     ignore: {}
-  stagedDeploymentID: s-ee0480cffe0c0da150814f6844d7c5bc49cc05c158c5ba1efe9a45142f36e:c32e813ecbf48f56833aa2267cd3d8758eecc94f9948fb0dea510147a57760b5
+  stagedDeploymentID: s-eaab4652f067cb4cbb2498af40082a70b5bf089873703a72b6895e53daaf0dac:c32e813ecbf48f56833aa2267cd3d8758eecc94f9948fb0dea510147a57760b5
   stagedOptions:
     helm:
       chart: config-chart
diff --git a/integrationtests/cli/deploy/deploy_test.go b/integrationtests/cli/deploy/deploy_test.go
index 62165028..abfc78d3 100644
--- a/integrationtests/cli/deploy/deploy_test.go
+++ b/integrationtests/cli/deploy/deploy_test.go
@@ -157,9 +157,15 @@ var _ = Describe("Fleet CLI Deploy", func() {
 		It("prints a manifest and bundledeployment", func() {
 			buf, err := act(args)
 			Expect(err).NotTo(HaveOccurred())
-			Expect(buf).To(gbytes.Say("- apiVersion: v1"))
-			Expect(buf).To(gbytes.Say("  data:"))
-			Expect(buf).To(gbytes.Say("    name: example-value"))
+			Expect(buf.Contents()).To(And(
+				ContainSubstring("- apiVersion: v1"),
+				ContainSubstring("ConfigMap"),
+				ContainSubstring("  data:"),
+				ContainSubstring("    name: example-value"),
+				ContainSubstring("ServiceAccount"),
+				ContainSubstring("helm.sh/hook"),
+				ContainSubstring("some-operator"),
+			))
 
 			cm := &corev1.ConfigMap{}
 			err = k8sClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: "test-simple-chart-config"}, cm)
diff --git a/integrationtests/mocks/fleet_controller_mock.go b/integrationtests/mocks/fleet_controller_mock.go
index a3371fa1..4f52f3b0 100644
--- a/integrationtests/mocks/fleet_controller_mock.go
+++ b/integrationtests/mocks/fleet_controller_mock.go
@@ -7,7 +7,7 @@ package mocks
 import (
 	reflect "reflect"
 
-	gomock "github.com/golang/mock/gomock"
+	gomock "go.uber.org/mock/gomock"
 	v1alpha1 "github.com/rancher/fleet/pkg/generated/controllers/fleet.cattle.io/v1alpha1"
 )
 
diff --git a/integrationtests/mocks/getter_mock.go b/integrationtests/mocks/getter_mock.go
index add20daa..47fc119f 100644
--- a/integrationtests/mocks/getter_mock.go
+++ b/integrationtests/mocks/getter_mock.go
@@ -7,7 +7,7 @@ package mocks
 import (
 	reflect "reflect"
 
-	gomock "github.com/golang/mock/gomock"
+	gomock "go.uber.org/mock/gomock"
 	client "github.com/rancher/fleet/internal/client"
 )
 
diff --git a/internal/cmd/agent/clusterstatus/ticker_test.go b/internal/cmd/agent/clusterstatus/ticker_test.go
index d0d02f81..0321d769 100644
--- a/internal/cmd/agent/clusterstatus/ticker_test.go
+++ b/internal/cmd/agent/clusterstatus/ticker_test.go
@@ -5,11 +5,11 @@ import (
 	"encoding/json"
 	"time"
 
-	"github.com/golang/mock/gomock"
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
 	"github.com/rancher/wrangler/v3/pkg/generic/fake"
+	"go.uber.org/mock/gomock"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
diff --git a/internal/cmd/agent/register/register_test.go b/internal/cmd/agent/register/register_test.go
index 4b8c78bf..7537736b 100644
--- a/internal/cmd/agent/register/register_test.go
+++ b/internal/cmd/agent/register/register_test.go
@@ -7,10 +7,10 @@ import (
 	"testing"
 	"time"
 
-	"github.com/golang/mock/gomock"
 	corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1"
 	"github.com/rancher/wrangler/v3/pkg/generic/fake"
 	"github.com/stretchr/testify/assert"
+	"go.uber.org/mock/gomock"
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/internal/cmd/controller/agentmanagement/controllers/clusterregistration/controller_test.go b/internal/cmd/controller/agentmanagement/controllers/clusterregistration/controller_test.go
index a3163e19..930ee6da 100644
--- a/internal/cmd/controller/agentmanagement/controllers/clusterregistration/controller_test.go
+++ b/internal/cmd/controller/agentmanagement/controllers/clusterregistration/controller_test.go
@@ -3,9 +3,9 @@ package clusterregistration
 import (
 	"fmt"
 
-	"github.com/golang/mock/gomock"
 	"github.com/rancher/wrangler/v3/pkg/generic"
 	"github.com/rancher/wrangler/v3/pkg/generic/fake"
+	"go.uber.org/mock/gomock"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/internal/cmd/controller/agentmanagement/controllers/manageagent/manageagent_test.go b/internal/cmd/controller/agentmanagement/controllers/manageagent/manageagent_test.go
index 0bca795e..946f9ec4 100644
--- a/internal/cmd/controller/agentmanagement/controllers/manageagent/manageagent_test.go
+++ b/internal/cmd/controller/agentmanagement/controllers/manageagent/manageagent_test.go
@@ -3,8 +3,8 @@ package manageagent
 import (
 	"testing"
 
-	"github.com/golang/mock/gomock"
 	"github.com/rancher/wrangler/v3/pkg/generic/fake"
+	"go.uber.org/mock/gomock"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/utils/ptr"
diff --git a/internal/ociwrapper/ociwrapper_test.go b/internal/ociwrapper/ociwrapper_test.go
index a3f3752e..7b697ecc 100644
--- a/internal/ociwrapper/ociwrapper_test.go
+++ b/internal/ociwrapper/ociwrapper_test.go
@@ -8,8 +8,8 @@ import (
 	"net/http"
 	"os"
 
-	"github.com/golang/mock/gomock"
 	"github.com/opencontainers/go-digest"
+	"go.uber.org/mock/gomock"
 
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	"oras.land/oras-go/v2"