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 453c460c05b71388944fc0110e7635b9cb46c0ba Author: Marat Gubaidullin <marat.gubaidul...@gmail.com> AuthorDate: Thu Aug 10 16:32:58 2023 -0400 Implements #848 --- .../src/main/resources/application.properties | 13 ++-- .../org/apache/camel/karavan/cli/CommandUtils.java | 68 +++++++++++++------ .../org/apache/camel/karavan/cli/Constants.java | 7 +- .../apache/camel/karavan/cli/KaravanCommand.java | 9 +-- .../karavan/cli/resources/KaravanDeployment.java | 77 ++++++++++++---------- .../karavan-cli/src/main/resources/infinispan.yaml | 65 ++---------------- 6 files changed, 111 insertions(+), 128 deletions(-) diff --git a/karavan-web/karavan-app/src/main/resources/application.properties b/karavan-web/karavan-app/src/main/resources/application.properties index 002a0682..7b921f94 100644 --- a/karavan-web/karavan-app/src/main/resources/application.properties +++ b/karavan-web/karavan-app/src/main/resources/application.properties @@ -6,19 +6,20 @@ karavan.runtimes=camel-main,quarkus,spring-boot karavan.camel.status.interval=off karavan.container.status.interval=3s karavan.container.infinispan.interval=5s -karavan.devmode.image=ghcr.io/apache/camel-karavan-runner:4.0.0-RC2 +karavan.devmode.image=ghcr.io/apache/camel-karavan-devmode:4.0.0-RC2 karavan.headless.image=entropy1/karavan-headless:4.0.0-RC2 # Git repository Configuration -karavan.git.repository=${GIT_REPOSITORY} -karavan.git.username=${GIT_USERNAME} -karavan.git.password=${GIT_TOKEN} -karavan.git.branch=main -karavan.git.pull.interval=disabled +karavan.git-repository=${GIT_REPOSITORY} +karavan.git-username=${GIT_USERNAME} +karavan.git-password=${GIT_TOKEN} +karavan.git-branch=main +karavan.git-pull-interval=disabled # Infinispan container config in Docker infinispan.image=quay.io/infinispan/server:14.0.6.Final infinispan.port=11222:11222 +# Infinispan connection config infinispan.username=admin infinispan.password=karavan infinispan.hosts=localhost:11222 diff --git a/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/CommandUtils.java b/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/CommandUtils.java index 4b170f69..4c770ac4 100644 --- a/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/CommandUtils.java +++ b/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/CommandUtils.java @@ -29,6 +29,7 @@ import io.fabric8.tekton.pipeline.v1beta1.Task; import org.apache.camel.karavan.cli.resources.*; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; @@ -48,7 +49,7 @@ public class CommandUtils { System.out.println("⭕ Installing Karavan to OpenShift"); config.setOpenShift(true); } else { - System.out.println("\u2388 Installing Karavan to Kubernetes"); + System.out.println("⭕ Installing Karavan to Kubernetes"); config.setOpenShift(false); } install(config, client); @@ -58,7 +59,7 @@ public class CommandUtils { private static void install(KaravanCommand config, KubernetesClient client) { // Check and install Tekton if (!isTektonInstalled(client)) { - log("Tekton is not installed"); + logError("Tekton is not installed"); if (isOpenShift(client)) { logPoint("Please install Tekton Operator first"); System.exit(0); @@ -79,14 +80,13 @@ public class CommandUtils { // Check and install Infinispan if (!isInfinispanInstalled(client)) { - log("Infinispan is not installed"); + logError("Infinispan is not installed"); if (isOpenShift(client)) { logPoint("Please install Infinispan first"); System.exit(0); } installInfinispan(config, client); } - log("Infinispan is installed"); // Check secrets if (!checkKaravanSecrets(config, client)) { @@ -137,9 +137,9 @@ public class CommandUtils { } log("Karavan is installed"); System.out.print("\uD83D\uDC2B Karavan is starting "); - while (!checkReady(config, client)) { + while (!checkKaravanReady(config, client)) { try { - Thread.sleep(1000); + Thread.sleep(2000); } catch (Exception e) { } @@ -162,7 +162,12 @@ public class CommandUtils { config.setImageRegistry(Constants.DEFAULT_IMAGE_REGISTRY_OPENSHIFT); } else { Service registryService = client.services().inNamespace("kube-system").withName("registry").get(); - config.setImageRegistry(registryService.getSpec().getClusterIP()); + if (registryService != null) { + config.setImageRegistry(registryService.getSpec().getClusterIP()); + } else { + logError("Set Image Registry parameters"); + System.exit(0); + } } } if ((config.isAuthOidc() && config.oidcConfigured()) @@ -177,7 +182,7 @@ public class CommandUtils { return false; } - public static boolean checkReady(KaravanCommand config, KubernetesClient client) { + public static boolean checkKaravanReady(KaravanCommand config, KubernetesClient client) { Deployment deployment = client.apps().deployments().inNamespace(config.getNamespace()).withName(Constants.NAME).get(); Integer replicas = deployment.getStatus().getReplicas(); Integer ready = deployment.getStatus().getReadyReplicas(); @@ -190,6 +195,16 @@ public class CommandUtils { && condition.isPresent(); } + public static boolean checkInfinispanReady(KaravanCommand config, KubernetesClient client) { + StatefulSet statefulSet = client.apps().statefulSets().inNamespace(config.getNamespace()).withName(Constants.INFINISPAN_NAME).get(); + Integer replicas = statefulSet.getStatus().getReplicas(); + Integer ready = statefulSet.getStatus().getReadyReplicas(); + Integer available = statefulSet.getStatus().getAvailableReplicas(); + return statefulSet.getStatus() != null + && Objects.equals(replicas, ready) + && Objects.equals(replicas, available); + } + private static <T extends HasMetadata> void createOrReplace(T is, KubernetesClient client) { try { T result = client.resource(is).createOrReplace(); @@ -200,27 +215,38 @@ public class CommandUtils { } private static void installInfinispan(KaravanCommand config, KubernetesClient client) { - System.out.print("⏳ Installing Infinispan"); + System.out.print("⏳ Installing Infinispan "); String yaml = getResourceFile("/infinispan.yaml"); -// -// client.load(CommandUtils.class.getResourceAsStream("/pipelines.yaml")).create().forEach(hasMetadata -> { -// System.out.print("."); -// }); -// client.load(CommandUtils.class.getResourceAsStream("/dashboard.yaml")).create().forEach(hasMetadata -> { -// System.out.print("."); -// }); - System.out.println(yaml); - System.exit(0); + String resource = yaml + .replace("$INFINISPAN_PASSWORD", config.getInfinispanPassword()) + .replace("$INFINISPAN_IMAGE", config.getInfinispanImage()); + + client.load(new ByteArrayInputStream(resource.getBytes())).inNamespace(config.getNamespace()) + .create().forEach(hasMetadata -> System.out.print("\uD83D\uDC2B ")); + System.out.println(); log("Infinispan is installed"); + System.out.print("⏳ Infinispan is starting "); + while (!checkInfinispanReady(config, client)) { + try { + Thread.sleep(2000); + } catch (Exception e) { + + } + System.out.print("\uD83D\uDC2B "); + } + System.out.println(); + log("Infinispan is started"); } private static void installTekton(KaravanCommand config, KubernetesClient client) { - System.out.print("⏳ Installing Tekton"); + System.out.print("⏳ Installing Tekton "); client.load(CommandUtils.class.getResourceAsStream("/pipelines.yaml")).create().forEach(hasMetadata -> { - System.out.print("."); + System.out.print("\uD83D\uDC2B "); }); + System.out.println(); + System.out.print("⏳ Installing Tekton Dashboard "); client.load(CommandUtils.class.getResourceAsStream("/dashboard.yaml")).create().forEach(hasMetadata -> { - System.out.print("."); + System.out.print("\uD83D\uDC2B "); }); System.out.println(); log("Tekton is installed"); diff --git a/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/Constants.java b/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/Constants.java index 53558b88..eef4be08 100644 --- a/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/Constants.java +++ b/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/Constants.java @@ -19,14 +19,14 @@ package org.apache.camel.karavan.cli; public final class Constants { public static final String DEFAULT_NAMESPACE = "karavan"; public static final String DEFAULT_ENVIRONMENT = "dev"; - public static final String DEFAULT_RUNTIMES = "quarkus,spring-boot"; + public static final String DEFAULT_RUNTIMES = "camel-main,quarkus,spring-boot"; public static final String DEFAULT_AUTH = "public"; public static final String DEFAULT_GIT_PULL_INTERVAL = "off"; public static final String DEFAULT_IMAGE_REGISTRY_OPENSHIFT = "image-registry.openshift-image-registry.svc:5000"; public static final String DEFAULT_IMAGE_REGISTRY_MINIKUBE = "registry.kube-system.svc.cluster.local"; public static final int DEFAULT_NODE_PORT = 0; public static final int DEFAULT_INSTANCES = 1; - public static final String DEFAULT_BUILD_IMAGE = "ghcr.io/apache/camel-karavan-builder"; + public static final String DEFAULT_BUILD_IMAGE = "ghcr.io/apache/camel-karavan-devmode"; public static final String KARAVAN_IMAGE = "ghcr.io/apache/camel-karavan"; @@ -49,6 +49,9 @@ public final class Constants { public static final String PVC_M2_CACHE = "karavan-m2-cache"; public static final String PVC_JBANG_CACHE = "karavan-jbang-cache"; + public static final String INFINISPAN_NAME = "infinispan"; + public static final String INFINISPAN_SECRET_NAME = "infinispan-secret"; + public static final String PIPELINE_DEV = "karavan-pipeline-dev-"; public static final String TASK_DEV = "karavan-task-dev-"; diff --git a/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/KaravanCommand.java b/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/KaravanCommand.java index 82d0e3ec..b1ed1399 100644 --- a/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/KaravanCommand.java +++ b/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/KaravanCommand.java @@ -4,6 +4,7 @@ import picocli.CommandLine; import java.nio.file.Files; import java.nio.file.Path; +import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.Callable; @@ -19,7 +20,7 @@ public class KaravanCommand implements Callable<Integer> { private String namespace; @CommandLine.Option(names = {"-e", "--environment"}, description = "Environment", defaultValue = Constants.DEFAULT_ENVIRONMENT) private String environment; - @CommandLine.Option(names = {"-r", "--runtimes"}, description = "Runtimes: quarkus, spring-boot", defaultValue = Constants.DEFAULT_RUNTIMES) + @CommandLine.Option(names = {"-r", "--runtimes"}, description = "Runtimes: camel-main, quarkus, spring-boot", defaultValue = Constants.DEFAULT_RUNTIMES) private String runtimes; @CommandLine.Option(names = {"--auth"}, description = "Authentication: public, basic, oidc", defaultValue = Constants.DEFAULT_AUTH) private String auth; @@ -27,9 +28,9 @@ public class KaravanCommand implements Callable<Integer> { private int nodePort; @CommandLine.Option(names = {"--instances"}, description = "Instances. Default: 1", defaultValue = "1") private int instances; - @CommandLine.Option(names = {"--base-image"}, description = "Base Image", defaultValue = Constants.KARAVAN_IMAGE) + @CommandLine.Option(names = {"--image"}, description = "Karavan Base Image", defaultValue = Constants.KARAVAN_IMAGE) private String baseImage; - @CommandLine.Option(names = {"--base-builder-image"}, description = "Base Builder Image", defaultValue = Constants.DEFAULT_BUILD_IMAGE) + @CommandLine.Option(names = {"--builder-image"}, description = "Karavan Base Builder Image", defaultValue = Constants.DEFAULT_BUILD_IMAGE) private String baseBuilderImage; @CommandLine.Option(names = {"--file"}, description = "YAML file name", defaultValue = "karavan.yaml") private String file; @@ -78,7 +79,7 @@ public class KaravanCommand implements Callable<Integer> { @CommandLine.Option(names = { "-h", "--help" }, usageHelp = true, description = "Display help") private boolean helpRequested; - private Map<String,String> labels; + private Map<String,String> labels = new HashMap<>(); public static void main(String... args) { CommandLine commandLine = new CommandLine(new KaravanCommand()); diff --git a/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/resources/KaravanDeployment.java b/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/resources/KaravanDeployment.java index ccf6cd41..b73e7c97 100644 --- a/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/resources/KaravanDeployment.java +++ b/karavan-web/karavan-cli/src/main/java/org/apache/camel/karavan/cli/resources/KaravanDeployment.java @@ -16,16 +16,7 @@ */ package org.apache.camel.karavan.cli.resources; -import io.fabric8.kubernetes.api.model.EmptyDirVolumeSource; -import io.fabric8.kubernetes.api.model.EnvVar; -import io.fabric8.kubernetes.api.model.EnvVarSourceBuilder; -import io.fabric8.kubernetes.api.model.ObjectFieldSelector; -import io.fabric8.kubernetes.api.model.PersistentVolumeClaimVolumeSource; -import io.fabric8.kubernetes.api.model.Quantity; -import io.fabric8.kubernetes.api.model.ResourceRequirementsBuilder; -import io.fabric8.kubernetes.api.model.SecretKeySelector; -import io.fabric8.kubernetes.api.model.VolumeBuilder; -import io.fabric8.kubernetes.api.model.VolumeMountBuilder; +import io.fabric8.kubernetes.api.model.*; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; import org.apache.camel.karavan.cli.Constants; @@ -36,9 +27,12 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import static org.apache.camel.karavan.cli.Constants.INFINISPAN_SECRET_NAME; +import static org.apache.camel.karavan.cli.Constants.NAME; + public class KaravanDeployment { - public static Deployment getDeployment (KaravanCommand config) { + public static Deployment getDeployment(KaravanCommand config) { String baseImage = config.getBaseImage(); @@ -46,30 +40,45 @@ public class KaravanDeployment { List<EnvVar> envVarList = new ArrayList<>(); envVarList.add( - new EnvVar("KARAVAN_ENVIRONMENT",config.getEnvironment(), null) + new EnvVar("KARAVAN_ENVIRONMENT", config.getEnvironment(), null) ); envVarList.add( new EnvVar("KARAVAN_RUNTIMES", config.getRuntimes(), null) ); envVarList.add( - new EnvVar("KUBERNETES_NAMESPACE", null, new EnvVarSourceBuilder().withFieldRef(new ObjectFieldSelector("","metadata.namespace")).build()) + new EnvVar("KARAVAN_CONTAINER_STATUS_INTERVAL", "disabled", null) + ); + envVarList.add( + new EnvVar("KARAVAN_CONTAINER_INFINISPAN_INTERVAL", "disabled", null) + ); + envVarList.add( + new EnvVar("KARAVAN_CAMEL_STATUS_INTERVAL", "3s", null) + ); + envVarList.add( + new EnvVar("INFINISPAN_HOSTS", "infinispan." + config.getNamespace() + ":11222", null) + ); + envVarList.add( + new EnvVar("INFINISPAN_PASSWORD", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("password", INFINISPAN_SECRET_NAME, false)).build()) + ); + envVarList.add( + new EnvVar("KUBERNETES_NAMESPACE", null, new EnvVarSourceBuilder().withFieldRef(new ObjectFieldSelector("", "metadata.namespace")).build()) ); String auth = config.getAuth(); if (Objects.equals(auth, "basic")) { image = baseImage + "-basic:" + config.getVersion(); envVarList.add( - new EnvVar("MASTER_PASSWORD", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("master-password","karavan", false)).build()) + new EnvVar("MASTER_PASSWORD", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("master-password", NAME, false)).build()) ); - } else if (Objects.equals(auth,"oidc")) { + } else if (Objects.equals(auth, "oidc")) { image = baseImage + "-oidc:" + config.getVersion(); envVarList.add( - new EnvVar("OIDC_FRONTEND_URL", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("oidc-frontend-url","karavan", false)).build()) + new EnvVar("OIDC_FRONTEND_URL", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("oidc-frontend-url", "karavan", false)).build()) ); envVarList.add( - new EnvVar("OIDC_SERVER_URL", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("oidc-server-url","karavan", false)).build()) + new EnvVar("OIDC_SERVER_URL", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("oidc-server-url", "karavan", false)).build()) ); envVarList.add( - new EnvVar("OIDC_SECRET", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("oidc-secret","karavan", false)).build()) + new EnvVar("OIDC_SECRET", null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelector("oidc-secret", "karavan", false)).build()) ); } String gitPullInterval = config.getGitPullInterval(); @@ -108,22 +117,22 @@ public class KaravanDeployment { .endMetadata() .withNewSpec() - .addNewContainer() - .withName(Constants.NAME) - .withImage(image) - .withImagePullPolicy("Always") - .withEnv(envVarList) - .addNewPort() - .withContainerPort(8080) - .withName(Constants.NAME) - .endPort() - .withResources(new ResourceRequirementsBuilder().withRequests( - Map.of("memory", new Quantity("512Mi"))).build()) - .withVolumeMounts( - new VolumeMountBuilder().withName("karavan-data").withMountPath("/deployments/karavan-data").build(), - new VolumeMountBuilder().withName("ephemeral").withMountPath("/tmp").build() - ) - .endContainer() + .addNewContainer() + .withName(Constants.NAME) + .withImage(image) + .withImagePullPolicy("Always") + .withEnv(envVarList) + .addNewPort() + .withContainerPort(8080) + .withName(Constants.NAME) + .endPort() + .withResources(new ResourceRequirementsBuilder().withRequests( + Map.of("memory", new Quantity("512Mi"))).build()) + .withVolumeMounts( + new VolumeMountBuilder().withName("karavan-data").withMountPath("/deployments/karavan-data").build(), + new VolumeMountBuilder().withName("ephemeral").withMountPath("/tmp").build() + ) + .endContainer() .withServiceAccount(Constants.NAME) .withVolumes( new VolumeBuilder().withName("karavan-data").withPersistentVolumeClaim(new PersistentVolumeClaimVolumeSource("karavan-data", false)).build(), diff --git a/karavan-web/karavan-cli/src/main/resources/infinispan.yaml b/karavan-web/karavan-cli/src/main/resources/infinispan.yaml index 42fff892..bcb322ba 100644 --- a/karavan-web/karavan-cli/src/main/resources/infinispan.yaml +++ b/karavan-web/karavan-cli/src/main/resources/infinispan.yaml @@ -3,7 +3,7 @@ apiVersion: v1 kind: Secret metadata: - name: infinispan-generated-secret + name: infinispan-secret labels: app: infinispan-secret-identities clusterName: infinispan @@ -18,8 +18,8 @@ metadata: "helm.sh/resource-policy": keep type: Opaque stringData: - username: monitor - password: $INFINISPAN_PASSWORD + username: 'monitor' + password: '$INFINISPAN_PASSWORD' identities-batch: |- user create admin -p $INFINISPAN_PASSWORD user create monitor -p $INFINISPAN_PASSWORD --users-file metrics-users.properties --groups-file metrics-groups.properties @@ -201,63 +201,6 @@ data: </Loggers> </Configuration> --- -# Source: infinispan/templates/metrics-service.yaml -apiVersion: v1 -kind: Service -metadata: - name: infinispan-metrics - annotations: - meta.helm.sh/release-name: infinispan - meta.helm.sh/release-namespace: default - labels: - app: infinispan-service-metrics - clusterName: infinispan - helm.sh/chart: infinispan-0.3.1 - meta.helm.sh/release-name: infinispan - meta.helm.sh/release-namespace: default - app.kubernetes.io/version: "14.0" - app.kubernetes.io/managed-by: Helm - -spec: - type: ClusterIP - clusterIP: None - ports: - - port: 11223 - protocol: TCP - name: infinispan-met - selector: - clusterName: infinispan - app: infinispan-pod ---- -# Source: infinispan/templates/ping-service.yaml -apiVersion: v1 -kind: Service -metadata: - name: infinispan-ping - annotations: - meta.helm.sh/release-name: infinispan - meta.helm.sh/release-namespace: default - labels: - app: infinispan-service-ping - clusterName: infinispan - helm.sh/chart: infinispan-0.3.1 - meta.helm.sh/release-name: infinispan - meta.helm.sh/release-namespace: default - app.kubernetes.io/version: "14.0" - app.kubernetes.io/managed-by: Helm - -spec: - publishNotReadyAddresses: true - type: ClusterIP - clusterIP: None - ports: - - port: 8888 - protocol: TCP - name: infinispan - selector: - clusterName: infinispan - app: infinispan-pod ---- # Source: infinispan/templates/service.yaml apiVersion: v1 kind: Service @@ -407,7 +350,7 @@ spec: name: config-volume - name: identities-volume secret: - secretName: infinispan-generated-secret + secretName: infinispan-secret - name: data-volume emptyDir: { } updateStrategy: