All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.spotify.docker.AbstractDockerMojo Maven / Gradle / Ivy

/*
 * Copyright (c) 2014 Spotify AB.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.spotify.docker;

import com.google.common.base.Optional;
import com.spotify.docker.client.DefaultDockerClient;
import com.spotify.docker.client.DockerCertificates;
import com.spotify.docker.client.DockerClient;
import com.spotify.docker.client.exceptions.DockerCertificateException;
import com.spotify.docker.client.messages.AuthConfig;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;

import java.io.IOException;
import java.nio.file.Paths;

import static com.google.common.base.Strings.isNullOrEmpty;
import static com.spotify.docker.client.DefaultDockerClient.NO_TIMEOUT;

abstract class AbstractDockerMojo extends AbstractMojo {

  @Component(role = MavenSession.class)
  protected MavenSession session;

  @Component(role = MojoExecution.class)
  protected MojoExecution execution;

  /**
   * The system settings for Maven. This is the instance resulting from
   * merging global and user-level settings files.
   */
  @Component
  private Settings settings;

  /**
   * https://issues.apache.org/jira/browse/MNG-4384
   */
  @Component(role = SecDispatcher.class, hint = "mng-4384")
  private SecDispatcher secDispatcher;

  /**
   * URL of the docker host as specified in pom.xml.
   */
  @Parameter(property = "dockerHost")
  private String dockerHost;
  
  @Parameter(property = "dockerCertPath")
  private String dockerCertPath;
  
  @Parameter(property = "serverId")
  private String serverId;

  @Parameter(property = "registryUrl")
  private String registryUrl;

  @Parameter(property = "useConfigFile")
  private Boolean useConfigFile;

  /**
   * Number of retries for failing pushes, defaults to 5.
   */
  @Parameter(property = "retryPushCount", defaultValue = "5")
  private int retryPushCount;

  /**
   * Retry timeout for failing pushes, defaults to 10 seconds.
   */
  @Parameter(property = "retryPushTimeout", defaultValue = "10000")
  private int retryPushTimeout;

  public int getRetryPushTimeout() {
    return retryPushTimeout;
  }

  public int getRetryPushCount() {
    return retryPushCount;
  };

  public void execute() throws MojoExecutionException {
    DockerClient client = null;
    try {
      final DefaultDockerClient.Builder builder = getBuilder();

      final String dockerHost = rawDockerHost();
      if (!isNullOrEmpty(dockerHost)) {
        builder.uri(dockerHost);
      }
      final Optional certs = dockerCertificates();
      if (certs.isPresent()) {
        builder.dockerCertificates(certs.get());
      }

      final AuthConfig authConfig = authConfig();
      if (authConfig != null) {
        builder.authConfig(authConfig);
      }

      client = builder.build();
      execute(client);
    } catch (Exception e) {
      throw new MojoExecutionException("Exception caught", e);
    } finally {
      if (client != null) {
        client.close();
      }
    }
  }

  protected DefaultDockerClient.Builder getBuilder() throws DockerCertificateException {
    return DefaultDockerClient.fromEnv()
      .readTimeoutMillis(NO_TIMEOUT);
  }

  protected abstract void execute(final DockerClient dockerClient) throws Exception;

  protected String rawDockerHost() {
    return dockerHost;
  }

  protected Optional dockerCertificates() throws DockerCertificateException {
    if (!isNullOrEmpty(dockerCertPath)) {
      return DockerCertificates.builder()
        .dockerCertPath(Paths.get(dockerCertPath)).build();
    } else {
      return Optional.absent();
    }
  }
  
  /**
   * Get the email from the server configuration in ~/.m2/settings.xml.
   *
   * 
   * 
   *   
   *     my-private-docker-registry
   *     [...]
   *     
   *       [email protected]
   *     
   *   
   * 
   * 
* * The above settings.xml would return "[email protected]". * * @param server {@link org.apache.maven.settings.Server} * @return email string. */ private String getEmail(final Server server) { String email = null; final Xpp3Dom configuration = (Xpp3Dom) server.getConfiguration(); if (configuration != null) { final Xpp3Dom emailNode = configuration.getChild("email"); if (emailNode != null) { email = emailNode.getValue(); } } return email; } /** * Checks for incomplete private Docker registry authorization settings. * @param username Auth username. * @param password Auth password. * @param email Auth email. * @return boolean true if any of the three credentials are present but not all. False otherwise. */ private boolean incompleteAuthSettings(final String username, final String password, final String email) { return (!isNullOrEmpty(username) || !isNullOrEmpty(password) || !isNullOrEmpty(email)) && (isNullOrEmpty(username) || isNullOrEmpty(password) || isNullOrEmpty(email)); } /** * Builds the AuthConfig object from server details. * @return AuthConfig * @throws MojoExecutionException * @throws SecDispatcherException */ protected AuthConfig authConfig() throws MojoExecutionException, SecDispatcherException { if (settings != null) { final Server server = settings.getServer(serverId); if (server != null) { final AuthConfig.Builder authConfigBuilder = AuthConfig.builder(); final String username = server.getUsername(); String password = server.getPassword(); if (secDispatcher != null) { password = secDispatcher.decrypt(password); } final String email = getEmail(server); if (incompleteAuthSettings(username, password, email)) { throw new MojoExecutionException( "Incomplete Docker registry authorization credentials. " + "Please provide all of username, password, and email or none."); } if (!isNullOrEmpty(username)) { authConfigBuilder.username(username); } if (!isNullOrEmpty(email)) { authConfigBuilder.email(email); } if (!isNullOrEmpty(password)) { authConfigBuilder.password(password); } // registryUrl is optional. // Spotify's docker-client defaults to 'https://index.docker.io/v1/'. if (!isNullOrEmpty(registryUrl)) { authConfigBuilder.serverAddress(registryUrl); } return authConfigBuilder.build(); } else if (useConfigFile != null && useConfigFile){ final AuthConfig.Builder authConfigBuilder; try { if (!isNullOrEmpty(registryUrl)) { authConfigBuilder = AuthConfig.fromDockerConfig(registryUrl); } else { authConfigBuilder = AuthConfig.fromDockerConfig(); } } catch (IOException ex){ throw new MojoExecutionException( "Docker config file could not be read", ex ); } return authConfigBuilder.build(); } } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy