Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression: dotnet tool restore with a dotnet-tools.json is broken in .NET 8 RC 2 #35989

Closed
alexrp opened this issue Oct 10, 2023 · 9 comments
Closed
Labels
Area-Tools untriaged Request triage from a team member

Comments

@alexrp
Copy link

alexrp commented Oct 10, 2023

$ git clone https://github.com/vezel-dev/celerity.git
$ cd celerity
$ sed -i 's/8.0.100-rc.1.23455.8/8.0.100-rc.2.23502.2/' global.json
$ sed -i 's/7.0.442301/3.0.0-preview9.19454.1/' dotnet-tools.json
$ dotnet tool restore
Skipping NuGet package signature verification.
Unhandled exception: System.AggregateException: One or more errors occurred. (The process cannot access the file 'C:\Users\Alex Rønne Petersen\AppData\Local\Temp\cbdfc8b6-d7cf-4926-8cac-e05a4d1adbe4\project.assets.json' because it is being used by another process.) (The process cannot access the file 'C:\Users\Alex Rønne Petersen\AppData\Local\Temp\cbdfc8b6-d7cf-4926-8cac-e05a4d1adbe4\project.assets.json' because it is being used by another process.) (The process cannot access the file 'C:\Users\Alex Rønne Petersen\AppData\Local\Temp\cbdfc8b6-d7cf-4926-8cac-e05a4d1adbe4\project.assets.json' because it is being used by another process.) (The process cannot access the file 'C:\Users\Alex Rønne Petersen\AppData\Local\Temp\cbdfc8b6-d7cf-4926-8cac-e05a4d1adbe4\project.assets.json' because it is being used by another process.)
 ---> System.IO.IOException: The process cannot access the file 'C:\Users\Alex Rønne Petersen\AppData\Local\Temp\cbdfc8b6-d7cf-4926-8cac-e05a4d1adbe4\project.assets.json' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at NuGet.ProjectModel.LockFileFormat.Write(String filePath, LockFile lockFile)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.CreateAssetFile(PackageId packageId, NuGetVersion version, DirectoryPath packagesRootPath, DirectoryPath assetFileDirectory, String runtimeJsonGraph, String targetFramework)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.<>c__DisplayClass8_0.<InstallPackage>b__0()
   at Microsoft.DotNet.Cli.TransactionalAction.Run[T](Func`1 action, Action commit, Action rollback)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.InstallPackages(ToolManifestPackage package, Nullable`1 configFile)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.<>c__DisplayClass10_0.<Execute>b__0(ToolManifestPackage package)
   at System.Linq.Parallel.SelectQueryOperator`2.SelectQueryOperatorResults.GetElement(Int32 index)
   at System.Linq.Parallel.QueryResults`1.get_Item(Int32 index)
   at System.Linq.Parallel.PartitionedDataSource`1.ListContiguousIndexRangeEnumerator.MoveNext(T& currentElement, Int32& currentKey)
   at System.Linq.Parallel.StopAndGoSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
   at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of inner exception stack trace ---
   at System.Linq.Parallel.QueryTaskGroupState.QueryEnd(Boolean userInitiatedDispose)
   at System.Linq.Parallel.SpoolingTask.SpoolStopAndGo[TInputOutput,TIgnoreKey](QueryTaskGroupState groupState, PartitionedStream`2 partitions, SynchronousChannel`1[] channels, TaskScheduler taskScheduler)
   at System.Linq.Parallel.DefaultMergeHelper`2.System.Linq.Parallel.IMergeHelper<TInputOutput>.Execute()
   at System.Linq.Parallel.MergeExecutor`1.Execute()
   at System.Linq.Parallel.MergeExecutor`1.Execute[TKey](PartitionedStream`2 partitions, Boolean ignoreOutput, ParallelMergeOptions options, TaskScheduler taskScheduler, Boolean isOrdered, CancellationState cancellationState, Int32 queryId)
   at System.Linq.Parallel.PartitionedStreamMerger`1.Receive[TKey](PartitionedStream`2 partitionedStream)
   at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
   at System.Linq.Parallel.QueryOperator`1.ExecuteAndGetResultsAsArray()
   at System.Linq.ParallelEnumerable.ToArray[TSource](ParallelQuery`1 source)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.Execute()
   at System.CommandLine.Invocation.InvocationPipeline.Invoke(ParseResult parseResult)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient)
 ---> (Inner Exception #1) System.IO.IOException: The process cannot access the file 'C:\Users\Alex Rønne Petersen\AppData\Local\Temp\cbdfc8b6-d7cf-4926-8cac-e05a4d1adbe4\project.assets.json' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at NuGet.ProjectModel.LockFileFormat.Write(String filePath, LockFile lockFile)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.CreateAssetFile(PackageId packageId, NuGetVersion version, DirectoryPath packagesRootPath, DirectoryPath assetFileDirectory, String runtimeJsonGraph, String targetFramework)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.<>c__DisplayClass8_0.<InstallPackage>b__0()
   at Microsoft.DotNet.Cli.TransactionalAction.Run[T](Func`1 action, Action commit, Action rollback)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.InstallPackages(ToolManifestPackage package, Nullable`1 configFile)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.<>c__DisplayClass10_0.<Execute>b__0(ToolManifestPackage package)
   at System.Linq.Parallel.SelectQueryOperator`2.SelectQueryOperatorResults.GetElement(Int32 index)
   at System.Linq.Parallel.QueryResults`1.get_Item(Int32 index)
   at System.Linq.Parallel.PartitionedDataSource`1.ListContiguousIndexRangeEnumerator.MoveNext(T& currentElement, Int32& currentKey)
   at System.Linq.Parallel.StopAndGoSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
   at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)<---

 ---> (Inner Exception #2) System.IO.IOException: The process cannot access the file 'C:\Users\Alex Rønne Petersen\AppData\Local\Temp\cbdfc8b6-d7cf-4926-8cac-e05a4d1adbe4\project.assets.json' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at NuGet.ProjectModel.LockFileFormat.Write(String filePath, LockFile lockFile)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.CreateAssetFile(PackageId packageId, NuGetVersion version, DirectoryPath packagesRootPath, DirectoryPath assetFileDirectory, String runtimeJsonGraph, String targetFramework)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.<>c__DisplayClass8_0.<InstallPackage>b__0()
   at Microsoft.DotNet.Cli.TransactionalAction.Run[T](Func`1 action, Action commit, Action rollback)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.InstallPackages(ToolManifestPackage package, Nullable`1 configFile)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.<>c__DisplayClass10_0.<Execute>b__0(ToolManifestPackage package)
   at System.Linq.Parallel.SelectQueryOperator`2.SelectQueryOperatorResults.GetElement(Int32 index)
   at System.Linq.Parallel.QueryResults`1.get_Item(Int32 index)
   at System.Linq.Parallel.PartitionedDataSource`1.ListContiguousIndexRangeEnumerator.MoveNext(T& currentElement, Int32& currentKey)
   at System.Linq.Parallel.StopAndGoSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
   at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)<---

 ---> (Inner Exception #3) System.IO.IOException: The process cannot access the file 'C:\Users\Alex Rønne Petersen\AppData\Local\Temp\cbdfc8b6-d7cf-4926-8cac-e05a4d1adbe4\project.assets.json' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at NuGet.ProjectModel.LockFileFormat.Write(String filePath, LockFile lockFile)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.CreateAssetFile(PackageId packageId, NuGetVersion version, DirectoryPath packagesRootPath, DirectoryPath assetFileDirectory, String runtimeJsonGraph, String targetFramework)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.<>c__DisplayClass8_0.<InstallPackage>b__0()
   at Microsoft.DotNet.Cli.TransactionalAction.Run[T](Func`1 action, Action commit, Action rollback)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.InstallPackages(ToolManifestPackage package, Nullable`1 configFile)
   at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.<>c__DisplayClass10_0.<Execute>b__0(ToolManifestPackage package)
   at System.Linq.Parallel.SelectQueryOperator`2.SelectQueryOperatorResults.GetElement(Int32 index)
   at System.Linq.Parallel.QueryResults`1.get_Item(Int32 index)
   at System.Linq.Parallel.PartitionedDataSource`1.ListContiguousIndexRangeEnumerator.MoveNext(T& currentElement, Int32& currentKey)
   at System.Linq.Parallel.StopAndGoSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
   at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)<---

Notes:

  • 3.0.0-preview9.19454.1 is arbitrary; pick any version that isn't already installed on the machine.
  • --disable-parallel and --no-cache make no difference.
  • I have no idea what is up with the signature verification. I haven't disabled it myself.
  • This regression is a hard blocker for upgrading from .NET 8 RC 1 in most of my projects, as I rely on local tools during the build. Seems to me that this should be a .NET 8 release blocker.
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Tools untriaged Request triage from a team member labels Oct 10, 2023
@KalleOlaviNiemitalo
Copy link

It has been fixed for .NET SDK 8.0.100 in #35884.

The RC 2 known issue doc PR dotnet/core#8799 hasn't been merged yet.

@alexrp
Copy link
Author

alexrp commented Oct 11, 2023

Huh, ok. I guess I'm going to skip RC 2. Those suggested workarounds really don't scale to non-trivial projects, and judging by the linked issues, it seems even the different .NET teams gave up trying to work around the bug.

Honestly a bit baffling that RC 2 shipped with such a major known regression. 😕

@KalleOlaviNiemitalo
Copy link

The ToolRestoreCommandTests.ItRestoresMultipleTools test is not on the release/8.0.2xx and main branches yet. I guess the fix isn't on those branches either. Will those now be tracked in this issue, or is there a different issue for that?

@molinch
Copy link

molinch commented Oct 11, 2023

I used Docker image 8.0.100-rc.2 but still got issues with dotnet tool restore. Is it really fixed already?
If yes, which image contains the fix?

@dsplaisted
Copy link
Member

The ToolRestoreCommandTests.ItRestoresMultipleTools test is not on the release/8.0.2xx and main branches yet. I guess the fix isn't on those branches either. Will those now be tracked in this issue, or is there a different issue for that?

Here's the PR merging these changes to 8.0.2xx (and it will flow to main at some point after that PR is merged): #35914

I used Docker image 8.0.100-rc.2 but still got issues with dotnet tool restore. Is it really fixed already? If yes, which image contains the fix?

The issue is fixed in the code but there isn't a release or docker image with the fix. That will come with the 8.0.100 GA release.

@KalleOlaviNiemitalo
Copy link

KalleOlaviNiemitalo commented Oct 11, 2023

From the workaround in the known issue PR dotnet/core#8811:

If you are using .NET tools in CI where you can't easily modify the tools config file between multiple tool restores, you can create a separate dotnet-tools.json config file for each .NET tool in a separate subfolder. Then run dotnet tool restore in each subfolder.

Do these per-subfolder dotnet tool restore commands have to be run serially, or is it safe to run them in parallel?

@JL03-Yue
Copy link
Member

JL03-Yue commented Oct 11, 2023

Do these per-subfolder dotnet tool restore commands have to be run serially, or is it safe to run them in parallel?

I believe it's safe to run in parallel.

@mattleibow
Copy link
Member

I added this to our startup script:

$tools = Get-Content ".config/dotnet-tools.json" | ConvertFrom-Json
foreach ($tool in $tools.tools.PsObject.Properties) {
    & dotnet tool install $tool.Name --version $tool.Value.version
}

@JL03-Yue
Copy link
Member

This is targeted to be fixed in .NET GA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Tools untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests

6 participants