Skip to content

Commit

Permalink
Fix Openshift deployments when using a custom output directory
Browse files Browse the repository at this point in the history
There were two issues:
- The resources were not found when using the container image openshift and container image s2i. 
- The resources were not found at installing them in the cluster.

Fix quarkusio#34673
  • Loading branch information
Sgitario committed Jul 24, 2023
1 parent 2da3206 commit 7357d78
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ public void openshiftBuildFromJar(OpenshiftConfig openshiftConfig,

Optional<GeneratedFileSystemResourceBuildItem> openshiftYml = generatedResources
.stream()
.filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml"))
.filter(r -> r.getName().endsWith(File.separator + "openshift.yml"))
.findFirst();

if (openshiftYml.isEmpty()) {
Expand Down Expand Up @@ -336,7 +336,7 @@ public void openshiftBuildFromNative(OpenshiftConfig openshiftConfig, S2iConfig
+ kubernetesClient.getMasterUrl() + " in namespace:" + namespace + ".");
Optional<GeneratedFileSystemResourceBuildItem> openshiftYml = generatedResources
.stream()
.filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml"))
.filter(r -> r.getName().endsWith(File.separator + "openshift.yml"))
.findFirst();

if (openshiftYml.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public void s2iBuildFromJar(S2iConfig s2iConfig, ContainerImageConfig containerI

Optional<GeneratedFileSystemResourceBuildItem> openshiftYml = generatedResources
.stream()
.filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml"))
.filter(r -> r.getName().endsWith(File.separator + "openshift.yml"))
.findFirst();

if (openshiftYml.isEmpty()) {
Expand Down Expand Up @@ -241,7 +241,7 @@ public void s2iBuildFromNative(S2iConfig s2iConfig, ContainerImageConfig contain

Optional<GeneratedFileSystemResourceBuildItem> openshiftYml = generatedResources
.stream()
.filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml"))
.filter(r -> r.getName().endsWith(File.separator + "openshift.yml"))
.findFirst();

if (openshiftYml.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import static io.quarkus.kubernetes.deployment.Constants.CRONJOB;
import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT;
import static io.quarkus.kubernetes.deployment.Constants.JOB;
import static io.quarkus.kubernetes.deployment.Constants.KUBERNETES;
import static io.quarkus.kubernetes.deployment.Constants.STATEFULSET;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -614,4 +617,17 @@ public KubernetesConfig.DeploymentResourceKind getDeploymentResourceKind(Capabil

return DeploymentResourceKind.Deployment;
}

/**
* Resolve the effective output directory where to generate the Kubernetes manifests.
* If the `quarkus.kubernetes.output-directory` property is not provided, then the default project output directory will be
* used.
*
* @param projectOutputDirectory The project output target.
* @return the effective output directory.
*/
public Path getEffectiveOutputDirectory(Path projectOutputDirectory) {
return outputDirectory.map(d -> Paths.get("").toAbsolutePath().resolve(d))
.orElse(projectOutputDirectory.resolve(KUBERNETES));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public void deploy(KubernetesClientBuildItem kubernetesClientBuilder,
List<KubernetesDeploymentClusterBuildItem> deploymentClusters,
Optional<SelectedKubernetesDeploymentTargetBuildItem> selectedDeploymentTarget,
OutputTargetBuildItem outputTarget,
KubernetesConfig kubernetesConfig,
OpenshiftConfig openshiftConfig,
ContainerImageConfig containerImageConfig,
ApplicationInfoBuildItem applicationInfo,
Expand Down Expand Up @@ -137,7 +138,8 @@ public void deploy(KubernetesClientBuildItem kubernetesClientBuilder,

try (final KubernetesClient client = kubernetesClientBuilder.buildClient()) {
deploymentResult
.produce(deploy(selectedDeploymentTarget.get().getEntry(), client, outputTarget.getOutputDirectory(),
.produce(deploy(selectedDeploymentTarget.get().getEntry(), client,
kubernetesConfig.getEffectiveOutputDirectory(outputTarget.getOutputDirectory()),
openshiftConfig, applicationInfo, optionalResourceDefinitions));
}
}
Expand Down Expand Up @@ -191,8 +193,7 @@ private DeploymentResultBuildItem deploy(DeploymentTargetEntry deploymentTarget,
String namespace = Optional.ofNullable(client.getNamespace()).orElse("default");
log.info("Deploying to " + deploymentTarget.getName().toLowerCase() + " server: " + client.getMasterUrl()
+ " in namespace: " + namespace + ".");
File manifest = outputDir.resolve(KUBERNETES).resolve(deploymentTarget.getName().toLowerCase() + ".yml")
.toFile();
File manifest = outputDir.resolve(deploymentTarget.getName().toLowerCase() + ".yml").toFile();

try (FileInputStream fis = new FileInputStream(manifest)) {
KubernetesList list = Serialization.unmarshalAsList(fis);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,7 @@ public void build(ApplicationInfoBuildItem applicationInfo,
}
});

Path targetDirectory = kubernetesConfig.outputDirectory.map(d -> Paths.get("").toAbsolutePath().resolve(d))
.orElse(outputTarget.getOutputDirectory().resolve(KUBERNETES));
Path targetDirectory = kubernetesConfig.getEffectiveOutputDirectory(outputTarget.getOutputDirectory());

// write the generated resources to the filesystem
generatedResourcesMap = session.close();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# ensure that an attempt to deploy is made, but that the attempt fails (as we don't want to deploy this test application to a cluster that the runner of test may have configured)
invoker.goals=clean package -Dquarkus.kubernetes.output-directory=woo -Dquarkus.kubernetes.deploy=true ${kubernetes-client-api-server-url}
# expect a failure since there is no Kubernetes cluster to deploy to
invoker.buildResult = ${build-result}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>openshift-with-output-directory-build-and-deploy</artifactId>
<version>0.1-SNAPSHOT</version>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<surefire-plugin.version>3.0.0</surefire-plugin.version>
<maven.compiler.source>11</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId>
<version>@project.version@</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-openshift</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${native.surefire.skip}</skipTests>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.acme;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class Hello {

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Configuration file
# key = value
quarkus.kubernetes.deployment-target=openshift
quarkus.kubernetes-client.trust-certs=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import io.dekorate.utils.Serialization
import io.fabric8.kubernetes.api.model.KubernetesList
import io.fabric8.openshift.api.model.*

//Check that file exits
String base = basedir
File openshiftYml = new File(base, "woo/openshift.yml")
assert openshiftYml.exists()
openshiftYml.withInputStream { stream ->
//Check that its parse-able
KubernetesList list = Serialization.unmarshalAsList(stream)
assert list != null

BuildConfig buildConfig = list.items.find{r -> r.kind == "BuildConfig"}

//Check that ti contains a Deployment named after the project
assert buildConfig != null
assert buildConfig.metadata.name == "openshift-with-output-directory-build-and-deploy"
}

0 comments on commit 7357d78

Please sign in to comment.