From f37087a47f3e38600e1b1b1c6bd380c4173dba8d Mon Sep 17 00:00:00 2001 From: Tad Cordle Date: Wed, 22 Aug 2018 13:54:59 -0400 Subject: [PATCH] Add labels to docker context generator --- .../frontend/JavaDockerContextGenerator.java | 29 +++++++++++++++++ .../JavaDockerContextGeneratorTest.java | 11 +++++++ jib-core/src/test/resources/sampleDockerfile | 3 ++ .../jib/gradle/JibPluginIntegrationTest.java | 32 ++++++------------- .../tools/jib/gradle/DockerContextTask.java | 1 + .../tools/jib/maven/DockerContextMojo.java | 1 + .../DockerContextMojoIntegrationTest.java | 10 +++++- 7 files changed, 64 insertions(+), 23 deletions(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/JavaDockerContextGenerator.java b/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/JavaDockerContextGenerator.java index 711f4f058a..799e8e171f 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/JavaDockerContextGenerator.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/JavaDockerContextGenerator.java @@ -31,6 +31,8 @@ import java.nio.file.Path; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import javax.annotation.Nullable; /** @@ -103,6 +105,7 @@ private static void addIfNotEmpty( private String mainClass = ""; private List javaArguments = Collections.emptyList(); private List exposedPorts = Collections.emptyList(); + private Map labels = Collections.emptyMap(); /** * Constructs a Docker context generator for a Java application. @@ -190,6 +193,17 @@ public JavaDockerContextGenerator setExposedPorts(List exposedPorts) { return this; } + /** + * Sets the labels + * + * @param labels the map of labels + * @return this + */ + public JavaDockerContextGenerator setLabels(Map labels) { + this.labels = labels; + return this; + } + /** * Creates the Docker context in {@code #targetDirectory}. * @@ -238,6 +252,9 @@ public void generate(Path targetDirectory) throws IOException { * * EXPOSE [port] * [More EXPOSE instructions, if necessary] + * LABEL [key1]="[value1]" \ + * [key2]="[value2]" \ + * [...] * ENTRYPOINT java [jvm flags] -cp [classpaths] [main class] * CMD [main class args] * } @@ -256,10 +273,22 @@ String makeDockerfile() throws JsonProcessingException { .append(" ") .append(copyDirective.extractionPath); } + dockerfile.append("\n"); for (String port : exposedPorts) { dockerfile.append("\nEXPOSE ").append(port); } + + boolean firstLabel = true; + for (Entry label : labels.entrySet()) { + dockerfile + .append(firstLabel ? "\nLABEL " : " \\\n ") + .append(label.getKey()) + .append("=") + .append(objectMapper.writeValueAsString(label.getValue())); + firstLabel = false; + } + dockerfile .append("\nENTRYPOINT ") .append( diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/JavaDockerContextGeneratorTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/JavaDockerContextGeneratorTest.java index 3d0fadf16d..9bf01cd230 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/JavaDockerContextGeneratorTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/JavaDockerContextGeneratorTest.java @@ -19,6 +19,7 @@ import com.google.cloud.tools.jib.filesystem.DirectoryWalker; import com.google.cloud.tools.jib.image.LayerEntry; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.io.Resources; import java.io.IOException; import java.net.URISyntaxException; @@ -30,6 +31,7 @@ import java.util.Arrays; import java.util.Deque; import java.util.List; +import java.util.Map; import java.util.stream.Stream; import org.junit.Assert; import org.junit.Rule; @@ -124,6 +126,14 @@ public void testMakeDockerfile() throws IOException { String expectedMainClass = "SomeMainClass"; List expectedJavaArguments = Arrays.asList("arg1", "arg2"); List exposedPorts = Arrays.asList("1000/tcp", "2000-2010/udp"); + Map expectedLabels = + ImmutableMap.of( + "key1", + "value", + "key2", + "value with\\backslashes\"and\\\\\"\"quotes\"\\", + "key3", + "value3"); Mockito.when(mockJavaLayerConfigurations.getDependenciesLayerEntry()) .thenReturn( @@ -145,6 +155,7 @@ public void testMakeDockerfile() throws IOException { .setMainClass(expectedMainClass) .setJavaArguments(expectedJavaArguments) .setExposedPorts(exposedPorts) + .setLabels(expectedLabels) .makeDockerfile(); // Need to split/rejoin the string here to avoid cross-platform troubles diff --git a/jib-core/src/test/resources/sampleDockerfile b/jib-core/src/test/resources/sampleDockerfile index d15e47f901..48af0b1114 100644 --- a/jib-core/src/test/resources/sampleDockerfile +++ b/jib-core/src/test/resources/sampleDockerfile @@ -8,5 +8,8 @@ COPY root / EXPOSE 1000/tcp EXPOSE 2000-2010/udp +LABEL key1="value" \ + key2="value with\\backslashes\"and\\\\\"\"quotes\"\\" \ + key3="value3" ENTRYPOINT ["java","-flag","another\"Flag","-cp","/app/resources/:/app/classes/:/app/libs/*","SomeMainClass"] CMD ["arg1","arg2"] 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 5f16e9d883..a1cd24811b 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 @@ -59,7 +59,7 @@ private static String buildAndRun(TestProject testProject, String imageReference Assert.assertThat(buildResult.getOutput(), CoreMatchers.containsString(imageReference)); new Command("docker", "pull", imageReference).run(); - assertHasExposedPorts(imageReference); + assertDockerInspect(imageReference); return new Command("docker", "run", imageReference).run(); } @@ -80,8 +80,7 @@ private static String buildAndRunComplex( Assert.assertThat(buildResult.getOutput(), CoreMatchers.containsString(imageReference)); targetRegistry.pull(imageReference); - assertHasExposedPorts(imageReference); - assertHasLabels(imageReference); + assertDockerInspect(imageReference); return new Command("docker", "run", imageReference).run(); } @@ -94,8 +93,7 @@ private static String buildToDockerDaemonAndRun(TestProject testProject, String buildResult, JibPlugin.BUILD_DOCKER_TASK_NAME, "Built image to Docker daemon as "); Assert.assertThat(buildResult.getOutput(), CoreMatchers.containsString(imageReference)); - assertHasExposedPorts(imageReference); - assertHasLabels(imageReference); + assertDockerInspect(imageReference); return new Command("docker", "run", imageReference).run(); } @@ -137,16 +135,17 @@ private static void assertSimpleCreationTimeIsAfter(Instant before, String image } /** - * Asserts that the test project has the required exposed ports. + * Asserts that the test project has the required exposed ports and labels. * * @param imageReference the image to test * @throws IOException if the {@code docker inspect} command fails to run * @throws InterruptedException if the {@code docker inspect} command is interrupted */ - private static void assertHasExposedPorts(String imageReference) + private static void assertDockerInspect(String imageReference) throws IOException, InterruptedException { + String dockerInspect = new Command("docker", "inspect", imageReference).run(); Assert.assertThat( - new Command("docker", "inspect", imageReference).run(), + dockerInspect, CoreMatchers.containsString( " \"ExposedPorts\": {\n" + " \"1000/tcp\": {},\n" @@ -154,19 +153,8 @@ private static void assertHasExposedPorts(String imageReference) + " \"2001/udp\": {},\n" + " \"2002/udp\": {},\n" + " \"2003/udp\": {}")); - } - - /** - * Asserts that the test project has the required labels. - * - * @param imageReference the image to test - * @throws IOException if the {@code docker inspect} command fails to run - * @throws InterruptedException if the {@code docker inspect} command is interrupted - */ - private static void assertHasLabels(String imageReference) - throws IOException, InterruptedException { Assert.assertThat( - new Command("docker", "inspect", imageReference).run(), + dockerInspect, CoreMatchers.containsString( " \"Labels\": {\n" + " \"key1\": \"value1\",\n" @@ -300,7 +288,7 @@ public void testBuildTar_simple() throws IOException, InterruptedException { new Command("docker", "load", "--input", outputPath).run(); Assert.assertEquals( "Hello, world. An argument.\nfoo\ncat\n", new Command("docker", "run", targetImage).run()); - assertHasExposedPorts(targetImage); + assertDockerInspect(targetImage); assertSimpleCreationTimeIsAfter(beforeBuild, targetImage); } @@ -325,7 +313,7 @@ public void testDockerContext() throws IOException, InterruptedException { .toString()) .run(); - assertHasExposedPorts(imageName); + assertDockerInspect(imageName); Assert.assertEquals( "Hello, world. An argument.\nfoo\ncat\n", new Command("docker", "run", imageName).run()); 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 1ce773c093..ca21ab27c2 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 @@ -121,6 +121,7 @@ public void generateDockerContext() { .setMainClass(mainClass) .setJavaArguments(jibExtension.getArgs()) .setExposedPorts(jibExtension.getExposedPorts()) + .setLabels(jibExtension.getLabels()) .generate(Paths.get(targetDir)); gradleJibLogger.lifecycle("Created Docker context at " + targetDir); diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java index 0fdfd38448..528e1c8809 100644 --- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java +++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java @@ -74,6 +74,7 @@ public void execute() throws MojoExecutionException { .setMainClass(mainClass) .setJavaArguments(getArgs()) .setExposedPorts(getExposedPorts()) + .setLabels(getLabels()) .generate(Paths.get(targetDir)); mavenJibLogger.lifecycle("Created Docker context at " + targetDir); diff --git a/jib-maven-plugin/src/test/java/com/google/cloud/tools/jib/maven/DockerContextMojoIntegrationTest.java b/jib-maven-plugin/src/test/java/com/google/cloud/tools/jib/maven/DockerContextMojoIntegrationTest.java index 99f275ae54..fef2748db7 100644 --- a/jib-maven-plugin/src/test/java/com/google/cloud/tools/jib/maven/DockerContextMojoIntegrationTest.java +++ b/jib-maven-plugin/src/test/java/com/google/cloud/tools/jib/maven/DockerContextMojoIntegrationTest.java @@ -51,8 +51,9 @@ public void testExecute() throws VerificationException, IOException, Interrupted String imageName = "jib/integration-test" + System.nanoTime(); new Command("docker", "build", "-t", imageName, dockerContextDirectory.toString()).run(); + String dockerInspect = new Command("docker", "inspect", imageName).run(); Assert.assertThat( - new Command("docker", "inspect", imageName).run(), + dockerInspect, CoreMatchers.containsString( " \"ExposedPorts\": {\n" + " \"1000/tcp\": {},\n" @@ -60,6 +61,13 @@ public void testExecute() throws VerificationException, IOException, Interrupted + " \"2001/udp\": {},\n" + " \"2002/udp\": {},\n" + " \"2003/udp\": {}")); + Assert.assertThat( + dockerInspect, + CoreMatchers.containsString( + " \"Labels\": {\n" + + " \"key1\": \"value1\",\n" + + " \"key2\": \"value2\"\n" + + " }")); Assert.assertEquals( "Hello, world. An argument.\nfoo\ncat\n", new Command("docker", "run", imageName).run());