blob: 6030a9c3d966ffa1b385368ba918c64113c154c7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2018 Red Hat.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat - Initial Contribution
*******************************************************************************/
package org.eclipse.linuxtools.internal.docker.core;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.linuxtools.docker.core.IDockerContainerConfig;
import com.spotify.docker.client.messages.ContainerConfig;
import com.spotify.docker.client.messages.HostConfig;
public class DockerContainerConfig implements IDockerContainerConfig {
private final String hostname;
private final String domainname;
private final String user;
private final Long memory;
private final Long memorySwap;
private final Long cpuShares;
private final String cpuset;
private final boolean attachStdin;
private final boolean attachStdout;
private final boolean attachStderr;
private final List<String> portSpecs;
private final Set<String> exposedPorts;
private final boolean tty;
private final boolean openStdin;
private final boolean stdinOnce;
private final List<String> env;
private String rawcmd;
private final List<String> cmd;
private final String image;
@SuppressWarnings("rawtypes")
private final Map<String, Map> volumes;
private final String workingDir;
private final List<String> entrypoint;
private final boolean networkDisabled;
private final List<String> onBuild;
private final Map<String, String> labels;
public DockerContainerConfig(final ContainerConfig containerConfig) {
this.hostname = containerConfig != null ? containerConfig.hostname()
: null;
this.domainname = containerConfig != null ? containerConfig.domainname()
: null;
this.user = containerConfig != null ? containerConfig.user() : null;
final HostConfig hc = containerConfig != null
? containerConfig.hostConfig() : null;
this.memory = hc != null ? hc.memory() : null;
this.memorySwap = hc != null ? hc.memorySwap() : null;
this.cpuShares = hc != null ? hc.cpuShares() : null;
this.cpuset = hc != null ? hc.cpusetCpus() : null;
this.attachStdin = containerConfig != null
&& containerConfig.attachStdin() != null
? containerConfig.attachStdin() : false;
this.attachStdout = containerConfig != null
&& containerConfig.attachStdout() != null
? containerConfig.attachStdout() : false;
this.attachStderr = containerConfig != null
&& containerConfig.attachStderr() != null
? containerConfig.attachStderr() : false;
this.portSpecs = containerConfig != null ? containerConfig.portSpecs()
: null;
this.exposedPorts = containerConfig != null
? containerConfig.exposedPorts() : null;
this.tty = containerConfig != null && containerConfig.tty() != null
? containerConfig.tty()
: false;
this.openStdin = containerConfig != null
&& containerConfig.openStdin() != null
? containerConfig.openStdin() : false;
this.stdinOnce = containerConfig != null
&& containerConfig.stdinOnce() != null
? containerConfig.stdinOnce() : false;
this.env = containerConfig != null ? containerConfig.env() : null;
this.cmd = containerConfig != null ? containerConfig.cmd() : null;
this.image = containerConfig != null ? containerConfig.image() : null;
@SuppressWarnings("rawtypes")
Map<String, Map> res = new HashMap<>();
try {
if (containerConfig != null && containerConfig.volumes() != null) {
containerConfig.volumes().forEach(v -> res.put(v, Collections.emptyMap()));
}
} catch (NullPointerException e) {
}
this.volumes = res;
this.workingDir = containerConfig != null ? containerConfig.workingDir()
: null;
this.entrypoint = containerConfig != null ? containerConfig.entrypoint()
: null;
this.networkDisabled = containerConfig != null
&& containerConfig.networkDisabled() != null
? containerConfig.networkDisabled() : false;
this.onBuild = containerConfig != null ? containerConfig.onBuild()
: null;
this.labels = containerConfig != null ? containerConfig.labels() : null;
}
private DockerContainerConfig(final Builder builder) {
this.hostname = builder.hostname;
this.domainname = builder.domainname;
this.user = builder.user;
this.memory = builder.memory;
this.memorySwap = builder.memorySwap;
this.cpuShares = builder.cpuShares;
this.cpuset = builder.cpuset;
this.attachStdin = builder.attachStdin != null ? builder.attachStdin
: false;
this.attachStdout = builder.attachStdout != null ? builder.attachStdout
: false;
this.attachStderr = builder.attachStderr != null ? builder.attachStderr
: false;
this.portSpecs = builder.portSpecs;
this.exposedPorts = builder.exposedPorts;
this.tty = builder.tty != null ? builder.tty : false;
this.openStdin = builder.openStdin != null ? builder.openStdin : false;
this.stdinOnce = builder.stdinOnce != null ? builder.stdinOnce : false;
this.env = builder.env;
this.rawcmd = builder.rawcmd;
this.cmd = builder.cmd;
this.image = builder.image;
this.volumes = builder.volumes;
this.workingDir = builder.workingDir;
this.entrypoint = builder.entrypoint;
this.networkDisabled = builder.networkDisabled != null
? builder.networkDisabled : false;
this.onBuild = builder.onBuild;
this.labels = builder.labels;
}
@Override
public String hostname() {
return hostname;
}
@Override
public String domainname() {
return domainname;
}
@Override
public String user() {
return user;
}
/**
* @see DockerHostConfig#memory()
*/
@Deprecated
@Override
public Long memory() {
return memory;
}
@Deprecated
@Override
public Long memorySwap() {
return memorySwap;
}
/**
* @see DockerHostConfig#cpuShares()
*/
@Deprecated
@Override
public Long cpuShares() {
return cpuShares;
}
@Deprecated
@Override
public String cpuset() {
return cpuset;
}
@Override
public boolean attachStdin() {
return attachStdin;
}
@Override
public boolean attachStdout() {
return attachStdout;
}
@Override
public boolean attachStderr() {
return attachStderr;
}
@Override
public List<String> portSpecs() {
if (portSpecs == null) {
return Collections.emptyList();
}
return portSpecs;
}
@Override
public Set<String> exposedPorts() {
if (exposedPorts == null) {
return Collections.emptySet();
}
return exposedPorts;
}
@Override
public boolean tty() {
return tty;
}
@Override
public boolean openStdin() {
return openStdin;
}
@Override
public boolean stdinOnce() {
return stdinOnce;
}
@Override
public List<String> env() {
if (env == null) {
return Collections.emptyList();
}
return env;
}
@Override
public List<String> cmd() {
if (cmd == null) {
return Collections.emptyList();
}
return cmd;
}
public String rawcmd() {
return rawcmd;
}
@Override
public String image() {
return image;
}
@SuppressWarnings("rawtypes")
@Override
public Map<String, Map> volumes() {
if (volumes == null) {
return Collections.emptyMap();
}
return volumes;
}
@Override
public String workingDir() {
return workingDir;
}
@Override
public List<String> entrypoint() {
if (entrypoint == null) {
return Collections.emptyList();
}
return entrypoint;
}
@Override
public boolean networkDisabled() {
return networkDisabled;
}
@Override
public List<String> onBuild() {
if (onBuild == null) {
return Collections.emptyList();
}
return onBuild;
}
// @Override
@Override
public Map<String, String> labels() {
if (this.labels == null) {
return Collections.emptyMap();
}
return this.labels;
}
public static class Builder {
private String hostname;
private String domainname;
private String user;
private Long memory;
private Long memorySwap;
private Long cpuShares;
private String cpuset;
private Boolean attachStdin;
private Boolean attachStdout;
private Boolean attachStderr;
private List<String> portSpecs;
private Set<String> exposedPorts;
private Boolean tty;
private Boolean openStdin;
private Boolean stdinOnce;
private List<String> env;
private String rawcmd;
private List<String> cmd;
private String image;
@SuppressWarnings("rawtypes")
private Map<String, Map> volumes;
private String workingDir;
private List<String> entrypoint;
private Boolean networkDisabled;
private List<String> onBuild;
private Map<String, String> labels;
public Builder hostname(final String hostname) {
this.hostname = hostname;
return this;
}
public String hostname() {
return hostname;
}
public Builder domainname(final String domainname) {
this.domainname = domainname;
return this;
}
public String domainname() {
return domainname;
}
public Builder user(final String user) {
this.user = user;
return this;
}
public String user() {
return user;
}
public Builder memory(final Long memory) {
this.memory = memory;
return this;
}
public Long memory() {
return memory;
}
public Builder memorySwap(final Long memorySwap) {
this.memorySwap = memorySwap;
return this;
}
public Long memorySwap() {
return memorySwap;
}
public Builder cpuShares(final Long cpuShares) {
this.cpuShares = cpuShares;
return this;
}
public Long cpuShares() {
return cpuShares;
}
public Builder cpuset(final String cpuset) {
this.cpuset = cpuset;
return this;
}
public String cpuset() {
return cpuset;
}
public Builder attachStdin(final Boolean attachStdin) {
this.attachStdin = attachStdin;
return this;
}
public Boolean attachStdin() {
return attachStdin;
}
public Builder attachStdout(final Boolean attachStdout) {
this.attachStdout = attachStdout;
return this;
}
public Boolean attachStdout() {
return attachStdout;
}
public Builder attachStderr(final Boolean attachStderr) {
this.attachStderr = attachStderr;
return this;
}
public Boolean attachStderr() {
return attachStderr;
}
public Builder portSpecs(final List<String> portSpecs) {
this.portSpecs = new ArrayList<>(portSpecs);
return this;
}
public Builder portSpecs(final String... portSpecs) {
this.portSpecs = Arrays.asList(portSpecs);
return this;
}
public List<String> portSpecs() {
return portSpecs;
}
public Builder exposedPorts(final Set<String> exposedPorts) {
this.exposedPorts = new TreeSet<>(exposedPorts);
return this;
}
public Builder exposedPorts(final String... exposedPorts) {
this.exposedPorts = new TreeSet<>(Arrays.asList(exposedPorts));
return this;
}
public Set<String> exposedPorts() {
return exposedPorts;
}
public Builder tty(final Boolean tty) {
this.tty = tty;
return this;
}
public Boolean tty() {
return tty;
}
public Builder openStdin(final Boolean openStdin) {
this.openStdin = openStdin;
return this;
}
public Boolean openStdin() {
return openStdin;
}
public Builder stdinOnce(final Boolean stdinOnce) {
this.stdinOnce = stdinOnce;
return this;
}
public Boolean stdinOnce() {
return stdinOnce;
}
public Builder env(final List<String> env) {
this.env = new ArrayList<>(env);
return this;
}
public Builder env(final String... env) {
this.env = Arrays.asList(env);
return this;
}
public List<String> env() {
return env;
}
public Builder cmd(final List<String> cmd) {
this.cmd = cmd;
return this;
}
public Builder cmd(final String... cmd) {
return cmd(Arrays.asList(cmd));
}
public Builder cmd(final String cmd) {
this.rawcmd = cmd;
this.cmd = getCmdList(cmd);
return this;
}
public List<String> cmd() {
return cmd;
}
public Builder image(final String image) {
this.image = image;
return this;
}
public String image() {
return image;
}
public Builder volumes(
@SuppressWarnings("rawtypes") final Map<String, Map> volumes) {
this.volumes = volumes;
return this;
}
@SuppressWarnings("rawtypes")
public Map<String, Map> volumes() {
return volumes;
}
public Builder workingDir(final String workingDir) {
this.workingDir = workingDir;
return this;
}
public String workingDir() {
return workingDir;
}
public Builder entryPoint(final List<String> entrypoint) {
if (entrypoint != null && !entrypoint.isEmpty()) {
this.entrypoint = new ArrayList<>(entrypoint);
}
return this;
}
public Builder entryPoint(final String... entrypoint) {
return entryPoint(Arrays.asList(entrypoint));
}
public Builder entryPoint(final String entrypoint) {
if (entrypoint != null && !entrypoint.isEmpty()) {
return entryPoint(entrypoint.split(" "));
} else {
this.entrypoint = null;
}
return this;
}
public List<String> entryPoint() {
return entrypoint;
}
public Builder networkDisabled(final Boolean networkDisabled) {
this.networkDisabled = networkDisabled;
return this;
}
public Boolean networkDisabled() {
return networkDisabled;
}
public Builder onBuild(final List<String> onBuild) {
this.onBuild = new ArrayList<>(onBuild);
return this;
}
public Builder onBuild(final String... onBuild) {
this.onBuild = Arrays.asList(onBuild);
return this;
}
public List<String> onBuild() {
return onBuild;
}
public Builder labels(final Map<String, String> labels) {
this.labels = labels;
return this;
}
public DockerContainerConfig build() {
return new DockerContainerConfig(this);
}
/**
* Create a proper command list after handling quotation.
*
* @param command
* the command as a single {@link String}
* @return the command splitted in a list of ars or <code>null</code> if
* the input <code>command</code> was <code>null</code>.
*/
private List<String> getCmdList(final String command) {
if (command == null) {
return null;
}
final List<String> list = new ArrayList<>();
int length = command.length();
boolean insideQuote1 = false; // single-quote
boolean insideQuote2 = false; // double-quote
boolean escaped = false;
StringBuilder buffer = new StringBuilder();
// Parse the string and break it up into chunks that are
// separated by white-space or are quoted. Ignore characters
// that have been escaped, including the escape character.
for (int i = 0; i < length; ++i) {
char c = command.charAt(i);
if (escaped) {
buffer.append(c);
escaped = false;
}
switch (c) {
case '\'':
if (!insideQuote2)
insideQuote1 = insideQuote1 ^ true;
else
buffer.append(c);
break;
case '\"':
if (!insideQuote1)
insideQuote2 = insideQuote2 ^ true;
else
buffer.append(c);
break;
case '\\':
escaped = true;
break;
case ' ':
case '\t':
case '\r':
case '\n':
if (insideQuote1 || insideQuote2)
buffer.append(c);
else {
String item = buffer.toString();
buffer.setLength(0);
if (item.length() > 0)
list.add(item);
}
break;
default:
buffer.append(c);
break;
}
}
// add last item of string that will be in the buffer
String item = buffer.toString();
if (item.length() > 0)
list.add(item);
return list;
}
}
}