1 package io.micronaut.build;
2
3 import com.github.dockerjava.api.command.BuildImageCmd;
4 import com.google.common.io.FileWriteMode;
5 import com.google.common.io.Files;
6 import io.micronaut.build.services.ApplicationConfigurationService;
7 import io.micronaut.build.services.DockerService;
8 import io.micronaut.build.services.JibConfigurationService;
9 import org.apache.maven.plugin.MojoExecutionException;
10 import org.apache.maven.plugins.annotations.Mojo;
11 import org.apache.maven.plugins.annotations.ResolutionScope;
12 import org.apache.maven.project.MavenProject;
13
14 import javax.inject.Inject;
15 import java.io.File;
16 import java.io.IOException;
17 import java.nio.charset.Charset;
18
19
20
21
22
23
24
25
26
27
28
29 @Mojo(name = DockerNativeMojo.DOCKER_NATIVE_PACKAGING, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
30 public class DockerNativeMojo extends AbstractDockerMojo {
31
32 public static final String DOCKER_NATIVE_PACKAGING = "docker-native";
33 public static final String DEFAULT_GRAAL_JVM_VERSION = "java11";
34
35 @SuppressWarnings("CdiInjectionPointsInspection")
36 @Inject
37 public DockerNativeMojo(MavenProject mavenProject, JibConfigurationService jibConfigurationService,
38 ApplicationConfigurationService applicationConfigurationService, DockerService dockerService) {
39 super(mavenProject, jibConfigurationService, applicationConfigurationService, dockerService);
40 }
41
42 @Override
43 public void execute() throws MojoExecutionException {
44 checkJavaVersion();
45
46 try {
47 copyDependencies();
48
49 MicronautRuntime runtime = MicronautRuntime.valueOf(micronautRuntime.toUpperCase());
50
51 switch (runtime.getBuildStrategy()) {
52 case LAMBDA:
53 buildDockerNativeLambda();
54 break;
55
56 case ORACLE_FUNCTION:
57 buildOracleCloud();
58 break;
59
60 case DEFAULT:
61 buildDockerNative();
62 break;
63 }
64
65
66 } catch (Exception e) {
67 throw new MojoExecutionException(e.getMessage(), e);
68 }
69 }
70
71 private void checkJavaVersion() throws MojoExecutionException {
72 if (javaVersion().getMajorVersion() > 11) {
73 throw new MojoExecutionException("To build native images you must set the Java target byte code level to Java 11 or below");
74 }
75 }
76
77 private void buildDockerNativeLambda() throws IOException {
78 BuildImageCmd buildImageCmd = dockerService.buildImageCmd("DockerfileAwsCustomRuntime")
79 .withBuildArg("GRAALVM_VERSION", graalVmVersion())
80 .withBuildArg("GRAALVM_JVM_VERSION", graalVmJvmVersion());
81
82 getLog().info("Using GRAALVM_VERSION: " + graalVmVersion());
83 getLog().info("Using GRAALVM_JVM_VERSION: " + graalVmJvmVersion());
84
85 if (nativeImageBuildArgs != null && !nativeImageBuildArgs.trim().isEmpty()) {
86 getLog().info("Using GRAALVM_ARGS: " + nativeImageBuildArgs);
87 buildImageCmd = buildImageCmd.withBuildArg("GRAALVM_ARGS", nativeImageBuildArgs);
88 }
89
90 String imageId = dockerService.buildImage(buildImageCmd);
91 File functionZip = dockerService.copyFromContainer(imageId, "/function/function.zip");
92 getLog().info("AWS Lambda Custom Runtime ZIP: " + functionZip.getPath());
93 }
94
95 private void buildDockerNative() throws IOException {
96 String dockerfileName = "DockerfileNative";
97 if (staticNativeImage) {
98 getLog().info("Generating a static native image");
99 dockerfileName = "DockerfileNativeStatic";
100 }
101
102 buildDockerfile(dockerfileName, true);
103 }
104
105 private void buildOracleCloud() throws IOException {
106 buildDockerfile("DockerfileNativeOracleCloud", false);
107 }
108
109 private void buildDockerfile(String dockerfileName, boolean passClassName) throws IOException {
110 String from = getFrom();
111 String port = getPort();
112 getLog().info("Exposing port: " + port);
113
114 File dockerfile = dockerService.loadDockerfileAsResource(dockerfileName);
115
116 if (appArguments != null && appArguments.size() > 0) {
117 getLog().info("Using application arguments: " + appArguments);
118 Files.asCharSink(dockerfile, Charset.defaultCharset(), FileWriteMode.APPEND).write(System.lineSeparator() + getCmd());
119 }
120
121 BuildImageCmd buildImageCmd = dockerService.buildImageCmd()
122 .withDockerfile(dockerfile)
123 .withTags(getTags())
124 .withBuildArg("BASE_IMAGE", from)
125 .withBuildArg("PORT", port);
126
127 getLog().info("Using BASE_IMAGE: " + from);
128
129 if (passClassName) {
130 getLog().info("Using CLASS_NAME: " + mainClass);
131 buildImageCmd = buildImageCmd.withBuildArg("CLASS_NAME", mainClass);
132 }
133
134 if (nativeImageBuildArgs != null && !nativeImageBuildArgs.trim().isEmpty()) {
135 getLog().info("Using GRAALVM_ARGS: " + nativeImageBuildArgs);
136 buildImageCmd = buildImageCmd.withBuildArg("GRAALVM_ARGS", nativeImageBuildArgs);
137 }
138
139 dockerService.buildImage(buildImageCmd);
140 }
141
142 }