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 8cfafd092bbf5d6f1becc579dad6705949519076 Author: Marat Gubaidullin <ma...@talismancloud.io> AuthorDate: Thu May 1 17:00:24 2025 -0400 API Improvements --- .../camel/karavan/api/ContainerResource.java | 4 ++-- .../camel/karavan/api/InfrastructureResource.java | 2 +- .../apache/camel/karavan/api/ProjectResource.java | 2 +- .../camel/karavan/docker/DockerForKaravan.java | 2 +- .../apache/camel/karavan/docker/DockerService.java | 19 ++++++++++-------- .../apache/camel/karavan/docker/DockerUtils.java | 12 +++++++++-- .../karavan/kubernetes/KubernetesService.java | 23 +++++++++++++--------- .../apache/camel/karavan/model/ContainerType.java | 2 +- .../camel/karavan/model/DockerComposeService.java | 9 +++++++++ .../karavan/scheduler/CamelStatusScheduler.java | 4 ++-- .../apache/camel/karavan/service/CodeService.java | 4 ++-- 11 files changed, 54 insertions(+), 29 deletions(-) diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java index aeef850a..fc5dee63 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java @@ -124,11 +124,11 @@ public class ContainerResource { dockerService.createContainerFromCompose(dockerComposeService, labels, needPull(command)); dockerService.runContainer(dockerComposeService.getContainer_name()); } - } else if (Objects.equals(type, ContainerType.project.name())) { + } else if (Objects.equals(type, ContainerType.packaged.name())) { DockerComposeService dockerComposeService = projectService.getProjectDockerComposeService(projectId); if (dockerComposeService != null) { Map<String, String> labels = new HashMap<>(); - labels.put(LABEL_TYPE, ContainerType.project.name()); + labels.put(LABEL_TYPE, ContainerType.packaged.name()); labels.put(LABEL_CAMEL_RUNTIME, CamelRuntime.CAMEL_MAIN.getValue()); labels.put(LABEL_PROJECT_ID, projectId); dockerService.createContainerFromCompose(dockerComposeService, labels, needPull(command)); diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java index 862ec999..2ae58da9 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java @@ -94,7 +94,7 @@ public class InfrastructureResource { if (resources == null) { return Response.status(Response.Status.NOT_FOUND).entity("Resource file " + KUBERNETES_YAML_FILENAME + " not found").build(); } - kubernetesService.startDeployment(resources.getCode(), Map.of(LABEL_TYPE, ContainerType.project.name())); + kubernetesService.startDeployment(resources.getCode(), Map.of(LABEL_TYPE, ContainerType.packaged.name())); return Response.ok().build(); } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java index 4f2babaa..fb2cadb8 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java @@ -100,7 +100,7 @@ public class ProjectResource extends AbstractApiResource { LOGGER.info("Deleting containers"); Response res1 = devModeResource.deleteDevMode(projectId, true); Response res2 = containerResource.deleteContainer(projectId, ContainerType.devmode.name(), projectId); - Response res3 = containerResource.deleteContainer(projectId, ContainerType.project.name(), projectId); + Response res3 = containerResource.deleteContainer(projectId, ContainerType.packaged.name(), projectId); LOGGER.info("Deleting deployments"); Response res4 = infrastructureResource.deleteDeployment(null, projectId); } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java b/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java index c46625e7..a8bda0d6 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java @@ -91,7 +91,7 @@ public class DockerForKaravan { env, compose.getPortsMap(), healthCheck, containerLabels, compose.getVolumes(), null, RestartPolicy.noRestart(), DockerService.PULL_IMAGE.ifNotExists, - compose.getCpus(), compose.getCpu_percent(), compose.getMem_limit(), compose.getMem_reservation()); + compose.getCpus(), compose.getCpu_percent(), compose.getMem_limit(), compose.getMem_reservation(), compose.getCommand()); } public void runBuildProject(Project project, String script, DockerComposeService compose, Map<String, String> sshFiles, String tag) throws Exception { diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java b/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java index 8d944295..92d48873 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java @@ -142,7 +142,7 @@ public class DockerService { } } - public Container createContainerFromCompose(DockerComposeService compose, Map<String, String> labels, PULL_IMAGE pullImage, String... command) throws InterruptedException { + public Container createContainerFromCompose(DockerComposeService compose, Map<String, String> labels, PULL_IMAGE pullImage) throws InterruptedException { List<Container> containers = findContainer(compose.getContainer_name()); if (containers.isEmpty()) { HealthCheck healthCheck = DockerUtils.getHealthCheck(compose.getHealthcheck()); @@ -160,7 +160,7 @@ public class DockerService { return createContainer(compose.getContainer_name(), compose.getImage(), env, compose.getPortsMap(), healthCheck, labels, compose.getVolumes(), networkName, restartPolicy, pullImage, - compose.getCpus(), compose.getCpu_percent(), compose.getMem_limit(), compose.getMem_reservation(), command); + compose.getCpus(), compose.getCpu_percent(), compose.getMem_limit(), compose.getMem_reservation(), compose.getCommand()); } else { LOGGER.info("Compose Service already exists: " + containers.get(0).getId()); @@ -178,7 +178,7 @@ public class DockerService { HealthCheck healthCheck, Map<String, String> labels, List<DockerComposeVolume> volumes, String network, RestartPolicy restartPolicy, PULL_IMAGE pullImage, String cpus, String cpu_percent, String mem_limit, String mem_reservation, - String... command) throws InterruptedException { + String dockerCommand) throws InterruptedException { List<Container> containers = findContainer(name); if (containers.isEmpty()) { if (Objects.equals(labels.get(LABEL_TYPE), ContainerType.devmode.name()) @@ -187,13 +187,15 @@ public class DockerService { LOGGER.info("Pulling DevMode image from DockerHub: " + image); pullImageFromDockerHub(image, Objects.equals(pullImage, PULL_IMAGE.always)); } - if (Objects.equals(labels.get(LABEL_TYPE), ContainerType.project.name())) { + if (Objects.equals(labels.get(LABEL_TYPE), ContainerType.packaged.name())) { LOGGER.info("Pulling Project image from Registry: " + image); pullImage(image, Objects.equals(pullImage, PULL_IMAGE.always)); } - try (CreateContainerCmd createContainerCmd = getDockerClient().createContainerCmd(image).withName(name).withLabels(labels).withEnv(env).withHostName(name).withHealthcheck(healthCheck)) { - Ports portBindings = DockerUtils.getPortBindings(ports); + Ports portBindings = DockerUtils.getPortBindings(ports); + List<ExposedPort> exposePorts = DockerUtils.getExposedPorts(ports); + try (CreateContainerCmd createContainerCmd = getDockerClient().createContainerCmd(image) + .withName(name).withLabels(labels).withEnv(env).withHostName(name).withExposedPorts(exposePorts).withHealthcheck(healthCheck)) { List<Mount> mounts = new ArrayList<>(); if (volumes != null && !volumes.isEmpty()) { @@ -205,8 +207,9 @@ public class DockerService { mounts.add(mount); }); } - if (command.length > 0) { - createContainerCmd.withCmd(command); + if (dockerCommand != null) { + createContainerCmd.withCmd("/bin/sh", "-c", dockerCommand); + System.out.println(dockerCommand); } if (Objects.equals(labels.get(LABEL_PROJECT_ID), ContainerType.build.name())) { mounts.add(new Mount().withType(MountType.BIND).withSource("/var/run/docker.sock").withTarget("/var/run/docker.sock")); diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerUtils.java b/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerUtils.java index 1f85f119..8abb56fc 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerUtils.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerUtils.java @@ -104,6 +104,14 @@ public class DockerUtils { return portBindings; } + static List<ExposedPort> getExposedPorts(Map<Integer, Integer> ports) { + List<ExposedPort> exposedPorts = new ArrayList<>(ports.size()); + ports.forEach((hostPort, containerPort) -> { + exposedPorts.add(ExposedPort.tcp(containerPort)); + }); + return exposedPorts; + } + public static PodContainerStatus getContainerStatus(Container container, String environment) { String name = container.getNames()[0].replace("/", ""); List<ContainerPort> ports = Arrays.stream(container.getPorts()) @@ -166,8 +174,8 @@ public class DockerUtils { return ContainerType.devmode; } else if (Objects.equals(type, ContainerType.devservice.name())) { return ContainerType.devservice; - } else if (Objects.equals(type, ContainerType.project.name())) { - return ContainerType.project; + } else if (Objects.equals(type, ContainerType.packaged.name())) { + return ContainerType.packaged; } else if (Objects.equals(type, ContainerType.internal.name())) { return ContainerType.internal; } else if (Objects.equals(type, ContainerType.build.name())) { diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java b/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java index 1bebbe3f..d47abaaa 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/kubernetes/KubernetesService.java @@ -16,8 +16,6 @@ */ package org.apache.camel.karavan.kubernetes; -import org.apache.camel.karavan.model.KubernetesConfigMap; -import org.apache.camel.karavan.model.KubernetesSecret; import io.fabric8.kubernetes.api.model.*; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.client.KubernetesClient; @@ -32,7 +30,8 @@ import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; import org.apache.camel.karavan.KaravanConstants; import org.apache.camel.karavan.model.ContainerType; -import org.apache.camel.karavan.model.Project; +import org.apache.camel.karavan.model.KubernetesConfigMap; +import org.apache.camel.karavan.model.KubernetesSecret; import org.apache.camel.karavan.service.CodeService; import org.apache.camel.karavan.service.ConfigService; import org.eclipse.microprofile.config.inject.ConfigProperty; @@ -41,6 +40,7 @@ import org.jboss.logging.Logger; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.*; +import java.util.concurrent.TimeUnit; import static org.apache.camel.karavan.KaravanConstants.*; import static org.apache.camel.karavan.service.CodeService.BUILD_SCRIPT_FILENAME; @@ -349,24 +349,29 @@ public class KubernetesService { Pod old = client.pods().inNamespace(getNamespace()).withName(projectId).get(); if (old == null) { Pod pod = getDevModePod(projectId, verbose, compile, podLabels, projectDevmodeImage, deploymentFragment, envVars); - Pod result = client.resource(pod).serverSideApply(); - copyFilesToContainer(result, files, "/karavan/code"); - copyFilesToContainer(result, Map.of(".karavan.done", "done"), "/tmp"); - LOGGER.info("Created pod " + result.getMetadata().getName()); + Pod result = client.resource(pod).serverSideApply(); // important + result = client.pods().inNamespace(getNamespace()).withName(projectId).waitUntilReady(30, TimeUnit.SECONDS); + LOGGER.info("Pod " + result.getMetadata().getName() + " status " + result.getStatus()); + var copyFiles = copyFilesToContainer(result, files, "/karavan/code"); + LOGGER.info("Pod files copy result is " + copyFiles); + var copyDone = copyFilesToContainer(result, Map.of(".karavan.done", "done"), "/tmp"); + LOGGER.info("Pod files copy done is " + copyDone); + LOGGER.info("Pod pod " + result.getMetadata().getName()); } } createService(projectId, podLabels); } - private void copyFilesToContainer(Pod pod, Map<String, String> files, String dirName) { + private boolean copyFilesToContainer(Pod pod, Map<String, String> files, String dirName) { try (KubernetesClient client = kubernetesClient()) { String temp = codeService.saveProjectFilesInTemp(files); - client.pods().inNamespace(getNamespace()) + return client.pods().inNamespace(getNamespace()) .withName(pod.getMetadata().getName()) .dir(dirName) .upload(Paths.get(temp)); } catch (Exception e) { LOGGER.info("Error copying filed to devmode pod: " + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage())); + return false; } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/ContainerType.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/ContainerType.java index 7b315b69..6640dcfa 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/ContainerType.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/ContainerType.java @@ -21,7 +21,7 @@ public enum ContainerType { internal, devmode, devservice, - project, + packaged, build, unknown, } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/DockerComposeService.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/DockerComposeService.java index 010d88d9..b1de4e71 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/DockerComposeService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/DockerComposeService.java @@ -32,6 +32,7 @@ public class DockerComposeService { private String cpu_percent; private String mem_limit; private String mem_reservation; + private String command; private List<String> ports = new ArrayList<>(); private List<DockerComposeVolume> volumes = new ArrayList<>(); private List<String> expose = new ArrayList<>(); @@ -187,6 +188,14 @@ public class DockerComposeService { this.labels = labels; } + public String getCommand() { + return command; + } + + public void setCommand(String command) { + this.command = command; + } + @Override public String toString() { return "DockerComposeService {" + diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/scheduler/CamelStatusScheduler.java b/karavan-app/src/main/java/org/apache/camel/karavan/scheduler/CamelStatusScheduler.java index 2bafd074..edd95637 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/scheduler/CamelStatusScheduler.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/scheduler/CamelStatusScheduler.java @@ -56,7 +56,7 @@ public class CamelStatusScheduler { if (ConfigService.inKubernetes()) { karavanCache.getPodContainerStatuses(environment).stream() .filter(cs -> Objects.equals(cs.getLabels().get(LABEL_KUBERNETES_RUNTIME), CAMEL_PREFIX)) - .filter(cs -> Objects.equals(cs.getType(), ContainerType.devmode) || Objects.equals(cs.getType(), ContainerType.project)) + .filter(cs -> Objects.equals(cs.getType(), ContainerType.devmode) || Objects.equals(cs.getType(), ContainerType.packaged)) .filter(cs -> Objects.equals(cs.getCamelRuntime(), KaravanConstants.CamelRuntime.CAMEL_MAIN.getValue())) .forEach(cs -> { CamelStatusRequest csr = new CamelStatusRequest(cs.getProjectId(), cs.getContainerName()); @@ -67,7 +67,7 @@ public class CamelStatusScheduler { } else { karavanCache.getPodContainerStatuses(environment).stream() .filter(cs -> Objects.equals(cs.getCamelRuntime(), KaravanConstants.CamelRuntime.CAMEL_MAIN.getValue())) - .filter(cs -> Objects.equals(cs.getType(), ContainerType.devmode) || Objects.equals(cs.getType(), ContainerType.project)) + .filter(cs -> Objects.equals(cs.getType(), ContainerType.devmode) || Objects.equals(cs.getType(), ContainerType.packaged)) .forEach(cs -> { CamelStatusRequest csr = new CamelStatusRequest(cs.getProjectId(), cs.getContainerName()); eventBus.publish(CMD_COLLECT_CAMEL_STATUS, diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/CodeService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/CodeService.java index 20bbba62..bc41fa38 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/CodeService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/CodeService.java @@ -39,8 +39,8 @@ import org.yaml.snakeyaml.constructor.SafeConstructor; import java.io.*; import java.net.URI; import java.net.URISyntaxException; -import java.nio.file.FileSystem; import java.nio.file.*; +import java.nio.file.FileSystem; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -400,7 +400,7 @@ public class CodeService { var canonicalName = toEnvFormat(envName); val = ConfigProvider.getConfig().getConfigValue(canonicalName); } - return val != null? val.getValue() : null; + return val != null? val.getValue() : System.getProperty(envName, null); } private static String toEnvFormat(String input) {