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

io.fabric8.maven.docker.BuildMojo Maven / Gradle / Ivy

There is a newer version: 0.45.0
Show newest version
package io.fabric8.maven.docker;

import io.fabric8.maven.docker.access.DockerAccessException;
import io.fabric8.maven.docker.config.BuildImageConfiguration;
import io.fabric8.maven.docker.config.ImageConfiguration;
import io.fabric8.maven.docker.service.BuildService;
import io.fabric8.maven.docker.service.ImagePullManager;
import io.fabric8.maven.docker.service.JibBuildService;
import io.fabric8.maven.docker.service.ServiceHub;
import io.fabric8.maven.docker.service.helper.BuildArgResolver;
import io.fabric8.maven.docker.util.EnvUtil;
import io.fabric8.maven.docker.util.Logger;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;

import static io.fabric8.maven.docker.service.RegistryService.createCompleteAuthConfigList;

/**
 * Mojo for building a data image
 *
 * @author roland
 * @since 28.07.14
 */
@Mojo(name = "build", defaultPhase = LifecyclePhase.INSTALL, requiresDependencyResolution = ResolutionScope.TEST)
public class BuildMojo extends AbstractDockerMojo {

    public static final String DMP_PLUGIN_DESCRIPTOR = "META-INF/maven/io.fabric8/dmp-plugin";
    public static final String DOCKER_EXTRA_DIR = "docker-extra";

    @Parameter(property = "docker.skip.build", defaultValue = "false")
    protected boolean skipBuild;

    @Parameter(property = "docker.name", defaultValue = "")
    protected String name;

    /**
     * Skip Sending created tarball to docker daemon
     */
    @Parameter(property = "docker.buildArchiveOnly", defaultValue = "false")
    protected String buildArchiveOnly;

    /**
     * Skip building tags
     */
    @Parameter(property = "docker.skip.tag", defaultValue = "false")
    protected boolean skipTag;

    @Override
    protected void executeInternal(ServiceHub hub) throws IOException, MojoExecutionException {
        if (skipBuild) {
            return;
        }

        // Check for build plugins
        executeBuildPlugins();

        // Iterate over all the ImageConfigurations and process one by one
        for (ImageConfiguration imageConfig : getResolvedImages()) {
            processImageConfig(hub, imageConfig);
        }
    }

    protected void buildAndTag(ServiceHub hub, ImageConfiguration imageConfig)
            throws MojoExecutionException, IOException {

        EnvUtil.storeTimestamp(getBuildTimestampFile(), getBuildTimestamp());

        BuildService.BuildContext buildContext = getBuildContext();
        ImagePullManager pullManager = getImagePullManager(determinePullPolicy(imageConfig.getBuildConfiguration()), autoPull);
        proceedWithBuildProcess(hub, buildContext, imageConfig, pullManager);
    }

    private void proceedWithBuildProcess(ServiceHub hub, BuildService.BuildContext buildContext, ImageConfiguration imageConfig, ImagePullManager pullManager) throws MojoExecutionException, IOException {
        if (Boolean.TRUE.equals(jib)) {
            proceedWithJibBuild(hub, buildContext, imageConfig);
        } else {
            proceedWithDockerBuild(hub, buildContext, imageConfig, pullManager);
        }
    }

    private void proceedWithJibBuild(ServiceHub hub, BuildService.BuildContext buildContext, ImageConfiguration imageConfig) throws MojoExecutionException {
        log.info("Building Container image with [[B]]JIB(Java Image Builder)[[B]] mode");
        new JibBuildService(hub, createMojoParameters(), log).build(jibImageFormat, imageConfig, buildContext.getRegistryConfig());
    }

    private void proceedWithDockerBuild(ServiceHub hub, BuildService.BuildContext buildContext, ImageConfiguration imageConfig, ImagePullManager pullManager)
        throws MojoExecutionException, IOException {
        BuildService buildService= hub.getBuildService();
        File buildArchiveFile = buildService.buildArchive(imageConfig, buildContext, resolveBuildArchiveParameter());
        if (Boolean.FALSE.equals(shallBuildArchiveOnly())) {
            if (imageConfig.isBuildX()) {
                BuildArgResolver buildArgResolver = new BuildArgResolver(log);
                Map buildArgsFromExternalSources = buildArgResolver.resolveBuildArgs(buildContext);
                hub.getBuildXService().build(createProjectPaths(), imageConfig, null, createCompleteAuthConfigList(false, imageConfig, getRegistryConfig(pullRegistry), createMojoParameters(), buildArgsFromExternalSources), buildArchiveFile);
            } else {
                buildService.buildImage(imageConfig, pullManager, buildContext, buildArchiveFile);
                if (!skipTag && !imageConfig.getBuildConfiguration().skipTag()) {
                    buildService.tagImage(imageConfig);
                }
            }
        }
    }

    // We ignore an already existing date file and always return the current date
    @Override
    protected Date getReferenceDate() {
        return new Date();
    }

    private String resolveBuildArchiveParameter() {
        if (buildArchiveOnly != null && !buildArchiveOnly.isEmpty()) {
            if (!(buildArchiveOnly.equalsIgnoreCase("false") ||
                buildArchiveOnly.equalsIgnoreCase("true"))) {
                return buildArchiveOnly;
            }
        }
        return null;
    }

    private boolean shallBuildArchiveOnly() {
        if (buildArchiveOnly != null && !buildArchiveOnly.isEmpty()) {
            if (buildArchiveOnly.equalsIgnoreCase("false") ||
                    buildArchiveOnly.equalsIgnoreCase("true")) {
                return Boolean.parseBoolean(buildArchiveOnly);
            }
        }
        return false;
    }

    private String determinePullPolicy(BuildImageConfiguration buildConfig) {
        return buildConfig != null && buildConfig.getImagePullPolicy() != null ? buildConfig.getImagePullPolicy() : imagePullPolicy;
    }

    /**
     * Helper method to process an ImageConfiguration.
     *
     * @param hub ServiceHub
     * @param aImageConfig ImageConfiguration that would be forwarded to build and tag
     * @throws DockerAccessException
     * @throws MojoExecutionException
     */
    private void processImageConfig(ServiceHub hub, ImageConfiguration aImageConfig) throws IOException, MojoExecutionException {
        BuildImageConfiguration buildConfig = aImageConfig.getBuildConfiguration();

        if (buildConfig != null) {
            if (buildConfig.skip() || shouldSkipPom()) {
                log.info("%s : Skipped building", aImageConfig.getDescription());
            } else {
                buildAndTag(hub, aImageConfig);
            }
        }
    }

    // check for a run-java.sh dependency an extract the script to target/ if found
    private void executeBuildPlugins() {
        try {
            Enumeration dmpPlugins = Thread.currentThread().getContextClassLoader().getResources(DMP_PLUGIN_DESCRIPTOR);
            while (dmpPlugins.hasMoreElements()) {

                URL dmpPlugin = dmpPlugins.nextElement();
                File outputDir = getAndEnsureOutputDirectory();
                processDmpPluginDescription(dmpPlugin, outputDir);
            }
        } catch (IOException e) {
            log.error("Cannot load dmp-plugins from %s", DMP_PLUGIN_DESCRIPTOR);
        }
    }

    private void processDmpPluginDescription(URL pluginDesc, File outputDir) throws IOException {
        String line = null;
        try (LineNumberReader reader =
                 new LineNumberReader(new InputStreamReader(pluginDesc.openStream(), "UTF8"))) {
            line = reader.readLine();
            while (line != null) {
                if (line.matches("^\\s*#")) {
                    // Skip comments
                    continue;
                }
                callBuildPlugin(outputDir, line);
                line = reader.readLine();
            }
        } catch (ClassNotFoundException e) {
            // Not declared as dependency, so just ignoring ...
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            log.verbose(Logger.LogVerboseCategory.BUILD,"Found dmp-plugin %s but could not be called : %s",
                     line,
                     e.getMessage());
        }
    }

    private File getAndEnsureOutputDirectory() {
        File outputDir = new File(new File(project.getBuild().getDirectory()), DOCKER_EXTRA_DIR);
        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }
        return outputDir;
    }

    private void callBuildPlugin(File outputDir, String buildPluginClass) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Class buildPlugin = Class.forName(buildPluginClass);
        try {
            Method method = buildPlugin.getMethod("addExtraFiles", File.class);
            method.invoke(null, outputDir);
            log.info("Extra files from %s extracted", buildPluginClass);
        } catch (NoSuchMethodException exp) {
            log.verbose(Logger.LogVerboseCategory.BUILD,"Build plugin %s does not support 'addExtraFiles' method", buildPluginClass);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy