diff --git a/extensions/container-image/container-image-buildpack/deployment/src/main/java/io/quarkus/container/image/buildpack/deployment/BuildpackProcessor.java b/extensions/container-image/container-image-buildpack/deployment/src/main/java/io/quarkus/container/image/buildpack/deployment/BuildpackProcessor.java index b4f74bc216874..f0e24b30c32a4 100644 --- a/extensions/container-image/container-image-buildpack/deployment/src/main/java/io/quarkus/container/image/buildpack/deployment/BuildpackProcessor.java +++ b/extensions/container-image/container-image-buildpack/deployment/src/main/java/io/quarkus/container/image/buildpack/deployment/BuildpackProcessor.java @@ -78,6 +78,7 @@ public void buildFromJar(ContainerImageConfig containerImageConfig, BuildpackCon return; } + log.info("Starting (local) container image build for jar using builpack."); String targetImageName = runBuildpackBuild(buildpackConfig, containerImage, containerImageConfig, pushRequest, outputTarget, false /* isNative */); @@ -109,6 +110,7 @@ public void buildFromNative(ContainerImageConfig containerImageConfig, Buildpack "The native binary produced by the build is not a Linux binary and therefore cannot be used in a Linux container image. Consider adding \"quarkus.native.container-build=true\" to your configuration"); } + log.info("Starting (local) container image build for native binary using buildpack."); String targetImageName = runBuildpackBuild(buildpackConfig, containerImage, containerImageConfig, pushRequest, outputTarget, true /* isNative */); diff --git a/extensions/container-image/container-image-docker/deployment/src/main/java/io/quarkus/container/image/docker/deployment/DockerProcessor.java b/extensions/container-image/container-image-docker/deployment/src/main/java/io/quarkus/container/image/docker/deployment/DockerProcessor.java index 0f8d083c3b24c..3145309f46cd0 100644 --- a/extensions/container-image/container-image-docker/deployment/src/main/java/io/quarkus/container/image/docker/deployment/DockerProcessor.java +++ b/extensions/container-image/container-image-docker/deployment/src/main/java/io/quarkus/container/image/docker/deployment/DockerProcessor.java @@ -99,7 +99,7 @@ public void dockerBuildFromJar(DockerConfig dockerConfig, dockerFileBaseInformation.get().getBaseImage())); } - log.info("Building docker image for jar."); + log.info("Starting (local) container image build for jar using docker."); ImageIdReader reader = new ImageIdReader(); String builtContainerImage = createContainerImage(containerImageConfig, dockerConfig, containerImageInfo, out, reader, @@ -143,7 +143,7 @@ public void dockerBuildFromNativeImage(DockerConfig dockerConfig, "The native binary produced by the build is not a Linux binary and therefore cannot be used in a Linux container image. Consider adding \"quarkus.native.container-build=true\" to your configuration"); } - log.info("Starting docker image build"); + log.info("Starting (local) container image build for native binary using docker."); ImageIdReader reader = new ImageIdReader(); String builtContainerImage = createContainerImage(containerImageConfig, dockerConfig, containerImage, out, reader, true, diff --git a/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java b/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java index 9ff6fbc9f9e2b..c15e6ef6c2b87 100644 --- a/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java +++ b/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java @@ -157,6 +157,7 @@ public void buildFromJar(ContainerImageConfig containerImageConfig, JibConfig ji setUser(jibConfig, jibContainerBuilder); setPlatforms(jibConfig, jibContainerBuilder); handleExtraFiles(outputTarget, jibContainerBuilder); + log.info("Starting (local) container image build for jar using jib."); JibContainer container = containerize(containerImageConfig, jibConfig, containerImage, jibContainerBuilder, pushRequest.isPresent()); writeOutputFiles(container, jibConfig, outputTarget); @@ -195,6 +196,8 @@ public void buildFromNative(ContainerImageConfig containerImageConfig, JibConfig setUser(jibConfig, jibContainerBuilder); setPlatforms(jibConfig, jibContainerBuilder); handleExtraFiles(outputTarget, jibContainerBuilder); + + log.info("Starting (local) container image build for native binary using jib."); JibContainer container = containerize(containerImageConfig, jibConfig, containerImage, jibContainerBuilder, pushRequest.isPresent()); writeOutputFiles(container, jibConfig, outputTarget); @@ -221,7 +224,6 @@ private JibContainer containerize(ContainerImageConfig containerImageConfig, previousContextStorageSysProp = System.setProperty(OPENTELEMETRY_CONTEXT_CONTEXT_STORAGE_PROVIDER_SYS_PROP, "default"); - log.info("Starting container image build"); JibContainer container = jibContainerBuilder.containerize(containerizer); log.infof("%s container image %s (%s)\n", containerImageConfig.isPushExplicitlyEnabled() ? "Pushed" : "Created", 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 671172a2d420e..7148702afe455 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 @@ -247,9 +247,8 @@ public void openshiftBuildFromJar(OpenshiftConfig openshiftConfig, } String namespace = Optional.ofNullable(kubernetesClient.getClient().getNamespace()).orElse("default"); - LOG.info("Performing openshift binary build with jar on server: " + kubernetesClient.getClient().getMasterUrl() - + " in namespace:" + namespace + "."); - + 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. @@ -302,9 +301,9 @@ public void openshiftBuildFromNative(OpenshiftConfig openshiftConfig, S2iConfig } String namespace = Optional.ofNullable(kubernetesClient.getClient().getNamespace()).orElse("default"); - LOG.info("Performing openshift binary build with native image on server: " + kubernetesClient.getClient().getMasterUrl() - + " in namespace:" + namespace + "."); + 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")) diff --git a/extensions/kubernetes/openshift/deployment/src/main/java/io/quarkus/openshift/deployment/OpenshiftProcessor.java b/extensions/kubernetes/openshift/deployment/src/main/java/io/quarkus/openshift/deployment/OpenshiftProcessor.java index 4e7091c4cd6ac..515098ecc62f9 100644 --- a/extensions/kubernetes/openshift/deployment/src/main/java/io/quarkus/openshift/deployment/OpenshiftProcessor.java +++ b/extensions/kubernetes/openshift/deployment/src/main/java/io/quarkus/openshift/deployment/OpenshiftProcessor.java @@ -6,6 +6,7 @@ import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.ApplicationInfoBuildItem; import io.quarkus.kubernetes.deployment.OpenshiftConfig; +import io.quarkus.kubernetes.deployment.OpenshiftConfig.DeploymentResourceKind; import io.quarkus.kubernetes.deployment.ResourceNameUtil; import io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem; import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem; @@ -17,17 +18,15 @@ public void checkOpenshift(ApplicationInfoBuildItem applicationInfo, OpenshiftCo BuildProducer deploymentTargets, BuildProducer resourceMeta) { - String kind = config.getDepoymentResourceKind(); - String group = config.getDepoymentResourceGroup(); - String version = config.getDepoymentResourceVersion(); - + DeploymentResourceKind deploymentResourceKind = config.getDeploymentResourceKind(); deploymentTargets .produce( - new KubernetesDeploymentTargetBuildItem(OPENSHIFT, kind, group, - version, true)); + new KubernetesDeploymentTargetBuildItem(OPENSHIFT, deploymentResourceKind.kind, + deploymentResourceKind.apiGroup, + deploymentResourceKind.apiVersion, true)); String name = ResourceNameUtil.getResourceName(config, applicationInfo); - resourceMeta.produce(new KubernetesResourceMetadataBuildItem(OPENSHIFT, group, - version, kind, name)); + resourceMeta.produce(new KubernetesResourceMetadataBuildItem(OPENSHIFT, deploymentResourceKind.apiGroup, + deploymentResourceKind.apiVersion, deploymentResourceKind.kind, name)); } } 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 d9afa74be98fe..d06b23f16fbea 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 @@ -128,7 +128,7 @@ private DeploymentTargetEntry determineDeploymentTarget( final DeploymentTargetEntry selectedTarget; boolean checkForMissingRegistry = true; - boolean checkForNamespaceGroupAlignment = true; + boolean checkForNamespaceGroupAlignment = false; List userSpecifiedDeploymentTargets = KubernetesConfigUtil.getUserSpecifiedDeploymentTargets(); if (userSpecifiedDeploymentTargets.isEmpty()) { selectedTarget = targets.getEntriesSortedByPriority().get(0); @@ -155,6 +155,8 @@ private DeploymentTargetEntry determineDeploymentTarget( if (OPENSHIFT.equals(selectedTarget.getName())) { checkForMissingRegistry = Capability.CONTAINER_IMAGE_S2I.equals(activeContainerImageCapability) || Capability.CONTAINER_IMAGE_OPENSHIFT.equals(activeContainerImageCapability); + + // We should ensure that we have image group and namespace alignment we are not using deployment triggers via DeploymentConfig. if (!targets.getEntriesSortedByPriority().get(0).getKind().equals("DeploymentConfig")) { checkForNamespaceGroupAlignment = true; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployerPrerequisite.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployerPrerequisite.java index 162ed8a70883e..ce0665e9d0882 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployerPrerequisite.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployerPrerequisite.java @@ -5,6 +5,7 @@ import io.quarkus.container.spi.ContainerImageBuildRequestBuildItem; import io.quarkus.container.spi.ContainerImageInfoBuildItem; import io.quarkus.container.spi.ContainerImagePushRequestBuildItem; +import io.quarkus.container.spi.FallbackContainerImageRegistryBuildItem; import io.quarkus.deployment.IsNormalNotRemoteDev; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -14,6 +15,7 @@ public class KubernetesDeployerPrerequisite { @BuildStep(onlyIf = IsNormalNotRemoteDev.class) public void prepare(ContainerImageInfoBuildItem containerImage, Optional selectedDeploymentTarget, + Optional fallbackRegistry, BuildProducer buildRequestProducer, BuildProducer pushRequestProducer) { @@ -28,7 +30,8 @@ public void prepare(ContainerImageInfoBuildItem containerImage, // When a registry is present, we want to push the image // However we need to make sure we don't push to the registry when deploying to Minikube // since all updates are meant to find the image from the docker daemon - if (containerImage.getRegistry().isPresent() && + boolean registryIsPresent = containerImage.getRegistry().isPresent() || fallbackRegistry.isPresent(); + if (registryIsPresent && !selectedDeploymentTarget.get().getEntry().getName().equals(Constants.MINIKUBE)) { pushRequestProducer.produce(new ContainerImagePushRequestBuildItem()); } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java index ad0ada68cfed5..8c05ac9252533 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java @@ -16,6 +16,9 @@ import io.dekorate.kubernetes.annotation.ImagePullPolicy; import io.dekorate.kubernetes.annotation.ServiceType; +import io.quarkus.container.image.deployment.ContainerImageCapabilitiesUtil; +import io.quarkus.container.image.deployment.ContainerImageConfig; +import io.quarkus.deployment.Capabilities; import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigRoot; @@ -32,9 +35,9 @@ public static enum DeploymentResourceKind { DeploymentConfig(DEPLOYMENT_CONFIG, DEPLOYMENT_CONFIG_GROUP, DEPLOYMENT_CONFIG_VERSION), StatefulSet(STATEFULSET, DEPLOYMENT_GROUP, DEPLOYMENT_VERSION); - final String kind; - final String apiGroup; - final String apiVersion; + public final String kind; + public final String apiGroup; + public final String apiVersion; DeploymentResourceKind(String kind, String apiGroup, String apiVersion) { this.kind = kind; @@ -55,8 +58,8 @@ public static enum DeploymentResourceKind { * The kind of the deployment resource to use. * Supported values are 'Deployment' and 'DeploymentConfig' defaulting to the later. */ - @ConfigItem(defaultValue = "DeploymentConfig") - DeploymentResourceKind deploymentKind; + @ConfigItem + Optional deploymentKind; /** * The name of the group this component belongs too @@ -505,15 +508,13 @@ public Optional getExposition() { return Optional.of(route); } - public String getDepoymentResourceGroup() { - return deploymentKind.apiGroup; - } - - public String getDepoymentResourceVersion() { - return deploymentKind.apiVersion; + public static boolean isOpenshiftBuildEnabled(ContainerImageConfig containerImageConfig, Capabilities capabilities) { + boolean implictlyEnabled = ContainerImageCapabilitiesUtil.getActiveContainerImageCapability(capabilities) + .filter(c -> c.contains("openshift") || c.contains("s2i")).isPresent(); + return containerImageConfig.builder.map(b -> b.equals("openshfit") || b.equals("s2i")).orElse(implictlyEnabled); } - public String getDepoymentResourceKind() { - return deploymentKind.kind; + public DeploymentResourceKind getDeploymentResourceKind() { + return deploymentKind.orElse(DeploymentResourceKind.DeploymentConfig); } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java index 552afd20a8c06..314ee65459d2c 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java @@ -31,7 +31,6 @@ import io.dekorate.s2i.decorator.AddBuilderImageStreamResourceDecorator; import io.dekorate.s2i.decorator.AddDockerImageStreamResourceDecorator; import io.dekorate.utils.Labels; -import io.fabric8.kubernetes.client.Config; import io.quarkus.container.image.deployment.ContainerImageConfig; import io.quarkus.container.image.deployment.util.ImageUtil; import io.quarkus.container.spi.BaseImageInfoBuildItem; @@ -66,6 +65,7 @@ public class OpenshiftProcessor { private static final int OPENSHIFT_PRIORITY = DEFAULT_PRIORITY; private static final String OPENSHIFT_INTERNAL_REGISTRY = "image-registry.openshift-image-registry.svc:5000"; + private static final String DOCKERIO_REGISTRY = "docker.io"; @BuildStep public void checkOpenshift(ApplicationInfoBuildItem applicationInfo, OpenshiftConfig config, @@ -73,30 +73,35 @@ public void checkOpenshift(ApplicationInfoBuildItem applicationInfo, OpenshiftCo BuildProducer resourceMeta) { List targets = KubernetesConfigUtil.getUserSpecifiedDeploymentTargets(); boolean openshiftEnabled = targets.contains(OPENSHIFT); - String kind = config.getDepoymentResourceKind(); - String group = config.getDepoymentResourceGroup(); - String version = config.getDepoymentResourceVersion(); - deploymentTargets.produce(new KubernetesDeploymentTargetBuildItem(OPENSHIFT, kind, group, version, OPENSHIFT_PRIORITY, - openshiftEnabled)); + DeploymentResourceKind deploymentResourceKind = config.getDeploymentResourceKind(); + deploymentTargets.produce( + new KubernetesDeploymentTargetBuildItem(OPENSHIFT, deploymentResourceKind.kind, deploymentResourceKind.apiGroup, + deploymentResourceKind.apiVersion, OPENSHIFT_PRIORITY, openshiftEnabled)); if (openshiftEnabled) { String name = ResourceNameUtil.getResourceName(config, applicationInfo); - resourceMeta.produce(new KubernetesResourceMetadataBuildItem(OPENSHIFT, group, - version, kind, name)); + resourceMeta.produce(new KubernetesResourceMetadataBuildItem(OPENSHIFT, deploymentResourceKind.apiGroup, + deploymentResourceKind.apiVersion, deploymentResourceKind.kind, name)); } } @BuildStep public void populateInternalRegistry(OpenshiftConfig openshiftConfig, ContainerImageConfig containerImageConfig, + Capabilities capabilities, BuildProducer containerImageRegistry) { - if (openshiftConfig.deploymentKind == DeploymentResourceKind.Deployment && !containerImageConfig.registry.isPresent()) { - containerImageRegistry.produce(new FallbackContainerImageRegistryBuildItem(OPENSHIFT_INTERNAL_REGISTRY)); - - // Images stored in internal openshift registry use the following patttern: - // 'image-registry.openshift-image-registry.svc:5000/{{ project name}}/{{ image name }}: {{image version }}. - // So, we need warn users if group does not match currently selected project. - String group = containerImageConfig.group.orElse(null); - Config config = Config.autoConfigure(null); + + if (!containerImageConfig.registry.isPresent()) { + DeploymentResourceKind deploymentResourceKind = openshiftConfig.getDeploymentResourceKind(); + if (deploymentResourceKind != DeploymentResourceKind.DeploymentConfig) { + if (openshiftConfig.isOpenshiftBuildEnabled(containerImageConfig, capabilities)) { + // Images stored in internal openshift registry use the following patttern: + // 'image-registry.openshift-image-registry.svc:5000/{{ project name}}/{{ image name }}: {{image version }}. + // So, we need warn users if group does not match currently selected project. + containerImageRegistry.produce(new FallbackContainerImageRegistryBuildItem(OPENSHIFT_INTERNAL_REGISTRY)); + } else { + containerImageRegistry.produce(new FallbackContainerImageRegistryBuildItem(DOCKERIO_REGISTRY)); + } + } } } @@ -148,6 +153,8 @@ public List createConfigurators(ApplicationInfoBuildItem public List createDecorators(ApplicationInfoBuildItem applicationInfo, OutputTargetBuildItem outputTarget, OpenshiftConfig config, + ContainerImageConfig containerImageConfig, + Optional fallbackRegistry, PackageConfig packageConfig, Optional metricsConfiguration, Capabilities capabilities, @@ -188,7 +195,8 @@ public List createDecorators(ApplicationInfoBuildItem applic result.add(new DecoratorBuildItem(new RemoveOptionalFromConfigMapKeySelectorDecorator())); } - switch (config.deploymentKind) { + DeploymentResourceKind deploymentResourceKind = config.getDeploymentResourceKind(); + switch (deploymentResourceKind) { case Deployment: result.add(new DecoratorBuildItem(OPENSHIFT, new RemoveDeploymentConfigResourceDecorator(name))); result.add(new DecoratorBuildItem(OPENSHIFT, new AddDeploymentResourceDecorator(name, config))); @@ -230,8 +238,11 @@ public List createDecorators(ApplicationInfoBuildItem applic if (!DEFAULT_S2I_IMAGE_NAME.equals(builderImageName)) { result.add(new DecoratorBuildItem(OPENSHIFT, new RemoveBuilderImageResourceDecorator(DEFAULT_S2I_IMAGE_NAME))); } - result.add(new DecoratorBuildItem(OPENSHIFT, new AddBuilderImageStreamResourceDecorator(s2iBuildConfig))); - result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyBuilderImageDecorator(name, builderImage))); + + if (containerImageConfig.builder.isEmpty() || config.isOpenshiftBuildEnabled(containerImageConfig, capabilities)) { + result.add(new DecoratorBuildItem(OPENSHIFT, new AddBuilderImageStreamResourceDecorator(s2iBuildConfig))); + result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyBuilderImageDecorator(name, builderImage))); + } }); if (!config.addVersionToLabelSelectors) { @@ -250,21 +261,22 @@ public List createDecorators(ApplicationInfoBuildItem applic .findFirst().orElse(DEFAULT_HTTP_PORT); result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyHttpGetActionPortDecorator(name, name, port))); - // Handle non-s2i - if (!capabilities.isPresent(Capability.CONTAINER_IMAGE_S2I) - && !capabilities.isPresent("io.quarkus.openshift") - && !capabilities.isPresent(Capability.CONTAINER_IMAGE_OPENSHIFT)) { - result.add(new DecoratorBuildItem(OPENSHIFT, new RemoveDeploymentTriggerDecorator())); - ImageConfiguration imageConfiguration = new ImageConfigurationBuilder() - .build(); - + // Handle non-openshift builds + if (deploymentResourceKind == DeploymentResourceKind.DeploymentConfig + && !OpenshiftConfig.isOpenshiftBuildEnabled(containerImageConfig, capabilities)) { image.ifPresent(i -> { - String repo = i.getRegistry().map(reg -> reg + "/" + i.getRepository()).orElse(i.getRepository()); + String registry = containerImageConfig.registry + .orElse(fallbackRegistry.map(f -> f.getRegistry()).orElse("docker.io")); + String repositoryWithRegistry = registry + "/" + i.getRepository(); + ImageConfiguration imageConfiguration = new ImageConfigurationBuilder() + .withName(name) + .withRegistry(registry) + .build(); + result.add(new DecoratorBuildItem(OPENSHIFT, - new AddDockerImageStreamResourceDecorator(imageConfiguration, repo))); + new AddDockerImageStreamResourceDecorator(imageConfiguration, repositoryWithRegistry))); }); } - return result; } } diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicOpenshiftTest.java b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicOpenshiftTest.java index 0fdfc42ce718f..02fcbec067927 100644 --- a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicOpenshiftTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicOpenshiftTest.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.nio.file.Path; -import java.util.Collection; import java.util.List; import java.util.Map; @@ -50,9 +49,6 @@ public void assertGeneratedResources() throws IOException { }); AbstractObjectAssert specAssert = assertThat(h).extracting("spec"); specAssert.extracting("replicas").isEqualTo(1); - specAssert.extracting("triggers").isInstanceOfSatisfying(Collection.class, c -> { - assertThat(c).isEmpty(); - }); specAssert.extracting("selector").isInstanceOfSatisfying(Map.class, selectorsMap -> { assertThat(selectorsMap).containsOnly(entry("app.kubernetes.io/name", "basic-openshift"), entry("app.kubernetes.io/version", "0.1-SNAPSHOT")); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicOpenshiftTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicOpenshiftTest.java index 8deab735f79f7..8d064b8666317 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicOpenshiftTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicOpenshiftTest.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.nio.file.Path; -import java.util.Collection; import java.util.List; import java.util.Map; @@ -49,9 +48,6 @@ public void assertGeneratedResources() throws IOException { }); AbstractObjectAssert specAssert = assertThat(h).extracting("spec"); specAssert.extracting("replicas").isEqualTo(1); - specAssert.extracting("triggers").isInstanceOfSatisfying(Collection.class, c -> { - assertThat(c).isEmpty(); - }); specAssert.extracting("selector").isInstanceOfSatisfying(Map.class, selectorsMap -> { assertThat(selectorsMap).containsOnly(entry("app.kubernetes.io/name", "basic-openshift"), entry("app.kubernetes.io/version", "0.1-SNAPSHOT")); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithDeploymentResourceTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithDeploymentResourceTest.java index 773c3232b0b55..257be2e151acd 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithDeploymentResourceTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithDeploymentResourceTest.java @@ -19,6 +19,15 @@ import io.quarkus.test.ProdModeTestResults; import io.quarkus.test.QuarkusProdModeTest; +// +// The purpose of this test is to assert that +// When: We run an in-cluster container builds targeting Openshift (and `Deployment` is used). +// Then: +// - A BuildConfg is generated. +// - Two ImageStream are generated (one named after the app). +// - A Deployment resource was created +// - image-registry.openshift-image-registry.svc:5000 is used as registry (why? so that Deployment can point to the incluster built image). +// public class OpenshiftWithDeploymentResourceTest { @RegisterExtension @@ -26,7 +35,9 @@ public class OpenshiftWithDeploymentResourceTest { .withApplicationRoot((jar) -> jar.addClasses(GreetingResource.class)) .setApplicationName("openshift-with-deployment-resource") .setApplicationVersion("0.1-SNAPSHOT") - .withConfigurationResource("openshift-with-deployment-resource.properties") + .overrideConfigKey("quarkus.openshift.deployment-kind", "Deployment") + .overrideConfigKey("quarkus.openshift.replicas", "3") + .overrideConfigKey("quarkus.container-image.group", "testme") .setLogFileName("k8s.log") .setForcedDependencies( Collections.singletonList(new AppArtifact("io.quarkus", "quarkus-openshift", Version.getVersion()))); @@ -43,6 +54,11 @@ public void assertGeneratedResources() throws IOException { List kubernetesList = DeserializationUtil .deserializeAsList(kubernetesDir.resolve("openshift.yml")); + assertThat(kubernetesList).filteredOn(h -> "BuildConfig".equals(h.getKind())).hasSize(1); + assertThat(kubernetesList).filteredOn(h -> "ImageStream".equals(h.getKind())).hasSize(2); + assertThat(kubernetesList).filteredOn(h -> "ImageStream".equals(h.getKind()) + && h.getMetadata().getName().equals("openshift-with-deployment-resource")).hasSize(1); + assertThat(kubernetesList).filteredOn(i -> i instanceof Deployment).singleElement().satisfies(i -> { assertThat(i).isInstanceOfSatisfying(Deployment.class, d -> { assertThat(d.getMetadata()).satisfies(m -> { @@ -53,6 +69,11 @@ public void assertGeneratedResources() throws IOException { assertThat(deploymentSpec.getReplicas()).isEqualTo(3); assertThat(deploymentSpec.getTemplate()).satisfies(t -> { assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { + assertThat(container.getImage()) + .isEqualTo( + "image-registry.openshift-image-registry.svc:5000/testme/openshift-with-deployment-resource:0.1-SNAPSHOT"); + }); }); }); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithLocalDockerAndDeploymentResourceTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithLocalDockerAndDeploymentResourceTest.java new file mode 100644 index 0000000000000..819978f3c1617 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithLocalDockerAndDeploymentResourceTest.java @@ -0,0 +1,74 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.builder.Version; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +// +// The purpose of this test is to assert that +// When: We run local container builds targeting Openshift using `Deployment` (instead of `DeploymentConfig`) +// Then: No BuildConfg and ImageStreams are generated and that `docker.io` is used as the default registry +// +public class OpenshiftWithLocalDockerAndDeploymentResourceTest { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class)) + .setApplicationName("openshift-with-local-docker-and-deployment-resource") + .setApplicationVersion("0.1-SNAPSHOT") + .overrideConfigKey("quarkus.openshift.deployment-kind", "Deployment") + .overrideConfigKey("quarkus.container-image.builder", "docker") + .overrideConfigKey("quarkus.container-image.group", "testme") + .setLogFileName("k8s.log") + .setForcedDependencies(Arrays.asList(new AppArtifact("io.quarkus", "quarkus-openshift", Version.getVersion()), + new AppArtifact("io.quarkus", "quarkus-container-image-docker", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("openshift.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("openshift.yml")); + List kubernetesList = DeserializationUtil.deserializeAsList(kubernetesDir.resolve("openshift.yml")); + + assertThat(kubernetesList.get(0)).isInstanceOfSatisfying(Deployment.class, d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo("openshift-with-local-docker-and-deployment-resource"); + }); + + assertThat(kubernetesList).filteredOn(h -> "BuildConfig".equals(h.getKind())).hasSize(0); + assertThat(kubernetesList).filteredOn(h -> "ImageStream".equals(h.getKind())).hasSize(0); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { + assertThat(container.getImage()) + .isEqualTo( + "docker.io/testme/openshift-with-local-docker-and-deployment-resource:0.1-SNAPSHOT"); + }); + }); + }); + }); + }); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithLocalDockerTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithLocalDockerTest.java new file mode 100644 index 0000000000000..c702d2200be4b --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithLocalDockerTest.java @@ -0,0 +1,77 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.openshift.api.model.DeploymentConfig; +import io.fabric8.openshift.api.model.ImageStream; +import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.builder.Version; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +// +// The purpose of this test is to assert that +// When: We run local container builds targeting Openshift (and `DeploymentConfig` is used). +// Then: +// - No BuildConfg is generated. +// - A signle docker ImageStreams are generated and that `docker.io` is used as the default registry. +// +public class OpenshiftWithLocalDockerTest { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class)) + .setApplicationName("openshift-with-local-docker") + .setApplicationVersion("0.1-SNAPSHOT") + .overrideConfigKey("quarkus.container-image.builder", "docker") + .overrideConfigKey("quarkus.container-image.group", "testme") + .setLogFileName("k8s.log") + .setForcedDependencies(Arrays.asList(new AppArtifact("io.quarkus", "quarkus-openshift", Version.getVersion()), + new AppArtifact("io.quarkus", "quarkus-container-image-docker", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("openshift.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("openshift.yml")); + List kubernetesList = DeserializationUtil.deserializeAsList(kubernetesDir.resolve("openshift.yml")); + + assertThat(kubernetesList.get(0)).isInstanceOfSatisfying(DeploymentConfig.class, d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo("openshift-with-local-docker"); + }); + + assertThat(kubernetesList).filteredOn(h -> "ImageStream".equals(h.getKind())).hasSize(1) + .anySatisfy(h -> { + assertThat(h).isInstanceOfSatisfying(ImageStream.class, imageStream -> { + assertThat(imageStream.getSpec().getDockerImageRepository()) + .isEqualTo("docker.io/testme/openshift-with-local-docker"); + }); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + + }); + }); + }); + }); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-with-deployment-resource.properties b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-with-deployment-resource.properties deleted file mode 100644 index 3382f521aaf34..0000000000000 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-with-deployment-resource.properties +++ /dev/null @@ -1,2 +0,0 @@ -quarkus.openshift.deployment-kind=Deployment -quarkus.openshift.replicas=3 \ No newline at end of file