Sdk: dotnet tool install fails, if dotnet-sdk is on a read-only file system

Created on 13 Aug 2019  路  4Comments  路  Source: dotnet/sdk

Steps to reproduce

This happens, if the filesystem where dotnet-sdk is installed, is mounted read-only like on NixOS.
To reproduce,
mark AppHostTemplate/apphost as read-only on your dotnet-sdk installation.

chmod -w /nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/sdk/2.2.203/AppHostTemplate/apphost

Expected behavior

dotnet tool install -g dotnetsay install the tool

Actual behavior

dotnet tool install  -g dotnetsay  
Failed to create shell shim for tool 'dotnetsay': Failed to create tool shim for command 'dotnetsay': Access to the path '/home/bara/.dotnet/tools/dotnetsay' is denied.
Tool 'dotnetsay' failed to install.

Running it with strace, I see that the readonly permissions of the original file are applied, then the file is opened in read-write mode, which fails:

...
openat(AT_FDCWD, "/home/bara/.dotnet/tools/dotnetsay", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = 114
...
sendfile(114, 113, NULL, 111008)        = 111008
fstat(113, {st_mode=S_IFREG|0555, st_size=111008, ...}) = 0
utimensat(114, NULL, [{tv_sec=1565715605, tv_nsec=506049000} /* 2019-08-13T19:00:05.506049000+0200 */, {tv_sec=1, tv_nsec=0} /* 1970-01-01T01:00:01+0100 */], 0) = 0
fchmod(114, 0555)                       = 0
flock(114, LOCK_UN)                     = 0
close(114)                              = 0
flock(113, LOCK_UN)                     = 0
close(113)                              = 0
openat(AT_FDCWD, "/home/bara/.dotnet/tools/dotnetsay", O_RDWR|O_CLOEXEC) = -1 EACCES (Permission denied)
...

Environment data

dotnet --info output:

.NET Core SDK (reflecting any global.json):
 Version:   2.2.203
 Commit:    e5bab63eca

Runtime Environment:
 OS Name:     nixos
 OS Version:  19.09pre185176.1036dc66416
 OS Platform: Linux
 RID:         linux-x64
 Base Path:   /nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/sdk/2.2.203/

Host (useful for support):
  Version: 2.2.4
  Commit:  f95848e524

.NET Core SDKs installed:
  2.2.203 [/nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.2.4 [/nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.2.4 [/nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.2.4 [/nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

Most helpful comment

Thank you for the reply.

NixOS bases on nix package manager, I am using the dotnet-sdk package, which is based on the tar.gz download.
https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/dotnet/sdk/default.nix#L20

Nix strives to make building packages reproducible. It stores packages in /nix/store according to hash of its inputs (hash of dependencies + hash of source files). The files are read-only to prevent user errors and find problems, where installed programs modify their files, which could prevent reproducible builds.
There is a section in the manual for more overview: https://nixos.org/nix/manual/#ch-about-nix

Ensuring, the destination file is writable, after copying, before opening for writing, should fix this issue.
https://github.com/dotnet/cli/blob/v2.2.203/src/Microsoft.DotNet.Cli.Utils/EmbedAppNameInHost.cs#L53

All 4 comments

cc @wli3

I need to understand more on why NixOS will it mount as read only. And could you tell me how you get the SDK in detail? Like you install it via tar.gz and then mount it or there is a different package manager.

Many components in SDK are permission sensitive, and they have correct permission when using existing official supported method like apt-get, rpm, tar.gz and download script.

Thank you for the reply.

NixOS bases on nix package manager, I am using the dotnet-sdk package, which is based on the tar.gz download.
https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/dotnet/sdk/default.nix#L20

Nix strives to make building packages reproducible. It stores packages in /nix/store according to hash of its inputs (hash of dependencies + hash of source files). The files are read-only to prevent user errors and find problems, where installed programs modify their files, which could prevent reproducible builds.
There is a section in the manual for more overview: https://nixos.org/nix/manual/#ch-about-nix

Ensuring, the destination file is writable, after copying, before opening for writing, should fix this issue.
https://github.com/dotnet/cli/blob/v2.2.203/src/Microsoft.DotNet.Cli.Utils/EmbedAppNameInHost.cs#L53

It seams to be fixed in 3.1-preview2

Was this page helpful?
0 / 5 - 0 ratings