Skip to content
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 plugin configuration for environment variables #930

Merged
merged 7 commits into from
Sep 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,34 @@ private static ImmutableList<Path> getResourceFilesList(String resourcePath)
}
}

private static void assertDockerInspect(String imageReference)
throws IOException, InterruptedException {
String dockerContainerConfig = new Command("docker", "inspect", imageReference).run();
Assert.assertThat(
dockerContainerConfig,
CoreMatchers.containsString(
" \"ExposedPorts\": {\n"
+ " \"1000/tcp\": {},\n"
+ " \"2000/tcp\": {},\n"
+ " \"2001/tcp\": {},\n"
+ " \"2002/tcp\": {},\n"
+ " \"3000/udp\": {}"));
Assert.assertThat(
dockerContainerConfig,
CoreMatchers.containsString(
" \"Labels\": {\n"
+ " \"key1\": \"value1\",\n"
+ " \"key2\": \"value2\"\n"
+ " }"));
String dockerConfigEnv =
new Command("docker", "inspect", "-f", "{{.Config.Env}}", imageReference).run();
Assert.assertThat(
dockerConfigEnv, CoreMatchers.containsString("env1=envvalue1 env2=envvalue2"));
String history = new Command("docker", "history", imageReference).run();
Assert.assertThat(history, CoreMatchers.containsString("jib-integration-test"));
Assert.assertThat(history, CoreMatchers.containsString("bazel build ..."));
}

private static final TestJibLogger logger = new TestJibLogger();

@Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();
Expand Down Expand Up @@ -104,18 +132,7 @@ public void testSteps_forBuildToDockerRegistry()

String imageReference = "localhost:5000/testimage:testtag";
localRegistry.pull(imageReference);
Assert.assertThat(
new Command("docker", "inspect", imageReference).run(),
CoreMatchers.containsString(
" \"ExposedPorts\": {\n"
+ " \"1000/tcp\": {},\n"
+ " \"2000/tcp\": {},\n"
+ " \"2001/tcp\": {},\n"
+ " \"2002/tcp\": {},\n"
+ " \"3000/udp\": {}"));
String history = new Command("docker", "history", imageReference).run();
Assert.assertThat(history, CoreMatchers.containsString("jib-integration-test"));
Assert.assertThat(history, CoreMatchers.containsString("bazel build ..."));
assertDockerInspect(imageReference);
Assert.assertEquals(
"Hello, world. An argument.\n", new Command("docker", "run", imageReference).run());
}
Expand Down Expand Up @@ -152,26 +169,7 @@ public void testSteps_forBuildToDockerDaemon()
new Caches.Initializer(cacheDirectory, false, cacheDirectory, false))
.run();

String dockerContainerConfig = new Command("docker", "inspect", imageReference).run();
Assert.assertThat(
dockerContainerConfig,
CoreMatchers.containsString(
" \"ExposedPorts\": {\n"
+ " \"1000/tcp\": {},\n"
+ " \"2000/tcp\": {},\n"
+ " \"2001/tcp\": {},\n"
+ " \"2002/tcp\": {},\n"
+ " \"3000/udp\": {}"));
Assert.assertThat(
dockerContainerConfig,
CoreMatchers.containsString(
" \"Labels\": {\n"
+ " \"key1\": \"value1\",\n"
+ " \"key2\": \"value2\"\n"
+ " }"));
String history = new Command("docker", "history", imageReference).run();
Assert.assertThat(history, CoreMatchers.containsString("jib-integration-test"));
Assert.assertThat(history, CoreMatchers.containsString("bazel build ..."));
assertDockerInspect(imageReference);
Assert.assertEquals(
"Hello, world. An argument.\n", new Command("docker", "run", imageReference).run());
}
Expand Down Expand Up @@ -213,6 +211,7 @@ private BuildConfiguration getBuildConfiguration(
JavaEntrypointConstructor.makeDefaultEntrypoint(
Collections.emptyList(), "HelloWorld"))
.setProgramArguments(Collections.singletonList("An argument."))
.setEnvironment(ImmutableMap.of("env1", "envvalue1", "env2", "envvalue2"))
.setExposedPorts(
ExposedPortsParser.parse(Arrays.asList("1000", "2000-2002/tcp", "3000/udp")))
.setLabels(ImmutableMap.of("key1", "value1", "key2", "value2"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringJoiner;
import javax.annotation.Nullable;

/**
Expand All @@ -58,6 +59,8 @@ public class JavaDockerContextGenerator {
private static final String CLASSES_LAYER_DIRECTORY = "classes";
private static final String EXTRA_FILES_LAYER_DIRECTORY = "root";

private static final ObjectMapper objectMapper = new ObjectMapper();

/** Represents a Dockerfile {@code COPY} directive. */
private static class CopyDirective {

Expand Down Expand Up @@ -98,11 +101,39 @@ private static void addIfNotEmpty(
layerEntry.getSourceFiles(), directoryInContext, layerEntry.getExtractionPath()));
}

/**
* Converts a map to a corresponding dockerfile string in the form of:
*
* <pre>{@code
* command key1="value1" \
* key2="value2" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we line up key1 and key2 since we're adding spaces anyways?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command names are different lengths, and adding a variable number of spaces here would have harmed readability or required a weird extra parameter, so I don't think it's worth it, unless there's a function we can use to generate whitespace that I don't know about (that doesn't require another import). I think it's fine as is.

* ...
* }</pre>
*
* @param map the map to convert
* @param command the dockerfile command to prefix the map values with
* @return the new dockerfile command as a string
* @throws JsonProcessingException if getting the json string of a map value fails
*/
private static String mapToDockerfileString(Map<String, String> map, String command)
throws JsonProcessingException {
if (map.isEmpty()) {
return "";
}

StringJoiner joiner = new StringJoiner(" \\\n ", "\n" + command + " ", "");
for (Entry<String, String> entry : map.entrySet()) {
joiner.add(entry.getKey() + "=" + objectMapper.writeValueAsString(entry.getValue()));
}
return joiner.toString();
}

private final ImmutableList<CopyDirective> copyDirectives;

@Nullable private String baseImage;
private List<String> entrypoint = Collections.emptyList();
private List<String> javaArguments = Collections.emptyList();
private Map<String, String> environment = Collections.emptyMap();
private List<String> exposedPorts = Collections.emptyList();
private Map<String, String> labels = Collections.emptyMap();

Expand Down Expand Up @@ -170,6 +201,17 @@ public JavaDockerContextGenerator setJavaArguments(List<String> javaArguments) {
return this;
}

/**
* Sets the environment variables
*
* @param environment map from the environment variable name to value
* @return this
*/
public JavaDockerContextGenerator setEnvironment(Map<String, String> environment) {
this.environment = environment;
return this;
}

/**
* Sets the exposed ports.
*
Expand Down Expand Up @@ -240,9 +282,12 @@ public void generate(Path targetDirectory) throws IOException {
*
* EXPOSE [port]
* [More EXPOSE instructions, if necessary]
* ENV [key1]="[value1]" \
* [key2]="[value2]" \
* [...]
* LABEL [key1]="[value1]" \
* [key2]="[value2]" \
* [...]
* [key2]="[value2]" \
* [...]
* ENTRYPOINT java [jvm flags] -cp [classpaths] [main class]
* CMD [main class args]
* }</pre>
Expand All @@ -251,7 +296,6 @@ public void generate(Path targetDirectory) throws IOException {
*/
@VisibleForTesting
String makeDockerfile() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
StringBuilder dockerfile = new StringBuilder();
dockerfile.append("FROM ").append(Preconditions.checkNotNull(baseImage)).append("\n");
for (CopyDirective copyDirective : copyDirectives) {
Expand All @@ -267,16 +311,8 @@ String makeDockerfile() throws JsonProcessingException {
dockerfile.append("\nEXPOSE ").append(port);
}

boolean firstLabel = true;
for (Entry<String, String> label : labels.entrySet()) {
dockerfile
.append(firstLabel ? "\nLABEL " : " \\\n ")
.append(label.getKey())
.append("=")
.append(objectMapper.writeValueAsString(label.getValue()));
firstLabel = false;
}

dockerfile.append(mapToDockerfileString(environment, "ENV"));
dockerfile.append(mapToDockerfileString(labels, "LABEL"));
dockerfile
.append("\nENTRYPOINT ")
.append(objectMapper.writeValueAsString(entrypoint))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public void testMakeDockerfile() throws IOException {
List<String> expectedJvmFlags = Arrays.asList("-flag", "another\"Flag");
String expectedMainClass = "SomeMainClass";
List<String> expectedJavaArguments = Arrays.asList("arg1", "arg2");
Map<String, String> expectedEnv = ImmutableMap.of("key1", "value1", "key2", "value2");
List<String> exposedPorts = Arrays.asList("1000/tcp", "2000-2010/udp");
Map<String, String> expectedLabels =
ImmutableMap.of(
Expand Down Expand Up @@ -155,6 +156,7 @@ public void testMakeDockerfile() throws IOException {
JavaEntrypointConstructor.makeDefaultEntrypoint(
expectedJvmFlags, expectedMainClass))
.setJavaArguments(expectedJavaArguments)
.setEnvironment(expectedEnv)
.setExposedPorts(exposedPorts)
.setLabels(expectedLabels)
.makeDockerfile();
Expand Down
6 changes: 4 additions & 2 deletions jib-core/src/test/resources/sampleDockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ COPY root /

EXPOSE 1000/tcp
EXPOSE 2000-2010/udp
ENV key1="value1" \
key2="value2"
LABEL key1="value" \
key2="value with\\backslashes\"and\\\\\"\"quotes\"\\" \
key3="value3"
key2="value with\\backslashes\"and\\\\\"\"quotes\"\\" \
key3="value3"
ENTRYPOINT ["java","-flag","another\"Flag","-cp","/app/resources/:/app/classes/:/app/libs/*","SomeMainClass"]
CMD ["arg1","arg2"]
2 changes: 2 additions & 0 deletions jib-gradle-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.

### Added

- `container.environment` configuration parameter to configure environment variables ([#890](https://github.com/GoogleContainerTools/jib/issues/890))

### Changed

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ public void testBuild_complex() throws IOException, InterruptedException {
String targetImage = "localhost:6000/compleximage:gradle" + System.nanoTime();
Instant beforeBuild = Instant.now();
Assert.assertEquals(
"Hello, world. An argument.\nfoo\ncat\n-Xms512m\n-Xdebug\n",
"Hello, world. An argument.\nfoo\ncat\n-Xms512m\n-Xdebug\nenvvalue1\nenvvalue2\n",
buildAndRunComplex(targetImage, "testuser2", "testpassword2", localRegistry2));
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
}
Expand All @@ -248,7 +248,7 @@ public void testBuild_complex_sameFromAndToRegistry() throws IOException, Interr
String targetImage = "localhost:5000/compleximage:gradle" + System.nanoTime();
Instant beforeBuild = Instant.now();
Assert.assertEquals(
"Hello, world. An argument.\nfoo\ncat\n-Xms512m\n-Xdebug\n",
"Hello, world. An argument.\nfoo\ncat\n-Xms512m\n-Xdebug\nenvvalue1\nenvvalue2\n",
buildAndRunComplex(targetImage, "testuser", "testpassword", localRegistry1));
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jib {
args = ['An argument.']
mainClass = 'com.test.HelloWorld'
jvmFlags = ['-Xms512m', '-Xdebug']
environment = [env1:'envvalue1', env2:'envvalue2']
ports = ['1000/tcp', '2000-2003/udp']
labels = [key1:'value1', key2:'value2']
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,12 @@ public static void main(String[] args) throws IOException, URISyntaxException {
for (String jvmFlag : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
System.out.println(jvmFlag);
}

if (System.getenv("env1") != null) {
System.out.println(System.getenv("env1"));
}
if (System.getenv("env2") != null) {
System.out.println(System.getenv("env2"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class ContainerParameters {

private boolean useCurrentTimestamp = false;
private List<String> jvmFlags = Collections.emptyList();
private Map<String, String> environment = Collections.emptyMap();
private List<String> entrypoint = Collections.emptyList();
@Nullable private String mainClass;
private List<String> args = Collections.emptyList();
Expand Down Expand Up @@ -71,6 +72,16 @@ public void setJvmFlags(List<String> jvmFlags) {
this.jvmFlags = jvmFlags;
}

@Input
@Optional
public Map<String, String> getEnvironment() {
return environment;
}

public void setEnvironment(Map<String, String> environment) {
this.environment = environment;
}

@Input
@Nullable
@Optional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ List<String> getJvmFlags() {
return container.getJvmFlags();
}

@Internal
@Optional
Map<String, String> getEnvironment() {
return container.getEnvironment();
}

// TODO: Make @Internal (deprecated)
@Input
@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ static PluginConfigurationProcessor processCommonConfiguration(
ContainerConfiguration.Builder containerConfigurationBuilder =
ContainerConfiguration.builder()
.setEntrypoint(entrypoint)
.setEnvironment(jibExtension.getEnvironment())
.setProgramArguments(jibExtension.getArgs())
.setExposedPorts(ExposedPortsParser.parse(jibExtension.getExposedPorts()))
.setLabels(jibExtension.getLabels());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,17 @@ public void testTo() {
@Test
public void testContainer() {
Assert.assertEquals(Collections.emptyList(), testJibExtension.getContainer().getJvmFlags());
Assert.assertEquals(Collections.emptyMap(), testJibExtension.getContainer().getEnvironment());
Assert.assertNull(testJibExtension.getContainer().getMainClass());
Assert.assertEquals(Collections.emptyList(), testJibExtension.getContainer().getArgs());
Assert.assertEquals(V22ManifestTemplate.class, testJibExtension.getContainer().getFormat());
Assert.assertEquals(Collections.emptyList(), testJibExtension.getContainer().getPorts());
Assert.assertEquals(Collections.emptyMap(), testJibExtension.getContainer().getLabels());

testJibExtension.container(
container -> {
container.setJvmFlags(Arrays.asList("jvmFlag1", "jvmFlag2"));
container.setEnvironment(ImmutableMap.of("var1", "value1", "var2", "value2"));
container.setEntrypoint(Arrays.asList("foo", "bar", "baz"));
container.setMainClass("mainClass");
container.setArgs(Arrays.asList("arg1", "arg2", "arg3"));
Expand All @@ -114,6 +117,9 @@ public void testContainer() {
Arrays.asList("foo", "bar", "baz"), testJibExtension.getContainer().getEntrypoint());
Assert.assertEquals(
Arrays.asList("jvmFlag1", "jvmFlag2"), testJibExtension.getContainer().getJvmFlags());
Assert.assertEquals(
ImmutableMap.of("var1", "value1", "var2", "value2"),
testJibExtension.getContainer().getEnvironment());
Assert.assertEquals("mainClass", testJibExtension.getContainer().getMainClass());
Assert.assertEquals(
Arrays.asList("arg1", "arg2", "arg3"), testJibExtension.getContainer().getArgs());
Expand Down
3 changes: 3 additions & 0 deletions jib-maven-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.

### Added

- `<skip>` configuration parameter to skip Jib execution in multi-module projects (also settable via `jib.skip` property) ([#865](https://github.com/GoogleContainerTools/jib/issues/865))
- `<container><environment>` configuration parameter to configure environment variables ([#890](https://github.com/GoogleContainerTools/jib/issues/890))

### Changed

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ public static class ContainerParameters {

@Parameter private List<String> jvmFlags = Collections.emptyList();

@Parameter private Map<String, String> environment = Collections.emptyMap();

@Nullable @Parameter private String mainClass;

@Parameter private List<String> args = Collections.emptyList();
Expand Down Expand Up @@ -152,8 +154,6 @@ public static class ContainerParameters {

@Deprecated @Parameter private List<String> jvmFlags = Collections.emptyList();

@Nullable @Parameter private Map<String, String> environment;

@Deprecated @Nullable @Parameter private String mainClass;

@Deprecated @Parameter private List<String> args = Collections.emptyList();
Expand Down Expand Up @@ -268,7 +268,7 @@ List<String> getJvmFlags() {

@Nullable
Map<String, String> getEnvironment() {
return environment;
return container.environment;
}

@Nullable
Expand Down
Loading