use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib by google.
the class Layers method toLayers.
/**
* Convert a layer spec to a list of layer objects.
*
* <p>Does not handle missing directories for files added via this method. We can either prefill
* directories here, or allow passing of the file entry information directly to the reproducible
* layer builder
*
* @param buildRoot the directory to resolve relative paths, usually the directory where the build
* config file is located
* @param layersSpec a layersSpec containing configuration for all layers
* @return a {@link List} of {@link FileEntriesLayer} to use as part of a jib container build
* @throws IOException if traversing a directory fails
*/
static List<FileEntriesLayer> toLayers(Path buildRoot, LayersSpec layersSpec) throws IOException {
List<FileEntriesLayer> layers = new ArrayList<>();
FilePropertiesStack filePropertiesStack = new FilePropertiesStack();
// base properties
layersSpec.getProperties().ifPresent(filePropertiesStack::push);
for (LayerSpec entry : layersSpec.getEntries()) {
// each loop is a new layer
if (entry instanceof FileLayerSpec) {
FileEntriesLayer.Builder layerBuiler = FileEntriesLayer.builder();
FileLayerSpec fileLayer = (FileLayerSpec) entry;
layerBuiler.setName(fileLayer.getName());
// layer properties
fileLayer.getProperties().ifPresent(filePropertiesStack::push);
for (CopySpec copySpec : ((FileLayerSpec) entry).getFiles()) {
// copy spec properties
copySpec.getProperties().ifPresent(filePropertiesStack::push);
// relativize all paths to the buildRoot location
Path rawSrc = copySpec.getSrc();
Path src = rawSrc.isAbsolute() ? rawSrc : buildRoot.resolve(rawSrc);
AbsoluteUnixPath dest = copySpec.getDest();
if (!Files.isDirectory(src) && !Files.isRegularFile(src)) {
throw new UnsupportedOperationException("Cannot create FileLayers from non-file, non-directory: " + src.toString());
}
if (Files.isRegularFile(src)) {
// regular file
if (!copySpec.getExcludes().isEmpty() || !copySpec.getIncludes().isEmpty()) {
throw new UnsupportedOperationException("Cannot apply includes/excludes on single file copy directives.");
}
layerBuiler.addEntry(src, copySpec.isDestEndsWithSlash() ? dest.resolve(src.getFileName()) : dest, filePropertiesStack.getFilePermissions(), filePropertiesStack.getModificationTime(), filePropertiesStack.getOwnership());
} else if (Files.isDirectory(src)) {
// directory
List<PathMatcher> excludes = copySpec.getExcludes().stream().map(Layers::toPathMatcher).collect(Collectors.toList());
List<PathMatcher> includes = copySpec.getIncludes().stream().map(Layers::toPathMatcher).collect(Collectors.toList());
try (Stream<Path> dirWalk = Files.walk(src)) {
List<Path> filtered = dirWalk.filter(path -> excludes.stream().noneMatch(exclude -> exclude.matches(path))).filter(path -> {
// if there are no includes directives, include everything
if (includes.isEmpty()) {
return true;
}
// if there are includes directives, only include those specified
for (PathMatcher matcher : includes) {
if (matcher.matches(path)) {
return true;
}
}
return false;
}).collect(Collectors.toList());
BiFunction<Path, FilePermissions, FileEntry> newEntry = (file, permission) -> new FileEntry(file, dest.resolve(src.relativize(file)), permission, filePropertiesStack.getModificationTime(), filePropertiesStack.getOwnership());
Set<Path> addedDirectories = new HashSet<>();
for (Path path : filtered) {
if (!Files.isDirectory(path) && !Files.isRegularFile(path)) {
throw new UnsupportedOperationException("Cannot create FileLayers from non-file, non-directory: " + src.toString());
}
if (Files.isDirectory(path)) {
addedDirectories.add(path);
layerBuiler.addEntry(newEntry.apply(path, filePropertiesStack.getDirectoryPermissions()));
} else if (Files.isRegularFile(path)) {
if (!path.startsWith(src)) {
// be from a link scenario that we do not understand.
throw new IllegalStateException(src.toString() + " is not a parent of " + path.toString());
}
Path parent = Verify.verifyNotNull(path.getParent());
while (true) {
if (addedDirectories.contains(parent)) {
break;
}
layerBuiler.addEntry(newEntry.apply(parent, filePropertiesStack.getDirectoryPermissions()));
addedDirectories.add(parent);
if (parent.equals(src)) {
break;
}
parent = Verify.verifyNotNull(parent.getParent());
}
layerBuiler.addEntry(newEntry.apply(path, filePropertiesStack.getFilePermissions()));
}
}
}
}
copySpec.getProperties().ifPresent(ignored -> filePropertiesStack.pop());
}
fileLayer.getProperties().ifPresent(ignored -> filePropertiesStack.pop());
// TODO: add logging/handling for empty layers
layers.add(layerBuiler.build());
} else {
throw new UnsupportedOperationException("Only FileLayers are supported at this time.");
}
}
layersSpec.getProperties().ifPresent(ignored -> filePropertiesStack.pop());
return layers;
}
use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib by google.
the class JavaContainerBuilderHelper method extraDirectoryLayerConfiguration.
/**
* Returns a {@link FileEntriesLayer} for adding the extra directory to the container.
*
* @param sourceDirectory the source extra directory path
* @param targetDirectory the root directory on the container to place the files in
* @param includes the list of glob patterns to include from the source directory
* @param excludes the list of glob patterns to exclude from the source directory
* @param extraDirectoryPermissions map from path on container to file permissions
* @param modificationTimeProvider file modification time provider
* @return a {@link FileEntriesLayer} for adding the extra directory to the container
* @throws IOException if walking the extra directory fails
*/
public static FileEntriesLayer extraDirectoryLayerConfiguration(Path sourceDirectory, AbsoluteUnixPath targetDirectory, List<String> includes, List<String> excludes, Map<String, FilePermissions> extraDirectoryPermissions, ModificationTimeProvider modificationTimeProvider) throws IOException {
FileEntriesLayer.Builder builder = FileEntriesLayer.builder().setName(LayerType.EXTRA_FILES.getName());
Map<PathMatcher, FilePermissions> permissionsPathMatchers = new LinkedHashMap<>();
for (Map.Entry<String, FilePermissions> entry : extraDirectoryPermissions.entrySet()) {
permissionsPathMatchers.put(FileSystems.getDefault().getPathMatcher(GLOB_PREFIX + entry.getKey()), entry.getValue());
}
DirectoryWalker walker = new DirectoryWalker(sourceDirectory).filterRoot();
// add exclusion filters
excludes.stream().map(pattern -> FileSystems.getDefault().getPathMatcher(GLOB_PREFIX + pattern)).forEach(pathMatcher -> walker.filter(path -> !pathMatcher.matches(sourceDirectory.relativize(path))));
// add an inclusion filter
includes.stream().map(pattern -> FileSystems.getDefault().getPathMatcher(GLOB_PREFIX + pattern)).map(pathMatcher -> (Predicate<Path>) path -> pathMatcher.matches(sourceDirectory.relativize(path))).reduce((matches1, matches2) -> matches1.or(matches2)).ifPresent(walker::filter);
// walk the source tree and add layer entries
walker.walk(localPath -> {
AbsoluteUnixPath pathOnContainer = targetDirectory.resolve(sourceDirectory.relativize(localPath));
Instant modificationTime = modificationTimeProvider.get(localPath, pathOnContainer);
Optional<FilePermissions> permissions = determinePermissions(pathOnContainer, extraDirectoryPermissions, permissionsPathMatchers);
if (permissions.isPresent()) {
builder.addEntry(localPath, pathOnContainer, permissions.get(), modificationTime);
} else {
builder.addEntry(localPath, pathOnContainer, modificationTime);
}
});
return builder.build();
}
use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib by google.
the class JavaContainerBuilderTest method testToJibContainerBuilder_missingAndMultipleAdds.
@Test
public void testToJibContainerBuilder_missingAndMultipleAdds() throws InvalidImageReferenceException, URISyntaxException, IOException, CacheDirectoryCreationException {
BuildContext buildContext = JavaContainerBuilder.from("scratch").addDependencies(getResource("core/application/dependencies/libraryA.jar")).addDependencies(getResource("core/application/dependencies/libraryB.jar")).addSnapshotDependencies(getResource("core/application/snapshot-dependencies/dependency-1.0.0-SNAPSHOT.jar")).addClasses(getResource("core/application/classes/")).addClasses(getResource("core/class-finder-tests/extension")).setMainClass("HelloWorld").toContainerBuilder().toBuildContext(Containerizer.to(RegistryImage.named("hello")));
// Check entrypoint
Assert.assertEquals(ImmutableList.of("java", "-cp", "/app/libs/*:/app/classes", "HelloWorld"), buildContext.getContainerConfiguration().getEntrypoint());
// Check dependencies
List<AbsoluteUnixPath> expectedDependencies = ImmutableList.of(AbsoluteUnixPath.get("/app/libs/libraryA.jar"), AbsoluteUnixPath.get("/app/libs/libraryB.jar"));
Assert.assertEquals(expectedDependencies, getExtractionPaths(buildContext, "dependencies"));
// Check snapshots
List<AbsoluteUnixPath> expectedSnapshotDependencies = ImmutableList.of(AbsoluteUnixPath.get("/app/libs/dependency-1.0.0-SNAPSHOT.jar"));
Assert.assertEquals(expectedSnapshotDependencies, getExtractionPaths(buildContext, "snapshot dependencies"));
// Check classes
List<AbsoluteUnixPath> expectedClasses = ImmutableList.of(AbsoluteUnixPath.get("/app/classes/HelloWorld.class"), AbsoluteUnixPath.get("/app/classes/some.class"), AbsoluteUnixPath.get("/app/classes/main/"), AbsoluteUnixPath.get("/app/classes/main/MainClass.class"), AbsoluteUnixPath.get("/app/classes/pack/"), AbsoluteUnixPath.get("/app/classes/pack/Apple.class"), AbsoluteUnixPath.get("/app/classes/pack/Orange.class"));
Assert.assertEquals(expectedClasses, getExtractionPaths(buildContext, "classes"));
// Check empty layers
Assert.assertEquals(ImmutableList.of(), getExtractionPaths(buildContext, "resources"));
Assert.assertEquals(ImmutableList.of(), getExtractionPaths(buildContext, "extra files"));
}
use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib by GoogleContainerTools.
the class StandardExplodedProcessorTest method testCreateLayers_withClassPathInManifest.
@Test
public void testCreateLayers_withClassPathInManifest() throws IOException, URISyntaxException {
Path standardJar = Paths.get(Resources.getResource(STANDARD_JAR_WITH_CLASS_PATH_MANIFEST).toURI());
Path destDir = temporaryFolder.newFolder().toPath();
StandardExplodedProcessor standardExplodedModeProcessor = new StandardExplodedProcessor(standardJar, destDir, JAR_JAVA_VERSION);
List<FileEntriesLayer> layers = standardExplodedModeProcessor.createLayers();
assertThat(layers.size()).isEqualTo(4);
FileEntriesLayer nonSnapshotLayer = layers.get(0);
FileEntriesLayer snapshotLayer = layers.get(1);
FileEntriesLayer resourcesLayer = layers.get(2);
FileEntriesLayer classesLayer = layers.get(3);
// Validate dependencies layers.
assertThat(nonSnapshotLayer.getName()).isEqualTo("dependencies");
assertThat(nonSnapshotLayer.getEntries().stream().map(FileEntry::getExtractionPath).collect(Collectors.toList())).isEqualTo(ImmutableList.of(AbsoluteUnixPath.get("/app/dependencies/dependency1"), AbsoluteUnixPath.get("/app/dependencies/dependency2"), AbsoluteUnixPath.get("/app/dependencies/dependency4")));
assertThat(snapshotLayer.getName()).isEqualTo("snapshot dependencies");
assertThat(snapshotLayer.getEntries().size()).isEqualTo(1);
assertThat(snapshotLayer.getEntries().get(0).getExtractionPath()).isEqualTo(AbsoluteUnixPath.get("/app/dependencies/dependency3-SNAPSHOT-1.jar"));
// Validate resources layer.
assertThat(resourcesLayer.getName()).isEqualTo("resources");
List<AbsoluteUnixPath> actualResourcesPaths = resourcesLayer.getEntries().stream().map(FileEntry::getExtractionPath).collect(Collectors.toList());
assertThat(actualResourcesPaths).containsExactly(AbsoluteUnixPath.get("/app/explodedJar/META-INF/MANIFEST.MF"), AbsoluteUnixPath.get("/app/explodedJar/directory1/resource1.txt"), AbsoluteUnixPath.get("/app/explodedJar/directory2/directory3/resource2.sql"), AbsoluteUnixPath.get("/app/explodedJar/directory4/resource3.txt"), AbsoluteUnixPath.get("/app/explodedJar/resource4.sql"));
// Validate classes layer.
assertThat(classesLayer.getName()).isEqualTo("classes");
List<AbsoluteUnixPath> actualClassesPaths = classesLayer.getEntries().stream().map(FileEntry::getExtractionPath).collect(Collectors.toList());
assertThat(actualClassesPaths).containsExactly(AbsoluteUnixPath.get("/app/explodedJar/class5.class"), AbsoluteUnixPath.get("/app/explodedJar/directory1/class1.class"), AbsoluteUnixPath.get("/app/explodedJar/directory1/class2.class"), AbsoluteUnixPath.get("/app/explodedJar/directory2/class4.class"), AbsoluteUnixPath.get("/app/explodedJar/directory2/directory3/class3.class"));
}
use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib by GoogleContainerTools.
the class StandardExplodedProcessorTest method testCreateLayers_withoutClassPathInManifest.
@Test
public void testCreateLayers_withoutClassPathInManifest() throws IOException, URISyntaxException {
Path standardJar = Paths.get(Resources.getResource(STANDARD_JAR_WITHOUT_CLASS_PATH_MANIFEST).toURI());
Path destDir = temporaryFolder.newFolder().toPath();
StandardExplodedProcessor standardExplodedModeProcessor = new StandardExplodedProcessor(standardJar, destDir, JAR_JAVA_VERSION);
List<FileEntriesLayer> layers = standardExplodedModeProcessor.createLayers();
assertThat(layers.size()).isEqualTo(2);
FileEntriesLayer resourcesLayer = layers.get(0);
FileEntriesLayer classesLayer = layers.get(1);
// Validate resources layer.
assertThat(resourcesLayer.getName()).isEqualTo("resources");
List<AbsoluteUnixPath> actualResourcesPaths = resourcesLayer.getEntries().stream().map(FileEntry::getExtractionPath).collect(Collectors.toList());
assertThat(actualResourcesPaths).containsExactly(AbsoluteUnixPath.get("/app/explodedJar/META-INF/MANIFEST.MF"), AbsoluteUnixPath.get("/app/explodedJar/directory1/resource1.txt"), AbsoluteUnixPath.get("/app/explodedJar/directory2/directory3/resource2.sql"), AbsoluteUnixPath.get("/app/explodedJar/directory4/resource3.txt"), AbsoluteUnixPath.get("/app/explodedJar/resource4.sql"));
// Validate classes layer.
assertThat(classesLayer.getName()).isEqualTo("classes");
List<AbsoluteUnixPath> actualClassesPaths = classesLayer.getEntries().stream().map(FileEntry::getExtractionPath).collect(Collectors.toList());
assertThat(actualClassesPaths).containsExactly(AbsoluteUnixPath.get("/app/explodedJar/class5.class"), AbsoluteUnixPath.get("/app/explodedJar/directory1/class1.class"), AbsoluteUnixPath.get("/app/explodedJar/directory1/class2.class"), AbsoluteUnixPath.get("/app/explodedJar/directory2/class4.class"), AbsoluteUnixPath.get("/app/explodedJar/directory2/directory3/class3.class"));
}
Aggregations