use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib-extensions by GoogleContainerTools.
the class JibNativeImageExtension method extendContainerBuildPlan.
@Override
public ContainerBuildPlan extendContainerBuildPlan(ContainerBuildPlan buildPlan, Map<String, String> properties, Optional<Void> config, MavenData mavenData, ExtensionLogger logger) throws JibPluginExtensionException {
logger.log(LogLevel.LIFECYCLE, "Running Jib Native Image extension");
MavenProject project = mavenData.getMavenProject();
Optional<String> executableName = getExecutableName(project, properties);
if (!executableName.isPresent()) {
throw new JibPluginExtensionException(getClass(), "cannot auto-detect native-image executable name; consider setting 'imageName' property");
}
String outputDirectory = project.getBuild().getDirectory();
Path localExecutable = Paths.get(outputDirectory, executableName.get());
if (!Files.isRegularFile(localExecutable)) {
throw new JibPluginExtensionException(getClass(), "Native-image executable does not exist or not a file: " + localExecutable + "\nDid you run the 'native-image:native-image' goal?");
}
// TODO: also check system and Maven properties (e.g., -Djib.container.appRoot).
String appRoot = getPluginConfigValue(project, JIB_APP_ROOT).orElse("/app");
AbsoluteUnixPath targetExecutable = AbsoluteUnixPath.get(appRoot).resolve(executableName.get());
ContainerBuildPlan.Builder planBuilder = buildPlan.toBuilder();
FileEntriesLayer nativeImageLayer = FileEntriesLayer.builder().setName("native image").addEntry(localExecutable, targetExecutable, FilePermissions.fromOctalString("755")).build();
planBuilder.setLayers(Collections.singletonList(nativeImageLayer));
// Preserve extra directories layers.
String extraFilesLayerName = JavaContainerBuilder.LayerType.EXTRA_FILES.getName();
buildPlan.getLayers().stream().filter(layer -> layer.getName().startsWith(extraFilesLayerName)).forEach(planBuilder::addLayer);
// TODO: also check system and Maven properties (e.g., -Djib.container.entrypoint).
if (!getPluginConfigValue(project, JIB_ENTRYPOINT).isPresent()) {
planBuilder.setEntrypoint(Collections.singletonList(targetExecutable.toString()));
}
return planBuilder.build();
}
use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib-extensions by GoogleContainerTools.
the class JibQuarkusExtension method extendContainerBuildPlan.
@Override
public ContainerBuildPlan extendContainerBuildPlan(ContainerBuildPlan buildPlan, Map<String, String> properties, Optional<Void> config, GradleData gradleData, ExtensionLogger logger) throws JibPluginExtensionException {
try {
logger.log(LogLevel.LIFECYCLE, "Running Quarkus Jib extension");
readJibConfigurations(gradleData.getProject());
Project project = gradleData.getProject();
Path buildDir = project.getBuildDir().toPath();
Jar jarTask = (Jar) project.getTasks().findByName("jar");
String jarName = jarTask.getArchiveFile().get().getAsFile().getName();
Path jar = buildDir.resolve(jarName.replaceAll("\\.jar$", "-runner.jar"));
if (!Files.isRegularFile(jar)) {
throw new JibPluginExtensionException(getClass(), jar + " doesn't exist; did you run the Qaurkus Gradle plugin ('quarkusBuild' task)?");
}
ContainerBuildPlan.Builder planBuilder = buildPlan.toBuilder();
planBuilder.setLayers(Collections.emptyList());
// dependency layers
addDependencyLayers(project, planBuilder, buildDir.resolve("lib"));
// Quarkus runner JAR layer
AbsoluteUnixPath appRootJar = appRoot.resolve("app.jar");
FileEntriesLayer jarLayer = FileEntriesLayer.builder().setName("quarkus jar").addEntry(jar, appRootJar).build();
planBuilder.addLayer(jarLayer);
// Preserve extra directories layers.
String extraFilesLayerName = JavaContainerBuilder.LayerType.EXTRA_FILES.getName();
buildPlan.getLayers().stream().filter(layer -> layer.getName().startsWith(extraFilesLayerName)).forEach(planBuilder::addLayer);
// set entrypoint
List<String> entrypoint = new ArrayList<>();
entrypoint.add("java");
entrypoint.addAll(jvmFlags);
entrypoint.add("-jar");
entrypoint.add(appRootJar.toString());
planBuilder.setEntrypoint(entrypoint);
return planBuilder.build();
} catch (IOException ex) {
throw new JibPluginExtensionException(getClass(), Verify.verifyNotNull(ex.getMessage()), ex);
}
}
use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project component-runtime by Talend.
the class ImageM2Mojo method addLayers.
// we create these layers - note that docker does not allow more than 128 layers
// 1. one layer per component stack (not including the component module code)
// 2. one layer with all our components
// 3. one layer for the main dependencies
// 4. one layer for the additional files
// 5. one layer for the main
private void addLayers(final JibContainerBuilder builder) {
final Set<Artifact> components = getComponentArtifacts();
final Set<Artifact> cars = getComponentsCar(components);
// 1
final List<String> coordinates = cars.stream().map(car -> {
final LayerConfiguration.Builder layerBuilder = LayerConfiguration.builder();
layerBuilder.setName(car.getArtifactId() + " component stack");
final AtomicLong size = new AtomicLong();
final String gav = copyComponentDependencies(car, (entry, read) -> {
final String depPath = entry.getName().substring("MAVEN-INF/repository/".length());
final File src = copyFile(entry, read, depPath);
size.addAndGet(src.length());
final AbsoluteUnixPath target = AbsoluteUnixPath.get(workingDirectory).resolve(depPath);
final Path srcPath = src.toPath().toAbsolutePath();
layerBuilder.addEntry(srcPath, target, LayerConfiguration.DEFAULT_FILE_PERMISSIONS_PROVIDER.apply(srcPath, target), lastModified(src.toPath()));
});
return gav == null ? null : new Layer(layerBuilder.build(), size.get(), gav);
}).filter(Objects::nonNull).distinct().sorted(comparing(Layer::getSize).reversed()).peek(it -> builder.addLayer(it.layerConfiguration)).peek(it -> getLog().info("Prepared layer for '" + it.gav + "' dependencies (" + toSize(it.size) + ")")).map(it -> it.gav).collect(toList());
// 2
final LayerConfiguration.Builder componentsLayerBuilder = LayerConfiguration.builder().setName("Components " + components.stream().sorted(comparing(Artifact::toString)).collect(toList()));
final AtomicLong componentSize = new AtomicLong();
components.forEach(it -> {
final Path from = it.getFile().toPath().toAbsolutePath();
componentSize.addAndGet(it.getFile().length());
final AbsoluteUnixPath target = AbsoluteUnixPath.get(workingDirectory).resolve(repositorySystemSession.getLocalRepository().getBasedir().toPath().toAbsolutePath().relativize(from));
componentsLayerBuilder.addEntry(from, target, LayerConfiguration.DEFAULT_FILE_PERMISSIONS_PROVIDER.apply(from, target), lastModified(from));
});
// the registry (only depends on components so belongs to this layer)
writeRegistry(getNewComponentRegistry(coordinates));
writeDigest(getDigests());
final Path registryLocation = getRegistry().toPath().toAbsolutePath();
final Path digestRegistryLocation = getDigestRegistry().toPath().toAbsolutePath();
final AbsoluteUnixPath registryTarget = AbsoluteUnixPath.get(workingDirectory).resolve(registryLocation.getFileName().toString());
final AbsoluteUnixPath digestRegistryTarget = AbsoluteUnixPath.get(workingDirectory).resolve(digestRegistryLocation.getFileName().toString());
Stream.of(new AbstractMap.SimpleEntry<>(registryLocation, registryTarget), new AbstractMap.SimpleEntry<>(digestRegistryLocation, digestRegistryTarget)).forEach(it -> componentsLayerBuilder.addEntry(it.getKey(), it.getValue(), LayerConfiguration.DEFAULT_FILE_PERMISSIONS_PROVIDER.apply(it.getKey(), it.getValue()), lastModified(it.getKey())));
builder.addLayer(componentsLayerBuilder.build());
getLog().info("Prepared layer for components " + cars.toString().replace(":car", "") + " (" + toSize(componentSize.get()) + ")");
// finally add the project binary
if (project.getArtifact() != null && project.getArtifact().getFile() != null && !"pom".equals(project.getArtifact().getType())) {
// 3
final LayerConfiguration.Builder dependenciesLayer = LayerConfiguration.builder().setName("Main Dependencies");
final Path path = project.getArtifact().getFile().toPath().toAbsolutePath();
final AbsoluteUnixPath mainLibs = mainLibFolder != null && !mainLibFolder.trim().isEmpty() && mainLibFolder.startsWith("/") ? AbsoluteUnixPath.get(mainLibFolder) : AbsoluteUnixPath.get(workingDirectory).resolve(mainLibFolder);
final AtomicLong mainDepSize = new AtomicLong();
final List<String> classpath = project.getArtifacts().stream().filter(it -> mainDependenciesScope == null || mainDependenciesScope.equalsIgnoreCase(it.getScope())).map(it -> {
final Path dep = it.getFile().toPath().toAbsolutePath();
final String relativized = repositorySystemSession.getLocalRepository().getBasedir().toPath().toAbsolutePath().relativize(dep).toString();
mainDepSize.addAndGet(it.getFile().length());
final AbsoluteUnixPath targetPath = mainLibs.resolve(relativized.replace(File.separatorChar, '/'));
dependenciesLayer.addEntry(dep, targetPath, LayerConfiguration.DEFAULT_FILE_PERMISSIONS_PROVIDER.apply(dep, targetPath), lastModified(dep));
return targetPath.toString();
}).collect(toList());
builder.addLayer(dependenciesLayer.build());
getLog().info("Prepared layer for main dependencies (" + toSize(mainDepSize.get()) + ")");
// 4
if (additionalFile != null && !additionalFile.isEmpty()) {
final AtomicLong additionalFilesSize = new AtomicLong();
try {
builder.addLayer(additionalFile.stream().filter(File::exists).map(f -> {
additionalFilesSize.addAndGet(f.length());
return f.toPath();
}).collect(toList()), AbsoluteUnixPath.get(additionalFiles.replace("${workingDirectory}", workingDirectory)));
getLog().info("Prepared layer for additional files (" + toSize(mainDepSize.get()) + ")");
} catch (final IOException e) {
getLog().error("Unable to add the additional files layer.", e);
throw new IllegalStateException(e);
}
} else {
getLog().debug("No additional file");
}
// 5
final AbsoluteUnixPath mainPath = mainLibs.resolve(path.getFileName());
classpath.add(mainPath.toString());
builder.addLayer(LayerConfiguration.builder().setName(project.getArtifactId() + " @" + project.getVersion()).addEntry(path, mainPath, LayerConfiguration.DEFAULT_FILE_PERMISSIONS_PROVIDER.apply(path, mainPath), lastModified(path)).build());
getLog().info("Prepared layer for main artifact (" + toSize(path.toFile().length()) + ")");
if (getLog().isDebugEnabled()) {
getLog().debug("> classpath=" + classpath);
}
// finally set the entry point if we have one
if (entryPoint != null) {
final String cp = String.join(":", classpath);
final List<String> newEntrypoint = entryPoint.stream().map(it -> replaceEntrypointPlaceholders(it, cp)).collect(toList());
builder.setEntrypoint(newEntrypoint);
if (getLog().isDebugEnabled()) {
getLog().debug("Entrypoint set to " + newEntrypoint);
}
}
} else {
getLog().info("No artifact attached to this project");
}
}
use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib by google.
the class JavaContainerBuilderHelperTest method testExtraDirectoryLayerConfiguration_overlappingPermissions.
@Test
public void testExtraDirectoryLayerConfiguration_overlappingPermissions() throws URISyntaxException, IOException {
Path extraFilesDirectory = Paths.get(Resources.getResource("core/layer").toURI());
Map<String, FilePermissions> permissionsMap = ImmutableMap.of("/a**", FilePermissions.fromOctalString("123"), // Should be ignored, since first match takes priority
"/a/b**", FilePermissions.fromOctalString("000"), // Should override first match since explicit path is used instead of glob
"/a/b/bar", FilePermissions.fromOctalString("765"));
FileEntriesLayer fileEntriesLayer = JavaContainerBuilderHelper.extraDirectoryLayerConfiguration(extraFilesDirectory, AbsoluteUnixPath.get("/"), Collections.emptyList(), Collections.emptyList(), permissionsMap, (ignored1, ignored2) -> Instant.EPOCH);
assertThat(fileEntriesLayer.getEntries()).comparingElementsUsing(EXTRACTION_PATH_OF).containsExactly("/a", "/a/b", "/a/b/bar", "/c", "/c/cat", "/foo");
Map<AbsoluteUnixPath, FilePermissions> expectedPermissions = ImmutableMap.<AbsoluteUnixPath, FilePermissions>builder().put(AbsoluteUnixPath.get("/a"), FilePermissions.fromOctalString("123")).put(AbsoluteUnixPath.get("/a/b"), FilePermissions.fromOctalString("123")).put(AbsoluteUnixPath.get("/a/b/bar"), FilePermissions.fromOctalString("765")).put(AbsoluteUnixPath.get("/c"), FilePermissions.DEFAULT_FOLDER_PERMISSIONS).put(AbsoluteUnixPath.get("/c/cat"), FilePermissions.DEFAULT_FILE_PERMISSIONS).put(AbsoluteUnixPath.get("/foo"), FilePermissions.DEFAULT_FILE_PERMISSIONS).build();
for (FileEntry entry : fileEntriesLayer.getEntries()) {
assertThat(entry.getPermissions()).isEqualTo(expectedPermissions.get(entry.getExtractionPath()));
}
}
use of com.google.cloud.tools.jib.api.buildplan.AbsoluteUnixPath in project jib by google.
the class JavaContainerBuilder method addDirectoryContentsToLayer.
private void addDirectoryContentsToLayer(Map<LayerType, FileEntriesLayer.Builder> layerBuilders, LayerType layerType, Path sourceRoot, Predicate<Path> pathFilter, AbsoluteUnixPath basePathInContainer) throws IOException {
if (!layerBuilders.containsKey(layerType)) {
layerBuilders.put(layerType, FileEntriesLayer.builder());
}
FileEntriesLayer.Builder builder = layerBuilders.get(layerType);
new DirectoryWalker(sourceRoot).filterRoot().filter(path -> Files.isDirectory(path) || pathFilter.test(path)).walk(path -> {
AbsoluteUnixPath pathOnContainer = basePathInContainer.resolve(sourceRoot.relativize(path));
Instant modificationTime = modificationTimeProvider.get(path, pathOnContainer);
builder.addEntry(path, pathOnContainer, modificationTime);
});
}
Aggregations