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
The following commit(s) were added to refs/heads/main by this push:
new d72e4dd2 Fix #1357
d72e4dd2 is described below
commit d72e4dd2ba75fe4b88fbd5141f6a403604531daf
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Mon Aug 12 07:07:20 2024 -0400
Fix #1357
---
.../camel/karavan/api/ContainerResource.java | 10 ++--
.../karavan/docker/DockerComposeConverter.java | 25 ++++++++++
.../camel/karavan/docker/DockerForKaravan.java | 15 ++----
.../apache/camel/karavan/docker/DockerService.java | 35 ++++++++++---
.../camel/karavan/model/DockerComposeService.java | 17 ++-----
.../camel/karavan/model/DockerComposeVolume.java | 58 ++++++++++++++++++++++
.../camel/karavan/service/ConfigService.java | 13 ++---
.../camel/karavan/service/ProjectService.java | 26 ++++++----
8 files changed, 145 insertions(+), 54 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 d20c0e6e..adf945a4 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
@@ -140,11 +140,11 @@ public class ContainerResource {
}
}
- private boolean needPull(JsonObject command) {
- if (command != null && command.containsKey("pullImage")) {
- return command.getBoolean("pullImage");
- }
- return false;
+ private DockerService.PULL_IMAGE needPull(JsonObject command) {
+ try {
+ return
DockerService.PULL_IMAGE.valueOf(command.getString("pullImage"));
+ } catch (Exception ignored) {}
+ return DockerService.PULL_IMAGE.never;
}
private void setContainerStatusTransit(String projectId, String name,
String type) {
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerComposeConverter.java
b/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerComposeConverter.java
index 27323646..61534da3 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerComposeConverter.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerComposeConverter.java
@@ -21,6 +21,7 @@ import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import org.apache.camel.karavan.model.DockerCompose;
import org.apache.camel.karavan.model.DockerComposeService;
+import org.apache.camel.karavan.model.DockerComposeVolume;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.introspector.Property;
@@ -29,9 +30,13 @@ import org.yaml.snakeyaml.representer.Representer;
import java.util.Map;
+import static com.github.dockerjava.api.model.MountType.BIND;
+import static com.github.dockerjava.api.model.MountType.VOLUME;
+
public class DockerComposeConverter {
private static final String ENVIRONMENT = "environment";
+ private static final String VOLUMES = "volumes";
public static DockerCompose fromCode(String code) {
Yaml yaml = new Yaml();
@@ -75,6 +80,26 @@ public class DockerComposeConverter {
});
service.put(ENVIRONMENT, env);
}
+ if (service.containsKey(VOLUMES) && service.getValue(VOLUMES)
instanceof JsonArray) {
+ JsonArray volumes = new JsonArray();
+ JsonArray yamlVolumes = service.getJsonArray(VOLUMES);
+ yamlVolumes.forEach(o -> {
+ if (o instanceof JsonObject) {
+ volumes.add(o);
+ } else if (o instanceof String) {
+ var parts = ((String) o).split(":");
+ if (parts.length == 2) {
+ var part0 = parts[0];
+ var type = part0.startsWith("/") ||
part0.startsWith("~") || part0.startsWith("./") ? VOLUME : BIND;
+ volumes.add(JsonObject.mapFrom(new
DockerComposeVolume(type.name().toLowerCase(), parts[0], parts[1])));
+ } else if (parts.length == 1) {
+ volumes.add(JsonObject.mapFrom(new
DockerComposeVolume(VOLUME.name().toLowerCase(), null, parts[0])));
+ }
+ }
+ });
+ service.put(VOLUMES, volumes);
+ }
+
DockerComposeService ds = service.mapTo(DockerComposeService.class);
if (ds.getContainer_name() == null) {
ds.setContainer_name(name);
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 feb08009..8b59d527 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
@@ -22,6 +22,7 @@ import com.github.dockerjava.api.model.RestartPolicy;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.apache.camel.karavan.model.DockerComposeService;
+import org.apache.camel.karavan.model.DockerComposeVolume;
import org.apache.camel.karavan.model.PodContainerStatus;
import org.apache.camel.karavan.model.Project;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@@ -30,7 +31,6 @@ import org.jboss.logging.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import static org.apache.camel.karavan.KaravanConstants.*;
import static
org.apache.camel.karavan.service.CodeService.BUILD_SCRIPT_FILENAME;
@@ -68,11 +68,6 @@ public class DockerForKaravan {
var imageName = projectDevmodeImage != null ? projectDevmodeImage :
devmodeImage;
- if (dockerService.getImages().stream().noneMatch(i ->
Objects.equals(i.getTag(), imageName))) {
- LOGGER.info("Pulling DevMode image from DockerHub: " + imageName);
- dockerService.pullImageFromDockerHub(imageName, true);
- }
-
return dockerService.createContainer(projectId,
(imageName),
env, compose.getPortsMap(), healthCheck,
@@ -80,14 +75,14 @@ public class DockerForKaravan {
LABEL_PROJECT_ID, projectId,
LABEL_CAMEL_RUNTIME, CamelRuntime.CAMEL_MAIN.getValue()
),
- compose.getVolumesMap(), null, RestartPolicy.noRestart(),
false,
+ compose.getVolumes(), null, RestartPolicy.noRestart(),
DockerService.PULL_IMAGE.ifNotExists,
compose.getCpus(), compose.getCpu_percent(),
compose.getMem_limit(), compose.getMem_reservation());
}
public void runBuildProject(Project project, String script,
DockerComposeService compose, Map<String, String> sshFiles, String tag) throws
Exception {
String containerName = project.getProjectId() + BUILDER_SUFFIX;
dockerService.deleteContainer(containerName);
- Container c = createBuildContainer(containerName, project,
compose.getEnvironmentList(), compose.getVolumesMap(), tag);
+ Container c = createBuildContainer(containerName, project,
compose.getEnvironmentList(), compose.getVolumes(), tag);
dockerService.copyExecFile(c.getId(), "/karavan/builder",
BUILD_SCRIPT_FILENAME, script);
sshFiles.forEach((name, text) -> {
dockerService.copyExecFile(c.getId(), "/karavan/.ssh", name, text);
@@ -95,7 +90,7 @@ public class DockerForKaravan {
dockerService.runContainer(c);
}
- protected Container createBuildContainer(String containerName, Project
project, List<String> env, Map<String, String> volumes, String tag) throws
InterruptedException {
+ protected Container createBuildContainer(String containerName, Project
project, List<String> env, List<DockerComposeVolume> volumes, String tag)
throws InterruptedException {
LOGGER.infof("Starting Build Container ", containerName);
return dockerService.createContainer(containerName, devmodeImage,
@@ -105,7 +100,7 @@ public class DockerForKaravan {
LABEL_PROJECT_ID, project.getProjectId(),
LABEL_TAG, tag
),
- volumes, null,RestartPolicy.noRestart(), false,
+ volumes, null,RestartPolicy.noRestart(),
DockerService.PULL_IMAGE.ifNotExists,
null, null, null, null,
"/karavan/builder/build.sh");
}
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 e5710187..ed89fd79 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
@@ -34,6 +34,7 @@ import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
import org.apache.camel.karavan.model.ContainerImage;
import org.apache.camel.karavan.model.DockerComposeService;
+import org.apache.camel.karavan.model.DockerComposeVolume;
import org.apache.camel.karavan.model.PodContainerStatus;
import org.apache.camel.karavan.service.CodeService;
import org.apache.camel.karavan.service.ConfigService;
@@ -54,10 +55,15 @@ import java.util.*;
import java.util.stream.Collectors;
import static org.apache.camel.karavan.KaravanConstants.LABEL_PROJECT_ID;
+import static org.apache.camel.karavan.KaravanConstants.LABEL_TYPE;
@ApplicationScoped
public class DockerService {
+ public enum PULL_IMAGE {
+ always, ifNotExists, never
+ }
+
private static final Logger LOGGER =
Logger.getLogger(DockerService.class.getName());
@ConfigProperty(name = "karavan.docker.network")
@@ -120,7 +126,7 @@ public class DockerService {
public Container getContainer(String id) {
try (ListContainersCmd cmd =
getDockerClient().listContainersCmd().withShowAll(true).withIdFilter(List.of(id)))
{
- List<Container> containers = cmd.exec();
+ List<Container> containers = cmd.exec();
return containers.isEmpty() ? null : containers.get(0);
}
}
@@ -136,7 +142,7 @@ public class DockerService {
}
}
- public Container createContainerFromCompose(DockerComposeService compose,
Map<String, String> labels, Boolean pullAlways, String... command) throws
InterruptedException {
+ public Container createContainerFromCompose(DockerComposeService compose,
Map<String, String> labels, PULL_IMAGE pullImage, String... command) throws
InterruptedException {
List<Container> containers =
findContainer(compose.getContainer_name());
if (containers.isEmpty()) {
HealthCheck healthCheck =
DockerUtils.getHealthCheck(compose.getHealthcheck());
@@ -153,7 +159,7 @@ public class DockerService {
}
return createContainer(compose.getContainer_name(),
compose.getImage(),
- env, compose.getPortsMap(), healthCheck, labels,
compose.getVolumesMap(), networkName, restartPolicy, pullAlways,
+ env, compose.getPortsMap(), healthCheck, labels,
compose.getVolumes(), networkName, restartPolicy, pullImage,
compose.getCpus(), compose.getCpu_percent(),
compose.getMem_limit(), compose.getMem_reservation(), command);
} else {
@@ -170,20 +176,33 @@ public class DockerService {
public Container createContainer(String name, String image, List<String>
env, Map<Integer, Integer> ports,
HealthCheck healthCheck, Map<String,
String> labels,
- Map<String, String> volumes, String
network, RestartPolicy restartPolicy,
- boolean pullAlways, String cpus, String
cpu_percent, String mem_limit, String mem_reservation,
+ 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 {
List<Container> containers = findContainer(name);
if (containers.isEmpty()) {
- pullImage(image, pullAlways);
+ if (Objects.equals(labels.get(LABEL_TYPE),
PodContainerStatus.ContainerType.devmode.name())
+ || Objects.equals(labels.get(LABEL_TYPE),
PodContainerStatus.ContainerType.build.name())
+ || Objects.equals(labels.get(LABEL_TYPE),
PodContainerStatus.ContainerType.devservice.name())) {
+ LOGGER.info("Pulling DevMode image from DockerHub: " + image);
+ pullImageFromDockerHub(image, Objects.equals(pullImage,
PULL_IMAGE.always));
+ }
+ if (Objects.equals(labels.get(LABEL_TYPE),
PodContainerStatus.ContainerType.project.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);
List<Mount> mounts = new ArrayList<>();
if (volumes != null && !volumes.isEmpty()) {
- volumes.forEach((hostPath, containerPath) -> {
- mounts.add(new
Mount().withType(MountType.BIND).withSource(hostPath).withTarget(containerPath));
+ volumes.forEach(volume -> {
+ var mount = new
Mount().withType(MountType.valueOf(volume.getType())).withTarget(volume.getTarget());
+ if (volume.getSource() != null) {
+ mount = mount.withSource(volume.getSource());
+ }
+ mounts.add(mount);
});
}
if (command.length > 0) {
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 75e3db3a..1e295399 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
@@ -33,7 +33,7 @@ public class DockerComposeService {
private String mem_limit;
private String mem_reservation;
private List<String> ports;
- private List<String> volumes;
+ private List<DockerComposeVolume> volumes;
private List<String> expose;
private List<String> depends_on;
private List<String> networks;
@@ -86,17 +86,6 @@ public class DockerComposeService {
return p;
}
- public Map<String, String> getVolumesMap() {
- Map<String, String> p = new HashMap<>();
- if (volumes != null && !volumes.isEmpty()) {
- volumes.forEach(s -> {
- String[] values = s.split(":");
- p.put(values[0], values[1]);
- });
- }
- return p;
- }
-
public List<String> getExpose() {
return expose;
}
@@ -181,11 +170,11 @@ public class DockerComposeService {
this.mem_reservation = mem_reservation;
}
- public List<String> getVolumes() {
+ public List<DockerComposeVolume> getVolumes() {
return volumes;
}
- public void setVolumes(List<String> volumes) {
+ public void setVolumes(List<DockerComposeVolume> volumes) {
this.volumes = volumes;
}
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/model/DockerComposeVolume.java
b/karavan-app/src/main/java/org/apache/camel/karavan/model/DockerComposeVolume.java
new file mode 100644
index 00000000..4f9920e3
--- /dev/null
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/model/DockerComposeVolume.java
@@ -0,0 +1,58 @@
+/*
+ * 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.model;
+
+public class DockerComposeVolume {
+
+ private String type;
+ private String source;
+ private String target;
+
+ public DockerComposeVolume() {
+ }
+
+ public DockerComposeVolume(String type, String source, String target) {
+ this.type = type;
+ this.source = source;
+ this.target = target;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getSource() {
+ return source;
+ }
+
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+}
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/service/ConfigService.java
b/karavan-app/src/main/java/org/apache/camel/karavan/service/ConfigService.java
index a4cb1e4d..87212c68 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/service/ConfigService.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/service/ConfigService.java
@@ -137,18 +137,19 @@ public class ConfigService {
var parts = filename.split("\\.");
var prefix = parts[0];
if (environment.equals(DEV_ENVIRONMENT) &&
!getEnvs().contains(prefix)) { // no prefix AND dev env
- storeFile(f);
- } else if (Objects.equals(prefix, environment)){ // with prefix == env
- storeFile(f);
+ storeFile(f.getName(), f.getCode());
+ } else if (Objects.equals(prefix, environment)) { // with prefix == env
+ filename = f.getName().substring(environment.length() + 1);
+ storeFile(filename, f.getCode());
}
}
- private void storeFile(ProjectFile f) throws Exception {
+ private void storeFile(String filename , String code) throws Exception {
if (inKubernetes()) {
- createConfigMapFromFile(f.getName(), f.getCode());
+ createConfigMapFromFile(filename, code);
} else {
if (sharedFolder.isPresent()) {
- Files.writeString(Paths.get(sharedFolder.get(), f.getName()),
f.getCode());
+ Files.writeString(Paths.get(sharedFolder.get(), filename),
code);
} else {
throw new Exception("Shared folder not configured");
}
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
b/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
index 2890eabd..e2954b68 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
@@ -69,17 +69,21 @@ public class ProjectService {
EventBus eventBus;
public Project commitAndPushProject(String projectId, String message)
throws Exception {
- LOGGER.info("Commit project: " + projectId);
- Project p = karavanCache.getProject(projectId);
- List<ProjectFile> files = karavanCache.getProjectFiles(projectId);
- RevCommit commit = gitService.commitAndPushProject(p, files, message);
- karavanCache.syncFilesCommited(projectId);
- String commitId = commit.getId().getName();
- Long lastUpdate = commit.getCommitTime() * 1000L;
- p.setLastCommit(commitId);
- p.setLastCommitTimestamp(lastUpdate);
- karavanCache.saveProject(p);
- return p;
+ if (Objects.equals(environment, DEV_ENVIRONMENT)) {
+ LOGGER.info("Commit project: " + projectId);
+ Project p = karavanCache.getProject(projectId);
+ List<ProjectFile> files = karavanCache.getProjectFiles(projectId);
+ RevCommit commit = gitService.commitAndPushProject(p, files,
message);
+ karavanCache.syncFilesCommited(projectId);
+ String commitId = commit.getId().getName();
+ Long lastUpdate = commit.getCommitTime() * 1000L;
+ p.setLastCommit(commitId);
+ p.setLastCommitTimestamp(lastUpdate);
+ karavanCache.saveProject(p);
+ return p;
+ } else {
+ throw new RuntimeException("Unsupported environment: " +
environment);
+ }
}
public String runProjectWithJBangOptions(Project project, String
jBangOptions) throws Exception {