001/* 002 * Copyright 2017-2022 original authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.micronaut.maven; 017 018import com.github.dockerjava.api.command.BuildImageCmd; 019import com.google.cloud.tools.jib.plugins.common.PropertyNames; 020import io.micronaut.maven.core.DockerBuildStrategy; 021import io.micronaut.maven.core.MicronautRuntime; 022import io.micronaut.maven.jib.JibConfigurationService; 023import io.micronaut.maven.services.ApplicationConfigurationService; 024import io.micronaut.maven.services.DockerService; 025import io.micronaut.maven.services.ExecutorService; 026import org.apache.maven.execution.MavenSession; 027import org.apache.maven.plugin.MojoExecution; 028import org.apache.maven.plugin.MojoExecutionException; 029import org.apache.maven.plugins.annotations.Mojo; 030import org.apache.maven.plugins.annotations.ResolutionScope; 031import org.apache.maven.project.MavenProject; 032 033import javax.inject.Inject; 034import java.io.File; 035import java.io.IOException; 036import java.nio.file.Files; 037import java.nio.file.LinkOption; 038import java.nio.file.StandardCopyOption; 039 040import static io.micronaut.maven.DockerfileMojo.DOCKERFILE_ORACLE_CLOUD; 041 042/** 043 * <p>Allows using a provided Dockerfile.</p> 044 * <p><strong>WARNING</strong>: this goal is not intended to be executed directly. Instead, specify the packaging type 045 * using the <code>packaging</code> property, eg:</p> 046 * 047 * <pre>mvn package -Dpackaging=docker</pre> 048 * 049 * @author Álvaro Sánchez-Mariscal 050 * @since 1.1 051 */ 052@Mojo(name = DockerMojo.DOCKER_PACKAGING, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) 053public class DockerMojo extends AbstractDockerMojo { 054 055 public static final String DOCKER_PACKAGING = "docker"; 056 057 private final ExecutorService executorService; 058 059 @SuppressWarnings("CdiInjectionPointsInspection") 060 @Inject 061 public DockerMojo(MavenProject mavenProject, JibConfigurationService jibConfigurationService, 062 ApplicationConfigurationService applicationConfigurationService, DockerService dockerService, 063 MavenSession mavenSession, MojoExecution mojoExecution, ExecutorService executorService) { 064 super(mavenProject, jibConfigurationService, applicationConfigurationService, dockerService, mavenSession, 065 mojoExecution); 066 this.executorService = executorService; 067 } 068 069 @Override 070 public void execute() throws MojoExecutionException { 071 var providedDockerfile = new File(mavenProject.getBasedir(), DockerfileMojo.DOCKERFILE); 072 if (shouldBuildWithDockerfile(providedDockerfile)) { 073 var dockerfile = determineDockerfile(providedDockerfile); 074 buildDockerfile(dockerfile, providedDockerfile.exists()); 075 } else { 076 validateJibBuildGoal(); 077 if (JIB_BUILD_GOAL_BUILD.equals(jibBuildGoal)) { 078 requireConfiguredToImageForJibRegistryBuild(); 079 } 080 if (jibConfigurationService.getFromImage().isEmpty()) { 081 mavenProject.getProperties().setProperty(PropertyNames.FROM_IMAGE, getBaseImage()); 082 } 083 executorService.executeGoal(mavenProject, "com.google.cloud.tools:jib-maven-plugin", jibBuildGoal); 084 } 085 } 086 087 private File determineDockerfile(File providedDockerfile) throws MojoExecutionException { 088 if (providedDockerfile.exists()) { 089 return providedDockerfile; 090 } 091 try { 092 return dockerService.loadDockerfileAsResource(DOCKERFILE_ORACLE_CLOUD); 093 } catch (IOException e) { 094 throw new MojoExecutionException("Error loading Dockerfile", e); 095 } 096 } 097 098 private void buildDockerfile(File dockerfile, boolean providedDockerfileExists) throws MojoExecutionException { 099 try { 100 var runtime = MicronautRuntime.valueOf(micronautRuntime.toUpperCase()); 101 if (runtime.getBuildStrategy() == DockerBuildStrategy.ORACLE_FUNCTION && !providedDockerfileExists) { 102 oracleCloudFunctionCmd(dockerfile); 103 DockerfileMojo.processOracleFunctionDockerfile(dockerfile); 104 } 105 getLog().info("Using Dockerfile: " + dockerfile.getAbsolutePath()); 106 mavenProject.getProperties().put(PropertyNames.SKIP, "true"); 107 108 copyDependencies(); 109 110 String targetDir = mavenProject.getBuild().getDirectory(); 111 var targetDockerfile = new File(targetDir, dockerfile.getName()); 112 Files.copy(dockerfile.toPath(), targetDockerfile.toPath(), LinkOption.NOFOLLOW_LINKS, 113 StandardCopyOption.REPLACE_EXISTING); 114 115 BuildImageCmd buildImageCmd = dockerService.buildImageCmd() 116 .withDockerfile(targetDockerfile) 117 .withTags(getTags()) 118 .withBaseDirectory(new File(targetDir)); 119 getNetworkMode().ifPresent(buildImageCmd::withNetworkMode); 120 dockerService.buildImage(buildImageCmd); 121 } catch (IOException e) { 122 throw new MojoExecutionException(e.getMessage(), e); 123 } 124 } 125 126}