diff --git a/src/main/java/com/github/dockerjava/core/AuthConfigFile.java b/src/main/java/com/github/dockerjava/core/AuthConfigFile.java index 1b61ff6e0..2ecb34c2e 100644 --- a/src/main/java/com/github/dockerjava/core/AuthConfigFile.java +++ b/src/main/java/com/github/dockerjava/core/AuthConfigFile.java @@ -110,24 +110,29 @@ public static AuthConfigFile loadConfig(File confFile) throws IOException { } Map configMap = null; - /* - Registry v2 expects config expects config.json while v2 expects .dockercfg - The only difference between them is that config.json wraps "auths" around the AuthConfig - */ - try { - // try registry version 2 - final ObjectNode node = filterNonAuthsFromJSON(confFile); - Map> configJson = MAPPER.convertValue(node, CONFIG_JSON_MAP_TYPE); - if (configJson != null && !configJson.isEmpty()) { - configMap = configJson.get(AUTHS_PROPERTY); - } - - } catch (IOException e1) { + if (isJSONFile(confFile)) { + /* + Registry v2 expects config expects config.json while v2 expects .dockercfg + The only difference between them is that config.json wraps "auths" around the AuthConfig + */ try { - // try registry version 1 - configMap = MAPPER.readValue(confFile, CONFIG_CFG_MAP_TYPE); - } catch (IOException e2) { - // pass + // try registry version 2 + final ObjectNode node = filterNonAuthsFromJSON(confFile); + Map> configJson = MAPPER.convertValue(node, CONFIG_JSON_MAP_TYPE); + if (configJson != null && !configJson.isEmpty()) { + configMap = configJson.get(AUTHS_PROPERTY); + } + + } catch (IOException e1) { + try { + // try registry version 1 + configMap = MAPPER.readValue(confFile, CONFIG_CFG_MAP_TYPE); + } catch (IOException e2) { + // we know it is JSON so it does not make sense to check for the old format + // probably Docker writes some unstructured contents here, see #806 + // at least it is not worse than the totally absent file + return new AuthConfigFile(); + } } } @@ -165,6 +170,14 @@ public static AuthConfigFile loadConfig(File confFile) throws IOException { } + private static boolean isJSONFile(final File confFile) { + try { + return MAPPER.readValue(confFile, ObjectNode.class) != null; + } catch (IOException e) { + return false; + } + } + private static ObjectNode filterNonAuthsFromJSON(final File confFile) throws IOException { final ObjectNode node = MAPPER.readValue(confFile, ObjectNode.class); if (!node.has(AUTHS_PROPERTY)) { diff --git a/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java b/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java index cbb01de08..5f5805555 100644 --- a/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java +++ b/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java @@ -81,6 +81,13 @@ public void validJsonWithUnknown() throws IOException { runTest("validJsonWithUnknown.json"); } + @Test + public void validJsonWithOnlyUnknown() throws IOException { + AuthConfigFile expected = new AuthConfigFile(); + AuthConfigFile actual = runTest("validJsonWithOnlyUnknown.json"); + Assert.assertEquals(actual, expected); + } + @Test public void validLegacy() throws IOException { AuthConfig authConfig = new AuthConfig() diff --git a/src/test/resources/testAuthConfigFile/validJsonWithOnlyUnknown.json b/src/test/resources/testAuthConfigFile/validJsonWithOnlyUnknown.json new file mode 100644 index 000000000..cd5f7a124 --- /dev/null +++ b/src/test/resources/testAuthConfigFile/validJsonWithOnlyUnknown.json @@ -0,0 +1,3 @@ +{ + "credsStore" : "osxkeychain" +}