View Javadoc
1   /*
2    * Copyright 2017-2022 original authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package io.micronaut.build;
17  
18  import com.github.dockerjava.api.command.PushImageCmd;
19  import com.github.dockerjava.api.model.AuthConfig;
20  import com.google.cloud.tools.jib.api.Credential;
21  import com.google.cloud.tools.jib.maven.MavenProjectProperties;
22  import io.micronaut.build.services.ApplicationConfigurationService;
23  import io.micronaut.build.services.DockerService;
24  import io.micronaut.build.services.JibConfigurationService;
25  import org.apache.maven.plugin.MojoExecutionException;
26  import org.apache.maven.plugin.MojoFailureException;
27  import org.apache.maven.plugins.annotations.Mojo;
28  import org.apache.maven.project.MavenProject;
29  import org.testcontainers.utility.DockerImageName;
30  import org.testcontainers.utility.RegistryAuthLocator;
31  
32  import javax.inject.Inject;
33  import java.util.Set;
34  
35  /**
36   * <p>Implementation of the <code>deploy</code> lifecycle for pushing Docker images</p>
37   * <p><strong>WARNING</strong>: this goal is not intended to be executed directly. Instead, Execute the <code>deploy</code>
38   * phase specifying the packaging type, eg:</p>
39   *
40   * <pre>mvn deploy -Dpackaging=docker-native</pre>
41   *
42   * @author Álvaro Sánchez-Mariscal
43   * @since 1.1
44   */
45  @Mojo(name = "docker-push")
46  public class DockerPushMojo extends AbstractDockerMojo {
47  
48      @Inject
49      public DockerPushMojo(MavenProject mavenProject, JibConfigurationService jibConfigurationService,
50                               ApplicationConfigurationService applicationConfigurationService, DockerService dockerService) {
51          super(mavenProject, jibConfigurationService, applicationConfigurationService, dockerService);
52      }
53  
54      @Override
55      public void execute() throws MojoExecutionException, MojoFailureException {
56          Packaging packaging = Packaging.of(mavenProject.getPackaging());
57          if (packaging == Packaging.DOCKER || packaging == Packaging.DOCKER_NATIVE || packaging == Packaging.DOCKER_CRAC) {
58              Set<String> images = getTags();
59  
60              // getTags() will automatically generate an image name if none is specified
61              // To maintain error compatibility, check that an image name has been
62              // manually specified.
63              if (jibConfigurationService.getToImage().isPresent()) {
64                  for (String taggedImage : images) {
65                      getLog().info("Pushing image: " + taggedImage);
66                      try (PushImageCmd pushImageCmd = dockerService.pushImageCmd(taggedImage)) {
67                          AuthConfig defaultAuthConfig = new AuthConfig();
68                          if (jibConfigurationService.getCredentials().isPresent()) {
69                              Credential credential = jibConfigurationService.getCredentials().get();
70                              defaultAuthConfig
71                                      .withUsername(credential.getUsername())
72                                      .withPassword(credential.getPassword());
73                          }
74                          RegistryAuthLocator registryAuthLocator = RegistryAuthLocator.instance();
75                          DockerImageName dockerImageName = DockerImageName.parse(taggedImage);
76                          AuthConfig authConfig = registryAuthLocator.lookupAuthConfig(dockerImageName, defaultAuthConfig);
77  
78                          pushImageCmd
79                                  .withAuthConfig(authConfig)
80                                  .start()
81                                  .awaitCompletion();
82                      } catch (InterruptedException e) {
83                          Thread.currentThread().interrupt();
84                      } catch (Exception e) {
85                          throw new MojoExecutionException(e.getMessage(), e);
86                      }
87                  }
88              } else {
89                  throw new MojoFailureException("The plugin " + MavenProjectProperties.PLUGIN_KEY + " is misconfigured. Missing <to> tag");
90              }
91          } else {
92              throw new MojoFailureException("The <packaging> must be set to either [" + Packaging.DOCKER.id() + "] or [" + Packaging.DOCKER_NATIVE.id() + "]");
93          }
94      }
95  }