de.gesellix.gradle.docker.tasks.DockerRunTask Maven / Gradle / Ivy
package de.gesellix.gradle.docker.tasks;
import de.gesellix.docker.client.EnvFileParser;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
import javax.inject.Inject;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DockerRunTask extends GenericDockerTask {
private final Property imageName;
@Input
public Property getImageName() {
return imageName;
}
private final Property imageTag;
@Input
@Optional
public Property getImageTag() {
return imageTag;
}
private final Property containerName;
@Input
@Optional
public Property getContainerName() {
return containerName;
}
private final ListProperty ports;
/**
* Accepts a list of port mappings with the following pattern: `hostPort:containerPort`.
* More sophisticated patterns are only supported via plain containerConfig.
*/
@Input
@Optional
public ListProperty getPorts() {
return ports;
}
private final MapProperty containerConfiguration;
@Input
@Optional
public MapProperty getContainerConfiguration() {
return containerConfiguration;
}
private final ListProperty env;
@Input
@Optional
public ListProperty getEnv() {
return env;
}
private final ListProperty environmentFiles;
@Input
@Optional
public ListProperty getEnvironmentFiles() {
return environmentFiles;
}
private Object result;
@Internal
public Object getResult() {
return result;
}
private final EnvFileParser envFileParser = new EnvFileParser();
@Inject
public DockerRunTask(ObjectFactory objectFactory) {
super(objectFactory);
setDescription("Run a command in a new container");
imageName = objectFactory.property(String.class);
imageTag = objectFactory.property(String.class);
imageTag.convention("");
containerName = objectFactory.property(String.class);
containerName.convention("");
ports = objectFactory.listProperty(String.class);
containerConfiguration = objectFactory.mapProperty(String.class, Object.class);
env = objectFactory.listProperty(String.class);
environmentFiles = objectFactory.listProperty(File.class);
}
@TaskAction
public void run() {
getLogger().info("docker run");
Map containerConfig = getActualContainerConfig();
result = getDockerClient().run(
getImageName().get(),
containerConfig,
getImageTag().get(),
getContainerName().get(),
getEncodedAuthConfig());
}
@Internal
public Map getActualContainerConfig() {
final Map containerConfig = new HashMap<>(getContainerConfiguration().getOrElse(new HashMap<>()));
containerConfig.putIfAbsent("HostConfig", new HashMap<>());
Map hostConfig = (Map) containerConfig.get("HostConfig");
if (!getEnvironmentFiles().get().isEmpty()) {
containerConfig.putIfAbsent("Env", new ArrayList<>());
final List env = (List) containerConfig.get("Env");
getEnvironmentFiles().get().forEach((File file) -> {
List parsedEnv = envFileParser.parse(file);
env.addAll(parsedEnv);
});
}
if (!getEnv().get().isEmpty()) {
containerConfig.putIfAbsent("Env", new ArrayList<>());
final List env = (List) containerConfig.get("Env");
env.addAll(getEnv().get());
}
if (!getPorts().get().isEmpty()) {
containerConfig.putIfAbsent("ExposedPorts", new HashMap<>());
final Map exposedPorts = (Map) containerConfig.get("ExposedPorts");
hostConfig.putIfAbsent("PortBindings", new HashMap<>());
final Map portBindings = (Map) hostConfig.get("PortBindings");
getPorts().get().forEach((String portMapping) -> {
// format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort
final String[] splittedPortMapping = portMapping.split(":");
if (splittedPortMapping.length != 2) {
throw new UnsupportedOperationException("please use the plain `containerConfig.ExposedPorts and containerConfig.HostConfig.PortBindings` properties");
}
String hostPort = splittedPortMapping[0];
String containerPort = splittedPortMapping[1] + "/tcp";
exposedPorts.put(containerPort, new HashMap<>());
Map hostBinding = new HashMap<>();
hostBinding.put("HostIp", "0.0.0.0");
hostBinding.put("HostPort", hostPort);
portBindings.put(containerPort, Collections.singletonList(hostBinding));
});
}
getLogger().info("effective container config: " + containerConfig);
return containerConfig;
}
/**
* @see #getImageName()
* @deprecated This setter will be removed, please use the Property instead.
*/
@Deprecated
public void setImageName(String imageName) {
this.imageName.set(imageName);
}
/**
* @see #getImageTag()
* @deprecated This setter will be removed, please use the Property instead.
*/
@Deprecated
public void setTag(String tag) {
this.imageTag.set(tag);
}
/**
* @see #getContainerName()
* @deprecated This setter will be removed, please use the Property instead.
*/
@Deprecated
public void setContainerName(String containerName) {
this.containerName.set(containerName);
}
/**
* @see #getPorts()
* @deprecated This setter will be removed, please use the Property instead.
*/
@Deprecated
public void setPorts(List ports) {
this.ports.set(ports);
}
/**
* @see #getContainerConfiguration()
* @deprecated This setter will be removed, please use the Property instead.
*/
@Deprecated
public void setContainerConfiguration(Map containerConfiguration) {
this.containerConfiguration.set(containerConfiguration);
}
/**
* @see #getEnv()
* @deprecated This setter will be removed, please use the Property instead.
*/
@Deprecated
public void setEnv(List env) {
this.env.set(env);
}
/**
* @see #getEnvironmentFiles()
* @deprecated This setter will be removed, please use the Property instead.
*/
@Deprecated
public void setEnvironmentFiles(List environmentFiles) {
this.environmentFiles.set(environmentFiles);
}
}