Unable to obtain lock file access (Dotnet CLI) - c#

I use Dev Containers to attach to a container and debug. And it was working just fine.
Recently however it shows this error when I hit F5 or run dotnet build from VS Code's terminal:
/usr/share/dotnet/sdk/7.0.102/NuGet.targets(132,5): error : Unable to obtain lock file access on '/tmp/NuGetScratch/lock/fcd2970c0c875310ff5855562ac5f3954170bddb' for operations on '/Crm/AdminApi/obj/project.nuget.cache'. This may mean that a different user or administrator is holding this lock and that this process does not have permission to access it. If no other process is currently performing an operation on this file it may mean that an earlier NuGet process crashed and left an inaccessible lock file, in this case removing the file '/tmp/NuGetScratch/lock/fcd2970c0c875310ff5855562ac5f3954170bddb' will allow NuGet to continue. [/Crm/AdminApi/Api.csproj]
And it shows the above message after trying to re-install every dependency, while NuGet has cached those dependencies already.
It works if:
1- I open a root bash using docker exec -it container_name bash and run dotnet build
2- I open a non root bash, and simply run sudo dotnet build
3- I open a VS Code termianl (which shows vscode as the user) and run sudo dotnet build
I tried sudo chown -R vscode:vscode /tmp/NuGetScratch/ as mentioned in dotnet error : Unable to obtain lock file access on '/tmp/NuGetScratch/lock/ and here, but that did not change anything. I then tried sudo chmod -R 777 /tmp/NuGetScratch and again no results. I even verified that the owner is changed using ls /tmp -lah | grep NuGet and this is the results:
drwxrwxrwx 1 vscode vscode 4.0K Feb 9 10:43 NuGetScratch
What else can I do?

This was recently logged as an issue: https://github.com/NuGet/Home/issues/12420
Possible workarounds listed from https://github.com/NuGet/Home/issues/12420#issuecomment-1423774814:
Run dotnet nuget locals temp -c to clear the /tmp/NuGetScratch (If there is a sticky bit in /tmp permissions then it won't work)
Set environment variable NUGET_ConcurrencyUtils_DeleteOnClose to 1 before running restore, so the lock files will be cleared after restore (This change is only available in NuGet 6.2 and above, probably .NET 7 preview6 and above)
Set environment variable NUGET_SCRATCH to a path. This variable will override the default temp folder. But it's only applied to NuGet version 6.2 and later, probably .NET 7 preview6 and above).

Related

Docker - dotnet restore fails connection to private feeds

Calling dotnet restore <project> from my Dockerfile is resulting in a NU1301: Unable to load the service index for source error. I've been going through many of the suggested similar questions and continue to have issues. Here is as much info about the things I've tried as I can provide:
Docker Engine has its DNS set to "8.8.8.8"
Using Linux containers
RUN ping google.com succeeds (so I can reach the internet)
Works perfectly fine hitting the nuget.org feed
The nuget.config file currently has credentials in it just to get this working
This will be removed for a different approach once I get this working
These are the same credentials (username/PAT) that I use during development on my host machine
RUN curl <nuget_feed_url> succeeds
Running the restore command with --verbosity detailed doesn't provide any other error messages but the one
Here is the section of the Dockerfile in question
FROM mcr.microsoft.com/dotnet/aspnet:6.0.13 AS base
# Create dockeruser in base layer
RUN addgroup --system --gid 1000 dockergroup \
&& adduser --system --uid 1000 --ingroup dockergroup --shell /bin/sh dockeruser
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
# Arguments are required in each stage in order to get the correct value
WORKDIR /src
COPY ["src/Nucleus.LumberYard.API/", "Nucleus.LumberYard.API/"]
COPY ["./nuget.config", "./nuget.config"]
WORKDIR "/src/Nucleus.LumberYard.API"
#COPY [".editorconfig", "./"]
RUN dotnet restore "Nucleus.LumberYard.API.csproj"
RUN dotnet build "Nucleus.LumberYard.API.csproj" -c Release --no-restore
Environment info
Docker Desktop v3.3.1
Docker v20.10.5
Based on my understanding you have the following scenario:
a .NET 6 application with some references to nuget packages
some nuget packages are taken from the usual Nuget public repository, some others are taken from a private nuget feed
you are distributing your application via a docker image and during the docker build process you want to run a dotnet restore command targeting one of your csproj file
the dotnet restore command fails because the dotnet cli is unable to talk with your private nuget feed
I encountered the very same situation with the project I'm working on. We have a private Nuget feed hosted in Azure Devops and we too had some troubles figuring out how to solve this.
First of all, let's clarify the root cause of the problem.
You did the right thing veryfying that you are able to reach the nuget feed from your build machine, via the curl command you mentioned.
What is actually failing is the authentication between your build machine and the private nuget feed.
The first thing you need is a personal access token with read permissions for your nuget feed. You can follow this guide to create the personal access token you need.
Once you have the token, you need to provide it to the dotnet cli.
There are several ways to do so, I'm going to explain the one that worked for us.
Instead of adding the nuget source to the nuget.config file, we registers it via a cli command.
I'm quite sure there is a way to do exactly the same thing via the nuget.config file (see here for more details).
This is the cli command we use inside of our docker file:
RUN dotnet nuget add source https://foo.bar.com/something/nuget/v3/index.json -u "whatever" -p "my-personal-access-token" --store-password-in-clear-text --valid-authentication-types "basic"
Notice that:
https://foo.bar.com/something/nuget/v3/index.json is the absolute URL pointing to the index of your private nuget feed
the username can be whatever you like. You do need to provide a value, but I didn't notice any difference even putting there a random string like whatever
the fictious value my-personal-access-token must be substituted with the personal access token you have created as a first step
Here you can find the full reference for the dotnet nuget add source command.
After registering this source with the dotnet cli, you will be able to run your dotnet restore command with no errors.
Hope this helps!

Visual Studio 2019 C# Docker debugging process attach error

I'm trying to debug a Linux container that runs a C#/.NET 6.0 console application from Visual Studio 2019 (version 16.11.10).
When I use Debug / Attach to Process... to connect to my running container and attach to my process, I get the error:
Failed to launch debug adapter. Additional information may be available in the output window.
Unable to find debugger script at '/home/dockeruser/.vs-debugger'
For company security purposes, I'm running my container workloads as user dockeruser, but I can reproduce this when I adjust my Dockerfile to run as user root. The error message changes into
Unable to find debugger script at '/root/.vs-debugger'
Output shows
Unable to find debugger script at '/home/dockeruser/.vs-debugger'.
Initialization log:
Determining user folder on remote system...
Checking for existing installation of debugging tools...
Downloading debugger launcher...
Creating debugger installation folder: /home/dockeruser/.vs-debugger
Copying debugger launcher to /home/dockeruser/.vs-debugger/GetVsDbg.sh
Failed: Failed to copy files.
Unable to find debugger script at '/home/dockeruser/.vs-debugger'.
Failed: Unable to find debugger script at '/home/dockeruser/.vs-debugger'.
The program '[1] dotnet' has exited with code -1 (0xffffffff).
I can work around this by docker exec'ing a bash session on my container and running GetDbgVs.sh as detailed in https://stackoverflow.com/a/68950674/17273131, but its a pain to do - it feels like something is misconfigured.
I've already verified that my windows identity is a member of the windows docker-users group.
While not the answer I wanted, I've got a 1-liner shell workaround that I execute on my container when I want to debug attach with VS2019, once I know my <CONTAINER_NAME>. This may be useful to others with this problem.
docker exec -u root <CONTAINER_NAME> sh -c "apt-get update && apt-get install wget -y"; docker exec <CONTAINER_NAME> sh -c "mkdir -p ~/.vs-debugger; wget https://aka.ms/getvsdbgsh -O ~/.vs-debugger/GetVsDbg.sh; chmod a+x ~/.vs-debugger/GetVsDbg.sh"
The first command installs wget as root
The second command downloads GetVsDbg.sh to ~/.vs-debugger

using the docfx.console nuget package on linux

At the moment I have a visual studio project and I use the docfx.console nuget package to build the documentation, and everything works fine and as expected... on windows. The point is now I want to make a docker image based on mcr.microsoft.com/dotnet/core/sdk:3.1 which is based on a linux image. And compiling in this docker image running the command:
dotnet publish -c Release -o out
Gives the following error
> [build 9/9] RUN dotnet publish -c Release -o out:
#22 1.080 Microsoft (R) Build Engine version 16.0.450+ga8dc7f1d34 for .NET Core
#22 1.080 Copyright (C) Microsoft Corporation. All rights reserved.
#22 1.080
#22 2.852 Restore completed in 215.94 ms for /app/Documentation/Documentation.csproj.
#22 6.299 Documentation -> /app/Documentation/bin/Release/netcoreapp2.1/Documentation.dll
#22 6.402 /bin/sh: 2: /tmp/tmpbd72ebbe5e6b49c1b3244f1f50c8b57a.exec.cmd: /root/.nuget/packages/docfx.console/2.48.1/build/../tools/docfx.exe: Exec format error
#22 6.407 /root/.nuget/packages/docfx.console/2.48.1/build/docfx.console.targets(57,5): error MSB3073: The command ""/root/.nuget/packages/docfx.console/2.48.1/build/../tools/docfx.exe" "/app/Documentation/docfx.json" -o "" -l "log.txt" --logLevel "Verbose"" exited with code 2. [/app/Documentation/Documentation.csproj]
I already did some prodding around and I believe I have the issue mostly solved. Running file on console.exe shows that this is a PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows. And these kind of files should not be executed on linux using sh but with mono. And indeed running:
mono docfx.exe "/app/Documentation/docfx.json" -o "" -l "log.txt" --logLevel "Verbose"
builds the documentation just fine as expected. At this point of course I have a bunch of workarounds to get the documentation building correctly, just remove docfx.console form the csproj and build it manualy from the command line using a docker command.
But the question is, can I also use the nuget package on linux by changing how the docfx.exe command is run by the nuget package? Or is this only possible by actually fixing this in docfx.console?
p.s. in case it matters, the version of docfx.console that I am using is the most recent one available at the time of writing, namely 2.48.1
But the question is, can I also use the nuget package on linux by changing how the docfx.exe command is run by the nuget package? Or is this only possible by actually fixing this in docfx.console?
Create script docfx that runs docfx.exe using Mono, e.g., like this (assuming docfx.exe is located in /opt/docfx/docfx.exe):
echo '#!/bin/bash\nmono /opt/docfx/docfx.exe $#' > /usr/bin/docfx && chmod +x /usr/bin/docfx
Then, pass MSBuild parameter BuildDocToolPath with path to that script, e.g., like this:
dotnet publish -c Release -o out -p:BuildDocToolPath=/usr/bin/docfx
docfx.console will than use this path to execute DocFX. I think the property BuildDocToolPath isn't documented anywhere, but you can see it in source code.

Absolute path in dotnet watch run command doesn't work

To run dotnet core application with specified absolute path we need to run following command:
dotnet run -p C:\foo\bar\Project\Project.csproj
But it seems it doesn't work the same with dotnet watch run:
watch : Could not find a MSBuild project file in 'C:\directory\where\we\execute\command'. Specify which project to use with the --project option.
Running the same command with -project instead of -p doesn't help however...
Dotnet watch help specifies -p or -project parameter anyway:
Microsoft DotNet File Watcher 2.1.1-rtm-30846
Usage: dotnet watch [options] [[--] ...]
Options: -?|-h|--help Show help information
-p|--project The project to watch -q|--quiet Suppresses all output except warnings and errors -v|--verbose
Show verbose output --list Lists all discovered
files without starting the watcher --version Show
version information
Environment variables:
DOTNET_USE_POLLING_FILE_WATCHER When set to '1' or 'true',
dotnet-watch will poll the file system for changes. This is required
for some file systems, such as network shares, Docker mounted
volumes, and other virtual file systems.
DOTNET_WATCH dotnet-watch sets this variable to '1' on all child
processes launched.
Remarks: The special option '--' is used to delimit the end of the
options and the beginning of arguments that will be passed to the
child dotnet process. Its use is optional. When the special option
'--' is not used, dotnet-watch will use the first unrecognized
argument as the beginning of all arguments passed into the child
dotnet process.
For example: dotnet watch -- --verbose run
Even though '--verbose' is an option dotnet-watch supports, the use
of '--' indicates that '--verbose' should be treated instead as an
argument for dotnet-run.
Examples: dotnet watch run dotnet watch test
What's wrong then? Why absolute path to project doesn't work with dotnet watch run while works with dotnet run?
You can resolve this by specifying the -p (or the longer --project) option on the watch command rather than on the run command. In your case, that would be:
dotnet watch -p C:\foo\bar\Project\Project.csproj run
There's a note in the docs that covers this:
You can use dotnet watch --project <PROJECT> to specify a project to watch. For example, running dotnet watch --project WebApp run from the root of the sample app will also run and watch the WebApp project.
I'm not 100% sure, but dotnet watch is looking for file changes in the current directory. So if you use absolute path it must know where should it looks for changes. Of course, such implementation is possible but I just think that nobody thinked about it when implementing watch command
In my case, its just a minor error, you have to enter in the project directory before executing dotnet command, like:
cd yourAppName
dotnet watch run
It'll run

.NetCore for Mac - Publish to Native Mac App/Binary?

I've been searching for quite some time now, and can't seem to find an answer to this problem. Found only two questions/answers on SO and they still don't answer this question (https://stackoverflow.com/search?q=netcore+publish+mac+app).
I'm working with DotNetCore on Mac, using Visual Studio as the IDE. The app is a Console App, not an ASP.Net app, simple "Hello World" app in C#:
...
Console.Writeline("Hello World");
...
So here's the question... To run the app, I know I can use the "dotnet" command to run it. I'm trying to build/publish the app, as you normally would do in Windows by creating an .exe file, but now on Mac by creating a native binary file.
I have found zero documentation on how to do this, and deploy the application as a self contained app that can run independently without having to call the program using the "dotnet" command. Maybe I'm looking in the wrong places but haven't even found anything on Microsoft's documentation, they all point to documentation for building ASP.Net apps on .NetCore.
Any suggestions?
Found the answer by looking at the "dotnet publish" options:
dotnet publish -c Release --self-contained -r osx.10.13-x64
Where --self-contained includes all required libraries, and -r specifies the runtime target.
$ dotnet publish -c Release --self-contained -a x64
Determining projects to restore...
Restored /Users/walshca/code/temp/MutexThrow/MutexThrow.csproj (in 155 ms).
MutexThrow -> /Users/walshca/code/temp/MutexThrow/bin/Release/net6.0/osx-x64/MutexThrow.dll
MutexThrow -> /Users/walshca/code/temp/MutexThrow/bin/Release/net6.0/osx-x64/publish/
dotnet publish docs
Then I run ./bin/Release/net6.0/osx-x64/publish/MutexThrow
This didn't specify the --output cli arg, so you can see in the build output it defaulted to [project_file_folder]/bin/[configuration]/[framework]/[runtime]/publish/
(In dotnet 6.0 instead of -r runtime target, you can specify --arch x86 and it uses the default RID for your system.)
If your project props sets a different build output, can you find the executable by enumerating files by unix file permissions:
$ gci -r -file | ? UnixMode -match 'x$' | % FullName
/Users/walshca/code/temp/MutexThrow/obj/Release/net6.0/osx-x64/apphost
/Users/walshca/code/temp/MutexThrow/bin/Release/net6.0/osx-x64/MutexThrow
/Users/walshca/code/temp/MutexThrow/bin/Release/net6.0/osx-x64/publish/MutexThrow

Categories

Resources