
net.wouterdanes.docker.maven.AbstractDockerMojo Maven / Gradle / Ivy
/*
Copyright 2014 Wouter Danes
Licensed 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 net.wouterdanes.docker.maven;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Parameter;
import net.wouterdanes.docker.provider.DockerProvider;
import net.wouterdanes.docker.provider.DockerProviderSupplier;
import net.wouterdanes.docker.provider.model.BuiltImageInfo;
import net.wouterdanes.docker.provider.model.ImageBuildConfiguration;
import net.wouterdanes.docker.provider.model.PushableImage;
import net.wouterdanes.docker.remoteapi.exception.DockerException;
import net.wouterdanes.docker.remoteapi.model.Credentials;
/**
* Base class for all Mojos with shared functionality
*/
public abstract class AbstractDockerMojo extends AbstractMojo {
private static final String STARTED_CONTAINERS_KEY = "startedContainers";
private static final String BUILT_IMAGES_KEY = "builtImages";
private static final String PUSHABLE_IMAGES_KEY = "pushableImages";
private static final String ERRORS_KEY = "errors";
@Parameter(defaultValue = "remote", property = "docker.provider", required = true)
private String providerName;
@Parameter(defaultValue = "false", property = "docker.skip", required = false)
private boolean skip;
@Parameter(defaultValue = "", property = "docker.userName", required = false)
private String userName;
@Parameter(defaultValue = "", property = "docker.email", required = false)
private String email;
@Parameter(defaultValue = "", property = "docker.password", required = false)
private String password;
public void setProviderName(final String providerName) {
this.providerName = providerName;
}
public void setSkip(final boolean skip) {
this.skip = skip;
}
@Override
public final void execute() throws MojoExecutionException, MojoFailureException {
if (skip) {
getLog().info("Execution skipped");
return;
}
getLog().info("Using docker provider: " + providerName);
doExecute();
}
protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;
protected void registerStartedContainer(String id) {
List startedContainers = obtainListFromPluginContext(STARTED_CONTAINERS_KEY);
startedContainers.add(id);
}
protected List getStartedContainers() {
return obtainListFromPluginContext(STARTED_CONTAINERS_KEY);
}
protected void registerBuiltImage(String imageId, ImageBuildConfiguration imageConfig) throws MojoFailureException {
BuiltImageInfo info = new BuiltImageInfo(imageId, imageConfig);
Map builtImages = obtainMapFromPluginContext(BUILT_IMAGES_KEY);
builtImages.put(info.getStartId(), info);
if (imageConfig.isPush()) {
enqueueForPushing(imageId, imageConfig);
}
}
protected Collection getBuiltImages() {
Map builtImagesMap = obtainMapFromPluginContext(BUILT_IMAGES_KEY);
return Collections.unmodifiableCollection(builtImagesMap.values());
}
protected DockerProvider getDockerProvider() {
DockerProvider provider = new DockerProviderSupplier(providerName).get();
provider.setCredentials(getCredentials());
return provider;
}
protected Credentials getCredentials() {
if (Strings.isNullOrEmpty(userName)) {
getLog().info("No user name provided");
return null;
}
getLog().info("Using credentials: " + userName);
return new Credentials(userName, password, email, null);
}
protected Optional getBuiltImageForStartId(final String imageId) {
Map builtImages = obtainMapFromPluginContext(BUILT_IMAGES_KEY);
return Optional.fromNullable(builtImages.get(imageId));
}
protected void registerPluginError(DockerPluginError error) {
List errors = obtainListFromPluginContext(ERRORS_KEY);
errors.add(error);
}
protected List getPluginErrors() {
List list = obtainListFromPluginContext(ERRORS_KEY);
return Collections.unmodifiableList(list);
}
protected void enqueueForPushing(final String imageId, final ImageBuildConfiguration imageConfig) throws MojoFailureException {
enqueueForPushing(imageId,
Optional.fromNullable(imageConfig.getNameAndTag()),
Optional.fromNullable(imageConfig.getRegistry()));
}
protected void enqueueForPushing(final String imageId, final Optional nameAndTag, final Optional registry) throws MojoFailureException {
if (!registry.isPresent()) {
enqueueForPushing(imageId, nameAndTag);
return;
}
enqueueForPushingToRegistry(imageId, nameAndTag, registry.get());
}
protected void enqueueForPushingToRegistry(final String imageId, final Optional nameAndTag, final String registry) throws MojoFailureException {
Preconditions.checkArgument(nameAndTag.isPresent(), "When pushing to an explicit registry, name-and-tag must be set.");
// build extended tag by prepending registry to name and tag
String newNameAndTag = registry + "/" + nameAndTag.get();
// apply extended tag
attachTag(imageId, newNameAndTag);
// now enqueue for pushing
enqueueForPushing(imageId, Optional.fromNullable(newNameAndTag));
}
protected void enqueueForPushing(final String imageId, final Optional nameAndTag) {
getLog().info(String.format("Enqueuing image '%s' to be pushed with tag '%s'..", imageId, nameAndTag.or("")));
List images = obtainListFromPluginContext(PUSHABLE_IMAGES_KEY);
PushableImage newImage = new PushableImage(imageId, nameAndTag);
if (!images.contains(newImage)) {
images.add(newImage);
}
}
protected List getImagesToPush() {
List list = obtainListFromPluginContext(PUSHABLE_IMAGES_KEY);
return Collections.unmodifiableList(list);
}
protected void attachTag(String imageId, String nameAndTag) throws MojoFailureException {
try {
getLog().info(String.format("Tagging image '%s' with tag '%s'..", imageId, nameAndTag));
getDockerProvider().tagImage(imageId, nameAndTag);
} catch (DockerException e) {
String message = String.format("Failed to add tag '%s' to image '%s'", imageId, nameAndTag);
handleDockerException(message, e);
}
}
/**
* Common method for re-throwing a {@link DockerException} as a {@link MojoFailureException}
* with a more specific error message. Extract into a common, template method in this base class
* to allow pre "verify" Mojos to handle errors differently.
*/
protected void handleDockerException(String message, DockerException e) throws MojoFailureException {
Optional apiResponse = e.getApiResponse();
if (apiResponse.isPresent()) {
message += "\nApi response:\n%s" + apiResponse.get();
}
throw new MojoFailureException(message, e);
}
@SuppressWarnings("unchecked")
private List obtainListFromPluginContext(String name) {
Object obj = getPluginContext().get(name);
if (obj == null) {
ArrayList list = new ArrayList<>();
getPluginContext().put(name, list);
return list;
} else {
return (List) obj;
}
}
@SuppressWarnings("unchecked")
private Map obtainMapFromPluginContext(String name) {
Object obj = getPluginContext().get(name);
if (obj == null) {
Map map = new HashMap<>();
getPluginContext().put(name, map);
return map;
} else {
return (Map) obj;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy