Skip to content

Commit

Permalink
fix: add timeout for docker info read to prevent Jib from getting stu…
Browse files Browse the repository at this point in the history
…ck indefinitely (#4319)

* fix: address nightly build failure with dockerBuild; add timeout for docker info read
  • Loading branch information
mpeddada1 authored Oct 25, 2024
1 parent 68f8947 commit aac44d3
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Function;

Expand Down Expand Up @@ -103,6 +109,12 @@ public List<DescriptorDigest> getDiffIds() throws DigestException {
/** Default path to the docker executable. */
public static final Path DEFAULT_DOCKER_CLIENT = Paths.get("docker");

/**
* 10 minute timeout to ensure that Jib doesn't get stuck indefinitely when expecting a docker
* output.
*/
public static final Long DOCKER_OUTPUT_TIMEOUT = (long) 10 * 60 * 1000;

/**
* Checks if Docker is installed on the user's system by running the `docker` command.
*
Expand Down Expand Up @@ -188,13 +200,19 @@ public boolean supported(Map<String, String> parameters) {
@Override
public DockerInfoDetails info() throws IOException, InterruptedException {
// Runs 'docker info'.
Process infoProcess = docker("info", "-f", "{{json .}}");
InputStream inputStream = infoProcess.getInputStream();
if (infoProcess.waitFor() != 0) {
throw new IOException(
"'docker info' command failed with error: " + getStderrOutput(infoProcess));
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<DockerInfoDetails> readerFuture = executor.submit(this::fetchInfoDetails);
try {
DockerInfoDetails details = readerFuture.get(DOCKER_OUTPUT_TIMEOUT, TimeUnit.MILLISECONDS);
return details;
} catch (TimeoutException e) {
readerFuture.cancel(true); // Interrupt the reader thread
throw new IOException("Timeout reached while waiting for 'docker info' output");
} catch (ExecutionException e) {
throw new IOException("Failed to read output of 'docker info': " + e.getMessage());
} finally {
executor.shutdownNow();
}
return JsonTemplateMapper.readJson(inputStream, DockerInfoDetails.class);
}

@Override
Expand Down Expand Up @@ -270,4 +288,14 @@ public DockerImageDetails inspect(ImageReference imageReference)
private Process docker(String... subCommand) throws IOException {
return processBuilderFactory.apply(Arrays.asList(subCommand)).start();
}

private DockerInfoDetails fetchInfoDetails() throws IOException, InterruptedException {
Process infoProcess = docker("info", "-f", "{{json .}}");
InputStream inputStream = infoProcess.getInputStream();
if (infoProcess.waitFor() != 0) {
throw new IOException(
"'docker info' command failed with error: " + getStderrOutput(infoProcess));
}
return JsonTemplateMapper.readJson(inputStream, DockerInfoDetails.class);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#!/bin/bash

if [[ "$1" == "info" ]]; then
# Output the JSON string
echo "{\"OSType\":\"linux\",\"Architecture\":\"x86_64\"}"
exit 0
fi

# Read stdin to avoid broken pipe
cat > /dev/null

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#!/bin/bash

if [[ "$1" == "info" ]]; then
# Output the JSON string
echo "{\"OSType\":\"linux\",\"Architecture\":\"x86_64\"}"
exit 0
fi

# Read stdin to avoid broken pipe
cat > /dev/null

Expand Down

0 comments on commit aac44d3

Please sign in to comment.