Skip to content

Commit

Permalink
Merge pull request #54 from jfdenise/main
Browse files Browse the repository at this point in the history
Openshift cleanup, add todo-backend.war example
  • Loading branch information
jfdenise authored Mar 20, 2024
2 parents a03c59f + 8f5fb39 commit 1a861fd
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 44 deletions.
1 change: 1 addition & 0 deletions cli/assembly.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<outputDirectory>examples</outputDirectory>
<includes>
<include>kitchensink.war</include>
<include>todo-backend.war</include>
</includes>
</fileSet>
<fileSet>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import io.fabric8.kubernetes.client.Watcher;
import io.fabric8.kubernetes.client.WatcherException;
import io.fabric8.kubernetes.client.dsl.NonDeletingOperation;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.openshift.api.model.Build;
import io.fabric8.openshift.api.model.BuildConfig;
import io.fabric8.openshift.api.model.BuildConfigBuilder;
Expand All @@ -54,7 +53,6 @@
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;
Expand All @@ -78,7 +76,7 @@
import org.wildfly.glow.GlowMessageWriter;
import org.wildfly.glow.Layer;
import org.wildfly.glow.deployment.openshift.api.Deployer;

import org.wildfly.glow.deployment.openshift.api.Utils;
/**
*
* @author jdenise
Expand Down Expand Up @@ -123,7 +121,7 @@ private static void createAppDeployment(GlowMessageWriter writer, Path target, O
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());
Utils.persistResource(target, pingService, name + "-ping-service.yaml");
}
Container container = new Container();
container.setName(name);
Expand Down Expand Up @@ -166,15 +164,15 @@ private static void createAppDeployment(GlowMessageWriter writer, Path target, O
withContainers(container).withRestartPolicy("Always").
endSpec().endTemplate().withNewStrategy().withType("RollingUpdate").endStrategy().endSpec().build();
osClient.resources(Deployment.class).resource(deployment).createOr(NonDeletingOperation::update);
Files.write(target.resolve(name + "-deployment.yaml"), Serialization.asYaml(deployment).getBytes());
Utils.persistResource(target, deployment, name + "-deployment.yaml");
IntOrString v = new IntOrString();
v.setValue(8080);
Service service = new ServiceBuilder().withNewMetadata().withName(name).endMetadata().
withNewSpec().withPorts(new ServicePort().toBuilder().withProtocol("TCP").
withPort(8080).
withTargetPort(v).build()).withType("ClusterIP").withSessionAffinity("None").withSelector(labels).endSpec().build();
osClient.services().resource(service).createOr(NonDeletingOperation::update);
Files.write(target.resolve(name + "-service.yaml"), Serialization.asYaml(service).getBytes());
Utils.persistResource(target, service, name + "-service.yaml");

writer.info("Waiting until the application is ready ...");
osClient.resources(Deployment.class).resource(deployment).waitUntilReady(5, TimeUnit.MINUTES);
Expand All @@ -192,7 +190,7 @@ static void deploy(GlowMessageWriter writer, Path target, String appName, Map<St
withTls(new TLSConfig().toBuilder().withTermination("edge").
withInsecureEdgeTerminationPolicy("Redirect").build()).endSpec().build();
osClient.routes().resource(route).createOr(NonDeletingOperation::update);
Files.write(target.resolve(appName + "-route.yaml"), Serialization.asYaml(route).getBytes());
Utils.persistResource(target, route, appName + "-route.yaml");
String host = osClient.routes().resource(route).get().getSpec().getHost();
// Done route creation
Map<String, Deployer> existingDeployers = new HashMap<>();
Expand Down Expand Up @@ -243,13 +241,14 @@ static void deploy(GlowMessageWriter writer, Path target, String appName, Map<St
actualEnv.putAll(extraEnv);
if (!actualEnv.isEmpty()) {
if (!disabledDeployers.isEmpty()) {
writer.warn("\nThe following environment variables have been set in the " + appName + " deployment. WARN: Some of them need possibly to be updated in the deployment:");
writer.warn("\nThe following environment variables have been set in the " + appName + " deployment. WARN: Some of them need possibly to be updated in the deployment:\n");
} else {
writer.warn("\nThe following environment variables have been set in the " + appName + " deployment:");
writer.warn("\nThe following environment variables have been set in the " + appName + " deployment:\n");
}
for (Entry<String, String> entry : actualEnv.entrySet()) {
writer.warn(entry.getKey() + "=" + entry.getValue());
}
writer.warn("\n");
}
createAppDeployment(writer, target, osClient, appName, actualEnv, ha);
writer.info("\nApplication route: https://" + host + ("ROOT.war".equals(appName) ? "" : "/" + appName));
Expand Down Expand Up @@ -283,12 +282,10 @@ private static String bytesToHex(byte[] hash) {
return hexString.toString();
}

static Map<String, String> createLabels(Path provisioning) throws Exception {
static Map<String, String> createLabels(Path target, Path provisioning) throws Exception {
GalleonBuilder provider = new GalleonBuilder();
Path dir = provisioning.getParent().resolve("tmpHome");
Path dir = target.resolve("tmp").resolve("tmpHome");
Files.createDirectory(dir);
StringBuilder layers = new StringBuilder();
StringBuilder excludedLayers = new StringBuilder();
StringBuilder fps = new StringBuilder();
Map<String, String> labels = new HashMap<>();
try (Provisioning p = provider.newProvisioningBuilder(provisioning).setInstallationHome(dir).build()) {
Expand Down Expand Up @@ -317,13 +314,6 @@ static Map<String, String> createLabels(Path provisioning) throws Exception {
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);
Expand All @@ -339,19 +329,18 @@ static String doServerImageBuild(GlowMessageWriter writer, Path target, OpenShif
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");
Path file = target.resolve("tmp").resolve("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");
Path stepOne = target.resolve("tmp").resolve("step-one");
Files.createDirectories(stepOne);
IoUtils.copy(target.resolve("galleon"), stepOne.resolve("galleon"));
ZipUtils.zip(stepOne, file);
stream = stream.toBuilder().editOrNewMetadata().withLabels(createLabels(provisioning)).endMetadata().build();
stream = stream.toBuilder().editOrNewMetadata().withLabels(createLabels(target, provisioning)).endMetadata().build();
osClient.imageStreams().resource(stream).createOr(NonDeletingOperation::update);
Files.write(target.resolve(serverImageName + "-image-stream.yaml"), Serialization.asYaml(stream).getBytes());
Utils.persistResource(target, stream, serverImageName + "-image-stream.yaml");
BuildConfigBuilder builder = new BuildConfigBuilder();
ObjectReference ref = new ObjectReference();
ref.setKind("ImageStreamTag");
Expand All @@ -369,7 +358,7 @@ static String doServerImageBuild(GlowMessageWriter writer, Path target, OpenShif
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());
Utils.persistResource(target, buildConfig, serverImageName + "-build-config.yaml");

Build build = osClient.buildConfigs().withName(serverImageName + "-build").instantiateBinary().fromFile(file.toFile());
CountDownLatch latch = new CountDownLatch(1);
Expand All @@ -383,7 +372,7 @@ static String doServerImageBuild(GlowMessageWriter writer, Path target, OpenShif
static void doAppImageBuild(String serverImageName, GlowMessageWriter writer, Path target, OpenShiftClient osClient, String name, Path initScript) throws Exception {
// 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");
Path stepTwo = target.resolve("tmp").resolve("step-two");
IoUtils.copy(target.resolve("deployments"), stepTwo.resolve("deployments"));
StringBuilder dockerFileBuilder = new StringBuilder();
dockerFileBuilder.append("FROM wildfly-runtime:latest\n");
Expand All @@ -400,12 +389,12 @@ static void doAppImageBuild(String serverImageName, GlowMessageWriter writer, Pa

Path dockerFile = stepTwo.resolve("Dockerfile");
Files.write(dockerFile, dockerFileBuilder.toString().getBytes());
Path file2 = Paths.get("openshiftApp.zip");
Path file2 = target.resolve("tmp").resolve("openshiftApp.zip");
if (Files.exists(file2)) {
Files.delete(file2);
}
ZipUtils.zip(stepTwo, file2);
writer.info("\nCreating and starting application image build on OpenShift...");
writer.info("\nBuilding application image...");
ImageStream runtimeStream = new ImageStreamBuilder().withNewMetadata().withName("wildfly-runtime").
endMetadata().withNewSpec().
addToTags(0, new TagReferenceBuilder()
Expand Down Expand Up @@ -439,7 +428,7 @@ static void doAppImageBuild(String serverImageName, GlowMessageWriter writer, Pa
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());
Utils.persistResource(target, buildConfig2, name + "-build-config.yaml");

Build build = osClient.buildConfigs().withName(name + "-build").instantiateBinary().fromFile(file2.toFile());
CountDownLatch latch = new CountDownLatch(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,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, initScriptFile.orElse(null));
print("@|bold Openshift build and deploy DONE.|@");
print("@|bold \nOpenshift build and deploy DONE.|@");
}
if (content.getDockerImageName() != null) {
print("@|bold To run the image call: 'docker run " + content.getDockerImageName() + "'|@");
Expand Down
19 changes: 18 additions & 1 deletion dist/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,21 @@ This war comes from the WildFly https://github.com/wildfly/quickstart/tree/30.0.

=== To provision a WildFly server for the cloud and produce a Docker image:

`./wildfly-glow scan ./examples/kitchensink.war --provision=DOCKER_IMAGE --cloud`
`./wildfly-glow scan ./examples/kitchensink.war --provision=DOCKER_IMAGE --cloud`

=== To provision a WildFly server for the cloud and directly deploy to OpenShift cluster:

You must first log into an OpenShift cluster.

`./wildfly-glow scan ./examples/kitchensink.war --provision=OPENSHIFT --cloud`

== ToDo backend example

This war comes from the WildFly https://github.com/wildfly/quickstart/tree/30.0.0.Final/todo-backend[todo-backend] quickstart.

=== To provision a WildFly server for the cloud and directly deploy to OpenShift cluster:

You must first log into an OpenShift cluster.
In this case, a `postgresql` database is started. The WildFly server automatically connects to it.

`./wildfly-glow scan ./examples/todo-backend.war --provision=OPENSHIFT --cloud --add-ons postgresql`
2 changes: 2 additions & 0 deletions docs/guide/intro/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ 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 OpenShift resources yaml files are generated in the directory `server-<wildfly version>/resources`

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
Expand Down
Binary file added examples/war/todo-backend.war
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
import io.fabric8.kubernetes.client.dsl.NonDeletingOperation;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.openshift.client.OpenShiftClient;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -103,7 +101,6 @@ private Map<String, String> getExistingEnv(Map<String, String> env) {
@Override
public Map<String, String> deploy(GlowMessageWriter writer, Path target, OpenShiftClient osClient,
Map<String, String> env, String appHost, String appName, String matching) throws Exception {
writer.info("\nDeploying " + dbName + " server");
Map<String, String> labels = new HashMap<>();
labels.put(LABEL, dbName);
ContainerPort port = new ContainerPort();
Expand All @@ -129,18 +126,19 @@ public Map<String, String> deploy(GlowMessageWriter writer, Path target, OpenShi
withContainers(container).withRestartPolicy("Always").
endSpec().endTemplate().withNewStrategy().withType("RollingUpdate").endStrategy().endSpec().build();
osClient.resources(Deployment.class).resource(deployment).createOr(NonDeletingOperation::update);
Files.write(target.resolve(dbName + "-deployment.yaml"), Serialization.asYaml(deployment).getBytes());
Utils.persistResource(target, deployment, dbName + "-deployment.yaml");
IntOrString v = new IntOrString();
v.setValue(this.port);
Service service = new ServiceBuilder().withNewMetadata().withName(dbName).endMetadata().
withNewSpec().withPorts(new ServicePort().toBuilder().withName(this.port + "-tcp").withProtocol("TCP").
withPort(this.port).
withTargetPort(v).build()).withType("ClusterIP").withSessionAffinity("None").withSelector(labels).endSpec().build();
osClient.services().resource(service).createOr(NonDeletingOperation::update);
Files.write(target.resolve(dbName + "-service.yaml"), Serialization.asYaml(service).getBytes());
Utils.persistResource(target, service, dbName + "-service.yaml");
Map<String, String> ret = new HashMap<>();
ret.putAll(getExistingEnv(env));
ret.putAll(APP_MAP);
writer.info("\n" + dbName + " server has been deployed");
return ret;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2024 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wildfly.glow.deployment.openshift.api;

import io.fabric8.kubernetes.client.utils.Serialization;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

/**
*
* @author jdenise
*/
public class Utils {

public static void persistResource(Path target, Object resource, String name) throws IOException {
Path dir = target.resolve("resources");
Files.createDirectories(dir);
Path resourceFile = dir.resolve(name);
Files.write(resourceFile, Serialization.asYaml(resource).getBytes());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
import io.fabric8.kubernetes.client.dsl.NonDeletingOperation;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.openshift.client.OpenShiftClient;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -39,6 +37,7 @@
import java.util.Set;
import org.wildfly.glow.GlowMessageWriter;
import org.wildfly.glow.deployment.openshift.api.Deployer;
import org.wildfly.glow.deployment.openshift.api.Utils;

/**
*
Expand Down Expand Up @@ -96,15 +95,15 @@ public Map<String, String> deploy(GlowMessageWriter writer, Path target, OpenShi
withContainers(container).withRestartPolicy("Always").
endSpec().endTemplate().withNewStrategy().withType("RollingUpdate").endStrategy().endSpec().build();
osClient.resources(Deployment.class).resource(deployment).createOr(NonDeletingOperation::update);
Files.write(target.resolve(REMOTE_BROKER_NAME + "-deployment.yaml"), Serialization.asYaml(deployment).getBytes());
Utils.persistResource(target, deployment, REMOTE_BROKER_NAME + "-deployment.yaml");
IntOrString v = new IntOrString();
v.setValue(61616);
Service service = new ServiceBuilder().withNewMetadata().withName(REMOTE_BROKER_NAME).endMetadata().
withNewSpec().withPorts(new ServicePort().toBuilder().withName("61616-tcp").withProtocol("TCP").
withPort(61616).
withTargetPort(v).build()).withType("ClusterIP").withSessionAffinity("None").withSelector(labels).endSpec().build();
osClient.services().resource(service).createOr(NonDeletingOperation::update);
Files.write(target.resolve(REMOTE_BROKER_NAME + "-service.yaml"), Serialization.asYaml(service).getBytes());
Utils.persistResource(target, service, REMOTE_BROKER_NAME + "-service.yaml");
Map<String, String> ret = new HashMap<>();
ret.putAll(REMOTE_BROKER_APP_MAP);
return REMOTE_BROKER_APP_MAP;
Expand Down
Loading

0 comments on commit 1a861fd

Please sign in to comment.