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

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

commit ffa53139cd78270b2f3b3bd1e850f49099b73266
Author: Christoph Deppisch <cdeppi...@redhat.com>
AuthorDate: Thu Jun 1 15:08:13 2023 +0200

    fix(#592): Introduce build order strategy
    
    - Run builds on same operator namespace with user defined strategy
    - Default strategy is "sequential" running only one single build at a time
    - Also support "fifo" strategy where builds are run/queued based on their 
creation timestamp. This strategy allows parallel builds as long as individual 
build dependency lists are not colliding
    - Users may adjust/overwrite the build order strategy via install command 
option, in the (local) integration platform settings or via the builder trait 
option
    - Max number of running builds limitation is not affected by the build 
order strategy (ensure to always obey the limitation)
---
 config/crd/bases/camel.apache.org_builds.yaml      |  12 ++
 .../bases/camel.apache.org_integrationkits.yaml    |   4 +
 .../camel.apache.org_integrationplatforms.yaml     |  20 +++
 .../crd/bases/camel.apache.org_integrations.yaml   |   4 +
 .../bases/camel.apache.org_kameletbindings.yaml    |   4 +
 config/crd/bases/camel.apache.org_pipes.yaml       |   4 +
 docs/modules/ROOT/pages/architecture/cr/build.adoc |   9 ++
 .../ROOT/pages/installation/advanced/advanced.adoc |   1 +
 docs/modules/ROOT/partials/apis/camel-k-crds.adoc  |  24 +++
 docs/modules/traits/pages/builder.adoc             |   4 +
 e2e/builder/build_test.go                          |  77 ++++++++-
 e2e/common/traits/builder_test.go                  |  35 ++++-
 e2e/commonwithcustominstall/local_platform_test.go |   1 +
 helm/camel-k/crds/crd-build.yaml                   |  12 ++
 helm/camel-k/crds/crd-integration-kit.yaml         |   4 +
 helm/camel-k/crds/crd-integration-platform.yaml    |  20 +++
 helm/camel-k/crds/crd-integration.yaml             |   4 +
 helm/camel-k/crds/crd-kamelet-binding.yaml         |   4 +
 helm/camel-k/crds/crd-pipe.yaml                    |   4 +
 pkg/apis/camel/v1/build_types_support.go           |  25 +++
 pkg/apis/camel/v1/common_types.go                  |  18 +++
 pkg/apis/camel/v1/common_types_support.go          |   1 +
 pkg/apis/camel/v1/trait/builder.go                 |   2 +
 .../camel/v1/buildconfiguration.go                 |  23 ++-
 pkg/cmd/install.go                                 |  22 +++
 pkg/cmd/install_test.go                            |   7 +
 pkg/controller/build/build_controller.go           |   3 +-
 pkg/controller/build/build_monitor.go              |  43 ++---
 pkg/controller/build/build_monitor_test.go         | 173 ++++++++++++++++++++-
 pkg/controller/integrationkit/build.go             |  13 +-
 pkg/platform/defaults.go                           |   9 ++
 pkg/platform/defaults_test.go                      |  37 ++++-
 pkg/resources/resources.go                         |  28 ++--
 pkg/trait/builder.go                               |  43 ++++-
 resources/traits.yaml                              |   4 +
 35 files changed, 634 insertions(+), 64 deletions(-)

diff --git a/config/crd/bases/camel.apache.org_builds.yaml 
b/config/crd/bases/camel.apache.org_builds.yaml
index 9e525152b..44ee86332 100644
--- a/config/crd/bases/camel.apache.org_builds.yaml
+++ b/config/crd/bases/camel.apache.org_builds.yaml
@@ -97,6 +97,12 @@ spec:
                     description: The namespace where to run the builder Pod 
(must
                       be the same of the operator in charge of this Build 
reconciliation).
                     type: string
+                  orderStrategy:
+                    description: the build order strategy to adopt
+                    enum:
+                    - fifo
+                    - sequential
+                    type: string
                   requestCPU:
                     description: The minimum amount of CPU required. Only used 
for
                       `pod` strategy
@@ -206,6 +212,12 @@ spec:
                                 Pod (must be the same of the operator in 
charge of
                                 this Build reconciliation).
                               type: string
+                            orderStrategy:
+                              description: the build order strategy to adopt
+                              enum:
+                              - fifo
+                              - sequential
+                              type: string
                             requestCPU:
                               description: The minimum amount of CPU required. 
Only
                                 used for `pod` strategy
diff --git a/config/crd/bases/camel.apache.org_integrationkits.yaml 
b/config/crd/bases/camel.apache.org_integrationkits.yaml
index 8ff5668a5..39fccd088 100644
--- a/config/crd/bases/camel.apache.org_integrationkits.yaml
+++ b/config/crd/bases/camel.apache.org_integrationkits.yaml
@@ -211,6 +211,10 @@ spec:
                         description: When using `pod` strategy, the maximum 
amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either 
`fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to 
the build
                           task
diff --git a/config/crd/bases/camel.apache.org_integrationplatforms.yaml 
b/config/crd/bases/camel.apache.org_integrationplatforms.yaml
index 080b76618..1d716f3e6 100644
--- a/config/crd/bases/camel.apache.org_integrationplatforms.yaml
+++ b/config/crd/bases/camel.apache.org_integrationplatforms.yaml
@@ -116,6 +116,12 @@ spec:
                         description: The namespace where to run the builder 
Pod (must
                           be the same of the operator in charge of this Build 
reconciliation).
                         type: string
+                      orderStrategy:
+                        description: the build order strategy to adopt
+                        enum:
+                        - fifo
+                        - sequential
+                        type: string
                       requestCPU:
                         description: The minimum amount of CPU required. Only 
used
                           for `pod` strategy
@@ -462,6 +468,10 @@ spec:
                         description: When using `pod` strategy, the maximum 
amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either 
`fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to 
the build
                           task
@@ -1753,6 +1763,12 @@ spec:
                         description: The namespace where to run the builder 
Pod (must
                           be the same of the operator in charge of this Build 
reconciliation).
                         type: string
+                      orderStrategy:
+                        description: the build order strategy to adopt
+                        enum:
+                        - fifo
+                        - sequential
+                        type: string
                       requestCPU:
                         description: The minimum amount of CPU required. Only 
used
                           for `pod` strategy
@@ -2147,6 +2163,10 @@ spec:
                         description: When using `pod` strategy, the maximum 
amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either 
`fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to 
the build
                           task
diff --git a/config/crd/bases/camel.apache.org_integrations.yaml 
b/config/crd/bases/camel.apache.org_integrations.yaml
index 0912bebc7..6106dc086 100644
--- a/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/config/crd/bases/camel.apache.org_integrations.yaml
@@ -6194,6 +6194,10 @@ spec:
                         description: When using `pod` strategy, the maximum 
amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either 
`fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to 
the build
                           task
diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml 
b/config/crd/bases/camel.apache.org_kameletbindings.yaml
index 93b4eba21..2ffcbaff3 100644
--- a/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -6469,6 +6469,10 @@ spec:
                             description: When using `pod` strategy, the 
maximum amount
                               of memory required by the pod builder.
                             type: string
+                          orderStrategy:
+                            description: The build order strategy to use, 
either `fifo`
+                              or `sequential` (default sequential)
+                            type: string
                           properties:
                             description: A list of properties to be provided 
to the
                               build task
diff --git a/config/crd/bases/camel.apache.org_pipes.yaml 
b/config/crd/bases/camel.apache.org_pipes.yaml
index 6b166be6b..4da7c6ade 100644
--- a/config/crd/bases/camel.apache.org_pipes.yaml
+++ b/config/crd/bases/camel.apache.org_pipes.yaml
@@ -6466,6 +6466,10 @@ spec:
                             description: When using `pod` strategy, the 
maximum amount
                               of memory required by the pod builder.
                             type: string
+                          orderStrategy:
+                            description: The build order strategy to use, 
either `fifo`
+                              or `sequential` (default sequential)
+                            type: string
                           properties:
                             description: A list of properties to be provided 
to the
                               build task
diff --git a/docs/modules/ROOT/pages/architecture/cr/build.adoc 
b/docs/modules/ROOT/pages/architecture/cr/build.adoc
index 306fb22bf..f331906f1 100644
--- a/docs/modules/ROOT/pages/architecture/cr/build.adoc
+++ b/docs/modules/ROOT/pages/architecture/cr/build.adoc
@@ -36,6 +36,15 @@ At the moment the available strategies are:
 - buildStrategy: pod (each build is run in a separate pod, the operator 
monitors the pod state)
 - buildStrategy: routine (each build is run as a go routine inside the 
operator pod)
 
+[[build-order-strategy]]
+== Build order strategy
+
+You can choose from different build order strategies. The strategy defines in 
which order queued builds are run.
+At the moment the available strategies are:
+
+- buildOrderStrategy: sequential (runs builds strictly sequential so that only 
one single build per operator namespace is running at a time.)
+- buildOrderStrategy: fifo (performs the builds with first in first out 
strategy based on the creation timestamp. The strategy allows builds to run in 
parallel to each other but oldest builds will be run first.)
+
 [[build-queue]]
 == Build queues
 
diff --git a/docs/modules/ROOT/pages/installation/advanced/advanced.adoc 
b/docs/modules/ROOT/pages/installation/advanced/advanced.adoc
index c34e804d6..595f9ccef 100644
--- a/docs/modules/ROOT/pages/installation/advanced/advanced.adoc
+++ b/docs/modules/ROOT/pages/installation/advanced/advanced.adoc
@@ -26,6 +26,7 @@ We have several configuration used to influence the building 
of an integration:
 --build-publish-strategy string               Set the build publish strategy
 --build-publish-strategy-option stringArray   Add a build publish strategy 
option, as <name=value>
 --build-strategy string                       Set the build strategy
+--build-order-strategy string                 Set the build order strategy
 --build-timeout string                        Set how long the build process 
can last
 ```
 A very important set of configuration you can provide is related to Maven:
diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc 
b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
index 169451c07..aa0730185 100644
--- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
+++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
@@ -533,6 +533,13 @@ The namespace where to run the builder Pod (must be the 
same of the operator in
 
 the strategy to adopt
 
+|`orderStrategy` +
+*xref:#_camel_apache_org_v1_BuildOrderStrategy[BuildOrderStrategy]*
+|
+
+
+the build order strategy to adopt
+
 |`requestCPU` +
 string
 |
@@ -564,6 +571,16 @@ The maximum amount of memory required. Only used for `pod` 
strategy
 
 |===
 
+[#_camel_apache_org_v1_BuildOrderStrategy]
+=== BuildOrderStrategy(`string` alias)
+
+*Appears on:*
+
+* <<#_camel_apache_org_v1_BuildConfiguration, BuildConfiguration>>
+
+BuildOrderStrategy specifies how builds are reconciled and queued.
+
+
 [#_camel_apache_org_v1_BuildPhase]
 === BuildPhase(`string` alias)
 
@@ -5390,6 +5407,13 @@ string
 
 The strategy to use, either `pod` or `routine` (default routine)
 
+|`orderStrategy` +
+string
+|
+
+
+The build order strategy to use, either `fifo` or `sequential` (default 
sequential)
+
 |`requestCPU` +
 string
 |
diff --git a/docs/modules/traits/pages/builder.adoc 
b/docs/modules/traits/pages/builder.adoc
index 3ae0a7f40..298d7afba 100755
--- a/docs/modules/traits/pages/builder.adoc
+++ b/docs/modules/traits/pages/builder.adoc
@@ -40,6 +40,10 @@ The following configuration options are available:
 | string
 | The strategy to use, either `pod` or `routine` (default routine)
 
+| builder.order-strategy
+| string
+| The build order strategy to use, either `fifo` or `sequential` (default 
sequential)
+
 | builder.request-cpu
 | string
 | When using `pod` strategy, the minimum amount of CPU required by the pod 
builder.
diff --git a/e2e/builder/build_test.go b/e2e/builder/build_test.go
index ae4835f13..ccb266706 100644
--- a/e2e/builder/build_test.go
+++ b/e2e/builder/build_test.go
@@ -45,8 +45,9 @@ func TestKitMaxBuildLimit(t *testing.T) {
                createOperator(ns, "8m0s", "--global", "--force")
 
                pl := Platform(ns)()
-               // set maximum number of running builds
+               // set maximum number of running builds and order strategy
                pl.Spec.Build.MaxRunningBuilds = 2
+               pl.Spec.Build.BuildConfiguration.OrderStrategy = 
v1.BuildOrderStrategySequential
                if err := TestClient().Update(TestContext, pl); err != nil {
                        t.Error(err)
                        t.FailNow()
@@ -139,6 +140,80 @@ func TestKitMaxBuildLimit(t *testing.T) {
        })
 }
 
+func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) {
+       WithNewTestNamespace(t, func(ns string) {
+               createOperator(ns, "8m0s", "--global", "--force")
+
+               pl := Platform(ns)()
+               // set maximum number of running builds and order strategy
+               pl.Spec.Build.MaxRunningBuilds = 2
+               pl.Spec.Build.BuildConfiguration.OrderStrategy = 
v1.BuildOrderStrategyFIFO
+               if err := TestClient().Update(TestContext, pl); err != nil {
+                       t.Error(err)
+                       t.FailNow()
+               }
+
+               buildA := "integration-a"
+               buildB := "integration-b"
+               buildC := "integration-c"
+
+               doKitBuildInNamespace(buildA, ns, TestTimeoutShort, kitOptions{
+                       operatorID: fmt.Sprintf("camel-k-%s", ns),
+                       dependencies: []string{
+                               "camel:timer", "camel:log",
+                       },
+                       traits: []string{
+                               "builder.properties=build-property=A",
+                       },
+               }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning)
+
+               doKitBuildInNamespace(buildB, ns, TestTimeoutShort, kitOptions{
+                       operatorID: fmt.Sprintf("camel-k-%s", ns),
+                       dependencies: []string{
+                               "camel:timer", "camel:log",
+                       },
+                       traits: []string{
+                               "builder.properties=build-property=B",
+                       },
+               }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning)
+
+               doKitBuildInNamespace(buildC, ns, TestTimeoutShort, kitOptions{
+                       operatorID: fmt.Sprintf("camel-k-%s", ns),
+                       dependencies: []string{
+                               "camel:timer", "camel:log",
+                       },
+                       traits: []string{
+                               "builder.properties=build-property=C",
+                       },
+               }, v1.BuildPhaseScheduling, v1.IntegrationKitPhaseNone)
+
+               var notExceedsMaxBuildLimit = func(runningBuilds int) bool {
+                       return runningBuilds <= 2
+               }
+
+               limit := 0
+               for limit < 5 && BuildPhase(ns, buildA)() == 
v1.BuildPhaseRunning {
+                       // verify that number of running builds does not exceed 
max build limit
+                       Consistently(BuildsRunning(BuildPhase(ns, buildA), 
BuildPhase(ns, buildB), BuildPhase(ns, buildC)), TestTimeoutShort, 
10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit))
+                       limit++
+               }
+
+               // make sure we have verified max build limit at least once
+               if limit == 0 {
+                       t.Error(errors.New(fmt.Sprintf("Unexpected build phase 
'%s' for %s - not able to verify max builds limit", BuildPhase(ns, buildA)(), 
buildA)))
+                       t.FailNow()
+               }
+
+               // verify that all builds are successful
+               Eventually(BuildPhase(ns, buildA), 
TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+               Eventually(KitPhase(ns, buildA), 
TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+               Eventually(BuildPhase(ns, buildB), 
TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+               Eventually(KitPhase(ns, buildB), 
TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+               Eventually(BuildPhase(ns, buildC), 
TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
+               Eventually(KitPhase(ns, buildC), 
TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
+       })
+}
+
 func TestKitTimerToLogFullBuild(t *testing.T) {
        doKitFullBuild(t, "timer-to-log", "8m0s", TestTimeoutLong, kitOptions{
                dependencies: []string{
diff --git a/e2e/common/traits/builder_test.go 
b/e2e/common/traits/builder_test.go
index f876a2445..d940aad83 100644
--- a/e2e/common/traits/builder_test.go
+++ b/e2e/common/traits/builder_test.go
@@ -37,9 +37,8 @@ import (
 func TestBuilderTrait(t *testing.T) {
        RegisterTestingT(t)
 
-       name := "java"
-
        t.Run("Run build strategy routine", func(t *testing.T) {
+               name := "java"
                Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
                        "--name", name,
                        "-t", 
"builder.strategy=routine").Execute()).To(Succeed())
@@ -51,6 +50,33 @@ func TestBuilderTrait(t *testing.T) {
                integrationKitName := IntegrationKit(ns, name)()
                builderKitName := fmt.Sprintf("camel-k-%s-builder", 
integrationKitName)
                Eventually(BuildConfig(ns, integrationKitName)().Strategy, 
TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine))
+               Eventually(BuildConfig(ns, integrationKitName)().OrderStrategy, 
TestTimeoutShort).Should(Equal(v1.BuildOrderStrategySequential))
+               // Default resource CPU Check
+               Eventually(BuildConfig(ns, integrationKitName)().RequestCPU, 
TestTimeoutShort).Should(Equal(""))
+               Eventually(BuildConfig(ns, integrationKitName)().LimitCPU, 
TestTimeoutShort).Should(Equal(""))
+               Eventually(BuildConfig(ns, integrationKitName)().RequestMemory, 
TestTimeoutShort).Should(Equal(""))
+               Eventually(BuildConfig(ns, integrationKitName)().LimitMemory, 
TestTimeoutShort).Should(Equal(""))
+
+               Eventually(BuilderPod(ns, builderKitName), 
TestTimeoutShort).Should(BeNil())
+
+               // We need to remove the kit as well
+               Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed())
+       })
+
+       t.Run("Run build order strategy fifo", func(t *testing.T) {
+               name := "java-fifo-strategy"
+               Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+                       "--name", name,
+                       "-t", 
"builder.order-strategy=fifo").Execute()).To(Succeed())
+
+               Eventually(IntegrationPodPhase(ns, name), 
TestTimeoutLong).Should(Equal(corev1.PodRunning))
+               Eventually(IntegrationConditionStatus(ns, name, 
v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+               Eventually(IntegrationLogs(ns, name), 
TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+               integrationKitName := IntegrationKit(ns, name)()
+               builderKitName := fmt.Sprintf("camel-k-%s-builder", 
integrationKitName)
+               Eventually(BuildConfig(ns, integrationKitName)().Strategy, 
TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine))
+               Eventually(BuildConfig(ns, integrationKitName)().OrderStrategy, 
TestTimeoutShort).Should(Equal(v1.BuildOrderStrategyFIFO))
                // Default resource CPU Check
                Eventually(BuildConfig(ns, integrationKitName)().RequestCPU, 
TestTimeoutShort).Should(Equal(""))
                Eventually(BuildConfig(ns, integrationKitName)().LimitCPU, 
TestTimeoutShort).Should(Equal(""))
@@ -64,6 +90,7 @@ func TestBuilderTrait(t *testing.T) {
        })
 
        t.Run("Run build resources configuration", func(t *testing.T) {
+               name := "java-resource-config"
                Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
                        "--name", name,
                        "-t", "builder.request-cpu=500m",
@@ -81,6 +108,7 @@ func TestBuilderTrait(t *testing.T) {
                builderKitName := fmt.Sprintf("camel-k-%s-builder", 
integrationKitName)
 
                Eventually(BuildConfig(ns, integrationKitName)().Strategy, 
TestTimeoutShort).Should(Equal(v1.BuildStrategyPod))
+               Eventually(BuildConfig(ns, integrationKitName)().OrderStrategy, 
TestTimeoutShort).Should(Equal(v1.BuildOrderStrategySequential))
                Eventually(BuildConfig(ns, integrationKitName)().RequestCPU, 
TestTimeoutShort).Should(Equal("500m"))
                Eventually(BuildConfig(ns, integrationKitName)().LimitCPU, 
TestTimeoutShort).Should(Equal("1000m"))
                Eventually(BuildConfig(ns, integrationKitName)().RequestMemory, 
TestTimeoutShort).Should(Equal("2Gi"))
@@ -98,6 +126,7 @@ func TestBuilderTrait(t *testing.T) {
        })
 
        t.Run("Run custom pipeline task", func(t *testing.T) {
+               name := "java-pipeline"
                Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
                        "--name", name,
                        "-t", "builder.tasks=custom1;alpine;tree",
@@ -141,8 +170,8 @@ func TestBuilderTrait(t *testing.T) {
                Expect(Kamel("delete", "--all", "-n", 
ns).Execute()).To(Succeed())
        })
 
-       name = "java-error"
        t.Run("Run custom pipeline task error", func(t *testing.T) {
+               name := "java-error"
                Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
                        "--name", name,
                        "-t", "builder.tasks=custom1;alpine;cat 
missingfile.txt",
diff --git a/e2e/commonwithcustominstall/local_platform_test.go 
b/e2e/commonwithcustominstall/local_platform_test.go
index 05ce8c3b7..2f924ac20 100644
--- a/e2e/commonwithcustominstall/local_platform_test.go
+++ b/e2e/commonwithcustominstall/local_platform_test.go
@@ -82,6 +82,7 @@ func TestLocalPlatform(t *testing.T) {
                        local := Platform(ns1)()
                        
Expect(local.Status.Build.PublishStrategy).To(Equal(pl.Status.Build.PublishStrategy))
                        
Expect(local.Status.Build.BuildConfiguration.Strategy).To(Equal(pl.Status.Build.BuildConfiguration.Strategy))
+                       
Expect(local.Status.Build.BuildConfiguration.OrderStrategy).To(Equal(pl.Status.Build.BuildConfiguration.OrderStrategy))
                        
Expect(local.Status.Build.Maven.LocalRepository).To(Equal(pl.Status.Build.Maven.LocalRepository))
                        
Expect(local.Status.Build.Maven.CLIOptions).To(ContainElements(pl.Status.Build.Maven.CLIOptions))
                        Expect(local.Status.Build.Maven.Extension).To(BeEmpty())
diff --git a/helm/camel-k/crds/crd-build.yaml b/helm/camel-k/crds/crd-build.yaml
index 9e525152b..44ee86332 100644
--- a/helm/camel-k/crds/crd-build.yaml
+++ b/helm/camel-k/crds/crd-build.yaml
@@ -97,6 +97,12 @@ spec:
                     description: The namespace where to run the builder Pod 
(must
                       be the same of the operator in charge of this Build 
reconciliation).
                     type: string
+                  orderStrategy:
+                    description: the build order strategy to adopt
+                    enum:
+                    - fifo
+                    - sequential
+                    type: string
                   requestCPU:
                     description: The minimum amount of CPU required. Only used 
for
                       `pod` strategy
@@ -206,6 +212,12 @@ spec:
                                 Pod (must be the same of the operator in 
charge of
                                 this Build reconciliation).
                               type: string
+                            orderStrategy:
+                              description: the build order strategy to adopt
+                              enum:
+                              - fifo
+                              - sequential
+                              type: string
                             requestCPU:
                               description: The minimum amount of CPU required. 
Only
                                 used for `pod` strategy
diff --git a/helm/camel-k/crds/crd-integration-kit.yaml 
b/helm/camel-k/crds/crd-integration-kit.yaml
index 8ff5668a5..39fccd088 100644
--- a/helm/camel-k/crds/crd-integration-kit.yaml
+++ b/helm/camel-k/crds/crd-integration-kit.yaml
@@ -211,6 +211,10 @@ spec:
                         description: When using `pod` strategy, the maximum 
amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either 
`fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to 
the build
                           task
diff --git a/helm/camel-k/crds/crd-integration-platform.yaml 
b/helm/camel-k/crds/crd-integration-platform.yaml
index 080b76618..1d716f3e6 100644
--- a/helm/camel-k/crds/crd-integration-platform.yaml
+++ b/helm/camel-k/crds/crd-integration-platform.yaml
@@ -116,6 +116,12 @@ spec:
                         description: The namespace where to run the builder 
Pod (must
                           be the same of the operator in charge of this Build 
reconciliation).
                         type: string
+                      orderStrategy:
+                        description: the build order strategy to adopt
+                        enum:
+                        - fifo
+                        - sequential
+                        type: string
                       requestCPU:
                         description: The minimum amount of CPU required. Only 
used
                           for `pod` strategy
@@ -462,6 +468,10 @@ spec:
                         description: When using `pod` strategy, the maximum 
amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either 
`fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to 
the build
                           task
@@ -1753,6 +1763,12 @@ spec:
                         description: The namespace where to run the builder 
Pod (must
                           be the same of the operator in charge of this Build 
reconciliation).
                         type: string
+                      orderStrategy:
+                        description: the build order strategy to adopt
+                        enum:
+                        - fifo
+                        - sequential
+                        type: string
                       requestCPU:
                         description: The minimum amount of CPU required. Only 
used
                           for `pod` strategy
@@ -2147,6 +2163,10 @@ spec:
                         description: When using `pod` strategy, the maximum 
amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either 
`fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to 
the build
                           task
diff --git a/helm/camel-k/crds/crd-integration.yaml 
b/helm/camel-k/crds/crd-integration.yaml
index 0912bebc7..6106dc086 100644
--- a/helm/camel-k/crds/crd-integration.yaml
+++ b/helm/camel-k/crds/crd-integration.yaml
@@ -6194,6 +6194,10 @@ spec:
                         description: When using `pod` strategy, the maximum 
amount
                           of memory required by the pod builder.
                         type: string
+                      orderStrategy:
+                        description: The build order strategy to use, either 
`fifo`
+                          or `sequential` (default sequential)
+                        type: string
                       properties:
                         description: A list of properties to be provided to 
the build
                           task
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml 
b/helm/camel-k/crds/crd-kamelet-binding.yaml
index 93b4eba21..2ffcbaff3 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -6469,6 +6469,10 @@ spec:
                             description: When using `pod` strategy, the 
maximum amount
                               of memory required by the pod builder.
                             type: string
+                          orderStrategy:
+                            description: The build order strategy to use, 
either `fifo`
+                              or `sequential` (default sequential)
+                            type: string
                           properties:
                             description: A list of properties to be provided 
to the
                               build task
diff --git a/helm/camel-k/crds/crd-pipe.yaml b/helm/camel-k/crds/crd-pipe.yaml
index 6b166be6b..4da7c6ade 100644
--- a/helm/camel-k/crds/crd-pipe.yaml
+++ b/helm/camel-k/crds/crd-pipe.yaml
@@ -6466,6 +6466,10 @@ spec:
                             description: When using `pod` strategy, the 
maximum amount
                               of memory required by the pod builder.
                             type: string
+                          orderStrategy:
+                            description: The build order strategy to use, 
either `fifo`
+                              or `sequential` (default sequential)
+                            type: string
                           properties:
                             description: A list of properties to be provided 
to the
                               build task
diff --git a/pkg/apis/camel/v1/build_types_support.go 
b/pkg/apis/camel/v1/build_types_support.go
index 6131f909b..8c05f66e7 100644
--- a/pkg/apis/camel/v1/build_types_support.go
+++ b/pkg/apis/camel/v1/build_types_support.go
@@ -201,3 +201,28 @@ func (c BuildCondition) GetReason() string {
 func (c BuildCondition) GetMessage() string {
        return c.Message
 }
+
+func (bl BuildList) HasRunningBuilds() bool {
+       for _, b := range bl.Items {
+               if b.Status.Phase == BuildPhasePending || b.Status.Phase == 
BuildPhaseRunning {
+                       return true
+               }
+       }
+
+       return false
+}
+
+func (bl BuildList) HasScheduledBuildsBefore(build *Build) bool {
+       for _, b := range bl.Items {
+               if b.Name == build.Name {
+                       continue
+               }
+
+               if (b.Status.Phase == BuildPhaseInitialization || 
b.Status.Phase == BuildPhaseScheduling) &&
+                       b.CreationTimestamp.Before(&build.CreationTimestamp) {
+                       return true
+               }
+       }
+
+       return false
+}
diff --git a/pkg/apis/camel/v1/common_types.go 
b/pkg/apis/camel/v1/common_types.go
index 4a4aaa2cf..979cd2a87 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -43,6 +43,8 @@ type BuildConfiguration struct {
        BuilderPodNamespace string `json:"operatorNamespace,omitempty"`
        // the strategy to adopt
        Strategy BuildStrategy `property:"strategy" json:"strategy,omitempty"`
+       // the build order strategy to adopt
+       OrderStrategy BuildOrderStrategy `property:"order-strategy" 
json:"orderStrategy,omitempty"`
        // The minimum amount of CPU required. Only used for `pod` strategy
        RequestCPU string `property:"request-cpu" json:"requestCPU,omitempty"`
        // The minimum amount of memory required. Only used for `pod` strategy
@@ -70,6 +72,12 @@ const (
        // mitigated by the presence of a Maven proxy.
        // Available for both Quarkus JVM and Native mode.
        BuildStrategyPod BuildStrategy = "pod"
+
+       // BuildOrderStrategyFIFO performs the builds with first in first out 
strategy based on the creation timestamp.
+       // The strategy allows builds to run in parallel to each other but 
oldest builds will be run first.
+       BuildOrderStrategyFIFO BuildOrderStrategy = "fifo"
+       // BuildOrderStrategySequential runs builds strictly sequential so that 
only one single build per operator namespace is running at a time.
+       BuildOrderStrategySequential BuildOrderStrategy = "sequential"
 )
 
 // BuildStrategies is a list of strategies allowed for the build
@@ -78,6 +86,16 @@ var BuildStrategies = []BuildStrategy{
        BuildStrategyPod,
 }
 
+// BuildOrderStrategy specifies how builds are reconciled and queued.
+// +kubebuilder:validation:Enum=fifo;sequential
+type BuildOrderStrategy string
+
+// BuildOrderStrategies is a list of order strategies allowed for the build
+var BuildOrderStrategies = []BuildOrderStrategy{
+       BuildOrderStrategyFIFO,
+       BuildOrderStrategySequential,
+}
+
 // ConfigurationSpec represents a generic configuration specification
 type ConfigurationSpec struct {
        // represents the type of configuration, ie: property, configmap, 
secret, ...
diff --git a/pkg/apis/camel/v1/common_types_support.go 
b/pkg/apis/camel/v1/common_types_support.go
index b66dca9a8..6b48170d3 100644
--- a/pkg/apis/camel/v1/common_types_support.go
+++ b/pkg/apis/camel/v1/common_types_support.go
@@ -159,6 +159,7 @@ var _ json.Unmarshaler = (*RawMessage)(nil)
 // IsEmpty -- .
 func (bc *BuildConfiguration) IsEmpty() bool {
        return bc.Strategy == "" &&
+               bc.OrderStrategy == "" &&
                bc.RequestCPU == "" &&
                bc.RequestMemory == "" &&
                bc.LimitCPU == "" &&
diff --git a/pkg/apis/camel/v1/trait/builder.go 
b/pkg/apis/camel/v1/trait/builder.go
index 6bfe96546..86e682ab3 100644
--- a/pkg/apis/camel/v1/trait/builder.go
+++ b/pkg/apis/camel/v1/trait/builder.go
@@ -29,6 +29,8 @@ type BuilderTrait struct {
        Properties []string `property:"properties" json:"properties,omitempty"`
        // The strategy to use, either `pod` or `routine` (default routine)
        Strategy string `property:"strategy" json:"strategy,omitempty"`
+       // The build order strategy to use, either `fifo` or `sequential` 
(default sequential)
+       OrderStrategy string `property:"order-strategy" 
json:"orderStrategy,omitempty"`
        // When using `pod` strategy, the minimum amount of CPU required by the 
pod builder.
        RequestCPU string `property:"request-cpu" json:"requestCPU,omitempty"`
        // When using `pod` strategy, the minimum amount of memory required by 
the pod builder.
diff --git a/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go 
b/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go
index 581db6aa5..7aa865add 100644
--- a/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go
+++ b/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go
@@ -26,13 +26,14 @@ import (
 // BuildConfigurationApplyConfiguration represents an declarative 
configuration of the BuildConfiguration type for use
 // with apply.
 type BuildConfigurationApplyConfiguration struct {
-       ToolImage           *string           `json:"toolImage,omitempty"`
-       BuilderPodNamespace *string           
`json:"operatorNamespace,omitempty"`
-       Strategy            *v1.BuildStrategy `json:"strategy,omitempty"`
-       RequestCPU          *string           `json:"requestCPU,omitempty"`
-       RequestMemory       *string           `json:"requestMemory,omitempty"`
-       LimitCPU            *string           `json:"limitCPU,omitempty"`
-       LimitMemory         *string           `json:"limitMemory,omitempty"`
+       ToolImage           *string                `json:"toolImage,omitempty"`
+       BuilderPodNamespace *string                
`json:"operatorNamespace,omitempty"`
+       Strategy            *v1.BuildStrategy      `json:"strategy,omitempty"`
+       OrderStrategy       *v1.BuildOrderStrategy 
`json:"orderStrategy,omitempty"`
+       RequestCPU          *string                `json:"requestCPU,omitempty"`
+       RequestMemory       *string                
`json:"requestMemory,omitempty"`
+       LimitCPU            *string                `json:"limitCPU,omitempty"`
+       LimitMemory         *string                
`json:"limitMemory,omitempty"`
 }
 
 // BuildConfigurationApplyConfiguration constructs an declarative 
configuration of the BuildConfiguration type for use with
@@ -65,6 +66,14 @@ func (b *BuildConfigurationApplyConfiguration) 
WithStrategy(value v1.BuildStrate
        return b
 }
 
+// WithOrderStrategy sets the OrderStrategy field in the declarative 
configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" 
function invocations.
+// If called multiple times, the OrderStrategy field is set to the value of 
the last call.
+func (b *BuildConfigurationApplyConfiguration) WithOrderStrategy(value 
v1.BuildOrderStrategy) *BuildConfigurationApplyConfiguration {
+       b.OrderStrategy = &value
+       return b
+}
+
 // WithRequestCPU sets the RequestCPU field in the declarative configuration 
to the given value
 // and returns the receiver, so that objects can be built by chaining "With" 
function invocations.
 // If called multiple times, the RequestCPU field is set to the value of the 
last call.
diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index cf68324c8..6a4f3bd08 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -107,6 +107,7 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) 
(*cobra.Command, *installCmdO
        cmd.Flags().String("operator-image", "", "Set the operator Image used 
for the operator deployment")
        cmd.Flags().String("operator-image-pull-policy", "", "Set the operator 
ImagePullPolicy used for the operator deployment")
        cmd.Flags().String("build-strategy", "", "Set the build strategy")
+       cmd.Flags().String("build-order-strategy", "", "Set the build order 
strategy")
        cmd.Flags().String("build-publish-strategy", "", "Set the build publish 
strategy")
        cmd.Flags().StringArray("build-publish-strategy-option", nil, "Add a 
build publish strategy option, as <name=value>")
        cmd.Flags().String("build-timeout", "", "Set how long the build process 
can last")
@@ -181,6 +182,7 @@ type installCmdOptions struct {
        OperatorImage               string   `mapstructure:"operator-image"`
        OperatorImagePullPolicy     string   
`mapstructure:"operator-image-pull-policy"`
        BuildStrategy               string   `mapstructure:"build-strategy"`
+       BuildOrderStrategy          string   
`mapstructure:"build-order-strategy"`
        BuildPublishStrategy        string   
`mapstructure:"build-publish-strategy"`
        BuildPublishStrategyOptions []string 
`mapstructure:"build-publish-strategy-options"`
        BuildTimeout                string   `mapstructure:"build-timeout"`
@@ -524,6 +526,9 @@ func (o *installCmdOptions) setupIntegrationPlatform(c 
client.Client, namespace
        if o.BuildStrategy != "" {
                platform.Spec.Build.BuildConfiguration.Strategy = 
v1.BuildStrategy(o.BuildStrategy)
        }
+       if o.BuildOrderStrategy != "" {
+               platform.Spec.Build.BuildConfiguration.OrderStrategy = 
v1.BuildOrderStrategy(o.BuildOrderStrategy)
+       }
        if o.BuildPublishStrategy != "" {
                platform.Spec.Build.PublishStrategy = 
v1.IntegrationPlatformBuildPublishStrategy(o.BuildPublishStrategy)
        }
@@ -749,6 +754,23 @@ func (o *installCmdOptions) validate(_ *cobra.Command, _ 
[]string) error {
                }
        }
 
+       if o.BuildOrderStrategy != "" {
+               found := false
+               for _, s := range v1.BuildOrderStrategies {
+                       if string(s) == o.BuildOrderStrategy {
+                               found = true
+                               break
+                       }
+               }
+               if !found {
+                       var strategies []string
+                       for _, s := range v1.BuildOrderStrategies {
+                               strategies = append(strategies, string(s))
+                       }
+                       return fmt.Errorf("unknown build order strategy: %s. 
One of [%s] is expected", o.BuildOrderStrategy, strings.Join(strategies, ", "))
+               }
+       }
+
        if o.BuildPublishStrategy != "" {
                found := false
                for _, s := range v1.IntegrationPlatformBuildPublishStrategies {
diff --git a/pkg/cmd/install_test.go b/pkg/cmd/install_test.go
index fcfdb8ecd..aacc8824b 100644
--- a/pkg/cmd/install_test.go
+++ b/pkg/cmd/install_test.go
@@ -107,6 +107,13 @@ func TestInstallBuildStrategyFlag(t *testing.T) {
        assert.Equal(t, "someString", installCmdOptions.BuildStrategy)
 }
 
+func TestInstallBuildOrderStrategyFlag(t *testing.T) {
+       installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t)
+       _, err := test.ExecuteCommand(rootCmd, cmdInstall, 
"--build-order-strategy", "someString")
+       assert.Nil(t, err)
+       assert.Equal(t, "someString", installCmdOptions.BuildOrderStrategy)
+}
+
 func TestInstallBuildTimeoutFlag(t *testing.T) {
        installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t)
        _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--build-timeout", 
"10")
diff --git a/pkg/controller/build/build_controller.go 
b/pkg/controller/build/build_controller.go
index 33fe525d8..75439a3d2 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -147,7 +147,8 @@ func (r *reconcileBuild) Reconcile(ctx context.Context, 
request reconcile.Reques
                return reconcile.Result{}, err
        }
        buildMonitor := Monitor{
-               maxRunningBuilds: ip.Status.Build.MaxRunningBuilds,
+               maxRunningBuilds:   ip.Status.Build.MaxRunningBuilds,
+               buildOrderStrategy: 
ip.Status.Build.BuildConfiguration.OrderStrategy,
        }
 
        switch instance.BuilderConfiguration().Strategy {
diff --git a/pkg/controller/build/build_monitor.go 
b/pkg/controller/build/build_monitor.go
index 521dd6b86..a60ce1b3a 100644
--- a/pkg/controller/build/build_monitor.go
+++ b/pkg/controller/build/build_monitor.go
@@ -33,7 +33,8 @@ import (
 var runningBuilds sync.Map
 
 type Monitor struct {
-       maxRunningBuilds int32
+       maxRunningBuilds   int32
+       buildOrderStrategy v1.BuildOrderStrategy
 }
 
 func (bm *Monitor) canSchedule(ctx context.Context, c ctrl.Reader, build 
*v1.Build) (bool, error) {
@@ -43,15 +44,15 @@ func (bm *Monitor) canSchedule(ctx context.Context, c 
ctrl.Reader, build *v1.Bui
                return true
        })
 
-       if runningBuildsTotal >= bm.maxRunningBuilds {
-               requestName := build.Name
-               requestNamespace := build.Namespace
-               buildCreator := kubernetes.GetCamelCreator(build)
-               if buildCreator != nil {
-                       requestName = buildCreator.Name
-                       requestNamespace = buildCreator.Namespace
-               }
+       requestName := build.Name
+       requestNamespace := build.Namespace
+       buildCreator := kubernetes.GetCamelCreator(build)
+       if buildCreator != nil {
+               requestName = buildCreator.Name
+               requestNamespace = buildCreator.Namespace
+       }
 
+       if runningBuildsTotal >= bm.maxRunningBuilds {
                Log.WithValues("request-namespace", requestNamespace, 
"request-name", requestName, "max-running-builds-limit", runningBuildsTotal).
                        ForBuild(build).Infof("Maximum number of running builds 
(%d) exceeded - the build gets enqueued", runningBuildsTotal)
 
@@ -84,18 +85,22 @@ func (bm *Monitor) canSchedule(ctx context.Context, c 
ctrl.Reader, build *v1.Bui
                return false, err
        }
 
-       // Emulate a serialized working queue to only allow one build to run at 
a given time.
-       // This is currently necessary for the incremental build to work as 
expected.
-       // We may want to explicitly manage build priority as opposed to 
relying on
-       // the reconciliation loop to handle the queuing.
-       for _, b := range builds.Items {
-               if b.Status.Phase == v1.BuildPhasePending || b.Status.Phase == 
v1.BuildPhaseRunning {
-                       // Let's requeue the build in case one is already 
running
-                       return false, nil
-               }
+       var allowed bool
+       switch bm.buildOrderStrategy {
+       case v1.BuildOrderStrategyFIFO:
+               // Check on builds that have been created before the current 
build and grant precedence if any.
+               allowed = !builds.HasScheduledBuildsBefore(build)
+       case v1.BuildOrderStrategySequential:
+               // Emulate a serialized working queue to only allow one build 
to run at a given time.
+               // Let's requeue the build in case one is already running
+               allowed = !builds.HasRunningBuilds()
+       default:
+               Log.WithValues("request-namespace", requestNamespace, 
"request-name", requestName, "order-strategy", bm.buildOrderStrategy).
+                       ForBuild(build).Infof("Unsupported build order strategy 
(%s) - the build gets enqueued", bm.buildOrderStrategy)
+               allowed = false
        }
 
-       return true, nil
+       return allowed, nil
 }
 
 func monitorRunningBuild(build *v1.Build) {
diff --git a/pkg/controller/build/build_monitor_test.go 
b/pkg/controller/build/build_monitor_test.go
index 0dd4ee2d3..b44cd0533 100644
--- a/pkg/controller/build/build_monitor_test.go
+++ b/pkg/controller/build/build_monitor_test.go
@@ -30,7 +30,7 @@ import (
        "k8s.io/apimachinery/pkg/runtime"
 )
 
-func TestMonitorBuilds(t *testing.T) {
+func TestMonitorSequentialBuilds(t *testing.T) {
        testcases := []struct {
                name     string
                running  []*v1.Build
@@ -49,7 +49,7 @@ func TestMonitorBuilds(t *testing.T) {
                        name:     "allowNewNativeBuild",
                        running:  []*v1.Build{},
                        finished: []*v1.Build{},
-                       build:    newNativeBuild("ns", "my-build"),
+                       build:    newNativeBuild("ns", "my-native-build"),
                        allowed:  true,
                },
                {
@@ -69,7 +69,7 @@ func TestMonitorBuilds(t *testing.T) {
                                newNativeBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
                                newNativeBuildInPhase("ns", "my-build-failed", 
v1.BuildPhaseFailed),
                        },
-                       build:   newNativeBuild("ns", "my-build"),
+                       build:   newNativeBuild("ns", "my-native-build"),
                        allowed: true,
                },
                {
@@ -144,7 +144,8 @@ func TestMonitorBuilds(t *testing.T) {
                        assert.Nil(t, err)
 
                        bm := Monitor{
-                               maxRunningBuilds: 3,
+                               maxRunningBuilds:   3,
+                               buildOrderStrategy: 
v1.BuildOrderStrategySequential,
                        }
 
                        // reset running builds in memory cache
@@ -167,7 +168,8 @@ func TestAllowBuildRequeue(t *testing.T) {
        assert.Nil(t, err)
 
        bm := Monitor{
-               maxRunningBuilds: 3,
+               maxRunningBuilds:   3,
+               buildOrderStrategy: v1.BuildOrderStrategySequential,
        }
 
        runningBuild := newBuild("some-ns", "my-build-1")
@@ -191,6 +193,165 @@ func TestAllowBuildRequeue(t *testing.T) {
        assert.True(t, allowed)
 }
 
+func TestMonitorFIFOBuilds(t *testing.T) {
+       testcases := []struct {
+               name    string
+               running []*v1.Build
+               builds  []*v1.Build
+               build   *v1.Build
+               allowed bool
+       }{
+               {
+                       name:    "allowNewBuild",
+                       running: []*v1.Build{},
+                       builds:  []*v1.Build{},
+                       build:   newBuild("ns", "my-build"),
+                       allowed: true,
+               },
+               {
+                       name:    "allowNewNativeBuild",
+                       running: []*v1.Build{},
+                       builds:  []*v1.Build{},
+                       build:   newNativeBuild("ns1", "my-build"),
+                       allowed: true,
+               },
+               {
+                       name:    "allowNewBuildWhenOthersFinished",
+                       running: []*v1.Build{},
+                       builds: []*v1.Build{
+                               newBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
+                               newBuildInPhase("ns", "my-build-failed", 
v1.BuildPhaseFailed),
+                       },
+                       build:   newBuild("ns", "my-build"),
+                       allowed: true,
+               },
+               {
+                       name:    "allowNewNativeBuildWhenOthersFinished",
+                       running: []*v1.Build{},
+                       builds: []*v1.Build{
+                               newNativeBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
+                               newNativeBuildInPhase("ns", "my-build-failed", 
v1.BuildPhaseFailed),
+                       },
+                       build:   newNativeBuild("ns", "my-build"),
+                       allowed: true,
+               },
+               {
+                       name: "limitMaxRunningBuilds",
+                       running: []*v1.Build{
+                               newBuild("some-ns", "my-build-1"),
+                               newBuild("other-ns", "my-build-2"),
+                               newBuild("another-ns", "my-build-3"),
+                       },
+                       builds: []*v1.Build{
+                               newBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
+                       },
+                       build:   newBuild("ns", "my-build"),
+                       allowed: false,
+               },
+               {
+                       name: "limitMaxRunningNativeBuilds",
+                       running: []*v1.Build{
+                               newBuildInPhase("some-ns", "my-build-1", 
v1.BuildPhaseRunning),
+                               newNativeBuildInPhase("other-ns", "my-build-2", 
v1.BuildPhaseRunning),
+                               newNativeBuildInPhase("another-ns", 
"my-build-3", v1.BuildPhaseRunning),
+                       },
+                       builds: []*v1.Build{
+                               newNativeBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
+                       },
+                       build:   newNativeBuildInPhase("ns", "my-build", 
v1.BuildPhaseInitialization),
+                       allowed: false,
+               },
+               {
+                       name: "allowParallelBuildsWithDifferentLayout",
+                       running: []*v1.Build{
+                               newNativeBuildInPhase("ns", "my-build-1", 
v1.BuildPhaseRunning),
+                       },
+                       build:   newBuild("ns", "my-build"),
+                       allowed: true,
+               },
+               {
+                       name: "allowParallelBuildsInSameNamespace",
+                       running: []*v1.Build{
+                               newBuild("ns", "my-build-1"),
+                               newBuild("other-ns", "my-build-2"),
+                       },
+                       builds: []*v1.Build{
+                               newBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
+                               newBuildInPhase("other-ns", "my-build-new", 
v1.BuildPhaseScheduling),
+                       },
+                       build:   newBuild("ns", "my-build"),
+                       allowed: true,
+               },
+               {
+                       name: "queueBuildWhenOlderBuildIsAlreadyInitialized",
+                       running: []*v1.Build{
+                               newBuild("ns", "my-build-1"),
+                               newBuild("other-ns", "my-build-2"),
+                       },
+                       builds: []*v1.Build{
+                               newBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
+                               newBuildInPhase("ns", "my-build-new", 
v1.BuildPhaseInitialization),
+                       },
+                       build:   newBuild("ns", "my-build"),
+                       allowed: false,
+               },
+               {
+                       name: "queueBuildWhenOlderBuildIsAlreadyScheduled",
+                       running: []*v1.Build{
+                               newBuild("ns", "my-build-1"),
+                               newBuild("other-ns", "my-build-2"),
+                       },
+                       builds: []*v1.Build{
+                               newBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
+                               newBuildInPhase("ns", "my-build-new", 
v1.BuildPhaseScheduling),
+                       },
+                       build:   newBuild("ns", "my-build"),
+                       allowed: false,
+               },
+               {
+                       name: "allowBuildsInNewNamespace",
+                       running: []*v1.Build{
+                               newBuild("some-ns", "my-build-1"),
+                               newBuild("other-ns", "my-build-2"),
+                       },
+                       builds: []*v1.Build{
+                               newBuildInPhase("ns", "my-build-x", 
v1.BuildPhaseSucceeded),
+                       },
+                       build:   newBuild("ns", "my-build"),
+                       allowed: true,
+               },
+       }
+
+       for _, tc := range testcases {
+               t.Run(tc.name, func(t *testing.T) {
+                       var initObjs []runtime.Object
+                       for _, build := range append(tc.running, tc.builds...) {
+                               initObjs = append(initObjs, build)
+                       }
+
+                       c, err := test.NewFakeClient(initObjs...)
+
+                       assert.Nil(t, err)
+
+                       bm := Monitor{
+                               maxRunningBuilds:   3,
+                               buildOrderStrategy: v1.BuildOrderStrategyFIFO,
+                       }
+
+                       // reset running builds in memory cache
+                       cleanRunningBuildsMonitor()
+                       for _, build := range tc.running {
+                               monitorRunningBuild(build)
+                       }
+
+                       allowed, err := bm.canSchedule(context.TODO(), c, 
tc.build)
+
+                       assert.Nil(t, err)
+                       assert.Equal(t, tc.allowed, allowed)
+               })
+       }
+}
+
 func cleanRunningBuildsMonitor() {
        runningBuilds.Range(func(key interface{}, v interface{}) bool {
                runningBuilds.Delete(key)
@@ -226,6 +387,7 @@ func newBuildWithLayoutInPhase(namespace string, name 
string, layout string, pha
                        Labels: map[string]string{
                                v1.IntegrationKitLayoutLabel: layout,
                        },
+                       CreationTimestamp: metav1.NewTime(time.Now()),
                },
                Spec: v1.BuildSpec{
                        Tasks: []v1.Task{
@@ -233,6 +395,7 @@ func newBuildWithLayoutInPhase(namespace string, name 
string, layout string, pha
                                        Builder: &v1.BuilderTask{
                                                Configuration: 
v1.BuildConfiguration{
                                                        Strategy:            
v1.BuildStrategyRoutine,
+                                                       OrderStrategy:       
v1.BuildOrderStrategySequential,
                                                        ToolImage:           
"camel:latest",
                                                        BuilderPodNamespace: 
"ns",
                                                },
diff --git a/pkg/controller/integrationkit/build.go 
b/pkg/controller/integrationkit/build.go
index 75228c041..d4b49fa97 100644
--- a/pkg/controller/integrationkit/build.go
+++ b/pkg/controller/integrationkit/build.go
@@ -113,9 +113,16 @@ func (action *buildAction) handleBuildSubmitted(ctx 
context.Context, kit *v1.Int
                if buildConfig.IsEmpty() {
                        // default to IntegrationPlatform configuration
                        buildConfig = 
&env.Platform.Status.Build.BuildConfiguration
-               } else if buildConfig.Strategy == "" {
-                       // we always need to define a strategy, so we default 
to platform if none
-                       buildConfig.Strategy = 
env.Platform.Status.Build.BuildConfiguration.Strategy
+               } else {
+                       if buildConfig.Strategy == "" {
+                               // we always need to define a strategy, so we 
default to platform if none
+                               buildConfig.Strategy = 
env.Platform.Status.Build.BuildConfiguration.Strategy
+                       }
+
+                       if buildConfig.OrderStrategy == "" {
+                               // we always need to define an order strategy, 
so we default to platform if none
+                               buildConfig.OrderStrategy = 
env.Platform.Status.Build.BuildConfiguration.OrderStrategy
+                       }
                }
 
                // nolint: contextcheck
diff --git a/pkg/platform/defaults.go b/pkg/platform/defaults.go
index 7504c195b..a7711e4cc 100644
--- a/pkg/platform/defaults.go
+++ b/pkg/platform/defaults.go
@@ -97,6 +97,11 @@ func ConfigureDefaults(ctx context.Context, c client.Client, 
p *v1.IntegrationPl
                log.Debugf("Integration Platform %s [%s]: setting build 
strategy %s", p.Name, p.Namespace, p.Status.Build.BuildConfiguration.Strategy)
        }
 
+       if p.Status.Build.BuildConfiguration.OrderStrategy == "" {
+               p.Status.Build.BuildConfiguration.OrderStrategy = 
v1.BuildOrderStrategySequential
+               log.Debugf("Integration Platform %s [%s]: setting build order 
strategy %s", p.Name, p.Namespace, 
p.Status.Build.BuildConfiguration.OrderStrategy)
+       }
+
        err := setPlatformDefaults(p, verbose)
        if err != nil {
                return err
@@ -237,6 +242,10 @@ func applyPlatformSpec(source *v1.IntegrationPlatform, 
target *v1.IntegrationPla
                target.Status.Build.BuildConfiguration.Strategy = 
source.Status.Build.BuildConfiguration.Strategy
        }
 
+       if target.Status.Build.BuildConfiguration.OrderStrategy == "" {
+               target.Status.Build.BuildConfiguration.OrderStrategy = 
source.Status.Build.BuildConfiguration.OrderStrategy
+       }
+
        if target.Status.Build.RuntimeVersion == "" {
                log.Debugf("Integration Platform %s [%s]: setting runtime 
version", target.Name, target.Namespace)
                target.Status.Build.RuntimeVersion = 
source.Status.Build.RuntimeVersion
diff --git a/pkg/platform/defaults_test.go b/pkg/platform/defaults_test.go
index b2a51fb22..d73b99af2 100644
--- a/pkg/platform/defaults_test.go
+++ b/pkg/platform/defaults_test.go
@@ -28,9 +28,35 @@ import (
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
        "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
        "github.com/apache/camel-k/v2/pkg/builder"
+       "github.com/apache/camel-k/v2/pkg/util/defaults"
        "github.com/apache/camel-k/v2/pkg/util/test"
 )
 
+func TestIntegrationPlatformDefaults(t *testing.T) {
+       ip := v1.IntegrationPlatform{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      DefaultPlatformName,
+                       Namespace: "ns",
+               },
+       }
+
+       c, err := test.NewFakeClient(&ip)
+       assert.Nil(t, err)
+
+       err = ConfigureDefaults(context.TODO(), c, &ip, false)
+       assert.Nil(t, err)
+
+       assert.Equal(t, v1.IntegrationPlatformClusterKubernetes, 
ip.Status.Cluster)
+       assert.Equal(t, v1.TraitProfile(""), ip.Status.Profile)
+       assert.Equal(t, v1.BuildStrategyRoutine, 
ip.Status.Build.BuildConfiguration.Strategy)
+       assert.Equal(t, v1.BuildOrderStrategySequential, 
ip.Status.Build.BuildConfiguration.OrderStrategy)
+       assert.Equal(t, defaults.BaseImage(), ip.Status.Build.BaseImage)
+       assert.Equal(t, defaults.LocalRepository, 
ip.Status.Build.Maven.LocalRepository)
+       assert.True(t, ip.Status.Build.MaxRunningBuilds == 3) // default for 
build strategy routine
+       assert.Equal(t, 3, len(ip.Status.Build.Maven.CLIOptions))
+       assert.NotNil(t, ip.Status.Traits)
+}
+
 func TestApplyGlobalPlatformSpec(t *testing.T) {
        global := v1.IntegrationPlatform{
                ObjectMeta: metav1.ObjectMeta{
@@ -40,7 +66,8 @@ func TestApplyGlobalPlatformSpec(t *testing.T) {
                Spec: v1.IntegrationPlatformSpec{
                        Build: v1.IntegrationPlatformBuildSpec{
                                BuildConfiguration: v1.BuildConfiguration{
-                                       Strategy: v1.BuildStrategyRoutine,
+                                       Strategy:      v1.BuildStrategyRoutine,
+                                       OrderStrategy: 
v1.BuildOrderStrategyFIFO,
                                },
                                Maven: v1.MavenSpec{
                                        Properties: map[string]string{
@@ -83,6 +110,7 @@ func TestApplyGlobalPlatformSpec(t *testing.T) {
        assert.Equal(t, v1.IntegrationPlatformClusterOpenShift, 
ip.Status.Cluster)
        assert.Equal(t, v1.TraitProfileOpenShift, ip.Status.Profile)
        assert.Equal(t, v1.BuildStrategyRoutine, 
ip.Status.Build.BuildConfiguration.Strategy)
+       assert.Equal(t, v1.BuildOrderStrategyFIFO, 
ip.Status.Build.BuildConfiguration.OrderStrategy)
        assert.True(t, ip.Status.Build.MaxRunningBuilds == 3) // default for 
build strategy routine
        assert.Equal(t, len(global.Status.Build.Maven.CLIOptions), 
len(ip.Status.Build.Maven.CLIOptions))
        assert.Equal(t, global.Status.Build.Maven.CLIOptions, 
ip.Status.Build.Maven.CLIOptions)
@@ -187,7 +215,8 @@ func TestRetainLocalPlatformSpec(t *testing.T) {
                Spec: v1.IntegrationPlatformSpec{
                        Build: v1.IntegrationPlatformBuildSpec{
                                BuildConfiguration: v1.BuildConfiguration{
-                                       Strategy: v1.BuildStrategyRoutine,
+                                       Strategy:      v1.BuildStrategyRoutine,
+                                       OrderStrategy: 
v1.BuildOrderStrategySequential,
                                },
                                Maven: v1.MavenSpec{
                                        Properties: map[string]string{
@@ -224,7 +253,8 @@ func TestRetainLocalPlatformSpec(t *testing.T) {
                Spec: v1.IntegrationPlatformSpec{
                        Build: v1.IntegrationPlatformBuildSpec{
                                BuildConfiguration: v1.BuildConfiguration{
-                                       Strategy: v1.BuildStrategyPod,
+                                       Strategy:      v1.BuildStrategyPod,
+                                       OrderStrategy: 
v1.BuildOrderStrategyFIFO,
                                },
                                MaxRunningBuilds: 1,
                                Maven: v1.MavenSpec{
@@ -251,6 +281,7 @@ func TestRetainLocalPlatformSpec(t *testing.T) {
        assert.Equal(t, v1.IntegrationPlatformClusterKubernetes, 
ip.Status.Cluster)
        assert.Equal(t, v1.TraitProfileKnative, ip.Status.Profile)
        assert.Equal(t, v1.BuildStrategyPod, 
ip.Status.Build.BuildConfiguration.Strategy)
+       assert.Equal(t, v1.BuildOrderStrategyFIFO, 
ip.Status.Build.BuildConfiguration.OrderStrategy)
        assert.True(t, ip.Status.Build.MaxRunningBuilds == 1)
        assert.Equal(t, len(global.Status.Build.Maven.CLIOptions), 
len(ip.Status.Build.Maven.CLIOptions))
        assert.Equal(t, global.Status.Build.Maven.CLIOptions, 
ip.Status.Build.Maven.CLIOptions)
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 8911750c1..582168091 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -117,9 +117,9 @@ var assets = func() http.FileSystem {
                "/crd/bases/camel.apache.org_builds.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             "camel.apache.org_builds.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 44155,
+                       uncompressedSize: 44653,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3d\x5d\x73\x1b\x39\x72\xef\xfa\x15\x5d\xab\x07\xcb\x55\x22\xb9\xeb\xbd\xbb\x6c\x94\x4a\xa5\x74\xf2\x7a\x4f\xf1\x87\x14\x53\xf6\xdd\xbd\x09\x9c\x69\x92\x38\xce\x00\x13\x00\x23\x9a\x97\xca\x7f\x4f\xa1\x01\x0c\x87\xe4\x7c\x60\x64\x69\xbd\xb9\x23\x5e\x6c\x0d\xf1\xd1\xdd\xe8\x2f\x34\x1a\xc0\x29\x8c\x9e\xae\x9c\x9c\xc2\x3b\x9e\xa0\xd0\x98\x82\x91\x60\x96\x08\x97\x05\x4b\x96\x08\x53\x39\x37\x6b\xa6\x10\xde\xc8\x52\xa4\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3d\x5d\x73\x1b\x39\x72\xef\xfa\x15\x5d\xab\x07\xcb\x55\x22\xb5\xeb\xbd\xbb\x6c\x94\x4a\xa5\x74\xf2\x7a\x4f\xf1\x87\x14\x53\xf6\xdd\xbd\x09\x9c\x69\x92\x38\xce\x00\x13\x00\x23\x9a\x97\xca\x7f\x4f\xa1\x01\x0c\x87\xe4\x7c\x60\x64\x6a\xbd\xb9\x23\x5e\x6c\x71\xf0\xd1\xdd\x68\xf4\x17\x1a\xc0\x29\x8c\x0e\x57\x4e\x4e\xe1\x1d\x4f\x50\x68\x4c\xc1\x48\x30\x0b\x84\xab\x82\x25\x0b\x84\x89\x9c\x99\x15\x53\x08\x6f\x64\x29\x52\x
 [...]
                },
                "/crd/bases/camel.apache.org_camelcatalogs.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             "camel.apache.org_camelcatalogs.yaml",
@@ -131,30 +131,30 @@ var assets = func() http.FileSystem {
                "/crd/bases/camel.apache.org_integrationkits.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             
"camel.apache.org_integrationkits.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 20532,
+                       uncompressedSize: 20753,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3c\x5d\x73\xdb\x38\x92\xef\xfa\x15\x5d\xf1\x43\xec\x2a\x49\xde\xb9\x9b\x9a\xba\xf2\xee\x6d\x95\xd7\x49\x66\x5d\x71\x12\x5f\xe4\xcc\xdc\x54\xcd\x83\x5b\x64\x4b\xc2\x88\x04\xb8\x00\x28\x59\x77\x75\xff\xfd\x0a\x0d\x80\xa2\x24\x92\x62\xe4\xf8\x6e\x1f\xc2\x97\x44\x24\xd0\xe8\xef\x0f\xa0\xe1\x33\x18\x7d\xbb\x67\x70\x06\x77\x22\x21\x69\x28\x05\xab\xc0\x2e\x08\xae\x0b\x4c\x16\x04\x13\x35\xb3\x6b\xd4\x04\xef\x54\x29\x53\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7c\x5f\x6f\xdb\xb8\x96\xf8\xbb\x3f\xc5\x41\xf3\xd0\x04\xb0\x9d\x3b\xbf\xdf\x60\xb0\xc8\xbd\x7b\x81\xdc\xb4\x9d\x1b\x34\x6d\xb3\x75\x3a\xb3\x03\xcc\x43\x8e\xa5\x63\x9b\x63\x89\xd4\x90\x94\x1d\xef\x62\xbf\xfb\x82\x87\xa4\x2c\xdb\x92\xac\x3a\xcd\xee\x3e\x54\x2f\xad\x25\xf2\xf0\xfc\xff\x43\x1e\xe6\x0c\x46\xdf\xee\x19\x9c\xc1\x9d\x48\x48\x1a\x4a\xc1\x2a\xb0\x0b\x82\xeb\x02\x93\x05\xc1\x44\xcd\xec\x1a\x35\xc1\x3b\x55\x
 [...]
                },
                "/crd/bases/camel.apache.org_integrationplatforms.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             
"camel.apache.org_integrationplatforms.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 182031,
+                       uncompressedSize: 182959,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\xe3\x36\x96\x30\x0e\xff\x9f\x4f\x81\x72\x6a\xab\xdd\x5d\x96\xd4\x99\xd9\xcc\x64\xbd\x9b\x7d\x1e\xc7\xdd\x49\x9c\xbe\xd8\x8f\xed\xee\xd9\xa9\x24\x15\x41\xe4\x91\x84\x18\x02\xb8\x00\x28\x5b\x79\xe7\xfd\xee\xbf\xc2\x01\x40\x52\x12\x09\x52\x92\x2f\x9d\x44\x4c\xd5\x4c\xdb\x26\xc0\x73\x80\x83\x73\xc3\xb9\x7c\x4e\x7a\xf7\xf7\x7c\xf6\x39\x79\xcb\x12\x10\x1a\x52\x62\x24\x31\x53\x20\x27\x19\x4d\xa6\x40\xae\xe4\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\xe3\x36\x96\x30\x0e\xff\x9f\x4f\x81\x72\x6a\xab\xdd\x5d\x96\xd4\x99\xd9\xcc\x64\xbd\x9b\x7d\x1e\xc7\xdd\x49\x9c\xbe\xd8\x8f\xed\xee\xd9\xa9\x24\x15\x41\xe4\x91\x84\x18\x02\xb8\x00\x28\x5b\x79\xe7\xfd\xee\xbf\xc2\x01\x40\x52\x12\x09\x52\x92\x2f\x9d\x44\x4c\xd5\x4c\xdb\x26\xc0\x73\x80\x83\x73\xc3\xb9\x7c\x4e\x7a\xf7\xf7\x7c\xf6\x39\x79\xcb\x12\x10\x1a\x52\x62\x24\x31\x53\x20\x27\x19\x4d\xa6\x40\xae\xe4\x
 [...]
                },
                "/crd/bases/camel.apache.org_integrations.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             "camel.apache.org_integrations.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 495936,
+                       uncompressedSize: 496157,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\xb6\x28\x8a\xff\x9f\x4f\x81\x72\x52\x47\xd2\x8e\x48\xd9\x99\xd9\xa9\x19\xff\xa6\x4e\x4a\x5b\x92\x13\xfd\x62\xcb\x2c\x4b\x49\x4e\xca\xc9\x4e\xc0\x6e\x90\xc4\x51\x13\xe8\x01\xd0\x94\x38\xd7\xf7\xbb\xdf\xc2\x02\xd0\x0f\xbe\x7a\xa1\x45\x3a\xce\x9e\xc6\x54\x65\x4c\x91\xbd\x1a\x8f\x85\xf5\x7e\x7c\x4e\x06\xfb\x1b\x9f\x7d\x4e\x5e\xf3\x84\x09\xcd\x52\x62\x24\x31\x33\x46\xce\x73\x9a\xcc\x18\xb9\x95\x13\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\x1b\x37\xb6\x28\x8a\xff\x9f\x4f\x81\x72\x52\x47\xd2\x8e\x48\xd9\x99\xd9\xa9\x19\xff\xa6\x4e\x4a\x5b\x92\x13\xfd\x62\xcb\x2c\x4b\x49\x4e\xca\xc9\x4e\xc0\x6e\x90\xc4\x51\x13\xe8\x01\xd0\x94\x38\xd7\xf7\xbb\xdf\xc2\x02\xd0\x0f\xbe\x7a\xa1\x45\x3a\xce\x9e\xc6\x54\x65\x4c\x91\xbd\x1a\x8f\x85\xf5\x7e\x7c\x4e\x06\xfb\x1b\x9f\x7d\x4e\x5e\xf3\x84\x09\xcd\x52\x62\x24\x31\x33\x46\xce\x73\x9a\xcc\x18\xb9\x95\x13\x
 [...]
                },
                "/crd/bases/camel.apache.org_kameletbindings.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             
"camel.apache.org_kameletbindings.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 575715,
+                       uncompressedSize: 575952,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1b\x37\xb6\x30\x0a\x7f\xf7\xaf\x40\xc9\xa9\x47\xd2\x8e\x48\xd9\x99\x99\xd4\x8c\xdf\xa9\x9d\xd2\xc8\x72\xa2\x37\xb6\xcc\xb2\x94\xe4\x49\x39\xd9\x09\xd8\x0d\x92\xd8\xea\x06\x7a\x00\x34\x25\xe6\xf8\xfc\xf7\x53\x58\x00\xfa\xc2\x9b\xb0\x9a\x92\x46\x9e\x69\x4c\x55\xc6\xa4\xd8\xab\x71\x5b\xf7\xdb\x73\x32\xb8\xbf\xf1\xec\x39\x79\xcb\x13\x26\x34\x4b\x89\x91\xc4\xcc\x18\x39\x29\x68\x32\x63\xe4\x52\x4e\xcc\x0d\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x6b\x73\x1b\x37\xb6\x30\x0a\x7f\xf7\xaf\x40\xc9\xa9\x47\xd2\x8e\x48\xd9\x99\x99\xd4\x8c\xdf\xa9\x9d\xd2\xc8\x72\xa2\x37\xb6\xcc\xb2\x94\xe4\x49\x39\xd9\x09\xd8\x0d\x92\xd8\xea\x06\x7a\x00\x34\x25\xe6\xf8\xfc\xf7\x53\x58\x00\xfa\xc2\x9b\xb0\x9a\x92\x46\x9e\x69\x4c\x55\xc6\xa4\xd8\xab\x71\x5b\xf7\xdb\x73\x32\xb8\xbf\xf1\xec\x39\x79\xcb\x13\x26\x34\x4b\x89\x91\xc4\xcc\x18\x39\x29\x68\x32\x63\xe4\x52\x4e\xcc\x0d\x
 [...]
                },
                "/crd/bases/camel.apache.org_kamelets.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             "camel.apache.org_kamelets.yaml",
@@ -166,9 +166,9 @@ var assets = func() http.FileSystem {
                "/crd/bases/camel.apache.org_pipes.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             "camel.apache.org_pipes.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 542983,
+                       uncompressedSize: 543220,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x79\x73\x1b\x37\xb6\x38\x0c\xff\xef\x4f\x81\x92\x53\x3f\x49\x37\x22\x65\x67\x96\x9a\xf1\x3b\x75\x53\xba\xb2\xec\xe8\x8d\x2d\xb3\x2c\x25\xf9\xa5\x9c\xdc\x04\xec\x06\x49\x5c\x75\x03\x7d\x01\x34\x25\xe6\xf1\xf3\xdd\x9f\xc2\x01\xd0\x0b\x37\xe1\x34\x25\x8d\x3c\xd3\x98\xaa\x8c\x49\xb1\x4f\x63\x3b\xfb\xf6\x9c\x0c\xee\x6f\x3c\x7b\x4e\xde\xf1\x84\x09\xcd\x52\x62\x24\x31\x33\x46\x4e\x0a\x9a\xcc\x18\xb9\x94\x13\x73\x43\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x79\x73\x1b\x37\xb6\x38\x0c\xff\xef\x4f\x81\x92\x53\x3f\x49\x37\x22\x65\x67\x96\x9a\xf1\x3b\x75\x53\xba\xb2\xec\xe8\x8d\x2d\xb3\x2c\x25\xf9\xa5\x9c\xdc\x04\xec\x06\x49\x5c\x75\x03\x7d\x01\x34\x25\xe6\xf1\xf3\xdd\x9f\xc2\x01\xd0\x0b\x37\xe1\x34\x25\x8d\x3c\xd3\x98\xaa\x8c\x49\xb1\x4f\x63\x3b\xfb\xf6\x9c\x0c\xee\x6f\x3c\x7b\x4e\xde\xf1\x84\x09\xcd\x52\x62\x24\x31\x33\x46\x4e\x0a\x9a\xcc\x18\xb9\x94\x13\x73\x43\x
 [...]
                },
                "/manager": &vfsgen۰DirInfo{
                        name:    "manager",
@@ -625,9 +625,9 @@ var assets = func() http.FileSystem {
                "/traits.yaml": &vfsgen۰CompressedFileInfo{
                        name:             "traits.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 66742,
+                       uncompressedSize: 66891,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x6b\x73\x1c\xb9\x91\x28\xfa\x5d\xbf\x02\xc1\xbd\x1b\x24\x75\xfb\x41\x8d\xd7\xde\x59\xee\xca\xbe\x1c\x8d\xc6\xa6\xf5\xe2\x15\x39\xe3\x75\xe8\x28\xdc\xe8\x2a\x74\x37\xd4\xd5\x40\x19\x40\x91\xea\x39\x7b\xfe\xfb\x09\x64\x26\x1e\x55\x5d\xcd\x6e\x4a\xe4\xac\xb9\xf6\x6e\x84\x47\x24\x0b\x89\x44\x22\x91\x48\xe4\xd3\x19\x2e\x9d\x3d\x7d\x32\x64\x8a\xaf\xc4\x29\xfb\x95\x2d\x78\x25\x9e\x30\x56\x57\xdc\xcd\xb4\x59\x9d\xb2\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x6b\x73\x1c\xb9\x91\x28\xfa\x5d\xbf\x02\xc1\xbd\x1b\x24\x75\xfb\x41\x8d\xd7\xde\x59\xee\xca\xbe\x1c\x8d\xc6\xa6\xf5\xe2\x15\x39\xe3\x75\xe8\x28\xdc\xe8\x2a\x74\x37\xd4\xd5\x40\x19\x40\x91\xea\x39\x7b\xfe\xfb\x09\x64\x26\x1e\x55\x5d\xcd\x6e\x4a\xe4\xac\xb9\xf6\x6e\x84\x47\x24\x0b\x89\x44\x22\x91\x48\xe4\xd3\x19\x2e\x9d\x3d\x7d\x32\x64\x8a\xaf\xc4\x29\xfb\x95\x2d\x78\x25\x9e\x30\x56\x57\xdc\xcd\xb4\x59\x9d\xb2\x
 [...]
                },
        }
        fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go
index e8b72419f..2d997210e 100644
--- a/pkg/trait/builder.go
+++ b/pkg/trait/builder.go
@@ -181,9 +181,10 @@ func (t *builderTrait) builderTask(e *Environment) 
(*v1.BuilderTask, error) {
                }
                // The builder trait must define certain resources requirements 
when we have a native build
                if ok && pointer.BoolDeref(quarkus.Enabled, true) && 
(isNativeIntegration || isNativeKit) {
-                       // Force the build to run in a separate Pod
+                       // Force the build to run in a separate Pod and 
strictly sequential
                        t.L.Info("This is a Quarkus native build: setting build 
configuration with build Pod strategy, 1 CPU core and 4 GiB memory. Make sure 
your cluster can handle it.")
                        t.Strategy = string(v1.BuildStrategyPod)
+                       t.OrderStrategy = 
string(v1.BuildOrderStrategySequential)
                        t.RequestCPU = "1000m"
                        t.RequestMemory = "4Gi"
                }
@@ -198,13 +199,39 @@ func (t *builderTrait) builderTask(e *Environment) 
(*v1.BuilderTask, error) {
 
        if t.Strategy != "" {
                t.L.Infof("User defined build strategy %s", t.Strategy)
-               switch t.Strategy {
-               case string(v1.BuildStrategyPod):
-                       buildConfig.Strategy = v1.BuildStrategyPod
-               case string(v1.BuildStrategyRoutine):
-                       buildConfig.Strategy = v1.BuildStrategyRoutine
-               default:
-                       return nil, fmt.Errorf("must specify either pod or 
routine build strategy, unknown %s", t.Strategy)
+               found := false
+               for _, s := range v1.BuildStrategies {
+                       if string(s) == t.Strategy {
+                               found = true
+                               buildConfig.Strategy = s
+                               break
+                       }
+               }
+               if !found {
+                       var strategies []string
+                       for _, s := range v1.BuildStrategies {
+                               strategies = append(strategies, string(s))
+                       }
+                       return nil, fmt.Errorf("unknown build strategy: %s. One 
of [%s] is expected", t.Strategy, strings.Join(strategies, ", "))
+               }
+       }
+
+       if t.OrderStrategy != "" {
+               t.L.Infof("User defined build order strategy %s", 
t.OrderStrategy)
+               found := false
+               for _, s := range v1.BuildOrderStrategies {
+                       if string(s) == t.OrderStrategy {
+                               found = true
+                               buildConfig.OrderStrategy = s
+                               break
+                       }
+               }
+               if !found {
+                       var strategies []string
+                       for _, s := range v1.BuildOrderStrategies {
+                               strategies = append(strategies, string(s))
+                       }
+                       return nil, fmt.Errorf("unknown build order strategy: 
%s. One of [%s] is expected", t.OrderStrategy, strings.Join(strategies, ", "))
                }
        }
 
diff --git a/resources/traits.yaml b/resources/traits.yaml
index 9a8f278c9..af06f964c 100755
--- a/resources/traits.yaml
+++ b/resources/traits.yaml
@@ -212,6 +212,10 @@ traits:
   - name: strategy
     type: string
     description: The strategy to use, either `pod` or `routine` (default 
routine)
+  - name: order-strategy
+    type: string
+    description: The build order strategy to use, either `fifo` or 
`sequential` (default
+      sequential)
   - name: request-cpu
     type: string
     description: When using `pod` strategy, the minimum amount of CPU required 
by

Reply via email to