diff --git a/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java b/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java index 256a45aec62a1..00236e4da2849 100644 --- a/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java +++ b/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java @@ -231,7 +231,7 @@ public void openshiftRequirementsNative(OpenshiftConfig openshiftConfig, public void openshiftBuildFromJar(OpenshiftConfig openshiftConfig, S2iConfig s2iConfig, ContainerImageConfig containerImageConfig, - KubernetesClientBuildItem kubernetesClient, + KubernetesClientBuildItem kubernetesClientSupplier, ContainerImageInfoBuildItem containerImage, ArchiveRootBuildItem archiveRoot, OutputTargetBuildItem out, PackageConfig packageConfig, List generatedResources, @@ -263,26 +263,28 @@ public void openshiftBuildFromJar(OpenshiftConfig openshiftConfig, return; } - String namespace = Optional.ofNullable(kubernetesClient.getClient().getNamespace()).orElse("default"); - LOG.info("Starting (in-cluster) container image build for jar using: " + config.buildStrategy + " on server: " - + kubernetesClient.getClient().getMasterUrl() + " in namespace:" + namespace + "."); - //The contextRoot is where inside the tarball we will add the jars. A null value means everything will be added under '/' while "target" means everything will be added under '/target'. - //For docker kind of builds where we use instructions like: `COPY target/*.jar /deployments` it using '/target' is a requirement. - //For s2i kind of builds where jars are expected directly in the '/' we have to use null. - String outputDirName = out.getOutputDirectory().getFileName().toString(); - String contextRoot = getContextRoot(outputDirName, packageConfig.isFastJar(), config.buildStrategy); - if (packageConfig.isFastJar()) { - createContainerImage(kubernetesClient, openshiftYml.get(), config, contextRoot, jar.getPath().getParent(), - jar.getPath().getParent()); - } else if (jar.getLibraryDir() != null) { //When using uber-jar the libraryDir is going to be null, potentially causing NPE. - createContainerImage(kubernetesClient, openshiftYml.get(), config, contextRoot, jar.getPath().getParent(), - jar.getPath(), jar.getLibraryDir()); - } else { - createContainerImage(kubernetesClient, openshiftYml.get(), config, contextRoot, jar.getPath().getParent(), - jar.getPath()); + try (KubernetesClient kubernetesClient = kubernetesClientSupplier.getClient().get()) { + String namespace = Optional.ofNullable(kubernetesClient.getNamespace()).orElse("default"); + LOG.info("Starting (in-cluster) container image build for jar using: " + config.buildStrategy + " on server: " + + kubernetesClient.getMasterUrl() + " in namespace:" + namespace + "."); + //The contextRoot is where inside the tarball we will add the jars. A null value means everything will be added under '/' while "target" means everything will be added under '/target'. + //For docker kind of builds where we use instructions like: `COPY target/*.jar /deployments` it using '/target' is a requirement. + //For s2i kind of builds where jars are expected directly in the '/' we have to use null. + String outputDirName = out.getOutputDirectory().getFileName().toString(); + String contextRoot = getContextRoot(outputDirName, packageConfig.isFastJar(), config.buildStrategy); + if (packageConfig.isFastJar()) { + createContainerImage(kubernetesClient, openshiftYml.get(), config, contextRoot, jar.getPath().getParent(), + jar.getPath().getParent()); + } else if (jar.getLibraryDir() != null) { //When using uber-jar the libraryDir is going to be null, potentially causing NPE. + createContainerImage(kubernetesClient, openshiftYml.get(), config, contextRoot, jar.getPath().getParent(), + jar.getPath(), jar.getLibraryDir()); + } else { + createContainerImage(kubernetesClient, openshiftYml.get(), config, contextRoot, jar.getPath().getParent(), + jar.getPath()); + } + artifactResultProducer.produce(new ArtifactResultBuildItem(null, "jar-container", Collections.emptyMap())); + containerImageBuilder.produce(new ContainerImageBuilderBuildItem(OPENSHIFT)); } - artifactResultProducer.produce(new ArtifactResultBuildItem(null, "jar-container", Collections.emptyMap())); - containerImageBuilder.produce(new ContainerImageBuilderBuildItem(OPENSHIFT)); } private String getContextRoot(String outputDirName, boolean isFastJar, BuildStrategy buildStrategy) { @@ -298,7 +300,7 @@ private String getContextRoot(String outputDirName, boolean isFastJar, BuildStra @BuildStep(onlyIf = { IsNormalNotRemoteDev.class, OpenshiftBuild.class, NativeBuild.class }) public void openshiftBuildFromNative(OpenshiftConfig openshiftConfig, S2iConfig s2iConfig, ContainerImageConfig containerImageConfig, - KubernetesClientBuildItem kubernetesClient, + KubernetesClientBuildItem kubernetesClientSupplier, ContainerImageInfoBuildItem containerImage, ArchiveRootBuildItem archiveRoot, OutputTargetBuildItem out, PackageConfig packageConfig, List generatedResources, @@ -319,31 +321,33 @@ public void openshiftBuildFromNative(OpenshiftConfig openshiftConfig, S2iConfig return; } - String namespace = Optional.ofNullable(kubernetesClient.getClient().getNamespace()).orElse("default"); + try (KubernetesClient kubernetesClient = kubernetesClientSupplier.getClient().get()) { + String namespace = Optional.ofNullable(kubernetesClient.getNamespace()).orElse("default"); - LOG.info("Starting (in-cluster) container image build for jar using: " + config.buildStrategy + " on server: " - + kubernetesClient.getClient().getMasterUrl() + " in namespace:" + namespace + "."); - Optional openshiftYml = generatedResources - .stream() - .filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml")) - .findFirst(); + LOG.info("Starting (in-cluster) container image build for jar using: " + config.buildStrategy + " on server: " + + kubernetesClient.getMasterUrl() + " in namespace:" + namespace + "."); + Optional openshiftYml = generatedResources + .stream() + .filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml")) + .findFirst(); - if (openshiftYml.isEmpty()) { - LOG.warn( - "No Openshift manifests were generated so no openshift build process will be taking place"); - return; + if (openshiftYml.isEmpty()) { + LOG.warn( + "No Openshift manifests were generated so no openshift build process will be taking place"); + return; + } + //The contextRoot is where inside the tarball we will add the jars. A null value means everything will be added under '/' while "target" means everything will be added under '/target'. + //For docker kind of builds where we use instructions like: `COPY target/*.jar /deployments` it using '/target' is a requirement. + //For s2i kind of builds where jars are expected directly in the '/' we have to use null. + String contextRoot = config.buildStrategy == BuildStrategy.DOCKER ? "target" : null; + createContainerImage(kubernetesClient, openshiftYml.get(), config, contextRoot, out.getOutputDirectory(), + nativeImage.getPath()); + artifactResultProducer.produce(new ArtifactResultBuildItem(null, "native-container", Collections.emptyMap())); + containerImageBuilder.produce(new ContainerImageBuilderBuildItem(OPENSHIFT)); } - //The contextRoot is where inside the tarball we will add the jars. A null value means everything will be added under '/' while "target" means everything will be added under '/target'. - //For docker kind of builds where we use instructions like: `COPY target/*.jar /deployments` it using '/target' is a requirement. - //For s2i kind of builds where jars are expected directly in the '/' we have to use null. - String contextRoot = config.buildStrategy == BuildStrategy.DOCKER ? "target" : null; - createContainerImage(kubernetesClient, openshiftYml.get(), config, contextRoot, out.getOutputDirectory(), - nativeImage.getPath()); - artifactResultProducer.produce(new ArtifactResultBuildItem(null, "native-container", Collections.emptyMap())); - containerImageBuilder.produce(new ContainerImageBuilderBuildItem(OPENSHIFT)); } - public static void createContainerImage(KubernetesClientBuildItem kubernetesClient, + public static void createContainerImage(KubernetesClient kubernetesClient, GeneratedFileSystemResourceBuildItem openshiftManifests, OpenshiftConfig openshiftConfig, String base, @@ -360,7 +364,7 @@ public static void createContainerImage(KubernetesClientBuildItem kubernetesClie throw new RuntimeException("Error creating the openshift binary build archive.", e); } - Config config = kubernetesClient.getClient().getConfiguration(); + Config config = kubernetesClient.getConfiguration(); //Let's disable http2 as it causes issues with duplicate build triggers. config.setHttp2Disable(true); try (KubernetesClient client = Clients.fromConfig(config)) { diff --git a/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java b/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java index 3052fe0666e5a..7585ad2111932 100644 --- a/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java +++ b/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java @@ -171,7 +171,7 @@ public void s2iRequirementsNative(S2iConfig s2iConfig, @BuildStep(onlyIf = { IsNormalNotRemoteDev.class, S2iBuild.class }, onlyIfNot = NativeBuild.class) public void s2iBuildFromJar(S2iConfig s2iConfig, ContainerImageConfig containerImageConfig, - KubernetesClientBuildItem kubernetesClient, + KubernetesClientBuildItem kubernetesClientSupplier, ContainerImageInfoBuildItem containerImage, ArchiveRootBuildItem archiveRoot, OutputTargetBuildItem out, PackageConfig packageConfig, List generatedResources, @@ -201,20 +201,21 @@ public void s2iBuildFromJar(S2iConfig s2iConfig, ContainerImageConfig containerI "No Openshift manifests were generated so no s2i process will be taking place"); return; } - - String namespace = Optional.ofNullable(kubernetesClient.getClient().getNamespace()).orElse("default"); - LOG.info("Performing s2i binary build with jar on server: " + kubernetesClient.getClient().getMasterUrl() - + " in namespace:" + namespace + "."); - - createContainerImage(kubernetesClient, openshiftYml.get(), s2iConfig, out.getOutputDirectory(), jar.getPath(), - out.getOutputDirectory().resolve("lib")); - artifactResultProducer.produce(new ArtifactResultBuildItem(null, "jar-container", Collections.emptyMap())); - containerImageBuilder.produce(new ContainerImageBuilderBuildItem(S2I)); + try (KubernetesClient kubernetesClient = kubernetesClientSupplier.getClient().get()) { + String namespace = Optional.ofNullable(kubernetesClient.getNamespace()).orElse("default"); + LOG.info("Performing s2i binary build with jar on server: " + kubernetesClient.getMasterUrl() + + " in namespace:" + namespace + "."); + + createContainerImage(kubernetesClient, openshiftYml.get(), s2iConfig, out.getOutputDirectory(), jar.getPath(), + out.getOutputDirectory().resolve("lib")); + artifactResultProducer.produce(new ArtifactResultBuildItem(null, "jar-container", Collections.emptyMap())); + containerImageBuilder.produce(new ContainerImageBuilderBuildItem(S2I)); + } } @BuildStep(onlyIf = { IsNormalNotRemoteDev.class, S2iBuild.class, NativeBuild.class }) public void s2iBuildFromNative(S2iConfig s2iConfig, ContainerImageConfig containerImageConfig, - KubernetesClientBuildItem kubernetesClient, + KubernetesClientBuildItem kubernetesClientSupplier, ContainerImageInfoBuildItem containerImage, ArchiveRootBuildItem archiveRoot, OutputTargetBuildItem out, PackageConfig packageConfig, List generatedResources, @@ -233,28 +234,30 @@ public void s2iBuildFromNative(S2iConfig s2iConfig, ContainerImageConfig contain return; } - String namespace = Optional.ofNullable(kubernetesClient.getClient().getNamespace()).orElse("default"); - LOG.info("Performing s2i binary build with native image on server: " + kubernetesClient.getClient().getMasterUrl() - + " in namespace:" + namespace + "."); + try (KubernetesClient kubernetesClient = kubernetesClientSupplier.getClient().get()) { + String namespace = Optional.ofNullable(kubernetesClient.getNamespace()).orElse("default"); + LOG.info("Performing s2i binary build with native image on server: " + kubernetesClient.getMasterUrl() + + " in namespace:" + namespace + "."); - Optional openshiftYml = generatedResources - .stream() - .filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml")) - .findFirst(); + Optional openshiftYml = generatedResources + .stream() + .filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml")) + .findFirst(); - if (openshiftYml.isEmpty()) { - LOG.warn( - "No Openshift manifests were generated so no s2i process will be taking place"); - return; - } + if (openshiftYml.isEmpty()) { + LOG.warn( + "No Openshift manifests were generated so no s2i process will be taking place"); + return; + } - createContainerImage(kubernetesClient, openshiftYml.get(), s2iConfig, out.getOutputDirectory(), - nativeImage.getPath()); - artifactResultProducer.produce(new ArtifactResultBuildItem(null, "native-container", Collections.emptyMap())); - containerImageBuilder.produce(new ContainerImageBuilderBuildItem(S2I)); + createContainerImage(kubernetesClient, openshiftYml.get(), s2iConfig, out.getOutputDirectory(), + nativeImage.getPath()); + artifactResultProducer.produce(new ArtifactResultBuildItem(null, "native-container", Collections.emptyMap())); + containerImageBuilder.produce(new ContainerImageBuilderBuildItem(S2I)); + } } - public static void createContainerImage(KubernetesClientBuildItem kubernetesClient, + public static void createContainerImage(KubernetesClient kubernetesClient, GeneratedFileSystemResourceBuildItem openshiftManifests, S2iConfig s2iConfig, Path output, @@ -270,7 +273,7 @@ public static void createContainerImage(KubernetesClientBuildItem kubernetesClie throw new RuntimeException("Error creating the s2i binary build archive.", e); } - Config config = kubernetesClient.getClient().getConfiguration(); + Config config = kubernetesClient.getConfiguration(); //Let's disable http2 as it causes issues with duplicate build triggers. config.setHttp2Disable(true); try (KubernetesClient client = Clients.fromConfig(config)) { diff --git a/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/KubernetesClientBuildStep.java b/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/KubernetesClientBuildStep.java index a65b82da207ae..6c5bd544cf0cd 100644 --- a/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/KubernetesClientBuildStep.java +++ b/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/KubernetesClientBuildStep.java @@ -13,6 +13,6 @@ public class KubernetesClientBuildStep { @BuildStep public KubernetesClientBuildItem process(TlsConfig tlsConfig) { - return new KubernetesClientBuildItem(createClient(buildConfig, tlsConfig)); + return new KubernetesClientBuildItem(createConfig(buildConfig, tlsConfig)); } } diff --git a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/QuarkusHttpClientFactory.java b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/QuarkusHttpClientFactory.java index 9660b7913b657..31c5c53d2618c 100644 --- a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/QuarkusHttpClientFactory.java +++ b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/QuarkusHttpClientFactory.java @@ -1,12 +1,12 @@ package io.quarkus.kubernetes.client.runtime; +import javax.enterprise.inject.spi.CDI; + import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.http.HttpClient; import io.fabric8.kubernetes.client.vertx.VertxHttpClientBuilder; import io.vertx.core.Vertx; -import javax.enterprise.inject.spi.CDI; - public class QuarkusHttpClientFactory implements io.fabric8.kubernetes.client.http.HttpClient.Factory { private Vertx vertx; diff --git a/extensions/kubernetes-client/spi/src/main/java/io/quarkus/kubernetes/client/spi/KubernetesClientBuildItem.java b/extensions/kubernetes-client/spi/src/main/java/io/quarkus/kubernetes/client/spi/KubernetesClientBuildItem.java index c8f9971b3e03d..b68b3fd113fb1 100644 --- a/extensions/kubernetes-client/spi/src/main/java/io/quarkus/kubernetes/client/spi/KubernetesClientBuildItem.java +++ b/extensions/kubernetes-client/spi/src/main/java/io/quarkus/kubernetes/client/spi/KubernetesClientBuildItem.java @@ -1,18 +1,26 @@ package io.quarkus.kubernetes.client.spi; +import java.util.function.Supplier; + +import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.quarkus.builder.item.SimpleBuildItem; public final class KubernetesClientBuildItem extends SimpleBuildItem { - private final KubernetesClient client; + private final Config config; + + public KubernetesClientBuildItem(Config config) { + this.config = config; + } - public KubernetesClientBuildItem(KubernetesClient client) { - this.client = client; + public Supplier getClient() { + return () -> new KubernetesClientBuilder().withConfig(config).build(); } - public KubernetesClient getClient() { - return this.client; + public Config getConfig() { + return config; } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeDeployer.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeDeployer.java index 4e9079689f8f2..7edfbeb45d6a9 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeDeployer.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeDeployer.java @@ -17,14 +17,14 @@ public class KnativeDeployer { @BuildStep public void checkEnvironment(Optional selectedDeploymentTarget, List resources, - KubernetesClientBuildItem client, BuildProducer deploymentCluster) { + KubernetesClientBuildItem clientSupplier, BuildProducer deploymentCluster) { selectedDeploymentTarget.ifPresent(target -> { if (!KubernetesDeploy.INSTANCE.checkSilently()) { return; } if (target.getEntry().getName().equals(KNATIVE)) { - try (DefaultKnativeClient knativeClient = client.getClient().adapt(DefaultKnativeClient.class)) { - if (knativeClient.isSupported()) { + try (DefaultKnativeClient client = clientSupplier.getClient().get().adapt(DefaultKnativeClient.class)) { + if (client.isSupported()) { deploymentCluster.produce(new KubernetesDeploymentClusterBuildItem(KNATIVE)); } else { throw new IllegalStateException( diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployer.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployer.java index 8e2e067cecf34..e5037121a6c7c 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployer.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployer.java @@ -102,7 +102,7 @@ public void checkEnvironment(Optional deploymentClusters, Optional selectedDeploymentTarget, @@ -130,10 +130,11 @@ public void deploy(KubernetesClientBuildItem kubernetesClient, return; } - final KubernetesClient client = Clients.fromConfig(kubernetesClient.getClient().getConfiguration()); - deploymentResult - .produce(deploy(selectedDeploymentTarget.get().getEntry(), client, outputTarget.getOutputDirectory(), - openshiftConfig, applicationInfo, optionalResourceDefinitions)); + try (final KubernetesClient client = Clients.fromConfig(kubernetesClientSupplier.getConfig())) { + deploymentResult + .produce(deploy(selectedDeploymentTarget.get().getEntry(), client, outputTarget.getOutputDirectory(), + openshiftConfig, applicationInfo, optionalResourceDefinitions)); + } } /** diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftDeployer.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftDeployer.java index 82ecd5a305eed..b74b863826fd7 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftDeployer.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftDeployer.java @@ -18,13 +18,13 @@ public class OpenshiftDeployer { @BuildStep public void checkEnvironment(Optional selectedDeploymentTarget, List resources, - KubernetesClientBuildItem client, BuildProducer deploymentCluster) { + KubernetesClientBuildItem clientSupplier, BuildProducer deploymentCluster) { selectedDeploymentTarget.ifPresent(target -> { if (!KubernetesDeploy.INSTANCE.checkSilently()) { return; } if (target.getEntry().getName().equals(OPENSHIFT)) { - try (var openShiftClient = client.getClient().adapt(OpenShiftClient.class)) { + try (var openShiftClient = clientSupplier.getClient().get().adapt(OpenShiftClient.class)) { if (openShiftClient.isSupported()) { deploymentCluster.produce(new KubernetesDeploymentClusterBuildItem(OPENSHIFT)); } else {