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 8f6b48043e9557edb642a3951ee046de040354f4
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Mon Sep 19 17:55:45 2022 -0400

    Deployment instead of DeploymentConfig
---
 karavan-app/pom.xml                                |  4 +
 .../camel/karavan/service/KubernetesService.java   | 91 ++++++++++++----------
 .../camel/karavan/service/StatusService.java       | 21 +++++
 .../src/main/resources/application.properties      |  5 --
 karavan-app/src/main/webapp/src/Main.tsx           | 14 ++--
 .../src/main/webapp/src/projects/ProjectInfo.tsx   | 10 +--
 .../src/main/webapp/src/projects/ProjectModels.ts  |  1 +
 .../src/main/webapp/src/projects/ProjectPage.tsx   |  1 -
 .../src/main/webapp/src/projects/ProjectsPage.tsx  | 13 +++-
 9 files changed, 96 insertions(+), 64 deletions(-)

diff --git a/karavan-app/pom.xml b/karavan-app/pom.xml
index 6957f39..0223375 100644
--- a/karavan-app/pom.xml
+++ b/karavan-app/pom.xml
@@ -66,6 +66,10 @@
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-arc</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-scheduler</artifactId>
+        </dependency>
         <dependency>
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-smallrye-openapi</artifactId>
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 efa64f5..e8368d5 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
@@ -20,6 +20,7 @@ import io.fabric8.kubernetes.api.model.ObjectMeta;
 import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
 import io.fabric8.kubernetes.api.model.Pod;
 import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.apps.Deployment;
 import io.fabric8.kubernetes.client.DefaultKubernetesClient;
 import io.fabric8.kubernetes.client.KubernetesClient;
 import io.fabric8.kubernetes.client.dsl.LogWatch;
@@ -35,7 +36,6 @@ import io.fabric8.tekton.pipeline.v1beta1.PipelineRunBuilder;
 import io.fabric8.tekton.pipeline.v1beta1.PipelineRunSpec;
 import io.fabric8.tekton.pipeline.v1beta1.PipelineRunSpecBuilder;
 import io.fabric8.tekton.pipeline.v1beta1.WorkspaceBindingBuilder;
-import io.vertx.core.json.JsonObject;
 import io.vertx.mutiny.core.eventbus.EventBus;
 import org.apache.camel.karavan.model.DeploymentStatus;
 import org.apache.camel.karavan.model.PipelineRunLog;
@@ -166,11 +166,7 @@ public class KubernetesService {
 
     public void rolloutDeployment(String name, String namespace) {
         try {
-            if (kubernetesClient().isAdaptable(OpenShiftClient.class)) {
-                
openshiftClient().deploymentConfigs().inNamespace(namespace).withName(name).deployLatest();
-            } else {
-                // TODO: Implement Deployment for Kubernetes/Minikube
-            }
+            
kubernetesClient().apps().deployments().inNamespace(namespace).withName(name).rolling();
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
         }
@@ -178,11 +174,7 @@ public class KubernetesService {
 
     public void deleteDeployment(String name, String namespace) {
         try {
-            if (kubernetesClient().isAdaptable(OpenShiftClient.class)) {
-                
openshiftClient().deploymentConfigs().inNamespace(namespace).withName(name).delete();
-            } else {
-                // TODO: Implement Deployment for Kubernetes/Minikube
-            }
+            
kubernetesClient().apps().deployments().inNamespace(namespace).withName(name).delete();
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
         }
@@ -198,43 +190,58 @@ public class KubernetesService {
 
     public DeploymentStatus getDeploymentStatus(String name, String namespace) 
{
         try {
-            if (kubernetesClient().isAdaptable(OpenShiftClient.class)) {
-                DeploymentConfig dc = 
openshiftClient().deploymentConfigs().inNamespace(namespace).withName(name).get();
-                String dsImage = 
dc.getSpec().getTemplate().getSpec().getContainers().get(0).getImage();
-                String imageName = 
dsImage.startsWith("image-registry.openshift-image-registry.svc")
-                        ? 
dsImage.replace("image-registry.openshift-image-registry.svc:5000/", "")
-                        : dsImage;
-
-                List<Pod> pods = 
openshiftClient().pods().inNamespace(namespace)
-                        .withLabel("app.kubernetes.io/name", name)
-                        .withLabel("deploymentconfig", name)
-                        .list().getItems();
-
-                List<PodStatus> podStatuses = pods.stream().map(pod -> new 
PodStatus(
-                        pod.getMetadata().getName(),
-                        
pod.getStatus().getContainerStatuses().get(0).getStarted(),
-                        
pod.getStatus().getContainerStatuses().get(0).getReady(),
-                        getPodReason(pod),
-                        pod.getMetadata().getLabels().get("deployment")
-                        )).collect(Collectors.toList());
-
-                return new DeploymentStatus(
-                        imageName,
-                        dc.getSpec().getReplicas(),
-                        dc.getStatus().getReadyReplicas(),
-                        dc.getStatus().getUnavailableReplicas(),
-                        podStatuses
-                );
-            } else {
-                // TODO: Implement Deployment for Kubernetes/Minikube
-                return new DeploymentStatus();
-            }
+            Deployment deployment = 
kubernetesClient().apps().deployments().inNamespace(namespace).withName(name).get();
+            String dsImage = 
deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage();
+            String imageName = 
dsImage.startsWith("image-registry.openshift-image-registry.svc")
+                    ? 
dsImage.replace("image-registry.openshift-image-registry.svc:5000/", "")
+                    : dsImage;
+
+            List<Pod> pods = openshiftClient().pods().inNamespace(namespace)
+                    .withLabel("app.kubernetes.io/name", name)
+                    .withLabel("app.openshift.io/runtime", "camel")
+                    .list().getItems();
+
+            List<PodStatus> podStatuses = pods.stream().map(pod -> new 
PodStatus(
+                    pod.getMetadata().getName(),
+                    pod.getStatus().getContainerStatuses().get(0).getStarted(),
+                    pod.getStatus().getContainerStatuses().get(0).getReady(),
+                    getPodReason(pod),
+                    pod.getMetadata().getLabels().get("app.kubernetes.io/name")
+            )).collect(Collectors.toList());
+
+            return new DeploymentStatus(
+                    imageName,
+                    deployment.getSpec().getReplicas(),
+                    deployment.getStatus().getReadyReplicas(),
+                    deployment.getStatus().getUnavailableReplicas(),
+                    podStatuses
+            );
         } catch (Exception ex) {
             LOGGER.error(ex.getMessage());
             return new DeploymentStatus();
         }
     }
 
+    public boolean hasDeployment(String name, String namespace) {
+        try {
+            Deployment deployment = 
kubernetesClient().apps().deployments().inNamespace(namespace).withName(name).get();
+            return deployment != null;
+        } catch (Exception ex) {
+            LOGGER.error(ex.getMessage());
+            return false;
+        }
+    }
+
+    public List<String> getCamelDeployments(String namespace) {
+        try {
+            return 
kubernetesClient().apps().deployments().inNamespace(namespace).withLabel("app.openshift.io/runtime","camel").list().getItems()
+                    .stream().map(deployment -> 
deployment.getMetadata().getName()).collect(Collectors.toList());
+        } catch (Exception ex) {
+            LOGGER.error(ex.getMessage());
+            return List.of();
+        }
+    }
+
     private String getPodReason (Pod pod){
         try {
             return 
pod.getStatus().getContainerStatuses().get(0).getState().getWaiting().getReason();
diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java 
b/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
index 0d340c6..eb2e33b 100644
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
+++ 
b/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
@@ -18,6 +18,7 @@ package org.apache.camel.karavan.service;
 
 import io.fabric8.tekton.pipeline.v1beta1.PipelineRun;
 import io.quarkus.runtime.configuration.ProfileManager;
+import io.quarkus.scheduler.Scheduled;
 import io.quarkus.vertx.ConsumeEvent;
 import io.smallrye.mutiny.tuples.Tuple4;
 import io.vertx.core.json.JsonObject;
@@ -70,6 +71,26 @@ public class StatusService {
         return webClient;
     }
 
+    @Scheduled(every="10s")
+    void checkDeployedProjects() {
+        LOGGER.info("Check deployed projects");
+        infinispanService.getProjects().forEach(project -> {
+            Optional<KaravanConfiguration.Environment> env = 
configuration.environments().stream().filter(environment -> 
environment.name().equals("dev")).findFirst();
+            if (env.isPresent()) {
+                boolean hasDeployment =  
kubernetesService.hasDeployment(project.getProjectId(), env.get().namespace());
+                System.out.println("Project " + project.getName() + " 
deployed: " + project.getDeployed() + " hasDeployment: " + hasDeployment);
+                if (!project.getDeployed() && hasDeployment) {
+                    project.setDeployed(true);
+                    infinispanService.saveProject(project);
+                } else if (project.getDeployed() && !hasDeployment) {
+                    project.setDeployed(false);
+                    infinispanService.saveProject(project);
+                    infinispanService.saveProjectStatus(new 
ProjectStatus(project.getProjectId(), List.of(), System.currentTimeMillis()));
+                }
+            }
+        });
+    }
+
     @ConsumeEvent(value = CMD_COLLECT_STATUSES, blocking = true, ordered = 
true)
     public void collectStatuses(String projectId) throws Exception {
         if ((System.currentTimeMillis() - lastCollect) > 
configuration.statusThreshold()) {
diff --git a/karavan-app/src/main/resources/application.properties 
b/karavan-app/src/main/resources/application.properties
index 817a4ec..c58c496 100644
--- a/karavan-app/src/main/resources/application.properties
+++ b/karavan-app/src/main/resources/application.properties
@@ -40,11 +40,6 @@ karavan.config.environments[2].pipeline=karavan-quarkus
 karavan.config.environments[2].cluster=svc.cluster.local
 karavan.config.environments[2].active=false
 
-%dev.karavan.config.environments[0].cluster=apps.cluster-bzs7w.bzs7w.sandbox863.opentlc.com
-%dev.karavan.config.environments[1].cluster=apps.cluster-bzs7w.bzs7w.sandbox863.opentlc.com
-%dev.karavan.config.environments[2].cluster=apps.cluster-bzs7w.bzs7w.sandbox863.opentlc.com
-
-
 # Infinispan Server address
 #quarkus.infinispan-client.server-list=localhost:12345
 quarkus.infinispan-client.devservices.enabled=false
diff --git a/karavan-app/src/main/webapp/src/Main.tsx 
b/karavan-app/src/main/webapp/src/Main.tsx
index 00e3efa..aa7341a 100644
--- a/karavan-app/src/main/webapp/src/Main.tsx
+++ b/karavan-app/src/main/webapp/src/Main.tsx
@@ -127,9 +127,6 @@ export class Main extends React.Component<Props, State> {
     }
 
     getData() {
-        KaravanApi.getConfiguration((config: any) => {
-            this.setState({ config: config })
-        });
         KaravanApi.getKameletNames(names => names.forEach(name => {
             KaravanApi.getKamelet(name, yaml => KameletApi.saveKamelet(yaml))
         }));
@@ -247,11 +244,14 @@ export class Main extends React.Component<Props, State> {
     };
 
     onGetProjects = () => {
-        KaravanApi.getProjects((projects: Project[]) => {
-            this.setState({
-                projects: projects, request: uuidv4()
-            })
+        KaravanApi.getConfiguration((config: any) => {
+            KaravanApi.getProjects((projects: Project[]) => {
+                this.setState({
+                    projects: projects, request: uuidv4(), config: config
+                })
+            });
         });
+
     }
 
     getMain() {
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx 
b/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx
index 25e6cf8..b2bec98 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx
@@ -59,7 +59,7 @@ export class ProjectInfo extends React.Component<Props, 
State> {
 
     componentDidMount() {
         this.onRefresh();
-        this.interval = setInterval(() => this.onRefreshStatus(), 700);
+        this.interval = setInterval(() => this.onRefreshStatus(), 1300);
     }
 
     componentWillUnmount() {
@@ -146,16 +146,14 @@ export class ProjectInfo extends React.Component<Props, 
State> {
         const status = this.state.status?.statuses.find(s => s.environment === 
env)
         const pipelineResult = status?.lastPipelineRunResult;
         const isRunning = pipelineResult === 'Running';
-        return (<Tooltip content="Commit, push, build and deploy" 
position={"left"}>
+        return (<Tooltip content="Build and deploy" position={"left"}>
             <Button isLoading={isDeploying ? true : undefined}
                     isDisabled={isDeploying || isRunning || isPushing}
                     isSmall
                     variant="secondary"
                     className="project-button"
                     icon={!isDeploying ? <BuildIcon/> : <div></div>}
-                    onClick={e => {
-                        this.push(() => this.build());
-                    }}>
+                    onClick={e => this.build()}>
                 {isDeploying ? "..." : "Deploy"}
             </Button>
         </Tooltip>)
@@ -205,7 +203,7 @@ export class ProjectInfo extends React.Component<Props, 
State> {
     }
 
     getEnvPanel(env: string) {
-        const {status} = this.state;
+        const {status, project} = this.state;
         const deploymentStatus = status?.statuses.find(s => s.environment === 
env)?.deploymentStatus;
         return (
             <DescriptionList isHorizontal>
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectModels.ts 
b/karavan-app/src/main/webapp/src/projects/ProjectModels.ts
index 172e90a..2d98870 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectModels.ts
+++ b/karavan-app/src/main/webapp/src/projects/ProjectModels.ts
@@ -3,6 +3,7 @@ export class Project {
     name: string = '';
     description: string = '';
     lastCommit: string = '';
+    deployed: boolean = false;
 
     public constructor(projectId: string, name: string, description: string, 
lastCommit: string);
     public constructor(init?: Partial<Project>);
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx 
b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
index 1758ac2..ce45398 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
@@ -46,7 +46,6 @@ import {UploadModal} from "./UploadModal";
 import {ProjectInfo} from "./ProjectInfo";
 import {ProjectDashboard} from "./ProjectDashboard";
 import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
-import {CamelUtil} from "karavan-core/src/core/api/CamelUtil";
 import * as yaml from 'js-yaml';
 
 interface Props {
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx 
b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
index cad4f3d..24c72ed 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
@@ -14,8 +14,6 @@ import {
     Form,
     Badge,
     Tooltip,
-    ToggleGroup,
-    ToggleGroupItem,
     Bullseye,
     EmptyState,
     EmptyStateVariant,
@@ -69,6 +67,15 @@ export class ProjectsPage extends React.Component<Props, 
State> {
         description: '',
         projectId: '',
     };
+    interval: any;
+
+    componentDidMount() {
+        this.interval = setInterval(() => this.props.onRefresh.call(this), 
500);
+    }
+
+    componentWillUnmount() {
+        clearInterval(this.interval);
+    }
 
     tools = () => (<Toolbar id="toolbar-group-types">
         <ToolbarContent>
@@ -193,7 +200,7 @@ export class ProjectsPage extends React.Component<Props, 
State> {
                                     <Td noPadding style={{width:"180px"}}>
                                         <Flex direction={{default: "row"}}>
                                             {environments.filter(e => e !== 
undefined)
-                                                .map(e => <FlexItem 
key={e}><Badge isRead>{e}</Badge></FlexItem>)}
+                                                .map(e => <FlexItem 
key={e}><Badge isRead={!project.deployed}>{e}</Badge></FlexItem>)}
                                         </Flex>
                                     </Td>
                                     <Td isActionCell>

Reply via email to