Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude docker compose #159

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 7 additions & 4 deletions first-party/jib-spring-boot-extension-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

Provides extra support for Spring Boot applications. As of now, this extension provides the following functionalities:

- Including and excluding `spring-boot-devtools`
- Including and excluding `spring-boot-devtools` and / or `spring-boot-docker-compose`

Handles the [Spring Boot developer tools issue](https://github.com/GoogleContainerTools/jib/issues/2336) that Jib always (correctly) packages the [`spring-boot-devtools`](https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools) dependency. Applying this extension makes Jib include or exclude the dependency in the same way Spring Boot does for their repackaged fat JAR. For example, Spring Boot by default excludes `spring-boot-devtools` from the repackaged JAR, so the extension by default excludes it from an image too. On the other hand, if you set `<excludeDevtools>false` in Spring Boot, the extension does nothing (keeps the dependency in the image).
Handles the [Spring Boot issue](https://github.com/GoogleContainerTools/jib/issues/2336) that Jib always (correctly) packages [optional dependencies](https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools). Applying this extension makes Jib include or exclude these dependencies in the same way Spring Boot does for their repackaged fat JAR. For example, Spring Boot by default excludes `spring-boot-devtools` and `spring-boot-docker-compose` from the repackaged JAR, so the extension by default excludes them from an image too. On the other hand, if you set `<excludeDevtools>false` or `<excludeDockerCompose>false` in Spring Boot, the extension keeps those dependencies in the image.

Note that one can still properly and correctly resolve this "issue" without this extension, for example, by setting up two Maven profiles, as explained in the issue link above.

Expand All @@ -22,15 +22,18 @@ Check out the [genenal instructions](../../README.md#using-jib-plugin-extensions
<dependency>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-spring-boot-extension-maven</artifactId>
<version>0.1.0</version>
<version>0.5.0</version>
</dependency>
</dependencies>

<configuration>
...
<pluginExtensions>
<pluginExtension>
<implementation>com.google.cloud.tools.jib.maven.extension.springboot.JibSpringBootExtension</implementation>
<implementation>com.google.cloud.tools.jib.maven.extension.springboot.JibSpringBootDevtoolsExtension</implementation>
</pluginExtension>
<pluginExtension>
<implementation>com.google.cloud.tools.jib.maven.extension.springboot.JibSpringBootDockerComposeExtension</implementation>
</pluginExtension>
</pluginExtensions>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2020 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.google.cloud.tools.jib.maven.extension.springboot;

public class JibSpringBootDevtoolsExtension implements JibSpringBootModuleExtension {

@Override
public String getModuleName() {
return "spring-boot-devtools";
}

@Override
public String getExcludePropertyName() {
return "excludeDevtools";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2020 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.google.cloud.tools.jib.maven.extension.springboot;

public class JibSpringBootDockerComposeExtension implements JibSpringBootModuleExtension {

@Override
public String getModuleName() {
return "spring-boot-docker-compose";
}

@Override
public String getExcludePropertyName() {
return "excludeDockerCompose";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,85 +25,83 @@
import com.google.cloud.tools.jib.maven.extension.MavenData;
import com.google.cloud.tools.jib.plugins.extension.ExtensionLogger;
import com.google.cloud.tools.jib.plugins.extension.ExtensionLogger.LogLevel;
import com.google.cloud.tools.jib.plugins.extension.JibPluginExtensionException;
import com.google.common.annotations.VisibleForTesting;
import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;

public class JibSpringBootExtension implements JibMavenPluginExtension<Void> {
public interface JibSpringBootModuleExtension extends JibMavenPluginExtension<Void> {

@Override
public Optional<Class<Void>> getExtraConfigType() {
default Optional<Class<Void>> getExtraConfigType() {
return Optional.empty();
}

String getModuleName();
String getExcludePropertyName();

@Override
public ContainerBuildPlan extendContainerBuildPlan(
default ContainerBuildPlan extendContainerBuildPlan(
ContainerBuildPlan buildPlan,
Map<String, String> properties,
Optional<Void> config,
MavenData mavenData,
ExtensionLogger logger)
throws JibPluginExtensionException {
logger.log(LogLevel.LIFECYCLE, "Running Jib Spring Boot extension");
ExtensionLogger logger) {
logger.log(LogLevel.LIFECYCLE, "Running Jib Spring Boot extension for module " + getModuleName());

if (!shouldExcludeDevtools(mavenData.getMavenProject(), logger)) {
logger.log(LogLevel.INFO, "Keeping spring-boot-devtools (if any)");
if (!shouldExcludeModule(mavenData.getMavenProject(), logger)) {
logger.log(LogLevel.INFO, "Keeping " + getModuleName() + " (if any)");
return buildPlan;
}
logger.log(LogLevel.INFO, "Removing spring-boot-devtools (if any)");
logger.log(LogLevel.INFO, "Removing " + getModuleName() + " (if any)");

List<LayerObject> newLayers =
buildPlan.getLayers().stream()
.map(JibSpringBootExtension::filterOutDevtools)
.map(this::filterOutModule)
.collect(Collectors.toList());
return buildPlan.toBuilder().setLayers(newLayers).build();
}

@VisibleForTesting
static boolean isDevtoolsJar(File file) {
return file.getName().startsWith("spring-boot-devtools-") && file.getName().endsWith(".jar");
}

@VisibleForTesting
static boolean shouldExcludeDevtools(MavenProject project, ExtensionLogger logger) {
default boolean shouldExcludeModule(MavenProject project, ExtensionLogger logger) {
Plugin bootPlugin = project.getPlugin("org.springframework.boot:spring-boot-maven-plugin");
if (bootPlugin == null) {
logger.log(
LogLevel.WARN,
"Jib Spring Boot extension: project doesn't have spring-boot-maven-plugin?");
LogLevel.WARN,
"Jib Spring Boot extension: project doesn't have spring-boot-maven-plugin?");
return true;
}

Xpp3Dom configuration = (Xpp3Dom) bootPlugin.getConfiguration();
if (configuration != null) {
Xpp3Dom excludeDevtools = configuration.getChild("excludeDevtools");
Xpp3Dom excludeDevtools = configuration.getChild(getExcludePropertyName());
if (excludeDevtools != null) {
return "true".equalsIgnoreCase(excludeDevtools.getValue());
}
}
return true; // Spring Boot's <excludeDevtools> default is true.
return true; // Spring Boot's exclude property default is true.
}

@VisibleForTesting
static LayerObject filterOutDevtools(LayerObject layerObject) {
default LayerObject filterOutModule(LayerObject layerObject) {
String dependencyLayerName = JavaContainerBuilder.LayerType.DEPENDENCIES.getName();
if (!dependencyLayerName.equals(layerObject.getName())) {
return layerObject;
}

FileEntriesLayer layer = (FileEntriesLayer) layerObject;
Predicate<FileEntry> notDevtoolsJar =
fileEntry -> !isDevtoolsJar(fileEntry.getSourceFile().toFile());
fileEntry -> !isModuleJar(fileEntry.getSourceFile().toFile());
List<FileEntry> newEntries =
layer.getEntries().stream().filter(notDevtoolsJar).collect(Collectors.toList());
return layer.toBuilder().setEntries(newEntries).build();
}

default boolean isModuleJar(File file) {
return file.getName().startsWith(getModuleName() + "-") && file.getName().endsWith(".jar");
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
com.google.cloud.tools.jib.maven.extension.springboot.JibSpringBootExtension
com.google.cloud.tools.jib.maven.extension.springboot.JibSpringBootDevtoolsExtension