core icon indicating copy to clipboard operation
core copied to clipboard

Interacting with NuGet fails on .NET 6.0.10 when running in docker with user

Open ravicini opened this issue 2 years ago • 14 comments

Description

We use the .NET SDK docker image to build our solution. Since the image mcr.microsoft.com/dotnet/sdk:6.0 has been updated (10.10.2022 / .NET 6.0.10), we are encountering the following error when interacting with NuGet. This error happens only when we use a specific user (-u 1000:1000) to run the command.

Steps to Reproduce:

  • Run Docker image and mount an existing solution: sudo docker run -it -u 1000:1000 -e DOTNET_CLI_HOME=/tmp --rm --net=host --mount type=bind,source=/path/to/sln,target=/project mcr.microsoft.com/dotnet/sdk:6.0
  • navigate to sln: cd /project
  • list nuget sources dotnet nuget list source

Error:

Unhandled exception. System.UnauthorizedAccessException: Access to the path '/.local/share/NuGet/Migrations' is denied.
 ---> System.IO.IOException: Permission denied
   --- End of inner exception stack trace ---
   at System.IO.FileSystem.CreateDirectory(String fullPath)
   at System.IO.Directory.CreateDirectory(String path)
   at NuGet.Common.Migrations.MigrationRunner.GetMigrationsDirectory()
   at NuGet.Common.Migrations.MigrationRunner.Run()
   at NuGet.CommandLine.XPlat.Program.MainInternal(String[] args, CommandOutputLogger log)
   at NuGet.CommandLine.XPlat.Program.Main(String[] args)

We tried to define a configuration to define the directory, as /.local does not exist, but we did not find any way to do this.

Configuration

  • .NET 6.0.10 (through docker image mcr.microsoft.com/dotnet/sdk:6.0
  • Occurs on multiple Environment Setup
    • Windows, WSL, Ubuntu 20.04
    • Windows, Docker Desktop
    • Jenkins, Ubuntu 20.04 Agent

Regression?

It had worked with an already downloaded docker image. After deleting the image and pulling it again, this error started to occur.

Comment

Listing the NuGet sources was the first command we encountered failing, but neither do dotnet restore nor dotnet build.

ravicini avatar Oct 12 '22 13:10 ravicini

Confirming that I am seeing this same issue, in our case in .NET Core SDK 3.1.424, using the official docker images. In addition to the commands listed in the original report, we also see this behavior with dotnet pack.

As of 3.1.424, when running a dotnet nuget command, an empty file at $HOME/.local/share/NuGet/Migrations/1 is being created. In the case of running as a user that does not have a mapped home directory, $HOME defaults to /, and when the dotnet process attempts to create $HOME/.local/share/NuGet/Migrations/1, the file/directory creation fails because only root has permissions to write to /.

This shouldn't be a problem, because the DOTNET_CLI_HOME environment variable can be used to specify a different base directory for the dotnet files and directories, but this new Migrations directory/file operation does not appear to make appropriate use of this environment variable.

SDK 3.1.423 and earlier do not share this behavior - the $HOME/.local/share/NuGet/Migrations/1 file does not appear to get created in these versions, and so this issue does not exist.

jsinger8290 avatar Oct 12 '22 20:10 jsinger8290

I'm seeing the same issue as well, and I tried a workaround where I have our Docker container a fake HOME by specifying --env HOME=/tmp/home, but that caused our dotnet commands to hang forever, and we have to kill them by deleting the Docker container.

bangfalse avatar Oct 12 '22 23:10 bangfalse

I also encountered this error. I had to force it to use the previous version of the image instead of the latest in the 6.0 family. So I used FROM mcr.microsoft.com/dotnet/sdk:6.0.401. 402 seems to be the most recent one.

keithotto avatar Oct 13 '22 01:10 keithotto

Confirming regression / new behaviour on SDK 3.1.424 is failing our builds for restore and pack :(

stephenpope avatar Oct 13 '22 09:10 stephenpope

I have also encountered this today. @jsinger8290 You detailed the issue very well. I was able to resolve the issue by set 'XDG_CONFIG_HOME' as you would 'DOTNET_CLI_HOME.' This I think is the nuget code that is making use of the environment variable: https://github.com/NuGet/NuGet.Client/blob/0966444b35d8a74fa25adf0368b983f389884377/src/NuGet.Core/NuGet.Common/Migrations/MigrationRunner.cs

justindrocco avatar Oct 13 '22 21:10 justindrocco

Thanks, @jsinger8290, for the detailed analysis, and thanks @justindrocco for the link to the MigrationRunner, this was the missing piece of detail I was missing.

Small correction to your comment: The flag is named XDG_DATA_HOME.

I was able to get a running version with the following command:

docker run -it -u 1000:1000 -e DOTNET_CLI_HOME=/tmp -e XDG_DATA_HOME=/tmp --rm --net=host --mount type=bind,source=/path/to/the/sln,target=/project mcr.microsoft.com/dotnet/sdk:6.0

I support the opinion mentioned by @jsinger8290 for the MigrationRunner to make appropriate use of the DOTNET_CLI_HOME environment variable.

ravicini avatar Oct 14 '22 06:10 ravicini

The same issue affected us in a different way. We're using a docker agent for our jenkins pipeline, based on mcr.microsoft.com/vscode/devcontainers/dotnet:0-6.0 (We're going to switch to the sdk directly soon). The issue happened just the same with those error messsages:

11:30:54  + dotnet restore
11:30:55    Determining projects to restore...
11:30:55  /usr/share/dotnet/sdk/6.0.402/NuGet.targets(132,5): error MSB4018: The "RestoreTask" task failed unexpectedly. [/var/lib/jenkins-slave/workspace/project/project.sln]
11:30:55  /usr/share/dotnet/sdk/6.0.402/NuGet.targets(132,5): error MSB4018: System.UnauthorizedAccessException: Access to the path '/.local/share/NuGet/Migrations' is denied.[/var/lib/jenkins-slave/workspace/project/project.sln]
11:30:55  /usr/share/dotnet/sdk/6.0.402/NuGet.targets(132,5): error MSB4018:  ---> System.IO.IOException: Permission denied [/var/lib/jenkins-slave/workspace/project/project.sln]

We recently rebuilded the agent, and no need to specify that the pipeline worked last week. Setting the environment variable specified by @ravicini fixed the issue:

environment {
        DOTNET_CLI_HOME = "/tmp/DOTNET_CLI_HOME"
        XDG_DATA_HOME = "/tmp"
}

Once a fix has been pushed and the command uses the proper variable again, we'll rebuild the image and remove the variable.

AlexisLessard avatar Nov 04 '22 12:11 AlexisLessard

@MichaelSimons is this something you can help with?

carlossanlop avatar Jan 30 '23 22:01 carlossanlop

FYI the issue is still present on dotnet 7, using the image mcr.microsoft.com/dotnet/sdk:7.0. We still need to have the environment variable XDG_DATA_HOME = "/tmp" to run our tests.

Image digest: sha256:f712881bafadf0e56250ece1da28ba2baedd03fb3dd49a67f209f9d0cf928e81

AlexisLessard avatar Apr 06 '23 20:04 AlexisLessard

Same here, we use read-only containers in Kubernetes but we mount a writable /tmp directly. ASP apps seem to use this by default so that works, but both DOTNET_CLI_HOME and XDG_DATA_HOME is needed to run dotnet test. We use this to run integration tests as Kubernetes Jobs after each deployment.

linjmeyer avatar May 25 '23 19:05 linjmeyer

We have a couple of folks that are still running in to this issue. @carlossanlop @MichaelSimons what is the correct way to get resolution on this?

vcsjones avatar Jan 25 '24 16:01 vcsjones

@lbussell - Can help out here?

MichaelSimons avatar Jan 26 '24 20:01 MichaelSimons

It seems like this should be handled in the NuGet.Client repo, I suggest opening an issue there - something like this looks similar: https://github.com/NuGet/Home/issues/12712. The code in question seems to be here - https://github.com/NuGet/NuGet.Client/blob/4b618ca3c42fa0b678b28d17af2d815c1d26d28b/src/NuGet.Core/NuGet.Common/Migrations/MigrationRunner.cs#L84-L97

Typically for .NET Docker we recommend building as root and setting your final container as non-root (example). For tests however, I understand that this might cause issues. @MichaelSimons do you think we need a note somewhere in our documentation about this with a link to an issue (perhaps in this sample where we have a test target defined)?

lbussell avatar Jan 26 '24 23:01 lbussell

@MichaelSimons do you think we need a note somewhere in our documentation about this with a link to an issue (perhaps in this sample where we have a test target defined)?

I guess that depends on how many people would find that documentation helpful (e.g. discover it when encountering the issue). Sometimes just having an issue is just as if not more discoverable for situations like this. Getting NuGet.Client to add support would be most useful.

MichaelSimons avatar Jan 29 '24 20:01 MichaelSimons