Skip to content

Commit

Permalink
Merge pull request #8815 from geoand/minikube-pull-policy
Browse files Browse the repository at this point in the history
Make deploying to Minikube effortless when not using a registry
  • Loading branch information
geoand authored Apr 24, 2020
2 parents fac9276 + 4781238 commit a527712
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.quarkus.kubernetes.deployment;

import static io.quarkus.container.image.deployment.util.ImageUtil.hasRegistry;

import java.util.Optional;

import io.quarkus.container.image.deployment.ContainerImageCapabilitiesUtil;
import io.quarkus.container.spi.ContainerImageInfoBuildItem;
import io.quarkus.deployment.Capabilities;

final class ContainerImageUtil {

private ContainerImageUtil() {
}

static boolean isRegistryMissingAndNotS2I(Capabilities capabilities, ContainerImageInfoBuildItem containerImageInfo) {
Optional<String> activeContainerImageCapability = ContainerImageCapabilitiesUtil
.getActiveContainerImageCapability(capabilities);
if (!activeContainerImageCapability.isPresent()) { // shouldn't ever happen when this method is called
return false;
}

return !hasRegistry(containerImageInfo.getImage())
&& !Capabilities.CONTAINER_IMAGE_S2I.equals(activeContainerImageCapability.get());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

package io.quarkus.kubernetes.deployment;

import static io.quarkus.container.image.deployment.util.ImageUtil.hasRegistry;
import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT;
import static io.quarkus.kubernetes.deployment.Constants.KUBERNETES;
import static io.quarkus.kubernetes.deployment.Constants.OPENSHIFT;
Expand Down Expand Up @@ -33,6 +32,7 @@
import io.quarkus.deployment.IsNormal;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.builditem.DeploymentResultBuildItem;
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
import io.quarkus.kubernetes.client.deployment.KubernetesClientErrorHanlder;
Expand All @@ -52,7 +52,9 @@ public void deploy(KubernetesClientBuildItem kubernetesClient,
List<KubernetesDeploymentTargetBuildItem> kubernetesDeploymentTargets,
OutputTargetBuildItem outputTarget,
Capabilities capabilities,
BuildProducer<DeploymentResultBuildItem> deploymentResult) {
BuildProducer<DeploymentResultBuildItem> deploymentResult,
// needed to ensure that this step runs after the container image has been built
@SuppressWarnings("unused") List<ArtifactResultBuildItem> artifactResults) {

Optional<String> activeContainerImageCapability = ContainerImageCapabilitiesUtil
.getActiveContainerImageCapability(capabilities);
Expand All @@ -64,11 +66,11 @@ public void deploy(KubernetesClientBuildItem kubernetesClient,
}

boolean isContainerImageS2IPresent = Capabilities.CONTAINER_IMAGE_S2I.equals(activeContainerImageCapability.get());
if (!hasRegistry(containerImageInfo.getImage()) && !isContainerImageS2IPresent) {
if (ContainerImageUtil.isRegistryMissingAndNotS2I(capabilities, containerImageInfo)) {
log.warn(
"A Kubernetes deployment was requested, but the container image to be built will not be pushed to any registry"
+ " because \"quarkus.container-image.registry\" has not been set. The Kubernetes deployment will only work properly"
+ " if the cluster is using the local Docker daemon.");
+ " if the cluster is using the local Docker daemon. For that reason 'ImagePullPolicy' is being force-set to 'IfNotPresent'");
}

//Get any build item but if the build was s2i, use openshift
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

import io.dekorate.Session;
import io.dekorate.SessionWriter;
import io.dekorate.kubernetes.annotation.ImagePullPolicy;
import io.dekorate.kubernetes.config.Annotation;
import io.dekorate.kubernetes.config.EnvBuilder;
import io.dekorate.kubernetes.config.Label;
Expand Down Expand Up @@ -79,6 +80,7 @@
import io.quarkus.container.spi.BaseImageInfoBuildItem;
import io.quarkus.container.spi.ContainerImageInfoBuildItem;
import io.quarkus.container.spi.ContainerImageLabelBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.IsNormal;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
Expand Down Expand Up @@ -179,6 +181,7 @@ public void build(ApplicationInfoBuildItem applicationInfo,
KubernetesConfig kubernetesConfig,
OpenshiftConfig openshiftConfig,
KnativeConfig knativeConfig,
Capabilities capabilities,
List<KubernetesAnnotationBuildItem> kubernetesAnnotations,
List<KubernetesLabelBuildItem> kubernetesLabels,
List<KubernetesEnvBuildItem> kubernetesEnvs,
Expand Down Expand Up @@ -224,11 +227,16 @@ public void build(ApplicationInfoBuildItem applicationInfo,

//Apply configuration
applyGlobalConfig(session, kubernetesConfig);

ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);

boolean needToForceUpdateImagePullPolicy = needToForceUpdateImagePullPolicy(containerImage, capabilities);
applyConfig(session, project, KUBERNETES, getResourceName(kubernetesConfig, applicationInfo), kubernetesConfig,
now);
applyConfig(session, project, OPENSHIFT, getResourceName(openshiftConfig, applicationInfo), openshiftConfig, now);
applyConfig(session, project, KNATIVE, getResourceName(knativeConfig, applicationInfo), knativeConfig, now);
now, determineImagePullPolicy(kubernetesConfig, needToForceUpdateImagePullPolicy));
applyConfig(session, project, OPENSHIFT, getResourceName(openshiftConfig, applicationInfo), openshiftConfig, now,
determineImagePullPolicy(openshiftConfig, needToForceUpdateImagePullPolicy));
applyConfig(session, project, KNATIVE, getResourceName(knativeConfig, applicationInfo), knativeConfig, now,
determineImagePullPolicy(knativeConfig, needToForceUpdateImagePullPolicy));

//apply build item configurations to the dekorate session.
applyBuildItems(session,
Expand Down Expand Up @@ -299,15 +307,16 @@ private void applyGlobalConfig(Session session, KubernetesConfig config) {

/**
* Apply changes to the target resource group
*
*
* @param session The session to apply the changes
* @param target The deployment target (e.g. kubernetes, openshift, knative)
* @param name The name of the resource to accept the configuration
* @param config The {@link PlatformConfiguration} instance
* @param now
* @param now ZonedDateTime indicating the current time
* @param imagePullPolicy Kubernetes ImagePullPolicy to be used
*/
private void applyConfig(Session session, Project project, String target, String name, PlatformConfiguration config,
ZonedDateTime now) {
ZonedDateTime now, ImagePullPolicy imagePullPolicy) {
if (OPENSHIFT.equals(target)) {
session.resources().decorate(OPENSHIFT, new AddLabelDecorator(new Label(OPENSHIFT_APP_RUNTIME, QUARKUS)));
}
Expand Down Expand Up @@ -347,7 +356,7 @@ private void applyConfig(Session session, Project project, String target, String
});

//Image Pull
session.resources().decorate(target, new ApplyImagePullPolicyDecorator(config.getImagePullPolicy()));
session.resources().decorate(target, new ApplyImagePullPolicyDecorator(imagePullPolicy));
config.getImagePullSecrets().ifPresent(l -> {
l.forEach(s -> session.resources().decorate(target, new AddImagePullSecretDecorator(name, s)));
});
Expand Down Expand Up @@ -391,6 +400,29 @@ private void applyConfig(Session session, Project project, String target, String
});
}

/**
* When there is no registry defined and s2i isn't being used, the only ImagePullPolicy that can work is 'IfNotPresent'.
* This case comes up when users want to deploy their application to a cluster like Minikube where no registry is used
* and instead they rely on the image being built directly into the docker daemon that the cluster uses.
*/
private boolean needToForceUpdateImagePullPolicy(Optional<ContainerImageInfoBuildItem> containerImage,
Capabilities capabilities) {
boolean result = containerImage.isPresent()
&& ContainerImageUtil.isRegistryMissingAndNotS2I(capabilities, containerImage.get());
if (result) {
log.warn("No registry was set for the container image, so 'ImagePullPolicy' is being force-set to 'IfNotPresent'");
return true;
}
return false;
}

private ImagePullPolicy determineImagePullPolicy(PlatformConfiguration config, boolean needToForceUpdateImagePullPolicy) {
if (needToForceUpdateImagePullPolicy) {
return ImagePullPolicy.IfNotPresent;
}
return config.getImagePullPolicy();
}

private void applyBuildItems(Session session,
ApplicationInfoBuildItem applicationInfo,
KubernetesConfig kubernetesConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public void assertGeneratedResources() throws IOException {
assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
assertThat(t.getSpec()).satisfies(podSpec -> {
assertThat(podSpec.getContainers()).hasOnlyOneElementSatisfying(container -> {
assertThat(container.getImagePullPolicy()).isEqualTo("Always"); // expect the default value
assertThat(container.getPorts()).hasOnlyOneElementSatisfying(p -> {
assertThat(p.getContainerPort()).isEqualTo(8080);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public void assertGeneratedResources() throws IOException {
assertThat(container.getLivenessProbe()).isNotNull().satisfies(p -> {
assertProbePath(p, "/health/live");
});
// since no registry was set and a container-image extension exists, we force-set 'IfNotPresent'
assertThat(container.getImagePullPolicy()).isEqualTo("IfNotPresent");
});
});
});
Expand Down

0 comments on commit a527712

Please sign in to comment.