|
@@ -1,219 +1,25 @@
|
|
|
package cn.reghao.autodop.common.docker;
|
|
package cn.reghao.autodop.common.docker;
|
|
|
|
|
|
|
|
-import cn.reghao.autodop.common.docker.api.DockerApi;
|
|
|
|
|
-import cn.reghao.autodop.common.docker.po.*;
|
|
|
|
|
|
|
+import cn.reghao.autodop.common.docker.DockerException;
|
|
|
|
|
+import cn.reghao.autodop.common.docker.po.Config;
|
|
|
import cn.reghao.autodop.common.docker.po.result.ContainerInfo;
|
|
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.JsonConverter;
|
|
|
|
|
-import cn.reghao.jdkutil.security.Base64Util;
|
|
|
|
|
-import cn.reghao.autodop.common.util.compression.TarFiles;
|
|
|
|
|
-import cn.reghao.jdkutil.security.Md5Util;
|
|
|
|
|
-import cn.reghao.jdkutil.text.TextFile;
|
|
|
|
|
-import com.google.gson.JsonObject;
|
|
|
|
|
-import com.google.gson.JsonParser;
|
|
|
|
|
-import io.netty.handler.codec.http.FullHttpResponse;
|
|
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
-
|
|
|
|
|
-import java.io.*;
|
|
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
|
|
-import java.util.*;
|
|
|
|
|
|
|
+import com.github.dockerjava.api.command.InspectContainerResponse;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Docker 客户端
|
|
* Docker 客户端
|
|
|
*
|
|
*
|
|
|
* @author reghao
|
|
* @author reghao
|
|
|
- * @date 2020-01-13 14:16:38
|
|
|
|
|
|
|
+ * @date 2021-10-27 04:17:38
|
|
|
*/
|
|
*/
|
|
|
-@Slf4j
|
|
|
|
|
-public class Docker implements AutoCloseable {
|
|
|
|
|
- private HttpClient client = new HttpClient(new UnixSocketClient());
|
|
|
|
|
- private TextFile textFile = new TextFile();
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public void close() {
|
|
|
|
|
- client.close();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private String checkResponse(FullHttpResponse response) throws DockerException {
|
|
|
|
|
- if (response != null) {
|
|
|
|
|
- int statusCode = response.status().code();
|
|
|
|
|
- String result = response.content().toString(StandardCharsets.UTF_8);
|
|
|
|
|
- if (statusCode >= 400) {
|
|
|
|
|
- throw new DockerException(result);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- String[] lines = result.split(System.lineSeparator());
|
|
|
|
|
- for (String line : lines) {
|
|
|
|
|
- if (line.contains("error") || line.contains("message")) {
|
|
|
|
|
- throw new DockerException("Docker 请求错误 -> " + line);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return result;
|
|
|
|
|
- } else {
|
|
|
|
|
- throw new DockerException("Docker 响应是 NULL");
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public String getIdByName(String name) throws DockerException {
|
|
|
|
|
- /*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;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void build(String repoTag, String compileHome, String dockerfile) throws Exception {
|
|
|
|
|
- String uri = DockerApi.buildPost + "?t=" + repoTag;
|
|
|
|
|
- if (dockerfile != null) {
|
|
|
|
|
- String dockerfilePath = compileHome + "/Dockerfile1";
|
|
|
|
|
- textFile.write(new File(dockerfilePath), dockerfile);
|
|
|
|
|
- // dockerfile 参数指定的是 Dockerfile 文件在 tar 文件内的相对路径和名字
|
|
|
|
|
- uri += "&dockerfile=Dockerfile1";
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Dockerfile 要包含在 tar 文件中
|
|
|
|
|
- // TODO /tmp 目录内文件的删除策略
|
|
|
|
|
- String dstPath = "/tmp/" + Md5Util.md5(compileHome) + ".tar";
|
|
|
|
|
- TarFiles.tar(compileHome, dstPath);
|
|
|
|
|
- File tarFile = new File(dstPath);
|
|
|
|
|
-
|
|
|
|
|
- List<DockerHeader> headers = new ArrayList<>();
|
|
|
|
|
- headers.add(new DockerHeader("Content-Type", "application/tar"));
|
|
|
|
|
- headers.add(new DockerHeader("Expect", "100-continue"));
|
|
|
|
|
-
|
|
|
|
|
- FullHttpResponse response = client.postFile(uri, headers, tarFile);
|
|
|
|
|
- tarFile.delete();
|
|
|
|
|
- checkResponse(response);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void push(String image) throws DockerException {
|
|
|
|
|
- String uri = DockerApi.pushPost.replace("{}", image);
|
|
|
|
|
-
|
|
|
|
|
- DockerAuth auth = new DockerAuth();
|
|
|
|
|
- auth.setUsername("reghao");
|
|
|
|
|
- auth.setPassword("12345678");
|
|
|
|
|
- auth.setEmail("reghaodev@gmail.com");
|
|
|
|
|
- auth.setServeraddress("localhost");
|
|
|
|
|
- String encodeAuth = Base64Util.encode(JsonConverter.objectToJson(auth));
|
|
|
|
|
- List<DockerHeader> headers = new ArrayList<>();
|
|
|
|
|
- headers.add(new DockerHeader("X-Registry-Auth", encodeAuth));
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- FullHttpResponse response = client.post(uri, headers);
|
|
|
|
|
- checkResponse(response);
|
|
|
|
|
- String result = response.content().toString(StandardCharsets.UTF_8);
|
|
|
|
|
- log.info("docker push 结果: {}", result);
|
|
|
|
|
- // TODO push 完成后查找镜像是否存在
|
|
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void pull(String repoTag) throws DockerException, InterruptedException {
|
|
|
|
|
- String params = "?fromImage=" + repoTag;
|
|
|
|
|
- String uri = DockerApi.pullPost + params;
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- FullHttpResponse response = client.post(uri, null);
|
|
|
|
|
- checkResponse(response);
|
|
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public String run(String containerName, Config config) throws DockerException {
|
|
|
|
|
- stopAndDelete(containerName);
|
|
|
|
|
- //config.setImage(repoTag);
|
|
|
|
|
- String containerId = create(containerName, config);
|
|
|
|
|
- start(containerId);
|
|
|
|
|
- return containerId;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private void stopAndDelete(String containerName) throws DockerException {
|
|
|
|
|
- /*List<Container> containers = ps(true);
|
|
|
|
|
- String name = "/" + containerName;
|
|
|
|
|
- for (Container container : containers) {
|
|
|
|
|
- Set<String> names = new HashSet<>(container.getNames());
|
|
|
|
|
- if (names.contains(name)) {
|
|
|
|
|
- String id = container.getId();
|
|
|
|
|
- // 匹配任意状态与名字相同的容器
|
|
|
|
|
- if ("running".equals(container.getState())) {
|
|
|
|
|
- stop(id);
|
|
|
|
|
- }
|
|
|
|
|
- rmContainer(id);
|
|
|
|
|
- }
|
|
|
|
|
- }*/
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private String create(String containerName, Config config) throws DockerException {
|
|
|
|
|
- String uri = DockerApi.createPost + "?name=" + containerName;
|
|
|
|
|
- String json = JsonConverter.objectToJson(config);
|
|
|
|
|
- try {
|
|
|
|
|
- FullHttpResponse response = client.postJson(uri, null, json);
|
|
|
|
|
- if (response != null) {
|
|
|
|
|
- int statusCode = response.status().code();
|
|
|
|
|
- String result = response.content().toString(StandardCharsets.UTF_8);
|
|
|
|
|
- if (statusCode == 201) {
|
|
|
|
|
- JsonObject jsonObject = new JsonParser().parse(result).getAsJsonObject();
|
|
|
|
|
- return jsonObject.get("Id").getAsString();
|
|
|
|
|
- } else {
|
|
|
|
|
- throw new DockerException(result);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
|
|
- }
|
|
|
|
|
- throw new DockerException("请求 " + uri + " 创建容器失败");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void start(String containerId) throws DockerException {
|
|
|
|
|
- String uri = DockerApi.startPost.replace("{}", containerId);
|
|
|
|
|
- try {
|
|
|
|
|
- FullHttpResponse response = client.post(uri, null);
|
|
|
|
|
- checkResponse(response);
|
|
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void restart(String containerId) throws DockerException {
|
|
|
|
|
- String uri = DockerApi.restartPost.replace("{}", containerId);
|
|
|
|
|
- try {
|
|
|
|
|
- FullHttpResponse response = client.post(uri, null);
|
|
|
|
|
- checkResponse(response);
|
|
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void stop(String containerId) throws DockerException {
|
|
|
|
|
- String uri = DockerApi.stopPost.replace("{}", containerId);
|
|
|
|
|
- try {
|
|
|
|
|
- FullHttpResponse response = client.post(uri, null);
|
|
|
|
|
- checkResponse(response);
|
|
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public ContainerInfo inspectContainer(String contianerId) throws DockerException {
|
|
|
|
|
- String uri = DockerApi.inspectContainerGet.replace("{}", contianerId);
|
|
|
|
|
- try {
|
|
|
|
|
- FullHttpResponse response = client.get(uri, null);
|
|
|
|
|
- if (response != null) {
|
|
|
|
|
- String result = response.content().toString(StandardCharsets.UTF_8);
|
|
|
|
|
- return JsonConverter.jsonToObject(result, ContainerInfo.class);
|
|
|
|
|
- } else {
|
|
|
|
|
- throw new DockerException("请求 " + uri + " 的响应是 NULL");
|
|
|
|
|
- }
|
|
|
|
|
- } catch (IOException | InterruptedException e) {
|
|
|
|
|
- throw new DockerException(ExceptionUtil.errorMsg(e));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+public interface Docker {
|
|
|
|
|
+ void build(String repoTag, String compileHome, String dockerfileContent) throws DockerException;
|
|
|
|
|
+ void push(String image) throws DockerException;
|
|
|
|
|
+ void pull(String repoTag) throws DockerException;
|
|
|
|
|
+ String getContainerIdByName(String containerName) throws DockerException;
|
|
|
|
|
+ void stopAndDelete(String containerName) throws DockerException;
|
|
|
|
|
+ String createAndRun(String containerName, Config config) throws DockerException;
|
|
|
|
|
+ void start(String containerId);
|
|
|
|
|
+ void restart(String containerId);
|
|
|
|
|
+ void stop(String containerId);
|
|
|
|
|
+ InspectContainerResponse inspectContainer(String containerId);
|
|
|
}
|
|
}
|