当前位置: 首页 > java >正文

基于docker-java封装的工具类

基于docker-java封装的工具类

  • 背景
  • 环境
  • 工具类

背景

写OJ系统时需要用docker作为代码沙箱使用,顺手封装了一个工具类,给自己做个笔记,如果可以的话也希望帮助到其他人。

环境

  • docker 26.1.4
  • docker-java 3.4.2
  • docker-java-transport-httpclient5 3.4.2

工具类


import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.PullImageResultCallback;
import com.github.dockerjava.api.model.Frame;
import com.github.dockerjava.api.model.Image;
import com.github.dockerjava.api.model.PullResponseItem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;/*** @author * @Description dockerClient工具类* @create 2025-04-19 0:30*/
@Slf4j
public class DockerClientUtil {/*** 获取镜像* @return*/public static void getImage(DockerClient dockerClient, String imageName, String imageTag) throws InterruptedException {// 判断镜像是否存在imageTag = ObjectUtils.isEmpty(imageTag)? "latest" : imageTag;// 获取所有本地镜像List<Image> images = dockerClient.listImagesCmd().exec();// 构造完整镜像名String fullImageName = imageName + ":" + imageTag;// 假设镜像不辞你在boolean isImageExists = false;// 遍历镜像列表,检查是否存在匹配的镜像for (Image image : images) {if (image.getRepoTags() != null) {// 确保 RepoTags 不为空for (String repoTag : image.getRepoTags()) {if (repoTag.equals(fullImageName)) {// 存在isImageExists = true;break;}}}}if (!isImageExists) {System.out.println("拉取镜像");// 不存在,拉取镜像dockerClient.pullImageCmd(fullImageName).exec(new PullImageResultCallback() {@Overridepublic void onNext(PullResponseItem item) {super.onNext(item);}}).awaitCompletion();}}/*** 创建可交互控制台容器*/public static CreateContainerResponse createContainer(DockerClient dockerClient, String imageName, String imageTag) {return dockerClient.createContainerCmd(String.format("%s:%s", imageName, imageTag))// 启用伪终端.withTty(true)// 保持标准输入打开.withStdinOpen(true)// 附加标准输入.withAttachStdin(true)// 附加标准输出.withAttachStdout(true)// 附加标准错误.withAttachStderr(true)// 使用登录 shell.withCmd("sh", "-l").exec();}/*** 字符串作为文件保存到容器* @param dockerClient docker客户端* @param containerId 容器id* @param filePath 文件目标路径* @param fileContent 文件内容* @return 是否保存成功* @throws InterruptedException*/public static boolean saveFileToContainer(DockerClient dockerClient, String containerId, String filePath, String fileContent) throws InterruptedException {// 准备编译命令String command = String.format("mkdir -p %s && printf \"%s\" > %s",filePath.replaceAll("([^/]+)/[^/]*$", "$1"), fileContent.replace("\"", "\\\""), filePath);// 创建exec配置String execId = dockerClient.execCreateCmd(containerId).withAttachStdout(true).withAttachStderr(true)// 通过sh -c执行.withCmd("sh", "-c", command).exec().getId();AtomicBoolean rs = new AtomicBoolean(true);// 执行并获取输出dockerClient.execStartCmd(execId).exec(new ResultCallback.Adapter<Frame>() {@Overridepublic void onNext(Frame object) {rs.set(ObjectUtils.isEmpty(object.getPayload()));if (!ObjectUtils.isEmpty(object.getPayload())) {rs.set(false);}super.onNext(object);}}).awaitCompletion();return rs.get();}/*** 运行命令* @param dockerClient* @param containerId* @param command* @return* @throws InterruptedException*/public static String runCommand(DockerClient dockerClient, String containerId, String command) throws InterruptedException {// 创建exec配置String execId = dockerClient.execCreateCmd(containerId).withAttachStdout(true).withAttachStderr(true)// 通过sh -c执行.withCmd("sh", "-c", command).exec().getId();StringBuilder rs = new StringBuilder();// 执行并获取输出dockerClient.execStartCmd(execId).exec(new ResultCallback.Adapter<Frame>() {@Overridepublic void onNext(Frame object) {rs.append(new String(object.getPayload()));super.onNext(object);}}).awaitCompletion();return rs.toString();}/*** 运行代码并批量输入* @param dockerClient* @param containerId* @param runCommand* @param inputStr* @return 运行结果* @throws InterruptedException*/public static String runCommandWithInputBatch(DockerClient dockerClient, String containerId, String runCommand, String inputStr) throws InterruptedException {return runCommand(dockerClient, containerId, String.format("echo -e \"%s\" | %s", inputStr.trim().replaceAll(" ", "\n").replaceAll("\"", "\\\""), runCommand)).replaceAll("\\n$", "");}/*** 清理容器* @param dockerClient* @param containerId*/public static void destroyContainer(DockerClient dockerClient, String containerId) throws InterruptedException {// 停止容器dockerClient.stopContainerCmd(containerId).exec();// 删除容器dockerClient.removeContainerCmd(containerId).exec();}
}
http://www.xdnf.cn/news/663.html

相关文章:

  • 从入门到精通汇编语言 第五章(流程转移与子程序)
  • 【MySQL】数据类型
  • 【OSG学习笔记】Day 4: 相机与视口——控制观察视角
  • 【C++】深入浅出之多态
  • Arduino示例代码讲解:Project 07 - Keyboard 键盘
  • 【AI+HR实战应用】用DeepSeek提升HR工作效能
  • LeetCode[225]用队列实现栈
  • 基于 Spring Boot 瑞吉外卖系统开发(五)
  • thymeleaf模板引擎
  • 【AI训练环境搭建】在Windows11上搭建WSL2+Ubuntu22.04+Tensorflow+GPU机器学习训练环境
  • 996引擎-拓展变量:物品变量
  • 【技术派后端篇】Redis实现统计计数
  • 全同态加密医疗数据分析集python实现
  • 深入探索 Unix 与 Linux:历史、内核及发行版
  • QML 样式库
  • OpenCV基础01-图像文件的读取与保存
  • 【每日八股】复习计算机网络 Day3:TCP 协议的其他相关问题
  • Qt基础005(文件操作后续)
  • 中间件--ClickHouse-14--案例-3-其他案例思路概述
  • 爆肝整理!Stable Diffusion的完全使用手册(二)
  • trivy开源安全漏洞扫描器——筑梦之路
  • 【21天学习打卡挑战赛】如何学习WEB安全:逼自己在短时间掌握WEB安全核心内容
  • 深入理解 CICD 与 Jenkins 流水线:从原理到实践
  • Python 项目环境配置与 Vanna 安装避坑指南 (PyCharm + venv)
  • 机器学习中的“三态模型“:过拟合、欠拟合和刚刚好
  • WordPress按分类ID调用该分类的内容数量
  • 【网络】数据链路层知识梳理
  • Vue3项目自定义全局防抖节流
  • Linux命令-Shell编程
  • 星拍相机APP:时尚与科技的完美融合,打造你的专属美