From 2b6582331aac1f8d7ce280de4dfd36498794752a Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Sat, 23 Nov 2019 01:45:46 +0530 Subject: [PATCH] Fix #544: Avoiding chown to reduce the image size --- doc/changelog.md | 3 ++ src/main/asciidoc/inc/build/_assembly.adoc | 1 + .../docker/assembly/DockerFileBuilder.java | 30 +++++++++---------- .../docker/assembly/DockerFileKeyword.java | 1 + .../assembly/DockerFileBuilderTest.java | 5 +--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index 953d745eb..eaa14b867 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -6,6 +6,9 @@ - Allow merging of image configurations using ([#360](https://github.com/fabric8io/docker-maven-plugin/issues/360)) - Update to joda-time 2.10.4 (#706) - Add docker:build support for 'network' option #1030 + - Avoiding chown to reduce the image size (#544) + (_Note: Assembly user format `user:user:user` with the third user option has been marked deprecated + and will not be available in future versions of plugin_) - Failure referencing a previous staged image in FROM clause #1264 - Treat bridged and default network mode the same (#1234) - Fix NPE when cacheFrom is missing from config (#1274) diff --git a/src/main/asciidoc/inc/build/_assembly.adoc b/src/main/asciidoc/inc/build/_assembly.adoc index a5be7c789..2f535bdbf 100644 --- a/src/main/asciidoc/inc/build/_assembly.adoc +++ b/src/main/asciidoc/inc/build/_assembly.adoc @@ -61,6 +61,7 @@ assembly configuration It has the general format `user[:group[:run-user]]`. The user and group can be given either as numeric user- and group-id or as names. The group id is optional. If a third part is given, then the build changes to user `root` before changing the ownerships, changes the ownerships and then change to user `run-user` which is then used for the final command to execute. This feature might be needed, if the base image already changed the user (e.g. to 'jboss') so that a `chown` from root to this user would fail. +(_**This third user part has been marked as deprecated and will not be supported in future versions of this plugin.**_) For example, the image `jboss/wildfly` use a "jboss" user under which all commands are executed. Adding files in Docker always happens under the UID root. These files can only be changed to "jboss" is the `chown` command is executed as root. For the following commands to be run again as "jboss" (like the final `standalone.sh`), the plugin switches back to user `jboss` (this is this "run-user") after changing the file ownership. For this example a specification of `jboss:jboss:jboss` would be required. diff --git a/src/main/java/io/fabric8/maven/docker/assembly/DockerFileBuilder.java b/src/main/java/io/fabric8/maven/docker/assembly/DockerFileBuilder.java index 12cb25614..55101fc6c 100644 --- a/src/main/java/io/fabric8/maven/docker/assembly/DockerFileBuilder.java +++ b/src/main/java/io/fabric8/maven/docker/assembly/DockerFileBuilder.java @@ -195,28 +195,26 @@ private static void buildOption(StringBuilder b, DockerFileOption option, Object private void addCopy(StringBuilder b) { if (assemblyUser != null) { - String tmpDir = createTempDir(); - addCopyEntries(b, tmpDir); - - String[] userParts = StringUtils.split(assemblyUser, ":"); - String userArg = userParts.length > 1 ? userParts[0] + ":" + userParts[1] : userParts[0]; - String chmod = "chown -R " + userArg + " " + tmpDir + " && cp -rp " + tmpDir + "/* / && rm -rf " + tmpDir; - if (userParts.length > 2) { - DockerFileKeyword.USER.addTo(b, "root"); - DockerFileKeyword.RUN.addTo(b, chmod); - DockerFileKeyword.USER.addTo(b, userParts[2]); - } else { - DockerFileKeyword.RUN.addTo(b, chmod); + String[] userParts = assemblyUser.split(":"); + + for (CopyEntry entry : copyEntries) { + String dest = (basedir.equals("/") ? "" : basedir) + "/" + entry.destination; + if (userParts.length > 2) { + DockerFileKeyword.USER.addTo(b, "root"); + } + DockerFileKeyword.ADD.addTo(b, " --chown=" + + (userParts.length > 1 ? + userParts[0] + ":" + userParts[1] : + userParts[0]), entry.source, dest); + if (userParts.length > 2) { + DockerFileKeyword.USER.addTo(b, userParts[2]); + } } } else { addCopyEntries(b, ""); } } - private String createTempDir() { - return "/tmp/" + UUID.randomUUID().toString(); - } - private void addCopyEntries(StringBuilder b, String topLevelDir) { for (CopyEntry entry : copyEntries) { String dest = topLevelDir + (basedir.equals("/") ? "" : basedir) + "/" + entry.destination; diff --git a/src/main/java/io/fabric8/maven/docker/assembly/DockerFileKeyword.java b/src/main/java/io/fabric8/maven/docker/assembly/DockerFileKeyword.java index 8bed23005..aaa54b4a0 100644 --- a/src/main/java/io/fabric8/maven/docker/assembly/DockerFileKeyword.java +++ b/src/main/java/io/fabric8/maven/docker/assembly/DockerFileKeyword.java @@ -9,6 +9,7 @@ public enum DockerFileKeyword { MAINTAINER, + ADD, EXPOSE, FROM, SHELL, diff --git a/src/test/java/io/fabric8/maven/docker/assembly/DockerFileBuilderTest.java b/src/test/java/io/fabric8/maven/docker/assembly/DockerFileBuilderTest.java index 9f5c0df6f..fdb1f0b9b 100644 --- a/src/test/java/io/fabric8/maven/docker/assembly/DockerFileBuilderTest.java +++ b/src/test/java/io/fabric8/maven/docker/assembly/DockerFileBuilderTest.java @@ -228,10 +228,7 @@ public void illegalNonAbsoluteBaseDir() { public void testAssemblyUserWithChown() { String dockerFile = new DockerFileBuilder().assemblyUser("jboss:jboss:jboss") .add("a","a/nested").add("b","b/deeper/nested").content(); - String EXPECTED_REGEXP = "chown\\s+-R\\s+jboss:jboss\\s+([^\\s]+)" - + "\\s+&&\\s+cp\\s+-rp\\s+\\1/\\*\\s+/\\s+&&\\s+rm\\s+-rf\\s+\\1"; - Pattern pattern = Pattern.compile(EXPECTED_REGEXP); - assertTrue(pattern.matcher(dockerFile).find()); + assertThat(dockerfileToMap(dockerFile), hasEntry("ADD", "--chown=jboss:jboss b /maven/b/deeper/nested")); } @Test