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

Replace ContainerRequest.BindMounts and ContainerRequest.VolumeMounts with ContainerRequest.Mounts as dedicated type #386

Merged
merged 4 commits into from
Dec 21, 2021

Conversation

prskr
Copy link
Contributor

@prskr prskr commented Nov 24, 2021

What does this PR do?

  • introduce dedicated type for mounts
  • introduce generic and Docker specific types for different mount sources (bind, volume, tmpfs)
  • introduce convenience methods to support common mount scenarios
  • add validation to avoid duplicate mount targets

Why is it important?

The current map based data structure is somehow confusing. This change avoids confusion by introducing dedicated types for all components to get help by IDEs and the compiler.

How to migrate

Simple bind mount

req := ContainerRequest {
    		//...
    		BindMounts: map[string]string{
		    "/var/run/docker.sock": "/var/run/docker.sock",
    		}
    		//...
}

becomes:

req := ContainerRequest {
    		//...
    		Mounts: Mounts(BindMount("/var/run/docker.sock", "/var/run/docker.sock")),
    		//...
}

Multiple mounts including a volume mount

req := ContainerRequest {
    		//...
    		BindMounts: map[string]string {
		    // container path : host path
		    "/hello.sh", absPath
    		},
    		VolumeMounts: map[string]string {
		    // container path : volume name
		    "/data": volumeName
    		//...
}

becomes

req := ContainerRequest {
    		//...
    		Mounts: Mounts(BindMount(absPath, "/hello.sh"), VolumeMount(volumeName, "/data")),
    		//...
}

mounts.go Outdated
package testcontainers

import (
"github.com/docker/docker/api/types/mount"
Copy link

Choose a reason for hiding this comment

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

As I understood the already existing code the things related to particular container backend (in this case - docker) are kept in the docker.go so that the testcontainers implementation is decoupled from it (although there is right now only one container backend provider).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see. To be honest after this comment I assumed it would be okay to rely on Docker API types but I refactored my draft to be Docker API independent, moved all the Docker related code to mounts_docker.go and split the mount sources into generic, container provider agnostic variants and added Docker specific ones in case one would like to be able to provide e.g. volume options.

I hope this matches better the current code structure?

@prskr
Copy link
Contributor Author

prskr commented Dec 13, 2021

@mdelapenya probably any feedback on this? 😊

Copy link
Collaborator

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

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

Hey @baez90, thanks for this great PR, I added a few comments, although I'm OK with the changes. Let'd discuss them before moving forward

Thanks in advance and sorry for the late response, I was on PTO past week

mounts_docker.go Outdated
@@ -0,0 +1,116 @@
package testcontainers
Copy link
Collaborator

Choose a reason for hiding this comment

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

NIT: I'd rename this file to docker_mounts.go as it's used as ..DockerMounts... everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fair enough!

mounts_docker.go Outdated

// MapToDockerMounts maps the given []ContainerMount to the corresponding
// []mount.Mount for further processing
func MapToDockerMounts(containerMounts ContainerMounts) []mount.Mount {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we want to expose this method externally? Not against it, but I'm simply double-checking it's on purpose

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tend to expose rather more than less because personally I prefer a breaking API instead of an API I cannot easily extend or 'hack' but for the sake of stability I made it private.
I was actually already wondering about the same and I think if there is a use case it can still be done later on?

mounts_docker.go Outdated
MountTypeBind: mount.TypeBind,
MountTypeVolume: mount.TypeVolume,
MountTypeTmpfs: mount.TypeTmpfs,
MountTypePipe: mount.TypeNamedPipe,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I cannot see an implementation for MountTypePipe but there are for Bind, Volume and Tmpfs. Is this on purpose?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😄 yes and no, I don't have any Windows running around here and I could not think of good test for MountTypePipe without it but it is supported for Docker (although I don't expect it to be implemented e.g. in Podman) hence I thought if someone has the need for it, it can be done without having to change testcontainers-go because it's already supported in the mapping.

There's no such thing like mount.NamedPipeOptions in Docker so no need to support it with an optional interface. I can remove it, it's another 'keep it open'-thing I thought could be nice

@prskr
Copy link
Contributor Author

prskr commented Dec 13, 2021

Thanks @mdelapenya for your kind words and the feedback!
Don't you worry, I just wasn't sure if there's something missing or if i forgot something or the like 😅

I tried to 'resolve' everything you mentioned.
Anything else that pops into mind?

@codecov
Copy link

codecov bot commented Dec 20, 2021

Codecov Report

Merging #386 (acb1983) into master (cdd4aba) will increase coverage by 0.89%.
The diff coverage is 77.77%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #386      +/-   ##
==========================================
+ Coverage   63.27%   64.16%   +0.89%     
==========================================
  Files          16       18       +2     
  Lines        1070     1108      +38     
==========================================
+ Hits          677      711      +34     
- Misses        291      293       +2     
- Partials      102      104       +2     
Impacted Files Coverage Δ
docker.go 64.60% <23.07%> (-1.09%) ⬇️
reaper.go 79.31% <50.00%> (-0.69%) ⬇️
wait/host_port.go 56.14% <50.00%> (ø)
generic.go 64.70% <66.66%> (ø)
container.go 88.37% <90.00%> (+3.07%) ⬆️
docker_mounts.go 92.59% <92.59%> (ø)
compose.go 75.18% <100.00%> (ø)
mounts.go 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6b77020...acb1983. Read the comment docs.

@mdelapenya mdelapenya added breaking change Causing compatibility issues. feature New functionality or new behaviors on the existing one labels Dec 20, 2021
- introduce specific types for different mount sources
- support read-only mount
- introduce convenience methods to support common mount scenarios
- add validation to avoid duplicate mount targets
- introduce Docker specific mount sources and generic counterparts
- move Docker specific code to mounts_docker.go
@gianarb
Copy link
Collaborator

gianarb commented Dec 20, 2021

Can we get a note about a migration for this breaking change? I would like to place it at the top of this PR and in the changelog! Let's get this bc break ready to get merged!

@prskr prskr changed the title Replace BindMounts and VolumeMounts with Mounts Replace ContainerRequest.BindMounts and ContainerRequest.VolumeMounts with ContainerRequest.Mounts as dedicated type Dec 20, 2021
@prskr
Copy link
Contributor Author

prskr commented Dec 20, 2021

Sure thing! I tried to improve the title and added some examples how to migrate in the PR description.
Something like that or did you already have some specific ideas? 😊

@gianarb
Copy link
Collaborator

gianarb commented Dec 21, 2021

Thanks a lot for your help with this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Causing compatibility issues. feature New functionality or new behaviors on the existing one
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants