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