diff --git a/extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ContainerImageInfoBuildItem.java b/extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ContainerImageInfoBuildItem.java index fd67ab86f1d7c..8f2f6ae735dac 100644 --- a/extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ContainerImageInfoBuildItem.java +++ b/extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ContainerImageInfoBuildItem.java @@ -79,4 +79,8 @@ public String getRepository() { public String getGroup() { return repository == null ? null : repository.split("/")[0]; } + + public String getName() { + return repository == null ? null : repository.split("/")[1]; + } } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageGroupConfigurator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageGroupConfigurator.java deleted file mode 100644 index 155961cf6c2cb..0000000000000 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageGroupConfigurator.java +++ /dev/null @@ -1,20 +0,0 @@ - -package io.quarkus.kubernetes.deployment; - -import io.dekorate.kubernetes.config.Configurator; -import io.dekorate.kubernetes.config.ImageConfigurationFluent; - -public class ApplyImageGroupConfigurator extends Configurator> { - - private final String group; - - public ApplyImageGroupConfigurator(String group) { - this.group = group; - } - - @Override - public void visit(ImageConfigurationFluent config) { - config.withGroup(group); - } - -} diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageInfoConfigurationSupplier.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageInfoConfigurationSupplier.java new file mode 100644 index 0000000000000..8719b0f45b17e --- /dev/null +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageInfoConfigurationSupplier.java @@ -0,0 +1,33 @@ + +package io.quarkus.kubernetes.deployment; + +import io.dekorate.config.ConfigurationSupplier; +import io.dekorate.kubernetes.config.ImageConfiguration; +import io.dekorate.kubernetes.config.ImageConfigurationBuilder; +import io.quarkus.container.spi.ContainerImageInfoBuildItem; + +/** + * Workaround for https://github.com/dekorateio/dekorate/issues/1147: Dekorate only allows providing the image info via + * suppliers, not configurators. + */ +public class ApplyImageInfoConfigurationSupplier extends ConfigurationSupplier { + + public ApplyImageInfoConfigurationSupplier(ContainerImageInfoBuildItem image, String defaultRegistry) { + super(create(image, defaultRegistry)); + } + + private static ImageConfigurationBuilder create(ContainerImageInfoBuildItem image, String defaultRegistry) { + ImageConfigurationBuilder builder = new ImageConfigurationBuilder(); + builder.withRegistry(image.getRegistry().orElse(defaultRegistry)); + builder.withEnabled(true); + builder.withGroup(image.getGroup()); + builder.withName(image.getName()); + builder.withVersion(image.getTag()); + return builder; + } + + @Override + public boolean isExplicit() { + return true; + } +} diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageRegistryConfigurator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageRegistryConfigurator.java deleted file mode 100644 index 1d4106eaa3a0d..0000000000000 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyImageRegistryConfigurator.java +++ /dev/null @@ -1,19 +0,0 @@ - -package io.quarkus.kubernetes.deployment; - -import io.dekorate.kubernetes.config.Configurator; -import io.dekorate.kubernetes.config.ImageConfigurationFluent; - -public class ApplyImageRegistryConfigurator extends Configurator> { - - private final String registry; - - public ApplyImageRegistryConfigurator(String registry) { - this.registry = registry; - } - - @Override - public void visit(ImageConfigurationFluent config) { - config.withRegistry(registry); - } -} diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ChangeDeploymentTriggerDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ChangeDeploymentTriggerDecorator.java deleted file mode 100644 index badd3dd41eb38..0000000000000 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ChangeDeploymentTriggerDecorator.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.quarkus.kubernetes.deployment; - -import io.dekorate.kubernetes.decorator.Decorator; -import io.dekorate.openshift.decorator.ApplyDeploymentTriggerDecorator; - -public class ChangeDeploymentTriggerDecorator extends ApplyDeploymentTriggerDecorator { - - public ChangeDeploymentTriggerDecorator(String containerName, String imageStreamTag) { - super(containerName, imageStreamTag); - } - - @Override - public Class[] after() { - return new Class[] { ApplyDeploymentTriggerDecorator.class, RemoveDeploymentTriggerDecorator.class }; - } -} 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 bad03339aa2ed..c2666ff6c2b98 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 @@ -18,8 +18,6 @@ import io.dekorate.kubernetes.annotation.ServiceType; import io.dekorate.kubernetes.config.EnvBuilder; -import io.dekorate.kubernetes.config.ImageConfiguration; -import io.dekorate.kubernetes.config.ImageConfigurationBuilder; import io.dekorate.kubernetes.config.Port; import io.dekorate.kubernetes.decorator.AddAnnotationDecorator; import io.dekorate.kubernetes.decorator.AddEnvVarDecorator; @@ -31,7 +29,6 @@ import io.dekorate.s2i.config.S2iBuildConfig; import io.dekorate.s2i.config.S2iBuildConfigBuilder; import io.dekorate.s2i.decorator.AddBuilderImageStreamResourceDecorator; -import io.dekorate.s2i.decorator.AddDockerImageStreamResourceDecorator; import io.quarkus.container.image.deployment.ContainerImageConfig; import io.quarkus.container.image.deployment.util.ImageUtil; import io.quarkus.container.spi.BaseImageInfoBuildItem; @@ -48,6 +45,7 @@ import io.quarkus.deployment.pkg.PackageConfig; import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; import io.quarkus.kubernetes.deployment.OpenshiftConfig.DeploymentResourceKind; +import io.quarkus.kubernetes.spi.ConfigurationSupplierBuildItem; import io.quarkus.kubernetes.spi.ConfiguratorBuildItem; import io.quarkus.kubernetes.spi.CustomProjectRootBuildItem; import io.quarkus.kubernetes.spi.DecoratorBuildItem; @@ -128,38 +126,35 @@ public void createLabels(OpenshiftConfig config, BuildProducer createConfigurators(ApplicationInfoBuildItem applicationInfo, - OpenshiftConfig config, Capabilities capabilities, Optional image, - List ports) { - - List result = new ArrayList<>(); + public void createConfigurators(ApplicationInfoBuildItem applicationInfo, + OpenshiftConfig config, Capabilities capabilities, + Optional image, + Optional fallbackRegistry, + List ports, + BuildProducer configurators, + BuildProducer configurationSuppliers) { KubernetesCommonHelper.combinePorts(ports, config).values().forEach(value -> { - result.add(new ConfiguratorBuildItem(new AddPortToOpenshiftConfig(value))); + configurators.produce(new ConfiguratorBuildItem(new AddPortToOpenshiftConfig(value))); }); - result.add(new ConfiguratorBuildItem(new ApplyOpenshiftRouteConfigurator(config.route, config.expose))); + configurators.produce(new ConfiguratorBuildItem(new ApplyOpenshiftRouteConfigurator(config.route, config.expose))); // Handle remote debug configuration for container ports if (config.remoteDebug.enabled) { - result.add(new ConfiguratorBuildItem(new AddPortToOpenshiftConfig(config.remoteDebug.buildDebugPort()))); + configurators.produce(new ConfiguratorBuildItem(new AddPortToOpenshiftConfig(config.remoteDebug.buildDebugPort()))); } if (!capabilities.isPresent(Capability.CONTAINER_IMAGE_S2I) && !capabilities.isPresent("io.quarkus.openshift") && !capabilities.isPresent(Capability.CONTAINER_IMAGE_OPENSHIFT)) { - result.add(new ConfiguratorBuildItem(new DisableS2iConfigurator())); - - image.flatMap(ContainerImageInfoBuildItem::getRegistry).ifPresent(r -> { - result.add(new ConfiguratorBuildItem(new ApplyImageRegistryConfigurator(r))); - }); - - image.map(ContainerImageInfoBuildItem::getGroup).ifPresent(g -> { - result.add(new ConfiguratorBuildItem(new ApplyImageGroupConfigurator(g))); - }); + configurators.produce(new ConfiguratorBuildItem(new DisableS2iConfigurator())); + image.ifPresent(i -> configurationSuppliers.produce( + new ConfigurationSupplierBuildItem( + new ApplyImageInfoConfigurationSupplier(i, + fallbackRegistry.map(f -> f.getRegistry()).orElse(DOCKERIO_REGISTRY))))); } - return result; } @BuildStep @@ -167,7 +162,6 @@ public List createDecorators(ApplicationInfoBuildItem applic OutputTargetBuildItem outputTarget, OpenshiftConfig config, ContainerImageConfig containerImageConfig, - Optional fallbackRegistry, PackageConfig packageConfig, Optional metricsConfiguration, Capabilities capabilities, @@ -308,25 +302,11 @@ public List createDecorators(ApplicationInfoBuildItem applic if (deploymentKind == DeploymentResourceKind.DeploymentConfig && !OpenshiftConfig.isOpenshiftBuildEnabled(containerImageConfig, capabilities)) { image.ifPresent(i -> { - String registry = i.registry - .or(() -> containerImageConfig.registry) - .orElse(fallbackRegistry.map(f -> f.getRegistry()).orElse(DOCKERIO_REGISTRY)); - String repositoryWithRegistry = registry + "/" + i.getRepository(); - ImageConfiguration imageConfiguration = new ImageConfigurationBuilder() - .withName(name) - .withRegistry(registry) - .build(); - result.add(new DecoratorBuildItem(OPENSHIFT, - new AddDockerImageStreamResourceDecorator(imageConfiguration, repositoryWithRegistry))); - String imageStreamWithTag = name + ":" + i.getTag(); - result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyContainerImageDecorator(name, imageStreamWithTag))); - // remove the default trigger which has a wrong version - result.add(new DecoratorBuildItem(OPENSHIFT, new RemoveDeploymentTriggerDecorator())); - // re-add the trigger with the correct version - result.add(new DecoratorBuildItem(OPENSHIFT, new ChangeDeploymentTriggerDecorator(name, imageStreamWithTag))); + new ApplyContainerImageDecorator(name, i.getName() + ":" + i.getTag()))); }); } else if (image.isPresent()) { + result.add(new DecoratorBuildItem(OPENSHIFT, new RemoveDockerImageStreamResourceDecorator(name))); result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyContainerImageDecorator(name, image.get().getImage()))); } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/RemoveDeploymentTriggerDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/RemoveDeploymentTriggerDecorator.java deleted file mode 100644 index 80730366ffdb9..0000000000000 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/RemoveDeploymentTriggerDecorator.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.quarkus.kubernetes.deployment; - -import java.util.Collections; - -import io.dekorate.kubernetes.decorator.Decorator; -import io.dekorate.kubernetes.decorator.NamedResourceDecorator; -import io.dekorate.openshift.decorator.ApplyDeploymentTriggerDecorator; -import io.fabric8.kubernetes.api.model.ObjectMeta; -import io.fabric8.openshift.api.model.DeploymentConfigSpecFluent; - -public class RemoveDeploymentTriggerDecorator extends NamedResourceDecorator> { - - @Override - public void andThenVisit(DeploymentConfigSpecFluent deploymentConfigSpec, ObjectMeta objectMeta) { - deploymentConfigSpec.withTriggers(Collections.emptyList()); - } - - @Override - public Class[] after() { - return new Class[] { ApplyDeploymentTriggerDecorator.class }; - } -} diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/RemoveDockerImageStreamResourceDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/RemoveDockerImageStreamResourceDecorator.java new file mode 100644 index 0000000000000..37bb5dd243de7 --- /dev/null +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/RemoveDockerImageStreamResourceDecorator.java @@ -0,0 +1,33 @@ +package io.quarkus.kubernetes.deployment; + +import io.dekorate.kubernetes.decorator.Decorator; +import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator; +import io.dekorate.s2i.decorator.AddDockerImageStreamResourceDecorator; +import io.fabric8.kubernetes.api.model.KubernetesListBuilder; +import io.fabric8.openshift.api.model.ImageStream; + +/** + * Workaround for https://github.com/dekorateio/dekorate/issues/1148: Dekorate is always adding an image stream if we're + * using a docker image, so we need to remove it if we're using a Deployment resource. + */ +public class RemoveDockerImageStreamResourceDecorator extends ResourceProvidingDecorator { + + private final String name; + + public RemoveDockerImageStreamResourceDecorator(String name) { + this.name = name; + } + + public void visit(KubernetesListBuilder list) { + list.getItems().stream() + .filter(i -> i.getMetadata().getName().equals(name) && i instanceof ImageStream) + .map(ImageStream.class::cast) + .findFirst() + .ifPresent(list::removeFromItems); + } + + @Override + public Class[] after() { + return new Class[] { AddDockerImageStreamResourceDecorator.class }; + } +} \ No newline at end of file diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithDockerAndImageTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithDockerAndImageTest.java index ac72f534352ab..b8c27f2bdd34a 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithDockerAndImageTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithDockerAndImageTest.java @@ -49,17 +49,17 @@ public void assertGeneratedResources() throws IOException { }); assertThat(h).isInstanceOfSatisfying(DeploymentConfig.class, d -> { Container container = d.getSpec().getTemplate().getSpec().getContainers().get(0); - assertThat(container.getImage()).isEqualTo(APP_NAME + ":1.0"); + assertThat(container.getImage()).isEqualTo("app:1.0"); DeploymentTriggerImageChangeParams imageTriggerParams = d.getSpec().getTriggers().get(0).getImageChangeParams(); assertThat(imageTriggerParams.getFrom().getKind()).isEqualTo("ImageStreamTag"); - assertThat(imageTriggerParams.getFrom().getName()).isEqualTo(APP_NAME + ":1.0"); + assertThat(imageTriggerParams.getFrom().getName()).isEqualTo("app:1.0"); }); }); assertThat(openshiftList).filteredOn(h -> "ImageStream".equals(h.getKind())).singleElement().satisfies(h -> { assertThat(h.getMetadata()).satisfies(m -> { - assertThat(m.getName()).isEqualTo(APP_NAME); + assertThat(m.getName()).isEqualTo("app"); }); assertThat(h).isInstanceOfSatisfying(ImageStream.class, i -> { assertThat(i.getSpec().getDockerImageRepository()).isEqualTo("quay.io/user/app"); 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 index 189e9f5b3008a..95fd6417d9ee9 100644 --- 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 @@ -22,7 +22,7 @@ // // 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 +// Then: No BuildConfig and ImageStreams are generated and that `docker.io` is used as the default registry // public class OpenshiftWithLocalDockerAndDeploymentResourceTest {