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 b2e88cd7505995e3add809ae0758e59455dbab60
Author: Marat Gubaidullin <marat.gubaidul...@gmail.com>
AuthorDate: Wed May 3 21:50:12 2023 -0400

    Runner prototype for #757
---
 .../apache/camel/karavan/api/RunnerResource.java   |  32 +++-
 .../DeploymentEventHandler.java                    |   3 +-
 .../PipelineRunEventHandler.java                   |   2 +-
 .../{informer => handler}/PodEventHandler.java     |  24 ++-
 .../{informer => handler}/ServiceEventHandler.java |   2 +-
 .../karavan/informer/RunnerPodEventHandler.java    |  84 -----------
 .../org/apache/camel/karavan/model/PodStatus.java  |  28 +++-
 .../camel/karavan/service/InfinispanService.java   |  13 +-
 .../camel/karavan/service/KubernetesService.java   |  34 +++--
 karavan-app/src/main/webui/src/api/KaravanApi.tsx  |   9 ++
 .../main/webui/src/projects/ProjectDevelopment.tsx |  14 +-
 .../src/main/webui/src/projects/ProjectModels.ts   |   2 +
 .../src/main/webui/src/projects/ProjectRunner.tsx  | 163 ---------------------
 .../src/main/webui/src/projects/RunnerInfoPod.tsx  | 111 ++++++++++++++
 ...{ProjectRunnerToolbar.tsx => RunnerToolbar.tsx} |   5 +-
 15 files changed, 229 insertions(+), 297 deletions(-)

diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/api/RunnerResource.java 
b/karavan-app/src/main/java/org/apache/camel/karavan/api/RunnerResource.java
index da001a54..fab2f5c8 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/api/RunnerResource.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/RunnerResource.java
@@ -16,20 +16,28 @@
  */
 package org.apache.camel.karavan.api;
 
+import org.apache.camel.karavan.model.PodStatus;
 import org.apache.camel.karavan.model.Project;
 import org.apache.camel.karavan.service.InfinispanService;
 import org.apache.camel.karavan.service.KubernetesService;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
 
 import javax.inject.Inject;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
+import javax.ws.rs.*;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.apache.camel.karavan.service.KubernetesService.RUNNER_SUFFIX;
 
 @Path("/api/runner")
 public class RunnerResource {
 
+    @ConfigProperty(name = "karavan.environment")
+    String environment;
+
     @Inject
     KubernetesService kubernetesService;
 
@@ -39,8 +47,22 @@ public class RunnerResource {
     @POST
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
-    public String runProject(Project project) throws Exception {
+    public String runProject(Project project) {
         Project p = infinispanService.getProject(project.getProjectId());
         return kubernetesService.tryCreatePod(p.getProjectId());
     }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/status/{projectId}/{name}")
+    public Response getPodStatus(@PathParam("projectId") String projectId, 
@PathParam("name") String name) {
+        Optional<PodStatus> ps =  infinispanService.getPodStatuses(projectId, 
environment).stream()
+                .filter(podStatus -> podStatus.getName().equals(name))
+                .findFirst();
+        if (ps.isPresent()) {
+            return Response.ok(ps.get()).build();
+        } else {
+            return Response.noContent().build();
+        }
+    }
 }
\ No newline at end of file
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/DeploymentEventHandler.java
 
b/karavan-app/src/main/java/org/apache/camel/karavan/handler/DeploymentEventHandler.java
similarity index 97%
rename from 
karavan-app/src/main/java/org/apache/camel/karavan/informer/DeploymentEventHandler.java
rename to 
karavan-app/src/main/java/org/apache/camel/karavan/handler/DeploymentEventHandler.java
index 65d34a7a..53a81a5f 100644
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/DeploymentEventHandler.java
+++ 
b/karavan-app/src/main/java/org/apache/camel/karavan/handler/DeploymentEventHandler.java
@@ -1,9 +1,8 @@
-package org.apache.camel.karavan.informer;
+package org.apache.camel.karavan.handler;
 
 import io.fabric8.kubernetes.api.model.apps.Deployment;
 import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
 import org.apache.camel.karavan.model.DeploymentStatus;
-import org.apache.camel.karavan.model.Environment;
 import org.apache.camel.karavan.service.InfinispanService;
 import org.apache.camel.karavan.service.KubernetesService;
 import org.jboss.logging.Logger;
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/PipelineRunEventHandler.java
 
b/karavan-app/src/main/java/org/apache/camel/karavan/handler/PipelineRunEventHandler.java
similarity index 98%
rename from 
karavan-app/src/main/java/org/apache/camel/karavan/informer/PipelineRunEventHandler.java
rename to 
karavan-app/src/main/java/org/apache/camel/karavan/handler/PipelineRunEventHandler.java
index 171e4b3b..9f2c0038 100644
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/PipelineRunEventHandler.java
+++ 
b/karavan-app/src/main/java/org/apache/camel/karavan/handler/PipelineRunEventHandler.java
@@ -1,4 +1,4 @@
-package org.apache.camel.karavan.informer;
+package org.apache.camel.karavan.handler;
 
 import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
 import io.fabric8.tekton.pipeline.v1beta1.PipelineRun;
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/PodEventHandler.java
 
b/karavan-app/src/main/java/org/apache/camel/karavan/handler/PodEventHandler.java
similarity index 73%
rename from 
karavan-app/src/main/java/org/apache/camel/karavan/informer/PodEventHandler.java
rename to 
karavan-app/src/main/java/org/apache/camel/karavan/handler/PodEventHandler.java
index 78f01be0..41bf5887 100644
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/PodEventHandler.java
+++ 
b/karavan-app/src/main/java/org/apache/camel/karavan/handler/PodEventHandler.java
@@ -1,4 +1,4 @@
-package org.apache.camel.karavan.informer;
+package org.apache.camel.karavan.handler;
 
 import io.fabric8.kubernetes.api.model.Pod;
 import io.fabric8.kubernetes.api.model.PodCondition;
@@ -10,6 +10,8 @@ import org.jboss.logging.Logger;
 
 import java.util.Optional;
 
+import static org.apache.camel.karavan.service.KubernetesService.RUNNER_SUFFIX;
+
 public class PodEventHandler implements ResourceEventHandler<Pod> {
 
     private static final Logger LOGGER = 
Logger.getLogger(PodEventHandler.class.getName());
@@ -48,9 +50,10 @@ public class PodEventHandler implements 
ResourceEventHandler<Pod> {
         try {
             LOGGER.info("onDelete " + pod.getMetadata().getName());
             String deployment = pod.getMetadata().getLabels().get("app");
+            String project = deployment != null ? deployment : 
pod.getMetadata().getLabels().get("project");
             PodStatus ps = new PodStatus(
                     pod.getMetadata().getName(),
-                    deployment,
+                    project,
                     kubernetesService.environment);
             infinispanService.deletePodStatus(ps);
         } catch (Exception e){
@@ -61,23 +64,28 @@ public class PodEventHandler implements 
ResourceEventHandler<Pod> {
 
     public PodStatus getPodStatus(Pod pod) {
         String deployment = pod.getMetadata().getLabels().get("app");
+        String project = deployment != null ? deployment : 
pod.getMetadata().getLabels().get("project");
         try {
-            Optional<PodCondition> initialized = 
pod.getStatus().getConditions().stream().filter(c -> 
c.getType().equals("Initialized")).findFirst();
-            Optional<PodCondition> ready = 
pod.getStatus().getConditions().stream().filter(c -> 
c.getType().equals("Initialized")).findFirst();
+            boolean initialized = 
pod.getStatus().getConditions().stream().anyMatch(c -> 
c.getType().equals("Initialized"));
+            boolean ready = 
pod.getStatus().getConditions().stream().anyMatch(c -> 
c.getType().equals("Ready"));
+            boolean terminating = pod.getMetadata().getDeletionTimestamp() != 
null;
             return new PodStatus(
                     pod.getMetadata().getName(),
                     pod.getStatus().getPhase(),
-                    initialized.isEmpty() ? false : 
initialized.get().getStatus().equals("True"),
-                    ready.isEmpty() ? false : 
ready.get().getStatus().equals("True"),
+                    initialized,
+                    ready && !terminating,
                     pod.getStatus().getReason(),
+                    project,
                     deployment,
-                    kubernetesService.environment
+                    kubernetesService.environment,
+                    deployment == null || 
pod.getMetadata().getName().endsWith(RUNNER_SUFFIX)
+
             );
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
             return new PodStatus(
                     pod.getMetadata().getName(),
-                    deployment,
+                    project,
                     kubernetesService.environment);
         }
     }
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/ServiceEventHandler.java
 
b/karavan-app/src/main/java/org/apache/camel/karavan/handler/ServiceEventHandler.java
similarity index 98%
rename from 
karavan-app/src/main/java/org/apache/camel/karavan/informer/ServiceEventHandler.java
rename to 
karavan-app/src/main/java/org/apache/camel/karavan/handler/ServiceEventHandler.java
index c522ffe6..ac0343ca 100644
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/ServiceEventHandler.java
+++ 
b/karavan-app/src/main/java/org/apache/camel/karavan/handler/ServiceEventHandler.java
@@ -1,4 +1,4 @@
-package org.apache.camel.karavan.informer;
+package org.apache.camel.karavan.handler;
 
 import io.fabric8.kubernetes.api.model.Service;
 import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/RunnerPodEventHandler.java
 
b/karavan-app/src/main/java/org/apache/camel/karavan/informer/RunnerPodEventHandler.java
deleted file mode 100644
index 28047871..00000000
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/informer/RunnerPodEventHandler.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.apache.camel.karavan.informer;
-
-import io.fabric8.kubernetes.api.model.Pod;
-import io.fabric8.kubernetes.api.model.PodCondition;
-import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
-import org.apache.camel.karavan.model.PodStatus;
-import org.apache.camel.karavan.service.InfinispanService;
-import org.apache.camel.karavan.service.KubernetesService;
-import org.jboss.logging.Logger;
-
-import java.util.Optional;
-
-public class RunnerPodEventHandler implements ResourceEventHandler<Pod> {
-
-    private static final Logger LOGGER = 
Logger.getLogger(RunnerPodEventHandler.class.getName());
-    private InfinispanService infinispanService;
-    private KubernetesService kubernetesService;
-
-    public RunnerPodEventHandler(InfinispanService infinispanService, 
KubernetesService kubernetesService) {
-        this.infinispanService = infinispanService;
-        this.kubernetesService = kubernetesService;
-    }
-
-    @Override
-    public void onAdd(Pod pod) {
-        try {
-            LOGGER.info("onAdd " + pod.getMetadata().getName());
-            PodStatus ps = getPodStatus(pod);
-            infinispanService.savePodStatus(ps);
-        } catch (Exception e){
-            LOGGER.error(e.getMessage());
-        }
-    }
-
-    @Override
-    public void onUpdate(Pod oldPod, Pod newPod) {
-        try {
-            LOGGER.info("onUpdate " + newPod.getMetadata().getName());
-            PodStatus ps = getPodStatus(newPod);
-            infinispanService.savePodStatus(ps);
-        } catch (Exception e){
-            LOGGER.error(e.getMessage());
-        }
-    }
-
-    @Override
-    public void onDelete(Pod pod, boolean deletedFinalStateUnknown) {
-        try {
-            LOGGER.info("onDelete " + pod.getMetadata().getName());
-            String deployment = pod.getMetadata().getLabels().get("app");
-            PodStatus ps = new PodStatus(
-                    pod.getMetadata().getName(),
-                    deployment,
-                    kubernetesService.environment);
-            infinispanService.deletePodStatus(ps);
-        } catch (Exception e){
-            LOGGER.error(e.getMessage());
-        }
-    }
-
-
-    public PodStatus getPodStatus(Pod pod) {
-        String deployment = pod.getMetadata().getLabels().get("app");
-        try {
-            Optional<PodCondition> initialized = 
pod.getStatus().getConditions().stream().filter(c -> 
c.getType().equals("Initialized")).findFirst();
-            Optional<PodCondition> ready = 
pod.getStatus().getConditions().stream().filter(c -> 
c.getType().equals("Initialized")).findFirst();
-            return new PodStatus(
-                    pod.getMetadata().getName(),
-                    pod.getStatus().getPhase(),
-                    initialized.isEmpty() ? false : 
initialized.get().getStatus().equals("True"),
-                    ready.isEmpty() ? false : 
ready.get().getStatus().equals("True"),
-                    pod.getStatus().getReason(),
-                    deployment,
-                    kubernetesService.environment
-            );
-        } catch (Exception ex) {
-            LOGGER.error(ex.getMessage());
-            return new PodStatus(
-                    pod.getMetadata().getName(),
-                    deployment,
-                    kubernetesService.environment);
-        }
-    }
-}
\ No newline at end of file
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/model/PodStatus.java 
b/karavan-app/src/main/java/org/apache/camel/karavan/model/PodStatus.java
index e24f9ea6..b8390b4b 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/model/PodStatus.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/PodStatus.java
@@ -18,27 +18,33 @@ public class PodStatus {
     @ProtoField(number = 6)
     String deployment;
     @ProtoField(number = 7)
+    String project;
+    @ProtoField(number = 8)
     String env;
+    @ProtoField(number = 9)
+    Boolean runner;
 
-    public PodStatus(String name, String deployment, String env) {
+    public PodStatus(String name, String project, String env) {
         this.name = name;
         this.phase = "";
         this.initialized = false;
         this.ready = false;
         this.reason = "";
-        this.deployment = deployment;
+        this.project = project;
         this.env = env;
     }
 
     @ProtoFactory
-    public PodStatus(String name, String phase, Boolean initialized, Boolean 
ready, String reason, String deployment, String env) {
+    public PodStatus(String name, String phase, Boolean initialized, Boolean 
ready, String reason, String project, String deployment, String env, Boolean 
runner) {
         this.name = name;
         this.phase = phase;
         this.initialized = initialized;
         this.ready = ready;
         this.reason = reason;
         this.deployment = deployment;
+        this.project = project;
         this.env = env;
+        this.runner = runner;
     }
 
     public String getName() {
@@ -96,4 +102,20 @@ public class PodStatus {
     public void setEnv(String env) {
         this.env = env;
     }
+
+    public Boolean getRunner() {
+        return runner;
+    }
+
+    public void setRunner(Boolean runner) {
+        this.runner = runner;
+    }
+
+    public String getProject() {
+        return project;
+    }
+
+    public void setProject(String project) {
+        this.project = project;
+    }
 }
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java
 
b/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java
index 75dfb184..38818466 100644
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java
+++ 
b/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java
@@ -49,6 +49,7 @@ import javax.enterprise.context.ApplicationScoped;
 import javax.enterprise.inject.Default;
 import javax.inject.Inject;
 import java.time.Instant;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -235,18 +236,18 @@ public class InfinispanService implements HealthCheck  {
     }
 
     public List<ServiceStatus> getServiceStatuses() {
-        return serviceStatuses.values().stream().collect(Collectors.toList());
+        return new ArrayList<>(serviceStatuses.values());
     }
 
     public List<PodStatus> getPodStatuses(String projectId, String env) {
         if (cacheManager == null) {
             return podStatuses.values().stream()
-                    .filter(s -> s.getEnv().equals(env) && 
s.getDeployment().equals(projectId))
+                    .filter(s -> s.getEnv().equals(env) && 
s.getProject().equals(projectId))
                     .collect(Collectors.toList());
         } else {
             QueryFactory queryFactory = Search.getQueryFactory((RemoteCache<?, 
?>) podStatuses);
-            return queryFactory.<PodStatus>create("FROM karavan.PodStatus 
WHERE deployment = :deployment AND env = :env")
-                    .setParameter("deployment", projectId)
+            return queryFactory.<PodStatus>create("FROM karavan.PodStatus 
WHERE project = :project AND env = :env")
+                    .setParameter("project", projectId)
                     .setParameter("env", env)
                     .execute().list();
         }
@@ -266,11 +267,11 @@ public class InfinispanService implements HealthCheck  {
     }
 
     public void savePodStatus(PodStatus status) {
-        podStatuses.put(GroupedKey.create(status.getDeployment(), 
status.getName()), status);
+        podStatuses.put(GroupedKey.create(status.getProject(), 
status.getName()), status);
     }
 
     public void deletePodStatus(PodStatus status) {
-        podStatuses.remove(GroupedKey.create(status.getDeployment(), 
status.getName()));
+        podStatuses.remove(GroupedKey.create(status.getProject(), 
status.getName()));
     }
 
     public CamelStatus getCamelStatus(String projectId, String env) {
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
 
b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
index 525f8738..93d9a901 100644
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
+++ 
b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
@@ -29,7 +29,7 @@ import io.fabric8.tekton.client.DefaultTektonClient;
 import io.fabric8.tekton.pipeline.v1beta1.*;
 import io.quarkus.vertx.ConsumeEvent;
 import io.vertx.mutiny.core.eventbus.EventBus;
-import org.apache.camel.karavan.informer.*;
+import org.apache.camel.karavan.handler.*;
 import org.apache.camel.karavan.model.Project;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.eclipse.microprofile.health.HealthCheck;
@@ -53,10 +53,10 @@ public class KubernetesService implements HealthCheck{
     private static final Logger LOGGER = 
Logger.getLogger(KubernetesService.class.getName());
     public static final String START_INFORMERS = "start-informers";
     public static final String STOP_INFORMERS = "stop-informers";
-    public static final int INFORMERS = 5;
+    public static final int INFORMERS = 4;
     private static final String CAMEL_PREFIX = "camel";
     private static final String KARAVAN_PREFIX = "karavan";
-    private static final String RUNNER_SUFFIX = "runner";
+    public static final String RUNNER_SUFFIX = "runner";
     private static final String JBANG_CACHE_SUFFIX = "jbang-cache";
     private static final String M2_CACHE_SUFFIX = "m2-cache";
 
@@ -116,10 +116,6 @@ public class KubernetesService implements HealthCheck{
             podRunInformer.addEventHandlerWithResyncPeriod(new 
PodEventHandler(infinispanService, this),30 * 1000L);
             informers.add(podRunInformer);
 
-            SharedIndexInformer<Pod> runnerInformer = 
kubernetesClient().pods().inNamespace(getNamespace()).withLabels(getKaravanTypeLabel()).inform();
-            runnerInformer.addEventHandlerWithResyncPeriod(new 
RunnerPodEventHandler(infinispanService, this),30 * 1000L);
-            informers.add(runnerInformer);
-
             LOGGER.info("Started Kubernetes Informers");
         } catch (Exception e) {
             LOGGER.error("Error starting informers: " + e.getMessage());
@@ -388,22 +384,27 @@ public class KubernetesService implements HealthCheck{
         createPVC(name + "-" + M2_CACHE_SUFFIX);
         Pod old = 
kubernetesClient().pods().inNamespace(getNamespace()).withName(name).get();
         if (old == null) {
-            createPod(name);
+            createPod(projectId, name);
         }
         return name;
     }
 
-    private void createPod(String name) {
-        Pod pod = getPod(name);
+    private void createPod(String projectId, String name) {
+        Pod pod = getPod(projectId, name);
         Pod result = kubernetesClient().resource(pod).create();
         LOGGER.info("Created pod " + result.getMetadata().getName());
     }
 
-    private Pod getPod(String name) {
+    private Pod getPod(String projectId, String name) {
+        Map<String,String> labels = new HashMap<>();
+        labels.putAll(getRuntimeLabels());
+        labels.putAll(getKaravanTypeLabel());
+        labels.put("project", projectId);
+
         ObjectMeta meta = new ObjectMetaBuilder()
                 .withName(name)
-                .withLabels(getKaravanTypeLabel())
-                .withNamespace("karavan")
+                .withLabels(labels)
+                .withNamespace(getNamespace())
                 .build();
 
         ContainerPort port = new ContainerPortBuilder()
@@ -422,6 +423,7 @@ public class KubernetesService implements HealthCheck{
                 .build();
 
         PodSpec spec = new PodSpecBuilder()
+                .withTerminationGracePeriodSeconds(0L)
                 .withContainers(container)
                 .withVolumes(new VolumeBuilder().withName(name + "-" + 
JBANG_CACHE_SUFFIX)
                         .withNewPersistentVolumeClaim(name + "-" + 
JBANG_CACHE_SUFFIX, false).build())
@@ -460,10 +462,14 @@ public class KubernetesService implements HealthCheck{
 
     public Map<String, String> getRuntimeLabels() {
         Map<String, String> result = new HashMap<>();
-        result.put(isOpenshift() ? "app.openshift.io/runtime" : 
"app.kubernetes.io/runtime", CAMEL_PREFIX);
+        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);
diff --git a/karavan-app/src/main/webui/src/api/KaravanApi.tsx 
b/karavan-app/src/main/webui/src/api/KaravanApi.tsx
index 01ad51b7..78736f22 100644
--- a/karavan-app/src/main/webui/src/api/KaravanApi.tsx
+++ b/karavan-app/src/main/webui/src/api/KaravanApi.tsx
@@ -300,6 +300,15 @@ export class KaravanApi {
         });
     }
 
+    static async getRunnerPodStatus(projectId: string, name: string, after: 
(res: AxiosResponse<PodStatus>) => void) {
+        instance.get('/api/runner/status/' + projectId + "/" + name)
+            .then(res => {
+                after(res);
+            }).catch(err => {
+            after(err);
+        });
+    }
+
     static async runProject(project: Project, after: (res: 
AxiosResponse<string>) => void) {
         instance.post('/api/runner', project)
             .then(res => {
diff --git a/karavan-app/src/main/webui/src/projects/ProjectDevelopment.tsx 
b/karavan-app/src/main/webui/src/projects/ProjectDevelopment.tsx
index beb40c6d..ce2fc1c7 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectDevelopment.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectDevelopment.tsx
@@ -5,8 +5,8 @@ import {
 } from '@patternfly/react-core';
 import '../designer/karavan.css';
 import {Project} from "./ProjectModels";
-import {ProjectRunnerToolbar} from "./ProjectRunnerToolbar";
-import {ProjectRunner} from "./ProjectRunner";
+import {RunnerToolbar} from "./RunnerToolbar";
+import {RunnerInfoPod} from "./RunnerInfoPod";
 
 
 interface Props {
@@ -22,16 +22,16 @@ export const ProjectDevelopment = (props: Props) => {
                 <CardBody>
                     <Flex direction={{default: "row"}}
                           justifyContent={{default: 
"justifyContentSpaceBetween"}}>
-                        <FlexItem flex={{default: "flex_4"}}>
-                            <ProjectRunner project={project} config={config} />
+                        <FlexItem flex={{default: "flex_1"}}>
+                            <RunnerInfoPod project={project} config={config} />
                         </FlexItem>
                         <Divider orientation={{default: "vertical"}}/>
-                        <FlexItem flex={{default: "flex_4"}}>
-                            <ProjectRunner project={project} config={config} />
+                        <FlexItem flex={{default: "flex_1"}}>
+                            {/*<Runner project={project} config={config} />*/}
                         </FlexItem>
                         <Divider orientation={{default: "vertical"}}/>
                         <FlexItem>
-                            <ProjectRunnerToolbar project={project} 
config={config} />
+                            <RunnerToolbar project={project} config={config} />
                         </FlexItem>
                     </Flex>
                 </CardBody>
diff --git a/karavan-app/src/main/webui/src/projects/ProjectModels.ts 
b/karavan-app/src/main/webui/src/projects/ProjectModels.ts
index 5957fe92..789bd3d1 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectModels.ts
+++ b/karavan-app/src/main/webui/src/projects/ProjectModels.ts
@@ -52,7 +52,9 @@ export class PodStatus {
     started: boolean = false;
     ready: boolean = false;
     reason: string = '';
+    project: string = '';
     deployment: string = '';
+    runner: boolean = false;
 }
 
 export class CamelStatus {
diff --git a/karavan-app/src/main/webui/src/projects/ProjectRunner.tsx 
b/karavan-app/src/main/webui/src/projects/ProjectRunner.tsx
deleted file mode 100644
index dcbd3112..00000000
--- a/karavan-app/src/main/webui/src/projects/ProjectRunner.tsx
+++ /dev/null
@@ -1,163 +0,0 @@
-import React from 'react';
-import {
-    DescriptionList,
-    DescriptionListTerm,
-    DescriptionListGroup,
-    DescriptionListDescription,
-    Tooltip,
-    Flex,
-    FlexItem,
-    Label,
-    Button,
-    Modal,
-    ModalVariant,
-    Form,
-    FormGroup,
-    TextInput,
-    FormHelperText
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import {Project} from "./ProjectModels";
-import {KaravanApi} from "../api/KaravanApi";
-import PushIcon from "@patternfly/react-icons/dist/esm/icons/code-branch-icon";
-
-
-interface Props {
-    project: Project,
-    config: any,
-}
-
-interface State {
-    environment: string,
-    isPushing: boolean,
-    commitMessageIsOpen: boolean,
-    commitMessage: string
-}
-
-export class ProjectRunner extends React.Component<Props, State> {
-
-    public state: State = {
-        environment: this.props.config.environment,
-        isPushing: false,
-        commitMessageIsOpen: false,
-        commitMessage: ''
-    };
-
-    push = (after?: () => void) => {
-        this.setState({isPushing: true, commitMessageIsOpen: false});
-        const params = {
-            "projectId": this.props.project.projectId,
-            "message": this.state.commitMessage
-        };
-        KaravanApi.push(params, res => {
-            if (res.status === 200 || res.status === 201) {
-                this.setState({isPushing: false});
-                after?.call(this);
-                // this.props.onRefresh.call(this);
-            } else {
-                // Todo notification
-            }
-        });
-    }
-
-    getDate(lastUpdate: number): string {
-        if (lastUpdate) {
-            const date = new Date(lastUpdate);
-            return date.toISOString().slice(0, 19).replace('T',' ');
-        } else {
-            return "N/A"
-        }
-    }
-
-    getLastUpdatePanel() {
-        const {project} = this.props;
-        const color = true ? "grey" : "green";
-        return (
-            <Flex direction={{default: "row"}} justifyContent={{default: 
"justifyContentFlexStart"}}>
-                {project?.lastCommitTimestamp && project?.lastCommitTimestamp 
> 0 &&
-                    <FlexItem>
-                        <Label 
color={color}>{this.getDate(project?.lastCommitTimestamp)}</Label>
-                    </FlexItem>
-                }
-            </Flex>
-        )
-    }
-
-    getCommitPanel() {
-        const {isPushing, commitMessage} = this.state;
-        const {project} = this.props;
-        const color = true ? "grey" : "green";
-        return (
-            <Flex direction={{default: "row"}} justifyContent={{default: 
"justifyContentSpaceBetween"}}>
-                <FlexItem>
-                    <Tooltip content={project?.lastCommit} position={"right"}>
-                        <Label
-                            color={color}>{project?.lastCommit ? 
project?.lastCommit?.substr(0, 18) : "-"}</Label>
-                    </Tooltip>
-                </FlexItem>
-                <FlexItem>
-
-                </FlexItem>
-            </Flex>
-        )
-    }
-
-    getCommitModal() {
-        let {commitMessage, commitMessageIsOpen} = this.state;
-        return (
-            <Modal
-                title="Commit"
-                variant={ModalVariant.small}
-                isOpen={commitMessageIsOpen}
-                onClose={() => this.setState({commitMessageIsOpen: false})}
-                actions={[
-                    <Button key="confirm" variant="primary" onClick={() => 
this.push()}>Save</Button>,
-                    <Button key="cancel" variant="secondary"
-                            onClick={() => this.setState({commitMessageIsOpen: 
false})}>Cancel</Button>
-                ]}
-            >
-                <Form autoComplete="off" isHorizontal 
className="create-file-form">
-                    <FormGroup label="Message" fieldId="name" isRequired>
-                        <TextInput value={commitMessage} onChange={value => 
this.setState({commitMessage: value})}/>
-                        <FormHelperText isHidden={false} component="div"/>
-                    </FormGroup>
-                </Form>
-            </Modal>
-        )
-    }
-
-    render() {
-        const {project} = this.props;
-        return (
-            <React.Fragment>
-                <DescriptionList isHorizontal>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Project ID</DescriptionListTerm>
-                        
<DescriptionListDescription>{project?.projectId}</DescriptionListDescription>
-                    </DescriptionListGroup>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Name</DescriptionListTerm>
-                        
<DescriptionListDescription>{project?.name}</DescriptionListDescription>
-                    </DescriptionListGroup>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Description</DescriptionListTerm>
-                        
<DescriptionListDescription>{project?.description}</DescriptionListDescription>
-                    </DescriptionListGroup>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Updated</DescriptionListTerm>
-                        <DescriptionListDescription>
-                            {this.getLastUpdatePanel()}
-                        </DescriptionListDescription>
-                    </DescriptionListGroup>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Commit</DescriptionListTerm>
-                        <DescriptionListDescription>
-                            {this.getCommitPanel()}
-                        </DescriptionListDescription>
-                    </DescriptionListGroup>
-                </DescriptionList>
-                {this.getCommitModal()}
-            </React.Fragment>
-        );
-    }
-}
diff --git a/karavan-app/src/main/webui/src/projects/RunnerInfoPod.tsx 
b/karavan-app/src/main/webui/src/projects/RunnerInfoPod.tsx
new file mode 100644
index 00000000..76478afb
--- /dev/null
+++ b/karavan-app/src/main/webui/src/projects/RunnerInfoPod.tsx
@@ -0,0 +1,111 @@
+import React, {useEffect, useState} from 'react';
+import {
+    Badge,
+    Button,
+    DescriptionList,
+    DescriptionListDescription,
+    DescriptionListGroup,
+    DescriptionListTerm,
+    Flex,
+    FlexItem,
+    Label,
+    LabelGroup,
+    Tooltip,
+    TooltipPosition
+} from '@patternfly/react-core';
+import '../designer/karavan.css';
+import {CamelStatus, DeploymentStatus, PipelineStatus, PodStatus, Project} 
from "./ProjectModels";
+import RocketIcon from "@patternfly/react-icons/dist/esm/icons/rocket-icon";
+import PlayIcon from "@patternfly/react-icons/dist/esm/icons/play-icon";
+import DeleteIcon from 
"@patternfly/react-icons/dist/esm/icons/times-circle-icon";
+import {KaravanApi} from "../api/KaravanApi";
+import {ProjectEventBus} from "./ProjectEventBus";
+import DownIcon from 
"@patternfly/react-icons/dist/esm/icons/error-circle-o-icon";
+import UpIcon from "@patternfly/react-icons/dist/esm/icons/check-circle-icon";
+
+
+interface Props {
+    project: Project,
+    config: any,
+}
+
+export const RunnerInfoPod = (props: Props) => {
+
+    const [podStatus, setPodStatus] = useState(new PodStatus());
+
+    useEffect(() => {
+        const interval = setInterval(() => {
+            onRefreshStatus();
+        }, 1000);
+        return () => clearInterval(interval);
+    }, []);
+
+    function onRefreshStatus() {
+        const projectId = props.project.projectId;
+        const name = projectId + "-runner";
+        KaravanApi.getRunnerPodStatus(projectId, name, res => {
+            if (res.status === 200) {
+                setPodStatus(res.data);
+            } else {
+                ProjectEventBus.showLog('container', name, 
props.config.environment, false);
+                setPodStatus(new PodStatus());
+            }
+        })
+    }
+
+    function getPodInfo() {
+        const running = podStatus.phase === 'Running' && podStatus.ready;
+        const env = props.config.environment;
+        return (
+            <Label icon={running ? <UpIcon/> : <DownIcon/>} color={running ? 
"green" : "grey"}>
+                <Button variant="link"
+                        onClick={e => ProjectEventBus.showLog('container', 
podStatus.name, env)}>
+                    {podStatus.name}
+                </Button>
+                {/*<Tooltip content={"Delete Pod"}>*/}
+                {/*    <Button icon={<DeleteIcon/>} variant="link" onClick={e 
=> this.setState({*/}
+                {/*        showDeleteConfirmation: true,*/}
+                {/*        deleteEntity: "pod",*/}
+                {/*        deleteEntityEnv: env,*/}
+                {/*        deleteEntityName: podStatus.name*/}
+                {/*    })}></Button>*/}
+                {/*</Tooltip>*/}
+            </Label>
+        )
+    }
+
+    return (
+        <DescriptionList isHorizontal>
+            <DescriptionListGroup>
+                <DescriptionListTerm>Pod</DescriptionListTerm>
+                <DescriptionListDescription>
+                    {getPodInfo()}
+                </DescriptionListDescription>
+            </DescriptionListGroup>
+            <DescriptionListGroup>
+                <DescriptionListTerm>????</DescriptionListTerm>
+                <DescriptionListDescription>
+                    {getPodInfo()}
+                </DescriptionListDescription>
+            </DescriptionListGroup>
+            <DescriptionListGroup>
+                <DescriptionListTerm>????</DescriptionListTerm>
+                <DescriptionListDescription>
+                    {getPodInfo()}
+                </DescriptionListDescription>
+            </DescriptionListGroup>
+            <DescriptionListGroup>
+                <DescriptionListTerm>????</DescriptionListTerm>
+                <DescriptionListDescription>
+                    {getPodInfo()}
+                </DescriptionListDescription>
+            </DescriptionListGroup>
+            <DescriptionListGroup>
+                <DescriptionListTerm>????</DescriptionListTerm>
+                <DescriptionListDescription>
+                    {getPodInfo()}
+                </DescriptionListDescription>
+            </DescriptionListGroup>
+        </DescriptionList>
+    );
+}
diff --git a/karavan-app/src/main/webui/src/projects/ProjectRunnerToolbar.tsx 
b/karavan-app/src/main/webui/src/projects/RunnerToolbar.tsx
similarity index 94%
rename from karavan-app/src/main/webui/src/projects/ProjectRunnerToolbar.tsx
rename to karavan-app/src/main/webui/src/projects/RunnerToolbar.tsx
index cfa6c3e9..b2944ed7 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectRunnerToolbar.tsx
+++ b/karavan-app/src/main/webui/src/projects/RunnerToolbar.tsx
@@ -18,9 +18,9 @@ interface Props {
     config: any,
 }
 
-export const ProjectRunnerToolbar = (props: Props) => {
+export const RunnerToolbar = (props: Props) => {
 
-    const [podName, setPodName] = useState('');
+    const [podName, setPodName] = useState(props.project.projectId + 
'-runner');
     const [isJbangRunning, setJbangIsRunning] = useState(false);
     const [isRunning, setIsRunning] = useState(false);
     const [isDeletingPod, setIsDeletingPod] = useState(false);
@@ -48,7 +48,6 @@ export const ProjectRunnerToolbar = (props: Props) => {
                 // Todo notification
                 setIsDeletingPod(false);
             }
-            ProjectEventBus.showLog('container', res.data, 
props.config.environment, false)
         });
     }
 


Reply via email to