Skip to content

Commit

Permalink
feat: Introduce a new extension for generating Dockerfiles
Browse files Browse the repository at this point in the history
  • Loading branch information
iocanel committed Aug 6, 2024
1 parent b5231da commit 8b617f8
Show file tree
Hide file tree
Showing 27 changed files with 1,004 additions and 1 deletion.
16 changes: 15 additions & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2817,6 +2817,21 @@
<artifactId>quarkus-container-image-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes</artifactId>
Expand Down Expand Up @@ -6847,7 +6862,6 @@
<version>${project.version}</version>
</dependency>
<!-- End of Relocations, please put new extensions above this list -->

</dependencies>
</dependencyManagement>

Expand Down
13 changes: 13 additions & 0 deletions devtools/bom-descriptor-json/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3099,6 +3099,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- END update-extension-dependencies.sh -->
</dependencies>
</profile>
Expand Down
13 changes: 13 additions & 0 deletions docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3111,6 +3111,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- END update-extension-dependencies.sh -->
</dependencies>

Expand Down
106 changes: 106 additions & 0 deletions extensions/dockerfiles/cli/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-dockerfiles-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-dockerfiles-cli</artifactId>
<name>Quarkus - Dockerfiles - CLI</name>
<description>CLI plugin that provides commands for Dockerfile genration</description>

<properties>
<quarkus.package.jar.type>uber-jar</quarkus.package.jar.type>
</properties>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-picocli</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devtools-common</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bootstrap-maven-resolver</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles-spi</artifactId>
</dependency>

<!-- This dependency is here to make sure the build order is correct-->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-picocli-deployment</artifactId>
<type>pom</type>
<scope>test</scope>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>


<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
<configuration>
<skipOriginalJarRename>true</skipOriginalJarRename>
<environmentVariables>
<MAVEN_REPO_LOCAL>${settings.localRepository}</MAVEN_REPO_LOCAL>
<GRADLE_OPTS>${env.MAVEN_OPTS}</GRADLE_OPTS>
</environmentVariables>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package io.quarkus.dockerfiles.cli;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.function.Consumer;

import io.quarkus.bootstrap.BootstrapException;
import io.quarkus.bootstrap.app.AugmentAction;
import io.quarkus.bootstrap.app.CuratedApplication;
import io.quarkus.bootstrap.app.QuarkusBootstrap;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.QuarkusProjectHelper;
import io.quarkus.dockerfiles.spi.GeneratedDockerfile;
import io.quarkus.picocli.runtime.annotations.TopCommand;
import picocli.CommandLine.Command;
import picocli.CommandLine.ExitCode;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@TopCommand
@Command(name = "dockerfiles", sortOptions = false, mixinStandardHelpOptions = false, header = "Generate Dockerfiles.", headerHeading = "%n", commandListHeading = "%nCommands:%n", synopsisHeading = "%nUsage: ", optionListHeading = "%nOptions:%n")
public class Dockerfiles implements Callable<Integer> {

@Option(names = { "--jvm" }, paramLabel = "", order = 5, description = "Flag to enable JVM Dockerfile generation")
boolean generateJvmDockerfile;

@Option(names = { "--native" }, paramLabel = "", order = 5, description = "Flag to enable Native Dockerfile generation")
boolean generateNativeDockerfile;

@Parameters(arity = "0..1", paramLabel = "GENERATION_PATH", description = " The path to generate Dockerfiles")
Optional<String> generationPath;

public Integer call() {
Path projectRoot = getWorkingDirectory();
BuildTool buildTool = QuarkusProjectHelper.detectExistingBuildTool(projectRoot);
if (buildTool == null) {
System.out.println("Unable to determine the build tool used for the project at " + projectRoot);
return ExitCode.USAGE;
}
Path targetDirecotry = projectRoot.resolve(buildTool.getBuildDirectory());
QuarkusBootstrap quarkusBootstrap = QuarkusBootstrap.builder()
.setMode(QuarkusBootstrap.Mode.PROD)
.setApplicationRoot(getWorkingDirectory())
.setProjectRoot(getWorkingDirectory())
.setTargetDirectory(targetDirecotry)
.setLocalProjectDiscovery(true)
.setIsolateDeployment(false)
.setBaseClassLoader(ClassLoader.getSystemClassLoader())
.build();

List<String> resultBuildItemFQCNs = new ArrayList<>();

boolean hasJvmSuffix = generationPath.map(p -> p.endsWith(".jvm")).orElse(false);
boolean hasNativeSuffix = generationPath.map(p -> p.endsWith(".native")).orElse(false);
boolean isDirectory = generationPath.map(p -> Paths.get(p).toFile().isDirectory())
.orElse(Paths.get("").toFile().isDirectory());

// Checking
if (generateJvmDockerfile && hasNativeSuffix) {
System.out.println("Cannot generate JVM Dockerfile when the path has a .native suffix");
return ExitCode.USAGE;
}
if (generateNativeDockerfile && hasJvmSuffix) {
System.out.println("Cannot generate Native Dockerfile when the path has a .jvm suffix");
return ExitCode.USAGE;
} else if (generateJvmDockerfile && generateNativeDockerfile && !isDirectory) {

}

if (generateJvmDockerfile || hasJvmSuffix) {
resultBuildItemFQCNs.add(GeneratedDockerfile.Jvm.class.getName());
}

if (generateNativeDockerfile || hasNativeSuffix) {
resultBuildItemFQCNs.add(GeneratedDockerfile.Native.class.getName());
}

if (resultBuildItemFQCNs.isEmpty()) {
generateJvmDockerfile = true;
resultBuildItemFQCNs.add(GeneratedDockerfile.Jvm.class.getName());
}

Path jvmDockerfile = (isDirectory
? generationPath.map(p -> Paths.get(p))
: generationPath.map(Paths::get))
.orElse(Paths.get("Dockerfile.jvm"));

Path nativeDockerfile = (isDirectory
? generationPath.map(p -> Paths.get(p))
: generationPath.map(Paths::get))
.orElse(Paths.get("Dockerfile.native"));

try (CuratedApplication curatedApplication = quarkusBootstrap.bootstrap()) {
AugmentAction action = curatedApplication.createAugmentor();

action.performCustomBuild(GenerateDockerfilesHandler.class.getName(), new Consumer<List<GeneratedDockerfile>>() {
@Override
public void accept(List<GeneratedDockerfile> dockerfiles) {
for (GeneratedDockerfile dockerfile : dockerfiles) {
if (dockerfile instanceof GeneratedDockerfile.Jvm) {
writeStringSafe(jvmDockerfile, dockerfile.getContent());
System.out.println("Generated JVM Dockerfile: " + jvmDockerfile);
} else if (dockerfile instanceof GeneratedDockerfile.Native) {
writeStringSafe(nativeDockerfile, dockerfile.getContent());
System.out.println("Generated Native Dockerfile: " + nativeDockerfile);
}
}
}
}, resultBuildItemFQCNs.toArray(new String[resultBuildItemFQCNs.size()]));

} catch (BootstrapException e) {
throw new RuntimeException(e);
}
return ExitCode.OK;
}

private void writeStringSafe(Path p, String content) {
try {
Files.writeString(p, content);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private Path getWorkingDirectory() {
return Paths.get(System.getProperty("user.dir"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.quarkus.dockerfiles.cli;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import io.quarkus.builder.BuildResult;
import io.quarkus.dockerfiles.spi.GeneratedDockerfile;
import io.quarkus.dockerfiles.spi.GeneratedDockerfile.Jvm;
import io.quarkus.dockerfiles.spi.GeneratedDockerfile.Native;

public class GenerateDockerfilesHandler implements BiConsumer<Object, BuildResult> {

@Override
public void accept(Object context, BuildResult buildResult) {
List<GeneratedDockerfile> dockerfiles = new ArrayList<>();

GeneratedDockerfile.Jvm jvmDockerfile = buildResult.consumeOptional(GeneratedDockerfile.Jvm.class);
GeneratedDockerfile.Native nativeDockerfile = buildResult.consumeOptional(GeneratedDockerfile.Native.class);

if (jvmDockerfile != null) {
dockerfiles.add(jvmDockerfile);
}

if (nativeDockerfile != null) {
dockerfiles.add(nativeDockerfile);
}
Consumer<List<GeneratedDockerfile>> consumer = (Consumer<List<GeneratedDockerfile>>) context;
consumer.accept(dockerfiles);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
quarkus.log.level=WARN
quarkus.banner.enabled=false
50 changes: 50 additions & 0 deletions extensions/dockerfiles/deployment/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles-parent</artifactId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>quarkus-dockerfiles-deployment</artifactId>
<name>Quarkus - Dockerfiles - Deployment</name>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-dockerfiles</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
Loading

0 comments on commit 8b617f8

Please sign in to comment.