testcontainers-dotnet icon indicating copy to clipboard operation
testcontainers-dotnet copied to clipboard

[Enhancement]: Support custom user

Open macsux opened this issue 1 year ago • 4 comments

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

Add WithUser(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

macsux avatar Aug 19 '24 16:08 macsux

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?).

HofmeisterAn avatar Aug 19 '24 17:08 HofmeisterAn

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.

macsux avatar Aug 19 '24 20:08 macsux

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 👍.

HofmeisterAn avatar Aug 20 '24 17:08 HofmeisterAn

@macsux I recently forked Docker.DotNet and am already using the fork in TC. If you would like to continue working on this topic, I would be happy to review the necessary changes and merge them into the fork.

HofmeisterAn avatar Feb 14 '25 19:02 HofmeisterAn

I've started looking into this issue. I created a local reproducer and will work on a fix/support over the next few days. As an intermediate workaround, you can use an overload that allows you to specify the permissions. It's not ideal, but it should work until proper support is added.

_ = new ContainerBuilder()
  .WithResourceMapping([], "/app/foo", Unix.FileMode777)

HofmeisterAn avatar Sep 18 '25 18:09 HofmeisterAn

I've looked into this, but I'm not entirely sure of the best way to handle it.

  1. Right now, copied files default to owner and group root (not ideal).
  2. Developers can set file mode (permissions) for each file or directory they copy (see the workaround mentioned above).
  3. We could extend the IResourceMapping interface to let developers set the owner and group, just like they can with file mode.
  4. The Docker Engine API has a CopyUIDGID option that sets the owner and group to the container's user (--user).
    1. But if CopyUIDGID is true, then specifying owner/group in the tarball won't work anymore (suggestion 3.).

HofmeisterAn avatar Sep 19 '25 19:09 HofmeisterAn