core
core copied to clipboard
Interacting with NuGet fails on .NET 6.0.10 when running in docker with user
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
.
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.
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.
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.
Confirming regression / new behaviour on SDK 3.1.424
is failing our builds for restore
and pack
:(
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
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.
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.
@MichaelSimons is this something you can help with?
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
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.
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?
@lbussell - Can help out here?
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)?
@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.