|
|
@@ -1,15 +1,11 @@
|
|
|
package cn.reghao.autodop.common.docker;
|
|
|
|
|
|
-import cn.reghao.autodop.common.docker.api.ContainerOps;
|
|
|
import cn.reghao.autodop.common.docker.api.DockerApi;
|
|
|
-import cn.reghao.autodop.common.docker.api.ImageOps;
|
|
|
import cn.reghao.autodop.common.docker.po.*;
|
|
|
-import cn.reghao.autodop.common.docker.po.result.Container;
|
|
|
import cn.reghao.autodop.common.docker.po.result.ContainerInfo;
|
|
|
import cn.reghao.autodop.common.docker.unixdomain.UnixSocketClient;
|
|
|
import cn.reghao.autodop.common.docker.unixdomain.HttpClient;
|
|
|
import cn.reghao.autodop.common.util.ExceptionUtil;
|
|
|
-import cn.reghao.jdkutil.serializer.JsonArrayDeserializer;
|
|
|
import cn.reghao.jdkutil.serializer.JsonConverter;
|
|
|
import cn.reghao.jdkutil.security.Base64Util;
|
|
|
import cn.reghao.autodop.common.util.compression.TarFiles;
|
|
|
@@ -23,7 +19,6 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import java.io.*;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.util.*;
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* Docker 客户端
|
|
|
@@ -32,7 +27,7 @@ import java.util.stream.Collectors;
|
|
|
* @date 2020-01-13 14:16:38
|
|
|
*/
|
|
|
@Slf4j
|
|
|
-public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
+public class Docker implements AutoCloseable {
|
|
|
private HttpClient client = new HttpClient(new UnixSocketClient());
|
|
|
private TextFile textFile = new TextFile();
|
|
|
|
|
|
@@ -41,13 +36,6 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
client.close();
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 检测 Docker 的响应
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2021-02-08 下午2:08
|
|
|
- */
|
|
|
private String checkResponse(FullHttpResponse response) throws DockerException {
|
|
|
if (response != null) {
|
|
|
int statusCode = response.status().code();
|
|
|
@@ -68,27 +56,18 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 根据容器名字找出容器 ID
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2021-02-25 上午10:31
|
|
|
- */
|
|
|
public String getIdByName(String name) throws DockerException {
|
|
|
- String wrappedName = "/" + name;
|
|
|
+ /*String wrappedName = "/" + name;
|
|
|
List<Container> containers = ps(true);
|
|
|
for (Container container : containers) {
|
|
|
Set<String> names = new HashSet<>(container.getNames());
|
|
|
if (names.contains(wrappedName)) {
|
|
|
return container.getId();
|
|
|
}
|
|
|
- }
|
|
|
+ }*/
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- /* image 操作 */
|
|
|
- @Override
|
|
|
public void build(String repoTag, String compileHome, String dockerfile) throws Exception {
|
|
|
String uri = DockerApi.buildPost + "?t=" + repoTag;
|
|
|
if (dockerfile != null) {
|
|
|
@@ -113,7 +92,6 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
checkResponse(response);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
public void push(String image) throws DockerException {
|
|
|
String uri = DockerApi.pushPost.replace("{}", image);
|
|
|
|
|
|
@@ -137,8 +115,7 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public void pull(String repoTag) throws DockerException {
|
|
|
+ public void pull(String repoTag) throws DockerException, InterruptedException {
|
|
|
String params = "?fromImage=" + repoTag;
|
|
|
String uri = DockerApi.pullPost + params;
|
|
|
|
|
|
@@ -150,34 +127,6 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public void rmImage(String repoTag) throws DockerException {
|
|
|
- String uri = DockerApi.rmImageDelete.replace("{}", repoTag);
|
|
|
- try {
|
|
|
- FullHttpResponse response = client.post(uri, null);
|
|
|
- checkResponse(response);
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String inspectImage(String image) throws DockerException {
|
|
|
- String uri = DockerApi.inspectImageGet.replace("{}", image);
|
|
|
- try {
|
|
|
- FullHttpResponse response = client.get(uri, null);
|
|
|
- if (response != null) {
|
|
|
- return response.content().toString(StandardCharsets.UTF_8);
|
|
|
- } else {
|
|
|
- throw new DockerException("请求 " + uri + " 的响应是 NULL");
|
|
|
- }
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* container 操作 */
|
|
|
- @Override
|
|
|
public String run(String containerName, Config config) throws DockerException {
|
|
|
stopAndDelete(containerName);
|
|
|
//config.setImage(repoTag);
|
|
|
@@ -186,15 +135,8 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
return containerId;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 停止并删除容器
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2020-03-13 下午10:16
|
|
|
- */
|
|
|
private void stopAndDelete(String containerName) throws DockerException {
|
|
|
- List<Container> containers = ps(true);
|
|
|
+ /*List<Container> containers = ps(true);
|
|
|
String name = "/" + containerName;
|
|
|
for (Container container : containers) {
|
|
|
Set<String> names = new HashSet<>(container.getNames());
|
|
|
@@ -206,7 +148,7 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
}
|
|
|
rmContainer(id);
|
|
|
}
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
private String create(String containerName, Config config) throws DockerException {
|
|
|
@@ -230,7 +172,6 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
throw new DockerException("请求 " + uri + " 创建容器失败");
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
public void start(String containerId) throws DockerException {
|
|
|
String uri = DockerApi.startPost.replace("{}", containerId);
|
|
|
try {
|
|
|
@@ -241,7 +182,6 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
public void restart(String containerId) throws DockerException {
|
|
|
String uri = DockerApi.restartPost.replace("{}", containerId);
|
|
|
try {
|
|
|
@@ -252,7 +192,6 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
public void stop(String containerId) throws DockerException {
|
|
|
String uri = DockerApi.stopPost.replace("{}", containerId);
|
|
|
try {
|
|
|
@@ -263,121 +202,6 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public void rmContainer(String containerId) throws DockerException {
|
|
|
- String uri = DockerApi.rmContainerDelete.replace("{}", containerId);
|
|
|
- try {
|
|
|
- FullHttpResponse response = client.delete(uri, null);
|
|
|
- checkResponse(response);
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 控制台日志
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2020-05-19 上午10:26
|
|
|
- */
|
|
|
- @Override
|
|
|
- public List<String> consoleLog(String containerId, String logLevel) throws DockerException {
|
|
|
- String uri = DockerApi.logsGet.replace("{}", containerId);
|
|
|
- FullHttpResponse response;
|
|
|
- // TODO 处理乱码
|
|
|
- /*switch (LogLevel.valueOf(logLevel)) {
|
|
|
- case info:
|
|
|
- // 标准输出
|
|
|
- String params = "?stdout=true&tail=1000";
|
|
|
- response = client.get(uri + params, null);
|
|
|
- if (response != null) {
|
|
|
- String stdout = response.content().toString(StandardCharsets.UTF_8);
|
|
|
- return Arrays.asList(stdout.split(System.lineSeparator()));
|
|
|
- } else {
|
|
|
- throw new DockerException("请求 " + uri + " 的响应是 NULL");
|
|
|
- }
|
|
|
- case error:
|
|
|
- // 标准错误
|
|
|
- params = "?stderr=true&tail=1000";
|
|
|
- response = client.get(uri + params, null);
|
|
|
- if (response != null) {
|
|
|
- String stderr = response.content().toString(StandardCharsets.UTF_8);
|
|
|
- return Arrays.asList(stderr.split(System.lineSeparator()));
|
|
|
- } else {
|
|
|
- throw new DockerException("请求 " + uri + " 的响应是 NULL");
|
|
|
- }
|
|
|
- default:
|
|
|
- throw new DockerException("日志级别 " + logLevel + " 不存在");
|
|
|
- }*/
|
|
|
- return Collections.emptyList();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 目录中的文件列表,只返回最近 10 天的日志文件
|
|
|
- * 需要保证日志文件名的格式类似于 2020-01-01.log
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2020-05-19 上午10:26
|
|
|
- */
|
|
|
- public List<String> fileList(String containerId, String dirPath) throws DockerException {
|
|
|
- String logDirPath = rootfs(containerId) + dirPath;
|
|
|
- File logDir = new File(logDirPath);
|
|
|
- if (logDir.exists()) {
|
|
|
- List<String> list = Arrays.stream(Objects.requireNonNull(logDir.listFiles()))
|
|
|
- .map(File::getName)
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- // 只返回最近 10 天的日志文件
|
|
|
- if (list.size() > 10) {
|
|
|
- list.sort(Comparator.reverseOrder());
|
|
|
- return list.subList(0, 10);
|
|
|
- }
|
|
|
- return list;
|
|
|
- } else {
|
|
|
- return new ArrayList<>();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 文件日志
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2020-05-19 上午10:26
|
|
|
- */
|
|
|
- @Override
|
|
|
- public List<String> fileLog(String containerId, String logPath) throws DockerException {
|
|
|
- String logFilePath = rootfs(containerId) + logPath;
|
|
|
- File logFile = new File(logFilePath);
|
|
|
- if (!logFile.exists()) {
|
|
|
- throw new DockerException(logFilePath + " 文件不存在");
|
|
|
- } else if (logFile.isDirectory()) {
|
|
|
- throw new DockerException(logFilePath + " 是一个文件");
|
|
|
- } else {
|
|
|
- try {
|
|
|
- return textFile.tailRead(logFilePath, 1000);
|
|
|
- } catch (IOException e) {
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<Container> ps(boolean isAll) throws DockerException {
|
|
|
- String uri = DockerApi.psGet + "?all=" + isAll;
|
|
|
- try {
|
|
|
- FullHttpResponse response = client.get(uri, null);
|
|
|
- String result = checkResponse(response);
|
|
|
- JsonArrayDeserializer<Container> jsonArrayDeserializer = new JsonArrayDeserializer<>();
|
|
|
- return jsonArrayDeserializer.fromJsonArray(result, Container.class);
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
public ContainerInfo inspectContainer(String contianerId) throws DockerException {
|
|
|
String uri = DockerApi.inspectContainerGet.replace("{}", contianerId);
|
|
|
try {
|
|
|
@@ -392,24 +216,4 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
|
|
|
throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- @Override
|
|
|
- public String rootfs(String containerId) throws DockerException {
|
|
|
- ContainerInfo containerInfo = inspectContainer(containerId);
|
|
|
- // 容器停止后 mergedDir 不再存在
|
|
|
- return containerInfo.getGraphDriver().getData().getMergedDir();
|
|
|
- }
|
|
|
-
|
|
|
- // TODO 待实现 docker cp
|
|
|
- public void archive(String containerId) {
|
|
|
- String uri = "http://v1.4.0/containers/32487cddf5d5/archive?path=/";
|
|
|
- try {
|
|
|
- FullHttpResponse response = client.get(uri, null);
|
|
|
- if (response != null) {
|
|
|
- String result = response.content().toString(StandardCharsets.UTF_8);
|
|
|
- }
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
}
|