package net.libertacasa.pubsh.web; import java.io.File; import java.time.Duration; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.BuildImageResultCallback; import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.ListContainersCmd; import com.github.dockerjava.api.command.ListImagesCmd; import com.github.dockerjava.api.command.WaitContainerResultCallback; import com.github.dockerjava.api.model.Image; 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; public class Docker { static DockerClientConfig DockerConfig = DefaultDockerClientConfig.createDefaultConfigBuilder() .withDockerHost("tcp://sweetsuse:2375") .withDockerTlsVerify(false) .build(); static DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder() .dockerHost(DockerConfig.getDockerHost()) .sslConfig(DockerConfig.getSSLConfig()) .maxConnections(100) .connectionTimeout(Duration.ofSeconds(30)) .responseTimeout(Duration.ofSeconds(45)) .build(); static DockerClient dockerClient = DockerClientImpl.getInstance(DockerConfig, httpClient); public static List getImageChecksums() { List imageQuery; List imageList; imageQuery = dockerClient.listImagesCmd().exec(); imageList = imageQuery.stream().map(Image::getId).collect(Collectors.toList()); return imageList; } public static List getImages(String name) { List imageQuery; ListImagesCmd imageQueryCmd = dockerClient.listImagesCmd(); if (name != null) { imageQueryCmd.getFilters().put("reference", Arrays.asList(name + "*")); //to-do: filter by nameshX instead } imageQuery = imageQueryCmd.exec(); return imageQuery; } public static List getContainers(String name) { List containerQuery; ListContainersCmd containerQueryCmd = dockerClient.listContainersCmd(); if (name != null) { containerQueryCmd.getFilters().put("name", Arrays.asList(name + "*")); } containerQuery = containerQueryCmd.withShowAll(true).exec(); return containerQuery; } public static void deleteContainer(String id) { Collection stringifiedId = Arrays.asList(id); //System.out.println(id); System.out.println(stringifiedId); List containerQuery = dockerClient.listContainersCmd().withShowAll(false).withIdFilter(stringifiedId).exec(); //apparently listContainersCmd returns a bunch of garbled crap, hence the less ideal toString/contains if(! containerQuery.toString().contains(id)) { System.out.println("Not found in running containers ..."); List containerQueryAll = dockerClient.listContainersCmd().withShowAll(true).withIdFilter(stringifiedId).exec(); if(containerQueryAll.toString().contains(id)) { System.out.println("Found in stopped containers ..."); } if(! containerQueryAll.toString().contains(id)) { System.out.println("Not found at all. The fuck."); } } if(containerQuery.toString().contains(id)) { System.out.println("Found in running containers, stopping ..."); dockerClient.stopContainerCmd(id).exec(); } dockerClient.removeContainerCmd(id).exec(); } public static String buildImage(String targetUser, String osChoice, Integer count) { String dockerfile = "/home/georg/tmp/docker/Dockerfile_" + osChoice; String tag = targetUser + ":" + osChoice + count; if (! new File(dockerfile).exists()) { System.out.printf("Invalid Dockerfile: %s\n", dockerfile); } Set tags = new HashSet(); tags.add(tag); String imgid = dockerClient.buildImageCmd() .withDockerfile(new File(dockerfile)) .withPull(false).withNoCache(false).withTags(tags) .exec(new BuildImageResultCallback()).awaitImageId(); System.out.printf("Built image with ID %s\n", imgid); return(imgid); } public static void deleteImage(String id) { List imagequery = Docker.getImages(null); if (imagequery.toString().contains(id)) { try { System.out.printf("Found image ID %s, deleting ...\n", id); dockerClient.removeImageCmd(id).withImageId(id).exec(); } catch (com.github.dockerjava.api.exception.ConflictException exception) { System.out.println("Image is still being used by a container."); throw exception; } //needs to wait for callback, but there is none //System.out.printf("%s", removeQuery); } if (! imagequery.toString().contains(id)) { System.out.printf("Image ID %s not found.\n", id); } } public static String createContainer(String name, String imgid) { //String containerid = dockerClient.createContainerCmd(imgid).exec(); WaitContainerResultCallback resultCallback = new WaitContainerResultCallback(); CreateContainerResponse createContainerResponse = dockerClient .createContainerCmd(imgid) .withName(name) .withTty(true) .withAttachStdin(true) .exec(); dockerClient.waitContainerCmd(createContainerResponse.getId()).exec(resultCallback); try { resultCallback.awaitCompletion(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } String containerid = createContainerResponse.getId(); //System.out.println(dockerClient.infoCmd().exec()); System.out.printf("Created container with ID %s from image ID %s\n", containerid, imgid); return(containerid); } public static String createShell(String user, String os, Integer count) { String name1 = user + "_" + os; String name = name1 + "_" + count; String imageid = null; List imageQuery = Docker.getImages(user + ":" + os); System.out.printf("Image query: %s\n", imageQuery); if (imageQuery.isEmpty()) { System.out.println("No result, building new image.\n"); imageid = Docker.buildImage(user, os, count); } if (! imageQuery.isEmpty()) { System.out.println("Found existing image.\n"); Image image = imageQuery.get(0); imageid = image.getId(); } String containerid = createContainer(name, imageid); System.out.printf("Initialized shell with image ID %s and container ID %s\n", imageid, containerid); return(containerid); } public static Integer deleteShell(String user, String id) { Docker.deleteContainer(id); List images = Docker.getImages(user); for (Image image : images) { String imageid = image.getId(); System.out.println(imageid); try { try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Docker.deleteImage(imageid); System.out.println("Removed."); } catch (com.github.dockerjava.api.exception.ConflictException exception) { System.out.println("Still being used, skipping."); } } return(null); } }