From cc0f440bfac43bb2abc1b044c45d6c5f9503f5f6 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Wed, 27 Jun 2018 10:37:59 -0400 Subject: [PATCH 1/7] Proposal RFC: Java Agents and More Layers --- proposals/java_agents_and_more_layers.md | 280 +++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 proposals/java_agents_and_more_layers.md diff --git a/proposals/java_agents_and_more_layers.md b/proposals/java_agents_and_more_layers.md new file mode 100644 index 0000000000..84db53944e --- /dev/null +++ b/proposals/java_agents_and_more_layers.md @@ -0,0 +1,280 @@ +# Proposal: Give users ability to add Java agents, arbitrary files, and separate dependencies + +## Motivation + +There are 3 feature requests that may be able to be solved together. These are: + +- Give users ability to add Java agents ([#378](/../../issues/378)) +- Give users ability to copy arbitrary files to the image ([#213](/../../issues/213)) +- Separate frequently changing from non-changing dependencies for more incrementality ([#403](/../../issues/403)) + +## Synopsis of the issues + +### Give users ability to add Java agents ([#378](/../../issues/378)) + +Currently, Jib only adds application files to the container image. These include dependency JARs, resource files, and classes. However, Java developers often run their applications with Java Agents that execute as part of the JVM invocation. + +For example, in [this Dockerfile example](https://github.com/saturnism/spring-petclinic-gcp/blob/master/docker/Dockerfile), the Cloud Debugger and Cloud Profiler agents are added to the container image. The agent archives are first downloaded, and then extracted to their own directory on the image. The archives contains the `.so` file to pass to the java invocation in the form of: + +```shell +java -agentpath:/path/to/agent/files/someagent.so ... +``` + +### Give users ability to copy arbitrary files to the image ([#213](/../../issues/213)) + +Users may wish to add other files for use in the image. Currently, the way to do this would be to place the files within the application resources. However, this conflates the classpath of the application, the file can only be reached under the `/app/resources` path, and changes to the file would mean repushing all the resources. Therefore, users should have some way of adding files to a new custom layer. + +### Separate frequently changing from non-changing dependencies for more incrementality ([#403](/../../issues/403)) + +The dependencies layer tends to be the largest layer in the image, since it contains all the dependency JARs. However, not all dependencies are the same. Some may change more frequently than others (especially `-SNAPSHOT` versions). Therefore, users should have some way to group different dependencies into different layers. For example, separating released artifacts from snapshot artifacts, and grouping dependencies from a BOM into a layer, or separating more frequently changed ones from less frequently changed ones to reduce the amortized push time. + +## Proposal + +The proposal is to keep the configuration for adding additional files and Java agents separate from the configuration for separating the application layers into thinner layers. The point of this is to keep the configuration simple and not allow arbitrary user-controlled layering. + +The configuration for adding additional files (including Java agents) would look something like: + +*(The exact configuration is to be decided before this PR is merged. Alternative naming for this parameter include: `additionalFiles`, `extraFiles`, and `copyFiles`.)* + +*Maven* + +```xml + + + path/to/file + /path/on/image + + + another/file + /another/path/on/image + + +``` + +*Gradle* + +```groovy +addFile 'path/to/file', '/path/on/image' +addFile 'another/file', '/another/path/on/image' +``` + +All of the files would be added to a single new layer. + +For separating application layers into thinner layers, the solution will only separate dependencies for simplicity. Jib will *automatically* separate `-SNAPSHOT` dependencies and dependencies with the same group as the project into a separate layer. + +In the future, we may consider allowing the user to configure this in the form of something like what was originally suggested in [#403](/../../issues/403): + +```xml +com.yourcompany.*, *-SNAPSHOT +``` + +This would match dependencies that are in the `com.yourcompany` package and `SNAPSHOT` dependencies and place these in a new volatile-dependencies layer. + +### Alternative (Rejected) Proposal + +The alternative proposal was rejected because we deemed that layering should be an implementation detail that should not be exposed to the user. + +Currently (`v0.9.1`), Jib's configuration looks like: + +```xml + + ... + ... + ... + + +``` + +- `from` defines the base image and credentials +- `to` defines the target image and credentials +- `container` defines container configuration like JVM flags, program arguments, and exposed ports + +The alternative proposal is to add another top-level configuration object called `layers` to add additional layers with custom files. The configuration would look like: + +```xml + + + + + path/to/file + /path/on/image + + + org.springframework:*, org.hibernate:*... + static/, *.jpg + my.package.that.does.not.change.much.* + + +``` + +The user can choose whatever subset of `layer` parameters to define. + +Parameter | Description +--- | --- +files | In the form `:`, where the file `` is added to the image at path ``. +matchDependencies | Matches dependencies with the given patterns and adds those dependency artifacts into this layer rather than the original dependencies layer. +matchResources | Like `matchDependencies`, but for resource files. +matchClasses | ... but for classes files. + +For implementation, `files` should be implemented first to support Java agent usage and `match*` could be added in later updates. + +And similarly for Gradle: + +```groovy +layer { + file 'path/to/file', '/path/on/image' + matchDependencies = 'org.springframework:*, org.hibernate:*...' + matchResources = 'static/, *.jpg' + matchClasses = 'my.package.that.does.not.change.much.*' +} +``` + +## Other options considered + +### Give users ability to add Java agents ([#378](/../../issues/378)) + +#### Option 1 - Specific configuration for each agent + +Provide agent-specific configuration options similar to [CloudFoundry BuildPacks](https://github.com/cloudfoundry/java-buildpack). This would mean that **each agent would have a different set of configuration parameters** specifically for that agent. Each agent-specific implementation would automatically download and add the agent files to the container image and automatically configure the JVM flags. + +**Benefit:** User would be given the exact and minimal controls over specific agents. +**Downside:** We would have to implement and maintain custom implementations for each agent we wish to support. + +#### Option 2 - `agents` configuration + +Provide configuration options to add agents by specifying the archive download location or local files. For example, the configuration could look like: + +```xml + + + ${project.basedir}/myagent-archive.tar.gz + /opt/myagent + + + + + -agentpath:/opt/myagent/myagent.so=-some_option=yes + + +``` + +#### Option 3 - copy to image + +Solve this as part of *### Give users ability to copy arbitrary files to the image ([#213](/../../issues/213))*. + +### Give users ability to copy arbitrary files to the image ([#213](/../../issues/213)) + +#### Option 1 - Single custom layer + +The user defines files to copy, along with their destinations on the image. For example: + +```xml + + + path/to/file + /path/on/image + + +``` + +All files defined would be placed in a single layer. + +**Benefit:** Prevents possible large number of layers. +**Downside:** All files are in same layer. + +#### Option 2 - Multiple custom layers + +The user can define their own custom layers, and define what files to copy into each layer. For example: + +```xml + + + + + path/to/file + /path/on/image + + + + +``` + +**Benefit:** Can be used to solve all three issues (with more options for other things to add to such custom layers) +**Downside:** Quite verbose + +#### Option 3 - Multiple automatic layers + +The user defines files to copy like in *Option 1*, but a separate layer is generated for each copy. + +#### Option 4 - Multiple custom layers by layer ID + +Like in *Option 1*, but the user can set a layer ID for each copy. Copies with the same layer ID are placed in the same layer. For example: + +```xml + + + path/to/file + /path/on/image + somelayername + + + path/to/another/file + /another/path/on/image + somelayername ← this goes in the same layer as the first + + + path/to/yet/another/file + /path/on/image + someotherlayername + + +``` + +**Benefit:** Keeps the configuration concise + +### Separate frequently changing from non-changing dependencies for more incrementality ([#403](/../../issues/403)) + +#### Option 1 - Top-level configuration + +Configuration options `silentDependencies` and `mutableDependencies`, as recommended in [#403](/../../issues/403). Example: + +```xml +org.springframework:*, org.hibernate:*, *:commons-*, org.webjars:* +com.yourcompany:*,*:*:*-SNAPSHOT +``` + +**Benefit:** Simple and understandable +**Downside:** Does not solve any of the other issues + +#### Option 2 - for classes, resources, and dependencies + +The user would be able to define patterns to match against both dependencies and any other files that go in the application layers. These matched files are taken from the `classes`, `resources`, and `dependencies` layers and placed into 3 new layers - `silentClasses`, `silentResources`, and `silentDependencies`. The configuration would look like: + +```xml +org.springframework:*, org.hibernate:*... +static/, *.jpg +my.package.that.does.not.change.much +``` + +**Benefit:** Supports splitting of all application layers into thinner layers. +**Downside:** Does not solve any of the other issues + +#### Option 3 - in custom layers + +Similar to the above *[Option 2 - Multiple custom layers](fix link)*: + +```xml + + + ... + org.springframework:*, org.hibernate:*... + static/, *.jpg + my.package.that.does.not.change.much + + +``` + +In the above example, each configuration option for `additionalLayer` is optional. + +**Benefits:** Solves all 3 issues +**Downside:** Might be confusing From 95e8e4969537c533a4934d30d08058a817997dce Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Wed, 27 Jun 2018 10:42:07 -0400 Subject: [PATCH 2/7] Fixes link. --- proposals/java_agents_and_more_layers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/java_agents_and_more_layers.md b/proposals/java_agents_and_more_layers.md index 84db53944e..5c124a2634 100644 --- a/proposals/java_agents_and_more_layers.md +++ b/proposals/java_agents_and_more_layers.md @@ -261,7 +261,7 @@ The user would be able to define patterns to match against both dependencies and #### Option 3 - in custom layers -Similar to the above *[Option 2 - Multiple custom layers](fix link)*: +Similar to the above *[Option 2 - Multiple custom layers](#option-2---multiple-custom-layers)*: ```xml From 498d06947523e04e0fb15fd381df9ef5541324c4 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Fri, 29 Jun 2018 12:31:45 -0400 Subject: [PATCH 3/7] Addresses briandealwis comments. --- proposals/java_agents_and_more_layers.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/java_agents_and_more_layers.md b/proposals/java_agents_and_more_layers.md index 5c124a2634..82d8f5e007 100644 --- a/proposals/java_agents_and_more_layers.md +++ b/proposals/java_agents_and_more_layers.md @@ -58,7 +58,7 @@ addFile 'path/to/file', '/path/on/image' addFile 'another/file', '/another/path/on/image' ``` -All of the files would be added to a single new layer. +*Directories will be handled using [rsync](https://linux.die.net/man/1/rsync) source-path semantics, where, for example, `addFile 'path/to/directory', '/path/on/image'` would put all the files in `path/to/directory` into the directory `/path/on/image/directory`, but `addFile 'path/to/directory', '/path/on/image'` (trailing slash) would put all the files into the directory `/path/on/image`.* For separating application layers into thinner layers, the solution will only separate dependencies for simplicity. Jib will *automatically* separate `-SNAPSHOT` dependencies and dependencies with the same group as the project into a separate layer. @@ -70,9 +70,11 @@ In the future, we may consider allowing the user to configure this in the form o This would match dependencies that are in the `com.yourcompany` package and `SNAPSHOT` dependencies and place these in a new volatile-dependencies layer. +\* + ### Alternative (Rejected) Proposal -The alternative proposal was rejected because we deemed that layering should be an implementation detail that should not be exposed to the user. +**The alternative proposal was rejected** because we deemed that layering should be an implementation detail that should not be exposed to the user. Currently (`v0.9.1`), Jib's configuration looks like: From a557978cb658c4ee11384dedc6f37b54cd1be259 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Fri, 29 Jun 2018 14:30:57 -0400 Subject: [PATCH 4/7] Adds trailing slash. --- proposals/java_agents_and_more_layers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/java_agents_and_more_layers.md b/proposals/java_agents_and_more_layers.md index 82d8f5e007..316c9f6437 100644 --- a/proposals/java_agents_and_more_layers.md +++ b/proposals/java_agents_and_more_layers.md @@ -58,7 +58,7 @@ addFile 'path/to/file', '/path/on/image' addFile 'another/file', '/another/path/on/image' ``` -*Directories will be handled using [rsync](https://linux.die.net/man/1/rsync) source-path semantics, where, for example, `addFile 'path/to/directory', '/path/on/image'` would put all the files in `path/to/directory` into the directory `/path/on/image/directory`, but `addFile 'path/to/directory', '/path/on/image'` (trailing slash) would put all the files into the directory `/path/on/image`.* +*Directories will be handled using [rsync](https://linux.die.net/man/1/rsync) source-path semantics, where, for example, `addFile 'path/to/directory', '/path/on/image'` would put all the files in `path/to/directory` into the directory `/path/on/image/directory`, but `addFile 'path/to/directory/', '/path/on/image'` (trailing slash) would put all the files into the directory `/path/on/image`.* For separating application layers into thinner layers, the solution will only separate dependencies for simplicity. Jib will *automatically* separate `-SNAPSHOT` dependencies and dependencies with the same group as the project into a separate layer. From 40772db7352a51629502622c145254d9a1810ec8 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Fri, 29 Jun 2018 16:32:34 -0400 Subject: [PATCH 5/7] Changes to be Dockerfile COPY semantics. --- proposals/java_agents_and_more_layers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/java_agents_and_more_layers.md b/proposals/java_agents_and_more_layers.md index 316c9f6437..bcc44c28d7 100644 --- a/proposals/java_agents_and_more_layers.md +++ b/proposals/java_agents_and_more_layers.md @@ -58,7 +58,7 @@ addFile 'path/to/file', '/path/on/image' addFile 'another/file', '/another/path/on/image' ``` -*Directories will be handled using [rsync](https://linux.die.net/man/1/rsync) source-path semantics, where, for example, `addFile 'path/to/directory', '/path/on/image'` would put all the files in `path/to/directory` into the directory `/path/on/image/directory`, but `addFile 'path/to/directory/', '/path/on/image'` (trailing slash) would put all the files into the directory `/path/on/image`.* +*The semantics of `from` and `to` will mostly be similar to [Dockerfile `COPY`](https://docs.docker.com/engine/reference/builder/#copy). However, glob matching won't be supported.* For separating application layers into thinner layers, the solution will only separate dependencies for simplicity. Jib will *automatically* separate `-SNAPSHOT` dependencies and dependencies with the same group as the project into a separate layer. From de3640796ace92f1f92963a899597e2f4dbd56b9 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Wed, 22 Aug 2018 18:03:55 -0400 Subject: [PATCH 6/7] Adds src/main/jib and moves to archives. --- .../{ => archives}/java_agents_and_more_layers.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) rename proposals/{ => archives}/java_agents_and_more_layers.md (94%) diff --git a/proposals/java_agents_and_more_layers.md b/proposals/archives/java_agents_and_more_layers.md similarity index 94% rename from proposals/java_agents_and_more_layers.md rename to proposals/archives/java_agents_and_more_layers.md index bcc44c28d7..8411a7d804 100644 --- a/proposals/java_agents_and_more_layers.md +++ b/proposals/archives/java_agents_and_more_layers.md @@ -1,5 +1,7 @@ # Proposal: Give users ability to add Java agents, arbitrary files, and separate dependencies +Implemented in: **v0.9.5** + ## Motivation There are 3 feature requests that may be able to be solved together. These are: @@ -30,6 +32,16 @@ The dependencies layer tends to be the largest layer in the image, since it cont ## Proposal +The proposal is to define a new convention for adding more files to the Jib container. + +The user can add arbitrary files to the image by placing them in a `src/main/jib` directory. This will copy all files within `src/main/jib` to the image's root directory `/`, maintaining the same structure. For example, if the user has a text file at `src/main/jib/dir/hello.txt`, then the built image have `/dir/hello.txt`. + +The directory should also be able to be configured to override the `src/main/jib` default. + +### Alternative (Rejected) Proposal + +**The alternative proposal was rejected** because we deemed that it required too much extra configuration on the part of the user. + The proposal is to keep the configuration for adding additional files and Java agents separate from the configuration for separating the application layers into thinner layers. The point of this is to keep the configuration simple and not allow arbitrary user-controlled layering. The configuration for adding additional files (including Java agents) would look something like: @@ -70,8 +82,6 @@ In the future, we may consider allowing the user to configure this in the form o This would match dependencies that are in the `com.yourcompany` package and `SNAPSHOT` dependencies and place these in a new volatile-dependencies layer. -\* - ### Alternative (Rejected) Proposal **The alternative proposal was rejected** because we deemed that layering should be an implementation detail that should not be exposed to the user. From 250d978c1771941b39bd92cf948f4abf719b1331 Mon Sep 17 00:00:00 2001 From: Q Chen Date: Thu, 23 Aug 2018 08:41:19 -0400 Subject: [PATCH 7/7] Puts alternative proposals under H2. --- proposals/archives/java_agents_and_more_layers.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/archives/java_agents_and_more_layers.md b/proposals/archives/java_agents_and_more_layers.md index 8411a7d804..43edfc0322 100644 --- a/proposals/archives/java_agents_and_more_layers.md +++ b/proposals/archives/java_agents_and_more_layers.md @@ -38,7 +38,9 @@ The user can add arbitrary files to the image by placing them in a `src/main/jib The directory should also be able to be configured to override the `src/main/jib` default. -### Alternative (Rejected) Proposal +## Alternative Proposals + +### Rejected Proposal 1 **The alternative proposal was rejected** because we deemed that it required too much extra configuration on the part of the user. @@ -82,7 +84,7 @@ In the future, we may consider allowing the user to configure this in the form o This would match dependencies that are in the `com.yourcompany` package and `SNAPSHOT` dependencies and place these in a new volatile-dependencies layer. -### Alternative (Rejected) Proposal +### Rejected Proposal 2 **The alternative proposal was rejected** because we deemed that layering should be an implementation detail that should not be exposed to the user.