testcontainers / testcontainers-dotnet

A library to support tests with throwaway instances of Docker containers for all compatible .NET Standard versions.
https://dotnet.testcontainers.org
MIT License
3.81k stars 278 forks source link

[Enhancement]: Support custom user #1236

Open macsux opened 2 months ago

macsux commented 2 months ago

Problem

Currently it's not possible to specify the user inside a container. This is problematic for containers that need to be tested to run as non default user / non root environment. This is also a problem for images that explicitly specify user via USER <name> directive when used in conjuction with WithResourceMapping which copies all files into container as ROOT, preventing their manipulation by the user the container is running under

Solution

AddWithUser(string name)toContainerBuilderthat would map to--user argument ofdocker run`.

Benefit

All proper testing of containers that need to run as non standard user.

Alternatives

No good alternatives have been identified

Would you like to help contributing this enhancement?

Yes

HofmeisterAn commented 2 months ago

You can change the user using the following container builder API:

WithCreateParameterModifier(parameterModifier => parameterModifier.User = "nobody")

However, this won't change the user for files uploaded using the WithResourceMapping API. In this case, you need to set the file mode using one of the overloaded methods. To "fix" this, we likely need to pass the user to the TarOutputMemoryStream class and set the user ID accordingly (which we do not know, right?).

macsux commented 2 months ago

I've started working on this and pretty much done, EXCEPT I'm blocked by the fact that Docker.DotNet doesn't expose the necessary argument to keep tarball's UID/GID. I've raised an issue and submitted PR against Docker.Dotnet to fix it, but given a long list of open issues/PRs against that repo and last release being over a year ago, I'm not holding my breath this will get fixed anytime soon.

I could hack it via reflection to access the necessary internal method in Docker.DotNet to make the necessary underlying http call with the right argument, but wanted to check first if that's something you would be willing to accept as a workaround. Edit: After looking at it closer, the way the code is written makes it impossible to do this reflectively as it relies on a model classes that use internal attributes, which we can't use. This looks like a blocker unless they merge my PR.

HofmeisterAn commented 2 months ago

I've raised an issue and submitted PR against Docker.Dotnet to fix it, but given a long list of open issues/PRs against that repo and last release being over a year ago, I'm not holding my breath this will get fixed anytime soon.

Yes, this is unfortunate. I offered my help a couple of times but was declined each time. It's sad that there isn’t more active development and maintenance. Since it is a very important upstream dependency, I looked into generating the client from the OpenAPI spec 1). @0xced took it even further and made good progress 👍.