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.PushImageCmd; 019import com.github.dockerjava.api.model.AuthConfig; 020import com.google.cloud.tools.jib.api.Credential; 021import com.google.cloud.tools.jib.maven.MavenProjectProperties; 022import io.micronaut.maven.jib.JibConfigurationService; 023import io.micronaut.maven.services.ApplicationConfigurationService; 024import io.micronaut.maven.services.DockerService; 025import org.apache.maven.execution.MavenSession; 026import org.apache.maven.plugin.MojoExecution; 027import org.apache.maven.plugin.MojoExecutionException; 028import org.apache.maven.plugin.MojoFailureException; 029import org.apache.maven.plugins.annotations.Mojo; 030import org.apache.maven.project.MavenProject; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034import javax.inject.Inject; 035import java.util.Optional; 036 037/** 038 * <p>Implementation of the <code>deploy</code> lifecycle for pushing Docker images</p> 039 * <p><strong>WARNING</strong>: this goal is not intended to be executed directly. Instead, Execute the <code>deploy</code> 040 * phase specifying the packaging type, eg:</p> 041 * 042 * <pre>mvn deploy -Dpackaging=docker-native</pre> 043 * 044 * @author Álvaro Sánchez-Mariscal 045 * @since 1.1 046 */ 047@Mojo(name = "docker-push") 048public class DockerPushMojo extends AbstractDockerMojo { 049 050 private static final Logger LOG = LoggerFactory.getLogger(DockerPushMojo.class); 051 052 @Inject 053 public DockerPushMojo(MavenProject mavenProject, JibConfigurationService jibConfigurationService, 054 ApplicationConfigurationService applicationConfigurationService, DockerService dockerService, 055 MavenSession mavenSession, MojoExecution mojoExecution) { 056 super(mavenProject, jibConfigurationService, applicationConfigurationService, dockerService, mavenSession, mojoExecution); 057 } 058 059 @Override 060 public void execute() throws MojoExecutionException, MojoFailureException { 061 Packaging packaging = Packaging.of(mavenProject.getPackaging()); 062 if (packaging == Packaging.DOCKER || packaging == Packaging.DOCKER_NATIVE || packaging == Packaging.DOCKER_CRAC) { 063 var images = getTags(); 064 065 // getTags() will automatically generate an image name if none is specified 066 // To maintain error compatibility, check that an image name has been 067 // manually specified. 068 if (jibConfigurationService.getToImage().isPresent()) { 069 for (String taggedImage : images) { 070 getLog().info("Pushing image: " + taggedImage); 071 try (PushImageCmd pushImageCmd = dockerService.pushImageCmd(taggedImage)) { 072 Optional<Credential> toCredentials = jibConfigurationService.getToCredentials(); 073 Optional<Credential> credential = toCredentials.or(() -> jibConfigurationService.resolveCredentialForImage(taggedImage, LOG)); 074 credential.ifPresent(cred -> { 075 var username = cred.getUsername(); 076 var password = cred.getPassword(); 077 AuthConfig authConfig = dockerService.getAuthConfigFor(taggedImage, username, password); 078 pushImageCmd.withAuthConfig(authConfig); 079 }); 080 081 pushImageCmd.start().awaitCompletion(); 082 } catch (InterruptedException e) { 083 Thread.currentThread().interrupt(); 084 } catch (Exception e) { 085 throw new MojoExecutionException(e.getMessage(), e); 086 } 087 } 088 } else { 089 throw new MojoFailureException("The plugin " + MavenProjectProperties.PLUGIN_KEY + " is misconfigured. Missing <to> tag"); 090 } 091 } else { 092 throw new MojoFailureException("The <packaging> must be set to either [" + Packaging.DOCKER.id() + "] or [" + Packaging.DOCKER_NATIVE.id() + "]"); 093 } 094 } 095 096}