diff --git a/jib-gradle-plugin/src/integration-test/java/com/google/cloud/tools/jib/gradle/JibPluginIntegrationTest.java b/jib-gradle-plugin/src/integration-test/java/com/google/cloud/tools/jib/gradle/JibPluginIntegrationTest.java index 22173150d5..617788b5a5 100644 --- a/jib-gradle-plugin/src/integration-test/java/com/google/cloud/tools/jib/gradle/JibPluginIntegrationTest.java +++ b/jib-gradle-plugin/src/integration-test/java/com/google/cloud/tools/jib/gradle/JibPluginIntegrationTest.java @@ -113,7 +113,7 @@ public void testBuild_simple() throws IOException, InterruptedException { } Assert.assertEquals( - "Hello, world. An argument.\n", + "Hello, world. An argument.\nfoo\ncat\n", buildAndRun(simpleTestProject, "gcr.io/jib-integration-testing/simpleimage:gradle")); } @@ -144,7 +144,7 @@ public void testDockerDaemon_empty() throws IOException, InterruptedException { @Test public void testDockerDaemon_simple() throws IOException, InterruptedException { Assert.assertEquals( - "Hello, world. An argument.\n", + "Hello, world. An argument.\nfoo\ncat\n", buildToDockerDaemonAndRun( simpleTestProject, "gcr.io/jib-integration-testing/simpleimage:gradle")); } diff --git a/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/java/com/test/HelloWorld.java b/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/java/com/test/HelloWorld.java index 5fc6d1cf3a..77a3cdc4a1 100644 --- a/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/java/com/test/HelloWorld.java +++ b/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/java/com/test/HelloWorld.java @@ -37,5 +37,12 @@ public static void main(String[] args) throws IOException, URISyntaxException { String world = new String(Files.readAllBytes(worldFile), StandardCharsets.UTF_8); System.out.println(greeting + ", " + world + ". " + (args.length > 0 ? args[0] : "")); + + // Prints the contents of the extra files. + if (Files.exists(Paths.get("/foo"))) { + System.out.println(new String(Files.readAllBytes(Paths.get("/foo")), StandardCharsets.UTF_8)); + System.out.println( + new String(Files.readAllBytes(Paths.get("/bar/cat")), StandardCharsets.UTF_8)); + } } } diff --git a/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/jib/bar/cat b/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/jib/bar/cat new file mode 100644 index 0000000000..5d5b306e57 --- /dev/null +++ b/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/jib/bar/cat @@ -0,0 +1 @@ +cat \ No newline at end of file diff --git a/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/jib/foo b/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/jib/foo new file mode 100644 index 0000000000..1910281566 --- /dev/null +++ b/jib-gradle-plugin/src/integration-test/resources/projects/simple/src/main/jib/foo @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java index 1465486d3c..37f4312470 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java @@ -19,6 +19,7 @@ import com.google.cloud.tools.jib.builder.BuildConfiguration; import com.google.cloud.tools.jib.cache.CacheDirectoryCreationException; import com.google.cloud.tools.jib.configuration.CacheConfiguration; +import com.google.cloud.tools.jib.configuration.LayerConfiguration; import com.google.cloud.tools.jib.docker.DockerClient; import com.google.cloud.tools.jib.frontend.BuildStepsExecutionException; import com.google.cloud.tools.jib.frontend.BuildStepsRunner; @@ -31,6 +32,11 @@ import com.google.cloud.tools.jib.registry.credentials.RegistryCredentials; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nullable; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; @@ -72,7 +78,7 @@ public void setTargetImage(String targetImage) { } @TaskAction - public void buildDocker() throws InvalidImageReferenceException { + public void buildDocker() throws InvalidImageReferenceException, IOException { if (!new DockerClient().isDockerInstalled()) { throw new GradleException(HELPFUL_SUGGESTIONS.forDockerNotInstalled()); } @@ -107,6 +113,15 @@ public void buildDocker() throws InvalidImageReferenceException { .setJvmFlags(jibExtension.getJvmFlags()) .setExposedPorts(ExposedPortsParser.parse(jibExtension.getExposedPorts())) .setAllowHttp(jibExtension.getAllowInsecureRegistries()); + if (Files.exists(jibExtension.getExtraDirectory())) { + try (Stream extraFilesLayerDirectoryFiles = + Files.list(jibExtension.getExtraDirectory())) { + buildConfigurationBuilder.setExtraFilesLayerConfiguration( + LayerConfiguration.builder() + .addEntry(extraFilesLayerDirectoryFiles.collect(Collectors.toList()), "/") + .build()); + } + } CacheConfiguration applicationLayersCacheConfiguration = CacheConfiguration.forPath(gradleProjectProperties.getCacheDirectory()); buildConfigurationBuilder.setApplicationLayersCacheConfiguration( diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java index 2d4d32cbaa..0770560aef 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java @@ -19,6 +19,7 @@ import com.google.cloud.tools.jib.builder.BuildConfiguration; import com.google.cloud.tools.jib.cache.CacheDirectoryCreationException; import com.google.cloud.tools.jib.configuration.CacheConfiguration; +import com.google.cloud.tools.jib.configuration.LayerConfiguration; import com.google.cloud.tools.jib.frontend.BuildStepsExecutionException; import com.google.cloud.tools.jib.frontend.BuildStepsRunner; import com.google.cloud.tools.jib.frontend.ExposedPortsParser; @@ -30,6 +31,11 @@ import com.google.cloud.tools.jib.registry.credentials.RegistryCredentials; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nullable; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; @@ -71,7 +77,7 @@ public void setTargetImage(String targetImage) { } @TaskAction - public void buildImage() throws InvalidImageReferenceException { + public void buildImage() throws InvalidImageReferenceException, IOException { // Asserts required @Input parameters are not null. Preconditions.checkNotNull(jibExtension); GradleBuildLogger gradleBuildLogger = new GradleBuildLogger(getLogger()); @@ -114,6 +120,15 @@ public void buildImage() throws InvalidImageReferenceException { .setExposedPorts(ExposedPortsParser.parse(jibExtension.getExposedPorts())) .setTargetFormat(jibExtension.getFormat()) .setAllowHttp(jibExtension.getAllowInsecureRegistries()); + if (Files.exists(jibExtension.getExtraDirectory())) { + try (Stream extraFilesLayerDirectoryFiles = + Files.list(jibExtension.getExtraDirectory())) { + buildConfigurationBuilder.setExtraFilesLayerConfiguration( + LayerConfiguration.builder() + .addEntry(extraFilesLayerDirectoryFiles.collect(Collectors.toList()), "/") + .build()); + } + } CacheConfiguration applicationLayersCacheConfiguration = CacheConfiguration.forPath(gradleProjectProperties.getCacheDirectory()); buildConfigurationBuilder.setApplicationLayersCacheConfiguration( diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java index 55c78fff86..7a57bc17f3 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java @@ -123,6 +123,7 @@ public void generateDockerContext() { // here. ExposedPortsParser.parse(jibExtension.getExposedPorts()); + // TODO: Add support for extra files layer. new DockerContextGenerator(gradleProjectProperties.getSourceFilesConfiguration()) .setBaseImage(jibExtension.getBaseImage()) .setJvmFlags(jibExtension.getJvmFlags()) diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibExtension.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibExtension.java index 065288823c..5ce87f4af4 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibExtension.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibExtension.java @@ -21,6 +21,7 @@ import com.google.cloud.tools.jib.image.json.BuildableManifestTemplate; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import java.nio.file.Path; import java.util.Collections; import java.util.List; import javax.annotation.Nullable; @@ -66,11 +67,16 @@ public class JibExtension { private static final boolean DEFAULT_USE_ONLY_PROJECT_CACHE = false; private static final boolean DEFAULT_ALLOW_INSECURE_REGISTIRIES = false; + private static Path resolveDefaultExtraDirectory(Path projectDirectory) { + return projectDirectory.resolve("src").resolve("main").resolve("jib"); + } + private final ImageConfiguration from; private final ImageConfiguration to; private final ContainerParameters container; private final Property useOnlyProjectCache; private final Property allowInsecureRegistries; + private final Property extraDirectory; // TODO: Deprecated parameters; remove these 4 private final ListProperty jvmFlags; @@ -92,6 +98,7 @@ public JibExtension(Project project) { useOnlyProjectCache = objectFactory.property(Boolean.class); allowInsecureRegistries = objectFactory.property(Boolean.class); + extraDirectory = objectFactory.property(Path.class); // Sets defaults. from.setImage(DEFAULT_FROM_IMAGE); @@ -99,6 +106,7 @@ public JibExtension(Project project) { args.set(Collections.emptyList()); useOnlyProjectCache.set(DEFAULT_USE_ONLY_PROJECT_CACHE); allowInsecureRegistries.set(DEFAULT_ALLOW_INSECURE_REGISTIRIES); + extraDirectory.set(resolveDefaultExtraDirectory(project.getProjectDir().toPath())); } /** @@ -176,6 +184,10 @@ public void setAllowInsecureRegistries(boolean allowInsecureRegistries) { this.allowInsecureRegistries.set(allowInsecureRegistries); } + public void setExtraDirectory(Path extraDirectory) { + this.extraDirectory.set(extraDirectory); + } + @Internal String getBaseImage() { return Preconditions.checkNotNull(from.getImage()); @@ -251,4 +263,10 @@ boolean getUseOnlyProjectCache() { boolean getAllowInsecureRegistries() { return allowInsecureRegistries.get(); } + + @Input + @Optional + Path getExtraDirectory() { + return extraDirectory.get(); + } }