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

feat: support reading Docker host from the current Docker context #2810

Open
wants to merge 56 commits into
base: main
Choose a base branch
from

Conversation

mdelapenya
Copy link
Member

@mdelapenya mdelapenya commented Oct 2, 2024

  • feat: support reading Docker context
  • chore: move read Docker config to the core
  • chore: read docker config more consistently
  • chore: extract to a parse function to detect remote docker hosts
  • docs: add Docker context to docs

What does this PR do?

This PR adds a new step in the Docekr host discovery algorithm, extracting the Docker host from the current Docker context. To achieve that, we are copying code from the docker/cli project,
as we don't want to receive all the dependencies from that project (please see docker_context.go file). In the end, it just does the following:

  • list all contexts from the default location: docker config path / context / meta / contextA / meta.json
  • get the current context from the docker config, located at docker config path / config.json
  • read the meta.json file for the current context, extracting the host endpoint
  • use that host endpoint for the Docker Host.

NOTE: The default docker config path lives in $HOME/.docker.

This PR also reduces the complexity in discovering the default bridge network, so instead of having to detect if a network named Bridge exists, it simply delegates to the container runtime to detect it under the hood.

Why is it important?

It will simplify the experience using different container runtimes, as this change means that with just setting the current context, testcontainers-go will use that container runtime.

@mdelapenya mdelapenya added the feature New functionality or new behaviors on the existing one label Oct 2, 2024
@mdelapenya mdelapenya self-assigned this Oct 2, 2024
@mdelapenya mdelapenya requested a review from stevenh October 2, 2024 15:24
Copy link

netlify bot commented Oct 2, 2024

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit 13934da
🔍 Latest deploy log https://app.netlify.com/sites/testcontainers-go/deploys/6751909473144700088a1713
😎 Deploy Preview https://deploy-preview-2810--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Collaborator

@stevenh stevenh left a comment

Choose a reason for hiding this comment

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

quick first pass with some question,.

internal/core/docker_config.go Outdated Show resolved Hide resolved
docs/features/configuration.md Outdated Show resolved Hide resolved
internal/core/docker_context.go Outdated Show resolved Hide resolved
internal/core/docker_context.go Outdated Show resolved Hide resolved
internal/core/docker_context.go Outdated Show resolved Hide resolved
internal/core/docker_context_test.go Show resolved Hide resolved
internal/core/docker_context_test.go Show resolved Hide resolved
return dockerHost, nil
}

return "", ErrDockerSocketNotSetInDockerContext
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: Is this discarding useful information from the actual error?

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed. Wdyt about this order: return "", errors.Join(ErrDockerSocketNotSetInDockerContext, err)?

Suggested change
return "", ErrDockerSocketNotSetInDockerContext
return "", errors.Join(ErrDockerSocketNotSetInDockerContext, err)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think that would be confusing, I would detect a specific "not found" error from the call and only translate that if needed. If that's not needed I would just return a wrapped straight wrapped error.

Copy link
Member Author

Choose a reason for hiding this comment

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

Wdyt a38a345 ?

internal/core/docker_host_test.go Outdated Show resolved Hide resolved
internal/core/testdata/.docker/config.json Outdated Show resolved Hide resolved
* main:
  chore: use require.(No)Error(t,err) instead of t.Fatal(err) (testcontainers#2851)
  fix: simplify fully-qualified image names (testcontainers#2846)
@mdelapenya mdelapenya mentioned this pull request Oct 28, 2024
* main: (34 commits)
  fix: only upload to sonar on ubuntu-latest (testcontainers#2891)
  fix: build artifact name properly (testcontainers#2890)
  fix: do not run sonar upload when ryuk is disabled (testcontainers#2889)
  fix: update GH actions for uploading/downloading artifacts (testcontainers#2888)
  feat(ci): Enable master moby with rootless (testcontainers#2880)
  fix(redpanda): temporary file use
  chore(deps): bump actions/download-artifact from 3.0.2 to 4.1.8 (testcontainers#2676)
  chore(deps): bump actions/upload-artifact from 3.1.3 to 4.4.3 (testcontainers#2885)
  fix!: port forwarding clean up and make private (testcontainers#2881)
  chore: resolve AWS deprecations for localstack (testcontainers#2879)
  docs: fix new lifecycle hooks section (testcontainers#2875)
  fix: host access port instability (testcontainers#2867)
  feat: add build to life cycle hooks (testcontainers#2653)
  fix: typo in containerd integration (testcontainers#2873)
  chore(deps): bump mkdocs-include-markdown-plugin from 6.0.4 to 6.2.2 (testcontainers#2806)
  chore: use testify instead of t.Error (testcontainers#2871)
  ci: enable perfsprint linter (testcontainers#2872)
  chore(deps): bump mkdocs-markdownextradata-plugin from 0.2.5 to 0.2.6 (testcontainers#2807)
  chore: use testcontainers.RequireContainerExec (testcontainers#2870)
  chore(deps): bump golangci/golangci-lint-action from 6.1.0 to 6.1.1 (testcontainers#2868)
  ...
}

nw, err := p.GetNetwork(ctx, NetworkRequest{Name: defaultNetwork})
nw, err := p.GetNetwork(ctx, NetworkRequest{Name: Bridge})
Copy link
Collaborator

Choose a reason for hiding this comment

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

bug: I believe this will fail on podman as the default network there is not bridge but podman.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope, the podman engine will retrieve the default bridge network, that's why it's fine to remove all the logic we had for calculating the default network.

➜ testcontainers-go (context-support) ✔ podman network ls
NETWORK ID    NAME        DRIVER
2f259bab93aa  podman      bridge
➜ testcontainers-go (context-support) ✔ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
2f259bab93aa   bridge    bridge    local
➜ testcontainers-go (context-support) ✔ 

Copy link
Collaborator

@stevenh stevenh Nov 25, 2024

Choose a reason for hiding this comment

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

But this is filtering for Name = "bridge" not type Driver = "bridge" so essentially its running:

docker network ls -f name=bridge

Does that work on podman?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, I verified this PR against podman, rancher desktop, colima, orbstack, docker, and testcontainers cloud

docker_test.go Outdated Show resolved Hide resolved
docker_test.go Outdated Show resolved Hide resolved
docker_test.go Outdated Show resolved Hide resolved
@@ -1701,7 +1639,7 @@ func TestContainerWithNoUserID(t *testing.T) {
func TestGetGatewayIP(t *testing.T) {
// When using docker compose with DinD mode, and using host port or http wait strategy
// It's need to invoke GetGatewayIP for get the host
provider, err := providerType.GetProvider(WithLogger(TestLogger(t)))
provider, err := ProviderDocker.GetProvider(WithLogger(TestLogger(t)))
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: is the intent to just have one, if so should we rename, also could we avoid exporting this to avoid future breaking changes when we do the client update discussed?

Copy link
Member Author

@mdelapenya mdelapenya Dec 4, 2024

Choose a reason for hiding this comment

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

I didn't want to rename here in this PR, but if we see it's related, I can deprecate the existing DockerProvider type and use RuntimeProvider instead.

var result []string
for _, fi := range fis {
if fi.IsDir() {
if isContextDir(filepath.Join(root, fi.Name())) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: Is this a duplicate check as if we start with root and fi is a directory it should not be possible that this could ever fail?

internal/core/docker_context.go Show resolved Hide resolved
@@ -0,0 +1,328 @@
package core
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: can we check this is all required, as it looks like some types don't seem to be referenced.

Copy link
Member Author

Choose a reason for hiding this comment

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

The only exposed function in this file is GetDockerHostFromCurrentContext, which starts the call to the types and functions here.

internal/core/docker_host.go Outdated Show resolved Hide resolved
internal/core/docker_host.go Outdated Show resolved Hide resolved
internal/config/config.go Outdated Show resolved Hide resolved
internal/config/config.go Show resolved Hide resolved
internal/config/config.go Outdated Show resolved Hide resolved
internal/core/docker_host.go Outdated Show resolved Hide resolved
* main:
  fix: container binds syntax (testcontainers#2899)
  refactor(cockroachdb): to use request driven options (testcontainers#2883)
  chore(deps): bump actions/setup-go from 5.0.0 to 5.1.0 (testcontainers#2904)
  chore(deps): bump ossf/scorecard-action from 2.3.1 to 2.4.0 (testcontainers#2903)
  chore(deps): bump test-summary/action from 2.3 to 2.4 (testcontainers#2902)
  feat(wait): strategy walk (testcontainers#2895)
  feat(wait): tls strategy (testcontainers#2896)
@mdelapenya mdelapenya requested a review from stevenh December 5, 2024 11:56
@mdelapenya mdelapenya marked this pull request as ready for review December 5, 2024 15:45
@mdelapenya mdelapenya requested a review from a team as a code owner December 5, 2024 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New functionality or new behaviors on the existing one
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants