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 b8862913 Sync build in Docker and Kubernetes #885
b8862913 is described below

commit b886291355c5efacb3cae8b0bb95b356c5bf6706
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Mon Sep 11 20:14:00 2023 -0400

    Sync build in Docker and Kubernetes #885
---
 .../apache/camel/karavan/api/ImagesResource.java   |   5 +-
 .../apache/camel/karavan/api/LogWatchResource.java |   6 +-
 .../org/apache/camel/karavan/code/CodeService.java |  10 +-
 .../camel/karavan/docker/DockerForKaravan.java     |   3 +-
 .../apache/camel/karavan/docker/DockerService.java |  36 +-
 .../org/apache/camel/karavan/git/GitService.java   |  29 +-
 .../karavan/kubernetes/KubernetesService.java      |  57 +-
 .../camel/karavan/kubernetes/PodEventHandler.java  |  10 +-
 .../camel/karavan/registry/RegistryConfig.java     |  34 +
 .../{service => registry}/RegistryService.java     |  40 +-
 .../camel/karavan/service/ConfigService.java       |   3 -
 .../karavan/service/ContainerStatusService.java    |  10 +-
 .../camel/karavan/service/ProjectService.java      |  12 +-
 .../org/apache/camel/karavan/shared/Constants.java |   7 +
 .../src/main/resources/application.properties      |   2 +-
 .../snippets/camel-main-builder-script-docker.sh   |   2 +-
 .../camel-main-builder-script-kubernetes.sh        |  21 +-
 .../main/webui/src/project/build/BuildPanel.tsx    |   3 +-
 karavan-web/karavan-cli/xxx.yaml                   | 695 +++++++++++++++++++++
 19 files changed, 897 insertions(+), 88 deletions(-)

diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ImagesResource.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ImagesResource.java
index 9f5e64b0..2c2fdf0e 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ImagesResource.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ImagesResource.java
@@ -22,14 +22,11 @@ import jakarta.ws.rs.*;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 import org.apache.camel.karavan.docker.DockerService;
-import org.apache.camel.karavan.infinispan.model.Project;
 import org.apache.camel.karavan.service.ConfigService;
 import org.apache.camel.karavan.service.ProjectService;
-import org.apache.camel.karavan.service.RegistryService;
+import org.apache.camel.karavan.registry.RegistryService;
 import org.jose4j.base64url.Base64;
 
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
 import java.util.Comparator;
 import java.util.List;
 
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
index bc0a68c7..e640b583 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/LogWatchResource.java
@@ -16,9 +16,11 @@
  */
 package org.apache.camel.karavan.api;
 
+import io.fabric8.kubernetes.client.KubernetesClient;
 import io.fabric8.kubernetes.client.dsl.LogWatch;
 import io.smallrye.context.api.ManagedExecutorConfig;
 import io.smallrye.context.api.NamedInstance;
+import io.smallrye.mutiny.tuples.Tuple2;
 import org.apache.camel.karavan.docker.DockerService;
 import org.apache.camel.karavan.docker.LogCallback;
 import org.apache.camel.karavan.kubernetes.KubernetesService;
@@ -96,7 +98,8 @@ public class LogWatchResource {
 
     private void getKubernetesLogs(String name, SseEventSink eventSink, Sse 
sse) {
         try (SseEventSink sink = eventSink) {
-            LogWatch logWatch = kubernetesService.getContainerLogWatch(name);
+            Tuple2<LogWatch, KubernetesClient> request = 
kubernetesService.getContainerLogWatch(name);
+            LogWatch logWatch = request.getItem1();
             BufferedReader reader = new BufferedReader(new 
InputStreamReader(logWatch.getOutput()));
             try {
                 for (String line; (line = reader.readLine()) != null && 
!sink.isClosed(); ) {
@@ -106,6 +109,7 @@ public class LogWatchResource {
                 LOGGER.error(e.getMessage());
             }
             logWatch.close();
+            request.getItem2().close();
             sink.close();
             LOGGER.info("LogWatch for " + name + " closed");
         }
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/code/CodeService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/code/CodeService.java
index b0ea0b9a..85a8a140 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/code/CodeService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/code/CodeService.java
@@ -61,8 +61,6 @@ public class CodeService {
     private static final String SNIPPETS_PATH = "/snippets/";
     private static final int INTERNAL_PORT = 8080;
 
-    protected static final String ENVIRONMENT = "environment";
-
     @Inject
     KubernetesService kubernetesService;
 
@@ -123,6 +121,14 @@ public class CodeService {
         }
     }
 
+    public String getBuilderScript(Project project) {
+        String target = ConfigService.inKubernetes()
+                ? (kubernetesService.isOpenshift() ? "openshift" : 
"kubernetes")
+                : "docker";
+        String templateName = project.getRuntime() + "-builder-script-" + 
target + ".sh";
+        return getTemplateText(templateName);
+    }
+
     public String getTemplateText(String fileName) {
         try {
             List<ProjectFile> files = 
infinispanService.getProjectFiles(Project.Type.templates.name());
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java
index b8cb910f..d05fd4ab 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForKaravan.java
@@ -20,10 +20,9 @@ import com.github.dockerjava.api.model.Container;
 import com.github.dockerjava.api.model.HealthCheck;
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
-import org.apache.camel.karavan.code.model.DockerComposeService;
 import org.apache.camel.karavan.infinispan.model.ContainerStatus;
 import org.apache.camel.karavan.infinispan.model.Project;
-import org.apache.camel.karavan.service.RegistryService;
+import org.apache.camel.karavan.registry.RegistryService;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.jboss.logging.Logger;
 
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 a3e35ee0..49398add 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
@@ -350,13 +350,21 @@ public class DockerService extends DockerServiceUtils {
         }
     }
 
-    private DockerClientConfig getDockerClientConfig() {
-        return DefaultDockerClientConfig.createDefaultConfigBuilder().build();
+    private DockerClientConfig getDockerClientConfig(String registryUrl, 
String registryUsername, String registryPassword) {
+        DefaultDockerClientConfig.Builder builder =  
DefaultDockerClientConfig.createDefaultConfigBuilder();
+        if (registryUrl != null) {
+            builder.withRegistryUrl(registryUrl);
+        }
+        if (registryUsername != null) {
+            builder.withRegistryUsername(registryUsername);
+        }
+        if (registryPassword != null) {
+            builder.withRegistryPassword(registryPassword);
+        }
+        return builder.build();
     }
 
-    private DockerHttpClient getDockerHttpClient() {
-        DockerClientConfig config = getDockerClientConfig();
-
+    private DockerHttpClient getDockerHttpClient(DockerClientConfig config) {
         return new ZerodepDockerHttpClient.Builder()
                 .dockerHost(config.getDockerHost())
                 .sslConfig(config.getSSLConfig())
@@ -366,11 +374,19 @@ public class DockerService extends DockerServiceUtils {
 
     public DockerClient getDockerClient() {
         if (dockerClient == null) {
-            dockerClient = 
DockerClientImpl.getInstance(getDockerClientConfig(), getDockerHttpClient());
+            DockerClientConfig config = getDockerClientConfig(null, null, 
null);
+            DockerHttpClient httpClient = getDockerHttpClient(config);
+            dockerClient = DockerClientImpl.getInstance(config, httpClient);
         }
         return dockerClient;
     }
 
+    public DockerClient getDockerClient(String registryUrl, String 
registryUsername, String registryPassword) {
+        DockerClientConfig config = getDockerClientConfig(registryUrl, 
registryUsername, registryPassword);
+        DockerHttpClient httpClient = getDockerHttpClient(config);
+        return DockerClientImpl.getInstance(config, httpClient);
+    }
+
     public int getMaxPortMapped(int port) {
         return 
getDockerClient().listContainersCmd().withShowAll(true).exec().stream()
                 .map(c -> List.of(c.ports))
@@ -386,6 +402,14 @@ public class DockerService extends DockerServiceUtils {
                 .map(image -> image.getRepoTags()[0]).toList();
     }
 
+    public List<String> getImages(String registryUrl, String registryUsername, 
String registryPassword, String pattern) throws IOException {
+        List<String> result = new ArrayList<>();
+        DockerClient client =  getDockerClient(registryUrl, registryUsername, 
registryPassword);
+        
getDockerClient().searchImagesCmd(pattern).exec().stream().map(searchItem -> 
searchItem.getName());
+        client.close();
+        return result;
+    }
+
     public void deleteImage(String imageName) {
         Optional<Image> image = 
getDockerClient().listImagesCmd().withShowAll(true).exec().stream()
                 .filter(i -> Arrays.stream(i.getRepoTags()).anyMatch(s -> 
Objects.equals(s, imageName))).findFirst();
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java
index 71a2f363..c81c40e7 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java
@@ -24,6 +24,7 @@ import org.apache.camel.karavan.git.model.GitRepo;
 import org.apache.camel.karavan.git.model.GitRepoFile;
 import org.apache.camel.karavan.infinispan.model.*;
 import org.apache.camel.karavan.kubernetes.KubernetesService;
+import org.apache.camel.karavan.registry.RegistryConfig;
 import org.apache.camel.karavan.service.ConfigService;
 import org.eclipse.jgit.api.CheckoutCommand;
 import org.eclipse.jgit.api.CloneCommand;
@@ -89,12 +90,11 @@ public class GitService {
         String branch = ConfigProvider.getConfig().getValue(propertiesPrefix + 
"git-branch", String.class);
         if (ConfigService.inKubernetes()) {
             Secret secret = kubernetesService.getKaravanSecret();
-            String uri = new 
String(Base64.getDecoder().decode(secret.getData().get("git-repository").getBytes(StandardCharsets.UTF_8)));
-            String username = new 
String(Base64.getDecoder().decode(secret.getData().get("git-username").getBytes(StandardCharsets.UTF_8)));
-            String password = new 
String(Base64.getDecoder().decode(secret.getData().get("git-password").getBytes(StandardCharsets.UTF_8)));
-            if (secret.getData().containsKey("git-branch")) {
-                branch = new 
String(Base64.getDecoder().decode(secret.getData().get("git-branch").getBytes(StandardCharsets.UTF_8)));
-            }
+            String uri = kubernetesService.getKaravanSecret("git-repository");
+            String username = 
kubernetesService.getKaravanSecret("git-username");
+            String password = 
kubernetesService.getKaravanSecret("git-password");
+            String branchInSecret = 
kubernetesService.getKaravanSecret("git-branch");
+            branch = branchInSecret != null ? branchInSecret : branch;
             return new GitConfig(uri, username, password, branch);
         } else if (ConfigService.inDocker()) {
             String uri = ConfigProvider.getConfig().getValue(propertiesPrefix 
+ "git-repository", String.class);
@@ -112,17 +112,26 @@ public class GitService {
         }
     }
 
+    public List<String> getEnvForBuild() {
+        GitConfig gitConfig = getGitConfigForBuilder();
+        return List.of(
+                "GIT_REPOSITORY=" + gitConfig.getUri(),
+                "GIT_USERNAME=" + gitConfig.getUsername(),
+                "GIT_PASSWORD=" + gitConfig.getPassword(),
+                "GIT_BRANCH=" + gitConfig.getBranch());
+    }
+
     public GitConfig getGitConfigForBuilder() {
         String propertiesPrefix = "karavan.";
         String branch = ConfigProvider.getConfig().getValue(propertiesPrefix + 
"git-branch", String.class);
         if (ConfigService.inKubernetes()) {
             LOGGER.info("inKubernetes " + kubernetesService.getNamespace());
             Secret secret = kubernetesService.getKaravanSecret();
-            String uri = new 
String(Base64.getDecoder().decode(secret.getData().get("git-repository").getBytes(StandardCharsets.UTF_8)));
-            String username = new 
String(Base64.getDecoder().decode(secret.getData().get("git-username").getBytes(StandardCharsets.UTF_8)));
-            String password = new 
String(Base64.getDecoder().decode(secret.getData().get("git-password").getBytes(StandardCharsets.UTF_8)));
+            String uri = kubernetesService.getKaravanSecret("git-repository");
+            String username = 
kubernetesService.getKaravanSecret("git-username");
+            String password = 
kubernetesService.getKaravanSecret("git-password");
             if (secret.getData().containsKey("git-branch")) {
-                branch = new 
String(Base64.getDecoder().decode(secret.getData().get("git-branch").getBytes(StandardCharsets.UTF_8)));
+                branch = kubernetesService.getKaravanSecret("git-branch");
             }
             return new GitConfig(uri, username, password, branch);
         } else {
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 063b8899..b02bc045 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
@@ -24,6 +24,7 @@ import io.fabric8.kubernetes.client.dsl.LogWatch;
 import io.fabric8.kubernetes.client.informers.SharedIndexInformer;
 import io.fabric8.openshift.api.model.ImageStream;
 import io.fabric8.openshift.client.OpenShiftClient;
+import io.smallrye.mutiny.tuples.Tuple2;
 import io.vertx.mutiny.core.eventbus.EventBus;
 import org.apache.camel.karavan.infinispan.InfinispanService;
 import org.apache.camel.karavan.infinispan.model.ContainerStatus;
@@ -42,6 +43,7 @@ import jakarta.enterprise.inject.Default;
 import jakarta.enterprise.inject.Produces;
 import jakarta.inject.Inject;
 
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -55,11 +57,6 @@ public class KubernetesService implements HealthCheck {
 
     private static final Logger LOGGER = 
Logger.getLogger(KubernetesService.class.getName());
     protected static final int INFORMERS = 3;
-    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";
-    protected static final String PVC_MAVEN_SETTINGS = "maven-settings";
 
     @Inject
     EventBus eventBus;
@@ -91,24 +88,22 @@ public class KubernetesService implements HealthCheck {
             LOGGER.info("Starting Kubernetes Informers");
 
             Map<String, String> labels = getRuntimeLabels();
+            KubernetesClient client = kubernetesClient();
 
-            try (KubernetesClient client = kubernetesClient()) {
+            SharedIndexInformer<Deployment> deploymentInformer = 
client.apps().deployments().inNamespace(getNamespace())
+                    
.withLabels(labels).inform();deploymentInformer.addEventHandlerWithResyncPeriod(new
 DeploymentEventHandler(infinispanService, this), 30 * 1000L);
+            informers.add(deploymentInformer);
 
-                SharedIndexInformer<Deployment> deploymentInformer = 
client.apps().deployments().inNamespace(getNamespace())
-                        .withLabels(labels).inform();
-                deploymentInformer.addEventHandlerWithResyncPeriod(new 
DeploymentEventHandler(infinispanService, this), 30 * 1000L);
-                informers.add(deploymentInformer);
+            SharedIndexInformer<Service> serviceInformer = 
client.services().inNamespace(getNamespace())
+                    .withLabels(labels).inform();
+            serviceInformer.addEventHandlerWithResyncPeriod(new 
ServiceEventHandler(infinispanService, this), 30 * 1000L);
+            informers.add(serviceInformer);
 
-                SharedIndexInformer<Service> serviceInformer = 
client.services().inNamespace(getNamespace())
-                        .withLabels(labels).inform();
-                serviceInformer.addEventHandlerWithResyncPeriod(new 
ServiceEventHandler(infinispanService, this), 30 * 1000L);
-                informers.add(serviceInformer);
+            SharedIndexInformer<Pod> podRunInformer = 
client.pods().inNamespace(getNamespace())
+                    .withLabels(labels).inform();
+            podRunInformer.addEventHandlerWithResyncPeriod(new 
PodEventHandler(infinispanService, this, eventBus), 30 * 1000L);
+            informers.add(podRunInformer);
 
-                SharedIndexInformer<Pod> podRunInformer = 
client.pods().inNamespace(getNamespace())
-                        .withLabels(labels).inform();
-                podRunInformer.addEventHandlerWithResyncPeriod(new 
PodEventHandler(infinispanService, this, eventBus), 30 * 1000L);
-                informers.add(podRunInformer);
-            }
             LOGGER.info("Started Kubernetes Informers");
         } catch (Exception e) {
             LOGGER.error("Error starting informers: " + e.getMessage());
@@ -228,6 +223,7 @@ public class KubernetesService implements HealthCheck {
                 .withTerminationGracePeriodSeconds(0L)
                 .withContainers(container)
                 .withRestartPolicy("Never")
+                .withServiceAccount(KARAVAN_PREFIX)
                 .withVolumes(
 //                        new VolumeBuilder().withName(name)
 //                                .withNewPersistentVolumeClaim(name, 
false).build(),
@@ -254,10 +250,10 @@ public class KubernetesService implements HealthCheck {
         }
     }
 
-    public LogWatch getContainerLogWatch(String podName) {
-        try (KubernetesClient client = kubernetesClient()) {
-            return 
client.pods().inNamespace(getNamespace()).withName(podName).tailingLines(100).watchLog();
-        }
+    public Tuple2<LogWatch, KubernetesClient> getContainerLogWatch(String 
podName) {
+        KubernetesClient client = kubernetesClient();
+        LogWatch logWatch = 
client.pods().inNamespace(getNamespace()).withName(podName).tailingLines(100).watchLog();
+        return Tuple2.of(logWatch, client);
     }
 
     private List<Condition> getCancelConditions(String reason) {
@@ -531,6 +527,21 @@ public class KubernetesService implements HealthCheck {
         }
     }
 
+    public String getKaravanSecret(String key) {
+        try (KubernetesClient client = kubernetesClient()) {
+            Secret secret =  
client.secrets().inNamespace(getNamespace()).withName("karavan").get();
+            Map<String, String> data = secret.getData();
+            return decodeSecret(data.get(key));
+        }
+    }
+
+    private String decodeSecret(String data) {
+        if (data != null){
+            return new 
String(Base64.getDecoder().decode(data.getBytes(StandardCharsets.UTF_8)));
+        }
+        return null;
+    }
+
     public boolean isOpenshift() {
         try (KubernetesClient client = kubernetesClient()) {
             return ConfigService.inKubernetes() ? 
client.isAdaptable(OpenShiftClient.class) : false;
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 1eaf01b8..c94d14c1 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
@@ -16,7 +16,6 @@ import java.util.List;
 import java.util.Objects;
 
 import static 
org.apache.camel.karavan.code.CodeService.DEFAULT_CONTAINER_RESOURCES;
-import static 
org.apache.camel.karavan.service.CamelService.RELOAD_PROJECT_CODE;
 import static org.apache.camel.karavan.shared.Constants.LABEL_PROJECT_ID;
 import static 
org.apache.camel.karavan.service.ContainerStatusService.CONTAINER_STATUS;
 import static org.apache.camel.karavan.shared.Constants.LABEL_TYPE;
@@ -82,7 +81,10 @@ public class PodEventHandler implements 
ResourceEventHandler<Pod> {
         String type = deployment != null ? deployment : 
pod.getMetadata().getLabels().get(LABEL_TYPE);
         ContainerStatus.ContainerType containerType = type != null ? 
ContainerStatus.ContainerType.valueOf(type) : 
ContainerStatus.ContainerType.unknown;
         try {
-            boolean ready = 
pod.getStatus().getConditions().stream().anyMatch(c -> 
c.getType().equals("Ready"));
+            boolean ready = 
pod.getStatus().getConditions().stream().anyMatch(c -> 
c.getType().equals("Ready") && c.getStatus().equals("True"));
+            boolean running = Objects.equals(pod.getStatus().getPhase(), 
"Running");
+            boolean failed = Objects.equals(pod.getStatus().getPhase(), 
"Failed");
+            boolean succeeded = Objects.equals(pod.getStatus().getPhase(), 
"Succeeded");
             String creationTimestamp = 
pod.getMetadata().getCreationTimestamp();
 
             ResourceRequirements defaultRR = 
kubernetesService.getResourceRequirements(DEFAULT_CONTAINER_RESOURCES);
@@ -105,6 +107,10 @@ public class PodEventHandler implements 
ResourceEventHandler<Pod> {
             status.setContainerId(pod.getMetadata().getName());
             if (ready) {
                 status.setState(ContainerStatus.State.running.name());
+            } else if (failed) {
+                status.setState(ContainerStatus.State.dead.name());
+            } else if (succeeded) {
+                status.setState(ContainerStatus.State.exited.name());
             } else {
                 status.setState(ContainerStatus.State.created.name());
             }
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/registry/RegistryConfig.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/registry/RegistryConfig.java
new file mode 100644
index 00000000..55ce936e
--- /dev/null
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/registry/RegistryConfig.java
@@ -0,0 +1,34 @@
+package org.apache.camel.karavan.registry;
+
+public class RegistryConfig {
+    private String registry;
+    private String group;
+    private String username;
+    private String password;
+
+    public RegistryConfig() {
+    }
+
+    public RegistryConfig(String registry, String group, String username, 
String password) {
+        this.registry = registry;
+        this.group = group;
+        this.username = username;
+        this.password = password;
+    }
+
+    public String getRegistry() {
+        return registry;
+    }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+}
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/RegistryService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/registry/RegistryService.java
similarity index 54%
rename from 
karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/RegistryService.java
rename to 
karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/registry/RegistryService.java
index 11d6f9f8..d979561d 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/RegistryService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/registry/RegistryService.java
@@ -14,9 +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.registry;
 
+import io.fabric8.kubernetes.api.model.Secret;
 import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import org.apache.camel.karavan.kubernetes.KubernetesService;
+import org.apache.camel.karavan.service.ConfigService;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.jboss.logging.Logger;
 
@@ -39,31 +43,45 @@ public class RegistryService {
     @ConfigProperty(name = "karavan.image-registry-password")
     Optional<String> password;
 
+    @Inject
+    KubernetesService kubernetesService;
 
-    public String getRegistry() {
+    public RegistryConfig getRegistryConfig() {
         String registryUrl = registry;
-        if (!ConfigService.inDocker() && installRegistry) {
+        String imageGroup = group;
+        String registryUsername = username.orElse(null);
+        String registryPassword = password.orElse(null);
+        if (ConfigService.inKubernetes()) {
+            registryUrl = kubernetesService.getKaravanSecret("image-registry");
+            String i = kubernetesService.getKaravanSecret("image-group");
+            imageGroup = i != null ? i : group;
+            registryUsername = 
kubernetesService.getKaravanSecret("image-registry-username");
+            registryPassword = 
kubernetesService.getKaravanSecret("image-registry-password");
+        } else if (!ConfigService.inDocker() && installRegistry) {
             registryUrl = "localhost:5555";
         }
-        return registryUrl;
+        return new RegistryConfig(registryUrl, imageGroup, registryUsername, 
registryPassword);
     }
 
     public String getRegistryWithGroup() {
-        return getRegistry() + "/" + group;
+        return getRegistryConfig().getRegistry() + "/" + group;
     }
 
     public String getRegistryWithGroupForSync() {
+        if (ConfigService.inKubernetes()) {
+            return getRegistryConfig().getRegistry() + "/" + group;
+        }
         return registry + "/" + group;
     }
 
     public List<String> getEnvForBuild() {
-        List<String> env = List.of(
-                "IMAGE_REGISTRY=" + registry,
-                "IMAGE_REGISTRY_USERNAME=" + username,
-                "IMAGE_REGISTRY_PASSWORD=" + password,
-                "IMAGE_GROUP=" + group
+        RegistryConfig rc = getRegistryConfig();
+        return List.of(
+                "IMAGE_REGISTRY=" + rc.getRegistry(),
+                "IMAGE_REGISTRY_USERNAME=" + rc.getUsername(),
+                "IMAGE_REGISTRY_PASSWORD=" + rc.getPassword(),
+                "IMAGE_GROUP=" + rc.getGroup()
         );
-        return env;
     }
 
 }
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ConfigService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ConfigService.java
index 349a41e2..cbb4ed56 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ConfigService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ConfigService.java
@@ -83,7 +83,4 @@ public class ConfigService {
         return inDocker;
     }
 
-    public static boolean isDevOrTest() {
-        return ProfileManager.getLaunchMode().isDevOrTest();
-    }
 }
\ No newline at end of file
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ContainerStatusService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ContainerStatusService.java
index f6dbec9d..281213de 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ContainerStatusService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ContainerStatusService.java
@@ -99,10 +99,12 @@ public class ContainerStatusService {
     }
 
     private void saveContainerStatus(ContainerStatus newStatus, 
ContainerStatus oldStatus) {
-        if ("exited".equalsIgnoreCase(newStatus.getState()) && 
Objects.isNull(oldStatus.getFinished())) {
-            newStatus.setFinished(Instant.now().toString());
-        } else if ("exited".equalsIgnoreCase(newStatus.getState()) && 
Objects.nonNull(oldStatus.getFinished())) {
-            return;
+        if (Objects.equals("exited", newStatus.getState()) || 
Objects.equals("dead", newStatus.getState())) {
+            if (Objects.isNull(oldStatus.getFinished())) {
+                newStatus.setFinished(Instant.now().toString());
+            } else if (Objects.nonNull(oldStatus.getFinished())) {
+                return;
+            }
         }
         if (newStatus.getCpuInfo() == null || 
newStatus.getCpuInfo().isEmpty()) {
             newStatus.setCpuInfo(oldStatus.getCpuInfo());
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
index 1a6a698a..b73a4fa9 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java
@@ -28,6 +28,7 @@ import org.apache.camel.karavan.git.model.GitRepo;
 import org.apache.camel.karavan.infinispan.InfinispanService;
 import org.apache.camel.karavan.infinispan.model.*;
 import org.apache.camel.karavan.kubernetes.KubernetesService;
+import org.apache.camel.karavan.registry.RegistryService;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.eclipse.microprofile.health.HealthCheck;
@@ -124,13 +125,10 @@ public class ProjectService implements HealthCheck {
     }
 
     public void buildProject(Project project, String tag) throws Exception {
-        String templateName = project.getRuntime() + 
"-builder-script-docker.sh";
-        String script = codeService.getTemplateText(templateName);
-
         tag = tag != null && !tag.isEmpty() && !tag.isBlank()
                 ? tag
                 : Instant.now().toString().substring(0, 19).replace(":", "-");
-
+        String script = codeService.getBuilderScript(project);
         List<String> env = getEnvForBuild(project, tag);
         if (ConfigService.inKubernetes()) {
             kubernetesService.runBuildProject(project, script, env, tag);
@@ -141,14 +139,10 @@ public class ProjectService implements HealthCheck {
     }
 
     private List<String> getEnvForBuild(Project project, String tag) {
-        GitConfig gitConfig = gitService.getGitConfigForBuilder();
         List<String> env = new ArrayList<>();
         env.addAll(registryService.getEnvForBuild());
+        env.addAll(gitService.getEnvForBuild());
         env.addAll(List.of(
-                "GIT_REPOSITORY=" + gitConfig.getUri(),
-                "GIT_USERNAME=" + gitConfig.getUsername(),
-                "GIT_PASSWORD=" + gitConfig.getPassword(),
-                "GIT_BRANCH=" + gitConfig.getBranch(),
                 "PROJECT_ID=" + project.getProjectId(),
                 "JBANG_REPO=~/.m2",
                 "TAG=" + tag
diff --git 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java
 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java
index 68d1361e..a63843a6 100644
--- 
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java
+++ 
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/Constants.java
@@ -27,4 +27,11 @@ public class Constants {
     public static final String LABEL_TAG = "org.apache.camel.karavan/tag";
 
     public static final String BUILDER_SUFFIX = "-builder";
+
+    public static final String CAMEL_PREFIX = "camel";
+    public static final String KARAVAN_PREFIX = "karavan";
+    public static final String JBANG_CACHE_SUFFIX = "jbang-cache";
+    public static final String M2_CACHE_SUFFIX = "m2-cache";
+    public static final String PVC_MAVEN_SETTINGS = "maven-settings";
+
 }
diff --git a/karavan-web/karavan-app/src/main/resources/application.properties 
b/karavan-web/karavan-app/src/main/resources/application.properties
index 0b3dc433..7ec18b80 100644
--- a/karavan-web/karavan-app/src/main/resources/application.properties
+++ b/karavan-web/karavan-app/src/main/resources/application.properties
@@ -123,7 +123,7 @@ quarkus.kubernetes-client.connection-timeout=2000
 quarkus.kubernetes-client.request-timeout=10000
 quarkus.kubernetes-client.devservices.enabled=false
 
-%dev.quarkus.swagger-ui.always-include=true
+quarkus.swagger-ui.always-include=true
 
 quarkus.quinoa.frozen-lockfile=false
 quarkus.quinoa.package-manager-install=false
diff --git 
a/karavan-web/karavan-app/src/main/resources/snippets/camel-main-builder-script-docker.sh
 
b/karavan-web/karavan-app/src/main/resources/snippets/camel-main-builder-script-docker.sh
index 037632f8..7404231d 100644
--- 
a/karavan-web/karavan-app/src/main/resources/snippets/camel-main-builder-script-docker.sh
+++ 
b/karavan-web/karavan-app/src/main/resources/snippets/camel-main-builder-script-docker.sh
@@ -29,4 +29,4 @@ mvn package jib:build \
   -Djib.allowInsecureRegistries=true \
   -Djib.to.image=${IMAGE_REGISTRY}/${IMAGE_GROUP}/${PROJECT_ID}:${DATE} \
   -Djib.to.auth.username=${IMAGE_REGISTRY_USERNAME} \
-  -Djib.to.auth.password=${IMAGE_REGISTRY_PASSWORD}
\ No newline at end of file
+  -Djib.to.auth.password=${IMAGE_REGISTRY_PASSWORD}
diff --git 
a/karavan-web/karavan-app/src/main/resources/snippets/camel-main-builder-script-kubernetes.sh
 
b/karavan-web/karavan-app/src/main/resources/snippets/camel-main-builder-script-kubernetes.sh
index fb3a074f..667e66c2 100644
--- 
a/karavan-web/karavan-app/src/main/resources/snippets/camel-main-builder-script-kubernetes.sh
+++ 
b/karavan-web/karavan-app/src/main/resources/snippets/camel-main-builder-script-kubernetes.sh
@@ -2,29 +2,34 @@
 CHECKOUT_DIR="/scripts"
 KAMELETS_DIR="/scripts/kamelets"
 
-if  [[ $GIT_REPOSITORY == https* ]] ;
+if  [[ ${GIT_REPOSITORY} == https* ]] ;
 then
-    replacer=https://$GIT_USERNAME:$GIT_PASSWORD@
+    replacer=https://${GIT_USERNAME}:${GIT_PASSWORD}@
     prefix=https://
     url="${GIT_REPOSITORY/$prefix/$replacer}"
     git clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}
+elif [[ ${GIT_REPOSITORY} == http* ]] ;
+then
+  replacer=http://${GIT_USERNAME}:${GIT_PASSWORD}@
+      prefix=http://
+      url="${GIT_REPOSITORY/$prefix/$replacer}"
+      git clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}
 else
     git clone --depth 1 --branch ${GIT_BRANCH} ${GIT_REPOSITORY} 
${CHECKOUT_DIR}
 fi
 
-cd ${CHECKOUT_DIR}/$(inputs.params.project)
+cd ${CHECKOUT_DIR}/${PROJECT_ID}
 
-jbang -Dcamel.jbang.version=$CAMEL_VERSION camel@apache/camel export 
--local-kamelet-dir=${KAMELETS_DIR}
+jbang -Dcamel.jbang.version=${CAMEL_VERSION} camel@apache/camel export 
--local-kamelet-dir=${KAMELETS_DIR}
 
 export LAST_COMMIT=$(git rev-parse --short HEAD)
-export DATE=$(date '+%Y%m%d%H%M%S')
+export DATE=${TAG}
 export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
 export NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
 
 mvn package jib:build k8s:resource k8s:apply \
   -Djkube.namespace=${NAMESPACE} \
   -Djib.allowInsecureRegistries=true \
-  
-Djib.to.image=${IMAGE_REGISTRY}/${IMAGE_GROUP}/$(inputs.params.project):${DATE}
 \
+  -Djib.to.image=${IMAGE_REGISTRY}/${IMAGE_GROUP}/${PROJECT_ID}:${DATE} \
   -Djib.to.auth.username=${IMAGE_REGISTRY_USERNAME} \
-  -Djib.to.auth.password=${IMAGE_REGISTRY_PASSWORD}  \
-  --settings=$MAVEN_SETTINGS
\ No newline at end of file
+  -Djib.to.auth.password=${IMAGE_REGISTRY_PASSWORD}
\ No newline at end of file
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx 
b/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
index 8dd06889..409ad63c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
@@ -124,7 +124,8 @@ export function BuildPanel () {
         const showTime = buildTime && buildTime > 0;
         const isRunning = state === 'running';
         const isExited = state === 'exited';
-        const color = isExited ? "grey" : (isRunning ? "blue" : "grey");
+        const isFailed = state === 'failed';
+        const color = (isRunning ? "blue" : (isFailed ? "red" : "grey"));
         const icon = isExited ? <UpIcon className="not-spinner"/> : <DownIcon 
className="not-spinner"/>
         return (
             <Flex justifyContent={{default: "justifyContentSpaceBetween"}} 
alignItems={{default: "alignItemsCenter"}}>
diff --git a/karavan-web/karavan-cli/xxx.yaml b/karavan-web/karavan-cli/xxx.yaml
new file mode 100644
index 00000000..76f91f90
--- /dev/null
+++ b/karavan-web/karavan-cli/xxx.yaml
@@ -0,0 +1,695 @@
+---
+apiVersion: "v1"
+kind: "PersistentVolumeClaim"
+metadata:
+  labels:
+    app: "karavan-data"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-data"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-data"
+  namespace: "karavan"
+spec:
+  accessModes:
+  - "ReadWriteOnce"
+  resources:
+    requests:
+      storage: "10Gi"
+  volumeMode: "Filesystem"
+---
+apiVersion: "tekton.dev/v1beta1"
+kind: "Pipeline"
+metadata:
+  labels:
+    app: "karavan-pipeline-dev-camel-main"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-pipeline-dev-camel-main"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-pipeline-dev-camel-main"
+  namespace: "karavan"
+spec:
+  params:
+  - description: "ProjectId"
+    name: "PROJECT_ID"
+    type: "string"
+  tasks:
+  - name: "karavan-task-dev-camel-main"
+    params:
+    - name: "project"
+      value: "$(params.PROJECT_ID)"
+    taskRef:
+      kind: "Task"
+      name: "karavan-task-dev-camel-main"
+    workspaces:
+    - name: "maven-settings"
+      subPath: ""
+      workspace: "maven-settings"
+    - name: "karavan-m2-cache"
+      subPath: ""
+      workspace: "karavan-m2-cache"
+    - name: "karavan-jbang-cache"
+      subPath: ""
+      workspace: "karavan-jbang-cache"
+  workspaces:
+  - description: "Maven Settings"
+    name: "maven-settings"
+    optional: false
+  - description: "Maven Cache"
+    name: "karavan-m2-cache"
+    optional: false
+  - description: "JBang Cache"
+    name: "karavan-jbang-cache"
+    optional: false
+---
+apiVersion: "rbac.authorization.k8s.io/v1"
+kind: "Role"
+metadata:
+  name: "deployer"
+  namespace: "karavan"
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - "secrets"
+  - "configmaps"
+  - "services"
+  - "persistentvolumes"
+  - "persistentvolumeclaims"
+  verbs:
+  - "*"
+- apiGroups:
+  - "networking.k8s.io"
+  resources:
+  - "ingresses"
+  verbs:
+  - "*"
+- apiGroups:
+  - "route.openshift.io"
+  resources:
+  - "routes"
+  verbs:
+  - "*"
+- apiGroups:
+  - "apps"
+  resources:
+  - "deployments"
+  verbs:
+  - "*"
+---
+apiVersion: "v1"
+kind: "ServiceAccount"
+metadata:
+  labels:
+    app: "karavan"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan"
+  namespace: "karavan"
+---
+apiVersion: "v1"
+kind: "ServiceAccount"
+metadata:
+  labels:
+    app: "pipeline"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "pipeline"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "pipeline"
+  namespace: "karavan"
+---
+apiVersion: "tekton.dev/v1beta1"
+kind: "Task"
+metadata:
+  labels:
+    app: "karavan-task-dev-quarkus"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-task-dev-quarkus"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-task-dev-quarkus"
+  namespace: "karavan"
+spec:
+  params:
+  - description: "ProjectId"
+    name: "project"
+    type: "string"
+  steps:
+  - env:
+    - name: "GIT_REPOSITORY"
+      valueFrom:
+        secretKeyRef:
+          key: "git-repository"
+          name: "karavan"
+    - name: "GIT_USERNAME"
+      valueFrom:
+        secretKeyRef:
+          key: "git-username"
+          name: "karavan"
+    - name: "GIT_PASSWORD"
+      valueFrom:
+        secretKeyRef:
+          key: "git-password"
+          name: "karavan"
+    - name: "GIT_BRANCH"
+      valueFrom:
+        secretKeyRef:
+          key: "git-branch"
+          name: "karavan"
+    - name: "IMAGE_REGISTRY"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_GROUP"
+      valueFrom:
+        secretKeyRef:
+          key: "image-group"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_REGISTRY_USERNAME"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry-username"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_REGISTRY_PASSWORD"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry-password"
+          name: "karavan"
+          optional: true
+    image: "ghcr.io/apache/camel-karavan-devmode:4.0.0-RC2"
+    imagePullPolicy: "Always"
+    name: "karavan-build-deploy"
+  workspaces:
+  - description: "Maven Settings"
+    mountPath: "/karavan-config-map"
+    name: "maven-settings"
+    optional: false
+    readOnly: false
+  - description: "Maven Cache"
+    mountPath: "/root/.m2"
+    name: "karavan-m2-cache"
+    optional: false
+    readOnly: false
+  - description: "JBang Cache"
+    mountPath: "/jbang/.jbang/cache"
+    name: "karavan-jbang-cache"
+    optional: false
+    readOnly: false
+---
+apiVersion: "tekton.dev/v1beta1"
+kind: "Task"
+metadata:
+  labels:
+    app: "karavan-task-dev-spring-boot"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-task-dev-spring-boot"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-task-dev-spring-boot"
+  namespace: "karavan"
+spec:
+  params:
+  - description: "ProjectId"
+    name: "project"
+    type: "string"
+  steps:
+  - env:
+    - name: "GIT_REPOSITORY"
+      valueFrom:
+        secretKeyRef:
+          key: "git-repository"
+          name: "karavan"
+    - name: "GIT_USERNAME"
+      valueFrom:
+        secretKeyRef:
+          key: "git-username"
+          name: "karavan"
+    - name: "GIT_PASSWORD"
+      valueFrom:
+        secretKeyRef:
+          key: "git-password"
+          name: "karavan"
+    - name: "GIT_BRANCH"
+      valueFrom:
+        secretKeyRef:
+          key: "git-branch"
+          name: "karavan"
+    - name: "IMAGE_REGISTRY"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_GROUP"
+      valueFrom:
+        secretKeyRef:
+          key: "image-group"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_REGISTRY_USERNAME"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry-username"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_REGISTRY_PASSWORD"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry-password"
+          name: "karavan"
+          optional: true
+    image: "ghcr.io/apache/camel-karavan-devmode:4.0.0-RC2"
+    imagePullPolicy: "Always"
+    name: "karavan-build-deploy"
+    script: "#!/usr/bin/env 
bash\nCHECKOUT_DIR=\"/scripts\"\nKAMELETS_DIR=\"/scripts/kamelets\"\
+      \n\nif  [[ $GIT_REPOSITORY == https* ]] ;\nthen\n    
replacer=https://$GIT_USERNAME:$GIT_PASSWORD@\n\
+      \    prefix=https://\n    url=\"${GIT_REPOSITORY/$prefix/$replacer}\"\n  
  git\
+      \ clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}\nelse\n    
git\
+      \ clone --depth 1 --branch ${GIT_BRANCH} ${GIT_REPOSITORY} 
${CHECKOUT_DIR}\n\
+      fi\n\ncd ${CHECKOUT_DIR}/$(inputs.params.project)\n\njbang 
-Dcamel.jbang.version=$CAMEL_VERSION\
+      \ camel@apache/camel export 
--local-kamelet-dir=${KAMELETS_DIR}\n\nexport LAST_COMMIT=$(git\
+      \ rev-parse --short HEAD)\nexport DATE=$(date '+%Y%m%d%H%M%S')\nexport 
TOKEN=$(cat\
+      \ /var/run/secrets/kubernetes.io/serviceaccount/token)\nexport 
NAMESPACE=$(cat\
+      \ /var/run/secrets/kubernetes.io/serviceaccount/namespace)\n\nmvn 
package k8s:build\
+      \ k8s:push k8s:resource k8s:apply \\\n  -Pkubernetes \\\n  
-Djkube.namespace=${NAMESPACE}\
+      \ \\\n  -Djkube.docker.push.registry=${IMAGE_REGISTRY} \\\n  
-Djkube.docker.username=${IMAGE_REGISTRY_USERNAME}\
+      \ \\\n  -Djkube.docker.password=${IMAGE_REGISTRY_PASSWORD} \\\n  
-Djkube.generator.name=${IMAGE_REGISTRY}/${IMAGE_GROUP}/$(inputs.params.project):${DATE}\
+      \ \\\n  --settings=$MAVEN_SETTINGS"
+  workspaces:
+  - description: "Maven Settings"
+    mountPath: "/karavan-config-map"
+    name: "maven-settings"
+    optional: false
+    readOnly: false
+  - description: "Maven Cache"
+    mountPath: "/root/.m2"
+    name: "karavan-m2-cache"
+    optional: false
+    readOnly: false
+  - description: "JBang Cache"
+    mountPath: "/jbang/.jbang/cache"
+    name: "karavan-jbang-cache"
+    optional: false
+    readOnly: false
+---
+apiVersion: "rbac.authorization.k8s.io/v1"
+kind: "Role"
+metadata:
+  name: "karavan"
+  namespace: "karavan"
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - "secrets"
+  - "configmaps"
+  verbs:
+  - "*"
+- apiGroups:
+  - ""
+  resources:
+  - "persistentvolumes"
+  - "persistentvolumeclaims"
+  verbs:
+  - "*"
+- apiGroups:
+  - "tekton.dev"
+  resources:
+  - "pipelineruns"
+  verbs:
+  - "*"
+- apiGroups:
+  - ""
+  resources:
+  - "pods"
+  - "services"
+  - "replicationcontrollers"
+  verbs:
+  - "*"
+- apiGroups:
+  - "route.openshift.io"
+  resources:
+  - "routes"
+  verbs:
+  - "*"
+- apiGroups:
+  - "apps"
+  resources:
+  - "deployments"
+  verbs:
+  - "*"
+---
+apiVersion: "rbac.authorization.k8s.io/v1"
+kind: "RoleBinding"
+metadata:
+  name: "karavan-view"
+  namespace: "karavan"
+roleRef:
+  kind: "ClusterRole"
+  apiGroup: "rbac.authorization.k8s.io"
+  name: "view"
+subjects:
+- kind: "ServiceAccount"
+  apiGroup: ""
+  name: "karavan"
+  namespace: "karavan"
+---
+apiVersion: "v1"
+kind: "PersistentVolumeClaim"
+metadata:
+  labels:
+    app: "karavan-jbang-cache"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-jbang-cache"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-jbang-cache"
+  namespace: "karavan"
+spec:
+  accessModes:
+  - "ReadWriteOnce"
+  resources:
+    requests:
+      storage: "2Gi"
+  volumeMode: "Filesystem"
+---
+apiVersion: "rbac.authorization.k8s.io/v1"
+kind: "RoleBinding"
+metadata:
+  name: "pipeline-deployer"
+  namespace: "karavan"
+roleRef:
+  kind: "Role"
+  apiGroup: "rbac.authorization.k8s.io"
+  name: "deployer"
+subjects:
+- kind: "ServiceAccount"
+  apiGroup: ""
+  name: "pipeline"
+  namespace: "karavan"
+---
+apiVersion: "rbac.authorization.k8s.io/v1"
+kind: "RoleBinding"
+metadata:
+  name: "karavan"
+  namespace: "karavan"
+roleRef:
+  kind: "Role"
+  apiGroup: "rbac.authorization.k8s.io"
+  name: "karavan"
+subjects:
+- kind: "ServiceAccount"
+  apiGroup: ""
+  name: "karavan"
+  namespace: "karavan"
+---
+apiVersion: "tekton.dev/v1beta1"
+kind: "Pipeline"
+metadata:
+  labels:
+    app: "karavan-pipeline-dev-spring-boot"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-pipeline-dev-spring-boot"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-pipeline-dev-spring-boot"
+  namespace: "karavan"
+spec:
+  params:
+  - description: "ProjectId"
+    name: "PROJECT_ID"
+    type: "string"
+  tasks:
+  - name: "karavan-task-dev-spring-boot"
+    params:
+    - name: "project"
+      value: "$(params.PROJECT_ID)"
+    taskRef:
+      kind: "Task"
+      name: "karavan-task-dev-spring-boot"
+    workspaces:
+    - name: "maven-settings"
+      subPath: ""
+      workspace: "maven-settings"
+    - name: "karavan-m2-cache"
+      subPath: ""
+      workspace: "karavan-m2-cache"
+    - name: "karavan-jbang-cache"
+      subPath: ""
+      workspace: "karavan-jbang-cache"
+  workspaces:
+  - description: "Maven Settings"
+    name: "maven-settings"
+    optional: false
+  - description: "Maven Cache"
+    name: "karavan-m2-cache"
+    optional: false
+  - description: "JBang Cache"
+    name: "karavan-jbang-cache"
+    optional: false
+---
+apiVersion: "v1"
+kind: "Service"
+metadata:
+  labels:
+    app: "karavan"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan"
+  namespace: "karavan"
+spec:
+  ports:
+  - name: "http"
+    port: 80
+    protocol: "TCP"
+    targetPort: 8080
+  selector:
+    app: "karavan"
+  type: "ClusterIP"
+---
+apiVersion: "tekton.dev/v1beta1"
+kind: "Pipeline"
+metadata:
+  labels:
+    app: "karavan-pipeline-dev-quarkus"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-pipeline-dev-quarkus"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-pipeline-dev-quarkus"
+  namespace: "karavan"
+spec:
+  params:
+  - description: "ProjectId"
+    name: "PROJECT_ID"
+    type: "string"
+  tasks:
+  - name: "karavan-task-dev-quarkus"
+    params:
+    - name: "project"
+      value: "$(params.PROJECT_ID)"
+    taskRef:
+      kind: "Task"
+      name: "karavan-task-dev-quarkus"
+    workspaces:
+    - name: "maven-settings"
+      subPath: ""
+      workspace: "maven-settings"
+    - name: "karavan-m2-cache"
+      subPath: ""
+      workspace: "karavan-m2-cache"
+    - name: "karavan-jbang-cache"
+      subPath: ""
+      workspace: "karavan-jbang-cache"
+  workspaces:
+  - description: "Maven Settings"
+    name: "maven-settings"
+    optional: false
+  - description: "Maven Cache"
+    name: "karavan-m2-cache"
+    optional: false
+  - description: "JBang Cache"
+    name: "karavan-jbang-cache"
+    optional: false
+---
+apiVersion: "v1"
+kind: "PersistentVolumeClaim"
+metadata:
+  labels:
+    app: "karavan-m2-cache"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-m2-cache"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-m2-cache"
+  namespace: "karavan"
+spec:
+  accessModes:
+  - "ReadWriteOnce"
+  resources:
+    requests:
+      storage: "10Gi"
+  volumeMode: "Filesystem"
+---
+apiVersion: "apps/v1"
+kind: "Deployment"
+metadata:
+  labels:
+    app.kubernetes.io/runtime: "quarkus"
+  name: "karavan"
+  namespace: "karavan"
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: "karavan"
+  template:
+    metadata:
+      labels:
+        app: "karavan"
+    spec:
+      containers:
+      - env:
+        - name: "KARAVAN_ENVIRONMENT"
+          value: "dev"
+        - name: "KARAVAN_RUNTIMES"
+          value: "camel-main,quarkus,spring-boot"
+        - name: "KARAVAN_CONTAINER_STATUS_INTERVAL"
+          value: "disabled"
+        - name: "KARAVAN_CONTAINER_INFINISPAN_INTERVAL"
+          value: "disabled"
+        - name: "KARAVAN_CAMEL_STATUS_INTERVAL"
+          value: "3s"
+        - name: "INFINISPAN_HOSTS"
+          value: "infinispan.karavan:11222"
+        - name: "INFINISPAN_PASSWORD"
+          valueFrom:
+            secretKeyRef:
+              key: "password"
+              name: "infinispan-secret"
+              optional: false
+        - name: "KUBERNETES_NAMESPACE"
+          valueFrom:
+            fieldRef:
+              apiVersion: ""
+              fieldPath: "metadata.namespace"
+        - name: "QUARKUS_SCHEDULER_ENABLED"
+          value: "true"
+        - name: "KARAVAN_GIT_PULL_INTERVAL"
+          value: "off"
+        image: "ghcr.io/apache/camel-karavan:4.0.0-RC2"
+        imagePullPolicy: "Always"
+        name: "karavan"
+        ports:
+        - containerPort: 8080
+          name: "karavan"
+        resources:
+          requests:
+            memory: "512Mi"
+        volumeMounts:
+        - mountPath: "/deployments/karavan-data"
+          name: "karavan-data"
+        - mountPath: "/tmp"
+          name: "ephemeral"
+      serviceAccount: "karavan"
+      volumes:
+      - name: "karavan-data"
+        persistentVolumeClaim:
+          claimName: "karavan-data"
+          readOnly: false
+      - emptyDir: {}
+        name: "ephemeral"
+---
+apiVersion: "tekton.dev/v1beta1"
+kind: "Task"
+metadata:
+  labels:
+    app: "karavan-task-dev-camel-main"
+    app.kubernetes.io/part-of: "karavan"
+    app.kubernetes.io/name: "karavan-task-dev-camel-main"
+    app.kubernetes.io/version: "4.0.0-RC2"
+  name: "karavan-task-dev-camel-main"
+  namespace: "karavan"
+spec:
+  params:
+  - description: "ProjectId"
+    name: "project"
+    type: "string"
+  steps:
+  - env:
+    - name: "GIT_REPOSITORY"
+      valueFrom:
+        secretKeyRef:
+          key: "git-repository"
+          name: "karavan"
+    - name: "GIT_USERNAME"
+      valueFrom:
+        secretKeyRef:
+          key: "git-username"
+          name: "karavan"
+    - name: "GIT_PASSWORD"
+      valueFrom:
+        secretKeyRef:
+          key: "git-password"
+          name: "karavan"
+    - name: "GIT_BRANCH"
+      valueFrom:
+        secretKeyRef:
+          key: "git-branch"
+          name: "karavan"
+    - name: "IMAGE_REGISTRY"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_GROUP"
+      valueFrom:
+        secretKeyRef:
+          key: "image-group"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_REGISTRY_USERNAME"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry-username"
+          name: "karavan"
+          optional: true
+    - name: "IMAGE_REGISTRY_PASSWORD"
+      valueFrom:
+        secretKeyRef:
+          key: "image-registry-password"
+          name: "karavan"
+          optional: true
+    image: "ghcr.io/apache/camel-karavan-devmode:4.0.0-RC2"
+    imagePullPolicy: "Always"
+    name: "karavan-build-deploy"
+    script: "#!/usr/bin/env 
bash\nCHECKOUT_DIR=\"/scripts\"\nKAMELETS_DIR=\"/scripts/kamelets\"\
+      \n\nif  [[ $GIT_REPOSITORY == https* ]] ;\nthen\n    
replacer=https://$GIT_USERNAME:$GIT_PASSWORD@\n\
+      \    prefix=https://\n    url=\"${GIT_REPOSITORY/$prefix/$replacer}\"\n  
  git\
+      \ clone --depth 1 --branch ${GIT_BRANCH} $url ${CHECKOUT_DIR}\nelse\n    
git\
+      \ clone --depth 1 --branch ${GIT_BRANCH} ${GIT_REPOSITORY} 
${CHECKOUT_DIR}\n\
+      fi\n\ncd ${CHECKOUT_DIR}/$(inputs.params.project)\n\njbang 
-Dcamel.jbang.version=$CAMEL_VERSION\
+      \ camel@apache/camel export 
--local-kamelet-dir=${KAMELETS_DIR}\n\nexport LAST_COMMIT=$(git\
+      \ rev-parse --short HEAD)\nexport DATE=$(date '+%Y%m%d%H%M%S')\nexport 
TOKEN=$(cat\
+      \ /var/run/secrets/kubernetes.io/serviceaccount/token)\nexport 
NAMESPACE=$(cat\
+      \ /var/run/secrets/kubernetes.io/serviceaccount/namespace)\n\nmvn 
package jib:build\
+      \ k8s:resource k8s:apply \\\n  -Djkube.namespace=${NAMESPACE} \\\n  
-Djib.allowInsecureRegistries=true\
+      \ \\\n  
-Djib.to.image=${IMAGE_REGISTRY}/${IMAGE_GROUP}/$(inputs.params.project):${DATE}\
+      \ \\\n  -Djib.to.auth.username=${IMAGE_REGISTRY_USERNAME} \\\n  
-Djib.to.auth.password=${IMAGE_REGISTRY_PASSWORD}\
+      \  \\\n  --settings=$MAVEN_SETTINGS"
+  workspaces:
+  - description: "Maven Settings"
+    mountPath: "/karavan-config-map"
+    name: "maven-settings"
+    optional: false
+    readOnly: false
+  - description: "Maven Cache"
+    mountPath: "/root/.m2"
+    name: "karavan-m2-cache"
+    optional: false
+    readOnly: false
+  - description: "JBang Cache"
+    mountPath: "/jbang/.jbang/cache"
+    name: "karavan-jbang-cache"
+    optional: false
+    readOnly: false

Reply via email to