-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add core 'ports' functionality to docker context exporter, fix cross-platform Dockerfile write inconsistency #438
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
Changes from 31 commits
0b82cf6
dd44f8b
fcfa21a
39c34a4
ac8d674
218bce1
5e68c1b
d60d7eb
6b7fba5
fefd342
7fa64bb
a71e7bb
519d720
901c7d8
cc25cd4
7c6f7f1
d2ab9d8
c13c6c2
bfec9bd
fb2fc0b
c8dc74d
1a71919
ddf8336
aab244a
964d85a
9185594
da15400
165a0d3
213d32c
8036cb3
0324e2a
a0aed3d
0c550c8
5c19ef5
b68aebb
b9bd25a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,6 @@ | |
import com.google.common.annotations.VisibleForTesting; | ||
import com.google.common.base.Preconditions; | ||
import com.google.common.io.MoreFiles; | ||
import com.google.common.io.Resources; | ||
import java.io.IOException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.DirectoryNotEmptyException; | ||
|
@@ -31,6 +30,7 @@ | |
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.regex.Matcher; | ||
import java.util.stream.Collectors; | ||
import javax.annotation.Nullable; | ||
|
||
/** | ||
|
@@ -46,12 +46,45 @@ | |
*/ | ||
public class DockerContextGenerator { | ||
|
||
/** | ||
* Formats a list for the Dockerfile's ENTRYPOINT or CMD. | ||
* | ||
* @see <a | ||
* href="https://docs.docker.com/engine/reference/builder/#exec-form-entrypoint-example">https://docs.docker.com/engine/reference/builder/#exec-form-entrypoint-example</a> | ||
* @param items the list of items to join into an array. | ||
* @return a string in the format: ["item1","item2",...] | ||
*/ | ||
@VisibleForTesting | ||
static String joinAsJsonArray(List<String> items) { | ||
return "[" | ||
+ String.join( | ||
",", | ||
items | ||
.stream() | ||
.map(item -> "\"" + item.replaceAll("\"", Matcher.quoteReplacement("\\\"")) + "\"") | ||
.collect(Collectors.toList())) | ||
+ "]"; | ||
} | ||
|
||
/** | ||
* Builds a list of Dockerfile "EXPOSE" instructions. | ||
* | ||
* @param exposedPorts the list of ports numbers/ranges to expose | ||
* @return a string containing an EXPOSE instruction for each of the entries | ||
*/ | ||
@VisibleForTesting | ||
static String makeExposeInstructions(List<String> exposedPorts) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could also be moved to |
||
return String.join( | ||
"\n", exposedPorts.stream().map(port -> "EXPOSE " + port).collect(Collectors.toList())); | ||
} | ||
|
||
private final SourceFilesConfiguration sourceFilesConfiguration; | ||
|
||
@Nullable private String baseImage; | ||
private List<String> jvmFlags = Collections.emptyList(); | ||
private String mainClass = ""; | ||
private List<String> javaArguments = Collections.emptyList(); | ||
private List<String> exposedPorts = Collections.emptyList(); | ||
|
||
public DockerContextGenerator(SourceFilesConfiguration sourceFilesConfiguration) { | ||
this.sourceFilesConfiguration = sourceFilesConfiguration; | ||
|
@@ -102,11 +135,22 @@ public DockerContextGenerator setJavaArguments(List<String> javaArguments) { | |
return this; | ||
} | ||
|
||
/** | ||
* Sets the exposed ports. | ||
* | ||
* @param exposedPorts the list of port numbers/port ranges to expose | ||
* @return this | ||
*/ | ||
public DockerContextGenerator setExposedPorts(List<String> exposedPorts) { | ||
this.exposedPorts = exposedPorts; | ||
return this; | ||
} | ||
|
||
/** | ||
* Creates the Docker context in {@code #targetDirectory}. | ||
* | ||
* @param targetDirectory the directory to generate the Docker context in. | ||
* @throws IOException if the export fails. | ||
* @param targetDirectory the directory to generate the Docker context in | ||
* @throws IOException if the export fails | ||
*/ | ||
public void generate(Path targetDirectory) throws IOException { | ||
Preconditions.checkNotNull(baseImage); | ||
|
@@ -141,56 +185,26 @@ public void generate(Path targetDirectory) throws IOException { | |
} | ||
|
||
/** | ||
* Makes a {@code Dockerfile} from the {@code DockerfileTemplate}. | ||
* | ||
* @return the {@code Dockerfile} contents. | ||
* @throws IOException if reading the Dockerfile template fails. | ||
*/ | ||
@VisibleForTesting | ||
String makeDockerfile() throws IOException { | ||
Preconditions.checkNotNull(baseImage); | ||
|
||
String dockerfileTemplate = | ||
Resources.toString(Resources.getResource("DockerfileTemplate"), StandardCharsets.UTF_8); | ||
|
||
return dockerfileTemplate | ||
.replace("@@BASE_IMAGE@@", baseImage) | ||
.replace( | ||
"@@DEPENDENCIES_PATH_ON_IMAGE@@", sourceFilesConfiguration.getDependenciesPathOnImage()) | ||
.replace("@@RESOURCES_PATH_ON_IMAGE@@", sourceFilesConfiguration.getResourcesPathOnImage()) | ||
.replace("@@CLASSES_PATH_ON_IMAGE@@", sourceFilesConfiguration.getClassesPathOnImage()) | ||
.replace( | ||
"@@ENTRYPOINT@@", | ||
joinAsJsonArray( | ||
EntrypointBuilder.makeEntrypoint(sourceFilesConfiguration, jvmFlags, mainClass))) | ||
.replace("@@CMD@@", joinAsJsonArray(javaArguments)); | ||
} | ||
|
||
/** | ||
* Formats a list for the Dockerfile's ENTRYPOINT or CMD. | ||
* Makes the contents of a {@code Dockerfile} using configuration data. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we're putting this in code, would be good to have in the javadoc an example of what it would look like. |
||
* | ||
* @see <a | ||
* href="https://docs.docker.com/engine/reference/builder/#exec-form-entrypoint-example">https://docs.docker.com/engine/reference/builder/#exec-form-entrypoint-example</a> | ||
* @param items the list of items to join into an array. | ||
* @return a string in the format: ["item1","item2",...] | ||
* @return the {@code Dockerfile} contents | ||
*/ | ||
@VisibleForTesting | ||
static String joinAsJsonArray(List<String> items) { | ||
StringBuilder resultString = new StringBuilder("["); | ||
boolean firstComponent = true; | ||
for (String item : items) { | ||
if (!firstComponent) { | ||
resultString.append(','); | ||
} | ||
|
||
// Escapes quotes. | ||
item = item.replaceAll("\"", Matcher.quoteReplacement("\\\"")); | ||
|
||
resultString.append('"').append(item).append('"'); | ||
firstComponent = false; | ||
} | ||
resultString.append(']'); | ||
|
||
return resultString.toString(); | ||
String makeDockerfile() { | ||
return "FROM " | ||
+ Preconditions.checkNotNull(baseImage) | ||
+ "\n\nCOPY libs " | ||
+ sourceFilesConfiguration.getDependenciesPathOnImage() | ||
+ "\nCOPY resources " | ||
+ sourceFilesConfiguration.getResourcesPathOnImage() | ||
+ "\nCOPY classes " | ||
+ sourceFilesConfiguration.getClassesPathOnImage() | ||
+ "\n\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh wait, wouldn't this add 3 newlines if there weren't any exposed ports? |
||
+ makeExposeInstructions(exposedPorts) | ||
+ "\nENTRYPOINT " | ||
+ joinAsJsonArray( | ||
EntrypointBuilder.makeEntrypoint(sourceFilesConfiguration, jvmFlags, mainClass)) | ||
+ "\nCMD " | ||
+ joinAsJsonArray(javaArguments); | ||
} | ||
} |
This file was deleted.
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 for this we could actually use
ObjectMapper
from the JSON library we use (I forgot about it when implementing this). It will automatically generate the JSON string from a list of strings.You could do like
Blobs.writeToString(JsonTemplateMapper.toBlob(thelist))
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 it needs a
ListOfJsonTemplate
, not a list of strings?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 right, maybe just use
new ObjectMapper().writeValueAsString
directly.