From c6f696370c4975777be32c23112da76ade761565 Mon Sep 17 00:00:00 2001 From: Jean-Francois Denise Date: Fri, 8 Mar 2024 16:19:36 +0100 Subject: [PATCH 1/5] Add support for HA when provisioning to OpenShift --- .../glow/cli/commands/OpenShiftSupport.java | 19 +++++++++++++++++++ docs/guide/intro/index.adoc | 7 ++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java index 39e824b5..bb9cdd8f 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java @@ -92,6 +92,25 @@ private static void createAppDeployment(GlowMessageWriter writer, Path target, O for (Entry entry : env.entrySet()) { vars.add(new EnvVar().toBuilder().withName(entry.getKey()).withValue(entry.getValue()).build()); } + if (ha) { + writer.info("\n HA enabled, 2 replicas will be started."); + vars.add(new EnvVar().toBuilder().withName("JGROUPS_PING_PROTOCOL").withValue("DNS_PING").build()); + vars.add(new EnvVar().toBuilder().withName("OPENSHIFT_DNS_PING_SERVICE_PORT").withValue("8888").build()); + vars.add(new EnvVar().toBuilder().withName("OPENSHIFT_DNS_PING_SERVICE_NAME").withValue(name + "-ping").build()); + IntOrString v = new IntOrString(); + v.setValue(8888); + Service pingService = new ServiceBuilder().withNewMetadata().withName(name + "-ping").endMetadata(). + withNewSpec().withPorts(new ServicePort().toBuilder().withProtocol("TCP"). + withPort(8888). + withName("ping"). + withTargetPort(v).build()). + withClusterIP("None").withPublishNotReadyAddresses().withIpFamilies("IPv4"). + withInternalTrafficPolicy("Cluster").withClusterIPs("None"). + withType("ClusterIP").withIpFamilyPolicy("SingleStack"). + withSessionAffinity("None").withSelector(labels).endSpec().build(); + osClient.services().resource(pingService).createOr(NonDeletingOperation::update); + Files.write(target.resolve(name + "-ping-service.yaml"), Serialization.asYaml(pingService).getBytes()); + } Container container = new Container(); container.setName(name); container.setImage(name + ":latest"); diff --git a/docs/guide/intro/index.adoc b/docs/guide/intro/index.adoc index 197cbc58..2e867774 100644 --- a/docs/guide/intro/index.adoc +++ b/docs/guide/intro/index.adoc @@ -67,11 +67,16 @@ provisioning and create your application deployment. At the end of the build, the application is deployed and the route to your application inside the cluster is printed. Use it to interact with your application. +Note: the support for OpenShift is currently specified by this WildFly Glow project link:https://github.com/wildfly/wildfly-glow/issues/49[GitHub Issue]. + ###### Automatic deployment of PostGreSQL, MySQL, MariaDB, Artemis JMS Broker and Keycloak If WildFly Glow detects the need for these technologies, it will automatically deploy the required servers and will bound the application to them. -This feature is currently specified by this link:https://github.com/wildfly/wildfly-glow/issues/49[GitHub Issue]. +###### High Availability support + +When the HA profile is enabled, 2 pods will be created for the deployment. +The JGroups `dns.DNS_PING` protocol is enabled for the members of the cluster to discover each others. #### WildFly additional features discovery From 30ee1ca2a404488fbcc6c174622586424bd9a8a0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Denise Date: Wed, 13 Mar 2024 10:02:01 +0100 Subject: [PATCH 2/5] Initial script support, inject route as env --- .../wildfly/glow/cli/commands/Constants.java | 3 +++ .../glow/cli/commands/OpenShiftSupport.java | 22 ++++++++++++++++++- .../glow/cli/commands/ScanCommand.java | 21 +++++++++++++++++- .../main/resources/UsageMessages.properties | 2 ++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/Constants.java b/cli/src/main/java/org/wildfly/glow/cli/commands/Constants.java index 9a636267..02d2a180 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/Constants.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/Constants.java @@ -56,6 +56,9 @@ public interface Constants { String HELP_OPTION = "--help"; String HELP_OPTION_SHORT = "-h"; + String INIT_SCRIPT_OPTION = "--init-script"; + String INIT_SCRIPT_OPTION_SHORT = "-id"; + String INIT_SCRIPT_OPTION_LABEL = ""; String INPUT_FEATURE_PACKS_FILE_OPTION = "--input-feature-packs-file"; String INPUT_FEATURE_PACKS_FILE_OPTION_LABEL = ""; String NO_DOCKER_IMAGE_OPTION = "--no-docker-image"; diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java index bb9cdd8f..138d3b5b 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java @@ -225,7 +225,7 @@ static void deploy(GlowMessageWriter writer, Path target, String appName, Map disabledDeployers) { return disabledDeployers.contains("ALL") || disabledDeployers.contains(name); } diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java b/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java index 4024dc83..9783f1df 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java @@ -114,6 +114,9 @@ public Stability convert(String value) throws Exception { @CommandLine.Option(names = {Constants.ENV_FILE_OPTION_SHORT, Constants.ENV_FILE_OPTION}, paramLabel = Constants.ENV_FILE_OPTION_LABEL) Optional envFile; + @CommandLine.Option(names = {Constants.INIT_SCRIPT_OPTION_SHORT, Constants.INIT_SCRIPT_OPTION}, paramLabel = Constants.INIT_SCRIPT_OPTION_LABEL) + Optional initScriptFile; + @CommandLine.Option(names = Constants.DISABLE_DEPLOYERS, split = ",", paramLabel = Constants.ADD_ONS_OPTION_LABEL) Set disableDeployers = new LinkedHashSet<>(); @@ -168,6 +171,19 @@ public Integer call() throws Exception { } } } + if (initScriptFile.isPresent()) { + if (provision.isPresent()) { + if (!OPENSHIFT.equals(provision.get())) { + throw new Exception("Init script file is only usable when --provision=" + OPENSHIFT + " option is set."); + } + } else { + throw new Exception("Init script file file is only usable when --provision=" + OPENSHIFT + " option is set."); + } + Path p = initScriptFile.get(); + if (!Files.exists(p)) { + throw new Exception(p + " file doesn't exist"); + } + } builder.setVerbose(verbose); if (!addOns.isEmpty()) { builder.setUserEnabledAddOns(addOns); @@ -323,13 +339,16 @@ public Integer call() throws Exception { int ext = p.getFileName().toString().indexOf("."); name = p.getFileName().toString().substring(0, ext); } + if (initScriptFile.isPresent()) { + OpenShiftSupport.packageInitScript(initScriptFile.get(), target); + } Map envMap = new HashMap<>(); for(Set envs : scanResults.getSuggestions().getStronglySuggestedConfigurations().values()) { for(Env env : envs) { envMap.put(env.getName(), env.getDescription()); } } - OpenShiftSupport.deploy(GlowMessageWriter.DEFAULT, target, name == null ? "app-from-wildfly-glow" : name, envMap, scanResults.getDiscoveredLayers(), + OpenShiftSupport.deploy(GlowMessageWriter.DEFAULT, target, name == null ? "app-from-wildfly-glow" : name.toLowerCase(), envMap, scanResults.getDiscoveredLayers(), scanResults.getEnabledAddOns(), haProfile.orElse(false), extraEnv, disableDeployers); print("@|bold Openshift build and deploy DONE.|@"); } diff --git a/cli/src/main/resources/UsageMessages.properties b/cli/src/main/resources/UsageMessages.properties index 812db6f9..5630dae7 100644 --- a/cli/src/main/resources/UsageMessages.properties +++ b/cli/src/main/resources/UsageMessages.properties @@ -36,6 +36,8 @@ output-dir = If specifying to provision, the directory where the result will be wildfly-preview = Use only WildFly preview feature-packs as input. stability-level = Specify a stability to be used when provisioning a server. The stability is also used to identify server features that would be not enabled by the specified stability. The stability is by default the minimum stability of each Galleon feature-packs. The stability can be @|fg(yellow) default|@, @|fg(yellow) community|@, @|fg(yellow) preview|@, @|fg(yellow) experimental|@. env-file = The path to a file that contains environment variables (in the form env=value) to be passed to the OpenShift deployment. Can only be used with @|fg(yellow) OPENSHIFT|@ kind of provisioning. +init-script = The path to a script that contains commands (JBoss CLI, add-user, ...) to fine tune the server on OpenShift deployment. Can only be used with @|fg(yellow) OPENSHIFT|@ kind of provisioning. + disable-deployers = A comma separated list of deployer names to disable. To retrieve all the deployer names call the @|fg(yellow) show-configuration|@ operation. To disable them all, use @|fg(yellow) ALL|@ value. Can only be used with @|fg(yellow) OPENSHIFT|@ kind of provisioning. usage.synopsisHeading = %nUsage:\u0020 From 0758f8153d33f27e7bf532cd203b3616bdb14f5b Mon Sep 17 00:00:00 2001 From: Jean-Francois Denise Date: Wed, 13 Mar 2024 13:53:43 +0100 Subject: [PATCH 3/5] Smart build, initial commit --- .../glow/cli/commands/OpenShiftSupport.java | 157 ++++++++++++++---- .../glow/cli/commands/ScanCommand.java | 4 +- 2 files changed, 126 insertions(+), 35 deletions(-) diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java index 138d3b5b..a461d52a 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java @@ -23,6 +23,7 @@ import io.fabric8.kubernetes.api.model.HTTPGetAction; import io.fabric8.kubernetes.api.model.IntOrString; import io.fabric8.kubernetes.api.model.ObjectReference; +import io.fabric8.kubernetes.api.model.ObjectReferenceBuilder; import io.fabric8.kubernetes.api.model.Probe; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.ServiceBuilder; @@ -39,16 +40,22 @@ import io.fabric8.openshift.api.model.BuildConfig; import io.fabric8.openshift.api.model.BuildConfigBuilder; import io.fabric8.openshift.api.model.ImageLookupPolicy; +import io.fabric8.openshift.api.model.ImageSource; +import io.fabric8.openshift.api.model.ImageSourceBuilder; +import io.fabric8.openshift.api.model.ImageSourcePath; +import io.fabric8.openshift.api.model.ImageSourcePathBuilder; import io.fabric8.openshift.api.model.ImageStream; import io.fabric8.openshift.api.model.ImageStreamBuilder; import io.fabric8.openshift.api.model.Route; import io.fabric8.openshift.api.model.RouteBuilder; import io.fabric8.openshift.api.model.RouteTargetReference; import io.fabric8.openshift.api.model.TLSConfig; +import io.fabric8.openshift.api.model.TagReferenceBuilder; import io.fabric8.openshift.client.OpenShiftClient; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.MessageDigest; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -59,6 +66,7 @@ import java.util.TreeMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import org.jboss.galleon.util.IoUtils; import org.jboss.galleon.util.ZipUtils; import org.wildfly.glow.AddOn; import org.wildfly.glow.GlowMessageWriter; @@ -242,22 +250,9 @@ static void deploy(GlowMessageWriter writer, Path target, String appName, Map disabledDeployers) { return disabledDeployers.contains("ALL") || disabledDeployers.contains(name); } + private static String bytesToHex(byte[] hash) { + StringBuilder hexString = new StringBuilder(2 * hash.length); + for (int i = 0; i < hash.length; i++) { + String hex = Integer.toHexString(0xff & hash[i]); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } + static void createBuild(GlowMessageWriter writer, Path target, OpenShiftClient osClient, String name) throws Exception { - // zip deployment and provisioning.xml to be pushed to OpenShift - Path file = Paths.get("openshiftApp.zip"); - if (Files.exists(file)) { - Files.delete(file); + Path provisioning = target.resolve("galleon").resolve("provisioning.xml"); + byte[] content = Files.readAllBytes(provisioning); + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] encodedhash = digest.digest(content); + String key = bytesToHex(encodedhash); + String serverImageName = "wildfly-server-" + key; + + ImageStream stream = new ImageStreamBuilder().withNewMetadata().withName(serverImageName). + endMetadata().withNewSpec().withLookupPolicy(new ImageLookupPolicy(Boolean.TRUE)).endSpec().build(); + // check if it exists + ImageStream existingStream = osClient.imageStreams().resource(stream).get(); + writer.info("\nCreating and starting application image build on OpenShift..."); + if (existingStream == null) { + writer.info("\nBuilding server image (this can take up to few minutes the first time)..."); + // zip deployment and provisioning.xml to be pushed to OpenShift + Path file = Paths.get("openshiftServer.zip"); + if (Files.exists(file)) { + Files.delete(file); + } + file.toFile().deleteOnExit(); + // First do a build of the naked server + Path stepOne = target.resolve("step-one"); + Files.createDirectories(stepOne); + IoUtils.copy(target.resolve("galleon"), stepOne.resolve("galleon")); + ZipUtils.zip(stepOne, file); + osClient.imageStreams().resource(stream).createOr(NonDeletingOperation::update); + Files.write(target.resolve(serverImageName + "-image-stream.yaml"), Serialization.asYaml(stream).getBytes()); + BuildConfigBuilder builder = new BuildConfigBuilder(); + ObjectReference ref = new ObjectReference(); + ref.setKind("ImageStreamTag"); + ref.setName(serverImageName + ":latest"); + BuildConfig buildConfig = builder. + withNewMetadata().withName(serverImageName + "-build").endMetadata().withNewSpec(). + withNewOutput(). + withNewTo(). + withKind("ImageStreamTag"). + withName(serverImageName + ":latest").endTo(). + endOutput().withNewStrategy().withNewSourceStrategy().withNewFrom().withKind("DockerImage"). + withName("quay.io/wildfly/wildfly-s2i:latest").endFrom(). + withIncremental(true). + withEnv(new EnvVar().toBuilder().withName("GALLEON_USE_LOCAL_FILE").withValue("true").build()). + endSourceStrategy().endStrategy().withNewSource(). + withType("Binary").endSource().endSpec().build(); + osClient.buildConfigs().resource(buildConfig).createOr(NonDeletingOperation::update); + Files.write(target.resolve(serverImageName + "-build-config.yaml"), Serialization.asYaml(buildConfig).getBytes()); + + Build build = osClient.buildConfigs().withName(serverImageName + "-build").instantiateBinary().fromFile(file.toFile()); + CountDownLatch latch = new CountDownLatch(1); + try (Watch watcher = osClient.builds().withName(build.getMetadata().getName()).watch(getBuildWatcher(writer, latch))) { + latch.await(); + } + } + // Now step 2 + // From the server image, do a docker build, copy the server and copy in it the deployments and init file. + Path stepTwo = target.resolve("step-two"); + IoUtils.copy(target.resolve("deployments"), stepTwo.resolve("deployments")); + StringBuilder dockerFileBuilder = new StringBuilder(); + dockerFileBuilder.append("FROM wildfly-runtime:latest\n"); + dockerFileBuilder.append("COPY --chown=jboss:root /server $JBOSS_HOME\n"); + dockerFileBuilder.append("COPY --chown=jboss:root deployments/* $JBOSS_HOME/standalone/deployments\n"); + + Path extensions = target.resolve("extensions"); + if(Files.exists(extensions)) { + IoUtils.copy(extensions, stepTwo.resolve("extensions")); + dockerFileBuilder.append("COPY --chown=jboss:root extensions $JBOSS_HOME/extensions\n"); + dockerFileBuilder.append("RUN chmod ug+rwx $JBOSS_HOME/extensions/postconfigure.sh\n"); } - file.toFile().deleteOnExit(); - ZipUtils.zip(target, file); - writer.info("\nCreating and starting application image build on OpenShift (this can take up to few minutes)..."); - ImageStream stream = new ImageStreamBuilder().withNewMetadata().withName(name). + + dockerFileBuilder.append("RUN chmod -R ug+rwX $JBOSS_HOME\n"); + + Path dockerFile = stepTwo.resolve("Dockerfile"); + Files.write(dockerFile, dockerFileBuilder.toString().getBytes()); + Path file2 = Paths.get("openshiftApp.zip"); + if (Files.exists(file2)) { + Files.delete(file2); + } + ZipUtils.zip(stepTwo, file2); + writer.info("\nCreating and starting application image build on OpenShift..."); + ImageStream runtimeStream = new ImageStreamBuilder().withNewMetadata().withName("wildfly-runtime"). + endMetadata().withNewSpec(). + addToTags(0, new TagReferenceBuilder() + .withName("latest") + .withFrom(new ObjectReferenceBuilder() + .withKind("DockerImage") + .withName("quay.io/wildfly/wildfly-runtime:latest") + .build()) + .build()). + withLookupPolicy(new ImageLookupPolicy(Boolean.TRUE)).endSpec().build(); + osClient.imageStreams().resource(runtimeStream).createOr(NonDeletingOperation::update); + ImageStream appStream = new ImageStreamBuilder().withNewMetadata().withName(name). endMetadata().withNewSpec().withLookupPolicy(new ImageLookupPolicy(Boolean.TRUE)).endSpec().build(); - osClient.imageStreams().resource(stream).createOr(NonDeletingOperation::update); - Files.write(target.resolve(name + "-image-stream.yaml"), Serialization.asYaml(stream).getBytes()); + osClient.imageStreams().resource(appStream).createOr(NonDeletingOperation::update); BuildConfigBuilder builder = new BuildConfigBuilder(); ObjectReference ref = new ObjectReference(); ref.setKind("ImageStreamTag"); - ref.setName(name + ":latest"); - BuildConfig buildConfig = builder. + ref.setName(serverImageName + ":latest"); + ImageSourcePath srcPath = new ImageSourcePathBuilder().withSourcePath("/opt/server").withDestinationDir(".").build(); + ImageSource imageSource = new ImageSourceBuilder().withFrom(ref).withPaths(srcPath).build(); + BuildConfig buildConfig2 = builder. withNewMetadata().withName(name + "-build").endMetadata().withNewSpec(). withNewOutput(). withNewTo(). withKind("ImageStreamTag"). withName(name + ":latest").endTo(). - endOutput().withNewStrategy().withNewSourceStrategy().withNewFrom().withKind("DockerImage"). - withName("quay.io/wildfly/wildfly-s2i:latest").endFrom(). - withIncremental(true). - withEnv(new EnvVar().toBuilder().withName("GALLEON_USE_LOCAL_FILE").withValue("true").build()). - endSourceStrategy().endStrategy().withNewSource(). - withType("Binary").endSource().endSpec().build(); - osClient.buildConfigs().resource(buildConfig).createOr(NonDeletingOperation::update); - Files.write(target.resolve(name + "-build-config.yaml"), Serialization.asYaml(buildConfig).getBytes()); + endOutput(). + withNewSource().withType("Binary").withImages(imageSource).endSource(). + withNewStrategy().withNewDockerStrategy().withNewFrom().withKind("ImageStream"). + withName("wildfly-runtime").endFrom(). + withDockerfilePath("./Dockerfile"). + endDockerStrategy().endStrategy().endSpec().build(); + osClient.buildConfigs().resource(buildConfig2).createOr(NonDeletingOperation::update); + Files.write(target.resolve(name + "-build-config.yaml"), Serialization.asYaml(buildConfig2).getBytes()); - Build build = osClient.buildConfigs().withName(name + "-build").instantiateBinary().fromFile(file.toFile()); + Build build = osClient.buildConfigs().withName(name + "-build").instantiateBinary().fromFile(file2.toFile()); CountDownLatch latch = new CountDownLatch(1); try (Watch watcher = osClient.builds().withName(build.getMetadata().getName()).watch(getBuildWatcher(writer, latch))) { latch.await(); diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java b/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java index 9783f1df..70d2be2f 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java @@ -334,8 +334,10 @@ public Integer call() throws Exception { } if (OutputFormat.OPENSHIFT.equals(provision.get())) { String name = null; + Path deploymentsDir = target.resolve("deployments"); + Files.createDirectories(deploymentsDir); for (Path p : deployments) { - Files.copy(p, target.resolve(p.getFileName())); + Files.copy(p, deploymentsDir.resolve(p.getFileName())); int ext = p.getFileName().toString().indexOf("."); name = p.getFileName().toString().substring(0, ext); } From 84d8a5f7c40b16dc3c4e137f3851aea205c1674a Mon Sep 17 00:00:00 2001 From: Jean-Francois Denise Date: Wed, 13 Mar 2024 15:36:23 +0100 Subject: [PATCH 4/5] cleanup 2 phases build --- .../glow/cli/commands/OpenShiftSupport.java | 23 ++++++++++++------- .../glow/cli/commands/ScanCommand.java | 5 +--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java index a461d52a..85a3e166 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java @@ -175,7 +175,7 @@ private static void createAppDeployment(GlowMessageWriter writer, Path target, O } static void deploy(GlowMessageWriter writer, Path target, String appName, Map env, Set layers, Set addOns, boolean ha, - Map extraEnv, Set disabledDeployers) throws Exception { + Map extraEnv, Set disabledDeployers, Path initScript) throws Exception { Map actualEnv = new TreeMap<>(); OpenShiftClient osClient = new KubernetesClientBuilder().build().adapt(OpenShiftClient.class); writer.info("\nConnected to OpenShift cluster"); @@ -232,7 +232,7 @@ static void deploy(GlowMessageWriter writer, Path target, String appName, Map envMap = new HashMap<>(); for(Set envs : scanResults.getSuggestions().getStronglySuggestedConfigurations().values()) { for(Env env : envs) { @@ -351,7 +348,7 @@ public Integer call() throws Exception { } } OpenShiftSupport.deploy(GlowMessageWriter.DEFAULT, target, name == null ? "app-from-wildfly-glow" : name.toLowerCase(), envMap, scanResults.getDiscoveredLayers(), - scanResults.getEnabledAddOns(), haProfile.orElse(false), extraEnv, disableDeployers); + scanResults.getEnabledAddOns(), haProfile.orElse(false), extraEnv, disableDeployers, initScriptFile.orElse(null)); print("@|bold Openshift build and deploy DONE.|@"); } if (content.getDockerImageName() != null) { From 2004f81d19a2916e78b7b5489abdf9b23285b490 Mon Sep 17 00:00:00 2001 From: Jean-Francois Denise Date: Wed, 13 Mar 2024 17:03:50 +0100 Subject: [PATCH 5/5] Add labels to server imageStreams based on layer and fps --- .../glow/cli/commands/OpenShiftSupport.java | 48 +++++++++++++++++++ openshift-deployment/api/pom.xml | 4 ++ 2 files changed, 52 insertions(+) diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java index 85a3e166..af692ee1 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/OpenShiftSupport.java @@ -66,6 +66,12 @@ import java.util.TreeMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import org.jboss.galleon.api.GalleonBuilder; +import org.jboss.galleon.api.Provisioning; +import org.jboss.galleon.api.config.GalleonConfigurationWithLayers; +import org.jboss.galleon.api.config.GalleonFeaturePackConfig; +import org.jboss.galleon.api.config.GalleonProvisioningConfig; +import org.jboss.galleon.config.ConfigId; import org.jboss.galleon.util.IoUtils; import org.jboss.galleon.util.ZipUtils; import org.wildfly.glow.AddOn; @@ -277,6 +283,47 @@ private static String bytesToHex(byte[] hash) { return hexString.toString(); } + static Map createLabels(Path provisioning) throws Exception { + GalleonBuilder provider = new GalleonBuilder(); + Path dir = provisioning.getParent().resolve("tmpHome"); + Files.createDirectory(dir); + StringBuilder layers = new StringBuilder(); + StringBuilder excludedLayers = new StringBuilder(); + StringBuilder fps = new StringBuilder(); + Map labels = new HashMap<>(); + try (Provisioning p = provider.newProvisioningBuilder(provisioning).setInstallationHome(dir).build()) { + GalleonProvisioningConfig config = provider.newProvisioningBuilder(provisioning).setInstallationHome(dir).build().loadProvisioningConfig(provisioning); + GalleonConfigurationWithLayers cl = config.getDefinedConfig(new ConfigId("standalone", "standalone.xml")); + for(String s : cl.getIncludedLayers()) { + labels.put("org.wildfly.glow.layer."+s,""); + } + for(String s : cl.getExcludedLayers()) { + labels.put("org.wildfly.glow.excluded.layer."+s,""); + } + for (GalleonFeaturePackConfig gfpc : config.getFeaturePackDeps()) { + if (fps.length() != 0) { + fps.append("_"); + } + String producerName = gfpc.getLocation().getProducerName(); + producerName = producerName.replaceAll("::zip", ""); + int i = producerName.indexOf(":"); + if(i > 0) { + producerName = producerName.substring(i+1); + } + producerName = producerName.replaceAll(":", "-"); + labels.put("org.wildfly.glow.feature-pack."+producerName,""); + } + } + return labels; + } + + private static String format(String label) { + if (label.length() > 63) { + label = label.substring(0, 56); + label += ".trunc"; + } + return label; + } static String doServerImageBuild(GlowMessageWriter writer, Path target, OpenShiftClient osClient) throws Exception { Path provisioning = target.resolve("galleon").resolve("provisioning.xml"); byte[] content = Files.readAllBytes(provisioning); @@ -302,6 +349,7 @@ static String doServerImageBuild(GlowMessageWriter writer, Path target, OpenShif Files.createDirectories(stepOne); IoUtils.copy(target.resolve("galleon"), stepOne.resolve("galleon")); ZipUtils.zip(stepOne, file); + stream = stream.toBuilder().editOrNewMetadata().withLabels(createLabels(provisioning)).endMetadata().build(); osClient.imageStreams().resource(stream).createOr(NonDeletingOperation::update); Files.write(target.resolve(serverImageName + "-image-stream.yaml"), Serialization.asYaml(stream).getBytes()); BuildConfigBuilder builder = new BuildConfigBuilder(); diff --git a/openshift-deployment/api/pom.xml b/openshift-deployment/api/pom.xml index 40098953..0a184124 100644 --- a/openshift-deployment/api/pom.xml +++ b/openshift-deployment/api/pom.xml @@ -15,6 +15,10 @@ ${project.groupId} wildfly-glow-core + + org.jboss.galleon + galleon-api + io.fabric8 openshift-client