|
|
@@ -1,452 +0,0 @@
|
|
|
-package cn.reghao.bnt.common.docker;
|
|
|
-
|
|
|
-import cn.reghao.bnt.common.docker.model.DockerAuth;
|
|
|
-import cn.reghao.jutil.jdk.exception.ExceptionUtil;
|
|
|
-import cn.reghao.jutil.jdk.io.TextFile;
|
|
|
-import com.github.dockerjava.api.DockerClient;
|
|
|
-import com.github.dockerjava.api.async.ResultCallback;
|
|
|
-import com.github.dockerjava.api.command.*;
|
|
|
-import com.github.dockerjava.api.model.*;
|
|
|
-import com.github.dockerjava.core.DefaultDockerClientConfig;
|
|
|
-import com.github.dockerjava.core.DockerClientConfig;
|
|
|
-import com.github.dockerjava.core.DockerClientImpl;
|
|
|
-import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
|
|
|
-import com.github.dockerjava.transport.DockerHttpClient;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-
|
|
|
-import java.io.Closeable;
|
|
|
-import java.io.File;
|
|
|
-import java.io.IOException;
|
|
|
-import java.time.Duration;
|
|
|
-import java.util.*;
|
|
|
-import java.util.concurrent.TimeUnit;
|
|
|
-import java.util.stream.Collectors;
|
|
|
-
|
|
|
-/**
|
|
|
- * Docker 客户端
|
|
|
- *
|
|
|
- * @author reghao
|
|
|
- * @date 2021-10-27 03:41:38
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-public class DockerImpl implements Docker {
|
|
|
- private DockerClient dockerClient;
|
|
|
- private final TextFile textFile = new TextFile();
|
|
|
- private final String unixSock = "/var/run/docker.sock";
|
|
|
-
|
|
|
- public DockerImpl() {
|
|
|
- DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
|
|
|
- .withDockerHost("unix://" + unixSock)
|
|
|
- .withDockerTlsVerify(false)
|
|
|
- //.withDockerCertPath(String.format("%s/.docker", System.getProperty("user.home")))
|
|
|
- //.withRegistryUsername("username")
|
|
|
- //.withRegistryPassword("password")
|
|
|
- //.withRegistryEmail(registryMail)
|
|
|
- //.withRegistryUrl(registryUrl)
|
|
|
- .build();
|
|
|
- init(config);
|
|
|
- }
|
|
|
-
|
|
|
- public DockerImpl(DockerAuth dockerAuth) {
|
|
|
- DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
|
|
|
- .withDockerHost("unix://" + unixSock)
|
|
|
- .withDockerTlsVerify(false)
|
|
|
- //.withDockerCertPath(String.format("%s/.docker", System.getProperty("user.home")))
|
|
|
- .withRegistryUrl(dockerAuth.getRegistryUrl())
|
|
|
- .withRegistryUsername(dockerAuth.getUsername())
|
|
|
- .withRegistryPassword(dockerAuth.getPassword())
|
|
|
- //.withRegistryEmail(registryMail)
|
|
|
- .build();
|
|
|
- init(config);
|
|
|
- }
|
|
|
-
|
|
|
- private void init(DockerClientConfig config) {
|
|
|
- DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
|
|
|
- .dockerHost(config.getDockerHost())
|
|
|
- .sslConfig(config.getSSLConfig())
|
|
|
- .maxConnections(100)
|
|
|
- .connectionTimeout(Duration.ofSeconds(60))
|
|
|
- .responseTimeout(Duration.ofSeconds(60))
|
|
|
- .build();
|
|
|
- this.dockerClient = DockerClientImpl.getInstance(config, httpClient);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void auth() {
|
|
|
- dockerClient.authCmd().exec();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Version version() {
|
|
|
- return dockerClient.versionCmd().exec();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void build(String repoTag, String compileHome, String dockerfileContent) throws Exception {
|
|
|
- File dockerfile = new File(compileHome + "/Dockerfile.tmp");
|
|
|
- try {
|
|
|
- textFile.write(dockerfile, dockerfileContent);
|
|
|
- String imageId = dockerClient.buildImageCmd()
|
|
|
- .withDockerfile(dockerfile)
|
|
|
- // repoTag 格式为 docker.reghao.cn/devops:12345678
|
|
|
- .withTags(Set.of(repoTag))
|
|
|
- .start()
|
|
|
- .awaitImageId(300, TimeUnit.SECONDS);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new Exception(ExceptionUtil.errorMsg(e));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void build(String repoTag, String compileHome) throws Exception {
|
|
|
- String dockerfilePath = compileHome + "/Dockerfile";
|
|
|
- dockerClient.buildImageCmd()
|
|
|
- .withDockerfile(new File(dockerfilePath))
|
|
|
- .withTags(Set.of(repoTag))
|
|
|
- .start()
|
|
|
- .awaitImageId(300, TimeUnit.SECONDS);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void push(String image) throws Exception {
|
|
|
- try {
|
|
|
- ResultCallback.Adapter<PushResponseItem> callback = new PushCallback();
|
|
|
- dockerClient.pushImageCmd(image)
|
|
|
- //.exec(new ResultCallback.Adapter<>())
|
|
|
- .exec(callback)
|
|
|
- .awaitCompletion(300, TimeUnit.SECONDS);
|
|
|
- PushCallback pushCallback = (PushCallback) callback;
|
|
|
- int code = pushCallback.getCode();
|
|
|
- if (code != 0) {
|
|
|
- throw new Exception(pushCallback.getMsg());
|
|
|
- }
|
|
|
- } catch (InterruptedException e) {
|
|
|
- throw new Exception(ExceptionUtil.errorMsg(e));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void pull(String image) throws Exception {
|
|
|
- try {
|
|
|
- dockerClient.pullImageCmd(image).exec(new PullImageResultCallback()).awaitCompletion();
|
|
|
- } catch (InterruptedException e) {
|
|
|
- throw new Exception(ExceptionUtil.errorMsg(e));
|
|
|
- }
|
|
|
- /*dockerClient.pullImageCmd(image).exec(new ResultCallback<PullResponseItem>() {
|
|
|
- public void onStart(Closeable closeable) {
|
|
|
- System.out.println("开始下载!");
|
|
|
- }
|
|
|
-
|
|
|
- public void onNext(PullResponseItem object) {
|
|
|
- // 实时显示出下载信息
|
|
|
- System.out.println(object.getStatus());
|
|
|
- }
|
|
|
-
|
|
|
- public void onError(Throwable throwable) {
|
|
|
- throwable.printStackTrace();
|
|
|
- }
|
|
|
-
|
|
|
- public void onComplete() {
|
|
|
- System.out.println("下载完毕!");
|
|
|
- }
|
|
|
-
|
|
|
- public void close() throws IOException {
|
|
|
- System.out.println("下载完毕...");
|
|
|
- }
|
|
|
- }).onComplete();*/
|
|
|
- }
|
|
|
-
|
|
|
- private String getContainerIdByName(String containerName) {
|
|
|
- List<Container> list = dockerClient.listContainersCmd()
|
|
|
- .withShowAll(true)
|
|
|
- .withNameFilter(List.of(containerName))
|
|
|
- .exec();
|
|
|
-
|
|
|
- for (Container container : list) {
|
|
|
- Set<String> set = new HashSet<>(Arrays.asList(container.getNames()));
|
|
|
- if (set.contains("/" + containerName)) {
|
|
|
- return container.getId();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void stopAndDelete(String containerName) {
|
|
|
- String containerId = getContainerIdByName(containerName);
|
|
|
- if (containerId != null) {
|
|
|
- InspectContainerResponse containerInfo = dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- InspectContainerResponse.ContainerState state = containerInfo.getState();
|
|
|
- boolean isRunning = state.getRunning() != null ? state.getRunning() : false;
|
|
|
- if (isRunning) {
|
|
|
- dockerClient.stopContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
- dockerClient.removeContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public InspectContainerResponse createAndRun(String containerName, cn.reghao.bnt.common.docker.model.Config containerConfig) throws Exception {
|
|
|
- stopAndDelete(containerName);
|
|
|
-
|
|
|
- String image = containerConfig.getImage();
|
|
|
- CreateContainerCmd createContainerCmd = dockerClient.createContainerCmd(image)
|
|
|
- .withName(containerName);
|
|
|
-
|
|
|
- List<String> env = containerConfig.getEnv();
|
|
|
- if (env != null) {
|
|
|
- createContainerCmd.withEnv(env);
|
|
|
- }
|
|
|
-
|
|
|
- RestartPolicy restartPolicy = RestartPolicy.onFailureRestart(3);
|
|
|
- HostConfig hostConfig = HostConfig.newHostConfig()
|
|
|
- // --init 参数
|
|
|
- //.withInit(true)
|
|
|
- .withNetworkMode("host")
|
|
|
- .withRestartPolicy(restartPolicy);
|
|
|
- if (containerConfig.getVolumes() != null) {
|
|
|
- Map<String, String> map = containerConfig.getVolumes().getMap();
|
|
|
- List<Bind> list = new ArrayList<>();
|
|
|
- for (Map.Entry<String, String> entry : map.entrySet()) {
|
|
|
- String key = entry.getKey();
|
|
|
- String value = entry.getValue();
|
|
|
- Volume volume2 = new Volume(value);
|
|
|
- Bind bind = new Bind(key, volume2);
|
|
|
- list.add(bind);
|
|
|
- }
|
|
|
- hostConfig.withBinds(list);
|
|
|
- }
|
|
|
-
|
|
|
- if (containerConfig.getHostConfig().getInit() != null) {
|
|
|
- hostConfig.withInit(containerConfig.getHostConfig().getInit());
|
|
|
- }
|
|
|
-
|
|
|
- createContainerCmd.withHostConfig(hostConfig);
|
|
|
- CreateContainerResponse response = createContainerCmd.exec();
|
|
|
- String containerId = response.getId();
|
|
|
- dockerClient.startContainerCmd(containerId).exec();
|
|
|
- return dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
-
|
|
|
- public void createAndRun() {
|
|
|
- String image = "";
|
|
|
- CreateContainerResponse container = dockerClient.createContainerCmd(image)
|
|
|
- .withHostConfig(HostConfig.newHostConfig()
|
|
|
- .withMemory(1024 * 1024 * 1024L) // 限制 1GB 内存
|
|
|
- .withMemoryReservation(512 * 1024 * 1024L) // 保证 512MB 内存
|
|
|
- .withCpuQuota(50000L) // 限制使用 0.5 核 (周期默认为 100000)
|
|
|
- .withBlkioWeight(500) // 设置磁盘 IO 权重
|
|
|
- .withNetworkMode("host")
|
|
|
- .withRestartPolicy(RestartPolicy.noRestart())
|
|
|
- )
|
|
|
- .exec();
|
|
|
- }
|
|
|
-
|
|
|
- public void runAndRm(cn.reghao.bnt.common.docker.model.Config containerConfig) throws Exception {
|
|
|
- String image = containerConfig.getImage();
|
|
|
- CreateContainerCmd createContainerCmd = dockerClient.createContainerCmd(image).withCmd("rm");
|
|
|
-
|
|
|
- List<String> env = containerConfig.getEnv();
|
|
|
- if (env != null) {
|
|
|
- createContainerCmd.withEnv(env);
|
|
|
- }
|
|
|
-
|
|
|
- HostConfig hostConfig = HostConfig.newHostConfig()
|
|
|
- .withNetworkMode("host")
|
|
|
- .withRestartPolicy(RestartPolicy.noRestart());
|
|
|
- if (containerConfig.getVolumes() != null) {
|
|
|
- Map<String, String> map = containerConfig.getVolumes().getMap();
|
|
|
- List<Bind> list = new ArrayList<>();
|
|
|
- for (Map.Entry<String, String> entry : map.entrySet()) {
|
|
|
- String hostPath = entry.getValue();
|
|
|
- String containerPath = entry.getKey();
|
|
|
-
|
|
|
- Volume volume2 = new Volume(containerPath);
|
|
|
- Bind bind = new Bind(hostPath, volume2);
|
|
|
- list.add(bind);
|
|
|
- }
|
|
|
- hostConfig.withBinds(list);
|
|
|
- }
|
|
|
-
|
|
|
- if (containerConfig.getCmd() != null) {
|
|
|
- createContainerCmd.withCmd(containerConfig.getCmd());
|
|
|
- }
|
|
|
-
|
|
|
- createContainerCmd.withHostConfig(hostConfig);
|
|
|
- CreateContainerResponse response = createContainerCmd.exec();
|
|
|
- String containerId = response.getId();
|
|
|
- dockerClient.startContainerCmd(containerId).exec();
|
|
|
-
|
|
|
- List<String> list = new ArrayList<>();
|
|
|
- LogContainerCmd logContainerCmd = dockerClient.logContainerCmd(containerId);
|
|
|
- logContainerCmd.withStdOut(true).withStdErr(true).withFollowStream(true);
|
|
|
- logContainerCmd.exec(new ResultCallback<Frame>() {
|
|
|
- @Override
|
|
|
- public void onStart(Closeable closeable) {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onNext(Frame object) {
|
|
|
- if (object.getStreamType().equals(StreamType.STDERR)) {
|
|
|
- list.add(object.toString());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onError(Throwable throwable) {
|
|
|
- log.info(throwable.toString());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onComplete() {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void close() throws IOException {
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- dockerClient.waitContainerCmd(containerId).exec(new ResultCallback.Adapter<>())
|
|
|
- .awaitCompletion(300, TimeUnit.SECONDS);
|
|
|
-
|
|
|
- InspectContainerResponse response1 = dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- InspectContainerResponse.ContainerState state = response1.getState();
|
|
|
- Long exitCode = state.getExitCodeLong();
|
|
|
- if (Boolean.TRUE.equals(state.getRunning())) {
|
|
|
- dockerClient.stopContainerCmd(containerId).exec();
|
|
|
- dockerClient.removeContainerCmd(containerId).exec();
|
|
|
- throw new Exception("docker build timeout after 300 seconds");
|
|
|
- } else if (exitCode != null && exitCode == 0) {
|
|
|
- dockerClient.removeContainerCmd(containerId).exec();
|
|
|
- } else {
|
|
|
- dockerClient.removeContainerCmd(containerId).exec();
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
- list.forEach(line -> {
|
|
|
- sb.append(line).append(System.lineSeparator());
|
|
|
- });
|
|
|
- throw new Exception("docker build failed:\n" + sb.toString());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public InspectContainerResponse start(String containerName) {
|
|
|
- String containerId = getContainerIdByName(containerName);
|
|
|
- dockerClient.startContainerCmd(containerId).exec();
|
|
|
- return dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public InspectContainerResponse stop(String containerName) {
|
|
|
- String containerId = getContainerIdByName(containerName);
|
|
|
- dockerClient.stopContainerCmd(containerId).exec();
|
|
|
- return dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public InspectContainerResponse restart(String containerName) {
|
|
|
- String containerId = getContainerIdByName(containerName);
|
|
|
- dockerClient.restartContainerCmd(containerId).exec();
|
|
|
- return dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public InspectContainerResponse inspectContainer(String containerName) {
|
|
|
- String containerId = getContainerIdByName(containerName);
|
|
|
- return dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<Image> images() {
|
|
|
- List<Image> images = dockerClient.listImagesCmd().exec();
|
|
|
- return images;
|
|
|
- /*return images.stream().map(image -> {
|
|
|
- long created = image.getCreated();
|
|
|
- String[] repoTags = image.getRepoTags();
|
|
|
- if (repoTags.length == 0) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- String imageId = image.getId();
|
|
|
- String[] repoTag = repoTags[0].split(":");
|
|
|
- String repo = repoTag[0];
|
|
|
- String tag = repoTag[1];
|
|
|
- LocalDateTime created1 = DateTimeConverter.localDateTime(created*1000);
|
|
|
- return new ImageInfo(repo, tag, imageId, created1);
|
|
|
- }).filter(Objects::nonNull).collect(Collectors.toList());*/
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void imageRm(String imageId) {
|
|
|
- dockerClient.removeImageCmd(imageId).exec();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void rm(String containerId) {
|
|
|
- dockerClient.removeContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<InspectContainerResponse> psAll() {
|
|
|
- List<Container> list = dockerClient.listContainersCmd()
|
|
|
- .withShowAll(true)
|
|
|
- .exec();
|
|
|
- return list.stream().map(container -> {
|
|
|
- String containerId = container.getId();
|
|
|
- return dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- }).collect(Collectors.toList());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public InspectContainerResponse ps(String appId) {
|
|
|
- List<Container> list = dockerClient.listContainersCmd()
|
|
|
- .withNameFilter(List.of(appId))
|
|
|
- .exec();
|
|
|
-
|
|
|
- if (list.isEmpty()) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- Container container = list.get(0);
|
|
|
- String containerId = container.getId();
|
|
|
- return dockerClient.inspectContainerCmd(containerId).exec();
|
|
|
- }
|
|
|
-
|
|
|
- static class PushCallback extends ResultCallback.Adapter<PushResponseItem> {
|
|
|
- private int code;
|
|
|
- private String msg;
|
|
|
-
|
|
|
- public PushCallback() {
|
|
|
- this.code = 0;
|
|
|
- }
|
|
|
-
|
|
|
- public int getCode() {
|
|
|
- return code;
|
|
|
- }
|
|
|
-
|
|
|
- public String getMsg() {
|
|
|
- return msg;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onNext(PushResponseItem object) {
|
|
|
- PushResponseItem.ErrorDetail errorDetail = object.getErrorDetail();
|
|
|
- if (errorDetail != null) {
|
|
|
- //log.info("error: {} {}", errorDetail.getCode(), errorDetail.getMessage());
|
|
|
- code = 1;
|
|
|
- msg = errorDetail.getMessage();
|
|
|
- } else {
|
|
|
- //log.info("info: {} {} {}", object.getStatus(), object.getId(), object.getProgressDetail());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onComplete() {
|
|
|
- super.onComplete();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onError(Throwable throwable) {
|
|
|
- throwable.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
-}
|