/
StartCommand.java
100 lines (84 loc) · 3.57 KB
/
StartCommand.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package org.jenkinsci.plugins.dockerbuildstep.cmd;
import hudson.Extension;
import hudson.model.AbstractBuild;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.jenkinsci.plugins.dockerbuildstep.action.EnvInvisibleAction;
import org.jenkinsci.plugins.dockerbuildstep.log.ConsoleLogger;
import org.jenkinsci.plugins.dockerbuildstep.util.PortUtils;
import org.jenkinsci.plugins.dockerbuildstep.util.Resolver;
import org.kohsuke.stapler.DataBoundConstructor;
import com.kpelykh.docker.client.DockerClient;
import com.kpelykh.docker.client.DockerException;
import com.kpelykh.docker.client.model.ContainerInspectResponse;
/**
* This command starts one or more Docker containers. It also exports some build environment variable like IP or started
* containers.
*
* @see http://docs.docker.io/en/master/api/docker_remote_api_v1.8/#start-a-container
*
* @author vjuranek
*
*/
public class StartCommand extends DockerCommand {
private final String containerIds;
private final String waitPorts;
@DataBoundConstructor
public StartCommand(String containerIds, String waitPorts) {
this.containerIds = containerIds;
this.waitPorts = waitPorts;
}
public String getContainerIds() {
return containerIds;
}
public String getWaitPorts() {
return waitPorts;
}
@Override
public void execute(@SuppressWarnings("rawtypes") AbstractBuild build, ConsoleLogger console)
throws DockerException {
if (containerIds == null || containerIds.isEmpty()) {
throw new IllegalArgumentException("At least one parameter is required");
}
String containerIdsRes = Resolver.buildVar(build, containerIds);
List<String> ids = Arrays.asList(containerIdsRes.split(","));
DockerClient client = getClient();
//TODO check, if container exists and is stopped (probably catch exception)
for (String id : ids) {
id = id.trim();
client.startContainer(id);
console.logInfo("started container id " + id);
ContainerInspectResponse inspectResp = client.inspectContainer(id);
EnvInvisibleAction envAction = new EnvInvisibleAction(inspectResp);
build.addAction(envAction);
}
//wait for ports
if(waitPorts != null && !waitPorts.isEmpty()) {
Map<String, List<Integer>> containers = PortUtils.parsePorts(waitPorts);
for(String cId : containers.keySet()) {
ContainerInspectResponse inspectResp = client.inspectContainer(cId);
String ip = inspectResp.getNetworkSettings().ipAddress;
List<Integer> ports = containers.get(cId);
for(Integer port : ports) {
console.logInfo("Waiting for port " + port + " on " + ip + " (conatiner ID " + cId + ")");
boolean portReady = PortUtils.waitForPort(ip, port);
if(portReady) {
console.logInfo(ip + ":" + port + " ready");
}
else {
//TODO fail the build, but make timeout configurable first
console.logWarn(ip + ":" + port + " still not available (conatiner ID " + cId + "), but build continues ...");
}
}
}
}
}
@Extension
public static class StartCommandDescriptor extends DockerCommandDescriptor {
@Override
public String getDisplayName() {
return "Start container(s)";
}
}
}