Skip to content

Commit 964c6e6

Browse files
authored
Fix docker credentials output (#9544)
In #8007, docker credentials stdout and stderr are separated and stderr has been used to display error messages. However, docker credentials writes error messages to stdout. This commit, read the process execution exit value for better handling and read stdout for error messages. Fixes #9478
1 parent c01fc1b commit 964c6e6

File tree

3 files changed

+44
-37
lines changed

3 files changed

+44
-37
lines changed

core/src/main/java/org/testcontainers/utility/RegistryAuthLocator.java

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.testcontainers.DockerClientFactory;
1313
import org.zeroturnaround.exec.InvalidResultException;
1414
import org.zeroturnaround.exec.ProcessExecutor;
15+
import org.zeroturnaround.exec.ProcessResult;
1516
import org.zeroturnaround.exec.stream.LogOutputStream;
1617

1718
import java.io.ByteArrayInputStream;
@@ -284,8 +285,8 @@ private AuthConfig runCredentialProvider(String hostName, String helperOrStoreNa
284285

285286
try {
286287
data = runCredentialProgram(hostName, credentialProgramName);
287-
if (data.getStderr() != null && !data.getStderr().isEmpty()) {
288-
final String responseErrorMsg = data.getStderr();
288+
if (data.getExitValue() == 1) {
289+
final String responseErrorMsg = data.getStdout();
289290

290291
if (!StringUtils.isBlank(responseErrorMsg)) {
291292
String credentialsNotFoundMsg = getGenericCredentialsNotFoundMsg(credentialProgramName);
@@ -300,15 +301,16 @@ private AuthConfig runCredentialProvider(String hostName, String helperOrStoreNa
300301
}
301302

302303
log.debug(
303-
"Failure running docker credential helper/store ({}) with output '{}'",
304+
"Failure running docker credential helper/store ({}) with output '{}' and error '{}'",
304305
credentialProgramName,
305-
responseErrorMsg
306+
responseErrorMsg,
307+
data.getStderr()
306308
);
307309
} else {
308310
log.debug("Failure running docker credential helper/store ({})", credentialProgramName);
309311
}
310312

311-
throw new InvalidResultException(data.getStderr(), null);
313+
throw new InvalidResultException(data.getStdout(), null);
312314
}
313315
} catch (Exception e) {
314316
log.debug("Failure running docker credential helper/store ({})", credentialProgramName);
@@ -367,8 +369,8 @@ private String discoverCredentialsHelperNotFoundMessage(String credentialHelperN
367369
try {
368370
CredentialOutput data = runCredentialProgram(notExistentFakeHostName, credentialHelperName);
369371

370-
if (data.getStderr() != null && !data.getStderr().isEmpty()) {
371-
credentialsNotFoundMsg = data.getStderr();
372+
if (data.getStdout() != null && !data.getStdout().isEmpty()) {
373+
credentialsNotFoundMsg = data.getStdout();
372374

373375
log.debug(
374376
"Got credentials not found error message from docker credential helper - {}",
@@ -395,50 +397,55 @@ private CredentialOutput runCredentialProgram(String hostName, String credential
395397
StringBuffer stdout = new StringBuffer();
396398
StringBuffer stderr = new StringBuffer();
397399

398-
try {
399-
new ProcessExecutor()
400-
.command(command)
401-
.redirectInput(new ByteArrayInputStream(hostName.getBytes()))
402-
.redirectOutput(
403-
new LogOutputStream() {
404-
@Override
405-
protected void processLine(String line) {
406-
stdout.append(line).append(System.lineSeparator());
407-
}
400+
ProcessResult processResult = new ProcessExecutor()
401+
.command(command)
402+
.redirectInput(new ByteArrayInputStream(hostName.getBytes()))
403+
.redirectOutput(
404+
new LogOutputStream() {
405+
@Override
406+
protected void processLine(String line) {
407+
stdout.append(line).append(System.lineSeparator());
408408
}
409-
)
410-
.redirectError(
411-
new LogOutputStream() {
412-
@Override
413-
protected void processLine(String line) {
414-
stderr.append(line).append(System.lineSeparator());
415-
}
409+
}
410+
)
411+
.redirectError(
412+
new LogOutputStream() {
413+
@Override
414+
protected void processLine(String line) {
415+
stderr.append(line).append(System.lineSeparator());
416416
}
417-
)
418-
.exitValueNormal()
419-
.timeout(30, TimeUnit.SECONDS)
420-
.execute();
421-
} catch (InvalidResultException e) {}
417+
}
418+
)
419+
.timeout(30, TimeUnit.SECONDS)
420+
.execute();
421+
int exitValue = processResult.getExitValue();
422422

423-
return new CredentialOutput(stdout.toString(), stderr.toString());
423+
return new CredentialOutput(exitValue, stdout.toString(), stderr.toString());
424424
}
425425

426426
static class CredentialOutput {
427427

428+
private final int exitValue;
429+
428430
private final String stdout;
429431

430432
private final String stderr;
431433

432-
public CredentialOutput(String stdout, String stderr) {
434+
public CredentialOutput(int exitValue, String stdout, String stderr) {
435+
this.exitValue = exitValue;
433436
this.stdout = stdout.trim();
434437
this.stderr = stderr.trim();
435438
}
436439

437-
public String getStdout() {
440+
int getExitValue() {
441+
return this.exitValue;
442+
}
443+
444+
String getStdout() {
438445
return this.stdout;
439446
}
440447

441-
public String getStderr() {
448+
String getStderr() {
442449
return this.stderr;
443450
}
444451
}

core/src/test/resources/auth-config/docker-credential-fake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ fi
77
read inputLine
88

99
if [ "$inputLine" = "registry2.example.com" ]; then
10-
echo Fake credentials not found on credentials store \'$inputLine\' 1>&2
10+
echo Fake credentials not found on credentials store \'$inputLine\' 0>&2
1111
exit 1
1212
fi
1313
if [ "$inputLine" = "https://not.a.real.registry/url" ]; then
14-
echo Fake credentials not found on credentials store \'$inputLine\' 1>&2
14+
echo Fake credentials not found on credentials store \'$inputLine\' 0>&2
1515
exit 1
1616
fi
1717

core/src/test/resources/auth-config/win/docker-credential-fake.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ if not "%1" == "get" (
66
set /p inputLine=""
77

88
if "%inputLine%" == "registry2.example.com" (
9-
echo Fake credentials not found on credentials store '%inputLine%' 1>&2
9+
echo Fake credentials not found on credentials store '%inputLine%' 0>&2
1010
exit 1
1111
)
1212
if "%inputLine%" == "https://not.a.real.registry/url" (
13-
echo Fake credentials not found on credentials store '%inputLine%' 1>&2
13+
echo Fake credentials not found on credentials store '%inputLine%' 0>&2
1414
exit 1
1515
)
1616

0 commit comments

Comments
 (0)