Shell creation logic

Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
This commit is contained in:
Georg Pfuetzenreuter 2022-05-08 15:03:42 +02:00
parent 5bb047c960
commit a014a0126f
Signed by: Georg
GPG Key ID: 1ED2F138E7E6FF57
3 changed files with 72 additions and 13 deletions

View File

@ -11,11 +11,11 @@ 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.InspectContainerResponse;
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.api.model.SearchItem;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
@ -74,7 +74,7 @@ public class Docker {
public static void deleteContainer(String id) {
Collection<String> stringifiedId = Arrays.asList(id);
System.out.println(id);
//System.out.println(id);
System.out.println(stringifiedId);
List<com.github.dockerjava.api.model.Container> containerQuery = dockerClient.listContainersCmd().withShowAll(false).withIdFilter(stringifiedId).exec();
//apparently listContainersCmd returns a bunch of garbled crap, hence the less ideal toString/contains
@ -93,7 +93,6 @@ public class Docker {
dockerClient.stopContainerCmd(id).exec();
}
//System.out.println(containerQuery);
dockerClient.removeContainerCmd(id).exec();
}
@ -135,10 +134,15 @@ public class Docker {
}
public static String createContainer(String imgid) {
public static String createContainer(String name, String imgid) {
//String containerid = dockerClient.createContainerCmd(imgid).exec();
WaitContainerResultCallback resultCallback = new WaitContainerResultCallback();
CreateContainerResponse createContainerResponse = dockerClient.createContainerCmd(imgid).exec();
CreateContainerResponse createContainerResponse = dockerClient
.createContainerCmd(imgid)
.withName(name)
.withTty(true)
.withAttachStdin(true)
.exec();
dockerClient.waitContainerCmd(createContainerResponse.getId()).exec(resultCallback);
try {
resultCallback.awaitCompletion();
@ -153,24 +157,49 @@ public class Docker {
return(containerid);
}
public static String deleteShell(String user, String id) {
public static String createShell(String user, String os, Integer count) {
String name1 = user + "_" + os;
String name = name1 + "_" + count;
String imageid = null;
List<Image> 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<Image> images = Docker.getImages(user);
for (Image image : images) {
System.out.println(image.getLabels());
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("foo");
return(null);
}
}

View File

@ -158,7 +158,7 @@ public class WebApplication {
System.out.printf("Deletion triggered for ID %s by %s (%s)\n", id, userid, username);
//Docker.deleteContainer(id);
Docker.deleteShell(username, id);
Docker.deleteShell(username, id); //to-do: move to separate mapping
return("redirect:/portal");
}
@ -220,6 +220,36 @@ public class WebApplication {
return("redirect:/portal");
}
@PostMapping(path="/frontend/shell/add",consumes=MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public static String addShell(@RequestBody MultiValueMap<String, String> body, HttpServletRequest request, RedirectAttributes redirectAttributes) {
KeycloakAuthenticationToken principal = (KeycloakAuthenticationToken) request.getUserPrincipal();
String username = null;
String userid = principal.getName();
IDToken token = principal.getAccount().getKeycloakSecurityContext().getIdToken();
Map<String, Object> customClaims = token.getOtherClaims();
username = String.valueOf(customClaims.get("username"));
String os = (String) body.getFirst("osChoice");
System.out.printf("New shell with OS %s requested by %s (%s)\n", os, userid, username);
Random rand = new Random();
Integer randomInt = rand.nextInt(9999999-1111);
Integer count = randomInt;
try {
String containerid = Docker.createShell(username, os, count);
String returnmessage = "Success - spawned shell " + username + "_" + os + "_" + count + " - internal ID: " + containerid;
redirectAttributes.addFlashAttribute("message", returnmessage);
} catch (Exception exception) {
redirectAttributes.addFlashAttribute("message", "Success!");
String returnmessage = "Error - failed to build image :-(";
redirectAttributes.addFlashAttribute("message", returnmessage);
System.out.println(exception);
}
return("redirect:/portal");
}
@GetMapping(path = "/logout")
public String logout(HttpServletRequest request) throws ServletException {
request.logout();

View File

@ -9,7 +9,7 @@
Hello, <span th:text="${username}"></span>.
</h2>
<h3>Generate new throw-away shell:</h3>
<form th:object="${osChoice}" th:id="request_pseudoform" action="#" th:action="@{'/frontend/container/add'}" th:method="post" th:os="${osChoice}" th:onsubmit="return confirm('You are about to generate a shell with the OS ' + this.getAttribute('osoption') + ' - please be patient after you confirm, as the generation may take a short while.');">
<form th:object="${osChoice}" th:id="request_pseudoform" action="#" th:action="@{'/frontend/shell/add'}" th:method="post" th:os="${osChoice}" th:onsubmit="return confirm('You are about to generate a shell with the OS ' + this.getAttribute('osoption') + ' - please be patient after you confirm, as the generation may take a short while.');">
<select class="form-control" th:object="${osChoice}" name="osChoice">
<option value="">Select operating system ...</option>
<option