Repository: apache/camel-k
Pull request #4462 (2023-06-06 14:56:49)

chore(deps): home made Set to replace github.com/scylladb/go-set
Ref #4326

<!-- Description -->




<!--
Enter your extended release note in the below block. If the PR requires
additional action from users switching to the new release, include the string
"action required". If no release note is required, write "NONE". 

You can (optionally) mark this PR with labels "kind/bug" or "kind/feature" to make sure
the text is added to the right section of the release notes. 
-->

**Release Note**
```release-note
chore(deps): home made Set to replace github.com/scylladb/go-set
```



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5556c68d3..90a71a51f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,14 +6,20 @@
 
 **Closed issues:**
 
+- \[Regression\] likely all cmd/utils were required by CI [\#4460](https://github.com/apache/camel-k/issues/4460)
 - SBOM for Camel K [\#4430](https://github.com/apache/camel-k/issues/4430)
+- Operator is not able to push builder image to the internal registry \(OpenShift cluster\) [\#4297](https://github.com/apache/camel-k/issues/4297)
 - Configure memory resource requests on builder pods [\#1092](https://github.com/apache/camel-k/issues/1092)
 
 **Merged pull requests:**
 
+- fix\(ci\): bring back CLIs required by ci tasks [\#4461](https://github.com/apache/camel-k/pull/4461) ([squakez](https://github.com/squakez))
+- chore\(ci\): define IMAGE\_ARCH parameter [\#4457](https://github.com/apache/camel-k/pull/4457) ([squakez](https://github.com/squakez))
+- chore\(deps\): bump github.com/sirupsen/logrus from 1.9.2 to 1.9.3 [\#4455](https://github.com/apache/camel-k/pull/4455) ([dependabot[bot]](https://github.com/apps/dependabot))
 - chore\(e2e\): split upgrade from install [\#4454](https://github.com/apache/camel-k/pull/4454) ([squakez](https://github.com/squakez))
 - chore\(deps\): revert vfs-gen removal [\#4450](https://github.com/apache/camel-k/pull/4450) ([gansheer](https://github.com/gansheer))
 - fix\(ci\): temporarily repair upgrade checks [\#4449](https://github.com/apache/camel-k/pull/4449) ([squakez](https://github.com/squakez))
+- chore\(deps\): replace github.com/radovskyb/watcher with github.com/fsn… [\#4448](https://github.com/apache/camel-k/pull/4448) ([squakez](https://github.com/squakez))
 - chore\(ci\): use ubuntu-latest [\#4445](https://github.com/apache/camel-k/pull/4445) ([squakez](https://github.com/squakez))
 - chore\(deps\): bump github.com/cloudflare/circl from 1.1.0 to 1.3.3 [\#4442](https://github.com/apache/camel-k/pull/4442) ([dependabot[bot]](https://github.com/apps/dependabot))
 - chore\(deps\): bump github.com/cloudflare/circl from 1.1.0 to 1.3.3 in /pkg/kamelet/repository [\#4441](https://github.com/apache/camel-k/pull/4441) ([dependabot[bot]](https://github.com/apps/dependabot))
diff --git a/camel-k-sbom/camel-k-sbom.json b/camel-k-sbom/camel-k-sbom.json
index 9249c36e8..a36b33fb0 100644
--- a/camel-k-sbom/camel-k-sbom.json
+++ b/camel-k-sbom/camel-k-sbom.json
@@ -2,10 +2,10 @@
   "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json",
   "bomFormat": "CycloneDX",
   "specVersion": "1.4",
-  "serialNumber": "urn:uuid:23bfbc4b-5db1-47df-9a81-e5d5fdfc9fa3",
+  "serialNumber": "urn:uuid:a58965f4-be38-4ac1-ad69-33d44a736e38",
   "version": 1,
   "metadata": {
-    "timestamp": "2023-06-04T23:45:46Z",
+    "timestamp": "2023-06-06T23:49:17Z",
     "tools": [
       {
         "vendor": "CycloneDX",
@@ -46,11 +46,11 @@
       }
     ],
     "component": {
-      "bom-ref": "pkg:golang/github.com/apache/camel-k/v2@v0.0.0-20230603234547-38cf863e7a42?type=module",
+      "bom-ref": "pkg:golang/github.com/apache/camel-k/v2@v0.0.0-20230606234232-119431a38188?type=module",
       "type": "application",
       "name": "github.com/apache/camel-k/v2",
-      "version": "v0.0.0-20230603234547-38cf863e7a42",
-      "purl": "pkg:golang/github.com/apache/camel-k/v2@v0.0.0-20230603234547-38cf863e7a42?type=module\u0026goos=linux\u0026goarch=amd64",
+      "version": "v0.0.0-20230606234232-119431a38188",
+      "purl": "pkg:golang/github.com/apache/camel-k/v2@v0.0.0-20230606234232-119431a38188?type=module\u0026goos=linux\u0026goarch=amd64",
       "externalReferences": [
         {
           "url": "https://github.com/apache/camel-k",
@@ -423,18 +423,18 @@
       }
     },
     {
-      "bom-ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
+      "bom-ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230606234232-119431a38188?type=module",
       "type": "library",
       "name": "github.com/apache/camel-k/v2/pkg/apis/camel",
-      "version": "v0.0.0-20230603234547-38cf863e7a42",
+      "version": "v0.0.0-20230606234232-119431a38188",
       "scope": "required",
       "hashes": [
         {
           "alg": "SHA-256",
-          "content": "f68c5bb518639f34c788bcf40c9530edce01df20317364e7879d6c9b429628c6"
+          "content": "1eefb884e3c96e24c243c122db7c37321bb857523beb70de1b40803a3970c7ff"
         }
       ],
-      "purl": "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230603234547-38cf863e7a42?type=module\u0026goos=linux\u0026goarch=amd64",
+      "purl": "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230606234232-119431a38188?type=module\u0026goos=linux\u0026goarch=amd64",
       "externalReferences": [
         {
           "url": "https://github.com/apache/camel-k/v2/pkg/apis/camel",
@@ -443,18 +443,18 @@
       ]
     },
     {
-      "bom-ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
+      "bom-ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230606234232-119431a38188?type=module",
       "type": "library",
       "name": "github.com/apache/camel-k/v2/pkg/client/camel",
-      "version": "v0.0.0-20230603234547-38cf863e7a42",
+      "version": "v0.0.0-20230606234232-119431a38188",
       "scope": "required",
       "hashes": [
         {
           "alg": "SHA-256",
-          "content": "3236e0ee1c66916cc5372105fc2f5b1f326016807e98a342abf0b205d44c00bc"
+          "content": "99425fbf32bb274b55a3f9de7c05033ecc4b4c0b91fa44e83e912f51253eb20a"
         }
       ],
-      "purl": "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230603234547-38cf863e7a42?type=module\u0026goos=linux\u0026goarch=amd64",
+      "purl": "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230606234232-119431a38188?type=module\u0026goos=linux\u0026goarch=amd64",
       "externalReferences": [
         {
           "url": "https://github.com/apache/camel-k/v2/pkg/client/camel",
@@ -463,18 +463,18 @@
       ]
     },
     {
-      "bom-ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/kamelet/repository@v0.0.0-20230603234547-38cf863e7a42?type=module",
+      "bom-ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/kamelet/repository@v0.0.0-20230606234232-119431a38188?type=module",
       "type": "library",
       "name": "github.com/apache/camel-k/v2/pkg/kamelet/repository",
-      "version": "v0.0.0-20230603234547-38cf863e7a42",
+      "version": "v0.0.0-20230606234232-119431a38188",
       "scope": "required",
       "hashes": [
         {
           "alg": "SHA-256",
-          "content": "079d6e94cd1deb42902ae7755f2b33f7132e10c2d045d80a454904ae5b3cbe60"
+          "content": "1e5655856db9c1fc4cbd6eeaa2e31031fed617c8aaca9714aae074a71e4fda80"
         }
       ],
-      "purl": "pkg:golang/github.com/apache/camel-k/v2/pkg/kamelet/repository@v0.0.0-20230603234547-38cf863e7a42?type=module\u0026goos=linux\u0026goarch=amd64",
+      "purl": "pkg:golang/github.com/apache/camel-k/v2/pkg/kamelet/repository@v0.0.0-20230606234232-119431a38188?type=module\u0026goos=linux\u0026goarch=amd64",
       "externalReferences": [
         {
           "url": "https://github.com/apache/camel-k/v2/pkg/kamelet/repository",
@@ -2512,35 +2512,6 @@
         ]
       }
     },
-    {
-      "bom-ref": "pkg:golang/github.com/radovskyb/watcher@v1.0.7?type=module",
-      "type": "library",
-      "name": "github.com/radovskyb/watcher",
-      "version": "v1.0.7",
-      "scope": "required",
-      "hashes": [
-        {
-          "alg": "SHA-256",
-          "content": "01878f2e287a769992df6be51df8427a58bcd76ecbce4220c0919cc307bcb541"
-        }
-      ],
-      "purl": "pkg:golang/github.com/radovskyb/watcher@v1.0.7?type=module\u0026goos=linux\u0026goarch=amd64",
-      "externalReferences": [
-        {
-          "url": "https://github.com/radovskyb/watcher",
-          "type": "vcs"
-        }
-      ],
-      "evidence": {
-        "licenses": [
-          {
-            "license": {
-              "id": "BSD-3-Clause"
-            }
-          }
-        ]
-      }
-    },
     {
       "bom-ref": "pkg:golang/github.com/redhat-developer/service-binding-operator@v1.3.4?type=module",
       "type": "library",
@@ -2774,18 +2745,18 @@
       }
     },
     {
-      "bom-ref": "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+      "bom-ref": "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
       "type": "library",
       "name": "github.com/sirupsen/logrus",
-      "version": "v1.9.2",
+      "version": "v1.9.3",
       "scope": "required",
       "hashes": [
         {
           "alg": "SHA-256",
-          "content": "a31c75782849188e9492cd990b85b5ce92e5560a81f277abe04b90c15e089356"
+          "content": "76e794409d42daaf6813717bc2f992180695b539948b345ebba7e337cbaacdb4"
         }
       ],
-      "purl": "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module\u0026goos=linux\u0026goarch=amd64",
+      "purl": "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module\u0026goos=linux\u0026goarch=amd64",
       "externalReferences": [
         {
           "url": "https://github.com/sirupsen/logrus",
@@ -3230,6 +3201,29 @@
         ]
       }
     },
+    {
+      "bom-ref": "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
+      "type": "library",
+      "name": "golang.org/x/mod",
+      "version": "v0.10.0",
+      "scope": "required",
+      "hashes": [
+        {
+          "alg": "SHA-256",
+          "content": "9453bdaad39d96b7b95b58f14b7affe2ccefdbfea25f149c7738e804c5cd8589"
+        }
+      ],
+      "purl": "pkg:golang/golang.org/x/mod@v0.10.0?type=module\u0026goos=linux\u0026goarch=amd64",
+      "evidence": {
+        "licenses": [
+          {
+            "license": {
+              "id": "BSD-3-Clause"
+            }
+          }
+        ]
+      }
+    },
     {
       "bom-ref": "pkg:golang/golang.org/x/net@v0.10.0?type=module",
       "type": "library",
@@ -3391,6 +3385,29 @@
         ]
       }
     },
+    {
+      "bom-ref": "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
+      "type": "library",
+      "name": "golang.org/x/tools",
+      "version": "v0.9.1",
+      "scope": "required",
+      "hashes": [
+        {
+          "alg": "SHA-256",
+          "content": "f1630d240cf7cebb4f9a7602ec849fe5d127dcc4f4818ee30497f0dbbcabacba"
+        }
+      ],
+      "purl": "pkg:golang/golang.org/x/tools@v0.9.1?type=module\u0026goos=linux\u0026goarch=amd64",
+      "evidence": {
+        "licenses": [
+          {
+            "license": {
+              "id": "BSD-3-Clause"
+            }
+          }
+        ]
+      }
+    },
     {
       "bom-ref": "pkg:golang/gomodules.xyz/jsonpatch/v2@v2.2.0?type=module",
       "type": "library",
@@ -3783,6 +3800,29 @@
         ]
       }
     },
+    {
+      "bom-ref": "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
+      "type": "library",
+      "name": "k8s.io/gengo",
+      "version": "v0.0.0-20221011193443-fad74ee6edd9",
+      "scope": "required",
+      "hashes": [
+        {
+          "alg": "SHA-256",
+          "content": "8aede8fd2c5a1d523bb4a3ed906cc3dccf48ceb136d63f8250a1fdf0d409f0cb"
+        }
+      ],
+      "purl": "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module\u0026goos=linux\u0026goarch=amd64",
+      "evidence": {
+        "licenses": [
+          {
+            "license": {
+              "id": "Apache-2.0"
+            }
+          }
+        ]
+      }
+    },
     {
       "bom-ref": "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
       "type": "library",
@@ -4053,14 +4093,15 @@
   ],
   "dependencies": [
     {
-      "ref": "pkg:golang/github.com/apache/camel-k/v2@v0.0.0-20230603234547-38cf863e7a42?type=module",
+      "ref": "pkg:golang/github.com/apache/camel-k/v2@v0.0.0-20230606234232-119431a38188?type=module",
       "dependsOn": [
         "pkg:golang/github.com/Masterminds/semver@v1.5.0?type=module",
-        "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
-        "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
-        "pkg:golang/github.com/apache/camel-k/v2/pkg/kamelet/repository@v0.0.0-20230603234547-38cf863e7a42?type=module",
+        "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230606234232-119431a38188?type=module",
+        "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230606234232-119431a38188?type=module",
+        "pkg:golang/github.com/apache/camel-k/v2/pkg/kamelet/repository@v0.0.0-20230606234232-119431a38188?type=module",
         "pkg:golang/github.com/container-tools/spectrum@v0.6.19?type=module",
         "pkg:golang/github.com/evanphx/json-patch@v5.6.0+incompatible?type=module",
+        "pkg:golang/github.com/fsnotify/fsnotify@v1.6.0?type=module",
         "pkg:golang/github.com/gertd/go-pluralize@v0.2.1?type=module",
         "pkg:golang/github.com/go-logr/logr@v1.2.4?type=module",
         "pkg:golang/github.com/google/go-containerregistry@v0.15.2?type=module",
@@ -4076,13 +4117,12 @@
         "pkg:golang/github.com/otiai10/copy@v1.11.0?type=module",
         "pkg:golang/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring@v0.60.0?type=module",
         "pkg:golang/github.com/prometheus/client_golang@v1.15.1?type=module",
-        "pkg:golang/github.com/radovskyb/watcher@v1.0.7?type=module",
         "pkg:golang/github.com/redhat-developer/service-binding-operator@v1.3.4?type=module",
         "pkg:golang/github.com/rs/xid@v1.5.0?type=module",
         "pkg:golang/github.com/scylladb/go-set@v1.0.2?type=module",
         "pkg:golang/github.com/shurcooL/httpfs@v0.0.0-20190707220628-8d4bc4ba7749?type=module",
         "pkg:golang/github.com/shurcooL/vfsgen@v0.0.0-20181202132449-6a9ea43bcacd?type=module",
-        "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+        "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
         "pkg:golang/github.com/spf13/cobra@v1.7.0?type=module",
         "pkg:golang/github.com/spf13/pflag@v1.0.5?type=module",
         "pkg:golang/github.com/spf13/viper@v1.16.0?type=module",
@@ -4102,6 +4142,7 @@
         "pkg:golang/k8s.io/apimachinery@v0.25.6?type=module",
         "pkg:golang/k8s.io/cli-runtime@v0.25.6?type=module",
         "pkg:golang/k8s.io/client-go@v0.25.6?type=module",
+        "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
         "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
         "pkg:golang/k8s.io/kubectl@v0.25.6?type=module",
         "pkg:golang/k8s.io/utils@v0.0.0-20221108210102-8e77b1f39fe2?type=module",
@@ -4215,7 +4256,7 @@
       "ref": "pkg:golang/github.com/antlr/antlr4/runtime/Go/antlr@v1.4.10?type=module"
     },
     {
-      "ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
+      "ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230606234232-119431a38188?type=module",
       "dependsOn": [
         "pkg:golang/github.com/imdario/mergo@v0.3.13?type=module",
         "pkg:golang/github.com/stretchr/testify@v1.8.4?type=module",
@@ -4241,9 +4282,9 @@
       ]
     },
     {
-      "ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
+      "ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230606234232-119431a38188?type=module",
       "dependsOn": [
-        "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
+        "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230606234232-119431a38188?type=module",
         "pkg:golang/k8s.io/api@v0.25.6?type=module",
         "pkg:golang/k8s.io/apimachinery@v0.25.6?type=module",
         "pkg:golang/k8s.io/client-go@v0.25.6?type=module",
@@ -4287,10 +4328,10 @@
       ]
     },
     {
-      "ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/kamelet/repository@v0.0.0-20230603234547-38cf863e7a42?type=module",
+      "ref": "pkg:golang/github.com/apache/camel-k/v2/pkg/kamelet/repository@v0.0.0-20230606234232-119431a38188?type=module",
       "dependsOn": [
-        "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
-        "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230603234547-38cf863e7a42?type=module",
+        "pkg:golang/github.com/apache/camel-k/v2/pkg/apis/camel@v0.0.0-20230606234232-119431a38188?type=module",
+        "pkg:golang/github.com/apache/camel-k/v2/pkg/client/camel@v0.0.0-20230606234232-119431a38188?type=module",
         "pkg:golang/github.com/stretchr/testify@v1.8.4?type=module",
         "pkg:golang/golang.org/x/oauth2@v0.8.0?type=module",
         "pkg:golang/k8s.io/apimachinery@v0.25.6?type=module",
@@ -4436,7 +4477,7 @@
         "pkg:golang/github.com/opencontainers/image-spec@v1.1.0-rc3?type=module",
         "pkg:golang/github.com/pkg/errors@v0.9.1?type=module",
         "pkg:golang/github.com/pmezard/go-difflib@v1.0.0?type=module",
-        "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+        "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
         "pkg:golang/github.com/spf13/cobra@v1.7.0?type=module",
         "pkg:golang/github.com/spf13/pflag@v1.0.5?type=module",
         "pkg:golang/github.com/stretchr/testify@v1.8.4?type=module",
@@ -4544,7 +4585,10 @@
       ]
     },
     {
-      "ref": "pkg:golang/github.com/gogo/protobuf@v1.3.2?type=module"
+      "ref": "pkg:golang/github.com/gogo/protobuf@v1.3.2?type=module",
+      "dependsOn": [
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module"
+      ]
     },
     {
       "ref": "pkg:golang/github.com/golang-jwt/jwt/v4@v4.4.2?type=module"
@@ -4564,6 +4608,7 @@
       "dependsOn": [
         "pkg:golang/github.com/golang/protobuf@v1.5.3?type=module",
         "pkg:golang/github.com/stoewer/go-strcase@v1.3.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/google.golang.org/genproto@v0.0.0-20230410155749-daa745c078e1?type=module",
         "pkg:golang/google.golang.org/protobuf@v1.30.0?type=module",
         "pkg:golang/gopkg.in/yaml.v3@v3.0.1?type=module"
@@ -4591,15 +4636,17 @@
         "pkg:golang/github.com/opencontainers/go-digest@v1.0.0?type=module",
         "pkg:golang/github.com/opencontainers/image-spec@v1.1.0-rc3?type=module",
         "pkg:golang/github.com/pkg/errors@v0.9.1?type=module",
-        "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+        "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
         "pkg:golang/github.com/spf13/cobra@v1.7.0?type=module",
         "pkg:golang/github.com/spf13/pflag@v1.0.5?type=module",
         "pkg:golang/github.com/vbatts/tar-split@v0.11.3?type=module",
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
         "pkg:golang/golang.org/x/net@v0.10.0?type=module",
         "pkg:golang/golang.org/x/oauth2@v0.8.0?type=module",
         "pkg:golang/golang.org/x/sync@v0.2.0?type=module",
         "pkg:golang/golang.org/x/sys@v0.8.0?type=module",
         "pkg:golang/golang.org/x/time@v0.3.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/google.golang.org/appengine@v1.6.7?type=module",
         "pkg:golang/google.golang.org/protobuf@v1.30.0?type=module",
         "pkg:golang/gopkg.in/yaml.v3@v3.0.1?type=module"
@@ -4731,6 +4778,7 @@
         "pkg:golang/golang.org/x/net@v0.10.0?type=module",
         "pkg:golang/golang.org/x/sys@v0.8.0?type=module",
         "pkg:golang/golang.org/x/text@v0.9.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/google.golang.org/protobuf@v1.30.0?type=module",
         "pkg:golang/gopkg.in/yaml.v3@v3.0.1?type=module"
       ]
@@ -4754,7 +4802,7 @@
     {
       "ref": "pkg:golang/github.com/operator-framework/api@v0.13.0?type=module",
       "dependsOn": [
-        "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+        "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
         "pkg:golang/github.com/spf13/cobra@v1.7.0?type=module",
         "pkg:golang/github.com/stretchr/testify@v1.8.4?type=module",
         "pkg:golang/google.golang.org/genproto@v0.0.0-20230410155749-daa745c078e1?type=module",
@@ -4846,9 +4894,6 @@
         "pkg:golang/gopkg.in/yaml.v2@v2.4.0?type=module"
       ]
     },
-    {
-      "ref": "pkg:golang/github.com/radovskyb/watcher@v1.0.7?type=module"
-    },
     {
       "ref": "pkg:golang/github.com/redhat-developer/service-binding-operator@v1.3.4?type=module",
       "dependsOn": [
@@ -4881,7 +4926,7 @@
         "pkg:golang/github.com/pmezard/go-difflib@v1.0.0?type=module",
         "pkg:golang/github.com/prometheus/client_golang@v1.15.1?type=module",
         "pkg:golang/github.com/prometheus/procfs@v0.9.0?type=module",
-        "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+        "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
         "pkg:golang/github.com/spf13/pflag@v1.0.5?type=module",
         "pkg:golang/github.com/stretchr/testify@v1.8.4?type=module",
         "pkg:golang/go.uber.org/atomic@v1.9.0?type=module",
@@ -4894,6 +4939,7 @@
         "pkg:golang/golang.org/x/term@v0.8.0?type=module",
         "pkg:golang/golang.org/x/text@v0.9.0?type=module",
         "pkg:golang/golang.org/x/time@v0.3.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/gomodules.xyz/jsonpatch/v2@v2.2.0?type=module",
         "pkg:golang/google.golang.org/appengine@v1.6.7?type=module",
         "pkg:golang/google.golang.org/protobuf@v1.30.0?type=module",
@@ -4919,7 +4965,8 @@
       "dependsOn": [
         "pkg:golang/github.com/onsi/gomega@v1.27.7?type=module",
         "pkg:golang/github.com/rickb777/plural@v1.2.1?type=module",
-        "pkg:golang/golang.org/x/text@v0.9.0?type=module"
+        "pkg:golang/golang.org/x/text@v0.9.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module"
       ]
     },
     {
@@ -4941,7 +4988,7 @@
       "ref": "pkg:golang/github.com/shurcooL/vfsgen@v0.0.0-20181202132449-6a9ea43bcacd?type=module"
     },
     {
-      "ref": "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+      "ref": "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
       "dependsOn": [
         "pkg:golang/github.com/davecgh/go-spew@v1.1.1?type=module",
         "pkg:golang/github.com/stretchr/testify@v1.8.4?type=module",
@@ -5056,7 +5103,7 @@
     {
       "ref": "pkg:golang/github.com/vbatts/tar-split@v0.11.3?type=module",
       "dependsOn": [
-        "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+        "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
         "pkg:golang/golang.org/x/sys@v0.8.0?type=module"
       ]
     },
@@ -5118,6 +5165,12 @@
         "pkg:golang/golang.org/x/text@v0.9.0?type=module"
       ]
     },
+    {
+      "ref": "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
+      "dependsOn": [
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module"
+      ]
+    },
     {
       "ref": "pkg:golang/golang.org/x/net@v0.10.0?type=module",
       "dependsOn": [
@@ -5152,12 +5205,23 @@
     {
       "ref": "pkg:golang/golang.org/x/text@v0.9.0?type=module",
       "dependsOn": [
-        "pkg:golang/golang.org/x/sys@v0.8.0?type=module"
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
+        "pkg:golang/golang.org/x/sys@v0.8.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module"
       ]
     },
     {
       "ref": "pkg:golang/golang.org/x/time@v0.3.0?type=module"
     },
+    {
+      "ref": "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
+      "dependsOn": [
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
+        "pkg:golang/golang.org/x/net@v0.10.0?type=module",
+        "pkg:golang/golang.org/x/sync@v0.2.0?type=module",
+        "pkg:golang/golang.org/x/sys@v0.8.0?type=module"
+      ]
+    },
     {
       "ref": "pkg:golang/gomodules.xyz/jsonpatch/v2@v2.2.0?type=module",
       "dependsOn": [
@@ -5308,7 +5372,7 @@
         "pkg:golang/github.com/pmezard/go-difflib@v1.0.0?type=module",
         "pkg:golang/github.com/prometheus/client_golang@v1.15.1?type=module",
         "pkg:golang/github.com/prometheus/procfs@v0.9.0?type=module",
-        "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+        "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
         "pkg:golang/github.com/spf13/cobra@v1.7.0?type=module",
         "pkg:golang/github.com/spf13/pflag@v1.0.5?type=module",
         "pkg:golang/github.com/stoewer/go-strcase@v1.3.0?type=module",
@@ -5317,6 +5381,7 @@
         "pkg:golang/go.uber.org/multierr@v1.9.0?type=module",
         "pkg:golang/go.uber.org/zap@v1.24.0?type=module",
         "pkg:golang/golang.org/x/crypto@v0.9.0?type=module",
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
         "pkg:golang/golang.org/x/net@v0.10.0?type=module",
         "pkg:golang/golang.org/x/oauth2@v0.8.0?type=module",
         "pkg:golang/golang.org/x/sync@v0.2.0?type=module",
@@ -5324,6 +5389,7 @@
         "pkg:golang/golang.org/x/term@v0.8.0?type=module",
         "pkg:golang/golang.org/x/text@v0.9.0?type=module",
         "pkg:golang/golang.org/x/time@v0.3.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/google.golang.org/appengine@v1.6.7?type=module",
         "pkg:golang/google.golang.org/genproto@v0.0.0-20230410155749-daa745c078e1?type=module",
         "pkg:golang/google.golang.org/grpc@v1.55.0?type=module",
@@ -5335,6 +5401,7 @@
         "pkg:golang/k8s.io/apimachinery@v0.25.6?type=module",
         "pkg:golang/k8s.io/client-go@v0.25.6?type=module",
         "pkg:golang/k8s.io/component-base@v0.25.6?type=module",
+        "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
         "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
         "pkg:golang/k8s.io/kube-openapi@v0.0.0-20221012153701-172d655c2280?type=module",
         "pkg:golang/k8s.io/utils@v0.0.0-20221108210102-8e77b1f39fe2?type=module",
@@ -5545,6 +5612,18 @@
         "pkg:golang/sigs.k8s.io/yaml@v1.3.0?type=module"
       ]
     },
+    {
+      "ref": "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
+      "dependsOn": [
+        "pkg:golang/github.com/davecgh/go-spew@v1.1.1?type=module",
+        "pkg:golang/github.com/google/go-cmp@v0.5.9?type=module",
+        "pkg:golang/github.com/google/gofuzz@v1.2.0?type=module",
+        "pkg:golang/github.com/spf13/pflag@v1.0.5?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
+        "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
+        "pkg:golang/sigs.k8s.io/yaml@v1.3.0?type=module"
+      ]
+    },
     {
       "ref": "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
       "dependsOn": [
@@ -5575,12 +5654,15 @@
         "pkg:golang/github.com/pmezard/go-difflib@v1.0.0?type=module",
         "pkg:golang/github.com/spf13/pflag@v1.0.5?type=module",
         "pkg:golang/github.com/stretchr/testify@v1.8.4?type=module",
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
         "pkg:golang/golang.org/x/net@v0.10.0?type=module",
         "pkg:golang/golang.org/x/sys@v0.8.0?type=module",
         "pkg:golang/golang.org/x/text@v0.9.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/google.golang.org/protobuf@v1.30.0?type=module",
         "pkg:golang/gopkg.in/yaml.v2@v2.4.0?type=module",
         "pkg:golang/gopkg.in/yaml.v3@v3.0.1?type=module",
+        "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
         "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
         "pkg:golang/k8s.io/utils@v0.0.0-20221108210102-8e77b1f39fe2?type=module",
         "pkg:golang/sigs.k8s.io/structured-merge-diff/v4@v4.2.3?type=module",
@@ -5712,6 +5794,7 @@
         "pkg:golang/go.uber.org/multierr@v1.9.0?type=module",
         "pkg:golang/go.uber.org/zap@v1.24.0?type=module",
         "pkg:golang/golang.org/x/crypto@v0.9.0?type=module",
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
         "pkg:golang/golang.org/x/net@v0.10.0?type=module",
         "pkg:golang/golang.org/x/oauth2@v0.8.0?type=module",
         "pkg:golang/golang.org/x/sync@v0.2.0?type=module",
@@ -5719,6 +5802,7 @@
         "pkg:golang/golang.org/x/term@v0.8.0?type=module",
         "pkg:golang/golang.org/x/text@v0.9.0?type=module",
         "pkg:golang/golang.org/x/time@v0.3.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/gomodules.xyz/jsonpatch/v2@v2.2.0?type=module",
         "pkg:golang/google.golang.org/api@v0.122.0?type=module",
         "pkg:golang/google.golang.org/appengine@v1.6.7?type=module",
@@ -5732,6 +5816,7 @@
         "pkg:golang/k8s.io/apiextensions-apiserver@v0.25.6?type=module",
         "pkg:golang/k8s.io/apimachinery@v0.25.6?type=module",
         "pkg:golang/k8s.io/client-go@v0.25.6?type=module",
+        "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
         "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
         "pkg:golang/k8s.io/kube-openapi@v0.0.0-20221012153701-172d655c2280?type=module",
         "pkg:golang/k8s.io/utils@v0.0.0-20221108210102-8e77b1f39fe2?type=module",
@@ -5785,6 +5870,7 @@
         "pkg:golang/go.uber.org/atomic@v1.9.0?type=module",
         "pkg:golang/go.uber.org/multierr@v1.9.0?type=module",
         "pkg:golang/go.uber.org/zap@v1.24.0?type=module",
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
         "pkg:golang/golang.org/x/net@v0.10.0?type=module",
         "pkg:golang/golang.org/x/oauth2@v0.8.0?type=module",
         "pkg:golang/golang.org/x/sync@v0.2.0?type=module",
@@ -5792,6 +5878,7 @@
         "pkg:golang/golang.org/x/term@v0.8.0?type=module",
         "pkg:golang/golang.org/x/text@v0.9.0?type=module",
         "pkg:golang/golang.org/x/time@v0.3.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/gomodules.xyz/jsonpatch/v2@v2.2.0?type=module",
         "pkg:golang/google.golang.org/api@v0.122.0?type=module",
         "pkg:golang/google.golang.org/appengine@v1.6.7?type=module",
@@ -5804,6 +5891,7 @@
         "pkg:golang/k8s.io/api@v0.25.6?type=module",
         "pkg:golang/k8s.io/apimachinery@v0.25.6?type=module",
         "pkg:golang/k8s.io/client-go@v0.25.6?type=module",
+        "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
         "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
         "pkg:golang/k8s.io/kube-openapi@v0.0.0-20221012153701-172d655c2280?type=module",
         "pkg:golang/k8s.io/utils@v0.0.0-20221108210102-8e77b1f39fe2?type=module",
@@ -5860,6 +5948,7 @@
         "pkg:golang/go.uber.org/multierr@v1.9.0?type=module",
         "pkg:golang/go.uber.org/zap@v1.24.0?type=module",
         "pkg:golang/golang.org/x/crypto@v0.9.0?type=module",
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
         "pkg:golang/golang.org/x/net@v0.10.0?type=module",
         "pkg:golang/golang.org/x/oauth2@v0.8.0?type=module",
         "pkg:golang/golang.org/x/sync@v0.2.0?type=module",
@@ -5867,6 +5956,7 @@
         "pkg:golang/golang.org/x/term@v0.8.0?type=module",
         "pkg:golang/golang.org/x/text@v0.9.0?type=module",
         "pkg:golang/golang.org/x/time@v0.3.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/gomodules.xyz/jsonpatch/v2@v2.2.0?type=module",
         "pkg:golang/google.golang.org/api@v0.122.0?type=module",
         "pkg:golang/google.golang.org/appengine@v1.6.7?type=module",
@@ -5880,6 +5970,7 @@
         "pkg:golang/k8s.io/apiextensions-apiserver@v0.25.6?type=module",
         "pkg:golang/k8s.io/apimachinery@v0.25.6?type=module",
         "pkg:golang/k8s.io/client-go@v0.25.6?type=module",
+        "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
         "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
         "pkg:golang/k8s.io/kube-openapi@v0.0.0-20221012153701-172d655c2280?type=module",
         "pkg:golang/k8s.io/utils@v0.0.0-20221108210102-8e77b1f39fe2?type=module",
@@ -5946,7 +6037,7 @@
         "pkg:golang/github.com/prometheus/client_golang@v1.15.1?type=module",
         "pkg:golang/github.com/prometheus/procfs@v0.9.0?type=module",
         "pkg:golang/github.com/prometheus/statsd_exporter@v0.21.0?type=module",
-        "pkg:golang/github.com/sirupsen/logrus@v1.9.2?type=module",
+        "pkg:golang/github.com/sirupsen/logrus@v1.9.3?type=module",
         "pkg:golang/github.com/spf13/pflag@v1.0.5?type=module",
         "pkg:golang/github.com/vbatts/tar-split@v0.11.3?type=module",
         "pkg:golang/go.opencensus.io@v0.24.0?type=module",
@@ -5955,6 +6046,7 @@
         "pkg:golang/go.uber.org/multierr@v1.9.0?type=module",
         "pkg:golang/go.uber.org/zap@v1.24.0?type=module",
         "pkg:golang/golang.org/x/crypto@v0.9.0?type=module",
+        "pkg:golang/golang.org/x/mod@v0.10.0?type=module",
         "pkg:golang/golang.org/x/net@v0.10.0?type=module",
         "pkg:golang/golang.org/x/oauth2@v0.8.0?type=module",
         "pkg:golang/golang.org/x/sync@v0.2.0?type=module",
@@ -5962,6 +6054,7 @@
         "pkg:golang/golang.org/x/term@v0.8.0?type=module",
         "pkg:golang/golang.org/x/text@v0.9.0?type=module",
         "pkg:golang/golang.org/x/time@v0.3.0?type=module",
+        "pkg:golang/golang.org/x/tools@v0.9.1?type=module",
         "pkg:golang/gomodules.xyz/jsonpatch/v2@v2.2.0?type=module",
         "pkg:golang/google.golang.org/api@v0.122.0?type=module",
         "pkg:golang/google.golang.org/appengine@v1.6.7?type=module",
@@ -5975,6 +6068,7 @@
         "pkg:golang/k8s.io/apiextensions-apiserver@v0.25.6?type=module",
         "pkg:golang/k8s.io/apimachinery@v0.25.6?type=module",
         "pkg:golang/k8s.io/client-go@v0.25.6?type=module",
+        "pkg:golang/k8s.io/gengo@v0.0.0-20221011193443-fad74ee6edd9?type=module",
         "pkg:golang/k8s.io/klog/v2@v2.100.1?type=module",
         "pkg:golang/k8s.io/kube-openapi@v0.0.0-20221012153701-172d655c2280?type=module",
         "pkg:golang/k8s.io/utils@v0.0.0-20221108210102-8e77b1f39fe2?type=module",
diff --git a/cmd/util/doc-gen/generators/generators.go b/cmd/util/doc-gen/generators/generators.go
new file mode 100644
index 000000000..09d66c501
--- /dev/null
+++ b/cmd/util/doc-gen/generators/generators.go
@@ -0,0 +1,69 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package generators
+
+import (
+	"path/filepath"
+	"strings"
+
+	"k8s.io/gengo/args"
+	"k8s.io/gengo/generator"
+	"k8s.io/gengo/namer"
+)
+
+// CustomArgs --.
+type CustomArgs struct {
+	DocDir      string
+	ResourceDir string
+	TraitPath   string
+	NavPath     string
+	ListPath    string
+}
+
+// NameSystems returns the name system used by the generators in this package.
+func NameSystems() namer.NameSystems {
+	return namer.NameSystems{
+		"default": namer.NewPublicNamer(0),
+	}
+}
+
+// DefaultNameSystem returns the default name system for ordering the types to be
+// processed by the generators in this package.
+func DefaultNameSystem() string {
+	return "default"
+}
+
+// Packages --.
+func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
+	var packages generator.Packages
+	for _, i := range context.Inputs {
+		pkg := context.Universe[i]
+		if pkg == nil {
+			continue
+		}
+
+		packages = append(packages, &generator.DefaultPackage{
+			PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0],
+			PackagePath: pkg.Path,
+			GeneratorFunc: func(c *generator.Context) []generator.Generator {
+				return []generator.Generator{NewTraitDocGen(arguments), NewtraitMetaDataGen(arguments)}
+			},
+		})
+	}
+	return packages
+}
diff --git a/cmd/util/doc-gen/generators/traitdocgen.go b/cmd/util/doc-gen/generators/traitdocgen.go
new file mode 100644
index 000000000..08f8c69af
--- /dev/null
+++ b/cmd/util/doc-gen/generators/traitdocgen.go
@@ -0,0 +1,328 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package generators
+
+import (
+	"fmt"
+	"io"
+	"os"
+	"path"
+	"reflect"
+	"regexp"
+	"sort"
+	"strings"
+
+	"golang.org/x/text/cases"
+	"golang.org/x/text/language"
+
+	"k8s.io/gengo/args"
+	"k8s.io/gengo/generator"
+	"k8s.io/gengo/types"
+
+	v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/v2/pkg/trait"
+	"github.com/apache/camel-k/v2/pkg/util"
+)
+
+const (
+	tagTrait = "+camel-k:trait"
+	tagLint  = "nolint"
+
+	adocCommonMarkerStart = "// Start of autogenerated code - DO NOT EDIT!"
+	adocCommonMarkerEnd   = "// End of autogenerated code - DO NOT EDIT!"
+
+	adocDescriptionMarkerStart = adocCommonMarkerStart + " (description)"
+	adocDescriptionMarkerEnd   = adocCommonMarkerEnd + " (description)"
+
+	adocConfigurationMarkerStart = adocCommonMarkerStart + " (configuration)"
+	adocConfigurationMarkerEnd   = adocCommonMarkerEnd + " (configuration)"
+
+	adocNavMarkerStart = adocCommonMarkerStart + " (trait-nav)"
+	adocNavMarkerEnd   = adocCommonMarkerEnd + " (trait-nav)"
+)
+
+var tagTraitID = regexp.MustCompile(fmt.Sprintf("%s=([a-z0-9-]+)", regexp.QuoteMeta(tagTrait)))
+
+// traitDocGen produces documentation about traits.
+type traitDocGen struct {
+	generator.DefaultGen
+	arguments           *args.GeneratorArgs
+	generatedTraitFiles []string
+}
+
+// traitDocGen implements Generator interface.
+var _ generator.Generator = &traitDocGen{}
+
+func NewTraitDocGen(arguments *args.GeneratorArgs) generator.Generator {
+	return &traitDocGen{
+		DefaultGen: generator.DefaultGen{},
+		arguments:  arguments,
+	}
+}
+
+func (g *traitDocGen) Filename() string {
+	return "zz_generated_doc.go"
+}
+
+func (g *traitDocGen) Filter(context *generator.Context, t *types.Type) bool {
+	for _, c := range t.CommentLines {
+		if strings.Contains(c, tagTrait) {
+			return true
+		}
+	}
+	return false
+}
+
+func (g *traitDocGen) GenerateType(context *generator.Context, t *types.Type, out io.Writer) error {
+	customArgs, ok := g.arguments.CustomArgs.(*CustomArgs)
+	if !ok {
+		return fmt.Errorf("type assertion failed: %v", g.arguments.CustomArgs)
+	}
+	docDir := customArgs.DocDir
+	traitPath := customArgs.TraitPath
+	traitID := getTraitID(t)
+	traitFile := traitID + ".adoc"
+	filename := path.Join(docDir, traitPath, traitFile)
+
+	g.generatedTraitFiles = append(g.generatedTraitFiles, traitFile)
+
+	return util.WithFileContent(filename, func(file *os.File, data []byte) error {
+		content := strings.Split(string(data), "\n")
+
+		writeTitle(traitID, &content)
+		writeDescription(t, traitID, &content)
+		writeFields(t, traitID, &content)
+
+		return writeFile(file, content)
+	})
+}
+
+func (g *traitDocGen) Finalize(c *generator.Context, w io.Writer) error {
+	return g.FinalizeNav(c)
+}
+
+func (g *traitDocGen) FinalizeNav(*generator.Context) error {
+	customArgs, ok := g.arguments.CustomArgs.(*CustomArgs)
+	if !ok {
+		return fmt.Errorf("type assertion failed: %v", g.arguments.CustomArgs)
+	}
+	docDir := customArgs.DocDir
+	navPath := customArgs.NavPath
+	filename := path.Join(docDir, navPath)
+
+	return util.WithFileContent(filename, func(file *os.File, data []byte) error {
+		content := strings.Split(string(data), "\n")
+
+		pre, post := split(content, adocNavMarkerStart, adocNavMarkerEnd)
+
+		content = append([]string(nil), pre...)
+		content = append(content, adocNavMarkerStart)
+		sort.Strings(g.generatedTraitFiles)
+		for _, t := range g.generatedTraitFiles {
+			name := traitNameFromFile(t)
+			content = append(content, "** xref:traits:"+t+"["+name+"]")
+		}
+		content = append(content, adocNavMarkerEnd)
+		content = append(content, post...)
+
+		return writeFile(file, content)
+	})
+}
+
+func traitNameFromFile(file string) string {
+	name := strings.TrimSuffix(file, ".adoc")
+	name = strings.ReplaceAll(name, "trait", "")
+	name = strings.ReplaceAll(name, "-", " ")
+	name = strings.Trim(name, " ")
+	name = cases.Title(language.English).String(name)
+	return name
+}
+
+func writeTitle(traitID string, content *[]string) {
+	res := append([]string(nil), *content...)
+	for _, s := range res {
+		if strings.HasPrefix(s, "= ") {
+			// Already has a title
+			return
+		}
+	}
+	res = append([]string{"= " + cases.Title(language.English).String(strings.ReplaceAll(traitID, "-", " ")) + " Trait"}, res...)
+	*content = res
+}
+
+func writeDescription(t *types.Type, traitID string, content *[]string) {
+	pre, post := split(*content, adocDescriptionMarkerStart, adocDescriptionMarkerEnd)
+	res := append([]string(nil), pre...)
+	res = append(res, adocDescriptionMarkerStart)
+	res = append(res, filterOutTagsAndComments(t.CommentLines)...)
+	profiles := strings.Join(determineProfiles(traitID), ", ")
+	res = append(res, "", fmt.Sprintf("This trait is available in the following profiles: **%s**.", profiles))
+	if isPlatformTrait(traitID) {
+		res = append(res, "", fmt.Sprintf("WARNING: The %s trait is a *platform trait*: disabling it may compromise the platform functionality.", traitID))
+	}
+	res = append(res, "", adocDescriptionMarkerEnd)
+	res = append(res, post...)
+	*content = res
+}
+
+func writeFields(t *types.Type, traitID string, content *[]string) {
+	pre, post := split(*content, adocConfigurationMarkerStart, adocConfigurationMarkerEnd)
+	res := append([]string(nil), pre...)
+	res = append(res, adocConfigurationMarkerStart, "== Configuration", "")
+	res = append(res, "Trait properties can be specified when running any integration with the CLI:")
+	res = append(res, "[source,console]")
+	res = append(res, "----")
+	if len(t.Members) > 1 {
+		res = append(res, fmt.Sprintf("$ kamel run --trait %s.[key]=[value] --trait %s.[key2]=[value2] integration.groovy", traitID, traitID))
+	} else {
+		res = append(res, fmt.Sprintf("$ kamel run --trait %s.[key]=[value] integration.groovy", traitID))
+	}
+	res = append(res, "----")
+	res = append(res, "The following configuration options are available:", "")
+	res = append(res, "[cols=\"2m,1m,5a\"]", "|===")
+	res = append(res, "|Property | Type | Description", "")
+	writeMembers(t, traitID, &res)
+	res = append(res, "|===", "", adocConfigurationMarkerEnd)
+	res = append(res, post...)
+	*content = res
+}
+
+func writeMembers(t *types.Type, traitID string, content *[]string) {
+	res := append([]string(nil), *content...)
+	for _, m := range t.Members {
+		prop := reflect.StructTag(m.Tags).Get("property")
+		if prop == "" {
+			continue
+		}
+
+		if strings.Contains(prop, "squash") {
+			writeMembers(m.Type, traitID, &res)
+		} else {
+			res = append(res, "| "+traitID+"."+prop)
+			res = append(res, "| "+strings.TrimPrefix(m.Type.Name.Name, "*"))
+			first := true
+			for _, l := range filterOutTagsAndComments(m.CommentLines) {
+				escapedComment := escapeASCIIDoc(l)
+				if first {
+					res = append(res, "| "+escapedComment)
+					first = false
+				} else {
+					res = append(res, escapedComment)
+				}
+			}
+			res = append(res, "")
+		}
+	}
+	*content = res
+}
+
+func getTraitID(t *types.Type) string {
+	for _, s := range t.CommentLines {
+		if strings.Contains(s, tagTrait) {
+			matches := tagTraitID.FindStringSubmatch(s)
+			if len(matches) < 2 {
+				panic(fmt.Sprintf("unable to extract trait ID from tag line `%s`", s))
+			}
+			return matches[1]
+		}
+	}
+	panic(fmt.Sprintf("trait ID not found in type %s", t.Name.Name))
+}
+
+func filterOutTagsAndComments(comments []string) []string {
+	res := make([]string, 0, len(comments))
+	for _, l := range comments {
+		if !strings.HasPrefix(strings.TrimLeft(l, " \t"), "+") &&
+			!strings.HasPrefix(strings.TrimLeft(l, " \t"), "TODO:") &&
+			!strings.HasPrefix(strings.TrimLeft(l, " \t"), tagLint) {
+			res = append(res, l)
+		}
+	}
+	return res
+}
+
+// escapeAsciiDoc is in charge to escape those chars used for formatting purposes.
+func escapeASCIIDoc(text string) string {
+	return strings.ReplaceAll(text, "|", "\\|")
+}
+
+func split(doc []string, startMarker, endMarker string) ([]string, []string) {
+	if len(doc) == 0 {
+		return nil, nil
+	}
+	idx := len(doc)
+	for i, s := range doc {
+		if s == startMarker {
+			idx = i
+			break
+		}
+	}
+	idy := len(doc)
+	for j, s := range doc {
+		if j > idx && s == endMarker {
+			idy = j
+			break
+		}
+	}
+	pre := doc[0:idx]
+	post := []string{}
+	if idy < len(doc) {
+		post = doc[idy+1:]
+	}
+	return pre, post
+}
+
+func writeFile(file *os.File, content []string) error {
+	if err := file.Truncate(0); err != nil {
+		return err
+	}
+	max := 0
+	for i, line := range content {
+		if line != "" {
+			max = i
+		}
+	}
+	for i, line := range content {
+		if i <= max {
+			if _, err := file.WriteString(line + "\n"); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func isPlatformTrait(traitID string) bool {
+	catalog := trait.NewCatalog(nil)
+	t := catalog.GetTrait(traitID)
+	return t.IsPlatformTrait()
+}
+
+func determineProfiles(traitID string) []string {
+	var profiles []string
+	catalog := trait.NewCatalog(nil)
+	for _, p := range v1.AllTraitProfiles {
+		traits := catalog.TraitsForProfile(p)
+		for _, t := range traits {
+			if string(t.ID()) == traitID {
+				profiles = append(profiles, string(p))
+			}
+		}
+	}
+	return profiles
+}
diff --git a/cmd/util/doc-gen/generators/traitmetadatagen.go b/cmd/util/doc-gen/generators/traitmetadatagen.go
new file mode 100644
index 000000000..5d3f3e0ab
--- /dev/null
+++ b/cmd/util/doc-gen/generators/traitmetadatagen.go
@@ -0,0 +1,183 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package generators
+
+import (
+	"fmt"
+	"io"
+	"os"
+	"path"
+	"reflect"
+	"sort"
+	"strings"
+
+	"github.com/apache/camel-k/v2/pkg/util"
+
+	"gopkg.in/yaml.v2"
+	"k8s.io/gengo/args"
+	"k8s.io/gengo/generator"
+	"k8s.io/gengo/types"
+)
+
+const traitFile = "traits.yaml"
+
+// traitMetaDataGen produces YAML documentation about trait descriptions.
+type traitMetaDataGen struct {
+	generator.DefaultGen
+	arguments *args.GeneratorArgs
+	Root      *traitMetaDataRoot
+}
+
+type traitMetaDataRoot struct {
+	Traits []traitMetaData `yaml:"traits"`
+}
+
+type traitMetaData struct {
+	Name        string                  `yaml:"name"`
+	Platform    bool                    `yaml:"platform"`
+	Profiles    []string                `yaml:"profiles"`
+	Description string                  `yaml:"description"`
+	Properties  []traitPropertyMetaData `yaml:"properties"`
+}
+
+type traitPropertyMetaData struct {
+	Name        string `yaml:"name"`
+	TypeName    string `yaml:"type"`
+	Description string `yaml:"description"`
+}
+
+// traitMetaDataGen implements Generator interface.
+var _ generator.Generator = &traitMetaDataGen{}
+
+// NewtraitMetaDataGen --.
+func NewtraitMetaDataGen(arguments *args.GeneratorArgs) generator.Generator {
+	return &traitMetaDataGen{
+		DefaultGen: generator.DefaultGen{},
+		arguments:  arguments,
+		Root:       &traitMetaDataRoot{},
+	}
+}
+
+func (g *traitMetaDataGen) Filename() string {
+	return "zz_desc_generated.go"
+}
+
+func (g *traitMetaDataGen) Filter(context *generator.Context, t *types.Type) bool {
+	for _, c := range t.CommentLines {
+		if strings.Contains(c, tagTrait) {
+			return true
+		}
+	}
+	return false
+}
+
+func (g *traitMetaDataGen) GenerateType(context *generator.Context, t *types.Type, out io.Writer) error {
+	traitID := g.getTraitID(t)
+	td := &traitMetaData{}
+	g.buildDescription(t, traitID, td)
+	g.buildFields(t, td)
+	g.Root.Traits = append(g.Root.Traits, *td)
+	return nil
+}
+
+func (g *traitMetaDataGen) Finalize(c *generator.Context, w io.Writer) error {
+	customArgs, ok := g.arguments.CustomArgs.(*CustomArgs)
+	if !ok {
+		return fmt.Errorf("type assertion failed: %v", g.arguments.CustomArgs)
+	}
+	deployDir := customArgs.ResourceDir
+	filename := path.Join(deployDir, traitFile)
+
+	// reorder the traits metadata so that it always gets the identical result
+	sort.Slice(g.Root.Traits, func(i, j int) bool {
+		return g.Root.Traits[i].Name < g.Root.Traits[j].Name
+	})
+
+	return util.WithFile(filename, os.O_RDWR|os.O_CREATE, 0o777, func(file *os.File) error {
+		if err := file.Truncate(0); err != nil {
+			return err
+		}
+
+		data, err := yaml.Marshal(g.Root)
+		if err != nil {
+			fmt.Fprintf(file, "error: %v", err)
+		}
+		fmt.Fprintf(file, "%s", string(data))
+
+		return nil
+	})
+}
+
+func (g *traitMetaDataGen) getTraitID(t *types.Type) string {
+	for _, s := range t.CommentLines {
+		if strings.Contains(s, tagTrait) {
+			matches := tagTraitID.FindStringSubmatch(s)
+			if len(matches) < 2 {
+				panic(fmt.Sprintf("unable to extract trait ID from tag line `%s`", s))
+			}
+			return matches[1]
+		}
+	}
+	panic(fmt.Sprintf("trait ID not found in type %s", t.Name.Name))
+}
+
+func (g *traitMetaDataGen) buildDescription(t *types.Type, traitID string, td *traitMetaData) {
+	desc := []string(nil)
+	desc = append(desc, filterOutTagsAndComments(t.CommentLines)...)
+	td.Name = traitID
+	td.Description = ""
+	for _, line := range desc {
+		text := strings.Trim(line, " ")
+		if len(text) == 0 {
+			continue
+		}
+		if len(td.Description) > 0 {
+			td.Description += " "
+		}
+		td.Description += text
+	}
+	td.Profiles = determineProfiles(traitID)
+	td.Platform = isPlatformTrait(traitID)
+}
+
+func (g *traitMetaDataGen) buildFields(t *types.Type, td *traitMetaData) {
+	if len(t.Members) > 1 {
+		res := []string(nil)
+		g.buildMembers(t, &res, td)
+	}
+}
+
+func (g *traitMetaDataGen) buildMembers(t *types.Type, content *[]string, td *traitMetaData) {
+	for _, m := range t.Members {
+		res := append([]string(nil), *content...)
+		prop := reflect.StructTag(m.Tags).Get("property")
+		if prop != "" {
+			if strings.Contains(prop, "squash") {
+				g.buildMembers(m.Type, &res, td)
+			} else {
+				pd := traitPropertyMetaData{}
+				pd.Name = prop
+				pd.TypeName = strings.TrimPrefix(m.Type.Name.Name, "*")
+
+				res = append(res, filterOutTagsAndComments(m.CommentLines)...)
+				pd.Description = strings.Join(res, " ")
+				td.Properties = append(td.Properties, pd)
+			}
+		}
+	}
+}
diff --git a/cmd/util/doc-gen/main.go b/cmd/util/doc-gen/main.go
new file mode 100644
index 000000000..b80d8bc54
--- /dev/null
+++ b/cmd/util/doc-gen/main.go
@@ -0,0 +1,47 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+	"github.com/apache/camel-k/v2/cmd/util/doc-gen/generators"
+	"github.com/spf13/pflag"
+	"k8s.io/gengo/args"
+
+	_ "github.com/apache/camel-k/v2/addons"
+)
+
+func main() {
+	arguments := args.Default()
+
+	// Custom args.
+	customArgs := &generators.CustomArgs{}
+	pflag.CommandLine.StringVar(&customArgs.DocDir, "doc-dir", "./docs", "Root of the document directory.")
+	pflag.CommandLine.StringVar(&customArgs.ResourceDir, "resource-dir", "./resources", "Root of the resource directory.")
+	pflag.CommandLine.StringVar(&customArgs.TraitPath, "traits-path", "modules/traits/pages", "Path to the traits directory.")
+	pflag.CommandLine.StringVar(&customArgs.NavPath, "nav-path", "modules/ROOT/nav.adoc", "Path to the navigation file.")
+	pflag.CommandLine.StringVar(&customArgs.ListPath, "list-path", "modules/traits/pages/traits.adoc", "Path to the trait list file.")
+	arguments.CustomArgs = customArgs
+
+	if err := arguments.Execute(
+		generators.NameSystems(),
+		generators.DefaultNameSystem(),
+		generators.Packages,
+	); err != nil {
+		panic(err)
+	}
+}
diff --git a/cmd/util/json-schema-gen/main.go b/cmd/util/json-schema-gen/main.go
new file mode 100644
index 000000000..d5ebe78cd
--- /dev/null
+++ b/cmd/util/json-schema-gen/main.go
@@ -0,0 +1,174 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"os"
+	"reflect"
+	"strings"
+
+	"github.com/apache/camel-k/v2/pkg/util"
+
+	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+	clientscheme "k8s.io/client-go/kubernetes/scheme"
+
+	"github.com/apache/camel-k/v2/pkg/util/kubernetes"
+)
+
+func main() {
+	if len(os.Args) != 6 {
+		fmt.Fprintln(os.Stderr, `Use "json-schema-gen <crd> <schema> <path> <isArray> <destination>`)
+		os.Exit(1)
+	}
+	crd := os.Args[1]
+	schema := os.Args[2]
+	path := os.Args[3]
+	isArray := os.Args[4] == "true"
+	destination := os.Args[5]
+
+	if err := generate(crd, schema, path, isArray, destination); err != nil {
+		panic(err)
+	}
+}
+
+func generate(crdFilename, dslFilename, path string, isArray bool, destination string) error {
+	dslSchema, err := loadDslSchema(dslFilename)
+	if err != nil {
+		return err
+	}
+	if !isArray && dslSchema["type"] == "array" {
+		// nolint: forcetypeassert
+		dslSchema = dslSchema["items"].(map[string]interface{})
+	}
+
+	rebaseRefs(dslSchema)
+
+	bytes, err := json.Marshal(dslSchema)
+	if err != nil {
+		return err
+	}
+	schema := apiextensionsv1.JSONSchemaProps{}
+	err = json.Unmarshal(bytes, &schema)
+	if err != nil {
+		return err
+	}
+
+	crdSchema, err := loadCrdSchema(crdFilename)
+	if err != nil {
+		return err
+	}
+	// relocate definitions
+	if len(crdSchema.Definitions) > 0 {
+		panic("unexpected definitions found in CRD")
+	}
+	if isArray {
+		crdSchema.Definitions = schema.Items.Schema.Definitions
+		schema.Items.Schema.Definitions = apiextensionsv1.JSONSchemaDefinitions{}
+	} else {
+		crdSchema.Definitions = schema.Definitions
+		schema.Definitions = apiextensionsv1.JSONSchemaDefinitions{}
+	}
+
+	// merge DSL schema into the CRD schema
+	ref := *crdSchema
+	paths := pathComponents(path)
+	for _, p := range paths[:len(paths)-1] {
+		ref = ref.Properties[p]
+	}
+	ref.Properties[paths[len(paths)-1]] = schema
+
+	result, err := json.MarshalIndent(crdSchema, "", "  ")
+	if err != nil {
+		return err
+	}
+	return os.WriteFile(destination, result, 0o600)
+}
+
+func remapRef(ref string) string {
+	return "#" + strings.TrimPrefix(ref, "#/items")
+}
+
+func rebaseRefs(schema map[string]interface{}) {
+	for k, v := range schema {
+		switch {
+		case k == "$ref" && reflect.TypeOf(v).Kind() == reflect.String:
+			schema[k] = remapRef(fmt.Sprintf("%v", v))
+		case reflect.TypeOf(v).Kind() == reflect.Map:
+			if m, ok := v.(map[string]interface{}); ok {
+				rebaseRefs(m)
+			}
+		case reflect.TypeOf(v).Kind() == reflect.Slice:
+			if vs, ok := v.([]interface{}); ok {
+				for _, vv := range vs {
+					if reflect.TypeOf(vv).Kind() == reflect.Map {
+						if m, ok := vv.(map[string]interface{}); ok {
+							rebaseRefs(m)
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+func loadDslSchema(filename string) (map[string]interface{}, error) {
+	bytes, err := util.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	var dslSchema map[string]interface{}
+	if err := json.Unmarshal(bytes, &dslSchema); err != nil {
+		return nil, err
+	}
+	return dslSchema, nil
+}
+
+func loadCrdSchema(filename string) (*apiextensionsv1.JSONSchemaProps, error) {
+	bytes, err := util.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	scheme := clientscheme.Scheme
+	err = apiextensionsv1.AddToScheme(scheme)
+	if err != nil {
+		return nil, err
+	}
+	obj, err := kubernetes.LoadResourceFromYaml(scheme, string(bytes))
+	if err != nil {
+		return nil, err
+	}
+	crd, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
+	if !ok {
+		return nil, fmt.Errorf("type assertion failed: %v", obj)
+	}
+
+	return crd.Spec.Versions[0].Schema.OpenAPIV3Schema, nil
+}
+
+func pathComponents(path string) []string {
+	res := make([]string, 0)
+	for _, p := range strings.Split(path, ".") {
+		if len(strings.TrimSpace(p)) == 0 {
+			continue
+		}
+		res = append(res, p)
+	}
+	return res
+}
diff --git a/cmd/util/license-check/main.go b/cmd/util/license-check/main.go
new file mode 100644
index 000000000..6d79257a6
--- /dev/null
+++ b/cmd/util/license-check/main.go
@@ -0,0 +1,55 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"strings"
+
+	"github.com/apache/camel-k/v2/pkg/util"
+)
+
+func main() {
+	if len(os.Args) != 3 {
+		fmt.Fprintln(os.Stderr, `Use "license-check <file> <license>`)
+		os.Exit(1)
+	}
+
+	fileName := os.Args[1]
+	licenseName := os.Args[2]
+
+	fileBin, err := util.ReadFile(fileName)
+	if err != nil {
+		_, _ = fmt.Fprintf(os.Stderr, "cannot read file %s: %v\n", fileName, err)
+		os.Exit(1)
+	}
+	file := string(fileBin)
+
+	licenseBin, err := util.ReadFile(licenseName)
+	if err != nil {
+		_, _ = fmt.Fprintf(os.Stderr, "cannot read file %s: %v\n", licenseName, err)
+		os.Exit(1)
+	}
+	license := string(licenseBin)
+
+	if !strings.Contains(file, license) {
+		_, _ = fmt.Fprintf(os.Stderr, "file %s does not contain license\n", fileName)
+		os.Exit(1)
+	}
+}
diff --git a/cmd/util/platform-check/main.go b/cmd/util/platform-check/main.go
new file mode 100644
index 000000000..4b052b279
--- /dev/null
+++ b/cmd/util/platform-check/main.go
@@ -0,0 +1,68 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"strings"
+
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/rest"
+	"sigs.k8s.io/controller-runtime/pkg/client/config"
+)
+
+func main() {
+	fmt.Println(platformID())
+}
+
+func platformID() string {
+	client := APIClient()
+	_, apiResourceLists, err := client.Discovery().ServerGroupsAndResources()
+	exitOnError(err)
+
+	for _, apiResList := range apiResourceLists {
+		// Should be version independent just in case image api is ever upgraded
+		if strings.Contains(apiResList.GroupVersion, "image.openshift.io") {
+			return "openshift"
+		}
+	}
+
+	return "kubernetes"
+}
+
+func exitOnError(err error) {
+	if err != nil {
+		fmt.Println("ERROR:", err)
+		os.Exit(1)
+	}
+}
+
+func RestConfig() *rest.Config {
+	restConfig, err := config.GetConfig()
+	exitOnError(err)
+
+	return restConfig
+}
+
+func APIClient() kubernetes.Interface {
+	apiClient, err := kubernetes.NewForConfig(RestConfig())
+	exitOnError(err)
+
+	return apiClient
+}
diff --git a/go.mod b/go.mod
index ae87e876c..0c09a8c7f 100644
--- a/go.mod
+++ b/go.mod
@@ -29,7 +29,6 @@ require (
 	github.com/prometheus/common v0.44.0
 	github.com/redhat-developer/service-binding-operator v1.3.4
 	github.com/rs/xid v1.5.0
-	github.com/scylladb/go-set v1.0.2
 	github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
 	github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
 	github.com/sirupsen/logrus v1.9.3
@@ -52,12 +51,13 @@ require (
 	k8s.io/apimachinery v0.25.6
 	k8s.io/cli-runtime v0.25.6
 	k8s.io/client-go v0.25.6
+	k8s.io/gengo v0.0.0-20221011193443-fad74ee6edd9
 	k8s.io/klog/v2 v2.100.1
 	k8s.io/kubectl v0.25.6
 	k8s.io/utils v0.0.0-20221108210102-8e77b1f39fe2
 	knative.dev/eventing v0.37.1
 	knative.dev/pkg v0.0.0-20230418073056-dfad48eaa5d0
-	knative.dev/serving v0.37.1
+	knative.dev/serving v0.37.2
 	sigs.k8s.io/controller-runtime v0.13.1
 )
 
@@ -139,8 +139,10 @@ require (
 	go.opencensus.io v0.24.0 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	golang.org/x/crypto v0.9.0 // indirect
+	golang.org/x/mod v0.10.0 // indirect
 	golang.org/x/net v0.10.0 // indirect
 	golang.org/x/sys v0.8.0 // indirect
+	golang.org/x/tools v0.9.1 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
 	google.golang.org/api v0.122.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
diff --git a/go.sum b/go.sum
index e7846c52a..713404a37 100644
--- a/go.sum
+++ b/go.sum
@@ -204,8 +204,6 @@ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
 github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
-github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA=
-github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI=
 github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
 github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
@@ -625,8 +623,6 @@ github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/scylladb/go-set v1.0.2 h1:SkvlMCKhP0wyyct6j+0IHJkBkSZL+TDzZ4E7f7BCcRE=
-github.com/scylladb/go-set v1.0.2/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
 github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
@@ -822,6 +818,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
+golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1070,6 +1067,7 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
+golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1279,6 +1277,8 @@ k8s.io/component-base v0.25.6 h1:v3ci6FbXFcxpjyQJaaLq0MgzT3vyFzwUDWtO+KRv9Bk=
 k8s.io/component-base v0.25.6/go.mod h1:k7DfcfJ8cOI6A2xTCfU5LxsnXV+lWw1ME8cRCHzIh6o=
 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
+k8s.io/gengo v0.0.0-20221011193443-fad74ee6edd9 h1:iu3o/SxaHVI7tKPtkGzD3M9IzrE21j+CUKH98NQJ8Ms=
+k8s.io/gengo v0.0.0-20221011193443-fad74ee6edd9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
 k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
 k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
@@ -1302,8 +1302,8 @@ knative.dev/networking v0.0.0-20230419144338-e5d04e805e50 h1:X9rPBYr7Vrm075q0iXT
 knative.dev/networking v0.0.0-20230419144338-e5d04e805e50/go.mod h1:o2MyGpGfU5DoSAWCE2f/jnSC9GjGOplCslbA99yDkGo=
 knative.dev/pkg v0.0.0-20230418073056-dfad48eaa5d0 h1:EFQcoUo8I4bc+U3y6tR1B3ONYZSHWUdAfI7Vh7dae8g=
 knative.dev/pkg v0.0.0-20230418073056-dfad48eaa5d0/go.mod h1:2qWPP9Gjh9Q7ETti+WRHnBnGCSCq+6q7m3p/nmUQviE=
-knative.dev/serving v0.37.1 h1:msn1sJ9yVBVWu/5slqkpSXXqCEQRIysHR+fKMO4EXlI=
-knative.dev/serving v0.37.1/go.mod h1:v0Xbfp7olb0Gljm5l4qNuLsIf8/2p1rIt/mphxvx1z0=
+knative.dev/serving v0.37.2 h1:BZqP1dObXlf5mOfgevVBlk4iG8fCfcUEvKFIhhGElyo=
+knative.dev/serving v0.37.2/go.mod h1:v0Xbfp7olb0Gljm5l4qNuLsIf8/2p1rIt/mphxvx1z0=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go
index d5a4a824f..5d5479529 100644
--- a/pkg/metadata/metadata.go
+++ b/pkg/metadata/metadata.go
@@ -18,10 +18,9 @@ limitations under the License.
 package metadata
 
 import (
-	"github.com/scylladb/go-set/strset"
-
 	v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/v2/pkg/util/camel"
+	"github.com/apache/camel-k/v2/pkg/util/sets"
 	src "github.com/apache/camel-k/v2/pkg/util/source"
 )
 
@@ -57,8 +56,8 @@ func merge(m1 src.Metadata, m2 src.Metadata) src.Metadata {
 	return src.Metadata{
 		FromURIs:             f,
 		ToURIs:               t,
-		Dependencies:         strset.Union(m1.Dependencies, m2.Dependencies),
-		RequiredCapabilities: strset.Union(m1.RequiredCapabilities, m2.RequiredCapabilities),
+		Dependencies:         sets.Union(m1.Dependencies, m2.Dependencies),
+		RequiredCapabilities: sets.Union(m1.RequiredCapabilities, m2.RequiredCapabilities),
 		ExposesHTTPServices:  m1.ExposesHTTPServices || m2.ExposesHTTPServices,
 		PassiveEndpoints:     m1.PassiveEndpoints && m2.PassiveEndpoints,
 	}
diff --git a/pkg/trait/dependencies.go b/pkg/trait/dependencies.go
index 09197877c..30dd6f691 100644
--- a/pkg/trait/dependencies.go
+++ b/pkg/trait/dependencies.go
@@ -18,8 +18,6 @@ limitations under the License.
 package trait
 
 import (
-	"github.com/scylladb/go-set/strset"
-
 	"k8s.io/utils/pointer"
 
 	v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
@@ -28,6 +26,7 @@ import (
 	"github.com/apache/camel-k/v2/pkg/util"
 	"github.com/apache/camel-k/v2/pkg/util/camel"
 	"github.com/apache/camel-k/v2/pkg/util/kubernetes"
+	"github.com/apache/camel-k/v2/pkg/util/sets"
 )
 
 type dependenciesTrait struct {
@@ -54,7 +53,7 @@ func (t *dependenciesTrait) Apply(e *Environment) error {
 		e.Integration.Status.Dependencies = make([]string, 0)
 	}
 
-	dependencies := strset.New()
+	dependencies := sets.NewSet()
 
 	if e.Integration.Spec.Dependencies != nil {
 		if err := camel.ValidateDependenciesE(e.CamelCatalog, e.Integration.Spec.Dependencies); err != nil {
diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go
index 811bb70e2..7dd081f19 100644
--- a/pkg/trait/jvm.go
+++ b/pkg/trait/jvm.go
@@ -24,8 +24,6 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/scylladb/go-set/strset"
-
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -39,6 +37,7 @@ import (
 	"github.com/apache/camel-k/v2/pkg/util"
 	"github.com/apache/camel-k/v2/pkg/util/camel"
 	"github.com/apache/camel-k/v2/pkg/util/envvar"
+	"github.com/apache/camel-k/v2/pkg/util/sets"
 )
 
 type jvmTrait struct {
@@ -96,7 +95,7 @@ func (t *jvmTrait) Apply(e *Environment) error {
 		return fmt.Errorf("unable to find integration kit for integration %s", e.Integration.Name)
 	}
 
-	classpath := strset.New()
+	classpath := sets.NewSet()
 
 	classpath.Add("./resources")
 	classpath.Add(filepath.ToSlash(camel.ConfigResourcesMountPath))
diff --git a/pkg/trait/util.go b/pkg/trait/util.go
index 0de30bf82..0f5f89de1 100644
--- a/pkg/trait/util.go
+++ b/pkg/trait/util.go
@@ -27,8 +27,6 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/scylladb/go-set/strset"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	ctrl "sigs.k8s.io/controller-runtime/pkg/client"
@@ -41,6 +39,7 @@ import (
 	"github.com/apache/camel-k/v2/pkg/util/camel"
 	"github.com/apache/camel-k/v2/pkg/util/kubernetes"
 	"github.com/apache/camel-k/v2/pkg/util/property"
+	"github.com/apache/camel-k/v2/pkg/util/sets"
 	"github.com/apache/camel-k/v2/pkg/util/uri"
 )
 
@@ -86,7 +85,7 @@ func getIntegrationKit(ctx context.Context, c client.Client, integration *v1.Int
 }
 
 func collectConfigurationValues(configurationType string, configurable ...v1.Configurable) []string {
-	result := strset.New()
+	result := sets.NewSet()
 
 	for _, c := range configurable {
 		c := c
@@ -209,8 +208,8 @@ func filterTransferableAnnotations(annotations map[string]string) map[string]str
 }
 
 // ExtractSourceDependencies extracts dependencies from source.
-func ExtractSourceDependencies(source v1.SourceSpec, catalog *camel.RuntimeCatalog) (*strset.Set, error) {
-	dependencies := strset.New()
+func ExtractSourceDependencies(source v1.SourceSpec, catalog *camel.RuntimeCatalog) (*sets.Set, error) {
+	dependencies := sets.NewSet()
 
 	// Add auto-detected dependencies
 	meta, err := metadata.Extract(catalog, source)
diff --git a/pkg/util/sets/set.go b/pkg/util/sets/set.go
new file mode 100644
index 000000000..707ebddab
--- /dev/null
+++ b/pkg/util/sets/set.go
@@ -0,0 +1,93 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+// Set is a very basic implementation for a Set data structure.
+type Set struct {
+	keys map[string]bool
+}
+
+// NewSet creates an empty Set.
+func NewSet() *Set {
+	return &Set{
+		keys: make(map[string]bool),
+	}
+}
+
+// Union creates a Set from the union of two.
+func Union(s1, s2 *Set) *Set {
+	items1 := s1.List()
+	items2 := s2.List()
+
+	unionSet := NewSet()
+	unionSet.Add(items1...)
+	unionSet.Add(items2...)
+
+	return unionSet
+}
+
+// List returns the list of items of the Set.
+func (s *Set) List() []string {
+	keys := make([]string, len(s.keys))
+
+	i := 0
+	for k := range s.keys {
+		keys[i] = k
+		i++
+	}
+
+	return keys
+}
+
+// Add items to the Set.
+func (s *Set) Add(items ...string) {
+	for _, i := range items {
+		s.keys[i] = true
+	}
+}
+
+// Merge with items from another set.
+func (s *Set) Merge(another *Set) {
+	s.Add(another.List()...)
+}
+
+// Each traverses the items in the Set, calling the provided function for each
+// Set member. Traversal will continue until all items in the Set have been
+// visited, or if the closure returns false.
+func (s *Set) Each(f func(item string) bool) {
+	for item := range s.keys {
+		if !f(item) {
+			break
+		}
+	}
+}
+
+// Has returns true if it contains the item.
+func (s *Set) Has(item string) bool {
+	return s.keys[item]
+}
+
+// IsEmpty returns true if the set has no items.
+func (s *Set) IsEmpty() bool {
+	return s.keys == nil || len(s.keys) == 0
+}
+
+// Size returns the number if items in the Set.
+func (s *Set) Size() int {
+	return len(s.keys)
+}
diff --git a/pkg/util/source/types.go b/pkg/util/source/types.go
index 3c8304d63..c37460d12 100644
--- a/pkg/util/source/types.go
+++ b/pkg/util/source/types.go
@@ -18,7 +18,7 @@ limitations under the License.
 package source
 
 import (
-	"github.com/scylladb/go-set/strset"
+	"github.com/apache/camel-k/v2/pkg/util/sets"
 )
 
 // Metadata represents metadata for Integration source.
@@ -28,7 +28,7 @@ type Metadata struct {
 	// All end URIs of defined routes
 	ToURIs []string
 	// All inferred dependencies required to run the integration
-	Dependencies *strset.Set
+	Dependencies *sets.Set
 	// ExposesHTTPServices indicates if a route defined by the source is exposed
 	// through HTTP
 	ExposesHTTPServices bool
@@ -36,9 +36,8 @@ type Metadata struct {
 	// are activated from external calls, including HTTP (useful to determine if the
 	// integration can scale to 0)
 	PassiveEndpoints bool
-	// RequiredCapabilities lists the capabilities required by the integration
-	// to run
-	RequiredCapabilities *strset.Set
+	// RequiredCapabilities lists the capabilities required by the integration to run
+	RequiredCapabilities *sets.Set
 	// All kamelets
 	Kamelets []string
 }
@@ -48,15 +47,17 @@ func NewMetadata() Metadata {
 	return Metadata{
 		FromURIs:             make([]string, 0),
 		ToURIs:               make([]string, 0),
-		Dependencies:         strset.New(),
-		RequiredCapabilities: strset.New(),
+		Dependencies:         sets.NewSet(),
+		RequiredCapabilities: sets.NewSet(),
 	}
 }
 
+// AddRequiredCapability -- .
 func (m *Metadata) AddRequiredCapability(capability string) {
 	m.RequiredCapabilities.Add(capability)
 }
 
+// AddDependency -- .
 func (m *Metadata) AddDependency(dependency string) {
 	m.Dependencies.Add(dependency)
 }
diff --git a/pkg/util/util.go b/pkg/util/util.go
index e0bede95f..2d91ee22d 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -35,11 +35,10 @@ import (
 	"strings"
 	"time"
 
+	"github.com/apache/camel-k/v2/pkg/util/sets"
 	"go.uber.org/multierr"
 
 	yaml2 "gopkg.in/yaml.v2"
-
-	"github.com/scylladb/go-set/strset"
 )
 
 // Directories and file names:
@@ -334,7 +333,7 @@ func WriteFileWithBytesMarshallerContent(basePath string, filePath string, conte
 }
 
 func FindAllDistinctStringSubmatch(data string, regexps ...*regexp.Regexp) []string {
-	submatchs := strset.New()
+	submatchs := sets.NewSet()
 
 	for _, reg := range regexps {
 		hits := reg.FindAllStringSubmatch(data, -1)


Test patch:
diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go
index 9467c509d..36dcf349a 100644
--- a/pkg/trait/jvm_test.go
+++ b/pkg/trait/jvm_test.go
@@ -24,7 +24,6 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/scylladb/go-set/strset"
 	"github.com/stretchr/testify/assert"
 
 	appsv1 "k8s.io/api/apps/v1"
@@ -38,6 +37,7 @@ import (
 	"github.com/apache/camel-k/v2/pkg/builder"
 	"github.com/apache/camel-k/v2/pkg/util/camel"
 	"github.com/apache/camel-k/v2/pkg/util/kubernetes"
+	"github.com/apache/camel-k/v2/pkg/util/sets"
 	"github.com/apache/camel-k/v2/pkg/util/test"
 )
 
@@ -109,7 +109,9 @@ func TestApplyJvmTraitWithDeploymentResource(t *testing.T) {
 
 	assert.Nil(t, err)
 
-	cp := strset.New("./resources", crMountPath, rdMountPath, "/mount/path").List()
+	s := sets.NewSet()
+	s.Add("./resources", crMountPath, rdMountPath, "/mount/path")
+	cp := s.List()
 	sort.Strings(cp)
 
 	assert.Equal(t, []string{
@@ -141,7 +143,9 @@ func TestApplyJvmTraitWithKNativeResource(t *testing.T) {
 
 	assert.Nil(t, err)
 
-	cp := strset.New("./resources", crMountPath, rdMountPath, "/mount/path").List()
+	st := sets.NewSet()
+	st.Add("./resources", crMountPath, rdMountPath, "/mount/path")
+	cp := st.List()
 	sort.Strings(cp)
 
 	assert.Equal(t, []string{
diff --git a/pkg/util/sets/set_test.go b/pkg/util/sets/set_test.go
new file mode 100644
index 000000000..ea0996da8
--- /dev/null
+++ b/pkg/util/sets/set_test.go
@@ -0,0 +1,60 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestSet(t *testing.T) {
+	s := NewSet()
+	assert.True(t, s.IsEmpty())
+	s.Add("hello")
+	assert.False(t, s.IsEmpty())
+	assert.Equal(t, 1, s.Size())
+	s.Add("hello another")
+	assert.Equal(t, 2, s.Size())
+	s.Add("hello")
+	assert.Equal(t, 2, s.Size())
+
+	s2 := NewSet()
+	s2.Add("hello")
+	s2.Add("ciao")
+	assert.Equal(t, 2, s2.Size())
+
+	s3 := Union(s, s2)
+	assert.Equal(t, 3, s3.Size())
+	assert.Contains(t, s3.List(), "hello", "ciao", "hello another")
+	assert.True(t, s3.Has("ciao"))
+	assert.False(t, s3.Has("bye"))
+
+	s.Merge(s2)
+	assert.Equal(t, 3, s.Size())
+	assert.Contains(t, s.List(), "hello", "ciao", "hello another")
+
+	processedList := make([]string, 0)
+
+	s.Each(func(item string) bool {
+		processedList = append(processedList, "processed:"+item)
+		return true
+	})
+
+	assert.Contains(t, processedList, "processed:hello", "processed:ciao", "processed:hello another")
+}