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 c56e125bbe8c959ae197a815128c57d8fc4d5802 Author: Marat Gubaidullin <marat.gubaidul...@gmail.com> AuthorDate: Tue Jul 25 20:40:13 2023 -0400 DevMode improvements #817 --- .../apache/camel/karavan/api/DevModeResource.java | 15 +++++--- .../camel/karavan/docker/DockerEventListener.java | 5 ++- .../apache/camel/karavan/docker/DockerService.java | 42 +++++++++++++--------- .../karavan/kubernetes/KubernetesService.java | 24 +++++++------ .../camel/karavan/kubernetes/PodEventHandler.java | 9 ++--- .../apache/camel/karavan/service/AuthService.java | 1 - .../apache/camel/karavan/service/EventService.java | 4 +-- .../apache/camel/karavan/shared/Configuration.java | 16 +++++++++ .../AuthService.java => shared/Constants.java} | 23 +++--------- .../org/apache/camel/karavan/shared/EventType.java | 16 +++++++++ .../src/main/webui/src/api/ProjectService.ts | 24 ++++++------- .../webui/src/containers/ContainerTableRow.tsx | 2 +- .../src/main/webui/src/project/DevModeToolbar.tsx | 21 ++++++----- .../src/main/webui/src/project/ProjectToolbar.tsx | 1 - .../webui/src/project/pipeline/ProjectStatus.tsx | 3 -- 15 files changed, 117 insertions(+), 89 deletions(-) diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/DevModeResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/DevModeResource.java index 6379b058..d6d647c9 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/DevModeResource.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/DevModeResource.java @@ -16,6 +16,8 @@ */ package org.apache.camel.karavan.api; +import io.vertx.core.json.JsonObject; +import io.vertx.mutiny.core.eventbus.EventBus; import org.apache.camel.karavan.docker.DockerService; import org.apache.camel.karavan.infinispan.InfinispanService; import org.apache.camel.karavan.infinispan.model.CamelStatus; @@ -24,6 +26,7 @@ import org.apache.camel.karavan.infinispan.model.Project; import org.apache.camel.karavan.kubernetes.KubernetesService; import org.apache.camel.karavan.service.CamelService; import org.apache.camel.karavan.shared.ConfigService; +import org.apache.camel.karavan.shared.EventType; import org.eclipse.microprofile.config.inject.ConfigProperty; import javax.inject.Inject; @@ -31,7 +34,6 @@ import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Objects; -import java.util.Optional; @Path("/api/devmode") public class DevModeResource { @@ -51,6 +53,9 @@ public class DevModeResource { @Inject DockerService dockerService; + @Inject + EventBus eventBus; + @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -64,12 +69,12 @@ public class DevModeResource { if (!Objects.equals(status.getState(), ContainerStatus.State.running.name())){ status.setInTransit(true); - infinispanService.saveContainerStatus(status); + eventBus.send(EventType.CONTAINER_STATUS, JsonObject.mapFrom(status)); if (ConfigService.inKubernetes()) { - kubernetesService.runDevModeContainer(project, ""); + kubernetesService.runDevModeContainer(project, jBangOptions); } else { - dockerService.runDevmodeContainer(project, ""); + dockerService.runDevmodeContainer(project, jBangOptions); } return Response.ok(containerName).build(); } @@ -102,7 +107,7 @@ public class DevModeResource { public Response deleteDevMode(@PathParam("projectId") String projectId, @PathParam("deletePVC") boolean deletePVC) { infinispanService.setContainerStatusTransit(projectId, environment, projectId); if (ConfigService.inKubernetes()) { - kubernetesService.deleteRunner(projectId, deletePVC); + kubernetesService.deleteDevModePod(projectId, deletePVC); } else { dockerService.deleteContainer(projectId); } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerEventListener.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerEventListener.java index 86c40428..34a2905f 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerEventListener.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerEventListener.java @@ -6,7 +6,6 @@ import com.github.dockerjava.api.model.ContainerPort; import com.github.dockerjava.api.model.Event; import com.github.dockerjava.api.model.EventType; import io.vertx.core.eventbus.EventBus; -import io.vertx.core.json.JsonObject; import org.apache.camel.karavan.infinispan.InfinispanService; import org.apache.camel.karavan.infinispan.model.ContainerStatus; import org.eclipse.microprofile.config.inject.ConfigProperty; @@ -20,8 +19,8 @@ import java.time.Instant; import java.util.*; import java.util.stream.Collectors; -import static org.apache.camel.karavan.docker.DockerService.LABEL_PROJECT_ID; -import static org.apache.camel.karavan.docker.DockerService.LABEL_TYPE; +import static org.apache.camel.karavan.shared.Constants.LABEL_PROJECT_ID; +import static org.apache.camel.karavan.shared.Constants.LABEL_TYPE; import static org.apache.camel.karavan.shared.EventType.DEVMODE_CONTAINER_READY; import static org.apache.camel.karavan.shared.EventType.INFINISPAN_STARTED; diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java index 84178d09..b7a6fa5e 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.camel.karavan.docker; import com.github.dockerjava.api.DockerClient; @@ -29,6 +45,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; +import static org.apache.camel.karavan.shared.Constants.*; import static org.apache.camel.karavan.shared.EventType.*; @ApplicationScoped @@ -36,12 +53,10 @@ public class DockerService { private static final Logger LOGGER = Logger.getLogger(DockerService.class.getName()); - public static final String INFINISPAN_CONTAINER_NAME = "infinispan"; - public static final String KARAVAN_CONTAINER_NAME = "karavan-headless"; + protected static final String INFINISPAN_CONTAINER_NAME = "infinispan"; + protected static final String KARAVAN_CONTAINER_NAME = "karavan-headless"; - public static final String NETWORK_NAME = "karavan"; - public static final String LABEL_TYPE = "org.apache.camel.karavan.type"; - public static final String LABEL_PROJECT_ID = "org.apache.camel.karavan.projectId"; + protected static final String NETWORK_NAME = "karavan"; private static final DecimalFormat formatCpu = new DecimalFormat("0.00"); private static final DecimalFormat formatMiB = new DecimalFormat("0.0"); private static final DecimalFormat formatGiB = new DecimalFormat("0.00"); @@ -59,8 +74,6 @@ public class DockerService { @ConfigProperty(name = "infinispan.image") String infinispanImage; - @ConfigProperty(name = "infinispan.hosts") - String infinispanHosts; @ConfigProperty(name = "infinispan.port") String infinispanPort; @ConfigProperty(name = "infinispan.username") @@ -71,9 +84,6 @@ public class DockerService { @Inject DockerEventListener dockerEventListener; - @Inject - InfinispanService infinispanService; - @Inject EventBus eventBus; @@ -81,13 +91,17 @@ public class DockerService { public void runDevmodeContainer(Project project, String jBangOptions) throws InterruptedException { String projectId = project.getProjectId(); - LOGGER.infof("DevMode starting for %s", projectId); + LOGGER.infof("DevMode starting for %s with JBANG_OPTIONS=%s", projectId, jBangOptions); HealthCheck healthCheck = new HealthCheck().withTest(List.of("CMD", "curl", "-f", "http://localhost:8080/q/dev/health")) .withInterval(10000000000L).withTimeout(10000000000L).withStartPeriod(10000000000L).withRetries(30); + List<String> env = jBangOptions !=null && !jBangOptions.trim().isEmpty() + ? List.of(ENV_VAR_JBANG_OPTIONS + "=" + jBangOptions) + : List.of(); + createContainer(projectId, devmodeImage, - List.of(), null, false, false, healthCheck, + env, null, false, false, healthCheck, Map.of(LABEL_TYPE, ContainerStatus.ContainerType.devmode.name(), LABEL_PROJECT_ID, projectId)); startContainer(projectId); @@ -298,14 +312,10 @@ public class DockerService { } public void deleteContainer(String name) { - long time = System.currentTimeMillis(); List<Container> containers = getDockerClient().listContainersCmd().withShowAll(true).withNameFilter(List.of(name)).exec(); - System.out.println("Get containers " + (System.currentTimeMillis() - time)); - time = System.currentTimeMillis(); if (containers.size() == 1) { Container container = containers.get(0); getDockerClient().removeContainerCmd(container.getId()).withForce(true).exec(); - System.out.println("removeContainerCmd " + (System.currentTimeMillis() - time)); } } 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 3be6850a..1e83cac7 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 @@ -29,6 +29,7 @@ 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; import org.apache.camel.karavan.infinispan.model.Project; import org.apache.camel.karavan.infinispan.model.ProjectFile; import org.apache.camel.karavan.service.CodeService; @@ -47,6 +48,7 @@ import java.util.*; import java.util.stream.Collectors; import static org.apache.camel.karavan.service.CodeService.APPLICATION_PROPERTIES_FILENAME; +import static org.apache.camel.karavan.shared.Constants.*; @Default @Readiness @@ -54,12 +56,12 @@ import static org.apache.camel.karavan.service.CodeService.APPLICATION_PROPERTIE public class KubernetesService implements HealthCheck { private static final Logger LOGGER = Logger.getLogger(KubernetesService.class.getName()); - public static final int INFORMERS = 4; + protected static final int INFORMERS = 4; private static final String CAMEL_PREFIX = "camel"; private static final String KARAVAN_PREFIX = "karavan"; private static final String JBANG_CACHE_SUFFIX = "jbang-cache"; private static final String M2_CACHE_SUFFIX = "m2-cache"; - public static final String PVC_MAVEN_SETTINGS = "maven-settings"; + protected static final String PVC_MAVEN_SETTINGS = "maven-settings"; @Inject EventBus eventBus; @@ -400,9 +402,9 @@ public class KubernetesService implements HealthCheck { createService(name); } - public void deleteRunner(String name, boolean deletePVC) { + public void deleteDevModePod(String name, boolean deletePVC) { try { - LOGGER.info("Delete runner: " + name + " in the namespace: " + getNamespace()); + LOGGER.info("Delete devmode pod: " + name + " in the namespace: " + getNamespace()); kubernetesClient().pods().inNamespace(getNamespace()).withName(name).delete(); kubernetesClient().services().inNamespace(getNamespace()).withName(name).delete(); if (deletePVC) { @@ -426,7 +428,7 @@ public class KubernetesService implements HealthCheck { Map<String, String> labels = new HashMap<>(); labels.putAll(getRuntimeLabels()); labels.putAll(getKaravanRunnerLabels(name)); - labels.put("karavan/projectId", projectId); + labels.put(LABEL_PROJECT_ID, projectId); ResourceRequirements resources = getResourceRequirements(containerResources); @@ -448,7 +450,7 @@ public class KubernetesService implements HealthCheck { .withPorts(port) .withResources(resources) .withImagePullPolicy("Always") - .withEnv(new EnvVarBuilder().withName("JBANG_OPTIONS").withValue(jbangOptions).build()) + .withEnv(new EnvVarBuilder().withName(ENV_VAR_JBANG_OPTIONS).withValue(jbangOptions).build()) .withVolumeMounts( new VolumeMountBuilder().withName(name).withMountPath("/karavan/.jbang/cache").build(), new VolumeMountBuilder().withName("maven-settings").withSubPath("maven-settings.xml") @@ -473,14 +475,14 @@ public class KubernetesService implements HealthCheck { .build(); } - private void createPVC(String runnerName) { - PersistentVolumeClaim old = kubernetesClient().persistentVolumeClaims().inNamespace(getNamespace()).withName(runnerName).get(); + private void createPVC(String podName) { + PersistentVolumeClaim old = kubernetesClient().persistentVolumeClaims().inNamespace(getNamespace()).withName(podName).get(); if (old == null) { PersistentVolumeClaim pvc = new PersistentVolumeClaimBuilder() .withNewMetadata() - .withName(runnerName) + .withName(podName) .withNamespace(getNamespace()) - .withLabels(getKaravanRunnerLabels(runnerName)) + .withLabels(getKaravanRunnerLabels(podName)) .endMetadata() .withNewSpec() .withResources(new ResourceRequirementsBuilder().withRequests(Map.of("storage", new Quantity("2Gi"))).build()) @@ -533,7 +535,7 @@ public class KubernetesService implements HealthCheck { } public static Map<String, String> getKaravanRunnerLabels(String name) { - return Map.of("karavan/type", "runner", + return Map.of(LABEL_TYPE, ContainerStatus.ContainerType.devmode.name(), "app.kubernetes.io/name", name); } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/PodEventHandler.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/PodEventHandler.java index b46af28c..5d9417ac 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/PodEventHandler.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/PodEventHandler.java @@ -14,6 +14,7 @@ import org.jboss.logging.Logger; import java.util.List; import static org.apache.camel.karavan.service.CodeService.DEFAULT_CONTAINER_RESOURCES; +import static org.apache.camel.karavan.shared.Constants.LABEL_PROJECT_ID; import static org.apache.camel.karavan.shared.EventType.CONTAINER_STATUS; public class PodEventHandler implements ResourceEventHandler<Pod> { @@ -60,7 +61,7 @@ public class PodEventHandler implements ResourceEventHandler<Pod> { try { LOGGER.info("onDelete " + pod.getMetadata().getName()); String deployment = pod.getMetadata().getLabels().get("app"); - String projectId = deployment != null ? deployment : pod.getMetadata().getLabels().get("karavan/projectId"); + String projectId = deployment != null ? deployment : pod.getMetadata().getLabels().get(LABEL_PROJECT_ID); infinispanService.deleteContainerStatus(projectId, kubernetesService.environment, pod.getMetadata().getName()); } catch (Exception e){ LOGGER.error(e.getMessage(), e.getCause()); @@ -70,7 +71,7 @@ public class PodEventHandler implements ResourceEventHandler<Pod> { public ContainerStatus getPodStatus(Pod pod) { String deployment = pod.getMetadata().getLabels().get("app"); - String projectId = deployment != null ? deployment : pod.getMetadata().getLabels().get("karavan/projectId"); + String projectId = deployment != null ? deployment : pod.getMetadata().getLabels().get(LABEL_PROJECT_ID); try { boolean ready = pod.getStatus().getConditions().stream().anyMatch(c -> c.getType().equals("Ready")); String creationTimestamp = pod.getMetadata().getCreationTimestamp(); @@ -89,8 +90,8 @@ public class PodEventHandler implements ResourceEventHandler<Pod> { projectId, kubernetesService.environment, pod.getMetadata().getName().equals(projectId) ? ContainerStatus.ContainerType.devmode : ContainerStatus.ContainerType.project, - requestMemory + " : " + limitMemory, - requestCpu + " : " + limitCpu, + requestMemory + " / " + limitMemory, + requestCpu + " / " + limitCpu, creationTimestamp); if (ready) { diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java index bcd8f90f..e3b489fe 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java @@ -16,7 +16,6 @@ */ package org.apache.camel.karavan.service; -import io.vertx.core.Vertx; import org.eclipse.microprofile.config.ConfigProvider; import org.jboss.logging.Logger; diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/EventService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/EventService.java index f3e011f4..ea858d05 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/EventService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/EventService.java @@ -78,7 +78,8 @@ public class EventService { void receiveCommand(String projectId) { LOGGER.info("DEVMODE_CONTAINER_READY " + projectId); ContainerStatus status = infinispanService.getContainerStatus(projectId, environment, projectId); - if (!status.getCodeLoaded() && status.getContainerId() != null && status.getState().equals(ContainerStatus.State.running.name())) { + System.out.println(status); + if (status != null && !status.getCodeLoaded() && status.getContainerId() != null && status.getState().equals(ContainerStatus.State.running.name())) { if (ConfigService.inKubernetes()) { camelService.reloadProjectCode(projectId); } else { @@ -91,7 +92,6 @@ public class EventService { public void saveContainerStatus(JsonObject data) { if (infinispanService.isReady()) { ContainerStatus newStatus = data.mapTo(ContainerStatus.class); - System.out.println(newStatus); ContainerStatus oldStatus = infinispanService.getContainerStatus(newStatus.getProjectId(), newStatus.getEnv(), newStatus.getContainerName()); if (oldStatus == null || Objects.equals(oldStatus.getInTransit(), Boolean.FALSE)) { infinispanService.saveContainerStatus(newStatus); diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Configuration.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Configuration.java index 2e39bbb0..6ccabdf9 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Configuration.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Configuration.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.camel.karavan.shared; import java.util.List; diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java similarity index 52% copy from karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java copy to karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java index bcd8f90f..07834b3b 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java @@ -14,26 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.karavan.service; +package org.apache.camel.karavan.shared; -import io.vertx.core.Vertx; -import org.eclipse.microprofile.config.ConfigProvider; -import org.jboss.logging.Logger; +public class Constants { -import javax.enterprise.context.ApplicationScoped; -import java.net.MalformedURLException; -import java.util.Map; + public static final String ENV_VAR_JBANG_OPTIONS = "JBANG_OPTIONS"; -@ApplicationScoped -public class AuthService { + public static final String LABEL_TYPE = "org.apache.camel.karavan/type"; + public static final String LABEL_PROJECT_ID = "org.apache.camel.karavan/projectId"; - private static final Logger LOGGER = Logger.getLogger(AuthService.class.getName()); - - public String authType() { - return ConfigProvider.getConfig().getValue("karavan.auth", String.class); - } - - public Map<String, String> getSsoConfig() throws MalformedURLException { - return Map.of("url", ConfigProvider.getConfig().getValue("karavan.frontend.auth-server-url", String.class)); - } } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/EventType.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/EventType.java index a1085fb9..3a375e41 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/EventType.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/EventType.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.camel.karavan.shared; public class EventType { diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts index 28f6cf2b..8b043d61 100644 --- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts +++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts @@ -17,10 +17,10 @@ export class ProjectService { public static startDevModeContainer(project: Project, verbose: boolean) { useDevModeStore.setState({status: "wip"}) KaravanApi.startDevModeContainer(project, verbose, res => { + useDevModeStore.setState({status: "none"}) if (res.status === 200 || res.status === 201) { ProjectEventBus.sendLog("set", ''); useLogStore.setState({showLog: true, type: 'container', podName: res.data}) - useDevModeStore.setState({status: "none"}) } else { // Todo notification } @@ -30,19 +30,20 @@ export class ProjectService { public static reloadDevModeCode(project: Project) { useDevModeStore.setState({status: "wip"}) KaravanApi.reloadDevModeCode(project.projectId, res => { + useDevModeStore.setState({status: "none"}) if (res.status === 200 || res.status === 201) { // setIsReloadingPod(false); } else { // Todo notification // setIsReloadingPod(false); } - useDevModeStore.setState({status: "none"}) }); } public static stopDevModeContainer(project: Project) { useDevModeStore.setState({status: "wip"}) KaravanApi.manageContainer("dev", project.projectId, 'stop', res => { + useDevModeStore.setState({status: "none"}) if (res.status === 200) { useLogStore.setState({showLog: false, type: 'container', isRunning: false}) } else { @@ -54,6 +55,7 @@ export class ProjectService { public static pauseDevModeContainer(project: Project) { useDevModeStore.setState({status: "wip"}) KaravanApi.manageContainer("dev", project.projectId, 'pause', res => { + useDevModeStore.setState({status: "none"}) if (res.status === 200) { useLogStore.setState({showLog: false, type: 'container', isRunning: false}) } else { @@ -66,12 +68,12 @@ export class ProjectService { useDevModeStore.setState({status: "wip"}) ProjectEventBus.sendLog("set", ''); KaravanApi.deleteDevModeContainer(project.projectId, false, res => { + useDevModeStore.setState({status: "none"}) if (res.status === 202) { useLogStore.setState({showLog: false, type: 'container', isRunning: false}) } else { ProjectEventBus.sendAlert(new ToastMessage("Error delete runner", res.statusText, 'warning')) } - useDevModeStore.setState({status: "none"}) }); } @@ -80,22 +82,19 @@ export class ProjectService { KaravanApi.getDevModePodStatus(projectId, res => { if (res.status === 200) { unstable_batchedUpdates(() => { - const podStatus = res.data; - if (useDevModeStore.getState().podName !== podStatus.containerName){ - useDevModeStore.setState({podName: podStatus.containerName}) + const containerStatus = res.data; + if (useDevModeStore.getState().podName !== containerStatus.containerName){ + useDevModeStore.setState({podName: containerStatus.containerName}) } if (useDevModeStore.getState().status !== "wip"){ - useDevModeStore.setState({status: "wip"}) useLogStore.setState({isRunning: true}) } - useProjectStore.setState({containerStatus: res.data}); + useProjectStore.setState({containerStatus: containerStatus}); }) } else { unstable_batchedUpdates(() => { - if (useDevModeStore.getState().status !== 'none') { - useDevModeStore.setState({status: "none", podName: undefined}) - useProjectStore.setState({containerStatus: new ContainerStatus()}); - } + useDevModeStore.setState({status: "none", podName: undefined}) + useProjectStore.setState({containerStatus: new ContainerStatus({})}); }) } }); @@ -178,7 +177,6 @@ export class ProjectService { public static createProject(project: Project) { KaravanApi.postProject(project, res => { - console.log(res.status) if (res.status === 200 || res.status === 201) { ProjectService.refreshProjectData(); // this.props.toast?.call(this, "Success", "Project created", "success"); diff --git a/karavan-web/karavan-app/src/main/webui/src/containers/ContainerTableRow.tsx b/karavan-web/karavan-app/src/main/webui/src/containers/ContainerTableRow.tsx index 660c2f0d..13d702d2 100644 --- a/karavan-web/karavan-app/src/main/webui/src/containers/ContainerTableRow.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/containers/ContainerTableRow.tsx @@ -57,7 +57,7 @@ export const ContainerTableRow = (props: Props) => { </Td> <Td> {!inTransit && <Label color={color}>{container.state}</Label>} - {inTransit && <Spinner isSVG size="md" aria-label="spinner"/>} + {inTransit && <Spinner isSVG size="lg" aria-label="spinner"/>} </Td> <Td className="project-action-buttons"> {container.type !== 'internal' && diff --git a/karavan-web/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx b/karavan-web/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx index 510372e5..58dae7ea 100644 --- a/karavan-web/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx @@ -1,5 +1,5 @@ import React, {useState} from 'react'; -import {Button, Flex, FlexItem, Label, Switch, Tooltip, TooltipPosition} from '@patternfly/react-core'; +import {Button, Flex, FlexItem, Label, Spinner, Switch, Tooltip, TooltipPosition} from '@patternfly/react-core'; import '../designer/karavan.css'; import RocketIcon from "@patternfly/react-icons/dist/esm/icons/rocket-icon"; import ReloadIcon from "@patternfly/react-icons/dist/esm/icons/bolt-icon"; @@ -23,13 +23,16 @@ export const DevModeToolbar = (props: Props) => { const [verbose, setVerbose] = useState(false); const commands = containerStatus.commands; - const ports = containerStatus.ports; const isRunning = containerStatus.state === 'running'; const inTransit = containerStatus.inTransit; + const isLoading= status === 'wip'; const color = containerStatus.state === 'running' ? "green" : "grey"; const icon = isRunning ? <UpIcon/> : <DownIcon/>; return (<Flex className="toolbar" direction={{default: "row"}} alignItems={{default: "alignItemsCenter"}}> - {<FlexItem> + <FlexItem> + {(inTransit || isLoading) && <Spinner isSVG size="lg" aria-label="spinner"/>} + </FlexItem> + {containerStatus.containerId && <FlexItem> <Label icon={icon} color={color}> <Tooltip content={"Show log"} position={TooltipPosition.bottom}> <Button variant="link" @@ -51,8 +54,7 @@ export const DevModeToolbar = (props: Props) => { </FlexItem> {!isRunning && <FlexItem> <Tooltip content="Run in developer mode" position={TooltipPosition.bottom}> - <Button isLoading={status === 'wip'} - isSmall + <Button isSmall isDisabled={(!(commands.length === 0) && !commands.includes('run')) || inTransit} variant={"primary"} icon={<RocketIcon/>} @@ -63,8 +65,7 @@ export const DevModeToolbar = (props: Props) => { </FlexItem>} {isRunning && <FlexItem> <Tooltip content="Reload" position={TooltipPosition.bottom}> - <Button isLoading={status === 'wip'} - isSmall + <Button isSmall isDisabled={inTransit} variant={"primary"} className="project-button" @@ -75,8 +76,7 @@ export const DevModeToolbar = (props: Props) => { </FlexItem>} {<FlexItem> <Tooltip content="Stop container" position={TooltipPosition.bottom}> - <Button isLoading={status === 'wip'} - isSmall + <Button isSmall isDisabled={!commands.includes('stop') || inTransit} variant={"control"} icon={<StopIcon/>} @@ -86,8 +86,7 @@ export const DevModeToolbar = (props: Props) => { </FlexItem>} {<FlexItem> <Tooltip content="Delete container" position={TooltipPosition.bottom}> - <Button isLoading={status === 'wip'} - isSmall + <Button isSmall isDisabled={!commands.includes('delete') || inTransit} variant={"control"} icon={<DeleteIcon/>} diff --git a/karavan-web/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx b/karavan-web/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx index 2f639228..daed745b 100644 --- a/karavan-web/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx @@ -34,7 +34,6 @@ export const ProjectToolbar = (props: Props) => { [state.file, state.editAdvancedProperties, state.setEditAdvancedProperties, state.setAddProperty], shallow ) useEffect(() => { - console.log("ProjectToolbar useEffect", isPushing, project.lastCommitTimestamp); }, [project, file]); function isFile(): boolean { diff --git a/karavan-web/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx b/karavan-web/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx index f32d070e..add844b9 100644 --- a/karavan-web/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx @@ -65,15 +65,12 @@ export class ProjectStatus extends React.Component<Props, State> { }); KaravanApi.getProjectDeploymentStatus(projectId, env, (status?: DeploymentStatus) => { this.setState({deploymentStatus: status}); - // console.log(status); }); KaravanApi.getProjectPodStatuses(projectId, env, (statuses: ContainerStatus[]) => { this.setState({podStatuses: statuses}); - // console.log(status); }); KaravanApi.getProjectCamelStatus(projectId, env, (status: CamelStatus) => { this.setState({camelStatus: status}); - // console.log(status); }); } }