You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2023/09/11 16:51:02 UTC

[camel-karavan] 01/03: Replace tekton pipleines with Builder pod for #817

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

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

commit 14ee133855aaf8e47a5984bb13f3661f9e95dd51
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Mon Sep 11 12:11:53 2023 -0400

    Replace tekton pipleines with Builder pod for #817
---
 karavan-web/karavan-app/pom.xml                    |   9 +-
 .../camel/karavan/api/ContainerResource.java       |   2 +-
 .../camel/karavan/api/InfrastructureResource.java  |  35 --
 .../apache/camel/karavan/api/LogWatchResource.java |   8 +-
 .../apache/camel/karavan/api/ProjectResource.java  |   2 +-
 .../apache/camel/karavan/api/StatusResource.java   |  14 -
 .../camel/karavan/docker/DockerForKaravan.java     |  17 +-
 .../karavan/infinispan/InfinispanService.java      |  22 --
 .../karavan/infinispan/model/KaravanSchema.java    |   1 -
 .../karavan/infinispan/model/PipelineStatus.java   |  83 -----
 .../camel/karavan/infinispan/model/Project.java    |   3 +-
 .../karavan/kubernetes/KubernetesService.java      | 412 ++++++++++-----------
 .../kubernetes/PipelineRunEventHandler.java        |  92 -----
 .../camel/karavan/service/ProjectService.java      |  58 +--
 .../org/apache/camel/karavan/shared/Constants.java |   2 +
 .../pipelines/karavan-pipeline-dev-quarkus.yaml    |  27 --
 .../karavan-pipeline-dev-spring-boot.yaml          |  27 --
 .../pipelines/karavan-task-dev-quarkus.yaml        |  90 -----
 .../pipelines/karavan-task-dev-spring-boot.yaml    |  78 ----
 .../src/main/webui/src/api/KaravanApi.tsx          |  35 --
 .../src/main/webui/src/api/ProjectEventBus.ts      |   4 +-
 .../src/main/webui/src/api/ProjectModels.ts        |   9 -
 .../src/main/webui/src/api/ProjectStore.ts         |   8 -
 .../karavan-app/src/main/webui/src/index.css       |  28 --
 .../src/main/webui/src/main/MainDataPoller.tsx     |   9 +-
 .../main/webui/src/project/build/BuildPanel.tsx    |  59 +--
 .../webui/src/project/container/ContainerPanel.tsx |   4 +-
 27 files changed, 247 insertions(+), 891 deletions(-)

diff --git a/karavan-web/karavan-app/pom.xml b/karavan-web/karavan-app/pom.xml
index fbf4dcad..c042dd30 100644
--- a/karavan-web/karavan-app/pom.xml
+++ b/karavan-web/karavan-app/pom.xml
@@ -67,6 +67,10 @@
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-kubernetes-client</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+        </dependency>
         <dependency>
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-openshift-client</artifactId>
@@ -95,11 +99,6 @@
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-scheduler</artifactId>
         </dependency>
-        <dependency>
-            <groupId>io.fabric8</groupId>
-            <artifactId>tekton-client</artifactId>
-            <version>${tekton.version}</version>
-        </dependency>
         <dependency>
             <groupId>io.micrometer</groupId>
             <artifactId>micrometer-registry-prometheus</artifactId>
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java
index 8a237d20..febf6201 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java
@@ -168,7 +168,7 @@ public class ContainerResource {
             setContainerStatusTransit(name, type);
             try {
                 if (ConfigService.inKubernetes()) {
-                    kubernetesService.deletePod(name, kubernetesService.getNamespace());
+                    kubernetesService.deletePod(name);
                 } else {
                     dockerService.deleteContainer(name);
                 }
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java
index 7c2a6b6a..8b62d4c0 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java
@@ -22,7 +22,6 @@ import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 import org.apache.camel.karavan.infinispan.InfinispanService;
 import org.apache.camel.karavan.infinispan.model.DeploymentStatus;
-import org.apache.camel.karavan.infinispan.model.Project;
 import org.apache.camel.karavan.infinispan.model.ServiceStatus;
 import org.apache.camel.karavan.kubernetes.KubernetesService;
 import org.apache.camel.karavan.service.ConfigService;
@@ -47,40 +46,6 @@ public class InfrastructureResource {
 
     private static final Logger LOGGER = Logger.getLogger(InfrastructureResource.class.getName());
 
-    @POST
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Path("/pipeline/{env}")
-    public String createPipeline(@PathParam("env") String env, Project project) throws Exception {
-        Project p = infinispanService.getProject(project.getProjectId());
-        return kubernetesService.createPipelineRun(project);
-    }
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    @Path("/pipeline/{env}/{name}")
-    public Response getPipeline(@PathParam("env") String env,
-                                @PathParam("name") String name) throws Exception {
-        return Response.ok(kubernetesService.getPipelineRun(name, kubernetesService.getNamespace())).build();
-    }
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    @Path("/pipeline/log/{env}/{name}")
-    public Response getPipelineLog(@PathParam("env") String env,
-                                   @PathParam("name") String name) throws Exception {
-        return Response.ok(kubernetesService.getPipelineRunLog(name, kubernetesService.getNamespace())).build();
-    }
-
-    @DELETE
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Path("/pipelinerun/{env}/{name}")
-    public Response stopPipelineRun(@PathParam("env") String env, @PathParam("name") String name) throws Exception {
-        kubernetesService.stopPipelineRun(name, kubernetesService.getNamespace());
-        return Response.ok().build();
-    }
-
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/deployment")
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
index 78cc5d6e..bc0a68c7 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
@@ -70,7 +70,7 @@ public class LogWatchResource {
         managedExecutor.execute(() -> {
             LOGGER.info("LogWatch for " + name + " starting...");
             if (ConfigService.inKubernetes()) {
-                getKubernetesLogs(type, name, eventSink, sse);
+                getKubernetesLogs(name, eventSink, sse);
             } else {
                 getDockerLogs(type, name, eventSink, sse);
             }
@@ -94,11 +94,9 @@ public class LogWatchResource {
         }
     }
 
-    private void getKubernetesLogs(String type, String name, SseEventSink eventSink, Sse sse) {
+    private void getKubernetesLogs(String name, SseEventSink eventSink, Sse sse) {
         try (SseEventSink sink = eventSink) {
-            LogWatch logWatch = type.equals("container")
-                    ? kubernetesService.getContainerLogWatch(name)
-                    : kubernetesService.getPipelineRunLogWatch(name);
+            LogWatch logWatch = kubernetesService.getContainerLogWatch(name);
             BufferedReader reader = new BufferedReader(new InputStreamReader(logWatch.getOutput()));
             try {
                 for (String line; (line = reader.readLine()) != null && !sink.isClosed(); ) {
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java
index 302d9746..fc9cd54f 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java
@@ -109,7 +109,7 @@ public class ProjectResource {
                        @PathParam("env") String env, @PathParam("buildName") String buildName) {
         buildName = URLDecoder.decode(buildName, StandardCharsets.UTF_8);
         if (ConfigService.inKubernetes()) {
-            kubernetesService.stopPipelineRun(buildName, kubernetesService.getNamespace());
+            kubernetesService.deletePod(buildName);
             return Response.ok().build();
         } else {
             dockerService.deleteContainer(buildName);
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
index b4dcd21d..0e3fdd8a 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
@@ -39,20 +39,6 @@ public class StatusResource {
     @Inject
     InfinispanService infinispanService;
 
-    @Inject
-    EventBus bus;
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    @Path("/pipeline/{env}")
-    public List<PipelineStatus> getPipelineStatuses(@PathParam("env") String env) {
-        if (infinispanService.isReady()) {
-            return infinispanService.getPipelineStatuses(env);
-        } else {
-            return List.of();
-        }
-    }
-
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/deployment/{name}/{env}")
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java
index 10e821f9..b8cb910f 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java
@@ -22,6 +22,7 @@ import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
 import org.apache.camel.karavan.code.model.DockerComposeService;
 import org.apache.camel.karavan.infinispan.model.ContainerStatus;
+import org.apache.camel.karavan.infinispan.model.Project;
 import org.apache.camel.karavan.service.RegistryService;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.jboss.logging.Logger;
@@ -68,21 +69,25 @@ public class DockerForKaravan {
 
     }
 
-    public void runBuildProject(String projectId, String script, Map<String, String> files, List<String> env,  Map<String, String> volumes, String tag) throws Exception {
-        String containerName = projectId + BUILDER_SUFFIX;
+    public void runBuildProject(Project project, String script, List<String> env, Map<String, String> volumes, String tag) throws Exception {
+        String containerName = project.getProjectId() + BUILDER_SUFFIX;
         dockerService.deleteContainer(containerName);
-        Container c = createBuildContainer(containerName, projectId, env, volumes, tag);
-        dockerService.copyFiles(c.getId(), "/code", files);
+        Container c = createBuildContainer(containerName, project, env, volumes, tag);
         dockerService.copyExecFile(c.getId(), "/karavan", "build.sh", script);
         dockerService.runContainer(c);
     }
 
-    protected Container createBuildContainer(String containerName, String projectId, List<String> env, Map<String, String> volumes, String tag) throws InterruptedException {
+    protected Container createBuildContainer(String containerName, Project project, List<String> env, Map<String, String> volumes, String tag) throws InterruptedException {
         LOGGER.infof("Starting Build Container ", containerName);
 
         return dockerService.createContainer(containerName, devmodeImage,
                 env, Map.of(), new HealthCheck(),
-                Map.of(LABEL_TYPE, ContainerStatus.ContainerType.build.name(), LABEL_PROJECT_ID, projectId, LABEL_TAG, tag),
+                Map.of(
+                        LABEL_TYPE, ContainerStatus.ContainerType.build.name(),
+                        LABEL_PROJECT_ID, project.getProjectId(),
+                        LABEL_PROJECT_RUNTIME, project.getRuntime(),
+                        LABEL_TAG, tag
+                ),
                 volumes, null,"/karavan/build.sh");
     }
 
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java
index 1734d8a4..da0d21a8 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java
@@ -60,7 +60,6 @@ public class InfinispanService implements HealthCheck {
 
     private RemoteCache<GroupedKey, Project> projects;
     private RemoteCache<GroupedKey, ProjectFile> files;
-    private RemoteCache<GroupedKey, PipelineStatus> pipelineStatuses;
     private RemoteCache<GroupedKey, DeploymentStatus> deploymentStatuses;
     private RemoteCache<GroupedKey, ContainerStatus> containerStatuses;
     private RemoteCache<GroupedKey, Boolean> transits;
@@ -101,7 +100,6 @@ public class InfinispanService implements HealthCheck {
             projects = getOrCreateCache(Project.CACHE);
             files = getOrCreateCache(ProjectFile.CACHE);
             containerStatuses = getOrCreateCache(ContainerStatus.CACHE);
-            pipelineStatuses = getOrCreateCache(PipelineStatus.CACHE);
             deploymentStatuses = getOrCreateCache(DeploymentStatus.CACHE);
             serviceStatuses = getOrCreateCache(ServiceStatus.CACHE);
             camelStatuses = getOrCreateCache(CamelStatus.CACHE);
@@ -191,25 +189,6 @@ public class InfinispanService implements HealthCheck {
         return projects.get(GroupedKey.create(projectId, DEFAULT_ENVIRONMENT, projectId));
     }
 
-    public PipelineStatus getPipelineStatus(String projectId, String environment) {
-        return pipelineStatuses.get(GroupedKey.create(projectId, environment, projectId));
-    }
-
-    public List<PipelineStatus> getPipelineStatuses(String environment) {
-        QueryFactory queryFactory = Search.getQueryFactory((RemoteCache<?, ?>) pipelineStatuses);
-        return queryFactory.<PipelineStatus>create("FROM karavan.PipelineStatus WHERE env = :env")
-                .setParameter("env", environment)
-                .execute().list();
-    }
-
-    public void savePipelineStatus(PipelineStatus status) {
-        pipelineStatuses.put(GroupedKey.create(status.getProjectId(), status.getEnv(), status.getProjectId()), status);
-    }
-
-    public void deletePipelineStatus(PipelineStatus status) {
-        pipelineStatuses.remove(GroupedKey.create(status.getProjectId(), status.getEnv(), status.getProjectId()));
-    }
-
     public DeploymentStatus getDeploymentStatus(String projectId, String environment) {
         return deploymentStatuses.get(GroupedKey.create(projectId, environment, projectId));
     }
@@ -367,7 +346,6 @@ public class InfinispanService implements HealthCheck {
         CompletableFuture.allOf(
                 deploymentStatuses.clearAsync(),
                 containerStatuses.clearAsync(),
-                pipelineStatuses.clearAsync(),
                 camelStatuses.clearAsync()
         ).join();
     }
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/KaravanSchema.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/KaravanSchema.java
index 29731935..3ccde791 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/KaravanSchema.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/KaravanSchema.java
@@ -9,7 +9,6 @@ import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
                 Project.class,
                 Project.Type.class,
                 ProjectFile.class,
-                PipelineStatus.class,
                 CamelStatus.class,
                 CamelStatus.Name.class,
                 DeploymentStatus.class,
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/PipelineStatus.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/PipelineStatus.java
deleted file mode 100644
index fd0831d0..00000000
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/PipelineStatus.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.apache.camel.karavan.infinispan.model;
-
-import org.infinispan.protostream.annotations.ProtoFactory;
-import org.infinispan.protostream.annotations.ProtoField;
-
-public class PipelineStatus {
-    public static final String CACHE = "pipeline_statuses";
-    @ProtoField(number = 1)
-    String projectId;
-    @ProtoField(number = 2)
-    String pipelineName;
-    @ProtoField(number = 3)
-    String result;
-    @ProtoField(number = 5)
-    String startTime;
-    @ProtoField(number = 6)
-    String completionTime;
-    @ProtoField(number = 7)
-    String env;
-
-    @ProtoFactory
-    public PipelineStatus(String projectId, String pipelineName, String result, String startTime, String completionTime, String env) {
-        this.projectId = projectId;
-        this.pipelineName = pipelineName;
-        this.result = result;
-        this.startTime = startTime;
-        this.completionTime = completionTime;
-        this.env = env;
-    }
-
-    public PipelineStatus(String projectId, String env) {
-        this.projectId = projectId;
-        this.env = env;
-    }
-
-    public String getProjectId() {
-        return projectId;
-    }
-
-    public void setProjectId(String projectId) {
-        this.projectId = projectId;
-    }
-
-    public String getPipelineName() {
-        return pipelineName;
-    }
-
-    public void setPipelineName(String pipelineName) {
-        this.pipelineName = pipelineName;
-    }
-
-    public String getResult() {
-        return result;
-    }
-
-    public void setResult(String result) {
-        this.result = result;
-    }
-
-    public String getStartTime() {
-        return startTime;
-    }
-
-    public void setStartTime(String startTime) {
-        this.startTime = startTime;
-    }
-
-    public String getCompletionTime() {
-        return completionTime;
-    }
-
-    public void setCompletionTime(String completionTime) {
-        this.completionTime = completionTime;
-    }
-
-    public String getEnv() {
-        return env;
-    }
-
-    public void setEnv(String env) {
-        this.env = env;
-    }
-}
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/Project.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/Project.java
index c719aa13..6d37868f 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/Project.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/model/Project.java
@@ -14,8 +14,7 @@ public class Project {
         @ProtoEnumValue(number = 0, name = "templates") templates,
         @ProtoEnumValue (number = 1, name = "kamelets") kamelets,
         @ProtoEnumValue (number = 2, name = "services") services,
-        @ProtoEnumValue (number = 3, name = "pipelines") pipelines,
-        @ProtoEnumValue (number = 4, name = "normal") normal,
+        @ProtoEnumValue (number = 3, name = "normal") normal,
     }
 
     @ProtoField(number = 1)
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java
index f04949e2..063b8899 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.karavan.kubernetes;
 
-import io.fabric8.knative.internal.pkg.apis.Condition;
 import io.fabric8.kubernetes.api.model.*;
 import io.fabric8.kubernetes.api.model.apps.Deployment;
 import io.fabric8.kubernetes.client.DefaultKubernetesClient;
@@ -25,8 +24,6 @@ import io.fabric8.kubernetes.client.dsl.LogWatch;
 import io.fabric8.kubernetes.client.informers.SharedIndexInformer;
 import io.fabric8.openshift.api.model.ImageStream;
 import io.fabric8.openshift.client.OpenShiftClient;
-import io.fabric8.tekton.client.DefaultTektonClient;
-import io.fabric8.tekton.pipeline.v1beta1.*;
 import io.vertx.mutiny.core.eventbus.EventBus;
 import org.apache.camel.karavan.infinispan.InfinispanService;
 import org.apache.camel.karavan.infinispan.model.ContainerStatus;
@@ -35,7 +32,6 @@ import org.apache.camel.karavan.infinispan.model.ProjectFile;
 import org.apache.camel.karavan.code.CodeService;
 import org.apache.camel.karavan.service.ConfigService;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
-import org.eclipse.microprofile.faulttolerance.Retry;
 import org.eclipse.microprofile.health.HealthCheck;
 import org.eclipse.microprofile.health.HealthCheckResponse;
 import org.eclipse.microprofile.health.Readiness;
@@ -46,9 +42,6 @@ import jakarta.enterprise.inject.Default;
 import jakarta.enterprise.inject.Produces;
 import jakarta.inject.Inject;
 
-import java.io.ByteArrayInputStream;
-import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -74,19 +67,11 @@ public class KubernetesService implements HealthCheck {
     @Inject
     InfinispanService infinispanService;
 
-    @Inject
-    CodeService codeService;
-
     @Produces
     public KubernetesClient kubernetesClient() {
         return new DefaultKubernetesClient();
     }
 
-    @Produces
-    public DefaultTektonClient tektonClient() {
-        return new DefaultTektonClient(kubernetesClient());
-    }
-
     @Produces
     public OpenShiftClient openshiftClient() {
         return kubernetesClient().adapt(OpenShiftClient.class);
@@ -105,26 +90,25 @@ public class KubernetesService implements HealthCheck {
             stopInformers();
             LOGGER.info("Starting Kubernetes Informers");
 
-            SharedIndexInformer<Deployment> deploymentInformer = kubernetesClient().apps().deployments().inNamespace(getNamespace())
-                    .withLabels(getRuntimeLabels()).inform();
-            deploymentInformer.addEventHandlerWithResyncPeriod(new DeploymentEventHandler(infinispanService, this), 30 * 1000L);
-            informers.add(deploymentInformer);
+            Map<String, String> labels = getRuntimeLabels();
 
-            SharedIndexInformer<Service> serviceInformer = kubernetesClient().services().inNamespace(getNamespace())
-                    .withLabels(getRuntimeLabels()).inform();
-            serviceInformer.addEventHandlerWithResyncPeriod(new ServiceEventHandler(infinispanService, this), 30 * 1000L);
-            informers.add(serviceInformer);
+            try (KubernetesClient client = kubernetesClient()) {
 
-//            SharedIndexInformer<PipelineRun> pipelineRunInformer = tektonClient().v1beta1().pipelineRuns().inNamespace(getNamespace())
-//                    .withLabels(getRuntimeLabels()).inform();
-//            pipelineRunInformer.addEventHandlerWithResyncPeriod(new PipelineRunEventHandler(infinispanService, this), 30 * 1000L);
-//            informers.add(pipelineRunInformer);
+                SharedIndexInformer<Deployment> deploymentInformer = client.apps().deployments().inNamespace(getNamespace())
+                        .withLabels(labels).inform();
+                deploymentInformer.addEventHandlerWithResyncPeriod(new DeploymentEventHandler(infinispanService, this), 30 * 1000L);
+                informers.add(deploymentInformer);
 
-            SharedIndexInformer<Pod> podRunInformer = kubernetesClient().pods().inNamespace(getNamespace())
-                    .withLabels(getRuntimeLabels()).inform();
-            podRunInformer.addEventHandlerWithResyncPeriod(new PodEventHandler(infinispanService, this, eventBus), 30 * 1000L);
-            informers.add(podRunInformer);
+                SharedIndexInformer<Service> serviceInformer = client.services().inNamespace(getNamespace())
+                        .withLabels(labels).inform();
+                serviceInformer.addEventHandlerWithResyncPeriod(new ServiceEventHandler(infinispanService, this), 30 * 1000L);
+                informers.add(serviceInformer);
 
+                SharedIndexInformer<Pod> podRunInformer = client.pods().inNamespace(getNamespace())
+                        .withLabels(labels).inform();
+                podRunInformer.addEventHandlerWithResyncPeriod(new PodEventHandler(infinispanService, this, eventBus), 30 * 1000L);
+                informers.add(podRunInformer);
+            }
             LOGGER.info("Started Kubernetes Informers");
         } catch (Exception e) {
             LOGGER.error("Error starting informers: " + e.getMessage());
@@ -151,108 +135,128 @@ public class KubernetesService implements HealthCheck {
         informers.clear();
     }
 
-    private String getPipelineName(Project project) {
-        return "karavan-pipeline-" + environment + "-" + project.getRuntime();
+    public void runBuildProject(Project project, String script, List<String> env, String tag) {
+        try (KubernetesClient client = kubernetesClient()) {
+            String containerName = project.getProjectId() + BUILDER_SUFFIX;
+            Map<String, String> labels = getLabels(containerName, project, ContainerStatus.ContainerType.build);
+//        createPVC(containerName, labels);
+
+            // create script configMap
+            ConfigMap configMap = client.configMaps().inNamespace(getNamespace()).withName(containerName).get();
+            if (configMap == null) {
+                configMap = getConfigMapForBuilder(containerName, labels);
+            }
+            configMap.setData(Map.of("build.sh", script));
+            client.resource(configMap).serverSideApply();
+
+//        Delete old build pod
+            Pod old = client.pods().inNamespace(getNamespace()).withName(containerName).get();
+            if (old != null) {
+                client.resource(old).delete();
+            }
+            Pod pod = getBuilderPod(project, containerName, env, labels);
+            Pod result = client.resource(pod).serverSideApply();
+
+            LOGGER.info("Created pod " + result.getMetadata().getName());
+        }
     }
 
-    public String createPipelineRun(Project project) {
-        String pipeline = getPipelineName(project);
-        LOGGER.info("Pipeline " + pipeline + " is creating for " + project.getProjectId());
+    private Map<String, String> getLabels(String name, Project project, ContainerStatus.ContainerType type) {
+        Map<String, String> labels = new HashMap<>();
+        labels.putAll(getRuntimeLabels());
+        labels.put("app.kubernetes.io/name", name);
+        labels.put(LABEL_PROJECT_ID, project.getProjectId());
+        labels.put(LABEL_PROJECT_RUNTIME, project.getRuntime());
+        if (type != null) {
+            labels.put(LABEL_TYPE, type.name());
+        }
+        return labels;
+    }
+
+    private Map<String, String> getRuntimeLabels() {
+        Map<String, String> labels = new HashMap<>();
+        labels.put(LABEL_PART_OF, KARAVAN_PREFIX);
+        labels.put(isOpenshift() ? "app.openshift.io/runtime" : "app.kubernetes.io/runtime", CAMEL_PREFIX);
+        return labels;
+    }
 
-        Map<String, String> labels = getRuntimeLabels(
-                Map.of("karavan-project-id", project.getProjectId(),
-                        "tekton.dev/pipeline", pipeline)
-        );
+
+    private ConfigMap getConfigMapForBuilder(String name, Map<String, String> labels) {
+        return new ConfigMapBuilder()
+                .withMetadata(new ObjectMetaBuilder()
+                        .withName(name)
+                        .withLabels(labels)
+                        .withNamespace(getNamespace())
+                        .build())
+                .build();
+    }
+
+    private Pod getBuilderPod(Project project, String name, List<String> env, Map<String, String> labels) {
+        List<EnvVar> envVars = env.stream().map(s -> {
+            String[] parts = s.split("=");
+            String varName = parts[0];
+            String varValue = parts[1];
+            return new EnvVarBuilder().withName(varName).withValue(varValue).build();
+        }).toList();
 
         ObjectMeta meta = new ObjectMetaBuilder()
-                .withGenerateName(KARAVAN_PREFIX + "-" + project.getProjectId() + "-")
+                .withName(name)
                 .withLabels(labels)
                 .withNamespace(getNamespace())
                 .build();
 
-        PipelineRef ref = new PipelineRefBuilder().withName(pipeline).build();
-
-        PipelineRunSpec spec = new PipelineRunSpecBuilder()
-                .withPipelineRef(ref)
-                .withServiceAccountName("pipeline")
-                .withParams(new ParamBuilder().withName("PROJECT_ID").withNewValue(project.getProjectId()).build())
-                .withWorkspaces(
-                        new WorkspaceBindingBuilder().withName(PVC_MAVEN_SETTINGS)
-                                .withConfigMap(new ConfigMapVolumeSourceBuilder().withName("karavan").build()).build(),
-                        new WorkspaceBindingBuilder().withName(KARAVAN_PREFIX + "-" + M2_CACHE_SUFFIX)
-                                .withNewPersistentVolumeClaim(KARAVAN_PREFIX + "-" + M2_CACHE_SUFFIX, false).build(),
-                        new WorkspaceBindingBuilder().withName(KARAVAN_PREFIX + "-" + JBANG_CACHE_SUFFIX)
-                                .withNewPersistentVolumeClaim(KARAVAN_PREFIX + "-" + JBANG_CACHE_SUFFIX, false).build())
+        ContainerPort port = new ContainerPortBuilder()
+                .withContainerPort(8080)
+                .withName("http")
+                .withProtocol("TCP")
                 .build();
 
-        PipelineRunBuilder pipelineRunBuilder = new PipelineRunBuilder()
-                .withMetadata(meta)
-                .withSpec(spec);
+        Container container = new ContainerBuilder()
+                .withName(name)
+                .withImage("ghcr.io/apache/camel-karavan-devmode:" + version)
+                .withPorts(port)
+                .withImagePullPolicy("Always")
+                .withEnv(envVars)
+                .withCommand("/bin/sh", "-c", "/builder/build.sh")
+                .withVolumeMounts(
+//                        new VolumeMountBuilder().withName(name).withMountPath("/karavan/.jbang/cache").build()
+                        new VolumeMountBuilder().withName("builder").withMountPath("/builder").withReadOnly(true).build()
+                )
+                .build();
 
-        PipelineRun pipelineRun = tektonClient().v1beta1().pipelineRuns().create(pipelineRunBuilder.build());
-        LOGGER.info("Pipeline run started " + pipelineRun.getMetadata().getName());
-        return pipelineRun.getMetadata().getName();
-    }
+        PodSpec spec = new PodSpecBuilder()
+                .withTerminationGracePeriodSeconds(0L)
+                .withContainers(container)
+                .withRestartPolicy("Never")
+                .withVolumes(
+//                        new VolumeBuilder().withName(name)
+//                                .withNewPersistentVolumeClaim(name, false).build(),
+                        new VolumeBuilder().withName("builder")
+                                .withConfigMap(new ConfigMapVolumeSourceBuilder().withName(name).withItems(
+                                        new KeyToPathBuilder().withKey("build.sh").withPath("build.sh").build()
+                                ).withDefaultMode(511).build()).build()
+//                        new VolumeBuilder().withName("maven-settings")
+//                                .withConfigMap(new ConfigMapVolumeSourceBuilder()
+//                                        .withName("karavan").build()).build()
+                ).build();
 
-    public PipelineRun getPipelineRun(String pipelineRuneName, String namespace) {
-        return tektonClient().v1beta1().pipelineRuns().inNamespace(namespace).withName(pipelineRuneName).get();
+        return new PodBuilder()
+                .withMetadata(meta)
+                .withSpec(spec)
+                .build();
     }
 
-    public List<TaskRun> getTaskRuns(String pipelineRuneName, String namespace) {
-        return tektonClient().v1beta1().taskRuns().inNamespace(namespace).withLabel("tekton.dev/pipelineRun", pipelineRuneName).list().getItems();
-    }
 
     public String getContainerLog(String podName, String namespace) {
-        String logText = kubernetesClient().pods().inNamespace(namespace).withName(podName).getLog(true);
-        return logText;
+        try (KubernetesClient client = kubernetesClient()) {
+            String logText = client.pods().inNamespace(namespace).withName(podName).getLog(true);
+            return logText;
+        }
     }
 
     public LogWatch getContainerLogWatch(String podName) {
-        return kubernetesClient().pods().inNamespace(getNamespace()).withName(podName).tailingLines(100).watchLog();
-    }
-
-    public LogWatch getPipelineRunLogWatch(String pipelineRuneName) {
-        List<TaskRun> tasks = getTaskRuns(pipelineRuneName, getNamespace());
-        TaskRun taskRun = tasks.get(0);
-        return kubernetesClient().pods().inNamespace(getNamespace()).withName(taskRun.getStatus().getPodName()).tailingLines(100).watchLog();
-    }
-
-    public String getPipelineRunLog(String pipelineRuneName, String namespace) {
-        StringBuilder result = new StringBuilder();
-        getTaskRuns(pipelineRuneName, namespace).forEach(taskRun -> {
-            String podName = taskRun.getStatus().getPodName();
-            taskRun.getStatus().getSteps().forEach(stepState -> {
-                String logText = kubernetesClient().pods().inNamespace(namespace).withName(podName).inContainer(stepState.getContainer()).getLog(true);
-                result.append(stepState.getContainer()).append(System.lineSeparator());
-                result.append(logText).append(System.lineSeparator());
-            });
-        });
-        return result.toString();
-    }
-
-    public PipelineRun getLastPipelineRun(String projectId, String pipelineName, String namespace) {
-        return tektonClient().v1beta1().pipelineRuns().inNamespace(namespace)
-                .withLabel("karavan-project-id", projectId)
-                .withLabel("tekton.dev/pipeline", pipelineName)
-                .list().getItems().stream().sorted((o1, o2) -> o2.getMetadata().getCreationTimestamp().compareTo(o1.getMetadata().getCreationTimestamp()))
-                .findFirst().get();
-    }
-
-    public void stopPipelineRun(String pipelineRunName, String namespace) {
-        try {
-            LOGGER.info("Stop PipelineRun: " + pipelineRunName + " in the namespace: " + namespace);
-
-            getTaskRuns(pipelineRunName, namespace).forEach(taskRun -> {
-                taskRun.getStatus().setConditions(getCancelConditions("TaskRunCancelled"));
-                kubernetesClient().pods().inNamespace(getNamespace()).withName(taskRun.getStatus().getPodName()).delete();
-                tektonClient().v1beta1().taskRuns().inNamespace(namespace).resource(taskRun).replaceStatus();
-            });
-
-            PipelineRun run = tektonClient().v1beta1().pipelineRuns().inNamespace(namespace).withName(pipelineRunName).get();
-            run.getStatus().setConditions(getCancelConditions("CancelledRunFinally"));
-            tektonClient().v1beta1().pipelineRuns().inNamespace(namespace).resource(run).replaceStatus();
-        } catch (Exception ex) {
-            LOGGER.error(ex.getMessage());
+        try (KubernetesClient client = kubernetesClient()) {
+            return client.pods().inNamespace(getNamespace()).withName(podName).tailingLines(100).watchLog();
         }
     }
 
@@ -268,35 +272,35 @@ public class KubernetesService implements HealthCheck {
     }
 
     public void rolloutDeployment(String name, String namespace) {
-        try {
-            kubernetesClient().apps().deployments().inNamespace(namespace).withName(name).rolling().restart();
+        try (KubernetesClient client = kubernetesClient()) {
+            client.apps().deployments().inNamespace(namespace).withName(name).rolling().restart();
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
         }
     }
 
     public void deleteDeployment(String name, String namespace) {
-        try {
+        try (KubernetesClient client = kubernetesClient()) {
             LOGGER.info("Delete deployment: " + name + " in the namespace: " + namespace);
-            kubernetesClient().apps().deployments().inNamespace(namespace).withName(name).delete();
-            kubernetesClient().services().inNamespace(namespace).withName(name).delete();
+            client.apps().deployments().inNamespace(namespace).withName(name).delete();
+            client.services().inNamespace(namespace).withName(name).delete();
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
         }
     }
 
-    public void deletePod(String name, String namespace) {
-        try {
-            LOGGER.info("Delete pod: " + name + " in the namespace: " + namespace);
-            kubernetesClient().pods().inNamespace(namespace).withName(name).delete();
+    public void deletePod(String name) {
+        try (KubernetesClient client = kubernetesClient()) {
+            LOGGER.info("Delete pod: " + name);
+            client.pods().inNamespace(getNamespace()).withName(name).delete();
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
         }
     }
 
     public Deployment getDeployment(String name, String namespace) {
-        try {
-            return kubernetesClient().apps().deployments().inNamespace(namespace).withName(name).get();
+        try (KubernetesClient client = kubernetesClient()) {
+            return client.apps().deployments().inNamespace(namespace).withName(name).get();
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
             return null;
@@ -304,8 +308,8 @@ public class KubernetesService implements HealthCheck {
     }
 
     public boolean hasDeployment(String name, String namespace) {
-        try {
-            Deployment deployment = kubernetesClient().apps().deployments().inNamespace(namespace).withName(name).get();
+        try (KubernetesClient client = kubernetesClient()) {
+            Deployment deployment = client.apps().deployments().inNamespace(namespace).withName(name).get();
             return deployment != null;
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
@@ -314,8 +318,8 @@ public class KubernetesService implements HealthCheck {
     }
 
     public List<String> getCamelDeployments(String namespace) {
-        try {
-            return kubernetesClient().apps().deployments().inNamespace(namespace).withLabels(getRuntimeLabels()).list().getItems()
+        try (KubernetesClient client = kubernetesClient()) {
+            return client.apps().deployments().inNamespace(namespace).withLabels(getRuntimeLabels()).list().getItems()
                     .stream().map(deployment -> deployment.getMetadata().getName()).collect(Collectors.toList());
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
@@ -333,8 +337,8 @@ public class KubernetesService implements HealthCheck {
 
     public List<String> getConfigMaps(String namespace) {
         List<String> result = new ArrayList<>();
-        try {
-            kubernetesClient().configMaps().inNamespace(namespace).list().getItems().forEach(configMap -> {
+        try (KubernetesClient client = kubernetesClient()) {
+            client.configMaps().inNamespace(namespace).list().getItems().forEach(configMap -> {
                 String name = configMap.getMetadata().getName();
                 if (configMap.getData() != null) {
                     configMap.getData().keySet().forEach(data -> result.add(name + "/" + data));
@@ -348,8 +352,8 @@ public class KubernetesService implements HealthCheck {
 
     public List<String> getSecrets(String namespace) {
         List<String> result = new ArrayList<>();
-        try {
-            kubernetesClient().secrets().inNamespace(namespace).list().getItems().forEach(secret -> {
+        try (KubernetesClient client = kubernetesClient()) {
+            client.secrets().inNamespace(namespace).list().getItems().forEach(secret -> {
                 String name = secret.getMetadata().getName();
                 if (secret.getData() != null) {
                     secret.getData().keySet().forEach(data -> result.add(name + "/" + data));
@@ -363,8 +367,8 @@ public class KubernetesService implements HealthCheck {
 
     public List<String> getServices(String namespace) {
         List<String> result = new ArrayList<>();
-        try {
-            kubernetesClient().services().inNamespace(namespace).list().getItems().forEach(service -> {
+        try (KubernetesClient client = kubernetesClient()) {
+            client.services().inNamespace(namespace).list().getItems().forEach(service -> {
                 String name = service.getMetadata().getName();
                 String host = name + "." + namespace + ".svc.cluster.local";
                 service.getSpec().getPorts().forEach(port -> result.add(name + "|" + host + ":" + port.getPort()));
@@ -394,26 +398,29 @@ public class KubernetesService implements HealthCheck {
 
     public void runDevModeContainer(Project project, String jBangOptions) {
         String name = project.getProjectId();
-        createPVC(name);
-        Pod old = kubernetesClient().pods().inNamespace(getNamespace()).withName(name).get();
-        if (old == null) {
-            ProjectFile properties = infinispanService.getProjectFile(project.getProjectId(), APPLICATION_PROPERTIES_FILENAME);
-            Map<String, String> containerResources = CodeService
-                    .getRunnerContainerResourcesMap(properties, isOpenshift(), project.getRuntime().equals("quarkus"));
-            Pod pod = getRunnerPod(project.getProjectId(), name, jBangOptions, containerResources);
-            Pod result = kubernetesClient().resource(pod).createOrReplace();
-            LOGGER.info("Created pod " + result.getMetadata().getName());
+        Map<String, String> labels = getLabels(name, project, ContainerStatus.ContainerType.devmode);
+        try (KubernetesClient client = kubernetesClient()) {
+            createPVC(name, labels);
+            Pod old = client.pods().inNamespace(getNamespace()).withName(name).get();
+            if (old == null) {
+                ProjectFile properties = infinispanService.getProjectFile(project.getProjectId(), APPLICATION_PROPERTIES_FILENAME);
+                Map<String, String> containerResources = CodeService
+                        .getRunnerContainerResourcesMap(properties, isOpenshift(), project.getRuntime().equals("quarkus"));
+                Pod pod = getDevModePod(name, jBangOptions, containerResources, labels);
+                Pod result = client.resource(pod).createOrReplace();
+                LOGGER.info("Created pod " + result.getMetadata().getName());
+            }
         }
-        createService(name);
+        createService(name, labels);
     }
 
     public void deleteDevModePod(String name, boolean deletePVC) {
-        try {
+        try (KubernetesClient client = kubernetesClient()) {
             LOGGER.info("Delete devmode pod: " + name + " in the namespace: " + getNamespace());
-            kubernetesClient().pods().inNamespace(getNamespace()).withName(name).delete();
-            kubernetesClient().services().inNamespace(getNamespace()).withName(name).delete();
+            client.pods().inNamespace(getNamespace()).withName(name).delete();
+            client.services().inNamespace(getNamespace()).withName(name).delete();
             if (deletePVC) {
-                kubernetesClient().persistentVolumeClaims().inNamespace(getNamespace()).withName(name).delete();
+                client.persistentVolumeClaims().inNamespace(getNamespace()).withName(name).delete();
             }
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
@@ -429,13 +436,7 @@ public class KubernetesService implements HealthCheck {
                 .build();
     }
 
-    private Pod getRunnerPod(String projectId, String name, String jbangOptions, Map<String, String> containerResources) {
-        Map<String, String> labels = new HashMap<>();
-        labels.putAll(getRuntimeLabels());
-        labels.putAll(getKaravanRunnerLabels(name));
-        labels.put(LABEL_PROJECT_ID, projectId);
-        labels.put(LABEL_TYPE, ContainerStatus.ContainerType.devmode.name());
-
+    private Pod getDevModePod(String name, String jbangOptions, Map<String, String> containerResources, Map<String, String> labels) {
         ResourceRequirements resources = getResourceRequirements(containerResources);
 
         ObjectMeta meta = new ObjectMetaBuilder()
@@ -482,80 +483,69 @@ public class KubernetesService implements HealthCheck {
                 .build();
     }
 
-    private void createPVC(String podName) {
-        PersistentVolumeClaim old = kubernetesClient().persistentVolumeClaims().inNamespace(getNamespace()).withName(podName).get();
-        if (old == null) {
-            PersistentVolumeClaim pvc = new PersistentVolumeClaimBuilder()
+    private void createPVC(String podName, Map<String, String> labels) {
+        try (KubernetesClient client = kubernetesClient()) {
+            PersistentVolumeClaim old = client.persistentVolumeClaims().inNamespace(getNamespace()).withName(podName).get();
+            if (old == null) {
+                PersistentVolumeClaim pvc = new PersistentVolumeClaimBuilder()
+                        .withNewMetadata()
+                        .withName(podName)
+                        .withNamespace(getNamespace())
+                        .withLabels(labels)
+                        .endMetadata()
+                        .withNewSpec()
+                        .withResources(new ResourceRequirementsBuilder().withRequests(Map.of("storage", new Quantity("2Gi"))).build())
+                        .withVolumeMode("Filesystem")
+                        .withAccessModes("ReadWriteOnce")
+                        .endSpec()
+                        .build();
+                client.resource(pvc).createOrReplace();
+            }
+        }
+    }
+
+    private void createService(String name, Map<String, String> labels) {
+        try (KubernetesClient client = kubernetesClient()) {
+            ServicePortBuilder portBuilder = new ServicePortBuilder()
+                    .withName("http").withPort(80).withProtocol("TCP").withTargetPort(new IntOrString(8080));
+
+            Service service = new ServiceBuilder()
                     .withNewMetadata()
-                    .withName(podName)
+                    .withName(name)
                     .withNamespace(getNamespace())
-                    .withLabels(getKaravanRunnerLabels(podName))
+                    .withLabels(labels)
                     .endMetadata()
                     .withNewSpec()
-                    .withResources(new ResourceRequirementsBuilder().withRequests(Map.of("storage", new Quantity("2Gi"))).build())
-                    .withVolumeMode("Filesystem")
-                    .withAccessModes("ReadWriteOnce")
+                    .withType("ClusterIP")
+                    .withPorts(portBuilder.build())
+                    .withSelector(labels)
                     .endSpec()
                     .build();
-            kubernetesClient().resource(pvc).createOrReplace();
+            client.resource(service).createOrReplace();
         }
     }
 
-    private void createService(String name) {
-
-        ServicePortBuilder portBuilder = new ServicePortBuilder()
-                .withName("http").withPort(80).withProtocol("TCP").withTargetPort(new IntOrString(8080));
-
-        Service service = new ServiceBuilder()
-                .withNewMetadata()
-                .withName(name)
-                .withNamespace(getNamespace())
-                .withLabels(getKaravanRunnerLabels(name))
-                .endMetadata()
-                .withNewSpec()
-                .withType("ClusterIP")
-                .withPorts(portBuilder.build())
-                .withSelector(getKaravanRunnerLabels(name))
-                .endSpec()
-                .build();
-        kubernetesClient().resource(service).createOrReplace();
-    }
-
     public Secret getKaravanSecret() {
-        return kubernetesClient().secrets().inNamespace(getNamespace()).withName("karavan").get();
-    }
-
-    public Map<String, String> getRuntimeLabels() {
-        Map<String, String> result = new HashMap<>();
-        result.put(getRuntimeLabelName(), CAMEL_PREFIX);
-        return result;
-    }
-
-    public String getRuntimeLabelName() {
-        return isOpenshift() ? "app.openshift.io/runtime" : "app.kubernetes.io/runtime";
-    }
-
-    public Map<String, String> getRuntimeLabels(Map<String, String> add) {
-        Map<String, String> map = getRuntimeLabels();
-        map.putAll(add);
-        return map;
-    }
-
-    public static Map<String, String> getKaravanRunnerLabels(String name) {
-        return Map.of(LABEL_TYPE, ContainerStatus.ContainerType.devmode.name(),
-                "app.kubernetes.io/name", name);
+        try (KubernetesClient client = kubernetesClient()) {
+            return client.secrets().inNamespace(getNamespace()).withName("karavan").get();
+        }
     }
 
     public boolean isOpenshift() {
-        return ConfigService.inKubernetes() ? kubernetesClient().isAdaptable(OpenShiftClient.class) : false;
+        try (KubernetesClient client = kubernetesClient()) {
+            return ConfigService.inKubernetes() ? client.isAdaptable(OpenShiftClient.class) : false;
+        }
     }
 
     public String getCluster() {
-        return kubernetesClient().getMasterUrl().getHost();
+        try (KubernetesClient client = kubernetesClient()) {
+            return client.getMasterUrl().getHost();
+        }
     }
 
     public String getNamespace() {
-        return kubernetesClient().getNamespace();
+        try (KubernetesClient client = kubernetesClient()) {
+            return client.getNamespace();
+        }
     }
-
 }
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/PipelineRunEventHandler.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/PipelineRunEventHandler.java
deleted file mode 100644
index 9dcf5c1f..00000000
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/PipelineRunEventHandler.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.apache.camel.karavan.kubernetes;
-
-import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
-import io.fabric8.tekton.pipeline.v1beta1.PipelineRun;
-import org.apache.camel.karavan.infinispan.InfinispanService;
-import org.apache.camel.karavan.infinispan.model.PipelineStatus;
-import org.apache.camel.karavan.infinispan.model.Project;
-import org.jboss.logging.Logger;
-
-import java.time.Instant;
-
-public class PipelineRunEventHandler implements ResourceEventHandler<PipelineRun> {
-
-    private static final Logger LOGGER = Logger.getLogger(PipelineRunEventHandler.class.getName());
-    private InfinispanService infinispanService;
-    private KubernetesService kubernetesService;
-
-    public PipelineRunEventHandler(InfinispanService infinispanService, KubernetesService kubernetesService) {
-        this.infinispanService = infinispanService;
-        this.kubernetesService = kubernetesService;
-    }
-
-    @Override
-    public void onAdd(PipelineRun pipelineRun) {
-        try {
-            LOGGER.info("onAdd " + pipelineRun.getMetadata().getName());
-            PipelineStatus ps = getPipelineStatus(pipelineRun);
-            if (ps != null) infinispanService.savePipelineStatus(ps);
-        } catch (Exception e){
-            LOGGER.error(e.getMessage());
-        }
-    }
-
-    @Override
-    public void onUpdate(PipelineRun oldPipelineRun, PipelineRun newPipelineRun) {
-        try {
-            LOGGER.info("onUpdate " + newPipelineRun.getMetadata().getName());
-            PipelineStatus ps = getPipelineStatus(newPipelineRun);
-            if (ps != null) infinispanService.savePipelineStatus(ps);
-        } catch (Exception e){
-            LOGGER.error(e.getMessage());
-        }
-    }
-
-    @Override
-    public void onDelete(PipelineRun pipelineRun, boolean deletedFinalStateUnknown) {
-        try {
-            LOGGER.info("onDelete " + pipelineRun.getMetadata().getName());
-            String projectId = pipelineRun.getMetadata().getLabels().get("karavan-project-id");
-            if (projectId != null) {
-                Project project = infinispanService.getProject(projectId);
-                if (project != null) {
-                    PipelineStatus ps = new PipelineStatus(project.getProjectId(), kubernetesService.environment);
-                    infinispanService.deletePipelineStatus(ps);
-                }
-            }
-        } catch (Exception e){
-            LOGGER.error(e.getMessage());
-        }
-    }
-
-    public PipelineStatus getPipelineStatus( PipelineRun pipelineRun) {
-        String projectId = pipelineRun.getMetadata().getLabels().get("karavan-project-id");
-        if (projectId != null) {
-            Project project = infinispanService.getProject(projectId);
-            if (project != null) {
-                PipelineStatus pipelineStatus = new PipelineStatus(project.getProjectId(), kubernetesService.environment);
-
-                if (pipelineRun.getStatus() != null) {
-                    Instant runStartTime = Instant.parse(pipelineRun.getStatus().getStartTime());
-                    Instant savedStartTime = pipelineStatus.getStartTime() != null
-                            ? Instant.parse(pipelineStatus.getStartTime())
-                            : Instant.MIN;
-
-                    if (runStartTime.isAfter(savedStartTime) || pipelineRun.getMetadata().getName().equals(pipelineStatus.getPipelineName())) {
-                        pipelineStatus.setPipelineName(pipelineRun.getMetadata().getName());
-                        pipelineStatus.setResult(pipelineRun.getStatus().getConditions().get(0).getReason());
-                        pipelineStatus.setStartTime(pipelineRun.getStatus().getStartTime());
-                        pipelineStatus.setCompletionTime(pipelineRun.getStatus().getCompletionTime());
-                    }
-                } else {
-                    pipelineStatus.setPipelineName(pipelineRun.getMetadata().getName());
-                    pipelineStatus.setResult(null);
-                    pipelineStatus.setStartTime(null);
-                    pipelineStatus.setCompletionTime(null);
-                }
-                return pipelineStatus;
-            }
-        }
-        return null;
-    }
-}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
index 6f3cac08..1a6a698a 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.karavan.service;
 
-import io.smallrye.mutiny.tuples.Tuple2;
 import io.vertx.core.json.JsonObject;
 import io.vertx.mutiny.core.eventbus.EventBus;
 import org.apache.camel.karavan.code.CodeService;
@@ -31,7 +30,6 @@ import org.apache.camel.karavan.infinispan.model.*;
 import org.apache.camel.karavan.kubernetes.KubernetesService;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
-import org.eclipse.microprofile.faulttolerance.Retry;
 import org.eclipse.microprofile.health.HealthCheck;
 import org.eclipse.microprofile.health.HealthCheckResponse;
 import org.eclipse.microprofile.health.Readiness;
@@ -125,27 +123,20 @@ public class ProjectService implements HealthCheck {
         }
     }
 
-    public String buildProject(Project project, String tag) throws Exception {
+    public void buildProject(Project project, String tag) throws Exception {
+        String templateName = project.getRuntime() + "-builder-script-docker.sh";
+        String script = codeService.getTemplateText(templateName);
+
+        tag = tag != null && !tag.isEmpty() && !tag.isBlank()
+                ? tag
+                : Instant.now().toString().substring(0, 19).replace(":", "-");
+
+        List<String> env = getEnvForBuild(project, tag);
         if (ConfigService.inKubernetes()) {
-            return kubernetesService.createPipelineRun(project);
+            kubernetesService.runBuildProject(project, script, env, tag);
         } else {
-            Map<String, String> files = infinispanService.getProjectFiles(project.getProjectId()).stream()
-                    .filter(f -> !Objects.equals(f.getName(), PROJECT_COMPOSE_FILENAME))
-                    .collect(Collectors.toMap(ProjectFile::getName, ProjectFile::getCode));
-
-            String templateName = project.getRuntime() + "-builder-script-docker.sh";
-            String script = codeService.getTemplateText(templateName);
-
-            tag = tag != null && !tag.isEmpty() && !tag.isBlank()
-                    ? tag
-                    : Instant.now().toString().substring(0, 19).replace(":", "-");
-
-            List<String> env = getEnvForBuild(project, tag);
-            Map<String, String> volumes = mavenCache
-                    .map(s -> Map.of(s, "/root/.m2"))
-                    .orElseGet(Map::of);
-            dockerForKaravan.runBuildProject(project.getProjectId(), script, files, env, volumes, tag);
-            return project.getProjectId();
+            Map<String, String> volumes = mavenCache.map(s -> Map.of(s, "/root/.m2")).orElseGet(Map::of);
+            dockerForKaravan.runBuildProject(project, script, env, volumes, tag);
         }
     }
 
@@ -181,7 +172,7 @@ public class ProjectService implements HealthCheck {
         Optional<ProjectFile> file = files.stream().filter(f -> Objects.equals(f.getProjectId(), projectId)).findFirst();
         if (file.isPresent()) {
             DockerComposeService service = DockerComposeConverter.fromCode(file.get().getCode(), projectId);
-            String image =  service.getImage();
+            String image = service.getImage();
             return Objects.equals(image, projectId) ? null : image;
         } else {
             return null;
@@ -207,7 +198,7 @@ public class ProjectService implements HealthCheck {
         return codeService.getProjectPort(composeFile);
     }
 
-//    @Retry(maxRetries = 100, delay = 2000)
+    //    @Retry(maxRetries = 100, delay = 2000)
     public void tryStart() throws Exception {
         if (infinispanService.isReady() && gitService.checkGit()) {
             if (infinispanService.getProjects().isEmpty()) {
@@ -234,8 +225,6 @@ public class ProjectService implements HealthCheck {
                     project = new Project(Project.Type.templates.name(), "Templates", "Templates", "", repo.getCommitId(), repo.getLastCommitTimestamp(), Project.Type.templates);
                 } else if (folderName.equals(Project.Type.kamelets.name())) {
                     project = new Project(Project.Type.kamelets.name(), "Custom Kamelets", "Custom Kamelets", "", repo.getCommitId(), repo.getLastCommitTimestamp(), Project.Type.kamelets);
-                } else if (folderName.equals(Project.Type.pipelines.name())) {
-                    project = new Project(Project.Type.pipelines.name(), "Pipelines", "CI/CD Pipelines", "", repo.getCommitId(), repo.getLastCommitTimestamp(), Project.Type.pipelines);
                 } else if (folderName.equals(Project.Type.services.name())) {
                     project = new Project(Project.Type.services.name(), "Services", "Development Services", "", repo.getCommitId(), repo.getLastCommitTimestamp(), Project.Type.services);
                 } else {
@@ -353,25 +342,6 @@ public class ProjectService implements HealthCheck {
         }
     }
 
-    void addPipelinesProject() {
-        LOGGER.info("Add pipelines project if not exists");
-        try {
-            Project pipelines = infinispanService.getProject(Project.Type.pipelines.name());
-            if (pipelines == null) {
-                pipelines = new Project(Project.Type.pipelines.name(), "Pipelines", "CI/CD Pipelines", "", "", Instant.now().toEpochMilli(), Project.Type.pipelines);
-                infinispanService.saveProject(pipelines);
-
-                codeService.getTemplates().forEach((name, value) -> {
-                    ProjectFile file = new ProjectFile(name, value, Project.Type.pipelines.name(), Instant.now().toEpochMilli());
-                    infinispanService.saveProjectFile(file);
-                });
-                commitAndPushProject(Project.Type.pipelines.name(), "Add default pipelines");
-            }
-        } catch (Exception e) {
-            LOGGER.error("Error during pipelines project creation", e);
-        }
-    }
-
     public String getDevServiceCode() {
         List<ProjectFile> files = infinispanService.getProjectFiles(Project.Type.services.name());
         Optional<ProjectFile> file = files.stream().filter(f -> f.getName().equals(DEV_SERVICES_FILENAME)).findFirst();
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java
index 1b339060..68d1361e 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java
@@ -20,8 +20,10 @@ public class Constants {
 
     public static final String ENV_VAR_JBANG_OPTIONS = "JBANG_OPTIONS";
 
+    public static final String LABEL_PART_OF = "app.kubernetes.io/part-of";
     public static final String LABEL_TYPE = "org.apache.camel.karavan/type";
     public static final String LABEL_PROJECT_ID = "org.apache.camel.karavan/projectId";
+    public static final String LABEL_PROJECT_RUNTIME = "org.apache.camel.karavan/projectRuntime";
     public static final String LABEL_TAG = "org.apache.camel.karavan/tag";
 
     public static final String BUILDER_SUFFIX = "-builder";
diff --git a/karavan-web/karavan-app/src/main/resources/pipelines/karavan-pipeline-dev-quarkus.yaml b/karavan-web/karavan-app/src/main/resources/pipelines/karavan-pipeline-dev-quarkus.yaml
deleted file mode 100644
index 7d063ba0..00000000
--- a/karavan-web/karavan-app/src/main/resources/pipelines/karavan-pipeline-dev-quarkus.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-apiVersion: tekton.dev/v1beta1
-kind: Pipeline
-metadata:
-  name: karavan-pipeline-dev-quarkus
-spec:
-  params:
-    - description: ProjectId
-      name: PROJECT_ID
-      type: string
-  tasks:
-    - name: karavan-task-dev-quarkus
-      params:
-        - name: project
-          value: $(params.PROJECT_ID)
-      taskRef:
-        kind: Task
-        name: karavan-task-dev-quarkus
-      workspaces:
-        - name: karavan-m2-cache
-          workspace: karavan-m2-cache
-        - name: karavan-jbang-cache
-          workspace: karavan-jbang-cache
-  workspaces:
-    - description: Maven Cache
-      name: karavan-m2-cache
-    - description: JBang Cache
-      name: karavan-jbang-cache
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/resources/pipelines/karavan-pipeline-dev-spring-boot.yaml b/karavan-web/karavan-app/src/main/resources/pipelines/karavan-pipeline-dev-spring-boot.yaml
deleted file mode 100644
index 6c50b4bb..00000000
--- a/karavan-web/karavan-app/src/main/resources/pipelines/karavan-pipeline-dev-spring-boot.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-apiVersion: tekton.dev/v1beta1
-kind: Pipeline
-metadata:
-  name: karavan-pipeline-dev-spring-boot
-spec:
-  params:
-    - description: ProjectId
-      name: PROJECT_ID
-      type: string
-  tasks:
-    - name: karavan-task-dev-spring-boot
-      params:
-        - name: project
-          value: $(params.PROJECT_ID)
-      taskRef:
-        kind: Task
-        name: karavan-task-dev-spring-boot
-      workspaces:
-        - name: karavan-m2-cache
-          workspace: karavan-m2-cache
-        - name: karavan-jbang-cache
-          workspace: karavan-jbang-cache
-  workspaces:
-    - description: Maven Cache
-      name: karavan-m2-cache
-    - description: JBang Cache
-      name: karavan-jbang-cache
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/resources/pipelines/karavan-task-dev-quarkus.yaml b/karavan-web/karavan-app/src/main/resources/pipelines/karavan-task-dev-quarkus.yaml
deleted file mode 100644
index 8ca8ec4f..00000000
--- a/karavan-web/karavan-app/src/main/resources/pipelines/karavan-task-dev-quarkus.yaml
+++ /dev/null
@@ -1,90 +0,0 @@
-apiVersion: tekton.dev/v1beta1
-kind: Task
-metadata:
-  name: karavan-task-dev-quarkus
-spec:
-  params:
-    - description: ProjectId
-      name: project
-      type: string
-  steps:
-    - env:
-        - name: GIT_REPOSITORY
-          valueFrom:
-            secretKeyRef:
-              key: git-repository
-              name: karavan
-        - name: GIT_USERNAME
-          valueFrom:
-            secretKeyRef:
-              key: git-username
-              name: karavan
-        - name: GIT_PASSWORD
-          valueFrom:
-            secretKeyRef:
-              key: git-password
-              name: karavan
-        - name: GIT_BRANCH
-          valueFrom:
-            secretKeyRef:
-              key: git-branch
-              name: karavan
-        - name: IMAGE_REGISTRY
-          valueFrom:
-            secretKeyRef:
-              key: image-registry
-              name: karavan
-              optional: true
-      image: 'ghcr.io/apache/camel-karavan-builder:3.20.0'
-      name: karavan-build-deploy
-      script: >-
-        #!/usr/bin/env bash
-        CHECKOUT_DIR="/scripts"
-        KAMELETS_DIR="/scripts/kamelets"
-
-        if  [[ $GIT_REPOSITORY == https* ]] ;
-        then
-            replacer=https://$GIT_USERNAME:$GIT_PASSWORD@
-            prefix=https://
-            url="${GIT_REPOSITORY/$prefix/$replacer}"
-            git clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}
-        else
-            git clone --depth 1 --branch ${GIT_BRANCH} ${GIT_REPOSITORY} ${CHECKOUT_DIR}
-        fi
-
-        cd ${CHECKOUT_DIR}/$(inputs.params.project)
-
-        entrypoint -Dcamel.jbang.version=4.0.0-RC2 camel@apache/camel export
-        --local-kamelet-dir=${KAMELETS_DIR}
-
-        export LAST_COMMIT=$(git rev-parse --short HEAD)
-        export DATE=$(date '+%Y%m%d%H%M%S')
-        export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
-
-        export NAMESPACE=$(cat
-        /var/run/secrets/kubernetes.io/serviceaccount/namespace)
-
-        /opt/mvnd/bin/mvnd package \
-          -Dquarkus.container-image.build=true \
-          -Dquarkus.container-image.push=true \
-          -Dquarkus.container-image.insecure=true \
-          -Dquarkus.container-image.username=sa \
-          -Dquarkus.container-image.password=${TOKEN} \
-          -Dquarkus.container-image.registry=${IMAGE_REGISTRY} \
-          -Dquarkus.container-image.builder=jib \
-          -Dquarkus.kubernetes-client.master-url=kubernetes.default.svc \
-          -Dquarkus.kubernetes-client.token=${TOKEN} \
-          -Dquarkus.kubernetes.deploy=true \
-          -Dquarkus.openshift.deployment-kind=Deployment \
-          -Dquarkus.openshift.add-version-to-label-selectors=false \
-          -Dquarkus.openshift.labels.\"app\"=$(inputs.params.project) \
-          -Dquarkus.openshift.labels.\"app.openshift.io/runtime\"=camel \
-          -Dquarkus.container-image.group=${NAMESPACE} \
-          -Dquarkus.container-image.tag=${DATE}
-  workspaces:
-    - description: Maven Cache
-      mountPath: /root/.m2
-      name: karavan-m2-cache
-    - description: JBang Cache
-      mountPath: /jbang/.jbang/cache
-      name: karavan-jbang-cache
diff --git a/karavan-web/karavan-app/src/main/resources/pipelines/karavan-task-dev-spring-boot.yaml b/karavan-web/karavan-app/src/main/resources/pipelines/karavan-task-dev-spring-boot.yaml
deleted file mode 100644
index 84b32928..00000000
--- a/karavan-web/karavan-app/src/main/resources/pipelines/karavan-task-dev-spring-boot.yaml
+++ /dev/null
@@ -1,78 +0,0 @@
-apiVersion: tekton.dev/v1beta1
-kind: Task
-metadata:
-  name: karavan-task-dev-spring-boot
-spec:
-  params:
-    - description: ProjectId
-      name: project
-      type: string
-  steps:
-    - env:
-        - name: GIT_REPOSITORY
-          valueFrom:
-            secretKeyRef:
-              key: git-repository
-              name: karavan
-        - name: GIT_USERNAME
-          valueFrom:
-            secretKeyRef:
-              key: git-username
-              name: karavan
-        - name: GIT_PASSWORD
-          valueFrom:
-            secretKeyRef:
-              key: git-password
-              name: karavan
-        - name: GIT_BRANCH
-          valueFrom:
-            secretKeyRef:
-              key: git-branch
-              name: karavan
-        - name: IMAGE_REGISTRY
-          valueFrom:
-            secretKeyRef:
-              key: image-registry
-              name: karavan
-              optional: true
-      image: 'ghcr.io/apache/camel-karavan-builder:3.20.0'
-      name: karavan-build-deploy
-      script: >-
-        #!/usr/bin/env bash
-        CHECKOUT_DIR="/scripts"
-        KAMELETS_DIR="/scripts/kamelets"
-
-        if  [[ $GIT_REPOSITORY == https* ]] ;
-        then
-            replacer=https://$GIT_USERNAME:$GIT_PASSWORD@
-            prefix=https://
-            url="${GIT_REPOSITORY/$prefix/$replacer}"
-            git clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}
-        else
-            git clone --depth 1 --branch ${GIT_BRANCH} ${GIT_REPOSITORY} ${CHECKOUT_DIR}
-        fi
-
-        cd ${CHECKOUT_DIR}/$(inputs.params.project)
-
-        entrypoint -Dcamel.jbang.version=4.0.0-RC2 camel@apache/camel export
-        --local-kamelet-dir=${KAMELETS_DIR}
-
-        export LAST_COMMIT=$(git rev-parse --short HEAD)
-        export DATE=$(date '+%Y%m%d%H%M%S')
-        export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
-
-        export NAMESPACE=$(cat
-        /var/run/secrets/kubernetes.io/serviceaccount/namespace)
-
-        /opt/mvnd/bin/mvnd package oc:build oc:push oc:resource oc:apply \
-          -Popenshift \
-          -Djkube.namespace=${NAMESPACE} \
-          -Djkube.docker.push.registry=${IMAGE_REGISTRY} \
-          -Djkube.generator.name=${IMAGE_REGISTRY}/${NAMESPACE}/$(inputs.params.project):${DATE}
-  workspaces:
-    - description: Maven Cache
-      mountPath: /root/.m2
-      name: karavan-m2-cache
-    - description: JBang Cache
-      mountPath: /jbang/.jbang/cache
-      name: karavan-jbang-cache
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx b/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx
index 05915131..af9487a0 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx
@@ -3,7 +3,6 @@ import {
     AppConfig,
     CamelStatus,
     DeploymentStatus,
-    PipelineStatus,
     ContainerStatus,
     Project,
     ProjectFile, ProjectType, ServiceStatus
@@ -169,20 +168,6 @@ export class KaravanApi {
         });
     }
 
-    static async getPipelineStatuses(env: string, after: (status: PipelineStatus[]) => void) {
-        instance.get('/api/status/pipeline/' + env)
-            .then(res => {
-                if (res.status === 200) {
-                    after(res.data);
-                } else if (res.status === 204) {
-                    after([]);
-                }
-
-            }).catch(err => {
-            console.log(err);
-        });
-    }
-
     static async getProjectDeploymentStatus(projectId: string, env: string, after: (status?: DeploymentStatus) => void) {
         instance.get('/api/status/deployment/' + projectId + "/" + env)
             .then(res => {
@@ -380,26 +365,6 @@ export class KaravanApi {
         });
     }
 
-    static async pipelineRun(project: Project, environment: string, after: (res: AxiosResponse<any>) => void) {
-        instance.post('/api/infrastructure/pipeline/' + environment, project)
-            .then(res => {
-                after(res);
-            }).catch(err => {
-            after(err);
-        });
-    }
-
-    static async getPipelineLog(environment: string, pipelineRunName: string, after: (res: AxiosResponse<any>) => void) {
-        instance.get('/api/infrastructure/pipeline/log/' + environment + "/" + pipelineRunName)
-            .then(res => {
-                if (res.status === 200) {
-                    after(res.data);
-                }
-            }).catch(err => {
-            console.log(err);
-        });
-    }
-
     static async stopBuild(environment: string, buildName: string, after: (res: AxiosResponse<any>) => void) {
         instance.delete('/api/project/build/' + environment + "/" + buildName)
             .then(res => {
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectEventBus.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectEventBus.ts
index 2c8f98ce..dcbc6c6e 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectEventBus.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectEventBus.ts
@@ -23,13 +23,11 @@ const mode = new BehaviorSubject<"design" | "code">("design");
 const log = new Subject<["add" | "set", string]>();
 
 export class ShowLogCommand {
-    type: 'container' | 'pipeline'
     name: string
     environment: string
     show: boolean
 
-    constructor(type: "container" | "pipeline", name: string, environment: string, show: boolean) {
-        this.type = type;
+    constructor(name: string, environment: string, show: boolean) {
         this.name = name;
         this.environment = environment;
         this.show = show;
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectModels.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectModels.ts
index 6ca10133..e81b4202 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectModels.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectModels.ts
@@ -12,7 +12,6 @@ export enum ProjectType {
     templates ='templates',
     kamelets ='kamelets',
     services ='services',
-    pipelines ='pipelines',
     normal ='normal',
 }
 
@@ -96,14 +95,6 @@ export class CamelStatus {
     env: string = '';
 }
 
-export class PipelineStatus {
-    projectId: string = '';
-    pipelineName: string = '';
-    result: string = '';
-    startTime: string = '';
-    completionTime: string = '';
-}
-
 export class ProjectFile {
     name: string = '';
     projectId: string = '';
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
index 42939630..78b066ab 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
@@ -15,7 +15,6 @@
  * limitations under the License.
  */
 
-import {create} from 'zustand'
 import {
     AppConfig,
     DeploymentStatus,
@@ -24,7 +23,6 @@ import {
     ProjectFile,
     ServiceStatus,
     CamelStatus,
-    PipelineStatus
 } from "./ProjectModels";
 import {ProjectEventBus} from "./ProjectEventBus";
 import {unstable_batchedUpdates} from "react-dom";
@@ -246,8 +244,6 @@ interface StatusesState {
     setServices: (s: ServiceStatus[]) => void;
     setContainers: (c: ContainerStatus[]) => void;
     setCamels: (c: CamelStatus[]) => void;
-    pipelineStatuses: PipelineStatus[],
-    setPipelineStatuses: (pipelineStatus: PipelineStatus[]) => void;
 }
 
 export const useStatusesStore = createWithEqualityFn<StatusesState>((set) => ({
@@ -275,10 +271,6 @@ export const useStatusesStore = createWithEqualityFn<StatusesState>((set) => ({
             camels: c,
         }));
     },
-    pipelineStatuses: [],
-    setPipelineStatuses: (pipelineStatuses: PipelineStatus[])  => {
-        set({pipelineStatuses: pipelineStatuses})
-    },
 }), shallow)
 
 interface LogState {
diff --git a/karavan-web/karavan-app/src/main/webui/src/index.css b/karavan-web/karavan-app/src/main/webui/src/index.css
index 45542add..480fec25 100644
--- a/karavan-web/karavan-app/src/main/webui/src/index.css
+++ b/karavan-web/karavan-app/src/main/webui/src/index.css
@@ -246,34 +246,10 @@
   color: white;
 }
 
-.karavan .project-page .pipeline {
-  background-color: #f5f5f5;
-  border-radius: 24px;
-  font-size: 12px;
-  font-weight: bold;
-  width: fit-content;
-  padding-right: 8px;
-  padding-left: 8px;
-}
-
-.karavan .project-page .pipeline-running {
-  background-color: rgb(139, 193, 247);
-}
-
-.karavan .project-page .pipeline-succeeded {
-  background-color: rgb(56, 129, 47);
-  color: white;
-}
-
 .karavan .project-page .env-chart {
   font-size: 18px;
 }
 
-.karavan .project-page .pipeline-failed {
-  background-color: #C9190B;
-  color: white;
-}
-
 .karavan .project-page .replicas-ready {
   background-color: rgb(56, 129, 47);
   color: white;
@@ -284,10 +260,6 @@
   color: white;
 }
 
-.karavan .project-page .pipeline .pf-v5-c-progress-stepper__step-main {
-  display: none;
-}
-
 .karavan .project-page .project-properties .delete-cell {
   padding: 0;
   margin: 0;
diff --git a/karavan-web/karavan-app/src/main/webui/src/main/MainDataPoller.tsx b/karavan-web/karavan-app/src/main/webui/src/main/MainDataPoller.tsx
index c371444c..7dbfa64a 100644
--- a/karavan-web/karavan-app/src/main/webui/src/main/MainDataPoller.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/main/MainDataPoller.tsx
@@ -3,11 +3,9 @@ import React, {useEffect, useState} from 'react';
 import {KaravanApi} from "../api/KaravanApi";
 import '../designer/karavan.css';
 import {
-    AppConfig,
     CamelStatus,
     ContainerStatus,
     DeploymentStatus,
-    PipelineStatus,
     Project,
     ServiceStatus
 } from "../api/ProjectModels";
@@ -19,9 +17,9 @@ export function MainDataPoller () {
     const [config, setLoading, readiness, setReadiness] = useAppConfigStore((s) =>
         [s.config, s.setLoading, s.readiness, s.setReadiness], shallow)
     const [projects, setProjects] = useProjectsStore((state) => [state.projects, state.setProjects], shallow)
-    const [deployments, services, containers, camels, setDeployments, setServices, setContainers, setCamels, setPipelineStatuses]
+    const [deployments, services, containers, camels, setDeployments, setServices, setContainers, setCamels]
         = useStatusesStore((s) => [s.deployments, s.services, s.containers, s.camels,
-        s.setDeployments, s.setServices, s.setContainers, s.setCamels, s.setPipelineStatuses], shallow);
+        s.setDeployments, s.setServices, s.setContainers, s.setCamels], shallow);
 
     const [project] = useProjectStore((state) => [state.project], shallow )
 
@@ -55,9 +53,6 @@ export function MainDataPoller () {
             KaravanApi.getAllCamelStatuses(config.environment, (statuses: CamelStatus[]) => {
                 setCamels(statuses);
             });
-            KaravanApi.getPipelineStatuses(config.environment, (status: PipelineStatus[]) => {
-                setPipelineStatuses(status);
-            });
             setLoading(false);
         }
     }
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx b/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
index eb4efa03..8dd06889 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
@@ -23,8 +23,8 @@ export function BuildPanel () {
     const [config] = useAppConfigStore((state) => [state.config], shallow)
     const [project] = useProjectStore((s) => [s.project], shallow);
     const [setShowLog] = useLogStore((s) => [s.setShowLog], shallow);
-    const [containers, deployments, camels, pipelineStatuses] =
-        useStatusesStore((s) => [s.containers, s.deployments, s.camels, s.pipelineStatuses], shallow);
+    const [containers, deployments, camels] =
+        useStatusesStore((s) => [s.containers, s.deployments, s.camels], shallow);
     const [isPushing, setIsPushing] = useState<boolean>(false);
     const [isBuilding, setIsBuilding] = useState<boolean>(false);
     const [showDeleteConfirmation, setShowDeleteConfirmation] = useState<boolean>(false);
@@ -56,8 +56,8 @@ export function BuildPanel () {
     }
 
     function buildButton() {
-        const status = pipelineStatuses.filter(p => p.projectId === project.projectId).at(0);
-        const isRunning = status?.result === 'Running';
+        const status = containers.filter(c => c.projectId === project.projectId && c.type === 'build').at(0);
+        const isRunning = status?.state === 'running';
         return (<Tooltip content="Start build" position={"left"}>
             <Button isLoading={isBuilding ? true : undefined}
                     isDisabled={isBuilding || isRunning || isPushing}
@@ -111,57 +111,6 @@ export function BuildPanel () {
         )
     }
 
-    function getPipelineState(env: string) {
-        const status = pipelineStatuses.filter(p => p.projectId === project.projectId).at(0);
-        const pipeline = status?.pipelineName;
-        const pipelineResult = status?.result;
-        let lastPipelineRunTime = 0;
-        if (status?.startTime) {
-            const start: Date = new Date(status.startTime);
-            const finish: Date = status.completionTime !== undefined && status.completionTime !== null ? new Date(status.completionTime) : new Date();
-            lastPipelineRunTime = Math.round((finish.getTime() - start.getTime()) / 1000);
-        }
-        const showTime = lastPipelineRunTime && lastPipelineRunTime > 0;
-        const isRunning = pipelineResult === 'Running';
-        const isFailed = pipelineResult === 'Failed';
-        const isSucceeded = pipelineResult === 'Succeeded';
-        const color = isSucceeded ? "green" : (isFailed ? "red" : (isRunning ? "blue" : "grey"))
-        const icon = isSucceeded ? <UpIcon className="not-spinner"/> : <DownIcon className="not-spinner"/>
-        return (
-            <Flex justifyContent={{default: "justifyContentSpaceBetween"}} alignItems={{default: "alignItemsCenter"}}>
-                <FlexItem>
-                    <Tooltip content={pipelineResult} position={"right"}>
-                        <LabelGroup numLabels={2}>
-                            <Label icon={isRunning ? <Spinner diameter="16px" className="spinner"/> : icon}
-                                   color={color}>
-                                {pipeline
-                                    ? <Button className='labeled-button' variant="link" onClick={e =>
-                                        useLogStore.setState({showLog: true, type: 'build', podName: pipeline})
-                                    }>
-                                        {pipeline}
-                                    </Button>
-                                    : "No builder"}
-                                {isRunning && <Tooltip content={"Stop build"}>
-                                    <Button
-                                        icon={<DeleteIcon/>}
-                                        className="labeled-button"
-                                        variant="link" onClick={e => {
-                                        setShowDeleteConfirmation(true);
-                                        setDeleteEntityName(pipeline);
-                                    }}></Button>
-                                </Tooltip>}
-                            </Label>
-                            {pipeline !== undefined && showTime === true && lastPipelineRunTime !== undefined &&
-                                <Label icon={<ClockIcon className="not-spinner"/>}
-                                       color={color}>{lastPipelineRunTime + "s"}</Label>}
-                        </LabelGroup>
-                    </Tooltip>
-                </FlexItem>
-                <FlexItem>{buildButton()}</FlexItem>
-            </Flex>
-        )
-    }
-
     function getBuildState() {
         const status = containers.filter(c => c.projectId === project.projectId && c.type === 'build').at(0);
         const buildName = status?.containerName;
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/container/ContainerPanel.tsx b/karavan-web/karavan-app/src/main/webui/src/project/container/ContainerPanel.tsx
index f1bda323..ec1fb5ab 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/container/ContainerPanel.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/container/ContainerPanel.tsx
@@ -31,8 +31,8 @@ export function ContainerPanel (props: Props) {
 
     const [project] = useProjectStore((s) => [s.project], shallow);
     const [setShowLog] = useLogStore((s) => [s.setShowLog], shallow);
-    const [containers, deployments, camels, pipelineStatuses] =
-        useStatusesStore((s) => [s.containers, s.deployments, s.camels, s.pipelineStatuses], shallow);
+    const [containers, deployments, camels] =
+        useStatusesStore((s) => [s.containers, s.deployments, s.camels], shallow);
 
     function getButtons() {
         const env = props.env;