diff --git a/docs/goal/image.md b/docs/goal/image.md index 764962f..b1770aa 100644 --- a/docs/goal/image.md +++ b/docs/goal/image.md @@ -2,12 +2,14 @@ Import images into k3s containerd. -| Name | User Property | Description | Default | -| -----| ------------- | ----------- | ------- | -| `ctrImages` | `k3s.ctrImages` | Download given images via `ctr image pull` inside k3s container. | [] | -| `tarFiles` | `k3s.tarFiles` | Import given tar files via `ctr image import` inside k3s container. | [] | -| `dockerImages` | `k3s.dockerImages` | Copy given images from docker deamon via `ctr image import` inside k3s container. | [] | -| `dockerPullAlways` | `k3s.dockerPullAlways` | Always pull docker images or only if not present. | false | -| `pullTimeout` | `k3s.pullTimeout` | Timout for `ctr image pull` or `docker pull` in seconds. | 1200 | -| `skipImage` | `k3s.skipImage` | Skip image handling. | false | -| `debug` | `k3s.debug` | Stream logs of docker and kubectl. | false | +| Name | User Property | Description | Default | +| -----|------------------------| ----------- |---------| +| `ctrImages` | `k3s.ctrImages` | Download given images via `ctr image pull` inside k3s container. | [] | +| `tarFiles` | `k3s.tarFiles` | Import given tar files via `ctr image import` inside k3s container. | [] | +| `dockerImages` | `k3s.dockerImages` | Copy given images from docker deamon via `ctr image import` inside k3s container. | [] | +| `dockerPullAlways` | `k3s.dockerPullAlways` | Always pull docker images or only if not present. | false | +| `pullTimeout` | `k3s.pullTimeout` | Timout for `ctr image pull` or `docker pull` in seconds. | 1200 | +| `copyToContainerTimeout` | `k3s.copyToContainerTimeout` | Timout for saving image to tar in seconds. | 60 | +| `saveImageTimeout` | `k3s.saveImageTimeout` | Timout for saving image to tar in seconds. | 60 | +| `skipImage` | `k3s.skipImage` | Skip image handling. | false | +| `debug` | `k3s.debug` | Stream logs of docker and kubectl. | false | diff --git a/src/main/java/io/kokuwa/maven/k3s/mojo/ApplyMojo.java b/src/main/java/io/kokuwa/maven/k3s/mojo/ApplyMojo.java index 6f2b9ee..99b8c94 100644 --- a/src/main/java/io/kokuwa/maven/k3s/mojo/ApplyMojo.java +++ b/src/main/java/io/kokuwa/maven/k3s/mojo/ApplyMojo.java @@ -84,25 +84,26 @@ public void execute() throws MojoExecutionException { // verify container and copy manifests - if (getDocker().getContainer().isEmpty()) { + if (getDocker().getContainer(getDefaultTaskTimeout()).isEmpty()) { throw new MojoExecutionException("No k3s container found"); } - getDocker().copyToContainer(manifests, toLinuxPath(path)); + getDocker().copyToContainer(manifests, toLinuxPath(path), getDefaultTaskTimeout()); // wait for service account, see https://github.com/kubernetes/kubernetes/issues/66689 var serviceAccount = new String[] { "kubectl", "get", "sa", "default", "--ignore-not-found", "--output=name" }; - if (getDocker().exec(serviceAccount).isEmpty()) { + if (getDocker().exec(getDefaultTaskTimeout(), serviceAccount).isEmpty()) { log.info(""); log.info("No service account found, waiting for sa ..."); - Await.await(log, "k3s service account ready").until(() -> !getDocker().exec(serviceAccount).isEmpty()); + Await.await(log, "k3s service account ready") + .until(() -> !getDocker().exec(getDefaultTaskTimeout(), serviceAccount).isEmpty()); log.info("Service account found, continue ..."); log.info(""); } // wait for node getting ready - getDocker().exec("kubectl", "wait", "--for=condition=Ready", "node", "k3s"); + getDocker().exec(getDefaultTaskTimeout(), "kubectl", "wait", "--for=condition=Ready", "node", "k3s"); // execute command @@ -182,7 +183,7 @@ private Stream>> waitFor(Entry>> waitFor(Entry> existingImages, Path tarFile) { var destination = "/tmp/" + tarFile.getFileName() + "_" + System.nanoTime(); var outputPattern = Pattern.compile("^unpacking (?.*) \\(sha256:[0-9a-f]{64}\\).*$"); - getDocker().copyToContainer(tarFile, destination); + getDocker().copyToContainer(tarFile, destination, copyToContainerTimeout); for (var output : getDocker().exec(pullTimeout, "ctr", "image", "import", destination.toString())) { var matcher = outputPattern.matcher(output); if (matcher.matches()) { - getDocker().exec("ctr", "image", "label", matcher.group("image"), labelPath + "=" + tarFile); - getDocker().exec("ctr", "image", "label", matcher.group("image"), + getDocker().exec(getDefaultTaskTimeout(), "ctr", "image", "label", matcher.group("image"), + labelPath + "=" + tarFile); + getDocker().exec(getDefaultTaskTimeout(), "ctr", "image", "label", matcher.group("image"), labelChecksum + "=" + newChecksum); } else { log.warn("Tar {} import output cannot be parsed: {}", tarFile, output); @@ -194,7 +211,7 @@ private boolean docker(Map> existingImages, String image) // pull image - var digest = getDocker().getImage(image).map(ContainerImage::getDigest).orElse(null); + var digest = getDocker().getImage(image, getDefaultTaskTimeout()).map(ContainerImage::getDigest).orElse(null); if (dockerPullAlways || digest == null) { if (digest != null) { log.debug("Image {} found in docker, pull always ...", image); @@ -207,7 +224,7 @@ private boolean docker(Map> existingImages, String image) log.error("Failed to pull docker image {}", image, e); return false; } - digest = getDocker().getImage(image).map(ContainerImage::getDigest).orElse(null); + digest = getDocker().getImage(image, getDefaultTaskTimeout()).map(ContainerImage::getDigest).orElse(null); } else { log.debug("Image {} found in docker", image); } @@ -232,10 +249,10 @@ private boolean docker(Map> existingImages, String image) var source = Paths.get(System.getProperty("java.io.tmpdir")).resolve(filename); var destination = "/tmp/" + filename; try { - getDocker().saveImage(image, source); - getDocker().copyToContainer(source, destination); + getDocker().saveImage(image, source, saveImageTimeout); + getDocker().copyToContainer(source, destination, copyToContainerTimeout); getDocker().exec(pullTimeout, "ctr", "image", "import", destination.toString()); - getDocker().exec("ctr", "image", "label", normalizedImage, label + "=" + digest); + getDocker().exec(getDefaultTaskTimeout(), "ctr", "image", "label", normalizedImage, label + "=" + digest); } catch (MojoExecutionException e) { log.error("Failed to import tar {}", source, e); return false; @@ -251,7 +268,7 @@ private boolean docker(Map> existingImages, String image) * @return Image name with labels. */ private Map> getCtrImages() throws MojoExecutionException { - return getDocker().exec("ctr", "image", "list").stream().map(String::strip) + return getDocker().exec(getDefaultTaskTimeout(), "ctr", "image", "list").stream().map(String::strip) .filter(row -> !row.startsWith("REF") && !row.startsWith("sha256:")) .map(row -> row.split("(\\s)+")) .filter(parts -> { @@ -290,6 +307,14 @@ public void setPullTimeout(int pullTimeout) { this.pullTimeout = Duration.ofSeconds(pullTimeout); } + public void setCopyToContainerTimeout(int copyToContainerTimeout) { + this.copyToContainerTimeout = Duration.ofSeconds(copyToContainerTimeout); + } + + public void setSaveImageTimeout(int saveImageTimeout) { + this.saveImageTimeout = Duration.ofSeconds(saveImageTimeout); + } + public void setSkipImage(boolean skipImage) { this.skipImage = skipImage; } diff --git a/src/main/java/io/kokuwa/maven/k3s/mojo/K3sMojo.java b/src/main/java/io/kokuwa/maven/k3s/mojo/K3sMojo.java index e838f51..bf794c6 100644 --- a/src/main/java/io/kokuwa/maven/k3s/mojo/K3sMojo.java +++ b/src/main/java/io/kokuwa/maven/k3s/mojo/K3sMojo.java @@ -2,6 +2,7 @@ import java.io.File; import java.nio.file.Path; +import java.time.Duration; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.logging.Log; @@ -28,6 +29,14 @@ public abstract class K3sMojo extends AbstractMojo { @Parameter(property = "k3s.debug", defaultValue = "false") private boolean debug; + /** + * Default timout for plugin tasks in seconds. + * + * @since 1.5.0 + */ + @Parameter(property = "k3s.defaultTaskTimeout", defaultValue = "30") + private Duration defaultTaskTimeout; + /** * Skip plugin. * @@ -61,6 +70,10 @@ public Marker getMarker() { return marker; } + public Duration getDefaultTaskTimeout() { + return defaultTaskTimeout; + } + @Deprecated @Override public Log getLog() { @@ -86,6 +99,10 @@ public void setDebug(boolean debug) { this.debug = debug; } + public void setDefaultTaskTimeout(int defaultTaskTimeout) { + this.defaultTaskTimeout = Duration.ofSeconds(defaultTaskTimeout); + } + public void setSkip(boolean skip) { this.skip = skip; } diff --git a/src/main/java/io/kokuwa/maven/k3s/mojo/RemoveMojo.java b/src/main/java/io/kokuwa/maven/k3s/mojo/RemoveMojo.java index c78992e..8a55e9d 100644 --- a/src/main/java/io/kokuwa/maven/k3s/mojo/RemoveMojo.java +++ b/src/main/java/io/kokuwa/maven/k3s/mojo/RemoveMojo.java @@ -36,9 +36,9 @@ public void execute() throws MojoExecutionException { return; } - getDocker().removeContainer(); + getDocker().removeContainer(getDefaultTaskTimeout()); if (includeCache) { - getDocker().removeVolume(); + getDocker().removeVolume(getDefaultTaskTimeout()); log.info("Deleted cache volume."); } } diff --git a/src/main/java/io/kokuwa/maven/k3s/mojo/RestartMojo.java b/src/main/java/io/kokuwa/maven/k3s/mojo/RestartMojo.java index 84bc98f..d93dcac 100644 --- a/src/main/java/io/kokuwa/maven/k3s/mojo/RestartMojo.java +++ b/src/main/java/io/kokuwa/maven/k3s/mojo/RestartMojo.java @@ -81,7 +81,7 @@ public void execute() throws MojoExecutionException { // verify container - if (getDocker().getContainer().isEmpty()) { + if (getDocker().getContainer(getDefaultTaskTimeout()).isEmpty()) { throw new MojoExecutionException("No k3s container found"); } @@ -118,14 +118,17 @@ private Callable restart(String resoure) { return () -> { try { - getDocker().exec("kubectl", "rollout", "restart", kind, name, "--namespace=" + namespace); + getDocker().exec(timeout, "kubectl", "rollout", "restart", kind, name, "--namespace=" + namespace); log.info("{} {}/{} restarted", kind, namespace, name); - getDocker().exec("kubectl", "rollout", "status", kind, name, "--namespace=" + namespace, + // Docker exec timeout should be greater than "inner" K3s timeout + getDocker().exec(timeout.plusSeconds(10), "kubectl", "rollout", "status", kind, name, + "--namespace=" + namespace, "--timeout=" + timeout.getSeconds() + "s"); log.info("{} {}/{} restart finished", kind, namespace, name); return true; } catch (MojoExecutionException e) { - getDocker().exec("kubectl", "get", "--output=yaml", "--namespace=" + namespace, kind, name); + getDocker().exec(getDefaultTaskTimeout(), "kubectl", "get", "--output=yaml", "--namespace=" + namespace, + kind, name); return false; } }; diff --git a/src/main/java/io/kokuwa/maven/k3s/mojo/RunMojo.java b/src/main/java/io/kokuwa/maven/k3s/mojo/RunMojo.java index f2791bd..796d9e8 100644 --- a/src/main/java/io/kokuwa/maven/k3s/mojo/RunMojo.java +++ b/src/main/java/io/kokuwa/maven/k3s/mojo/RunMojo.java @@ -244,14 +244,14 @@ public void execute() throws MojoExecutionException { var create = true; var restart = false; - var container = getDocker().getContainer().orElse(null); + var container = getDocker().getContainer(getDefaultTaskTimeout()).orElse(null); if (container != null) { if (failIfExists) { throw new MojoExecutionException("Container with id '" + container.id + "' found. Please remove that container or set 'k3s.failIfExists' to false."); } else if (replaceIfExists) { log.info("Container with id '{}' found, replacing", container.id); - getDocker().removeContainer(); + getDocker().removeContainer(getDefaultTaskTimeout()); } else if (!container.isRunning()) { log.warn("Container with id '{}' found in stopped state, restart container", container.id); create = false; @@ -269,20 +269,21 @@ public void execute() throws MojoExecutionException { if (create) { createAndStartK3sContainer(); } else if (restart) { - getDocker().startContainer(); + getDocker().startContainer(getDefaultTaskTimeout()); } // wait for k3s api to be ready var await = Await.await(log, "k3s api available").timeout(nodeTimeout); - getDocker().waitForLog(await, output -> output.stream().anyMatch(l -> l.contains("k3s is up and running"))); + getDocker().waitForLog(await, output -> output.stream().anyMatch(l -> l.contains("k3s is up and running")), + getDefaultTaskTimeout()); // write file that k3s started getMarker().writeStarted(); } - getDocker().copyFromContainer("/etc/rancher/k3s/k3s.yaml", kubeconfig); + getDocker().copyFromContainer("/etc/rancher/k3s/k3s.yaml", kubeconfig, getDefaultTaskTimeout()); log.info("k3s ready: KUBECONFIG={} kubectl get all --all-namespaces", kubeconfig); } @@ -340,8 +341,8 @@ private void createAndStartK3sContainer() throws MojoExecutionException { } var ports = new ArrayList<>(portBindings); ports.add(portKubeApi + ":" + portKubeApi); - getDocker().createContainer(image, ports, command, registries); - getDocker().createVolume(); + getDocker().createContainer(image, ports, command, registries, getDefaultTaskTimeout()); + getDocker().createVolume(getDefaultTaskTimeout()); } // setter diff --git a/src/main/java/io/kokuwa/maven/k3s/util/Docker.java b/src/main/java/io/kokuwa/maven/k3s/util/Docker.java index f1c03ad..09b035c 100644 --- a/src/main/java/io/kokuwa/maven/k3s/util/Docker.java +++ b/src/main/java/io/kokuwa/maven/k3s/util/Docker.java @@ -38,16 +38,17 @@ public Docker(String containerName, String volumeName, Logger log) { this.log = log; } - public Optional getContainer() throws MojoExecutionException { + public Optional getContainer(Duration timeout) throws MojoExecutionException { return Task - .of(log, "docker", "container", "ls", "--all", "--filter=name=" + containerName, "--format={{json .}}") + .of(log, timeout, "docker", "container", "ls", "--all", "--filter=name=" + containerName, + "--format={{json .}}") .run().stream() .map(output -> readValue(Container.class, output)) .filter(container -> containerName.equals(container.name)) .findAny(); } - public void createContainer(String image, List ports, List k3s, Path registries) + public void createContainer(String image, List ports, List k3s, Path registries, Duration timeout) throws MojoExecutionException { var command = new ArrayList(); command.add("docker"); @@ -62,37 +63,35 @@ public void createContainer(String image, List ports, List k3s, ports.stream().map(port -> "--publish=" + port).forEach(command::add); command.add(image); command.addAll(k3s); - Task.of(log, command).run(); + Task.of(log, timeout, command).run(); } - public void startContainer() throws MojoExecutionException { - Task.of(log, "docker", "start", containerName).run(); + public void startContainer(Duration timeout) throws MojoExecutionException { + Task.of(log, timeout, "docker", "start", containerName).run(); } - public void removeContainer() throws MojoExecutionException { - Task.of(log, "docker", "rm", containerName, "--force", "--volumes").run(); + public void removeContainer(Duration timeout) throws MojoExecutionException { + Task.of(log, timeout, "docker", "rm", containerName, "--force", "--volumes").run(); } - public void copyFromContainer(String source, Path destination) throws MojoExecutionException { - Task.of(log, "docker", "cp", containerName + ":" + source, destination.toString()).run(); + public void copyFromContainer(String source, Path destination, Duration timeout) throws MojoExecutionException { + Task.of(log, timeout, "docker", "cp", containerName + ":" + source, destination.toString()).run(); } - public void copyToContainer(Path source, String destination) throws MojoExecutionException { + public void copyToContainer(Path source, String destination, Duration timeout) throws MojoExecutionException { // suffix directories with '/.', see https://docs.docker.com/engine/reference/commandline/cp/#description var sourceString = Files.isDirectory(source) ? source + File.separator + "." : source.toString(); - Task.of(log, "docker", "cp", sourceString, containerName + ":" + destination).run(); + Task.of(log, timeout, "docker", "cp", sourceString, containerName + ":" + destination).run(); } - public void waitForLog(Await await, Function, Boolean> checker) throws MojoExecutionException { - var process = Task.of(log, "docker", "logs", containerName, "--follow").timeout(Duration.ofHours(1)).start(); + public void waitForLog(Await await, Function, Boolean> checker, Duration timeout) + throws MojoExecutionException { + var process = Task.of(log, timeout, "docker", "logs", containerName, "--follow").timeout(Duration.ofHours(1)) + .start(); await.onTimeout(() -> process.output().forEach(log::warn)).until(() -> process.output(), checker); process.close(); } - public List exec(String... commands) throws MojoExecutionException { - return exec(null, commands); - } - public List exec(Duration timeout, String... commands) throws MojoExecutionException { return exec(timeout, List.of(commands)); } @@ -101,39 +100,32 @@ public List exec(Duration timeout, List commands) throws MojoExe return execWithoutVerify(timeout, commands).verify().output(); } - public Task execWithoutVerify(List commands) throws MojoExecutionException { - return execWithoutVerify(null, commands); - } - public Task execWithoutVerify(Duration timeout, List commands) throws MojoExecutionException { var command = new ArrayList(); command.add("docker"); command.add("exec"); command.add(containerName); command.addAll(commands); - var task = Task.of(log, command); - if (timeout != null) { - task.timeout(timeout); - } + var task = Task.of(log, timeout, command); return task.start().waitFor(); } // volume - public Optional getVolume() throws MojoExecutionException { - return Task.of(log, "docker", "volume", "ls", "--filter=name=" + volumeName, "--format={{json .}}") + public Optional getVolume(Duration timeout) throws MojoExecutionException { + return Task.of(log, timeout, "docker", "volume", "ls", "--filter=name=" + volumeName, "--format={{json .}}") .run().stream() .map(output -> readValue(ContainerVolume.class, output)) .filter(volume -> volumeName.equals(volume.name)) .findAny(); } - public void createVolume() throws MojoExecutionException { - Task.of(log, "docker", "volume", "create", volumeName).run(); + public void createVolume(Duration timeout) throws MojoExecutionException { + Task.of(log, timeout, "docker", "volume", "create", volumeName).run(); } - public void removeVolume() throws MojoExecutionException { - Task.of(log, "docker", "volume", "rm", volumeName, "--force").run(); + public void removeVolume(Duration timeout) throws MojoExecutionException { + Task.of(log, timeout, "docker", "volume", "rm", volumeName, "--force").run(); } // images @@ -156,23 +148,23 @@ public String normalizeImage(String image) { return newImageName; } - public Optional getImage(String image) throws MojoExecutionException { - var task = Task.of(log, "docker", "image", "inspect", image, "--format={{json .}}").start().waitFor(); + public Optional getImage(String image, Duration timeout) throws MojoExecutionException { + var task = Task.of(log, timeout, "docker", "image", "inspect", image, "--format={{json .}}").start().waitFor(); return task.exitCode() == 0 ? task.output().stream().map(output -> readValue(ContainerImage.class, output)).findAny() : Optional.empty(); } public void pullImage(String image, Duration timeout) throws MojoExecutionException { - Task.of(log, "docker", "image", "pull", "--quiet", image).timeout(timeout).run(); + Task.of(log, timeout, "docker", "image", "pull", "--quiet", image).run(); } - public void saveImage(String image, Path path) throws MojoExecutionException { - Task.of(log, "docker", "image", "save", "--output=" + path, image).run(); + public void saveImage(String image, Path path, Duration timeout) throws MojoExecutionException { + Task.of(log, timeout, "docker", "image", "save", "--output=" + path, image).run(); } - public void removeImage(String image) throws MojoExecutionException { - Task.of(log, "docker", "image", "rm", "--force", image).run(); + public void removeImage(String image, Duration timeout) throws MojoExecutionException { + Task.of(log, timeout, "docker", "image", "rm", "--force", image).run(); } // internal diff --git a/src/main/java/io/kokuwa/maven/k3s/util/Task.java b/src/main/java/io/kokuwa/maven/k3s/util/Task.java index 6a19877..c18c377 100644 --- a/src/main/java/io/kokuwa/maven/k3s/util/Task.java +++ b/src/main/java/io/kokuwa/maven/k3s/util/Task.java @@ -24,25 +24,26 @@ public class Task { private final Logger log; private final List command; - private Duration timeout = Duration.ofSeconds(30); + private Duration timeout; private Process process; private final List output = new ArrayList<>(); private final List threads = new ArrayList<>(); - private Task(Logger log, List command) { + private Task(Logger log, Duration timeout, List command) { this.log = log; this.command = command; + this.timeout = timeout; } // config - public static Task of(Logger log, String... command) { - return new Task(log, List.of(command)); + public static Task of(Logger log, Duration timeout, String... command) { + return new Task(log, timeout, List.of(command)); } - public static Task of(Logger log, List command) { - return new Task(log, command); + public static Task of(Logger log, Duration timeout, List command) { + return new Task(log, timeout, command); } public List command() { diff --git a/src/test/java/io/kokuwa/maven/k3s/mojo/ApplyMojoTest.java b/src/test/java/io/kokuwa/maven/k3s/mojo/ApplyMojoTest.java index 2b430c0..11b7f30 100644 --- a/src/test/java/io/kokuwa/maven/k3s/mojo/ApplyMojoTest.java +++ b/src/test/java/io/kokuwa/maven/k3s/mojo/ApplyMojoTest.java @@ -22,7 +22,7 @@ public class ApplyMojoTest extends AbstractTest { @Test void withSkip(ApplyMojo applyMojo) throws MojoExecutionException { - assertFalse(docker.getContainer().isPresent()); + assertFalse(docker.getContainer(DEFAUL_TASK_TIMEOUT).isPresent()); applyMojo.setSkipApply(false); applyMojo.setSkip(true); diff --git a/src/test/java/io/kokuwa/maven/k3s/mojo/ImageMojoTest.java b/src/test/java/io/kokuwa/maven/k3s/mojo/ImageMojoTest.java index 1064f51..56c57dd 100644 --- a/src/test/java/io/kokuwa/maven/k3s/mojo/ImageMojoTest.java +++ b/src/test/java/io/kokuwa/maven/k3s/mojo/ImageMojoTest.java @@ -97,7 +97,8 @@ void dockerImages(RunMojo runMojo, ImageMojo imageMojo) throws MojoExecutionExce // pull again in docker, and copy to container because digest was changed imageMojo.setDockerPullAlways(true); - docker.exec("ctr", "image", "label", docker.normalizeImage(helloWorld()), "k3s-maven-digest=nope"); + docker.exec(DEFAUL_TASK_TIMEOUT, "ctr", "image", "label", docker.normalizeImage(helloWorld()), + "k3s-maven-digest=nope"); assertCtrImage(helloWorld(), true); assertDoesNotThrow(imageMojo::execute); assertCtrImage(helloWorld(), true); @@ -131,13 +132,13 @@ void tarFiles(RunMojo runMojo, ImageMojo imageMojo) throws MojoExecutionExceptio // internal private void assertCtrImage(String image, boolean exists) throws MojoExecutionException { - var images = docker.exec("ctr", "image", "list", "--quiet"); + var images = docker.exec(DEFAUL_TASK_TIMEOUT, "ctr", "image", "list", "--quiet"); var normalizedImage = docker.normalizeImage(image); assertEquals(exists, images.contains(normalizedImage), "Image '" + normalizedImage + "' " + (exists ? "not " : "") + "found, available: \n" + images); } private boolean hasDockerImage(String image) throws MojoExecutionException { - return docker.getImage(image).isPresent(); + return docker.getImage(image, DEFAUL_TASK_TIMEOUT).isPresent(); } } diff --git a/src/test/java/io/kokuwa/maven/k3s/mojo/RemoveMojoTest.java b/src/test/java/io/kokuwa/maven/k3s/mojo/RemoveMojoTest.java index 044b9c4..8aab6da 100644 --- a/src/test/java/io/kokuwa/maven/k3s/mojo/RemoveMojoTest.java +++ b/src/test/java/io/kokuwa/maven/k3s/mojo/RemoveMojoTest.java @@ -44,10 +44,10 @@ void withoutContainer(RemoveMojo removeMojo) { @DisplayName("without container but present cache") @Test void withoutContainerButPresentCache(RemoveMojo removeMojo) throws MojoExecutionException { - docker.createVolume(); + docker.createVolume(DEFAUL_TASK_TIMEOUT); removeMojo.setIncludeCache(true); assertDoesNotThrow(removeMojo::execute); - assertFalse(docker.getVolume().isPresent()); + assertFalse(docker.getVolume(DEFAUL_TASK_TIMEOUT).isPresent()); } @DisplayName("with container") @@ -55,8 +55,8 @@ void withoutContainerButPresentCache(RemoveMojo removeMojo) throws MojoExecution void withContainer(RunMojo runMojo, RemoveMojo removeMojo) throws MojoExecutionException { assertDoesNotThrow(runMojo::execute); assertDoesNotThrow(removeMojo::execute); - assertFalse(docker.getContainer().isPresent()); - assertTrue(docker.getVolume().isPresent()); + assertFalse(docker.getContainer(DEFAUL_TASK_TIMEOUT).isPresent()); + assertTrue(docker.getVolume(DEFAUL_TASK_TIMEOUT).isPresent()); } @DisplayName("with container and cache") @@ -65,7 +65,7 @@ void withContainerAndCache(RunMojo runMojo, RemoveMojo removeMojo) throws MojoEx removeMojo.setIncludeCache(true); assertDoesNotThrow(runMojo::execute); assertDoesNotThrow(removeMojo::execute); - assertFalse(docker.getContainer().isPresent()); - assertFalse(docker.getVolume().isPresent()); + assertFalse(docker.getContainer(DEFAUL_TASK_TIMEOUT).isPresent()); + assertFalse(docker.getVolume(DEFAUL_TASK_TIMEOUT).isPresent()); } } diff --git a/src/test/java/io/kokuwa/maven/k3s/mojo/RunMojoTest.java b/src/test/java/io/kokuwa/maven/k3s/mojo/RunMojoTest.java index 73de461..688234d 100644 --- a/src/test/java/io/kokuwa/maven/k3s/mojo/RunMojoTest.java +++ b/src/test/java/io/kokuwa/maven/k3s/mojo/RunMojoTest.java @@ -45,7 +45,7 @@ void withSkip(RunMojo runMojo) throws MojoExecutionException { runMojo.setSkip(true); assertDoesNotThrow(runMojo::execute); - assertFalse(docker.getContainer().isPresent()); + assertFalse(docker.getContainer(DEFAUL_TASK_TIMEOUT).isPresent()); } @DisplayName("with fail on existing container") @@ -54,7 +54,7 @@ void withFailIfExists(RunMojo runMojo) throws MojoExecutionException { runMojo.setFailIfExists(true); assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); - var expectedMessage = "Container with id '" + docker.getContainer().get().id + var expectedMessage = "Container with id '" + docker.getContainer(DEFAUL_TASK_TIMEOUT).get().id + "' found. Please remove that container or set 'k3s.failIfExists' to false."; var actualMessage = assertThrows(MojoExecutionException.class, runMojo::execute).getMessage(); assertEquals(expectedMessage, actualMessage, "exception message"); @@ -67,8 +67,8 @@ void withFailIfExistsStopped(RunMojo runMojo, Logger log) throws MojoExecutionEx runMojo.setFailIfExists(true); assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); - Task.of(log, "docker", "stop", "k3s-maven-plugin").run(); - var expectedMessage = "Container with id '" + docker.getContainer().get().id + Task.of(log, DEFAUL_TASK_TIMEOUT, "docker", "stop", "k3s-maven-plugin").run(); + var expectedMessage = "Container with id '" + docker.getContainer(DEFAUL_TASK_TIMEOUT).get().id + "' found. Please remove that container or set 'k3s.failIfExists' to false."; var actualMessage = assertThrows(MojoExecutionException.class, runMojo::execute).getMessage(); assertEquals(expectedMessage, actualMessage, "exception message"); @@ -82,10 +82,10 @@ void withReplaceIfExists(RunMojo runMojo) throws MojoExecutionException { runMojo.setReplaceIfExists(true); assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); - var containerBefore = docker.getContainer().orElseThrow(); + var containerBefore = docker.getContainer(DEFAUL_TASK_TIMEOUT).orElseThrow(); assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); - var containerAfter = docker.getContainer().orElseThrow(); + var containerAfter = docker.getContainer(DEFAUL_TASK_TIMEOUT).orElseThrow(); assertNotEquals(containerBefore.id, containerAfter.id, "container was not replaced"); } @@ -96,10 +96,10 @@ void withReplaceIfExistsStopped(RunMojo runMojo, Logger log) throws MojoExecutio runMojo.setReplaceIfExists(true); assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); - var containerBefore = docker.getContainer().orElseThrow(); - Task.of(log, "docker", "stop", "k3s-maven-plugin").run(); + var containerBefore = docker.getContainer(DEFAUL_TASK_TIMEOUT).orElseThrow(); + Task.of(log, DEFAUL_TASK_TIMEOUT, "docker", "stop", "k3s-maven-plugin").run(); assertDoesNotThrow(runMojo::execute); - var containerAfter = docker.getContainer().orElseThrow(); + var containerAfter = docker.getContainer(DEFAUL_TASK_TIMEOUT).orElseThrow(); assertNotEquals(containerBefore.id, containerAfter.id, "container was not replaced"); assertTrue(runMojo.getMarker().consumeStarted()); } @@ -111,9 +111,9 @@ void withoutFailIfExists(RunMojo runMojo) throws MojoExecutionException { runMojo.setReplaceIfExists(false); assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); - var containerBefore = docker.getContainer().orElseThrow(); + var containerBefore = docker.getContainer(DEFAUL_TASK_TIMEOUT).orElseThrow(); assertDoesNotThrow(runMojo::execute); - var containerAfter = docker.getContainer().orElseThrow(); + var containerAfter = docker.getContainer(DEFAUL_TASK_TIMEOUT).orElseThrow(); assertEquals(containerBefore.id, containerAfter.id, "container shouldn't be replaced"); assertFalse(runMojo.getMarker().consumeStarted(), "no started marker expected"); } @@ -125,12 +125,12 @@ void withoutFailIfExistsStopped(RunMojo runMojo, Logger log, ApplyMojo applyMojo runMojo.setReplaceIfExists(false); assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); - var containerBefore = docker.getContainer().orElseThrow(); - Task.of(log, "docker", "stop", "k3s-maven-plugin").run(); + var containerBefore = docker.getContainer(DEFAUL_TASK_TIMEOUT).orElseThrow(); + Task.of(log, DEFAUL_TASK_TIMEOUT, "docker", "stop", "k3s-maven-plugin").run(); assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); assertDoesNotThrow(applyMojo::execute); - var containerAfter = docker.getContainer().orElseThrow(); + var containerAfter = docker.getContainer(DEFAUL_TASK_TIMEOUT).orElseThrow(); assertEquals(containerBefore.id, containerAfter.id, "container shouldn't be replaced"); } @@ -141,7 +141,8 @@ void withRegistries(RunMojo runMojo, Logger log) throws MojoExecutionException { assertDoesNotThrow(runMojo::execute); assertTrue(runMojo.getMarker().consumeStarted(), "started marker expected"); docker.waitForLog(Await.await(log, "registries.yaml used"), logs -> logs.stream() - .anyMatch(l -> l.contains("Using private registry config file at /etc/rancher/k3s/registries.yaml"))); + .anyMatch(l -> l.contains("Using private registry config file at /etc/rancher/k3s/registries.yaml")), + DEFAUL_TASK_TIMEOUT); } @DisplayName("with custom registries.yaml (missing)") diff --git a/src/test/java/io/kokuwa/maven/k3s/test/AbstractTest.java b/src/test/java/io/kokuwa/maven/k3s/test/AbstractTest.java index 226e477..0069aed 100644 --- a/src/test/java/io/kokuwa/maven/k3s/test/AbstractTest.java +++ b/src/test/java/io/kokuwa/maven/k3s/test/AbstractTest.java @@ -9,6 +9,7 @@ import java.net.http.HttpClient.Version; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.time.Duration; import org.apache.maven.plugin.MojoExecutionException; import org.junit.jupiter.api.AfterEach; @@ -31,15 +32,17 @@ @TestMethodOrder(MethodOrderer.DisplayName.class) public abstract class AbstractTest { + public static final Duration DEFAUL_TASK_TIMEOUT = Duration.ofSeconds(30); + public Docker docker; @BeforeEach @AfterEach void reset(Docker newDocker) throws MojoExecutionException { this.docker = newDocker; - this.docker.removeContainer(); - this.docker.removeVolume(); - this.docker.removeImage(helloWorld()); + this.docker.removeContainer(DEFAUL_TASK_TIMEOUT); + this.docker.removeVolume(DEFAUL_TASK_TIMEOUT); + this.docker.removeImage(helloWorld(), DEFAUL_TASK_TIMEOUT); LoggerCapturer.clear(); } diff --git a/src/test/java/io/kokuwa/maven/k3s/util/DockerTest.java b/src/test/java/io/kokuwa/maven/k3s/util/DockerTest.java index 195ef3d..94f08b6 100644 --- a/src/test/java/io/kokuwa/maven/k3s/util/DockerTest.java +++ b/src/test/java/io/kokuwa/maven/k3s/util/DockerTest.java @@ -32,46 +32,47 @@ public class DockerTest extends AbstractTest { @Test void volume() throws MojoExecutionException { - assertFalse(docker.getVolume().isPresent(), "volume found before testing"); - docker.removeVolume(); + assertFalse(docker.getVolume(DEFAUL_TASK_TIMEOUT).isPresent(), "volume found before testing"); + docker.removeVolume(DEFAUL_TASK_TIMEOUT); - docker.createVolume(); - assertTrue(docker.getVolume().isPresent(), "volume missing after creating"); + docker.createVolume(DEFAUL_TASK_TIMEOUT); + assertTrue(docker.getVolume(DEFAUL_TASK_TIMEOUT).isPresent(), "volume missing after creating"); - docker.removeVolume(); - assertFalse(docker.getVolume().isPresent(), "volume found after removing"); + docker.removeVolume(DEFAUL_TASK_TIMEOUT); + assertFalse(docker.getVolume(DEFAUL_TASK_TIMEOUT).isPresent(), "volume found after removing"); } @DisplayName("container handling") @Test void container(Logger log) throws MojoExecutionException { - assertFalse(docker.getContainer().isPresent(), "container found before testing"); - docker.removeContainer(); + assertFalse(docker.getContainer(DEFAUL_TASK_TIMEOUT).isPresent(), "container found before testing"); + docker.removeContainer(DEFAUL_TASK_TIMEOUT); var ports = List.of("9001:9001", "9002:9002"); - docker.createVolume(); - docker.createContainer("rancher/k3s", ports, List.of("server"), null); - assertTrue(docker.getContainer().isPresent(), "container not found after creating"); - assertTrue(docker.getContainer().map(Container::isRunning).orElse(null)); - docker.waitForLog(Await.await(log, "k3s"), o -> o.stream().anyMatch(l -> l.contains("k3s is up and running"))); - - docker.removeContainer(); - assertFalse(docker.getContainer().isPresent(), "container found after removing"); + docker.createVolume(DEFAUL_TASK_TIMEOUT); + docker.createContainer("rancher/k3s", ports, List.of("server"), null, DEFAUL_TASK_TIMEOUT); + assertTrue(docker.getContainer(DEFAUL_TASK_TIMEOUT).isPresent(), "container not found after creating"); + assertTrue(docker.getContainer(DEFAUL_TASK_TIMEOUT).map(Container::isRunning).orElse(null)); + docker.waitForLog(Await.await(log, "k3s"), o -> o.stream().anyMatch(l -> l.contains("k3s is up and running")), + DEFAUL_TASK_TIMEOUT); + + docker.removeContainer(DEFAUL_TASK_TIMEOUT); + assertFalse(docker.getContainer(DEFAUL_TASK_TIMEOUT).isPresent(), "container found after removing"); } @DisplayName("image handling") @Test void image() throws MojoExecutionException { - assertFalse(docker.getImage(helloWorld()).isPresent(), "image found before testing"); - docker.removeImage(helloWorld()); + assertFalse(docker.getImage(helloWorld(), DEFAUL_TASK_TIMEOUT).isPresent(), "image found before testing"); + docker.removeImage(helloWorld(), DEFAUL_TASK_TIMEOUT); docker.pullImage(helloWorld(), Duration.ofSeconds(30)); - assertTrue(docker.getImage(helloWorld()).isPresent(), "image missing after pulling"); + assertTrue(docker.getImage(helloWorld(), DEFAUL_TASK_TIMEOUT).isPresent(), "image missing after pulling"); - docker.removeImage(helloWorld()); - assertFalse(docker.getImage(helloWorld()).isPresent(), "image found after removing"); + docker.removeImage(helloWorld(), DEFAUL_TASK_TIMEOUT); + assertFalse(docker.getImage(helloWorld(), DEFAUL_TASK_TIMEOUT).isPresent(), "image found after removing"); } @DisplayName("normalizeImage()") @@ -107,8 +108,8 @@ void copy() throws MojoExecutionException, IOException { // start container - docker.createVolume(); - docker.createContainer("rancher/k3s", List.of(), List.of("server"), null); + docker.createVolume(DEFAUL_TASK_TIMEOUT); + docker.createContainer("rancher/k3s", List.of(), List.of("server"), null, DEFAUL_TASK_TIMEOUT); // define test data @@ -126,8 +127,8 @@ void copy() throws MojoExecutionException, IOException { Files.deleteIfExists(sourceFile); Files.deleteIfExists(returnFile); Files.write(sourceFile, initialContent.toString().getBytes()); - docker.copyToContainer(sourceDir, containerDir.toString()); - docker.copyFromContainer(containerDir.toString(), returnDir); + docker.copyToContainer(sourceDir, containerDir.toString(), DEFAUL_TASK_TIMEOUT); + docker.copyFromContainer(containerDir.toString(), returnDir, DEFAUL_TASK_TIMEOUT); assertEquals(initialContent, Files.readString(returnFile)); // write changed file and copy to container @@ -136,8 +137,8 @@ void copy() throws MojoExecutionException, IOException { Files.deleteIfExists(sourceFile); Files.deleteIfExists(returnFile); Files.write(sourceFile, changedContent.toString().getBytes()); - docker.copyToContainer(sourceDir, containerDir.toString()); - docker.copyFromContainer(containerDir.toString(), returnDir); + docker.copyToContainer(sourceDir, containerDir.toString(), DEFAUL_TASK_TIMEOUT); + docker.copyFromContainer(containerDir.toString(), returnDir, DEFAUL_TASK_TIMEOUT); assertEquals(changedContent, Files.readString(returnFile)); } }