This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 422bba510d133e4f18f1a9d5f923170ec708c95f
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Thu Aug 29 14:39:21 2024 +0200

    feat(cli): promote kitless
---
 .../modules/ROOT/pages/running/camel-runtimes.adoc |   8 +-
 docs/modules/ROOT/pages/running/promoting.adoc     |  10 +-
 e2e/advanced/tekton_test.go                        |   5 -
 e2e/install/upgrade/upgrade_test.go                |  10 +-
 e2e/native/native_test.go                          |   3 -
 e2e/support/test_support.go                        |  22 +-
 pkg/apis/camel/v1/integration_types_support.go     |   7 +-
 .../camel/v1/integration_types_support_test.go     |  24 +++
 pkg/apis/camel/v1/integrationkit_types_support.go  |   7 +-
 .../camel/v1/integrationkit_types_support_test.go  |  13 +-
 pkg/cmd/promote.go                                 | 159 ++++++---------
 pkg/cmd/promote_test.go                            | 221 +++------------------
 pkg/cmd/run.go                                     |   8 -
 pkg/controller/integration/build_kit.go            |  30 +--
 pkg/controller/integration/monitor.go              |   1 +
 pkg/controller/integrationkit/error.go             |   1 +
 .../integrationkit/integrationkit_controller.go    |   1 +
 pkg/controller/integrationkit/monitor.go           |   1 +
 pkg/trait/builder_test.go                          |   7 +-
 pkg/trait/camel.go                                 |   2 +
 pkg/trait/container_probes_test.go                 |   1 +
 pkg/trait/container_test.go                        |  27 +--
 pkg/trait/istio_test.go                            |   7 +-
 pkg/trait/jvm.go                                   | 102 ++++++----
 pkg/trait/jvm_test.go                              |   2 +-
 pkg/trait/quarkus.go                               |  49 ++---
 pkg/trait/quarkus_test.go                          |  20 ++
 pkg/trait/service_test.go                          |  21 +-
 28 files changed, 313 insertions(+), 456 deletions(-)

diff --git a/docs/modules/ROOT/pages/running/camel-runtimes.adoc 
b/docs/modules/ROOT/pages/running/camel-runtimes.adoc
index 34da12edf..ebe583472 100644
--- a/docs/modules/ROOT/pages/running/camel-runtimes.adoc
+++ b/docs/modules/ROOT/pages/running/camel-runtimes.adoc
@@ -1,6 +1,8 @@
 = Camel Runtimes (aka "sourceless" Integrations)
 
-Camel K can run any runtime available in Apache Camel. However, this is 
possible only when the Camel application was previously built and packaged into 
a container image. Also, if you run through this option, some of the features 
offered by the operator may not be available. For example, you won't be able to 
discover Camel capabilities because the source is not available to the operator 
but embedded in the container image.
+Camel K operator is traditionally in charge to perform a build from a Camel 
DSL source. The resulting Integration depends directly on an IntegrationKit, 
which is a reusable custom resource backing the final container image that your 
application will run. In the last versions, the only runtime the operator can 
build is Camel Quarkus (via Camel K Runtime project).
+
+However Camel K can run any runtime available in Apache Camel. This is 
possible only when the Camel application was previously built and packaged into 
a container image externally. Mind that if you run through this option, some of 
the features offered by the operator may not be available. For example, you 
won't be able to discover Camel capabilities because the source is not 
available to the operator but embedded in the container image.
 
 This option is quite interesting if in general you're building your 
applications externally, ie, via a CICD technology, and you want to delegate 
the operator only the "operational" part, taking care on your own of the 
building and publishing part.
 
@@ -15,7 +17,7 @@ You can have your own Camel application or just create a 
basic one for the purpo
 
 The step above is a very quick way to create a basic Camel application in any 
of the available runtime. Let's imagine we've done this for Camel Main or we 
have already a Camel application as a Maven project. As the build part is 
something we want to take care on our own, we create a pipeline to build, 
containerize and push the container to a registry (see as a reference 
https://github.com/tektoncd/catalog/blob/main/task/kamel-run/0.1/samples/run-external-build.yaml[Camel
 K Tekton example]).
 
-At this stage we do have a container image with our Camel application. We can 
use the `kamel` CLI to run our Camel application via `kamel run --image 
docker.io/my-org/my-app:1.0.0` tuning, if it's the case, with any of the trait 
or configuration required. Mind that, when you run an Integration with this 
option, the operator will create a **synthetic** IntegrationKit.
+At this stage we do have a container image with our Camel application. We can 
use the `kamel` CLI to run our Camel application via `kamel run --image 
docker.io/my-org/my-app:1.0.0` tuning, if it's the case, with any of the trait 
or configuration required. As there is no creation of an IntegrationKit, this 
is also known as 'kit-less' Integration.
 
 If all is good, in a few seconds (there is no build involved) you should have 
your application up and running and you can monitor and operate with Camel K as 
usual.
 
@@ -27,4 +29,4 @@ Every Camel application requires a `CamelCatalog` object to 
know how to perform
 [[traits]]
 == Trait configuration
 
-Certain Camel K operational aspect may be driven by traits. When you're 
building the application outside the operator, some of those traits may not be 
executed as they are executed during the building phase that we are skipping 
when running **sourceless Integrations**. There is also no possible way to 
auto-tune certain traits that require the presence of the source. In this case, 
you should instead provide a trait configuration with the values that are 
required by your Integration (for e [...]
\ No newline at end of file
+Certain Camel K operational aspect may be driven by traits. When you're 
building the application outside the operator, some of those traits may not be 
executed as they are executed during the building phase that we are skipping 
when running **sourceless Integrations**. There is also no possible way to 
auto-tune certain traits that require the presence of the source. In this case, 
you should instead provide a trait configuration with the values that are 
required by your Integration (for e [...]
diff --git a/docs/modules/ROOT/pages/running/promoting.adoc 
b/docs/modules/ROOT/pages/running/promoting.adoc
index f7f5f4c35..308c87ae3 100644
--- a/docs/modules/ROOT/pages/running/promoting.adoc
+++ b/docs/modules/ROOT/pages/running/promoting.adoc
@@ -3,19 +3,11 @@
 
 As soon as you have an Integration running in your cluster, you will be 
challenged to move that Integration to an higher environment. Ie, you can test 
your Integration in a **development** environment, and, as soon as you're happy 
with the result, you will need to move it into a **production** environment.
 
-== External IntegrationKits
-
-When you create an Integration, the operator takes care to use an existing 
IntegrationKit or creating one from scratch. When you're moving your 
Integration across environments you'll therefore need to create an 
IntegrationKit accordingly. The creation of the IntegrationKit, in this case, 
is a simple copy of the original IntegrationKit with the `.spec.image` coming 
from the `.status.image` of the original IntegrationKit. Additionally, it has 
to be labelled as `camel.apache.org/kit.type: e [...]
-
-NOTE: these two configuration are required to avoid the new IntegrationKit to 
kick off a new build operation.
-
-The copy is something you can do with any external tooling or using the `kamel 
promote` command as provided below:
-
 == CLI `promote` command
 
 Camel K has an opinionated way to achieve the promotion goal through the usage 
of `kamel promote` command. With this command you will be able to easily move 
an Integration from one namespace to another without worrying about any low 
level detail such as resources needed by the Integration. You only need to make 
sure that both the source operator and the destination operator are using the 
same container registry and that the destination namespace provides the 
required Configmaps, Secrets  [...]
 
-NOTE: in order to use the same container registry, you can use the 
`--registry` option during installation phase or change the IntegrationPlatform 
to reflect that accordingly.
+NOTE: use dry run option (`-o yaml`) and export the result to any separated 
cluster or Git repository to perform a GitOps strategy.
 
 Let's see a simple Integration that uses a Configmap to expose some message on 
an HTTP endpoint. We can start creating such an Integration and testing in a 
namespace called `development`:
 
diff --git a/e2e/advanced/tekton_test.go b/e2e/advanced/tekton_test.go
index 56e4e2fcc..86f8e0557 100644
--- a/e2e/advanced/tekton_test.go
+++ b/e2e/advanced/tekton_test.go
@@ -73,11 +73,6 @@ func TestTektonLikeBehavior(t *testing.T) {
                        g.Eventually(IntegrationPodPhase(t, ctx, ns, name), 
TestTimeoutLong).Should(Equal(corev1.PodRunning))
                        g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
name, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
                        g.Eventually(IntegrationLogs(t, ctx, ns, name), 
TestTimeoutShort).Should(ContainSubstring("Echo"))
-                       tektonIntegrationKitName := IntegrationKit(t, ctx, ns, 
name)()
-                       g.Expect(tektonIntegrationKitName).ToNot(BeEmpty())
-                       tektonIntegrationKitImage := KitImage(t, ctx, ns, 
tektonIntegrationKitName)()
-                       g.Expect(tektonIntegrationKitImage).ToNot(BeEmpty())
-                       g.Eventually(Kit(t, ctx, ns, 
tektonIntegrationKitName)().Status.Image, 
TestTimeoutShort).Should(Equal(externalImage))
                })
        })
 }
diff --git a/e2e/install/upgrade/upgrade_test.go 
b/e2e/install/upgrade/upgrade_test.go
index 50903ccc0..fe4ff1cab 100644
--- a/e2e/install/upgrade/upgrade_test.go
+++ b/e2e/install/upgrade/upgrade_test.go
@@ -87,6 +87,7 @@ func TestUpgrade(t *testing.T) {
                // Check the IntegrationPlatform has been reconciled
                g.Eventually(PlatformPhase(t, ctx, 
ns)).Should(Equal(v1.IntegrationPlatformPhaseReady))
                g.Eventually(PlatformVersion(t, ctx, 
ns)).Should(Equal(lastVersion))
+               lastRuntimeVersion := PlatformRuntimeVersion(t, ctx, ns)()
 
                // We need a different namespace from the global operator
                WithNewTestNamespace(t, func(ctx context.Context, g *WithT, 
nsIntegration string) {
@@ -117,6 +118,7 @@ func TestUpgrade(t *testing.T) {
                        // Check the IntegrationPlatform has been reconciled
                        g.Eventually(PlatformPhase(t, ctx, ns), 
TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady))
                        g.Eventually(PlatformVersion(t, ctx, ns), 
TestTimeoutMedium).Should(Equal(defaults.Version))
+                       g.Eventually(PlatformRuntimeVersion(t, ctx, ns), 
TestTimeoutMedium).Should(Equal(defaults.DefaultRuntimeVersion))
 
                        // Check the Integration hasn't been upgraded
                        g.Consistently(IntegrationVersion(t, ctx, 
nsIntegration, name), 15*time.Second, 3*time.Second).
@@ -135,14 +137,14 @@ func TestUpgrade(t *testing.T) {
                        g.Eventually(IntegrationVersion(t, ctx, nsIntegration, 
name), TestTimeoutMedium).Should(Equal(defaults.Version))
 
                        // Check the previous kit is not garbage collected
-                       g.Eventually(Kits(t, ctx, ns, 
KitWithVersion(lastVersion))).Should(HaveLen(1))
+                       g.Eventually(Kits(t, ctx, ns, 
KitWithRuntimeVersion(lastRuntimeVersion))).Should(HaveLen(1))
                        // Check a new kit is created with the current version
-                       g.Eventually(Kits(t, ctx, ns, 
KitWithVersion(defaults.Version))).Should(HaveLen(1))
+                       g.Eventually(Kits(t, ctx, ns, 
KitWithRuntimeVersion(defaults.DefaultRuntimeVersion))).Should(HaveLen(1))
                        // Check the new kit is ready
-                       g.Eventually(Kits(t, ctx, ns, 
KitWithVersion(defaults.Version), KitWithPhase(v1.IntegrationKitPhaseReady)),
+                       g.Eventually(Kits(t, ctx, ns, 
KitWithRuntimeVersion(defaults.DefaultRuntimeVersion), 
KitWithPhase(v1.IntegrationKitPhaseReady)),
                                TestTimeoutMedium).Should(HaveLen(1))
 
-                       kit := Kits(t, ctx, ns, 
KitWithVersion(defaults.Version))()[0]
+                       kit := Kits(t, ctx, ns, 
KitWithRuntimeVersion(defaults.DefaultRuntimeVersion))()[0]
 
                        // Check the Integration uses the new image
                        g.Eventually(IntegrationKit(t, ctx, nsIntegration, 
name), TestTimeoutMedium).Should(Equal(kit.Name))
diff --git a/e2e/native/native_test.go b/e2e/native/native_test.go
index 893f96daa..29d93579f 100644
--- a/e2e/native/native_test.go
+++ b/e2e/native/native_test.go
@@ -27,7 +27,6 @@ import (
        "testing"
 
        . "github.com/onsi/gomega"
-
        corev1 "k8s.io/api/core/v1"
 
        . "github.com/apache/camel-k/v2/e2e/support"
@@ -41,8 +40,6 @@ func TestNativeIntegrations(t *testing.T) {
                        g.Expect(KamelRun(t, ctx, ns, "files/JavaScript.js", 
"--name", name, "-t", "quarkus.build-mode=native", "-t", 
"builder.tasks-limit-memory=quarkus-native:6.5Gi").Execute()).To(Succeed())
 
                        g.Eventually(IntegrationPhase(t, ctx, ns, 
name)).Should(Equal(v1.IntegrationPhaseError))
-                       g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
name, v1.IntegrationConditionKitAvailable)).
-                               Should(Equal(corev1.ConditionFalse))
                })
 
                t.Run("xml native support", func(t *testing.T) {
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index 48cab1b69..485379fcf 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -1291,18 +1291,10 @@ func KitWithPhase(phase v1.IntegrationKitPhase) 
KitFilter {
        }
 }
 
-func KitWithVersion(version string) KitFilter {
+func KitWithRuntimeVersion(version string) KitFilter {
        return &kitFilter{
                filter: func(kit *v1.IntegrationKit) bool {
-                       return kit.Status.Version == version
-               },
-       }
-}
-
-func KitWithVersionPrefix(versionPrefix string) KitFilter {
-       return &kitFilter{
-               filter: func(kit *v1.IntegrationKit) bool {
-                       return strings.HasPrefix(kit.Status.Version, 
versionPrefix)
+                       return kit.Status.RuntimeVersion == version
                },
        }
 }
@@ -2124,6 +2116,16 @@ func PlatformVersion(t *testing.T, ctx context.Context, 
ns string) func() string
        }
 }
 
+func PlatformRuntimeVersion(t *testing.T, ctx context.Context, ns string) 
func() string {
+       return func() string {
+               p := Platform(t, ctx, ns)()
+               if p == nil {
+                       return ""
+               }
+               return p.Status.Build.RuntimeVersion
+       }
+}
+
 func PlatformPhase(t *testing.T, ctx context.Context, ns string) func() 
v1.IntegrationPlatformPhase {
        return func() v1.IntegrationPlatformPhase {
                p := Platform(t, ctx, ns)()
diff --git a/pkg/apis/camel/v1/integration_types_support.go 
b/pkg/apis/camel/v1/integration_types_support.go
index dec40102f..9683fef31 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -19,6 +19,7 @@ package v1
 
 import (
        "fmt"
+       "regexp"
        "strings"
 
        corev1 "k8s.io/api/core/v1"
@@ -90,7 +91,11 @@ func (in *Integration) UserDefinedSources() []SourceSpec {
 
 // IsManagedBuild returns true when the Integration requires to be built by 
the operator.
 func (in *Integration) IsManagedBuild() bool {
-       return in.Spec.Traits.Container == nil || 
in.Spec.Traits.Container.Image == ""
+       if in.Spec.Traits.Container == nil || in.Spec.Traits.Container.Image == 
"" {
+               return true
+       }
+       isManagedBuild, err := 
regexp.MatchString("(.*)/(.*)/camel-k-kit-(.*)@sha256:(.*)", 
in.Spec.Traits.Container.Image)
+       return err == nil && isManagedBuild
 }
 
 func (in *IntegrationSpec) AddSource(name string, content string, language 
Language) {
diff --git a/pkg/apis/camel/v1/integration_types_support_test.go 
b/pkg/apis/camel/v1/integration_types_support_test.go
index d2bbb8781..fda60c1b2 100644
--- a/pkg/apis/camel/v1/integration_types_support_test.go
+++ b/pkg/apis/camel/v1/integration_types_support_test.go
@@ -21,6 +21,7 @@ import (
        "fmt"
        "testing"
 
+       "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
        "github.com/stretchr/testify/assert"
 )
 
@@ -101,3 +102,26 @@ func TestGetConfigurationProperty(t *testing.T) {
        v6 := integration.GetConfigurationProperty("key6")
        assert.Equal(t, "", v6)
 }
+
+func TestManagedBuild(t *testing.T) {
+       integration := Integration{
+               Spec: IntegrationSpec{},
+       }
+       assert.True(t, integration.IsManagedBuild())
+       integration.Spec.Traits = Traits{
+               Container: &trait.ContainerTrait{},
+       }
+       assert.True(t, integration.IsManagedBuild())
+       integration.Spec.Traits = Traits{
+               Container: &trait.ContainerTrait{
+                       Image: "registry.io/my-org/my-image",
+               },
+       }
+       assert.False(t, integration.IsManagedBuild())
+       integration.Spec.Traits = Traits{
+               Container: &trait.ContainerTrait{
+                       Image: 
"10.100.107.57/camel-k/camel-k-kit-cr82ehho23os73cgua70@sha256:13e5a67d37665710c0bdd89701c7ae10aee393b00f5e4e09dc8ecc234763e7c2",
+               },
+       }
+       assert.True(t, integration.IsManagedBuild())
+}
diff --git a/pkg/apis/camel/v1/integrationkit_types_support.go 
b/pkg/apis/camel/v1/integrationkit_types_support.go
index ed8595c3d..ec8e92d5a 100644
--- a/pkg/apis/camel/v1/integrationkit_types_support.go
+++ b/pkg/apis/camel/v1/integrationkit_types_support.go
@@ -20,7 +20,6 @@ package v1
 import (
        "fmt"
        "path/filepath"
-       "sort"
        "strconv"
 
        "github.com/apache/camel-k/v2/pkg/util/sets"
@@ -211,16 +210,14 @@ func (in *IntegrationKitStatus) GetConditions() 
[]ResourceCondition {
 }
 
 // GetDependenciesPaths returns the set of dependency paths.
-func (in *IntegrationKitStatus) GetDependenciesPaths() []string {
+func (in *IntegrationKitStatus) GetDependenciesPaths() *sets.Set {
        s := sets.NewSet()
        for _, dep := range in.Artifacts {
                path := filepath.Dir(dep.Target)
                s.Add(fmt.Sprintf("%s/*", path))
        }
-       values := s.List()
-       sort.Strings(values)
 
-       return values
+       return s
 }
 
 func (c IntegrationKitCondition) GetType() string {
diff --git a/pkg/apis/camel/v1/integrationkit_types_support_test.go 
b/pkg/apis/camel/v1/integrationkit_types_support_test.go
index 78a741f81..c75498ecf 100644
--- a/pkg/apis/camel/v1/integrationkit_types_support_test.go
+++ b/pkg/apis/camel/v1/integrationkit_types_support_test.go
@@ -18,6 +18,7 @@ limitations under the License.
 package v1
 
 import (
+       "sort"
        "testing"
 
        "github.com/stretchr/testify/assert"
@@ -39,9 +40,11 @@ func TestGetKitDependenciesDirectories(t *testing.T) {
                },
        }
        paths := kit.Status.GetDependenciesPaths()
-       assert.Len(t, paths, 4)
-       assert.Equal(t, "my-dir/*", paths[0])
-       assert.Equal(t, "my-dir1/lib/*", paths[1])
-       assert.Equal(t, "my-dir1/lib2/*", paths[2])
-       assert.Equal(t, "my-dir2/lib/*", paths[3])
+       pathsArray := paths.List()
+       sort.Strings(pathsArray)
+       assert.Len(t, pathsArray, 4)
+       assert.Equal(t, "my-dir/*", pathsArray[0])
+       assert.Equal(t, "my-dir1/lib/*", pathsArray[1])
+       assert.Equal(t, "my-dir1/lib2/*", pathsArray[2])
+       assert.Equal(t, "my-dir2/lib/*", pathsArray[3])
 }
diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go
index 0a368b28d..339afac7a 100644
--- a/pkg/cmd/promote.go
+++ b/pkg/cmd/promote.go
@@ -21,12 +21,14 @@ import (
        "context"
        "errors"
        "fmt"
+       "sort"
        "strings"
 
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
        traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
        "github.com/apache/camel-k/v2/pkg/client"
        "github.com/apache/camel-k/v2/pkg/util/kubernetes"
+       "github.com/apache/camel-k/v2/pkg/util/sets"
        "github.com/spf13/cobra"
        corev1 "k8s.io/api/core/v1"
        rbacv1 "k8s.io/api/rbac/v1"
@@ -133,12 +135,8 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args 
[]string) error {
 
        // Pipe promotion
        if promotePipe {
-               destPipe, destKit := o.editPipe(sourcePipe, sourceIntegration, 
sourceKit)
+               destPipe := o.editPipe(sourcePipe, sourceIntegration, sourceKit)
                if o.OutputFormat != "" {
-                       if err := showIntegrationKitOutput(cmd, destKit, 
o.OutputFormat); err != nil {
-                               return err
-                       }
-                       fmt.Fprintln(cmd.OutOrStdout(), `---`)
                        return showPipeOutput(cmd, destPipe, o.OutputFormat, 
c.GetScheme())
                }
                // Ensure the destination namespace has access to the source 
namespace images
@@ -146,10 +144,6 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args 
[]string) error {
                if err != nil {
                        return err
                }
-               _, err = o.replaceResource(destKit)
-               if err != nil {
-                       return err
-               }
                replaced, err := o.replaceResource(destPipe)
                if err != nil {
                        return err
@@ -163,12 +157,8 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args 
[]string) error {
        }
 
        // Plain Integration promotion
-       destIntegration, destKit := o.editIntegration(sourceIntegration, 
sourceKit)
+       destIntegration := o.editIntegration(sourceIntegration, sourceKit)
        if o.OutputFormat != "" {
-               if err := showIntegrationKitOutput(cmd, destKit, 
o.OutputFormat); err != nil {
-                       return err
-               }
-               fmt.Fprintln(cmd.OutOrStdout(), `---`)
                return showIntegrationOutput(cmd, destIntegration, 
o.OutputFormat)
        }
        // Ensure the destination namespace has access to the source namespace 
images
@@ -176,10 +166,6 @@ func (o *promoteCmdOptions) run(cmd *cobra.Command, args 
[]string) error {
        if err != nil {
                return err
        }
-       _, err = o.replaceResource(destKit)
-       if err != nil {
-               return err
-       }
        replaced, err := o.replaceResource(destIntegration)
        if err != nil {
                return err
@@ -233,6 +219,9 @@ func (o *promoteCmdOptions) getIntegration(c client.Client, 
name string) (*v1.In
 }
 
 func (o *promoteCmdOptions) getIntegrationKit(c client.Client, ref 
*corev1.ObjectReference) (*v1.IntegrationKit, error) {
+       if ref == nil {
+               return nil, nil
+       }
        ik := v1.NewIntegrationKit(ref.Namespace, ref.Name)
        key := k8sclient.ObjectKey{
                Name:      ref.Name,
@@ -245,41 +234,63 @@ func (o *promoteCmdOptions) getIntegrationKit(c 
client.Client, ref *corev1.Objec
        return ik, nil
 }
 
-func (o *promoteCmdOptions) editIntegration(it *v1.Integration, kit 
*v1.IntegrationKit) (*v1.Integration, *v1.IntegrationKit) {
+func (o *promoteCmdOptions) editIntegration(it *v1.Integration, kit 
*v1.IntegrationKit) *v1.Integration {
        contImage := it.Status.Image
-       // IntegrationKit
-       dstKit := v1.NewIntegrationKit(o.To, kit.Name)
-       dstKit.Spec = *kit.Spec.DeepCopy()
-       dstKit.Annotations = cloneAnnotations(kit.Annotations, o.ToOperator)
-       dstKit.Labels = cloneLabels(kit.Labels)
-       dstKit.Labels = alterKitLabels(dstKit.Labels, kit)
-       dstKit.Spec.Image = contImage
        // Integration
        dstIt := v1.NewIntegration(o.To, it.Name)
        dstIt.Spec = *it.Spec.DeepCopy()
        dstIt.Annotations = cloneAnnotations(it.Annotations, o.ToOperator)
        dstIt.Labels = cloneLabels(it.Labels)
-       dstIt.Spec.IntegrationKit = &corev1.ObjectReference{
-               Namespace: dstKit.Namespace,
-               Name:      dstKit.Name,
-               Kind:      dstKit.Kind,
-       }
-       // We must provide the classpath expected for the IntegrationKit. This 
is calculated dynamically and
-       // would get lost when creating the promoted IntegrationKit (which is 
in .status.artifacts). For this reason
-       // we must report it in the promoted Integration.
-       kitClasspath := kit.Status.GetDependenciesPaths()
-       if len(kitClasspath) > 0 {
+       dstIt.Spec.IntegrationKit = nil
+       if dstIt.Spec.Traits.Container == nil {
+               dstIt.Spec.Traits.Container = &traitv1.ContainerTrait{}
+       }
+       dstIt.Spec.Traits.Container.Image = contImage
+       if kit != nil {
+               // We must provide the classpath expected for the 
IntegrationKit. This is calculated dynamically and
+               // would get lost when creating the non managed build 
Integration. For this reason
+               // we must report it in the promoted Integration.
                if dstIt.Spec.Traits.JVM == nil {
                        dstIt.Spec.Traits.JVM = &traitv1.JVMTrait{}
                }
                jvmTrait := dstIt.Spec.Traits.JVM
-               if jvmTrait.Classpath != "" {
-                       jvmTrait.Classpath += ":"
+               mergedClasspath := getClasspath(kit, jvmTrait.Classpath)
+               jvmTrait.Classpath = mergedClasspath
+               // We must also set the runtime version so we pin it to the 
given catalog on which
+               // the container image was built
+               if dstIt.Spec.Traits.Camel == nil {
+                       dstIt.Spec.Traits.Camel = &traitv1.CamelTrait{}
+               }
+               dstIt.Spec.Traits.Camel.RuntimeVersion = 
kit.Status.RuntimeVersion
+       }
+
+       return &dstIt
+}
+
+// getClasspath merges the classpath required by the kit with any value 
provided in the trait.
+func getClasspath(kit *v1.IntegrationKit, jvmTraitClasspath string) string {
+       kitClasspathSet := kit.Status.GetDependenciesPaths()
+       if !kitClasspathSet.IsEmpty() {
+               if jvmTraitClasspath != "" {
+                       jvmTraitClasspathSet := 
getClasspathSet(jvmTraitClasspath)
+                       kitClasspathSet = sets.Union(kitClasspathSet, 
jvmTraitClasspathSet)
                }
-               jvmTrait.Classpath += strings.Join(kitClasspath, ":")
+               classPaths := kitClasspathSet.List()
+               sort.Strings(classPaths)
+
+               return strings.Join(classPaths, ":")
        }
 
-       return &dstIt, dstKit
+       return jvmTraitClasspath
+}
+
+func getClasspathSet(cps string) *sets.Set {
+       s := sets.NewSet()
+       for _, cp := range strings.Split(cps, ":") {
+               s.Add(cp)
+       }
+
+       return s
 }
 
 // Return all annotations overriding the operator Id if provided.
@@ -311,54 +322,14 @@ func cloneLabels(lbs map[string]string) map[string]string 
{
        return newMap
 }
 
-// Change labels expected by Integration Kit replacing the creator to reflect 
the
-// fact the new kit was cloned by another one instead.
-func alterKitLabels(lbs map[string]string, kit *v1.IntegrationKit) 
map[string]string {
-       lbs[v1.IntegrationKitTypeLabel] = v1.IntegrationKitTypeExternal
-       if lbs[kubernetes.CamelCreatorLabelKind] != "" {
-               delete(lbs, kubernetes.CamelCreatorLabelKind)
-       }
-       if lbs[kubernetes.CamelCreatorLabelName] != "" {
-               delete(lbs, kubernetes.CamelCreatorLabelName)
-       }
-       if lbs[kubernetes.CamelCreatorLabelNamespace] != "" {
-               delete(lbs, kubernetes.CamelCreatorLabelNamespace)
-       }
-       if lbs[kubernetes.CamelCreatorLabelVersion] != "" {
-               delete(lbs, kubernetes.CamelCreatorLabelVersion)
-       }
-
-       lbs[kubernetes.CamelClonedLabelKind] = v1.IntegrationKitKind
-       lbs[kubernetes.CamelClonedLabelName] = kit.Name
-       lbs[kubernetes.CamelClonedLabelNamespace] = kit.Namespace
-       lbs[kubernetes.CamelClonedLabelVersion] = kit.ResourceVersion
-
-       return lbs
-}
-
-func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it *v1.Integration, kit 
*v1.IntegrationKit) (*v1.Pipe, *v1.IntegrationKit) {
+func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it *v1.Integration, kit 
*v1.IntegrationKit) *v1.Pipe {
        contImage := it.Status.Image
-       // IntegrationKit
-       dstKit := v1.NewIntegrationKit(o.To, kit.Name)
-       dstKit.Spec = *kit.Spec.DeepCopy()
-       dstKit.Annotations = cloneAnnotations(kit.Annotations, o.ToOperator)
-       dstKit.Labels = cloneLabels(kit.Labels)
-       dstKit.Labels = alterKitLabels(dstKit.Labels, kit)
-       dstKit.Spec.Image = contImage
        // Pipe
        dst := v1.NewPipe(o.To, kb.Name)
        dst.Spec = *kb.Spec.DeepCopy()
        dst.Annotations = cloneAnnotations(kb.Annotations, o.ToOperator)
        dst.Labels = cloneLabels(kb.Labels)
-       if dst.Spec.Integration == nil {
-               dst.Spec.Integration = &v1.IntegrationSpec{}
-       }
-       dst.Spec.Integration.IntegrationKit = &corev1.ObjectReference{
-               Namespace: dstKit.Namespace,
-               Name:      dstKit.Name,
-               Kind:      dstKit.Kind,
-       }
-
+       dst.Annotations[fmt.Sprintf("%scontainer.image", 
v1.TraitAnnotationPrefix)] = contImage
        if dst.Spec.Source.Ref != nil {
                dst.Spec.Source.Ref.Namespace = o.To
        }
@@ -373,22 +344,18 @@ func (o *promoteCmdOptions) editPipe(kb *v1.Pipe, it 
*v1.Integration, kit *v1.In
                }
        }
 
-       // We must provide the classpath expected for the IntegrationKit. This 
is calculated dynamically and
-       // would get lost when creating the promoted IntegrationKit (which is 
in .status.artifacts). For this reason
-       // we must report it in the promoted Integration.
-       kitClasspath := kit.Status.GetDependenciesPaths()
-       if len(kitClasspath) > 0 {
-               if dst.Spec.Integration.Traits.JVM == nil {
-                       dst.Spec.Integration.Traits.JVM = &traitv1.JVMTrait{}
-               }
-               jvmTrait := dst.Spec.Integration.Traits.JVM
-               if jvmTrait.Classpath != "" {
-                       jvmTrait.Classpath += ":"
-               }
-               jvmTrait.Classpath += strings.Join(kitClasspath, ":")
+       if kit != nil {
+               // We must provide the classpath expected for the 
IntegrationKit. This is calculated dynamically and
+               // would get lost when creating the non managed build 
Integration. For this reason
+               // we must report it in the promoted Integration.
+               mergedClasspath := getClasspath(kit, 
dst.Annotations[fmt.Sprintf("%sjvm.classpath", v1.TraitAnnotationPrefix)])
+               dst.Annotations[fmt.Sprintf("%sjvm.classpath", 
v1.TraitAnnotationPrefix)] = mergedClasspath
+               // We must also set the runtime version so we pin it to the 
given catalog on which
+               // the container image was built
+               dst.Annotations[fmt.Sprintf("%scamel.runtime-version", 
v1.TraitAnnotationPrefix)] = kit.Status.RuntimeVersion
        }
 
-       return &dst, dstKit
+       return &dst
 }
 
 func (o *promoteCmdOptions) replaceResource(res k8sclient.Object) (bool, 
error) {
diff --git a/pkg/cmd/promote_test.go b/pkg/cmd/promote_test.go
index 72b87d495..0d92f4089 100644
--- a/pkg/cmd/promote_test.go
+++ b/pkg/cmd/promote_test.go
@@ -24,7 +24,6 @@ import (
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
        "github.com/apache/camel-k/v2/pkg/platform"
        "github.com/apache/camel-k/v2/pkg/util/defaults"
-       "github.com/apache/camel-k/v2/pkg/util/kubernetes"
        "github.com/apache/camel-k/v2/pkg/util/test"
        "github.com/spf13/cobra"
        "github.com/stretchr/testify/assert"
@@ -95,34 +94,17 @@ func TestIntegrationDryRun(t *testing.T) {
        assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
        require.NoError(t, err)
        assert.Equal(t, `apiVersion: camel.apache.org/v1
-kind: IntegrationKit
-metadata:
-  creationTimestamp: null
-  labels:
-    camel.apache.org/cloned.from.kind: IntegrationKit
-    camel.apache.org/cloned.from.name: my-it-test-kit
-    camel.apache.org/cloned.from.namespace: default
-    camel.apache.org/cloned.from.version: "999"
-    camel.apache.org/kit.type: external
-  name: my-it-test-kit
-  namespace: prod-namespace
-spec:
-  image: my-special-image
-  traits: {}
-status: {}
----
-apiVersion: camel.apache.org/v1
 kind: Integration
 metadata:
   creationTimestamp: null
   name: my-it-test
   namespace: prod-namespace
 spec:
-  integrationKit:
-    kind: IntegrationKit
-    name: my-it-test-kit
-    namespace: prod-namespace
   traits:
+    camel:
+      runtimeVersion: 1.2.3
+    container:
+      image: my-special-image
     jvm:
       classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
 status: {}
@@ -139,6 +121,7 @@ func nominalIntegration(name string) (v1.Integration, 
v1.IntegrationKit) {
                        {Target: "/path/to/artifact-1/a-1.jar"},
                        {Target: "/path/to/artifact-2/a-2.jar"},
                },
+               RuntimeVersion: "1.2.3",
        }
        it.Status.IntegrationKit = &corev1.ObjectReference{
                Namespace: ik.Namespace,
@@ -167,37 +150,16 @@ func TestPipeDryRun(t *testing.T) {
        assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
        require.NoError(t, err)
        assert.Equal(t, `apiVersion: camel.apache.org/v1
-kind: IntegrationKit
-metadata:
-  creationTimestamp: null
-  labels:
-    camel.apache.org/cloned.from.kind: IntegrationKit
-    camel.apache.org/cloned.from.name: my-kb-test-kit
-    camel.apache.org/cloned.from.namespace: default
-    camel.apache.org/cloned.from.version: "999"
-    camel.apache.org/kit.type: external
-  name: my-kb-test-kit
-  namespace: prod-namespace
-spec:
-  image: my-special-image
-  traits: {}
-status: {}
----
-apiVersion: camel.apache.org/v1
 kind: Pipe
 metadata:
+  annotations:
+    trait.camel.apache.org/camel.runtime-version: 1.2.3
+    trait.camel.apache.org/container.image: my-special-image
+    trait.camel.apache.org/jvm.classpath: 
/path/to/artifact-1/*:/path/to/artifact-2/*
   creationTimestamp: null
   name: my-kb-test
   namespace: prod-namespace
 spec:
-  integration:
-    integrationKit:
-      kind: IntegrationKit
-      name: my-kb-test-kit
-      namespace: prod-namespace
-    traits:
-      jvm:
-        classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
   sink: {}
   source: {}
 status: {}
@@ -241,23 +203,6 @@ func TestIntegrationWithMetadataDryRun(t *testing.T) {
        assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
        require.NoError(t, err)
        assert.Equal(t, `apiVersion: camel.apache.org/v1
-kind: IntegrationKit
-metadata:
-  creationTimestamp: null
-  labels:
-    camel.apache.org/cloned.from.kind: IntegrationKit
-    camel.apache.org/cloned.from.name: my-it-test-kit
-    camel.apache.org/cloned.from.namespace: default
-    camel.apache.org/cloned.from.version: "999"
-    camel.apache.org/kit.type: external
-  name: my-it-test-kit
-  namespace: prod-namespace
-spec:
-  image: my-special-image
-  traits: {}
-status: {}
----
-apiVersion: camel.apache.org/v1
 kind: Integration
 metadata:
   annotations:
@@ -268,11 +213,11 @@ metadata:
   name: my-it-test
   namespace: prod-namespace
 spec:
-  integrationKit:
-    kind: IntegrationKit
-    name: my-it-test-kit
-    namespace: prod-namespace
   traits:
+    camel:
+      runtimeVersion: 1.2.3
+    container:
+      image: my-special-image
     jvm:
       classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
 status: {}
@@ -305,41 +250,19 @@ func TestPipeWithMetadataDryRun(t *testing.T) {
        assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
        require.NoError(t, err)
        assert.Equal(t, `apiVersion: camel.apache.org/v1
-kind: IntegrationKit
-metadata:
-  creationTimestamp: null
-  labels:
-    camel.apache.org/cloned.from.kind: IntegrationKit
-    camel.apache.org/cloned.from.name: my-kb-test-kit
-    camel.apache.org/cloned.from.namespace: default
-    camel.apache.org/cloned.from.version: "999"
-    camel.apache.org/kit.type: external
-  name: my-kb-test-kit
-  namespace: prod-namespace
-spec:
-  image: my-special-image
-  traits: {}
-status: {}
----
-apiVersion: camel.apache.org/v1
 kind: Pipe
 metadata:
   annotations:
     my-annotation: my-value
+    trait.camel.apache.org/camel.runtime-version: 1.2.3
+    trait.camel.apache.org/container.image: my-special-image
+    trait.camel.apache.org/jvm.classpath: 
/path/to/artifact-1/*:/path/to/artifact-2/*
   creationTimestamp: null
   labels:
     my-label: my-value
   name: my-kb-test
   namespace: prod-namespace
 spec:
-  integration:
-    integrationKit:
-      kind: IntegrationKit
-      name: my-kb-test-kit
-      namespace: prod-namespace
-    traits:
-      jvm:
-        classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
   sink: {}
   source: {}
 status: {}
@@ -404,25 +327,6 @@ func TestIntegrationToOperatorId(t *testing.T) {
        assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
        require.NoError(t, err)
        assert.Equal(t, `apiVersion: camel.apache.org/v1
-kind: IntegrationKit
-metadata:
-  annotations:
-    camel.apache.org/operator.id: my-prod-operator
-  creationTimestamp: null
-  labels:
-    camel.apache.org/cloned.from.kind: IntegrationKit
-    camel.apache.org/cloned.from.name: my-it-test-kit
-    camel.apache.org/cloned.from.namespace: default
-    camel.apache.org/cloned.from.version: "999"
-    camel.apache.org/kit.type: external
-  name: my-it-test-kit
-  namespace: prod
-spec:
-  image: my-special-image
-  traits: {}
-status: {}
----
-apiVersion: camel.apache.org/v1
 kind: Integration
 metadata:
   annotations:
@@ -431,11 +335,11 @@ metadata:
   name: my-it-test
   namespace: prod
 spec:
-  integrationKit:
-    kind: IntegrationKit
-    name: my-it-test-kit
-    namespace: prod
   traits:
+    camel:
+      runtimeVersion: 1.2.3
+    container:
+      image: my-special-image
     jvm:
       classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
 status: {}
@@ -449,25 +353,6 @@ status: {}
        assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
        require.NoError(t, err)
        assert.Equal(t, `apiVersion: camel.apache.org/v1
-kind: IntegrationKit
-metadata:
-  annotations:
-    camel.apache.org/operator.id: my-prod-operator
-  creationTimestamp: null
-  labels:
-    camel.apache.org/cloned.from.kind: IntegrationKit
-    camel.apache.org/cloned.from.name: my-it-test-kit
-    camel.apache.org/cloned.from.namespace: default
-    camel.apache.org/cloned.from.version: "999"
-    camel.apache.org/kit.type: external
-  name: my-it-test-kit
-  namespace: prod
-spec:
-  image: my-special-image
-  traits: {}
-status: {}
----
-apiVersion: camel.apache.org/v1
 kind: Integration
 metadata:
   annotations:
@@ -476,69 +361,11 @@ metadata:
   name: my-it-test
   namespace: prod
 spec:
-  integrationKit:
-    kind: IntegrationKit
-    name: my-it-test-kit
-    namespace: prod
-  traits:
-    jvm:
-      classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
-status: {}
-`, output)
-}
-
-func TestIntegrationKitWithLabels(t *testing.T) {
-       srcPlatform := v1.NewIntegrationPlatform("default", 
platform.DefaultPlatformName)
-       srcPlatform.Status.Version = defaults.Version
-       srcPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
-       srcPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
-       dstPlatform := v1.NewIntegrationPlatform("prod-namespace", 
platform.DefaultPlatformName)
-       dstPlatform.Status.Version = defaults.Version
-       dstPlatform.Status.Build.RuntimeVersion = defaults.DefaultRuntimeVersion
-       dstPlatform.Status.Phase = v1.IntegrationPlatformPhaseReady
-       defaultIntegration, defaultKit := nominalIntegration("my-it-test")
-       defaultKit.Labels = map[string]string{
-               kubernetes.CamelCreatorLabelKind:      "Integration",
-               kubernetes.CamelCreatorLabelName:      "my-original-it-name",
-               kubernetes.CamelCreatorLabelNamespace: 
"my-original-it-namespace",
-               kubernetes.CamelCreatorLabelVersion:   "my-original-it-version",
-       }
-       srcCatalog := createTestCamelCatalog(srcPlatform)
-       dstCatalog := createTestCamelCatalog(dstPlatform)
-
-       promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, 
&srcPlatform, &dstPlatform, &defaultIntegration, &defaultKit, &srcCatalog, 
&dstCatalog)
-       output, err := test.ExecuteCommand(promoteCmd, cmdPromote, 
"my-it-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default")
-       assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat)
-       require.NoError(t, err)
-       assert.Equal(t, `apiVersion: camel.apache.org/v1
-kind: IntegrationKit
-metadata:
-  creationTimestamp: null
-  labels:
-    camel.apache.org/cloned.from.kind: IntegrationKit
-    camel.apache.org/cloned.from.name: my-it-test-kit
-    camel.apache.org/cloned.from.namespace: default
-    camel.apache.org/cloned.from.version: "999"
-    camel.apache.org/kit.type: external
-  name: my-it-test-kit
-  namespace: prod-namespace
-spec:
-  image: my-special-image
-  traits: {}
-status: {}
----
-apiVersion: camel.apache.org/v1
-kind: Integration
-metadata:
-  creationTimestamp: null
-  name: my-it-test
-  namespace: prod-namespace
-spec:
-  integrationKit:
-    kind: IntegrationKit
-    name: my-it-test-kit
-    namespace: prod-namespace
   traits:
+    camel:
+      runtimeVersion: 1.2.3
+    container:
+      image: my-special-image
     jvm:
       classpath: /path/to/artifact-1/*:/path/to/artifact-2/*
 status: {}
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 52419bdfd..8f458b33d 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -594,14 +594,6 @@ func showIntegrationOutput(cmd *cobra.Command, integration 
*v1.Integration, outp
        return printer.PrintObj(integration, cmd.OutOrStdout())
 }
 
-func showIntegrationKitOutput(cmd *cobra.Command, integrationKit 
*v1.IntegrationKit, outputFormat string) error {
-       printer := printers.NewTypeSetter(scheme.Scheme)
-       printer.Delegate = &kubernetes.CLIPrinter{
-               Format: outputFormat,
-       }
-       return printer.PrintObj(integrationKit, cmd.OutOrStdout())
-}
-
 func (o *runCmdOptions) getIntegration(cmd *cobra.Command, c client.Client, 
namespace, name string) (*v1.Integration, *v1.Integration, error) {
        it := &v1.Integration{
                TypeMeta: metav1.TypeMeta{
diff --git a/pkg/controller/integration/build_kit.go 
b/pkg/controller/integration/build_kit.go
index 1ec95bac6..2ac2d4fd0 100644
--- a/pkg/controller/integration/build_kit.go
+++ b/pkg/controller/integration/build_kit.go
@@ -45,7 +45,6 @@ func (action *buildKitAction) CanHandle(integration 
*v1.Integration) bool {
 
 func (action *buildKitAction) Handle(ctx context.Context, integration 
*v1.Integration) (*v1.Integration, error) {
        // TODO: we may need to add a timeout strategy, i.e give up after some 
time in case of an unrecoverable error.
-
        secrets, configmaps := 
getIntegrationSecretAndConfigmapResourceVersions(ctx, action.client, 
integration)
        hash, err := digest.ComputeForIntegration(integration, configmaps, 
secrets)
        if err != nil {
@@ -73,9 +72,10 @@ func (action *buildKitAction) Handle(ctx context.Context, 
integration *v1.Integr
        action.L.Debug("No kit specified in integration status so looking up", 
"integration", integration.Name, "namespace", integration.Namespace)
        existingKits, err := lookupKitsForIntegration(ctx, action.client, 
integration)
        if err != nil {
-               return nil, fmt.Errorf("failed to lookup kits for integration 
%s/%s: %w",
-                       integration.Namespace, integration.Name, err)
-
+               err = fmt.Errorf("failed to lookup kits for integration %s/%s: 
%w", integration.Namespace, integration.Name, err)
+               integration.Status.Phase = v1.IntegrationPhaseError
+               integration.SetReadyConditionError(err.Error())
+               return integration, err
        }
 
        action.L.Debug("Applying traits to integration",
@@ -83,9 +83,10 @@ func (action *buildKitAction) Handle(ctx context.Context, 
integration *v1.Integr
                "namespace", integration.Namespace)
        env, err := trait.Apply(ctx, action.client, integration, nil)
        if err != nil {
-               return nil, fmt.Errorf("failed to apply traits to integration 
%s/%s: %w",
-                       integration.Namespace, integration.Name, err)
-
+               err = fmt.Errorf("failed to apply traits to integration %s/%s: 
%w", integration.Namespace, integration.Name, err)
+               integration.Status.Phase = v1.IntegrationPhaseError
+               integration.SetReadyConditionError(err.Error())
+               return integration, err
        }
 
        action.L.Debug("Searching integration kits to assign to integration", 
"integration",
@@ -100,9 +101,10 @@ kits:
                        action.L.Debug("Comparing existing kit with 
environment", "env kit", kit.Name, "existing kit", k.Name)
                        match, err := kitMatches(action.client, &kit, k)
                        if err != nil {
-                               return nil, fmt.Errorf("error occurred matches 
integration kits with environment for integration %s/%s: %w",
-                                       integration.Namespace, 
integration.Name, err)
-
+                               err = fmt.Errorf("error occurred matches 
integration kits with environment for integration %s/%s: %w", 
integration.Namespace, integration.Name, err)
+                               integration.Status.Phase = 
v1.IntegrationPhaseError
+                               integration.SetReadyConditionError(err.Error())
+                               return integration, err
                        }
                        if match {
                                if integrationKit == nil ||
@@ -123,9 +125,10 @@ kits:
                        "namespace", integration.Namespace,
                        "integration kit", kit.Name)
                if err := action.client.Create(ctx, &kit); err != nil {
-                       return nil, fmt.Errorf("failed to create new 
integration kit for integration %s/%s: %w",
-                               integration.Namespace, integration.Name, err)
-
+                       err = fmt.Errorf("failed to create new integration kit 
for integration %s/%s: %w", integration.Namespace, integration.Name, err)
+                       integration.Status.Phase = v1.IntegrationPhaseError
+                       integration.SetReadyConditionError(err.Error())
+                       return integration, err
                }
                if integrationKit == nil {
                        integrationKit = &kit
@@ -133,7 +136,6 @@ kits:
        }
 
        if integrationKit != nil {
-
                action.L.Debug("Setting integration kit for integration", 
"integration", integration.Name, "namespace", integration.Namespace, 
"integration kit", integrationKit.Name)
                // Set the kit name so the next handle loop, will fall through 
the
                // same path as integration with a user defined kit
diff --git a/pkg/controller/integration/monitor.go 
b/pkg/controller/integration/monitor.go
index f82e8a13e..af90cc3db 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -65,6 +65,7 @@ func (action *monitorAction) CanHandle(integration 
*v1.Integration) bool {
                integration.Status.Phase == v1.IntegrationPhaseError
 }
 
+//nolint:nestif
 func (action *monitorAction) Handle(ctx context.Context, integration 
*v1.Integration) (*v1.Integration, error) {
        // When in InitializationFailed condition a kit is not available for 
the integration
        // so handle it differently from the rest
diff --git a/pkg/controller/integrationkit/error.go 
b/pkg/controller/integrationkit/error.go
index 9f245f0ef..596690ee9 100644
--- a/pkg/controller/integrationkit/error.go
+++ b/pkg/controller/integrationkit/error.go
@@ -42,6 +42,7 @@ func (action *errorAction) CanHandle(kit *v1.IntegrationKit) 
bool {
 }
 
 func (action *errorAction) Handle(ctx context.Context, kit *v1.IntegrationKit) 
(*v1.IntegrationKit, error) {
+       //nolint: staticcheck
        if kit.IsExternal() || kit.IsSynthetic() {
                // do nothing, it's not a managed kit
                return nil, nil
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go 
b/pkg/controller/integrationkit/integrationkit_controller.go
index 4dde58bb4..6705907e8 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -242,6 +242,7 @@ func (r *reconcileIntegrationKit) Reconcile(ctx 
context.Context, request reconci
        //nolint:nestif
        if target.Status.Phase == v1.IntegrationKitPhaseNone || 
target.Status.Phase == v1.IntegrationKitPhaseWaitingForPlatform {
                rlog.Debug("Preparing to shift integration kit phase")
+               //nolint: staticcheck
                if target.IsExternal() || target.IsSynthetic() {
                        target.Status.Phase = 
v1.IntegrationKitPhaseInitialization
                        return r.update(ctx, &instance, target)
diff --git a/pkg/controller/integrationkit/monitor.go 
b/pkg/controller/integrationkit/monitor.go
index a574bb944..82e958ffc 100644
--- a/pkg/controller/integrationkit/monitor.go
+++ b/pkg/controller/integrationkit/monitor.go
@@ -44,6 +44,7 @@ func (action *monitorAction) CanHandle(kit 
*v1.IntegrationKit) bool {
 }
 
 func (action *monitorAction) Handle(ctx context.Context, kit 
*v1.IntegrationKit) (*v1.IntegrationKit, error) {
+       //nolint: staticcheck
        if kit.IsExternal() || kit.IsSynthetic() {
                // do nothing, it's not a managed kit
                // if it's a syntetic Kit add a condition to warn this is a
diff --git a/pkg/trait/builder_test.go b/pkg/trait/builder_test.go
index bc1adede5..a096c6e7c 100644
--- a/pkg/trait/builder_test.go
+++ b/pkg/trait/builder_test.go
@@ -45,11 +45,12 @@ func TestBuilderTraitNotAppliedBecauseOfNilKit(t 
*testing.T) {
                e.IntegrationKit = nil
 
                t.Run(string(e.Platform.Status.Cluster), func(t *testing.T) {
-                       conditions, err := NewBuilderTestCatalog().apply(e)
+                       trait, _ := newBuilderTrait().(*builderTrait)
 
+                       configure, conditions, err := trait.Configure(e)
+                       assert.False(t, configure)
+                       assert.Empty(t, conditions)
                        require.NoError(t, err)
-                       assert.NotEmpty(t, conditions)
-                       assert.NotEmpty(t, e.ExecutedTraits)
                        assert.Nil(t, e.GetTrait("builder"))
                        assert.Empty(t, e.Pipeline)
                })
diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go
index 0d585a3e6..698f36051 100644
--- a/pkg/trait/camel.go
+++ b/pkg/trait/camel.go
@@ -78,6 +78,7 @@ func (t *camelTrait) Configure(e *Environment) (bool, 
*TraitCondition, error) {
        }
 
        var cond *TraitCondition
+       //nolint: staticcheck
        if (e.Integration != nil && !e.Integration.IsManagedBuild()) || 
(e.IntegrationKit != nil && e.IntegrationKit.IsSynthetic()) {
                // We set a condition to warn the user the catalog used to run 
the Integration
                // may differ from the runtime version which we don't control
@@ -118,6 +119,7 @@ func (t *camelTrait) Apply(e *Environment) error {
                }
        }
        if e.IntegrationKit != nil {
+               //nolint: staticcheck
                if !e.IntegrationKit.IsSynthetic() {
                        e.IntegrationKit.Status.RuntimeVersion = 
e.CamelCatalog.Runtime.Version
                        e.IntegrationKit.Status.RuntimeProvider = 
e.CamelCatalog.Runtime.Provider
diff --git a/pkg/trait/container_probes_test.go 
b/pkg/trait/container_probes_test.go
index 5a60f7352..4b128e9c2 100644
--- a/pkg/trait/container_probes_test.go
+++ b/pkg/trait/container_probes_test.go
@@ -57,6 +57,7 @@ func newTestProbesEnv(t *testing.T, integration 
*v1.Integration) Environment {
                                },
                        },
                },
+               IntegrationKit:        &v1.IntegrationKit{},
                Integration:           integration,
                Resources:             kubernetes.NewCollection(),
                ApplicationProperties: make(map[string]string),
diff --git a/pkg/trait/container_test.go b/pkg/trait/container_test.go
index 80a60efcf..db41467a8 100644
--- a/pkg/trait/container_test.go
+++ b/pkg/trait/container_test.go
@@ -384,10 +384,11 @@ func TestContainerWithImagePullPolicy(t *testing.T) {
        traitCatalog := NewCatalog(nil)
 
        environment := Environment{
-               Ctx:          context.TODO(),
-               Client:       client,
-               CamelCatalog: catalog,
-               Catalog:      traitCatalog,
+               Ctx:            context.TODO(),
+               Client:         client,
+               CamelCatalog:   catalog,
+               Catalog:        traitCatalog,
+               IntegrationKit: &v1.IntegrationKit{},
                Integration: &v1.Integration{
                        Spec: v1.IntegrationSpec{
                                Profile: v1.TraitProfileKubernetes,
@@ -431,10 +432,11 @@ func TestDeploymentContainerPorts(t *testing.T) {
        traitCatalog := NewCatalog(nil)
 
        environment := Environment{
-               Ctx:          context.TODO(),
-               Client:       client,
-               CamelCatalog: catalog,
-               Catalog:      traitCatalog,
+               Ctx:            context.TODO(),
+               Client:         client,
+               CamelCatalog:   catalog,
+               Catalog:        traitCatalog,
+               IntegrationKit: &v1.IntegrationKit{},
                Integration: &v1.Integration{
                        Spec: v1.IntegrationSpec{
                                Profile: v1.TraitProfileKubernetes,
@@ -496,10 +498,11 @@ func TestKnativeServiceContainerPorts(t *testing.T) {
        traitCatalog := NewCatalog(nil)
 
        environment := Environment{
-               Ctx:          context.TODO(),
-               Client:       client,
-               CamelCatalog: catalog,
-               Catalog:      traitCatalog,
+               Ctx:            context.TODO(),
+               Client:         client,
+               CamelCatalog:   catalog,
+               Catalog:        traitCatalog,
+               IntegrationKit: &v1.IntegrationKit{},
                Integration: &v1.Integration{
                        Spec: v1.IntegrationSpec{
                                Profile: v1.TraitProfileKnative,
diff --git a/pkg/trait/istio_test.go b/pkg/trait/istio_test.go
index 7be2a6291..e6f63df4c 100644
--- a/pkg/trait/istio_test.go
+++ b/pkg/trait/istio_test.go
@@ -45,9 +45,10 @@ func NewIstioTestEnv(t *testing.T, d *appsv1.Deployment, s 
*serving.Service, ena
        require.NoError(t, err)
 
        env := Environment{
-               Catalog:      NewEnvironmentTestCatalog(),
-               CamelCatalog: catalog,
-               Client:       client,
+               Catalog:        NewEnvironmentTestCatalog(),
+               CamelCatalog:   catalog,
+               Client:         client,
+               IntegrationKit: &v1.IntegrationKit{},
                Integration: &v1.Integration{
                        Status: v1.IntegrationStatus{
                                Phase: v1.IntegrationPhaseDeploying,
diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go
index a123f00da..0a28ba036 100644
--- a/pkg/trait/jvm.go
+++ b/pkg/trait/jvm.go
@@ -69,17 +69,12 @@ func (t *jvmTrait) Configure(e *Environment) (bool, 
*TraitCondition, error) {
                notice := userDisabledMessage + "; this configuration is 
deprecated and may be removed within next releases"
                return false, NewIntegrationCondition("JVM", 
v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, 
traitConfigurationReason, notice), nil
        }
-       if !e.IntegrationKitInPhase(v1.IntegrationKitPhaseReady) || 
!e.IntegrationInRunningPhases() {
-               return false, nil, nil
-       }
 
-       // The JVM trait must be disabled in case the current IntegrationKit 
corresponds to a native build
-       if qt := e.Catalog.GetTrait(quarkusTraitID); qt != nil {
-               if quarkus, ok := qt.(*quarkusTrait); ok && 
quarkus.isNativeIntegration(e) {
-                       return false, 
NewIntegrationConditionPlatformDisabledWithMessage("JVM", "quarkus native 
build"), nil
-               }
+       if (e.IntegrationKit != nil && 
!e.IntegrationKitInPhase(v1.IntegrationKitPhaseReady)) || 
!e.IntegrationInRunningPhases() {
+               return false, nil, nil
        }
 
+       //nolint: staticcheck
        if ((e.Integration != nil && !e.Integration.IsManagedBuild()) || 
(e.IntegrationKit != nil && e.IntegrationKit.IsSynthetic())) &&
                t.Jar == "" {
                // We skip this trait since we cannot make any assumption on 
the container Java tooling running
@@ -90,6 +85,13 @@ func (t *jvmTrait) Configure(e *Environment) (bool, 
*TraitCondition, error) {
                ), nil
        }
 
+       // The JVM trait must be disabled in case the current IntegrationKit 
corresponds to a native build
+       if qt := e.Catalog.GetTrait(quarkusTraitID); qt != nil {
+               if quarkus, ok := qt.(*quarkusTrait); ok && 
quarkus.isNativeIntegration(e) {
+                       return false, 
NewIntegrationConditionPlatformDisabledWithMessage("JVM", "quarkus native 
build"), nil
+               }
+       }
+
        return true, nil, nil
 }
 
@@ -139,6 +141,11 @@ func (t *jvmTrait) Apply(e *Environment) error {
                args = append(args, httpProxyArgs...)
        }
 
+       return t.feedContainer(container, args, e)
+}
+
+//nolint:nestif
+func (t *jvmTrait) feedContainer(container *corev1.Container, args []string, e 
*Environment) error {
        // If user provided the jar, we will execute on the container something 
like
        // java -Dxyx ... -cp ... -jar my-app.jar
        // For this reason it's important that the container is a java based 
container able to run a Camel (hence Java) application
@@ -147,20 +154,23 @@ func (t *jvmTrait) Apply(e *Environment) error {
        classpathItems := t.prepareClasspathItems(container)
        if t.Jar != "" {
                // User is providing the Jar to execute explicitly
-               args = append(args, "-cp", strings.Join(classpathItems, ":"))
+               args = append(args, "-cp", classpathItems)
                args = append(args, "-jar", t.Jar)
        } else {
                kit, err := t.getIntegrationKit(e)
                if err != nil {
                        return err
                }
-               kitDepsDirs := kit.Status.GetDependenciesPaths()
-               if len(kitDepsDirs) == 0 {
-                       // Use legacy Camel Quarkus expected structure
-                       kitDepsDirs = getLegacyCamelQuarkusDependenciesPaths()
+               if kit != nil {
+                       // managed Integrations
+                       kitDepsDirs := kit.Status.GetDependenciesPaths()
+                       if kitDepsDirs.IsEmpty() {
+                               // Use legacy Camel Quarkus expected structure
+                               kitDepsDirs = 
getLegacyCamelQuarkusDependenciesPaths()
+                       }
+                       classpathItems = getClasspath(kitDepsDirs, 
classpathItems)
                }
-               classpathItems = append(classpathItems, kitDepsDirs...)
-               args = append(args, "-cp", strings.Join(classpathItems, ":"))
+               args = append(args, "-cp", classpathItems)
                args = append(args, e.CamelCatalog.Runtime.ApplicationClass)
        }
        container.Args = args
@@ -168,28 +178,41 @@ func (t *jvmTrait) Apply(e *Environment) error {
        return nil
 }
 
+// getClasspath merges the classpath required by the kit with any value 
provided in the trait.
+func getClasspath(depsDirs *sets.Set, jvmTraitClasspath string) string {
+       if !depsDirs.IsEmpty() {
+               if jvmTraitClasspath != "" {
+                       jvmTraitClasspathSet := 
getClasspathSet(jvmTraitClasspath)
+                       depsDirs = sets.Union(depsDirs, jvmTraitClasspathSet)
+               }
+               classPaths := depsDirs.List()
+               sort.Strings(classPaths)
+
+               return strings.Join(classPaths, ":")
+       }
+
+       return jvmTraitClasspath
+}
+
+func getClasspathSet(cps string) *sets.Set {
+       s := sets.NewSet()
+       for _, cp := range strings.Split(cps, ":") {
+               s.Add(cp)
+       }
+
+       return s
+}
+
 func (t *jvmTrait) getIntegrationKit(e *Environment) (*v1.IntegrationKit, 
error) {
        kit := e.IntegrationKit
 
        if kit == nil && e.Integration.Status.IntegrationKit != nil {
                name := e.Integration.Status.IntegrationKit.Name
                ns := e.Integration.GetIntegrationKitNamespace(e.Platform)
-               k := v1.NewIntegrationKit(ns, name)
-               if err := t.Client.Get(e.Ctx, ctrl.ObjectKeyFromObject(k), k); 
err != nil {
+               kit = v1.NewIntegrationKit(ns, name)
+               if err := t.Client.Get(e.Ctx, ctrl.ObjectKeyFromObject(kit), 
kit); err != nil {
                        return nil, fmt.Errorf("unable to find integration kit 
%s/%s: %w", ns, name, err)
                }
-               kit = k
-       }
-
-       if kit == nil {
-               if e.Integration.Status.IntegrationKit != nil {
-                       return nil, fmt.Errorf(
-                               "unable to find integration kit %s/%s",
-                               
e.Integration.GetIntegrationKitNamespace(e.Platform),
-                               e.Integration.Status.IntegrationKit.Name,
-                       )
-               }
-               return nil, fmt.Errorf("unable to find integration kit for 
integration %s", e.Integration.Name)
        }
 
        return kit, nil
@@ -212,7 +235,7 @@ func (t *jvmTrait) enableDebug(e *Environment) string {
                suspend, t.DebugAddress)
 }
 
-func (t *jvmTrait) prepareClasspathItems(container *corev1.Container) []string 
{
+func (t *jvmTrait) prepareClasspathItems(container *corev1.Container) string {
        existingClasspaths := extractExistingClasspathItems(container)
        classpath := sets.NewSet()
        // Deprecated: replaced by 
/etc/camel/resources.d/[_configmaps/_secrets] 
(camel.ResourcesConfigmapsMountPath/camel.ResourcesSecretsMountPath).
@@ -235,10 +258,10 @@ func (t *jvmTrait) prepareClasspathItems(container 
*corev1.Container) []string {
 
        if existingClasspaths != nil {
                existingClasspaths = append(existingClasspaths, items...)
-               return existingClasspaths
+               return strings.Join(existingClasspaths, ":")
        }
 
-       return items
+       return strings.Join(items, ":")
 }
 
 // extractExistingClasspathItems returns any container classpath option (if 
exists).
@@ -317,11 +340,12 @@ func (t *jvmTrait) prepareHTTPProxy(container 
*corev1.Container) ([]string, erro
 }
 
 // Deprecated: to be removed as soon as version 2.3.x is no longer supported.
-func getLegacyCamelQuarkusDependenciesPaths() []string {
-       return []string{
-               "dependencies/*",
-               "dependencies/lib/boot/*",
-               "dependencies/lib/main/*",
-               "dependencies/quarkus/*",
-       }
+func getLegacyCamelQuarkusDependenciesPaths() *sets.Set {
+       s := sets.NewSet()
+       s.Add("dependencies/*")
+       s.Add("dependencies/lib/boot/*")
+       s.Add("dependencies/lib/main/*")
+       s.Add("dependencies/quarkus/*")
+
+       return s
 }
diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go
index dff67c63e..0eea06c2f 100644
--- a/pkg/trait/jvm_test.go
+++ b/pkg/trait/jvm_test.go
@@ -493,7 +493,7 @@ func 
TestApplyJvmTraitWithClasspathAndExistingContainerCPArg(t *testing.T) {
                "-cp",
                "my-precious-lib.jar",
                "-cp",
-               
fmt.Sprintf("my-precious-lib.jar:./resources:%s:%s:%s:%s:%s:dependencies/*",
+               
fmt.Sprintf("./resources:%s:%s:%s:%s:%s:dependencies/*:my-precious-lib.jar",
                        rdMountPath, cmrMountPath, scrMountPath,
                        "/path/to/another/dep.jar", "/path/to/my-dep.jar"),
                "io.quarkus.bootstrap.runner.QuarkusEntryPoint",
diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go
index 748edaac5..b2193b1ec 100644
--- a/pkg/trait/quarkus.go
+++ b/pkg/trait/quarkus.go
@@ -142,6 +142,15 @@ func (t *quarkusTrait) Matches(trait Trait) bool {
 func (t *quarkusTrait) Configure(e *Environment) (bool, *TraitCondition, 
error) {
        condition := t.adaptDeprecatedFields()
 
+       if t.containsMode(traitv1.NativeQuarkusMode) && 
e.IntegrationInPhase(v1.IntegrationPhaseBuildingKit) {
+               // Native compilation is only supported for a subset of 
languages,
+               // so let's check for compatibility, and fail-fast the 
Integration,
+               // to save compute resources and user time.
+               if err := t.validateNativeSupport(e); err != nil {
+                       return false, nil, err
+               }
+       }
+
        return e.IntegrationInPhase(v1.IntegrationPhaseBuildingKit) ||
                        
e.IntegrationKitInPhase(v1.IntegrationKitPhaseBuildSubmitted) ||
                        e.IntegrationKitInPhase(v1.IntegrationKitPhaseReady) && 
e.IntegrationInRunningPhases(),
@@ -167,10 +176,20 @@ func (t *quarkusTrait) adaptDeprecatedFields() 
*TraitCondition {
        return nil
 }
 
+func (t *quarkusTrait) validateNativeSupport(e *Environment) error {
+       for _, source := range e.Integration.AllSources() {
+               if language := source.InferLanguage(); !getLanguageSettings(e, 
language).native {
+                       return fmt.Errorf("invalid native support: Integration 
%s/%s contains a %s source that cannot be compiled to native executable",
+                               e.Integration.Namespace, e.Integration.Name, 
language)
+               }
+       }
+
+       return nil
+}
+
 func (t *quarkusTrait) Apply(e *Environment) error {
        if e.IntegrationInPhase(v1.IntegrationPhaseBuildingKit) {
                t.applyWhileBuildingKit(e)
-
                return nil
        }
 
@@ -190,16 +209,6 @@ func (t *quarkusTrait) Apply(e *Environment) error {
 }
 
 func (t *quarkusTrait) applyWhileBuildingKit(e *Environment) {
-       if t.containsMode(traitv1.NativeQuarkusMode) {
-               // Native compilation is only supported for a subset of 
languages,
-               // so let's check for compatibility, and fail-fast the 
Integration,
-               // to save compute resources and user time.
-               if !t.validateNativeSupport(e) {
-                       // Let the calling controller handle the Integration 
update
-                       return
-               }
-       }
-
        switch len(t.Modes) {
        case 0:
                // Default behavior
@@ -224,24 +233,6 @@ func (t *quarkusTrait) applyWhileBuildingKit(e 
*Environment) {
        }
 }
 
-func (t *quarkusTrait) validateNativeSupport(e *Environment) bool {
-       for _, source := range e.Integration.AllSources() {
-               if language := source.InferLanguage(); !getLanguageSettings(e, 
language).native {
-                       t.L.ForIntegration(e.Integration).Infof("Integration 
%s/%s contains a %s source that cannot be compiled to native executable", 
e.Integration.Namespace, e.Integration.Name, language)
-                       e.Integration.Status.Phase = v1.IntegrationPhaseError
-                       e.Integration.Status.SetCondition(
-                               v1.IntegrationConditionKitAvailable,
-                               corev1.ConditionFalse,
-                               
v1.IntegrationConditionUnsupportedLanguageReason,
-                               fmt.Sprintf("native compilation for language %q 
is not supported", language))
-
-                       return false
-               }
-       }
-
-       return true
-}
-
 func (t *quarkusTrait) newIntegrationKit(e *Environment, packageType 
quarkusPackageType) *v1.IntegrationKit {
        integration := e.Integration
        kit := 
v1.NewIntegrationKit(integration.GetIntegrationKitNamespace(e.Platform), 
fmt.Sprintf("kit-%s", xid.New()))
diff --git a/pkg/trait/quarkus_test.go b/pkg/trait/quarkus_test.go
index 6c0ae919d..107eecfaa 100644
--- a/pkg/trait/quarkus_test.go
+++ b/pkg/trait/quarkus_test.go
@@ -21,6 +21,7 @@ import (
        "testing"
 
        "github.com/apache/camel-k/v2/pkg/util/boolean"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
        traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
 
@@ -55,6 +56,21 @@ func TestConfigureQuarkusTraitBuildSubmitted(t *testing.T) {
        assert.Len(t, packageTask.Steps, 4)
 }
 
+func TestConfigureQuarkusTraitNativeNotSupported(t *testing.T) {
+       quarkusTrait, environment := createNominalQuarkusTest()
+       // Set a source not supporting Quarkus native
+       environment.Integration.Spec.Sources[0].Language = v1.LanguageJavaScript
+       environment.Integration.Status.Phase = v1.IntegrationPhaseBuildingKit
+       quarkusTrait.Modes = []traitv1.QuarkusMode{traitv1.NativeQuarkusMode}
+
+       configured, condition, err := quarkusTrait.Configure(environment)
+
+       assert.False(t, configured)
+       require.Error(t, err)
+       assert.Equal(t, "invalid native support: Integration default/my-it 
contains a js source that cannot be compiled to native executable", err.Error())
+       assert.Nil(t, condition)
+}
+
 func TestApplyQuarkusTraitDefaultKitLayout(t *testing.T) {
        quarkusTrait, environment := createNominalQuarkusTest()
        environment.Integration.Status.Phase = v1.IntegrationPhaseBuildingKit
@@ -96,6 +112,10 @@ func createNominalQuarkusTest() (*quarkusTrait, 
*Environment) {
                Catalog:      NewCatalog(client),
                CamelCatalog: &camel.RuntimeCatalog{},
                Integration: &v1.Integration{
+                       ObjectMeta: metav1.ObjectMeta{
+                               Namespace: "default",
+                               Name:      "my-it",
+                       },
                        Spec: v1.IntegrationSpec{
                                Sources: []v1.SourceSpec{
                                        {
diff --git a/pkg/trait/service_test.go b/pkg/trait/service_test.go
index 58063df29..b61149115 100644
--- a/pkg/trait/service_test.go
+++ b/pkg/trait/service_test.go
@@ -431,9 +431,10 @@ func TestServiceWithKnativeServiceEnabled(t *testing.T) {
        require.NoError(t, err)
 
        environment := Environment{
-               CamelCatalog: catalog,
-               Catalog:      traitCatalog,
-               Client:       client,
+               CamelCatalog:   catalog,
+               Catalog:        traitCatalog,
+               Client:         client,
+               IntegrationKit: &v1.IntegrationKit{},
                Integration: &v1.Integration{
                        ObjectMeta: metav1.ObjectMeta{
                                Name:      ServiceTestName,
@@ -523,9 +524,10 @@ func TestServicesWithKnativeProfile(t *testing.T) {
        require.NoError(t, err)
 
        environment := Environment{
-               CamelCatalog: catalog,
-               Catalog:      traitCatalog,
-               Client:       client,
+               CamelCatalog:   catalog,
+               Catalog:        traitCatalog,
+               Client:         client,
+               IntegrationKit: &v1.IntegrationKit{},
                Integration: &v1.Integration{
                        ObjectMeta: metav1.ObjectMeta{
                                Name:      ServiceTestName,
@@ -603,9 +605,10 @@ func 
TestServiceWithKnativeServiceDisabledInIntegrationPlatform(t *testing.T) {
        require.NoError(t, err)
 
        environment := Environment{
-               CamelCatalog: catalog,
-               Catalog:      traitCatalog,
-               Client:       client,
+               CamelCatalog:   catalog,
+               Catalog:        traitCatalog,
+               Client:         client,
+               IntegrationKit: &v1.IntegrationKit{},
                Integration: &v1.Integration{
                        ObjectMeta: metav1.ObjectMeta{
                                Name:      ServiceTestName,

Reply via email to