dotnet migrate fails on Linux if the app directory is directly under root (e.g. /app). It's easy to repro with docker containers, but it should also repro on the host OS.
It repros when using microsoft/dotnet-nightly:1.1.0-sdk-msbuild-rc4 or later. It works fine when using microsoft/dotnet:1.1.0-sdk-msbuild-rc3.
It also works fine if the app directory is two levels below root (e.g. /src/app).
mkdir ~/new
docker run -it --rm -v ~/new:/new microsoft/dotnet:1.1.0-sdk-projectjson
cd new
dotnet new
exit
docker run -it --rm -v ~/new:/new microsoft/dotnet-nightly:1.1.0-sdk-msbuild-rc4
cd new
dotnet migrate
App is migrated from project.json to MSBuild.
dotnet migrate will either hang or throw the following exception:
root@08dd3e787323:/new# dotnet migrate
Migration failed.
Unhandled Exception: System.IO.DirectoryNotFoundException: Could not find a part of the path '/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/root/proc/7/fd/78'.
at System.IO.UnixFileSystem.FileSystemEnumerable`1.OpenDirectory(String fullPath)
at System.IO.UnixFileSystem.FileSystemEnumerable`1.<Enumerate>d__11.MoveNext()
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source, Int32& length)
at System.IO.DirectoryInfo.InternalGetDirectories(String searchPattern, SearchOption searchOption)
at System.IO.DirectoryInfo.GetDirectories(String searchPattern, SearchOption searchOption)
at Microsoft.DotNet.ProjectJsonMigration.ProjectDependencyFinder.GetPotentialProjects(IEnumerable`1 searchPaths)
at Microsoft.DotNet.ProjectJsonMigration.ProjectDependencyFinder.FindPossibleProjectDependencies(SlnFile slnFile, String projectJsonFilePath)
at Microsoft.DotNet.ProjectJsonMigration.ProjectDependencyFinder.ResolveDirectProjectDependenciesForFramework(Project project, NuGetFramework framework, IEnumerable`1 preResolvedProjects, SlnFile solutionFile)
at Microsoft.DotNet.ProjectJsonMigration.ProjectDependencyFinder.ResolveAllProjectDependenciesForFramework(ProjectDependency projectToResolve, NuGetFramework framework, IEnumerable`1 preResolvedProjects, SlnFile solutionFile)
at Microsoft.DotNet.ProjectJsonMigration.Rules.MigrateProjectDependenciesRule.MigrateProjectJsonProjectDependency(Project project, NuGetFramework framework, HashSet`1 migratedXProjDependencyNames, SlnFile solutionFile, ProjectRootElement outputMSBuildProject)
at Microsoft.DotNet.ProjectJsonMigration.Rules.MigrateProjectDependenciesRule.MigrateProjectJsonProjectDependencies(IEnumerable`1 projectContexts, HashSet`1 migratedXProjDependencyNames, SlnFile solutionFile, ProjectRootElement outputMSBuildProject)
at Microsoft.DotNet.ProjectJsonMigration.Rules.MigrateProjectDependenciesRule.Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
at Microsoft.DotNet.ProjectJsonMigration.DefaultMigrationRuleSet.Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
at Microsoft.DotNet.ProjectJsonMigration.ProjectMigrator.MigrateProject(MigrationSettings migrationSettings)
at Microsoft.DotNet.ProjectJsonMigration.ProjectMigrator.Migrate(MigrationSettings rootSettings, Boolean skipProjectReferences)
at Microsoft.DotNet.Tools.Migrate.MigrateCommand.Execute()
at Microsoft.DotNet.Tools.Migrate.MigrateCommand.<>c__DisplayClass35_0.<Run>b__0()
at Microsoft.DotNet.Cli.CommandLine.CommandLineApplication.Execute(String[] args)
at Microsoft.DotNet.Tools.Migrate.MigrateCommand.Run(String[] args)
at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
at Microsoft.DotNet.Cli.Program.Main(String[] args)
Aborted (core dumped)
dotnet --info output:
.NET Command Line Tools (1.0.0-rc4-004757)
Product Information:
Version: 1.0.0-rc4-004757
Commit SHA-1 hash: f69f0ed266
Runtime Environment:
OS Name: debian
OS Version: 8
OS Platform: Linux
RID: debian.8-x64
Base Path: /usr/share/dotnet/sdk/1.0.0-rc4-004757
It seems like you have a cyclic symlink somewhere. This is an issue called out at the GetDirectories API.
The host machine is a VM using the Azure image of Ubuntu 16.04 LTS, and docker was installed per the instructions at https://docs.docker.com/engine/installation/linux/ubuntu/. If there is a cyclic symlink, it's something that exists by default, so I think this scenario needs to work on this environment.
The cycle at /proc/[pid]/root/proc/[pid]/root/... appears to be by design:
/proc/[pid]/root
UNIX and Linux support the idea of a per-process root of the
filesystem, set by the chroot(2) system call. This file is a
symbolic link that points to the process's root directory, and
behaves in the same way as exe, and fd/*.
I tried to repro on another VM which should have been identical. However, on this VM when I run dotnet migrate inside the docker container, rather than crash it just hangs.
Ok, I understand why this happens. This happens because you created your new project at the root of the docker machine. If you create something like src/new and then put your project there, it will work.
Migration looks at the parent folder you are migration migration at, in this case / so that it can find dependencies for your project, which is why we are hitting this issue.
We had to add the GetDirectories call with SearchOptions.AllDirectories so that we could actually find dependencies for a project that were deeper on the folder structure than the project itself.
Can you try the work around I suggested?
Thanks, that worked. I will update this issue with the correct root cause: dotnet migrate fails if the app directory is at the root. This is a fairly common pattern in docker containers (e.g. see the instructions at https://hub.docker.com/r/microsoft/dotnet/).
This issue was moved to dotnet/cli-migrate#27
Most helpful comment
Thanks, that worked. I will update this issue with the correct root cause:
dotnet migratefails if the app directory is at the root. This is a fairly common pattern in docker containers (e.g. see the instructions at https://hub.docker.com/r/microsoft/dotnet/).