1212import org .testcontainers .DockerClientFactory ;
1313import org .zeroturnaround .exec .InvalidResultException ;
1414import org .zeroturnaround .exec .ProcessExecutor ;
15+ import org .zeroturnaround .exec .stream .LogOutputStream ;
1516
1617import java .io .ByteArrayInputStream ;
1718import java .io .File ;
@@ -273,7 +274,7 @@ private AuthConfig runCredentialProvider(String hostName, String helperOrStoreNa
273274 }
274275
275276 final String credentialProgramName = getCredentialProgramName (helperOrStoreName );
276- final String data ;
277+ final CredentialOutput data ;
277278
278279 log .debug (
279280 "Executing docker credential provider: {} to locate auth config for: {}" ,
@@ -283,37 +284,38 @@ private AuthConfig runCredentialProvider(String hostName, String helperOrStoreNa
283284
284285 try {
285286 data = runCredentialProgram (hostName , credentialProgramName );
286- } catch (InvalidResultException e ) {
287- final String responseErrorMsg = extractCredentialProviderErrorMessage (e );
288-
289- if (!StringUtils .isBlank (responseErrorMsg )) {
290- String credentialsNotFoundMsg = getGenericCredentialsNotFoundMsg (credentialProgramName );
291- if (credentialsNotFoundMsg != null && credentialsNotFoundMsg .equals (responseErrorMsg )) {
292- log .info (
293- "Credential helper/store ({}) does not have credentials for {}" ,
287+ if (data .getStderr () != null && !data .getStderr ().isEmpty ()) {
288+ final String responseErrorMsg = data .getStderr ();
289+
290+ if (!StringUtils .isBlank (responseErrorMsg )) {
291+ String credentialsNotFoundMsg = getGenericCredentialsNotFoundMsg (credentialProgramName );
292+ if (credentialsNotFoundMsg != null && credentialsNotFoundMsg .equals (responseErrorMsg )) {
293+ log .info (
294+ "Credential helper/store ({}) does not have credentials for {}" ,
295+ credentialProgramName ,
296+ hostName
297+ );
298+
299+ return null ;
300+ }
301+
302+ log .debug (
303+ "Failure running docker credential helper/store ({}) with output '{}'" ,
294304 credentialProgramName ,
295- hostName
305+ responseErrorMsg
296306 );
297-
298- return null ;
307+ } else {
308+ log . debug ( "Failure running docker credential helper/store ({})" , credentialProgramName ) ;
299309 }
300310
301- log .debug (
302- "Failure running docker credential helper/store ({}) with output '{}'" ,
303- credentialProgramName ,
304- responseErrorMsg
305- );
306- } else {
307- log .debug ("Failure running docker credential helper/store ({})" , credentialProgramName );
311+ throw new InvalidResultException (data .getStderr (), null );
308312 }
309-
310- throw e ;
311313 } catch (Exception e ) {
312314 log .debug ("Failure running docker credential helper/store ({})" , credentialProgramName );
313315 throw e ;
314316 }
315317
316- final JsonNode helperResponse = OBJECT_MAPPER .readTree (data );
318+ final JsonNode helperResponse = OBJECT_MAPPER .readTree (data . getStdout () );
317319 log .debug ("Credential helper/store provided auth config for: {}" , hostName );
318320
319321 final String username = helperResponse .at ("/Username" ).asText ();
@@ -363,55 +365,81 @@ private String discoverCredentialsHelperNotFoundMessage(String credentialHelperN
363365
364366 String credentialsNotFoundMsg = null ;
365367 try {
366- runCredentialProgram (notExistentFakeHostName , credentialHelperName );
368+ CredentialOutput data = runCredentialProgram (notExistentFakeHostName , credentialHelperName );
367369
368- // should not reach here
369- log .warn (
370- "Failure running docker credential helper ({}) with fake call, expected 'credentials not found' response" ,
371- credentialHelperName
372- );
373- } catch (Exception e ) {
374- if (e instanceof InvalidResultException ) {
375- credentialsNotFoundMsg = extractCredentialProviderErrorMessage ((InvalidResultException ) e );
376- }
370+ if (data .getStderr () != null && !data .getStderr ().isEmpty ()) {
371+ credentialsNotFoundMsg = data .getStderr ();
377372
378- if (StringUtils .isBlank (credentialsNotFoundMsg )) {
379- log .warn (
380- "Failure running docker credential helper ({}) with fake call, expected 'credentials not found' response. Exception message: {}" ,
381- credentialHelperName ,
382- e .getMessage ()
383- );
384- } else {
385373 log .debug (
386374 "Got credentials not found error message from docker credential helper - {}" ,
387375 credentialsNotFoundMsg
388376 );
389377 }
378+ } catch (Exception e ) {
379+ log .warn (
380+ "Failure running docker credential helper ({}) with fake call, expected 'credentials not found' response. Exception message: {}" ,
381+ credentialHelperName ,
382+ e .getMessage ()
383+ );
390384 }
391385
392386 return credentialsNotFoundMsg ;
393387 }
394388
395- private String extractCredentialProviderErrorMessage (InvalidResultException invalidResultEx ) {
396- if (invalidResultEx .getResult () != null && invalidResultEx .getResult ().hasOutput ()) {
397- return invalidResultEx .getResult ().outputString ().trim ();
398- }
399- return null ;
400- }
401-
402- private String runCredentialProgram (String hostName , String credentialHelperName )
403- throws InvalidResultException , InterruptedException , TimeoutException , IOException {
389+ private CredentialOutput runCredentialProgram (String hostName , String credentialHelperName )
390+ throws InterruptedException , TimeoutException , IOException {
404391 String [] command = SystemUtils .IS_OS_WINDOWS
405392 ? new String [] { "cmd" , "/c" , credentialHelperName , "get" }
406393 : new String [] { credentialHelperName , "get" };
407- return new ProcessExecutor ()
408- .command (command )
409- .redirectInput (new ByteArrayInputStream (hostName .getBytes ()))
410- .readOutput (true )
411- .exitValueNormal ()
412- .timeout (30 , TimeUnit .SECONDS )
413- .execute ()
414- .outputUTF8 ()
415- .trim ();
394+
395+ StringBuffer stdout = new StringBuffer ();
396+ StringBuffer stderr = new StringBuffer ();
397+
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+ }
408+ }
409+ )
410+ .redirectError (
411+ new LogOutputStream () {
412+ @ Override
413+ protected void processLine (String line ) {
414+ stderr .append (line ).append (System .lineSeparator ());
415+ }
416+ }
417+ )
418+ .exitValueNormal ()
419+ .timeout (30 , TimeUnit .SECONDS )
420+ .execute ();
421+ } catch (InvalidResultException e ) {}
422+
423+ return new CredentialOutput (stdout .toString (), stderr .toString ());
424+ }
425+
426+ static class CredentialOutput {
427+
428+ private final String stdout ;
429+
430+ private final String stderr ;
431+
432+ public CredentialOutput (String stdout , String stderr ) {
433+ this .stdout = stdout .trim ();
434+ this .stderr = stderr .trim ();
435+ }
436+
437+ public String getStdout () {
438+ return this .stdout ;
439+ }
440+
441+ public String getStderr () {
442+ return this .stderr ;
443+ }
416444 }
417445}
0 commit comments