Skip to content

Commit

Permalink
feat: disable s2i when the capability is mising.
Browse files Browse the repository at this point in the history
  • Loading branch information
iocanel committed Jul 13, 2020
1 parent 85b60f0 commit b2a8e63
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 2 deletions.
11 changes: 11 additions & 0 deletions docs/src/main/asciidoc/container-image.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ To push a container image for your project, `quarkus.container-image.push=true`

NOTE: If no registry is set (using `quarkus.container-image.registry`) then `docker.io` will be used as the default.

== Selecting among multiple extensions

It does not make sense to use multiple extension as part of the same build. When multiple container image extensions are present, an error will be raised to inform the user. The user can either remove the uneeded extensions or select one using `application.properties`.

For example, if both `container-image-docker` and `container-image-s2i` are present and the user needs to use `container-image-docker`:

[source]
----
quarkus.container-image.builder=docker
----

== Customizing

The following properties can be used to customize the container image build process.
Expand Down
25 changes: 24 additions & 1 deletion docs/src/main/asciidoc/deploying-to-openshift.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,30 @@ Building is handled by the link:container-image#s2i[container-image-s2i] extensi
./mvnw clean package -Dquarkus.container-image.build=true
----

The command above will trigger an s2i binary build.
The build that will be performed is an s2i binary build. The input of the build is the jar that has been built locally and the output of the build is an ImageStream that is configured to automatically trigger a deployment.

=== Non S2i Builds

Out of the box the openshift extension is configured to use link:container-image#s2i[container-image-s2i]. However, it's still possible to use other container image extensions like:

- link:container-image#s2i[container-image-docker]
- link:container-image#s2i[container-image-jib]

When a non-s2i container image extension is used, an ImageStream is created that is pointing to an external `dockerImageRepository`. The image is built and pushed to the registry and the ImageStream populates the tags that are available in the `dockerImageRepository`.

To select which extension will be used for building the image:

[source]
---
quarkus.container-image.builder=docker
---

or

[source]
---
quarkus.container-image.builder=jib
---

=== Deploying

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public static Optional<String> getActiveContainerImageCapability(Capabilities ca
.getContainerImageCapabilities(capabilities);
if (activeContainerImageCapabilities.size() > 1) {
throw new IllegalStateException(String.join(" and ", activeContainerImageCapabilities)
+ " were detected, at most one container-image extension can be present. ");
+ " were detected, at most one container-image extension can be present.\n"
+ "Either remove the uneeded ones, or select one using the property 'quarkus.container-image-builder=<extension name (without the `container-image-` prefix)>'.");
}
return activeContainerImageCapabilities.isEmpty() ? Optional.empty()
: Optional.of(activeContainerImageCapabilities.iterator().next());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@
import io.dekorate.kubernetes.annotation.ImagePullPolicy;
import io.dekorate.kubernetes.annotation.ServiceType;
import io.dekorate.kubernetes.config.Annotation;
import io.dekorate.kubernetes.config.Configurator;
import io.dekorate.kubernetes.config.EnvBuilder;
import io.dekorate.kubernetes.config.ImageConfigurationFluent;
import io.dekorate.kubernetes.config.Label;
import io.dekorate.kubernetes.config.LabelBuilder;
import io.dekorate.kubernetes.config.PortBuilder;
Expand Down Expand Up @@ -103,6 +105,7 @@
import io.dekorate.project.ScmInfo;
import io.dekorate.s2i.config.S2iBuildConfig;
import io.dekorate.s2i.config.S2iBuildConfigBuilder;
import io.dekorate.s2i.config.S2iBuildConfigFluent;
import io.dekorate.s2i.decorator.AddBuilderImageStreamResourceDecorator;
import io.dekorate.utils.Annotations;
import io.dekorate.utils.Maps;
Expand Down Expand Up @@ -321,7 +324,32 @@ public void build(ApplicationInfoBuildItem applicationInfo,
determineImagePullPolicy(knativeConfig, needToForceUpdateImagePullPolicy));

applyKnativeConfig(session, project, getResourceName(knativeConfig, applicationInfo), knativeConfig);
//When S2i is disabled we need to pass that information to dekorate.
//Also we need to make sure that the alternatives (instances of ImageConfiguration)
//are properly configured.
if (!capabilities.isCapabilityPresent(Capabilities.CONTAINER_IMAGE_S2I)) {
session.configurators().add(new Configurator<ImageConfigurationFluent<?>>() {
@Override
public void visit(ImageConfigurationFluent<?> image) {
containerImage.ifPresent(i -> {
String group = ImageUtil.getRepository(i.getImage()).split("/")[0];
image.withGroup(group);
i.getRegistry().ifPresent(r -> {
image.withRegistry(r);
});
});
}
});

//JAVA_APP_JAR value is not compatible with our Dockerfiles, so its causing problems
session.resources().decorate(OPENSHIFT, new RemoveEnvVarDecorator("JAVA_APP_JAR"));
session.configurators().add(new Configurator<S2iBuildConfigFluent<?>>() {
@Override
public void visit(S2iBuildConfigFluent<?> s2i) {
s2i.withEnabled(false);
}
});
}
//apply build item configurations to the dekorate session.
applyBuildItems(session,
applicationInfo,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.quarkus.kubernetes.deployment;

import io.dekorate.deps.kubernetes.api.model.ContainerFluent;
import io.dekorate.kubernetes.decorator.AddEnvVarDecorator;
import io.dekorate.kubernetes.decorator.ApplicationContainerDecorator;
import io.dekorate.kubernetes.decorator.Decorator;
import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator;

public class RemoveEnvVarDecorator extends ApplicationContainerDecorator<ContainerFluent<?>> {

private final String envVarName;

public RemoveEnvVarDecorator(String envVarName) {
this(ANY, envVarName);
}

public RemoveEnvVarDecorator(String name, String envVarName) {
super(name);
this.envVarName = envVarName;
}

public void andThenVisit(ContainerFluent<?> container) {
container.removeMatchingFromEnv(e -> e.getName().equals(envVarName));
}

public String getEnvVarKey() {
return this.envVarName;
}

public Class<? extends Decorator>[] after() {
return new Class[] { ResourceProvidingDecorator.class, AddEnvVarDecorator.class };
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((envVarName == null) ? 0 : envVarName.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RemoveEnvVarDecorator other = (RemoveEnvVarDecorator) obj;
if (envVarName == null) {
if (other.envVarName != null)
return false;
} else if (!envVarName.equals(other.envVarName))
return false;
return true;
}
}

0 comments on commit b2a8e63

Please sign in to comment.