Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Docker authentiation using credential store/helpers #647

Closed
wants to merge 12 commits into from

Conversation

rnorth
Copy link
Member

@rnorth rnorth commented Apr 18, 2018

Not quite ready for review yet, but nearly.

This change adds support for docker's credential store/helper mechanism.

The main gap at the moment is Windows support; it may work, but I've not tried it. The tests so far definitely don't work on Windows.

Copy link
Member

@bsideup bsideup left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍 wow, will be so cool to have it once we figure out the edge cases!

CHANGELOG.md Outdated
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
- Fixed missing `commons-codec` dependency ([\#642](https://github.com/testcontainers/testcontainers-java/issues/642))
- Fixed `HostPortWaitStrategy` throws `NumberFormatException` when port is exposed but not mapped ([\#640](https://github.com/testcontainers/testcontainers-java/issues/640))
- Fixed log processing: multibyte unicode, linebreaks and ASCII color codes. Color codes can be turned on with `withRemoveAnsiCodes(false)` ([PR \#643](https://github.com/testcontainers/testcontainers-java/pull/643))
- Add support for private repositories using docker credential stores/helpers (fixes [\#567](https://github.com/testcontainers/testcontainers-java/issues/567))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aren't we link PRs here? :) Maybe next to "fixes" part, useful to check what was changed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep

* @param defaultAuthConfig an AuthConfig object that should be returned if there is no overriding authentication
* available for images that are looked up
*/
public RegistryAuthLocator(AuthConfig defaultAuthConfig) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this ctor should call

this(defaultAuthConfig, new File(System.getProperty("user.home") + "/.docker/config.json"), "")

*/
public RegistryAuthLocator(AuthConfig defaultAuthConfig) {
this.defaultAuthConfig = defaultAuthConfig;
this.configFile = new File(System.getProperty("user.home") + "/.docker/config.json");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/moby/moby/blob/131e2bf12b2e1b3ee31b628a501f96bbb901f479/cliconfig/config.go#L29

it seems that the location is configurable. Not sure we can detect it tho

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well... I guess we can do a best-efforts detection of the location using the DOCKER_CONFIG env var. I'll add that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See also DefaultDockerClientConfig::dockerConfigPath field


private AuthConfig authConfigUsingCredentialsStoreOrHelper(String hostName, JsonNode config) throws Exception {

final String credsStoreName = config.at("/credsStore").asText();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI asText() returns "null" instead of null when it's null :)

Also, config.path("/credsStore") should be faster (doesn't parse the json path, but keeps the null safety by returning a missing node), but not critical here :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - will update

@bsideup bsideup added this to the next milestone Apr 20, 2018
@rnorth rnorth force-pushed the credential-helpers branch 2 times, most recently from eb5558b to c8dfeee Compare April 30, 2018 08:16
@bsideup bsideup removed this from the next milestone Apr 30, 2018
@rnorth rnorth force-pushed the credential-helpers branch 2 times, most recently from 5c8f9e6 to 56217da Compare April 30, 2018 17:33
@rnorth
Copy link
Member Author

rnorth commented Apr 30, 2018

I'll try and test this on Windows tonight, then I think we should be good to go.

@rnorth rnorth added this to the next milestone Apr 30, 2018
@bsideup bsideup modified the milestone: next Apr 30, 2018
@bsideup bsideup removed this from the next milestone May 16, 2018
@rnorth
Copy link
Member Author

rnorth commented May 18, 2018

I've added the help wanted label because:

  • I've not been able to test this on Windows yet, and if a Windows user has time to test, and revise/add to the JUnit tests for this feature, we can ship this quicker
  • I'm aware that this will not work with docker-compose in anything other than 'local compose' mode. This doesn't feel like a blocker to me (we could address this later) but if anyone has thoughts on this limitation or ways to address it'd be good to hear.

@bsideup
Copy link
Member

bsideup commented May 18, 2018

@rnorth Remember our discussion about containerised Compose? Maybe this is a great moment to finally make a decision and remove it? :)

@kiview
Copy link
Member

kiview commented May 18, 2018

I'd be fine with removing dockerized compose, it promises to be easy for user, but it adds a lot of additional hidden complexity, which can lead to strange edge cases.

I can test this on Windows this weekend though :)

final String reposName = dockerImageName.getRegistry();
final JsonNode auths = config.at("/auths/" + reposName);

if (!auths.isMissingNode() && auths.size() == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested this with Docker-for-Mac, works perfectly fine if changed to || here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if !auths.isMissingNode() is needed here, maybe just auths.size() == 0 is enough?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked Jackson source code, should be safe to leave size() == 0 only, but I do not think it matters that much, leaving both of them should be fine too.

@TheIndifferent
Copy link
Contributor

Small comment on how to make it work with Docker-for-Mac, other than that works like charm! So, gentle ping to continue the progress :)

@TheIndifferent
Copy link
Contributor

I tried to test this on Windows myself, but seems like Docker-for-Windows does not work on official MSEdge - Win10 for VirtualBox. @kiview all hopes is on you now.

@TheIndifferent TheIndifferent mentioned this pull request Jun 4, 2018
@rnorth
Copy link
Member Author

rnorth commented Jun 10, 2018

Closed in favour of #729

@rnorth rnorth closed this Jun 10, 2018
rnorth pushed a commit that referenced this pull request Jun 16, 2018
See also #647 for previous discussions.
@rnorth rnorth deleted the credential-helpers branch October 8, 2018 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants