-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Add support for defining an entrypoint #873
Conversation
Is there a way we could provide a shortcut to the jib specific java classpath through some kind of template or keyword?
|
I wonder if we can expose the class path as a property — so that it can be referenced but also changed. |
@briandealwis I believe that can be done by calling |
I did some investigation and setting the project properties doesn't seem to much matter. I'm instead going to allow the user to set the classpath — it's not like we have a complicated class path — and use Maven Surefire-style "late-binding" property references (e.g., <container>
<entrypoint>
<arg>/my/custom/java</arg>
<arg>-cp</arg>
<arg>@{jib.classpath}:/some/other/item</arg>
</entrypoint>
</container Gradle doesn't need that providing we expose the classpath as a variable, right?
Or would it make sense to allow setting the classpath too? For example, if a user wanted to add libraries that had been pulled in via <container>
<classpath>
<classes>/opt/path</classes>
<jar>/opt/foo/bar.jar</jar>
</classpath>
</container>
What do you think? |
The late-binding construct is pretty neat! For Gradle, yea, a variable is sufficient - it could be part of the I think we wouldn't need to give a special construct for just setting the classpath. The current workaround is to just place other jars in |
I've opened #894 for exposing the classpath and other possibly other variables. |
JavaEntrypointConstructor.makeDefaultEntrypoint( | ||
jibPluginConfiguration.getJvmFlags(), mainClass); | ||
} else if (jibPluginConfiguration.getMainClass() != null | ||
|| jibPluginConfiguration.getJvmFlags() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just double-checking: for the Gradle plugin code, you do .getJvmFlags().isEmpty()
} else if (jibExtension.getMainClass() != null || !jibExtension.getJvmFlags().isEmpty()) {
while here, you do .getJvmFlags() != null
. Are they correct?
jib-maven-plugin/README.md
Outdated
<!-- Maven doesn't check the names of child tags --> | ||
<entrypoint> | ||
<executable>/busybox/sh</executable> | ||
<script>/bin/start.sh</script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't understand what it means by "Maven doesn't check the names of child tags" until I saw examples using <arg>
below. This also gives me the impression that <executable>
and <script>
are fixed names that I must use. TBH, I think this is confusing. It also makes me to believe that the order of <executable>
and <script>
shouldn't matter. I'd just go with using a single tag name.
Is this PR ready for review? (The Not Ready is present) |
Oops, let me fix up @chanseokoh's findings and I'll remove the label. |
PTAL |
@@ -149,6 +150,18 @@ public JavaDockerContextGenerator setBaseImage(String baseImage) { | |||
return this; | |||
} | |||
|
|||
/** | |||
* Sets the entrypoint to be used as the {@code ENTRYPOINT}. If not empty, then overrides the | |||
* {@link #setJvmFlags(List) jvmFlags} and {@link #setMainClass(String) mainclass}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if we have this method, we should just remove the setJvmFlags
and setMainClass
methods and delegate the call of JavaEntrypointConstructor#makeEntrypoint
to the user of JavaDockerContextGenerator
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's not much specific to Java in JavaDockerContextGenerator
now!
jib-gradle-plugin/README.md
Outdated
@@ -197,6 +197,7 @@ Property | Type | Default | Description | |||
`ports` | `List<String>` | *None* | Ports that the container exposes at runtime (similar to Docker's [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) instruction). | |||
`format` | `String` | `Docker` | Use `OCI` to build an [OCI container image](https://www.opencontainers.org/). | |||
`useCurrentTimestamp` | `boolean` | `false` | By default, Jib wipes all timestamps to guarantee reproducibility. If this parameter is set to `true`, Jib will set the image's creation timestamp to the time of the build, which sacrifices reproducibility for easily being able to tell when your image was created. | |||
`entrypoint` | list | *None* | The executable to be run (similar to Docker's [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) instruction). If set then `jvmFlags` and `mainClass` are ignored. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should leave changes to documentation to another PR (like #871) after the feature is released as a new version of Jib, so users do not see an unreleased feature documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, if this is going in 0.9.10, feel free to push to that branch so we can merge all the documentation changes in at once after releasing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will back out the docs.
@@ -70,8 +70,7 @@ public void execute() throws MojoExecutionException { | |||
|
|||
new JavaDockerContextGenerator(mavenProjectProperties.getJavaLayerConfigurations()) | |||
.setBaseImage(getBaseImage()) | |||
.setJvmFlags(getJvmFlags()) | |||
.setMainClass(mainClass) | |||
.setEntrypoint(getEntrypoint()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is missing the logic to handle JVM flags and main class? We might want to add some tests to make sure JVM flags and mainClass still work.
@@ -16,6 +16,7 @@ dependencies { | |||
|
|||
jib { | |||
container { | |||
entrypoint = ['foo', 'bar', 'baz'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These cause the integration tests to fail, since the integration tests actually try to run the built image, and 'foo' isn't an executable. For example, for testBuildTar_simple
:
java.lang.RuntimeException: Command 'docker run simpleimage:gradle3455722031277561' failed: docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"foo\": executable file not found in $PATH": unknown.
time="2018-08-29T14:41:10-04:00" level=error msg="error waiting for container: context canceled"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To go off of what @coollog said, maybe it'd be a good idea to put this in a separate test that doesn't actually run the image and just inspects it, but continues to run the images generated using mainClass
and jvmFlags
.
Sorry :-( Had someone drop by and pushed — ITs don't run well locally. |
verifier.setAutoclean(false); | ||
verifier.executeGoal("package"); | ||
|
||
verifier.executeGoal("jib:" + BuildTarMojo.GOAL_NAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this should be part of BuildTarMojoIntegrationTest
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a test of building a tar — I chose the tar as it has the lowest overhead of the three build options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, let's add a javadoc describing what this class is testing/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we are using jib:buildTar
to build a tar and then verifying that it has the correct entrypoint here, aren't we? I think I agree that it does make more sense to put this in BuildTarMojoIntegrationTest
. As far as I understand, the test file should correspond directly to a source file (and we don't have an Entrypoint class in jib-maven-plugin).
} | ||
|
||
@Test | ||
public void testBuildTar_entrypoint() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do choose only one of the tasks to test, I would lean towards jib
(build to registry) since it is the main functionality of Jib.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Communicating back to the registry to pull out the entrypoint only adds more overhead. I'd rather build a test mojo / task.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this method should just be called testCustomEntrypoint
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like what you did here, I wonder if it's viable to replace some of our other integration tests with this style to speed things up.
@@ -150,24 +149,13 @@ public JavaDockerContextGenerator setBaseImage(String baseImage) { | |||
} | |||
|
|||
/** | |||
* Sets the JVM flags used in the {@code ENTRYPOINT}. | |||
* Sets the entrypoint to be used as the {@code ENTRYPOINT}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just Sets the {@code ENTRYPOINT}.
?
Assert.assertNotNull(jibTask); | ||
Assert.assertEquals(TaskOutcome.SUCCESS, jibTask.getOutcome()); | ||
Assert.assertThat( | ||
buildResult.getOutput(), CoreMatchers.containsString("Created Docker context at ")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should add a bit more verification here, if you think it's necessary (e.g. build with docker like the other tests and inspect, although that could be too much overhead. Or maybe just check for the dockerfile and make sure it contains the correct commands)?
} | ||
|
||
@Test | ||
public void testBuildTar_entrypoint() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like what you did here, I wonder if it's viable to replace some of our other integration tests with this style to speed things up.
verifier.setAutoclean(false); | ||
verifier.executeGoal("package"); | ||
|
||
verifier.executeGoal("jib:" + BuildTarMojo.GOAL_NAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we are using jib:buildTar
to build a tar and then verifying that it has the correct entrypoint here, aren't we? I think I agree that it does make more sense to put this in BuildTarMojoIntegrationTest
. As far as I understand, the test file should correspond directly to a source file (and we don't have an Entrypoint class in jib-maven-plugin).
I've reverted the integration tests and instead added tests around |
import org.mockito.junit.MockitoJUnitRunner; | ||
|
||
@RunWith(MockitoJUnitRunner.class) | ||
public class PluginConfigurationProcessorTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: short javadoc Tests for {@link PluginConfigurationProcessor}.
import org.mockito.junit.MockitoJUnitRunner; | ||
|
||
@RunWith(MockitoJUnitRunner.class) | ||
public class PluginConfigurationProcessorTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tiny nit: newline after class definition
|
||
@RunWith(MockitoJUnitRunner.class) | ||
public class PluginConfigurationProcessorTest { | ||
@Mock GradleJibLogger gradleJibLogger; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: in this codebase, we prefer to name mocks with a mock- prefix, so like mockGradleJibLogger
.
} | ||
|
||
@Test | ||
public void testBase() throws InvalidImageReferenceException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally, we try to name the test methods with test<method/behavior being tested>[_<thing this test is testing for>]
, so for example, this would be named testProcessCommonConfiguration_default
.
PluginConfigurationProcessor processor = | ||
PluginConfigurationProcessor.processCommonConfiguration( | ||
gradleJibLogger, jibExtension, projectProperties); | ||
ContainerConfiguration configuration = processor.getContainerConfigurationBuilder().build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should prob add a TODO for testing the other processing results too.
.gitignore
Outdated
@@ -1,3 +1,4 @@ | |||
jib-*/bin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this referring to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I wasn't supposed to commit that. I have Eclipse set to generate to bin/, which prevents clashes when running Maven and Gradle from outside.
Fixes #579
Fixes #850
Adds support for providing an entrypoint using
<container><entrypoint>
(Maven) /container.entrypoint
(Gradle).entrypoint
causesjvmFlags
andmainClass
to be ignored, and a warning is issued if they are found.Maven supports both using a list or just a string:
And it turns out that Maven doesn't actually check the names of child elements of a list. So you can use something like the following if you like:
(PR: Not Ready while I get the ITs working.)