fix(podman): do not pass the tag directly to pullImageCmd (withTag) (#9607)

This commit is contained in:
François Delbrayelle
2025-06-18 18:05:16 +02:00
committed by GitHub
parent 185fa80058
commit a981a309d6
3 changed files with 51 additions and 6 deletions

View File

@@ -398,7 +398,7 @@ public class Docker extends TaskRunner<Docker.DockerTaskRunnerDetailResult> {
String remotePath = windowsToUnixPath(taskCommands.getWorkingDirectory().toString());
// first, create an archive
Path fileArchive = runContext.workingDir().createFile("inputFiles.tart");
Path fileArchive = runContext.workingDir().createFile("inputFiles.tar");
try (FileOutputStream fos = new FileOutputStream(fileArchive.toString());
TarArchiveOutputStream out = new TarArchiveOutputStream(fos)) {
out.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); // allow long file name
@@ -827,8 +827,23 @@ public class Docker extends TaskRunner<Docker.DockerTaskRunnerDetailResult> {
.longValue();
}
private String getImageNameWithoutTag(String fullImageName) {
if (fullImageName == null || fullImageName.isEmpty()) {
return fullImageName;
}
int lastColonIndex = fullImageName.lastIndexOf(':');
int firstSlashIndex = fullImageName.indexOf('/');
if (lastColonIndex > -1 && (firstSlashIndex == -1 || lastColonIndex > firstSlashIndex)) {
return fullImageName.substring(0, lastColonIndex);
} else {
return fullImageName; // No tag found or the colon is part of the registry host
}
}
private void pullImage(DockerClient dockerClient, String image, PullPolicy policy, Logger logger) {
NameParser.ReposTag imageParse = NameParser.parseRepositoryTag(image);
var imageNameWithoutTag = getImageNameWithoutTag(image);
var parsedTagFromImage = NameParser.parseRepositoryTag(image);
if (policy.equals(PullPolicy.IF_NOT_PRESENT)) {
try {
@@ -839,7 +854,9 @@ public class Docker extends TaskRunner<Docker.DockerTaskRunnerDetailResult> {
}
}
try (PullImageCmd pull = dockerClient.pullImageCmd(image)) {
// pullImageCmd without the tag (= repository) to avoid being redundant with withTag below
// and prevent errors with Podman trying to pull "image:tag:tag"
try (var pull = dockerClient.pullImageCmd(imageNameWithoutTag)) {
new RetryUtils().<Boolean, InternalServerErrorException>of(
Exponential.builder()
.delayFactor(2.0)
@@ -851,8 +868,8 @@ public class Docker extends TaskRunner<Docker.DockerTaskRunnerDetailResult> {
(bool, throwable) -> throwable instanceof InternalServerErrorException ||
throwable.getCause() instanceof ConnectionClosedException,
() -> {
String tag = !imageParse.tag.isEmpty() ? imageParse.tag : "latest";
String repository = pull.getRepository().contains(":") ? pull.getRepository().split(":")[0] : pull.getRepository();
var tag = !parsedTagFromImage.tag.isEmpty() ? parsedTagFromImage.tag : "latest";
var repository = pull.getRepository().contains(":") ? pull.getRepository().split(":")[0] : pull.getRepository();
pull
.withTag(tag)
.exec(new PullImageResultCallback())

View File

@@ -1,12 +1,40 @@
package io.kestra.plugin.scripts.runner.docker;
import io.kestra.core.models.property.Property;
import io.kestra.core.models.tasks.runners.AbstractTaskRunnerTest;
import io.kestra.core.models.tasks.runners.TaskRunner;
import io.kestra.plugin.scripts.exec.scripts.runners.CommandsWrapper;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
class DockerTest extends AbstractTaskRunnerTest {
@Override
protected TaskRunner<?> taskRunner() {
return Docker.builder().image("rockylinux:9.3-minimal").build();
}
@Test
void shouldNotHaveTagInDockerPullButJustInWithTag() throws Exception {
var runContext = runContext(this.runContextFactory);
var docker = Docker.builder()
.image("ghcr.io/kestra-io/kestrapy:latest")
.pullPolicy(Property.ofValue(PullPolicy.ALWAYS))
.build();
var taskCommands = new CommandsWrapper(runContext).withCommands(Property.ofValue(List.of(
"/bin/sh", "-c",
"echo Hello World!"
)));
var result = docker.run(runContext, taskCommands, Collections.emptyList());
assertThat(result).isNotNull();
assertThat(result.getExitCode()).isZero();
Assertions.assertThat(result.getLogConsumer().getStdOutCount()).isEqualTo(1);
}
}

View File

@@ -32,7 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
public abstract class AbstractTaskRunnerTest {
@Inject private TestRunContextFactory runContextFactory;
@Inject protected TestRunContextFactory runContextFactory;
@Inject private StorageInterface storage;
@Test