Skip to content

Commit

Permalink
Merge pull request quarkusio#7356 from iocanel/openshift-extension
Browse files Browse the repository at this point in the history
Create openshift wrapper extension.
  • Loading branch information
maxandersen authored Feb 27, 2020
2 parents a809292 + c6bcc8c commit 3aa36b5
Show file tree
Hide file tree
Showing 58 changed files with 512 additions and 88 deletions.
5 changes: 5 additions & 0 deletions bom/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,11 @@
<artifactId>quarkus-kubernetes-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-openshift-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes-spi</artifactId>
Expand Down
5 changes: 5 additions & 0 deletions bom/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,11 @@
<artifactId>quarkus-kubernetes</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-openshift</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes-client</artifactId>
Expand Down
4 changes: 3 additions & 1 deletion docs/src/main/asciidoc/kubernetes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Generating Kubernetes resources
= Quarkus - Kubernetes extension

include::./attributes.adoc[]

Expand Down Expand Up @@ -387,6 +387,8 @@ If you need to generate resources for both platforms (vanilla Kubernetes and Ope
quarkus.kubernetes.deployment-target=kubernetes, openshift
----

Note: In latest versions of Quarkus a wrapper extension of link:openshift[Openshift] is provided. If you use it, there is no need to explicitly set this property.

The OpenShift resources can be customized in a similar approach with Kubernetes.

.Openshift
Expand Down
186 changes: 186 additions & 0 deletions docs/src/main/asciidoc/openshift.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Openshift extension

include::./attributes.adoc[]

This guide covers generating and deploying Openshift resources based on sane default and user supplied configuration.


== Prerequisites

To complete this guide, you need:

* roughly 5 minutes
* an IDE
* JDK 1.8+ installed with `JAVA_HOME` configured appropriately
* Apache Maven 3.5.3+
* access to an Openshift or cluster (Minishift is a viable options)

== Creating the Maven project

First, we need a new project that contains the Openshift extension. This can be done using the following command:

[source, subs=attributes+]
----
mvn io.quarkus:quarkus-maven-plugin:{quarkus-version}:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=openshift-quickstart \
-DclassName="org.acme.rest.GreetingResource" \
-Dpath="/greeting" \
-Dextensions="openshift"
cd openshift-quickstart
----

=== Openshift

Quarkus offers the ability to automatically generate Openshift resources based on sane default and user supplied configuration.
The Openshift extension is actually a wrapper extension that brings together the link:kubernetes[kubernetes] and link:container-image-s2i[container-image-s2i]
extensions with sensible defaults so that it's easier for the user to get started with Quarkus on Openshift.

When we added the `openshift` extension to the command line invocation above, the following dependency was added to the `pom.xml`

[source,xml]
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-openshift</artifactId>
</dependency>
----

By adding this dependency, we now have the ability to configure the Openshift resource generation and application using the usual `application.properties` approach that Quarkus provides.
The configuration items that are available can be found in: `io.quarkus.kubernetes.deployment.OpenshiftConfig` class.
Furthermore, the items provided by `io.quarkus.deployment.ApplicationConfig` affect the Openshift resources.

=== Building

Building is handled by the link:container-image#s2i[container-image-s2i] extension. To trigger a build:

[source, subs=attributes+]
----
mvn clean package -Dquarkus.container-image.build=true
----

The command above will trigger an s2i binary build.

=== Deploying

To trigger a deployment:

[source, subs=attributes+]
----
mvn clean package -Dquarkus.kubernetes.deploy=true
----

The command above will trigger a container image build and will apply the generated Openshift resources, right after.
The generated resources are using Openshift's `DeploymentConfig` that is configured to automatically trigger a redeployment when a change in the `ImageStream` is noticed.
In other words, any container image build after the inital deployment will automatically trigger redeployment, without the need to delete, update or re-apply the generated resources.

=== Customizing

All available customization options are available in the link:kubenretes#openshift[Openshift configuration options].

Some examples are provided in the sections below:

==== Exposing Routes

To expose a `Route` for the Quarkus application:

[source]
----
quarkus.openshift.expose=true
----

Tip: You don't necesserily need to add this property in the `application.properties`. You can pass it as a command line argument:

[source, subs=attributes+]
----
mvn clean package -Dquarkus.openshift.expose=true
----

The same applies to all properties listed below.

==== Labels

To add a label in the generated resources:

[source]
----
quarkus.openshift.labels.foo=bar
----

==== Annotations

To add an annotation in the generated resources:

[source]
----
quarkus.openshift.annotations.foo=bar
----

==== Environment variables

To add an annotation in the generated resources:

[source]
----
quarkus.openshift.env-vars.my-env-var.value=foobar
----

The command above will add `MY_ENV_VAR=foobar` as an environment variable.
Please note that the key `my-env-var` will be converted to uppercase and dashes will be replaced by underscores resulting in `MY_ENV_VAR`.

You may also noticed that in contrast to labels, and annotations for environment variables you don't just use a key=value approach.
That is because for environment variables there are additional options rather than just value.

===== Environment variables from Secret

To add all key value pairs of a `Secret` as environment variables:

[source]
----
quarkus.openshift.env-vars.my-env-var.secret=my-secret
----

===== Environment variables from ConfigMap

To add all key value pairs of a `ConfigMap` as environment variables:

[source]
----
quarkus.openshift.env-vars.my-env-var.configmap=my-secret
----


==== Mounting volumes

The Openshift extension allows the user to configure both volumes and mounts for the application.

Any volume can be mounted with a simple configuration:

[source]
----
quarkus.openshift.mounts.my-volume.path=/where/to/mount
----

This will add a mount to my pod for volume `my-voume` to path `/where/to/mount`

The volumes themselves can be configured as shown in the sections below:

===== Secret volumes

[source]
----
quarkus.openshift.secret-volumes.my-volume.secret-name=my-secret
----

===== ConfigMap volumes

[source]
----
quarkus.openshift.config-map-volumes.my-volume.config-map-name=my-secret
----
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
public class DockerProcessor {

private static final Logger log = Logger.getLogger(DockerProcessor.class);
private static final String DOCKER = "docker";
private static final String DOCKERFILE_JVM = "Dockerfile.jvm";
private static final String DOCKERFILE_NATIVE = "Dockerfile.native";

Expand Down Expand Up @@ -65,7 +66,7 @@ public void dockerBuildFromJar(DockerConfig dockerConfig,
createContainerImage(containerImageConfig, dockerConfig, image, out, reader, false, pushRequest.isPresent());

artifactResultProducer.produce(new ArtifactResultBuildItem(null, "jar-container", Collections.emptyMap()));
containerImageResultProducer.produce(new ContainerImageResultBuildItem(reader.getImageId(),
containerImageResultProducer.produce(new ContainerImageResultBuildItem(DOCKER, reader.getImageId(),
ImageUtil.getRepository(image), ImageUtil.getTag(image)));
}

Expand Down Expand Up @@ -99,7 +100,7 @@ public void dockerBuildFromNativeImage(DockerConfig dockerConfig,
createContainerImage(containerImageConfig, dockerConfig, image, out, reader, true, pushRequest.isPresent());
artifactResultProducer.produce(new ArtifactResultBuildItem(null, "native-container", Collections.emptyMap()));
containerImageResultProducer
.produce(new ContainerImageResultBuildItem(reader.getImageId(), ImageUtil.getRepository(image),
.produce(new ContainerImageResultBuildItem(DOCKER, reader.getImageId(), ImageUtil.getRepository(image),
ImageUtil.getTag(image)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public class JibProcessor {

private static final Logger log = Logger.getLogger(JibProcessor.class);

private static final String JIB = "jib";
private static final IsClassPredicate IS_CLASS_PREDICATE = new IsClassPredicate();
private static final String BINARY_NAME_IN_CONTAINER = "application";

Expand All @@ -77,7 +78,7 @@ public void buildFromJar(ContainerImageConfig containerImageConfig, JibConfig ji
pushRequest.isPresent());

ImageReference targetImage = container.getTargetImage();
containerImageResultProducer.produce(new ContainerImageResultBuildItem(container.getImageId().getHash(),
containerImageResultProducer.produce(new ContainerImageResultBuildItem(JIB, container.getImageId().getHash(),
targetImage.getRepository(), targetImage.getTag()));
artifactResultProducer.produce(new ArtifactResultBuildItem(null, "jar-container", Collections.emptyMap()));
}
Expand Down Expand Up @@ -106,7 +107,7 @@ public void buildFromNative(ContainerImageConfig containerImageConfig, JibConfig
pushRequest.isPresent());

ImageReference targetImage = container.getTargetImage();
containerImageResultProducer.produce(new ContainerImageResultBuildItem(container.getImageId().getHash(),
containerImageResultProducer.produce(new ContainerImageResultBuildItem(JIB, container.getImageId().getHash(),
targetImage.getRepository(), targetImage.getTag()));
artifactResultProducer.produce(new ArtifactResultBuildItem(null, "native-container", Collections.emptyMap()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@

public class S2iProcessor {

private static final String S2I = "s2i";
private static final String JAR_ARTIFACT_FORMAT = "%s%s.jar";
private static final String NATIVE_ARTIFACT_FORMAT = "%s%s";

Expand Down Expand Up @@ -143,7 +144,7 @@ public void s2iBuildFromJar(S2iConfig s2iConfig, ContainerImageConfig containerI
out.getOutputDirectory().resolve("lib"));
artifactResultProducer.produce(new ArtifactResultBuildItem(null, "jar-container", Collections.emptyMap()));
containerImageResultProducer.produce(
new ContainerImageResultBuildItem(null, ImageUtil.getRepository(image), ImageUtil.getTag(image)));
new ContainerImageResultBuildItem(S2I, null, ImageUtil.getRepository(image), ImageUtil.getTag(image)));
}

@BuildStep(onlyIf = { IsNormal.class, S2iBuild.class, NativeBuild.class })
Expand Down Expand Up @@ -188,7 +189,7 @@ public void s2iBuildFromNative(S2iConfig s2iConfig, ContainerImageConfig contain
createContainerImage(kubernetesClient, openshiftYml, s2iConfig, out.getOutputDirectory(), applicationImagePath);
artifactResultProducer.produce(new ArtifactResultBuildItem(null, "native-container", Collections.emptyMap()));
containerImageResultProducer.produce(
new ContainerImageResultBuildItem(null, ImageUtil.getRepository(image), ImageUtil.getTag(image)));
new ContainerImageResultBuildItem(S2I, null, ImageUtil.getRepository(image), ImageUtil.getTag(image)));
}

public static void createContainerImage(KubernetesClientBuildItem kubernetesClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@

public final class ContainerImageResultBuildItem extends SimpleBuildItem {

private final String provider;
private final String imageId;
private final String repository;
private final String tag;

public ContainerImageResultBuildItem(String imageId, String repository, String tag) {
public ContainerImageResultBuildItem(String provider, String imageId, String repository, String tag) {
this.provider = provider;
this.imageId = imageId;
this.repository = repository;
this.tag = tag;
}

public String getProvider() {
return this.provider;
}

public String getImageId() {
return this.imageId;
}
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 3aa36b5

Please sign in to comment.