From 6c7bc49f2c3807fbc849e476887b0e41876e6a1e Mon Sep 17 00:00:00 2001 From: mamunozgil <miguel.munoz-gil@hft-stuttgart.de> Date: Fri, 10 Jan 2025 11:09:49 +0100 Subject: [PATCH] Modified paths --- .../dtabackend/utils/DockerUtil.java | 126 ++++++++++-------- .../dtabackend/utils/ExecuteTestUtil.java | 20 +-- 2 files changed, 82 insertions(+), 64 deletions(-) diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java index 28510e0..b59d882 100644 --- a/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java +++ b/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java @@ -19,6 +19,7 @@ import org.springframework.stereotype.Component; import java.io.IOException; import java.util.Arrays; +import java.util.UUID; import java.util.stream.Collectors; @Component @@ -94,60 +95,75 @@ public class DockerUtil { } public int runContainerWithVolumes(String image, Volume... volumes) throws InterruptedException, IOException { - LOG.debug(String.format("Pulling image: %s", image)); - try { - dockerClient.pullImageCmd(image) - .start() - .awaitCompletion() - .close(); - } catch (DockerException e) { - LOG.error(String.format( - "Pulling Docker image %s failed with %s, trying with local image", - image, - e.getMessage())); - } - - LOG.debug("Creating container"); - CreateContainerResponse containerResponse; - try { - // Prepare the host configuration with volumes - HostConfig hostConfig = HostConfig.newHostConfig() - .withMounts( - Arrays.stream(volumes) - .map(volume -> new Mount().withTarget(volume.getPath()).withType(MountType.VOLUME)) - .collect(Collectors.toList()) - ); - - // Create the container with the configured volumes - containerResponse = dockerClient.createContainerCmd("testcontainer") - .withImage(image) - .withHostConfig(hostConfig) - .exec(); - } catch (DockerException e) { - LOG.error(String.format( - "Creating Docker Testrunner container failed with %s", e.getMessage())); - throw e; - } - - LOG.debug(String.format("Container created: %s", containerResponse.getId())); - - LOG.debug(String.format("Starting container %s", containerResponse.getId())); - dockerClient.startContainerCmd(containerResponse.getId()).exec(); - - LOG.debug(String.format("Waiting for completion of container %s", containerResponse.getId())); - int ret = dockerClient - .waitContainerCmd(containerResponse.getId()) - .start() - .awaitCompletion() - .awaitStatusCode(); - LOG.debug(String.format("Container completed with status %d", ret)); - - LOG.debug(String.format("Deleting container %s", containerResponse.getId())); - dockerClient.removeContainerCmd(containerResponse.getId()) - .withRemoveVolumes(true) - .exec(); - - return ret; -} + LOG.debug(String.format("Pulling image: %s", image)); + + // Pull the Docker image or log and proceed with local image + try { + dockerClient.pullImageCmd(image).start().awaitCompletion(); + LOG.debug(String.format("Image %s pulled successfully", image)); + } catch (DockerException e) { + LOG.warn(String.format( + "Failed to pull image %s from remote: %s. Attempting to use local image.", + image, e.getMessage())); + + if (dockerClient.inspectImageCmd(image).exec() == null) { + LOG.error(String.format("Image %s not found locally. Aborting.", image)); + throw new IOException("Image not available locally or remotely: " + image); + } + } + + String containerId = null; + try { + LOG.debug("Configuring container with volumes"); + + // Prepare the host configuration for volumes + HostConfig hostConfig = HostConfig.newHostConfig() + .withMounts(Arrays.stream(volumes) + .map(volume -> new Mount() + .withTarget(volume.getPath()) + .withType(MountType.VOLUME)) + .collect(Collectors.toList())); + + // Create the container + LOG.debug("Creating container"); + CreateContainerResponse containerResponse = dockerClient.createContainerCmd(image) + .withHostConfig(hostConfig) + .withName("testcontainer-" + UUID.randomUUID()) + .exec(); + + containerId = containerResponse.getId(); + LOG.debug(String.format("Container created with ID: %s", containerId)); + + // Start the container + LOG.debug(String.format("Starting container %s", containerId)); + dockerClient.startContainerCmd(containerId).exec(); + + // Wait for container completion + LOG.debug(String.format("Waiting for completion of container %s", containerId)); + int statusCode = dockerClient.waitContainerCmd(containerId) + .start() + .awaitCompletion() + .awaitStatusCode(); + + LOG.debug(String.format("Container %s completed with status code %d", containerId, statusCode)); + return statusCode; + + } catch (DockerException | InterruptedException e) { + LOG.error(String.format("An error occurred: %s", e.getMessage()), e); + throw e; + } finally { + if (containerId != null) { + try { + LOG.debug(String.format("Cleaning up container %s", containerId)); + dockerClient.removeContainerCmd(containerId).withRemoveVolumes(false).exec(); + LOG.debug(String.format("Container %s removed successfully", containerId)); + } catch (DockerException cleanupException) { + LOG.error(String.format( + "Failed to clean up container %s: %s", + containerId, cleanupException.getMessage()), cleanupException); + } + } + } + } } diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java index bc5e73b..61541db 100644 --- a/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java +++ b/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java @@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.dockerjava.api.model.Volume; import de.hftstuttgart.dtabackend.models.ExerciseCompetencyProfile; -import de.hftstuttgart.dtabackend.models.ICompetencyProfile; import de.hftstuttgart.dtabackend.models.Recommendation; import de.hftstuttgart.dtabackend.models.ResultSummary; import de.hftstuttgart.dtabackend.models.TestCompetencyProfile; @@ -35,6 +34,7 @@ public class ExecuteTestUtil { private final DockerUtil dockerUtil; private final String assignmentBasePath; + private final String containerTestDir; public ExecuteTestUtil( Environment env, @@ -44,17 +44,19 @@ public class ExecuteTestUtil { // set base path for assignments to be stored Path p = Paths.get( - env.getProperty("data.dir"), - env.getProperty("data.dir.test.folder.name")); + env.getProperty("data.dir"), ///data + env.getProperty("data.dir.test.folder.name")); //UnitTests this.assignmentBasePath = p.toAbsolutePath().toString(); + this.containerTestDir = env.getProperty( "data.dir"); } public ResultSummary runTests(String assignmentId, Path workDirectory) throws IOException, InterruptedException { // Define paths for the test, the submission, and where the result is expected afterwards - Path testPath = Paths.get("/data/test"); // Volume mount path in the container - Path srcPath = Paths.get("/data/src"); // Volume mount path in the container - Path resultPath = Paths.get("/data/result"); // Volume mount path in the container + String containerTestDir = this.containerTestDir; + Path resultPath = Paths.get(containerTestDir, "result"); + Path testPath = Paths.get(containerTestDir, "test"); + Path srcPath = Paths.get(containerTestDir, "src"); // Clone stored test to testPath LOG.debug("Copying pre-downloaded unit test repo"); @@ -95,9 +97,9 @@ public class ExecuteTestUtil { // Start the test-container with professor-given image and volume mounts for test, submission, and result dockerUtil.runContainerWithVolumes( image, - new Volume("/data/test"), - new Volume("/data/src"), - new Volume("/data/result") + new Volume("test_volume: /data/test"), + new Volume("src_volume: /data/src"), + new Volume("result_volume: /data/result") ); ResultSummary resultSummary = generateResult(assignmentId, resultPath, testPath); -- GitLab