Skip to content

Commit

Permalink
Update gradle extraDirectory config parameter to include path and per…
Browse files Browse the repository at this point in the history
…missions field (#1178)
  • Loading branch information
TadCordle authored Oct 23, 2018
1 parent 37ed046 commit 90a0b66
Show file tree
Hide file tree
Showing 25 changed files with 349 additions and 81 deletions.
5 changes: 4 additions & 1 deletion jib-gradle-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ All notable changes to this project will be documented in this file.
- `jib.to.credHelper` and `jib.from.credHelper` can be used to specify a credential helper suffix or a full path to a credential helper executable ([#925](https://github.com/GoogleContainerTools/jib/issues/925))
- `container.user` configuration parameter to configure the user and group to run the container as ([#1029](https://github.com/GoogleContainerTools/jib/issues/1029))
- Preliminary support for building images for WAR projects ([#431](https://github.com/GoogleContainerTools/jib/issues/431))

- `jib.extraDirectory` closure with a `path` and `permissions` field ([#794](https://github.com/GoogleContainerTools/jib/issues/794))
- `jib.extraDirectory.path` configures the extra layer directory (still also configurable via `jib.extraDirectory = file(...)`)
- `jib.extraDirectory.permissions` is a map from absolute path on container to the file's permission bits (represented as an octal string)

### Changed

- Removed deprecated `jib.jvmFlags`, `jib.mainClass`, `jib.args`, and `jib.format` in favor of the equivalents under `jib.container` ([#461](https://github.com/GoogleContainerTools/jib/issues/461))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public void testBuild_simple() throws IOException, InterruptedException {

Instant beforeBuild = Instant.now();
Assert.assertEquals(
"Hello, world. An argument.\nfoo\ncat\n",
"Hello, world. An argument.\nrw-r--r--\nrw-r--r--\nfoo\ncat\n",
JibRunHelper.buildAndRun(simpleTestProject, targetImage));
assertDockerInspect(targetImage);
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
Expand All @@ -153,7 +153,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\nenvvalue1\nenvvalue2\n",
"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);
}
Expand All @@ -163,7 +163,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\nenvvalue1\nenvvalue2\n",
"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);
}
Expand All @@ -173,7 +173,7 @@ public void testDockerDaemon_simple() throws IOException, InterruptedException {
String targetImage = "simpleimage:gradle" + System.nanoTime();
Instant beforeBuild = Instant.now();
Assert.assertEquals(
"Hello, world. An argument.\nfoo\ncat\n",
"Hello, world. An argument.\nrw-r--r--\nrw-r--r--\nfoo\ncat\n",
JibRunHelper.buildToDockerDaemonAndRun(simpleTestProject, targetImage));
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
assertDockerInspect(targetImage);
Expand Down Expand Up @@ -201,7 +201,7 @@ public void testDockerContext() throws IOException, InterruptedException {

assertDockerInspect(imageName);
Assert.assertEquals(
"Hello, world. An argument.\nfoo\ncat\n",
"Hello, world. An argument.\nrw-r--r--\nrw-r--r--\nfoo\ncat\n",
new Command("docker", "run", "--rm", imageName).run());

// Checks that generating the Docker context again is skipped.
Expand Down Expand Up @@ -249,7 +249,7 @@ public void testBuildTar_simple() throws IOException, InterruptedException {

new Command("docker", "load", "--input", outputPath).run();
Assert.assertEquals(
"Hello, world. An argument.\nfoo\ncat\n",
"Hello, world. An argument.\nrw-r--r--\nrw-r--r--\nfoo\ncat\n",
new Command("docker", "run", "--rm", targetImage).run());
assertDockerInspect(targetImage);
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ jib {
ports = ['1000/tcp', '2000-2003/udp']
labels = [key1:'value1', key2:'value2']
}
extraDirectory {
path = file('src/main/custom-extra-dir')
permissions = ['/foo':'755', '/bar/cat':'777']
}
allowInsecureRegistries = true
extraDirectory = file('src/main/custom-extra-dir')

// Does not have tests use user-level cache for base image layers.
useOnlyProjectCache = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermissions;

/** Example class that uses a dependency and a resource file. */
public class HelloWorld {
Expand All @@ -41,6 +42,10 @@ public static void main(String[] args) throws IOException, URISyntaxException {

// Prints the contents of the extra files.
if (Files.exists(Paths.get("/foo"))) {
System.out.println(
PosixFilePermissions.toString(Files.getPosixFilePermissions(Paths.get("/foo"))));
System.out.println(
PosixFilePermissions.toString(Files.getPosixFilePermissions(Paths.get("/bar/cat"))));
System.out.println(new String(Files.readAllBytes(Paths.get("/foo")), StandardCharsets.UTF_8));
System.out.println(
new String(Files.readAllBytes(Paths.get("/bar/cat")), StandardCharsets.UTF_8));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ public void buildDocker()
AbsoluteUnixPath appRoot = PluginConfigurationProcessor.getAppRootChecked(jibExtension);
GradleProjectProperties gradleProjectProperties =
GradleProjectProperties.getForProject(
getProject(), getLogger(), jibExtension.getExtraDirectoryPath(), appRoot);
getProject(),
getLogger(),
jibExtension.getExtraDirectory().getPath(),
jibExtension.getExtraDirectory().getPermissions(),
appRoot);

GradleHelpfulSuggestionsBuilder gradleHelpfulSuggestionsBuilder =
new GradleHelpfulSuggestionsBuilder(HELPFUL_SUGGESTIONS_PREFIX, jibExtension);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ public void buildImage()
AbsoluteUnixPath appRoot = PluginConfigurationProcessor.getAppRootChecked(jibExtension);
GradleProjectProperties gradleProjectProperties =
GradleProjectProperties.getForProject(
getProject(), getLogger(), jibExtension.getExtraDirectoryPath(), appRoot);
getProject(),
getLogger(),
jibExtension.getExtraDirectory().getPath(),
jibExtension.getExtraDirectory().getPermissions(),
appRoot);

if (Strings.isNullOrEmpty(jibExtension.getTo().getImage())) {
throw new GradleException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public void setTargetImage(String targetImage) {
@InputFiles
public FileCollection getInputFiles() {
return GradleProjectProperties.getInputFiles(
Preconditions.checkNotNull(jibExtension).getExtraDirectoryPath().toFile(), getProject());
Preconditions.checkNotNull(jibExtension).getExtraDirectory().getPath().toFile(),
getProject());
}

/**
Expand Down Expand Up @@ -109,7 +110,11 @@ public void buildTar()
AbsoluteUnixPath appRoot = PluginConfigurationProcessor.getAppRootChecked(jibExtension);
GradleProjectProperties gradleProjectProperties =
GradleProjectProperties.getForProject(
getProject(), getLogger(), jibExtension.getExtraDirectoryPath(), appRoot);
getProject(),
getLogger(),
jibExtension.getExtraDirectory().getPath(),
jibExtension.getExtraDirectory().getPermissions(),
appRoot);

GradleHelpfulSuggestionsBuilder gradleHelpfulSuggestionsBuilder =
new GradleHelpfulSuggestionsBuilder(HELPFUL_SUGGESTIONS_PREFIX, jibExtension);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public JibExtension getJib() {
@InputFiles
public FileCollection getInputFiles() {
return GradleProjectProperties.getInputFiles(
Preconditions.checkNotNull(jibExtension).getExtraDirectoryPath().toFile(), getProject());
Preconditions.checkNotNull(jibExtension).getExtraDirectory().getPath().toFile(),
getProject());
}

/**
Expand Down Expand Up @@ -110,7 +111,11 @@ public void generateDockerContext() {
AbsoluteUnixPath appRoot = PluginConfigurationProcessor.getAppRootChecked(jibExtension);
GradleProjectProperties gradleProjectProperties =
GradleProjectProperties.getForProject(
getProject(), getLogger(), jibExtension.getExtraDirectoryPath(), appRoot);
getProject(),
getLogger(),
jibExtension.getExtraDirectory().getPath(),
jibExtension.getExtraDirectory().getPermissions(),
appRoot);
String targetDir = getTargetDir();

List<String> entrypoint =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2018 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

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

import com.google.cloud.tools.jib.plugins.common.ConfigurationPropertyValidator;
import com.google.cloud.tools.jib.plugins.common.PropertyNames;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Map;
import javax.inject.Inject;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;

/** Object in {@link JibExtension} that configures the extra directory. */
public class ExtraDirectoryParameters {

private static Path resolveDefaultExtraDirectory(Path projectDirectory) {
return projectDirectory.resolve("src").resolve("main").resolve("jib");
}

private Path path;
private Map<String, String> permissions = Collections.emptyMap();

@Inject
public ExtraDirectoryParameters(Path projectDirectory) {
path = resolveDefaultExtraDirectory(projectDirectory);
}

@Input
public String getPathString() {
// Gradle warns about @Input annotations on File objects, so we have to expose a getter for a
// String to make them go away.
if (System.getProperty(PropertyNames.EXTRA_DIRECTORY_PATH) != null) {
return System.getProperty(PropertyNames.EXTRA_DIRECTORY_PATH);
}
return path.toString();
}

@Internal
public Path getPath() {
// Gradle warns about @Input annotations on File objects, so we have to expose a getter for a
// String to make them go away.
if (System.getProperty(PropertyNames.EXTRA_DIRECTORY_PATH) != null) {
return Paths.get(System.getProperty(PropertyNames.EXTRA_DIRECTORY_PATH));
}
return path;
}

public void setPath(File path) {
this.path = path.toPath();
}

/**
* Gets the permissions for files in the extra layer on the container. Maps from absolute path on
* the container to a 3-digit octal string representation of the file permission bits (e.g. {@code
* "/path/on/container" -> "755"}).
*
* @return the permissions map from path on container to file permissions
*/
@Input
public Map<String, String> getPermissions() {
if (System.getProperty(PropertyNames.EXTRA_DIRECTORY_PERMISSIONS) != null) {
return ConfigurationPropertyValidator.parseMapProperty(
System.getProperty(PropertyNames.EXTRA_DIRECTORY_PERMISSIONS));
}
return permissions;
}

public void setPermissions(Map<String, String> permissions) {
this.permissions = permissions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ public void listFiles() {
printProjectFiles(project);

// Print extra layer
if (Files.exists(jibExtension.getExtraDirectoryPath())) {
System.out.println(jibExtension.getExtraDirectoryPath());
if (Files.exists(jibExtension.getExtraDirectory().getPath())) {
System.out.println(jibExtension.getExtraDirectory().getPath());
}

// Find project dependencies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

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

import com.google.cloud.tools.jib.configuration.FilePermissions;
import com.google.cloud.tools.jib.filesystem.AbsoluteUnixPath;
import com.google.cloud.tools.jib.frontend.JavaEntrypointConstructor;
import com.google.cloud.tools.jib.frontend.JavaLayerConfigurations;
Expand All @@ -26,6 +27,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
import org.gradle.api.logging.Logger;
Expand All @@ -44,18 +46,23 @@ class GradleLayerConfigurations {
* @param project the Gradle {@link Project}
* @param logger the logger for providing feedback about the resolution
* @param extraDirectory path to the source directory for the extra files layer
* @param permissions map from path on container to file permissions for extra-layer files
* @param appRoot root directory in the image where the app will be placed
* @return {@link JavaLayerConfigurations} for the layers for the Gradle {@link Project}
* @throws IOException if an I/O exception occurred during resolution
*/
static JavaLayerConfigurations getForProject(
Project project, Logger logger, Path extraDirectory, AbsoluteUnixPath appRoot)
Project project,
Logger logger,
Path extraDirectory,
Map<AbsoluteUnixPath, FilePermissions> permissions,
AbsoluteUnixPath appRoot)
throws IOException {
if (GradleProjectProperties.getWarTask(project) != null) {
logger.info("WAR project identified, creating WAR image: " + project.getDisplayName());
return getForWarProject(project, logger, extraDirectory, appRoot);
return getForWarProject(project, extraDirectory, permissions, appRoot);
} else {
return getForNonWarProject(project, logger, extraDirectory, appRoot);
return getForNonWarProject(project, logger, extraDirectory, permissions, appRoot);
}
}

Expand All @@ -65,12 +72,17 @@ static JavaLayerConfigurations getForProject(
* @param project the Gradle {@link Project}
* @param logger the logger for providing feedback about the resolution
* @param extraDirectory path to the source directory for the extra files layer
* @param permissions map from path on container to file permissions for extra-layer files
* @param appRoot root directory in the image where the app will be placed
* @return {@link JavaLayerConfigurations} for the layers for the Gradle {@link Project}
* @throws IOException if an I/O exception occurred during resolution
*/
private static JavaLayerConfigurations getForNonWarProject(
Project project, Logger logger, Path extraDirectory, AbsoluteUnixPath appRoot)
Project project,
Logger logger,
Path extraDirectory,
Map<AbsoluteUnixPath, FilePermissions> permissions,
AbsoluteUnixPath appRoot)
throws IOException {
AbsoluteUnixPath dependenciesExtractionPath =
appRoot.resolve(JavaEntrypointConstructor.DEFAULT_RELATIVE_DEPENDENCIES_PATH_ON_IMAGE);
Expand Down Expand Up @@ -127,7 +139,11 @@ private static JavaLayerConfigurations getForNonWarProject(
// Adds all the extra files.
if (Files.exists(extraDirectory)) {
layerBuilder.addDirectoryContents(
LayerType.EXTRA_FILES, extraDirectory, path -> true, AbsoluteUnixPath.get("/"));
LayerType.EXTRA_FILES,
extraDirectory,
path -> true,
AbsoluteUnixPath.get("/"),
permissions);
}

return layerBuilder.build();
Expand All @@ -137,17 +153,21 @@ private static JavaLayerConfigurations getForNonWarProject(
* Resolves the {@link JavaLayerConfigurations} for a WAR Gradle {@link Project}.
*
* @param project the Gradle {@link Project}
* @param logger the build logger for providing feedback about the resolution
* @param extraDirectory path to the source directory for the extra files layer
* @param permissions map from path on container to file permissions for extra-layer files
* @param appRoot root directory in the image where the app will be placed
* @return {@link JavaLayerConfigurations} for the layers for the Gradle {@link Project}
* @throws IOException if an I/O exception occurred during resolution
*/
private static JavaLayerConfigurations getForWarProject(
Project project, Logger logger, Path extraDirectory, AbsoluteUnixPath appRoot)
Project project,
Path extraDirectory,
Map<AbsoluteUnixPath, FilePermissions> permissions,
AbsoluteUnixPath appRoot)
throws IOException {
Path explodedWarPath = GradleProjectProperties.getExplodedWarDirectory(project);
return JavaLayerConfigurationsHelper.fromExplodedWar(explodedWarPath, appRoot, extraDirectory);
return JavaLayerConfigurationsHelper.fromExplodedWar(
explodedWarPath, appRoot, extraDirectory, permissions);
}

private GradleLayerConfigurations() {}
Expand Down
Loading

0 comments on commit 90a0b66

Please sign in to comment.