Skip to content

Commit

Permalink
Allow configuring working directory (#1266)
Browse files Browse the repository at this point in the history
* Allow configuring WorkDir
* Validate workingDirectory
* Add integration tests for WorkingDir
  • Loading branch information
chanseokoh authored Nov 27, 2018
1 parent d3418c1 commit 7fe4b4b
Show file tree
Hide file tree
Showing 31 changed files with 352 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,17 @@ public JibContainerBuilder setUser(@Nullable String user) {
return this;
}

/**
* Sets the working directory in the container.
*
* @param workingDirectory the working directory
* @return this
*/
public JibContainerBuilder setWorkingDirectory(@Nullable AbsoluteUnixPath workingDirectory) {
containerConfigurationBuilder.setWorkingDirectory(workingDirectory);
return this;
}

/**
* Builds the container.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ private Image<Layer> afterCachedLayerSteps()
.setExposedPorts(containerConfiguration.getExposedPorts())
.setVolumes(containerConfiguration.getVolumes())
.addLabels(containerConfiguration.getLabels());
if (containerConfiguration.getWorkingDirectory() != null) {
imageBuilder.setWorkingDirectory(containerConfiguration.getWorkingDirectory().toString());
}
}

// Gets the container configuration content descriptor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static class Builder {
@Nullable private List<AbsoluteUnixPath> volumes;
@Nullable private Map<String, String> labels;
@Nullable private String user;
@Nullable private AbsoluteUnixPath workingDirectory;

/**
* Sets the image creation time.
Expand Down Expand Up @@ -198,6 +199,17 @@ public Builder setUser(@Nullable String user) {
return this;
}

/**
* Sets the working directory in the container.
*
* @param workingDirectory the working directory
* @return this
*/
public Builder setWorkingDirectory(@Nullable AbsoluteUnixPath workingDirectory) {
this.workingDirectory = workingDirectory;
return this;
}

/**
* Builds the {@link ContainerConfiguration}.
*
Expand All @@ -212,7 +224,8 @@ public ContainerConfiguration build() {
exposedPorts == null ? null : ImmutableList.copyOf(exposedPorts),
volumes == null ? null : ImmutableList.copyOf(volumes),
labels == null ? null : ImmutableMap.copyOf(labels),
user);
user,
workingDirectory);
}

private Builder() {}
Expand All @@ -235,6 +248,7 @@ public static Builder builder() {
@Nullable private final ImmutableList<AbsoluteUnixPath> volumes;
@Nullable private final ImmutableMap<String, String> labels;
@Nullable private final String user;
@Nullable private final AbsoluteUnixPath workingDirectory;

private ContainerConfiguration(
Instant creationTime,
Expand All @@ -244,7 +258,8 @@ private ContainerConfiguration(
@Nullable ImmutableList<Port> exposedPorts,
@Nullable ImmutableList<AbsoluteUnixPath> volumes,
@Nullable ImmutableMap<String, String> labels,
@Nullable String user) {
@Nullable String user,
@Nullable AbsoluteUnixPath workingDirectory) {
this.creationTime = creationTime;
this.entrypoint = entrypoint;
this.programArguments = programArguments;
Expand All @@ -253,6 +268,7 @@ private ContainerConfiguration(
this.volumes = volumes;
this.labels = labels;
this.user = user;
this.workingDirectory = workingDirectory;
}

public Instant getCreationTime() {
Expand Down Expand Up @@ -294,6 +310,11 @@ public ImmutableMap<String, String> getLabels() {
return labels;
}

@Nullable
public AbsoluteUnixPath getWorkingDirectory() {
return workingDirectory;
}

@Override
@VisibleForTesting
public boolean equals(Object other) {
Expand All @@ -310,7 +331,8 @@ public boolean equals(Object other) {
&& Objects.equals(environmentMap, otherContainerConfiguration.environmentMap)
&& Objects.equals(exposedPorts, otherContainerConfiguration.exposedPorts)
&& Objects.equals(labels, otherContainerConfiguration.labels)
&& Objects.equals(user, otherContainerConfiguration.user);
&& Objects.equals(user, otherContainerConfiguration.user)
&& Objects.equals(workingDirectory, otherContainerConfiguration.workingDirectory);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.google.cloud.tools.jib.configuration.credentials.CredentialRetriever;
import com.google.cloud.tools.jib.event.EventHandlers;
import com.google.cloud.tools.jib.event.JibEvent;
import com.google.cloud.tools.jib.filesystem.AbsoluteUnixPath;
import com.google.cloud.tools.jib.image.ImageFormat;
import com.google.cloud.tools.jib.image.ImageReference;
import com.google.cloud.tools.jib.image.InvalidImageReferenceException;
Expand Down Expand Up @@ -69,7 +70,8 @@ public void testToBuildConfiguration_containerConfigurationSet()
.setLabels(ImmutableMap.of("key", "value"))
.setProgramArguments(Arrays.asList("program", "arguments"))
.setCreationTime(Instant.ofEpochMilli(1000))
.setUser("user");
.setUser("user")
.setWorkingDirectory(AbsoluteUnixPath.get("/working/directory"));

BuildConfiguration buildConfiguration =
jibContainerBuilder.toBuildConfiguration(Containerizer.to(baseImage));
Expand All @@ -84,6 +86,8 @@ public void testToBuildConfiguration_containerConfigurationSet()
Arrays.asList("program", "arguments"), containerConfiguration.getProgramArguments());
Assert.assertEquals(Instant.ofEpochMilli(1000), containerConfiguration.getCreationTime());
Assert.assertEquals("user", containerConfiguration.getUser());
Assert.assertEquals(
AbsoluteUnixPath.get("/working/directory"), containerConfiguration.getWorkingDirectory());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.cloud.tools.jib.configuration.BuildConfiguration;
import com.google.cloud.tools.jib.configuration.ContainerConfiguration;
import com.google.cloud.tools.jib.event.EventDispatcher;
import com.google.cloud.tools.jib.filesystem.AbsoluteUnixPath;
import com.google.cloud.tools.jib.image.DescriptorDigest;
import com.google.cloud.tools.jib.image.Image;
import com.google.cloud.tools.jib.image.Layer;
Expand Down Expand Up @@ -224,6 +225,26 @@ public void test_propagateBaseImageConfiguration()
Assert.assertEquals(ImmutableList.of(), image.getProgramArguments());
}

@Test
public void testOverrideWorkingDirectory() throws InterruptedException, ExecutionException {
Mockito.when(mockContainerConfiguration.getWorkingDirectory())
.thenReturn(AbsoluteUnixPath.get("/my/directory"));

BuildImageStep buildImageStep =
new BuildImageStep(
MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()),
mockBuildConfiguration,
mockPullBaseImageStep,
mockPullAndCacheBaseImageLayersStep,
ImmutableList.of(
mockBuildAndCacheApplicationLayerStepDependencies,
mockBuildAndCacheApplicationLayerStepResources,
mockBuildAndCacheApplicationLayerStepClasses));
Image<Layer> image = buildImageStep.getFuture().get().getFuture().get();

Assert.assertEquals("/my/directory", image.getWorkingDirectory());
}

@Test
public void test_inheritedEntrypoint() throws ExecutionException, InterruptedException {
Mockito.when(mockContainerConfiguration.getEntrypoint()).thenReturn(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.cloud.tools.jib.configuration;

import com.google.cloud.tools.jib.filesystem.AbsoluteUnixPath;
import com.google.common.collect.ImmutableMap;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -104,4 +105,11 @@ public void testBuilder_user() {
ContainerConfiguration configuration = ContainerConfiguration.builder().setUser("john").build();
Assert.assertEquals("john", configuration.getUser());
}

@Test
public void testBuilder_workingDirectory() {
ContainerConfiguration configuration =
ContainerConfiguration.builder().setWorkingDirectory(AbsoluteUnixPath.get("/path")).build();
Assert.assertEquals(AbsoluteUnixPath.get("/path"), configuration.getWorkingDirectory());
}
}
1 change: 1 addition & 0 deletions jib-gradle-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.

- Image ID is now written to `build/jib-image.id` ([#1204](https://github.com/GoogleContainerTools/jib/issues/1204))
- `jib.container.entrypoint = 'INHERIT'` allows inheriting `ENTRYPOINT` and `CMD` from the base image. While inheriting `ENTRYPOINT`, you can also override `CMD` using `jib.container.args`.
- `container.workingDirectory` configuration parameter to set the working directory ([#1225](https://github.com/GoogleContainerTools/jib/issues/1225))

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ private static void assertSimpleCreationTimeIsAfter(Instant before, String image
Assert.assertTrue(parsed.isAfter(before) || parsed.equals(before));
}

private static void assertWorkingDirectory(String expected, String imageReference)
throws IOException, InterruptedException {
Assert.assertEquals(
expected,
new Command("docker", "inspect", "-f", "{{.Config.WorkingDir}}", imageReference)
.run()
.trim());
}

/**
* Asserts that the test project has the required exposed ports and labels.
*
Expand Down Expand Up @@ -144,6 +153,7 @@ public void testBuild_simple() throws IOException, InterruptedException, DigestE
JibRunHelper.buildAndRun(simpleTestProject, targetImage));
assertDockerInspect(targetImage);
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
assertWorkingDirectory("/home", targetImage);
}

@Test
Expand All @@ -154,6 +164,7 @@ public void testBuild_complex() throws IOException, InterruptedException {
"Hello, world. An argument.\nrwxr-xr-x\nrwxrwxrwx\nfoo\ncat\n-Xms512m\n-Xdebug\nenvvalue1\nenvvalue2\n",
buildAndRunComplex(targetImage, "testuser2", "testpassword2", localRegistry2));
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
assertWorkingDirectory("", targetImage);
}

@Test
Expand All @@ -164,6 +175,7 @@ public void testBuild_complex_sameFromAndToRegistry() throws IOException, Interr
"Hello, world. An argument.\nrwxr-xr-x\nrwxrwxrwx\nfoo\ncat\n-Xms512m\n-Xdebug\nenvvalue1\nenvvalue2\n",
buildAndRunComplex(targetImage, "testuser", "testpassword", localRegistry1));
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
assertWorkingDirectory("", targetImage);
}

@Test
Expand All @@ -175,6 +187,7 @@ public void testDockerDaemon_simple() throws IOException, InterruptedException,
JibRunHelper.buildToDockerDaemonAndRun(simpleTestProject, targetImage));
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
assertDockerInspect(targetImage);
assertWorkingDirectory("/home", targetImage);
}

@Test
Expand All @@ -196,5 +209,6 @@ public void testBuildTar_simple() throws IOException, InterruptedException {
new Command("docker", "run", "--rm", targetImage).run());
assertDockerInspect(targetImage);
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
assertWorkingDirectory("/home", targetImage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jib {
args = ['An argument.']
ports = ['1000/tcp', '2000-2003/udp']
labels = [key1:'value1', key2:'value2']
workingDirectory = '/home'
}
extraDirectory = file('src/main/custom-extra-dir')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
import com.google.cloud.tools.jib.filesystem.AbsoluteUnixPath;
import com.google.cloud.tools.jib.image.ImageReference;
import com.google.cloud.tools.jib.image.InvalidImageReferenceException;
import com.google.cloud.tools.jib.plugins.common.AppRootInvalidException;
import com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException;
import com.google.cloud.tools.jib.plugins.common.BuildStepsRunner;
import com.google.cloud.tools.jib.plugins.common.HelpfulSuggestions;
import com.google.cloud.tools.jib.plugins.common.InferredAuthRetrievalException;
import com.google.cloud.tools.jib.plugins.common.InvalidAppRootException;
import com.google.cloud.tools.jib.plugins.common.InvalidWorkingDirectoryException;
import com.google.cloud.tools.jib.plugins.common.MainClassInferenceException;
import com.google.cloud.tools.jib.plugins.common.PluginConfigurationProcessor;
import com.google.cloud.tools.jib.plugins.common.RawConfiguration;
Expand Down Expand Up @@ -144,9 +145,14 @@ public void buildDocker()
projectProperties.getJavaLayerConfigurations().getLayerConfigurations(),
helpfulSuggestions);

} catch (AppRootInvalidException ex) {
} catch (InvalidAppRootException ex) {
throw new GradleException(
"container.appRoot is not an absolute Unix-style path: " + ex.getInvalidAppRoot());
"container.appRoot is not an absolute Unix-style path: " + ex.getInvalidPathValue(), ex);
} catch (InvalidWorkingDirectoryException ex) {
throw new GradleException(
"container.workingDirectory is not an absolute Unix-style path: "
+ ex.getInvalidPathValue(),
ex);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
import com.google.cloud.tools.jib.filesystem.AbsoluteUnixPath;
import com.google.cloud.tools.jib.image.ImageReference;
import com.google.cloud.tools.jib.image.InvalidImageReferenceException;
import com.google.cloud.tools.jib.plugins.common.AppRootInvalidException;
import com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException;
import com.google.cloud.tools.jib.plugins.common.BuildStepsRunner;
import com.google.cloud.tools.jib.plugins.common.HelpfulSuggestions;
import com.google.cloud.tools.jib.plugins.common.InferredAuthRetrievalException;
import com.google.cloud.tools.jib.plugins.common.InvalidAppRootException;
import com.google.cloud.tools.jib.plugins.common.InvalidWorkingDirectoryException;
import com.google.cloud.tools.jib.plugins.common.MainClassInferenceException;
import com.google.cloud.tools.jib.plugins.common.PluginConfigurationProcessor;
import com.google.cloud.tools.jib.plugins.common.RawConfiguration;
Expand Down Expand Up @@ -124,9 +125,14 @@ public void buildImage()
projectProperties.getJavaLayerConfigurations().getLayerConfigurations(),
helpfulSuggestions);

} catch (AppRootInvalidException ex) {
} catch (InvalidAppRootException ex) {
throw new GradleException(
"container.appRoot is not an absolute Unix-style path: " + ex.getInvalidAppRoot());
"container.appRoot is not an absolute Unix-style path: " + ex.getInvalidPathValue(), ex);
} catch (InvalidWorkingDirectoryException ex) {
throw new GradleException(
"container.workingDirectory is not an absolute Unix-style path: "
+ ex.getInvalidPathValue(),
ex);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
import com.google.cloud.tools.jib.event.DefaultEventDispatcher;
import com.google.cloud.tools.jib.filesystem.AbsoluteUnixPath;
import com.google.cloud.tools.jib.image.InvalidImageReferenceException;
import com.google.cloud.tools.jib.plugins.common.AppRootInvalidException;
import com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException;
import com.google.cloud.tools.jib.plugins.common.BuildStepsRunner;
import com.google.cloud.tools.jib.plugins.common.HelpfulSuggestions;
import com.google.cloud.tools.jib.plugins.common.InferredAuthRetrievalException;
import com.google.cloud.tools.jib.plugins.common.InvalidAppRootException;
import com.google.cloud.tools.jib.plugins.common.InvalidWorkingDirectoryException;
import com.google.cloud.tools.jib.plugins.common.MainClassInferenceException;
import com.google.cloud.tools.jib.plugins.common.PluginConfigurationProcessor;
import com.google.cloud.tools.jib.plugins.common.RawConfiguration;
Expand Down Expand Up @@ -141,9 +142,14 @@ public void buildTar()
projectProperties.getJavaLayerConfigurations().getLayerConfigurations(),
helpfulSuggestions);

} catch (AppRootInvalidException ex) {
} catch (InvalidAppRootException ex) {
throw new GradleException(
"container.appRoot is not an absolute Unix-style path: " + ex.getInvalidAppRoot());
"container.appRoot is not an absolute Unix-style path: " + ex.getInvalidPathValue(), ex);
} catch (InvalidWorkingDirectoryException ex) {
throw new GradleException(
"container.workingDirectory is not an absolute Unix-style path: "
+ ex.getInvalidPathValue(),
ex);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class ContainerParameters {
private Map<String, String> labels = Collections.emptyMap();
private String appRoot = "";
@Nullable private String user;
@Nullable private String workingDirectory;

@Input
@Optional
Expand Down Expand Up @@ -201,4 +202,18 @@ public String getUser() {
public void setUser(String user) {
this.user = user;
}

@Input
@Nullable
@Optional
public String getWorkingDirectory() {
if (System.getProperty(PropertyNames.CONTAINER_WORKING_DIRECTORY) != null) {
return System.getProperty(PropertyNames.CONTAINER_WORKING_DIRECTORY);
}
return workingDirectory;
}

public void setWorkingDirectory(String workingDirectory) {
this.workingDirectory = workingDirectory;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public Optional<String> getUser() {
return Optional.ofNullable(jibExtension.getContainer().getUser());
}

@Override
public Optional<String> getWorkingDirectory() {
return Optional.ofNullable(jibExtension.getContainer().getWorkingDirectory());
}

@Override
public boolean getUseCurrentTimestamp() {
return jibExtension.getContainer().getUseCurrentTimestamp();
Expand Down
Loading

0 comments on commit 7fe4b4b

Please sign in to comment.