Skip to content

Commit ab3e58a

Browse files
committed
apply docker component to handle docker related oper
1 parent 3ae07a6 commit ab3e58a

File tree

9 files changed

+266
-1
lines changed

9 files changed

+266
-1
lines changed

core/src/main/java/com/flowci/core/job/service/LocalTaskServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
public class LocalTaskServiceImpl implements LocalTaskService {
3434

3535
private static final String DefaultImage = "flowci/plugin-runtime";
36+
3637
private static final int DefaultTimeout = 60; // seconds
3738

3839
@Autowired
@@ -120,7 +121,6 @@ public ExecutedLocalTask execute(Job job, LocalTask task) {
120121
String message = event.getError().getMessage();
121122
log.warn(message);
122123
updateStatusTimeAndSave(exec, Executed.Status.EXCEPTION, message);
123-
;
124124
return exec;
125125
}
126126

docker/pom.xml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>flow-platform-x</artifactId>
7+
<groupId>com.flowci</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
<artifactId>docker</artifactId>
12+
<version>1.0-SNAPSHOT</version>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>com.flowci</groupId>
17+
<artifactId>util</artifactId>
18+
</dependency>
19+
20+
<dependency>
21+
<groupId>com.github.docker-java</groupId>
22+
<artifactId>docker-java</artifactId>
23+
</dependency>
24+
25+
<dependency>
26+
<groupId>com.jcraft</groupId>
27+
<artifactId>jsch</artifactId>
28+
</dependency>
29+
30+
<dependency>
31+
<groupId>junit</groupId>
32+
<artifactId>junit</artifactId>
33+
<scope>test</scope>
34+
</dependency>
35+
36+
<dependency>
37+
<groupId>com.github.docker-java</groupId>
38+
<artifactId>docker-java-api</artifactId>
39+
<version>3.2.1</version>
40+
<scope>compile</scope>
41+
</dependency>
42+
</dependencies>
43+
44+
</project>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.flowci.docker;
2+
3+
import com.flowci.docker.domain.DockerStartOption;
4+
import com.github.dockerjava.api.model.Container;
5+
6+
import java.util.List;
7+
8+
public interface ContainerManager {
9+
10+
List<Container> list(List<String> statusFilter, List<String> nameFilter) throws Exception;
11+
12+
String start(DockerStartOption option) throws Exception;
13+
14+
void stop(String containerId) throws Exception;
15+
16+
void resume(String containerId) throws Exception;
17+
18+
void delete(String containerId) throws Exception;
19+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.flowci.docker;
2+
3+
public interface DockerManager {
4+
5+
String DockerLocalHost = "unix:///var/run/docker.sock";
6+
7+
ContainerManager getContainerManager();
8+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package com.flowci.docker;
2+
3+
import com.flowci.docker.domain.DockerStartOption;
4+
import com.flowci.util.ObjectsHelper;
5+
import com.github.dockerjava.api.DockerClient;
6+
import com.github.dockerjava.api.command.*;
7+
import com.github.dockerjava.api.model.Container;
8+
import com.github.dockerjava.core.DefaultDockerClientConfig;
9+
import com.github.dockerjava.core.DockerClientBuilder;
10+
11+
import java.util.List;
12+
13+
public class DockerSDKManager implements DockerManager {
14+
15+
private final String dockerHost;
16+
17+
private final ContainerManager containerManager = new ContainerManagerImpl();
18+
19+
public DockerSDKManager(String dockerHost) {
20+
this.dockerHost = dockerHost;
21+
}
22+
23+
@Override
24+
public ContainerManager getContainerManager() {
25+
return containerManager;
26+
}
27+
28+
private class ContainerManagerImpl implements ContainerManager {
29+
30+
@Override
31+
public List<Container> list(List<String> statusFilter, List<String> nameFilter) throws Exception {
32+
try (DockerClient client = newClient()) {
33+
ListContainersCmd cmd = client.listContainersCmd().withShowAll(true);
34+
35+
if (ObjectsHelper.hasCollection(nameFilter)) {
36+
cmd.withNameFilter(nameFilter);
37+
}
38+
39+
if (ObjectsHelper.hasCollection(statusFilter)) {
40+
cmd.withStatusFilter(statusFilter);
41+
}
42+
43+
return cmd.exec();
44+
}
45+
}
46+
47+
@Override
48+
public String start(DockerStartOption option) throws Exception {
49+
try (DockerClient client = newClient()) {
50+
CreateContainerCmd createCmd = client.createContainerCmd(option.getImage());
51+
createCmd.withEnv(option.toEnvList());
52+
createCmd.withBinds(option.toBindList());
53+
54+
if (option.hasName()) {
55+
createCmd.withName(option.getName());
56+
}
57+
58+
CreateContainerResponse container = createCmd.exec();
59+
client.startContainerCmd(container.getId()).exec();
60+
return container.getId();
61+
}
62+
}
63+
64+
@Override
65+
public void stop(String containerId) throws Exception {
66+
try (DockerClient client = newClient()) {
67+
InspectContainerResponse exec = client.inspectContainerCmd(containerId).exec();
68+
InspectContainerResponse.ContainerState state = exec.getState();
69+
Boolean running = state.getRunning();
70+
if (running != null && running) {
71+
client.stopContainerCmd(containerId).exec();
72+
}
73+
}
74+
}
75+
76+
@Override
77+
public void resume(String containerId) throws Exception {
78+
try (DockerClient client = newClient()) {
79+
client.removeContainerCmd(containerId).exec();
80+
}
81+
}
82+
83+
@Override
84+
public void delete(String containerId) throws Exception {
85+
try (DockerClient client = newClient()) {
86+
RemoveContainerCmd removeCmd = client.removeContainerCmd(containerId).withForce(true);
87+
removeCmd.exec();
88+
}
89+
}
90+
}
91+
92+
private DockerClient newClient() {
93+
DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
94+
.withDockerHost(dockerHost).build();
95+
return DockerClientBuilder.getInstance(config).build();
96+
}
97+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.flowci.docker.domain;
2+
3+
import com.flowci.util.StringHelper;
4+
import com.github.dockerjava.api.model.Bind;
5+
import com.github.dockerjava.api.model.Volume;
6+
import lombok.Getter;
7+
import lombok.Setter;
8+
9+
import java.util.*;
10+
11+
@Getter
12+
@Setter
13+
public class DockerStartOption {
14+
15+
private String image;
16+
17+
private String name;
18+
19+
private final Map<String, String> env = new HashMap<>();
20+
21+
private final Map<String, String> bind = new HashMap<>();
22+
23+
public boolean hasName() {
24+
return StringHelper.hasValue(name);
25+
}
26+
27+
public void addEnv(String k, String v) {
28+
this.env.put(k, v);
29+
}
30+
31+
public void addBind(String src, String target) {
32+
this.bind.put(src, target);
33+
}
34+
35+
public List<Bind> toBindList() {
36+
List<Bind> list = new ArrayList<>(bind.size());
37+
bind.forEach((s, t) -> list.add(new Bind(s, new Volume(t))));
38+
return list;
39+
}
40+
41+
public List<String> toEnvList() {
42+
List<String> list = new ArrayList<>(env.size());
43+
env.forEach((k, v) -> list.add(String.format("%s=%s", k, v)));
44+
return list;
45+
}
46+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.flowci.docker.test;
2+
3+
import com.flowci.docker.ContainerManager;
4+
import com.flowci.docker.DockerManager;
5+
import com.flowci.docker.DockerSDKManager;
6+
import com.flowci.docker.domain.DockerStartOption;
7+
import com.github.dockerjava.api.model.Container;
8+
import org.junit.After;
9+
import org.junit.Assert;
10+
import org.junit.Before;
11+
import org.junit.Test;
12+
13+
import java.util.List;
14+
15+
public class DockerSDKManagerTest {
16+
17+
private DockerManager manager;
18+
19+
@Before
20+
public void init() {
21+
manager = new DockerSDKManager(DockerManager.DockerLocalHost);
22+
}
23+
24+
@After
25+
public void clean() {
26+
manager = null;
27+
}
28+
29+
@Test
30+
public void should_list_container() throws Exception {
31+
List<Container> containers = manager.getContainerManager().list(null, null);
32+
Assert.assertNotNull(containers);
33+
}
34+
35+
@Test
36+
public void should_create_and_start_container() throws Exception {
37+
DockerStartOption option = new DockerStartOption();
38+
option.setImage("ubuntu:18.04");
39+
option.addEnv("FLOW_TEST", "hello.world");
40+
41+
ContainerManager cm = manager.getContainerManager();
42+
String cid = cm.start(option);
43+
Assert.assertNotNull(cid);
44+
45+
cm.stop(cid);
46+
cm.delete(cid);
47+
}
48+
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<module>pool</module>
2020
<module>store</module>
2121
<module>sm</module>
22+
<module>docker</module>
2223
</modules>
2324

2425
<properties>

pool/src/test/java/com/flowci/pool/test/SshPoolManagerTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public void cleanup() throws DockerPoolException {
3131
}
3232
}
3333

34+
@Ignore
3435
@Test(expected = DockerPoolException.class)
3536
public void should_throw_exception_while_duplicate_container() throws DockerPoolException {
3637
String name = StringHelper.randomString(5);
@@ -44,6 +45,7 @@ public void should_throw_exception_while_duplicate_container() throws DockerPool
4445
startAgent(name);
4546
}
4647

48+
@Ignore
4749
@Test
4850
public void should_start_agent_and_stop() throws Exception {
4951
// when: start two agent

0 commit comments

Comments
 (0)