1 package io.micronaut.build;
2
3 import com.google.common.io.FileWriteMode;
4 import io.micronaut.build.services.ApplicationConfigurationService;
5 import io.micronaut.build.services.DockerService;
6 import io.micronaut.build.services.JibConfigurationService;
7 import org.apache.maven.plugin.MojoExecutionException;
8 import org.apache.maven.plugins.annotations.Mojo;
9 import org.apache.maven.plugins.annotations.ResolutionScope;
10 import org.apache.maven.project.MavenProject;
11
12 import javax.inject.Inject;
13 import java.io.File;
14 import java.io.IOException;
15 import java.nio.charset.Charset;
16 import java.nio.file.Files;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.Optional;
20 import java.util.stream.Collectors;
21
22 import static io.micronaut.build.DockerNativeMojo.DOCKER_NATIVE_PACKAGING;
23
24
25
26
27
28
29
30
31
32
33 @Mojo(name = "dockerfile", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
34 public class DockerfileMojo extends AbstractDockerMojo {
35
36 public static final String DOCKER_PACKAGING = "docker";
37
38 @Inject
39 public DockerfileMojo(MavenProject mavenProject, DockerService dockerService, JibConfigurationService jibConfigurationService,
40 ApplicationConfigurationService applicationConfigurationService) {
41 super(mavenProject, jibConfigurationService, applicationConfigurationService, dockerService);
42 }
43
44 @Override
45 public void execute() throws MojoExecutionException {
46 MicronautRuntime runtime = MicronautRuntime.valueOf(micronautRuntime.toUpperCase());
47 String packaging = mavenProject.getPackaging();
48 try {
49 copyDependencies();
50 Optional<File> dockerfile;
51
52 switch (packaging) {
53 case DOCKER_NATIVE_PACKAGING:
54 dockerfile = buildDockerfileNative(runtime);
55 break;
56
57 case DOCKER_PACKAGING:
58 dockerfile = buildDockerfile(runtime);
59 break;
60
61 default:
62 throw new MojoExecutionException("Packaging is set to [" + packaging + "]. To generate a Dockerfile, set the packaging to either [" + DOCKER_PACKAGING + "] or [" + DOCKER_NATIVE_PACKAGING + "]");
63 }
64
65 dockerfile.ifPresent(file -> getLog().info("Dockerfile written to: " + file.getAbsolutePath()));
66
67 } catch (Exception e) {
68 throw new MojoExecutionException(e.getMessage(), e);
69 }
70 }
71
72 private Optional<File> buildDockerfile(MicronautRuntime runtime) throws IOException {
73 File dockerfile = null;
74 switch (runtime.getBuildStrategy()) {
75 case ORACLE_FUNCTION:
76 return Optional.ofNullable(dockerService.loadDockerfileAsResource("DockerfileOracleCloud"));
77
78 case LAMBDA:
79 case DEFAULT:
80 dockerfile = dockerService.loadDockerfileAsResource("Dockerfile");
81 break;
82 }
83 processDockerfile(dockerfile);
84 return Optional.ofNullable(dockerfile);
85 }
86
87 private Optional<File> buildDockerfileNative(MicronautRuntime runtime) throws IOException {
88 File dockerfile = null;
89 switch (runtime.getBuildStrategy()) {
90 case LAMBDA:
91 dockerfile = dockerService.loadDockerfileAsResource("DockerfileAwsCustomRuntime");
92 break;
93
94 case ORACLE_FUNCTION:
95 dockerfile = dockerService.loadDockerfileAsResource("DockerfileNativeOracleCloud");
96 break;
97
98 case DEFAULT:
99 String dockerfileName = "DockerfileNative";
100 if (staticNativeImage) {
101 getLog().info("Generating a static native image");
102 dockerfileName = "DockerfileNativeStatic";
103 }
104 dockerfile = dockerService.loadDockerfileAsResource(dockerfileName);
105 break;
106 }
107 processDockerfile(dockerfile);
108 return Optional.ofNullable(dockerfile);
109
110 }
111
112 private void processDockerfile(File dockerfile) throws IOException {
113 if (dockerfile != null) {
114 List<String> allLines = Files.readAllLines(dockerfile.toPath());
115 List<String> result = new ArrayList<>();
116
117 for (String line : allLines) {
118 if (!line.startsWith("ARG")) {
119 if (line.contains("BASE_IMAGE")) {
120 result.add(line.replace("${BASE_IMAGE}", getFrom()));
121 } else if (line.contains("GRAALVM_") || line.contains("CLASS_NAME")) {
122 result.add(line
123 .replace("${GRAALVM_VERSION}", graalVmVersion())
124 .replace("${GRAALVM_JVM_VERSION}", graalVmJvmVersion())
125 .replace("${GRAALVM_ARGS} ", nativeImageBuildArgs != null ? nativeImageBuildArgs.trim() : "")
126 .replace("${CLASS_NAME}", mainClass)
127 );
128 } else if (line.contains("PORT")) {
129 result.add(line.replace("${PORT}", getPort()));
130 } else {
131 result.add(line);
132 }
133 }
134 }
135
136 if (appArguments != null && appArguments.size() > 0) {
137 getLog().info("Using application arguments: " + appArguments);
138 result.add(getCmd());
139 }
140
141 Files.write(dockerfile.toPath(), result);
142 }
143 }
144 }