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) }); }