dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.91k stars 4.63k forks source link

[NixOS] ping utility not found #83649

Closed Jiehong closed 1 year ago

Jiehong commented 1 year ago

Description

.NET, and by extension powershell, cannot find the ping command on NixOS, because it doesn't respect the PATH variable.

This breaks powershell's Test-Connection cmdlet.

Reproduction Steps

I discovered this issue while using powershell 7.2 in NixOS:

Test-Connection -TargetName localhost -IPv4

Test-Connection: Testing connection to computer 'localhost' failed: An exception occurred during a Ping request.
Test-Connection: Testing connection to computer 'localhost' failed: An exception occurred during a Ping request.
Test-Connection: Testing connection to computer 'localhost' failed: An exception occurred during a Ping request.
Test-Connection: Testing connection to computer 'localhost' failed: An exception occurred during a Ping request.

Checking the error:

Get-Error

Exception             : 
    Type           : System.Net.NetworkInformation.PingException
    Message        : Testing connection to computer 'localhost' failed: An exception occurred during a Ping request.
    InnerException : 
        Type       : System.PlatformNotSupportedException
        TargetSite : 
            Name          : GetPingProcess
            DeclaringType : System.Net.NetworkInformation.Ping
            MemberType    : Method
            Module        : System.Net.Ping.dll
        Message    : The system's ping utility could not be found.
        Source     : System.Net.Ping
        HResult    : -2146233031
        StackTrace : 
   at System.Net.NetworkInformation.Ping.GetPingProcess(IPAddress address, Byte[] buffer, Int32 timeout, PingOptions options)
   at System.Net.NetworkInformation.Ping.SendWithPingUtilityAsync(IPAddress address, Byte[] buffer, Int32 timeout, PingOptions options)
   at System.Net.NetworkInformation.Ping.SendPingAsyncCore(IPAddress address, Byte[] buffer, Int32 timeout, PingOptions options)
   at System.Net.NetworkInformation.Ping.SendPingAsyncInternal(IPAddress address, Int32 timeout, Byte[] buffer, PingOptions options)
    HResult        : -2146233079
TargetObject          : localhost
CategoryInfo          : ResourceUnavailable: (localhost:String) [Test-Connection], PingException
FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
InvocationInfo        : 
    MyCommand        : Test-Connection
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : 20
    Line             : Test-Connection -TargetName localhost -IPv4
    PositionMessage  : At line:1 char:1
                       + Test-Connection -TargetName localhost -IPv4
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    InvocationName   : Test-Connection
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo :

However, running ping localhost in powershell directly works just fine.

Expected behavior

.NET should find "ping" without issues, no matter where it is.

It seems to have special places only where it will look for stuff: https://github.com/dotnet/runtime/blob/6407eae2c9cda49c725e744f9628bca65b6e71d2/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs#L13

But on NixOS, it's not there:

which ping
/run/wrappers/bin/ping

But this is a special case only for some commands.

In general, NixOS links commands in /run/current-system/sw/bin (ping is there as expected):

stat /run/current-system/sw/bin/ping
  File: /run/current-system/sw/bin/ping -> /nix/store/gib6m18i3w1k5h619jww1dpvn93mavz5-iputils-20211215/bin/ping
  Size: 69          Blocks: 1          IO Block: 512    symbolic link
Device: 0,28    Inode: 1195624     Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-03-16 10:54:36.985177879 +0100
Modify: 1970-01-01 01:00:01.000000000 +0100
Change: 2023-03-16 10:54:36.968177896 +0100
 Birth: 2023-03-16 10:54:35.968178887 +0100

Solutions

Limitation: if running in a nix-shell environment, this won't work, because nix will add the command in the PATH only, and the actual path cannot be determined!

For example, nix-shell -p dbeaver generates a subshell in which dbeaver is available, but its path is /nix/store/75g823zvwj061w0q3amw8260s689cvd8-dbeaver-22.2.2/bin/dbeaver, and it's only available because PATH has been modified accordingly. That's just how nixos works.

Actual behavior

ping is not found, and Test-Connection fails.

Regression?

Unknown

Known Workarounds

No response

Configuration

Other information

No response

ghost commented 1 year ago

Tagging subscribers to this area: @dotnet/ncl See info in area-owners.md if you want to be subscribed.

Issue Details
### Description .NET, and by extension powershell, cannot find the `ping` command on NixOS, because it doesn't respect the PATH variable. This breaks powershell's Test-Connection cmdlet. ### Reproduction Steps I discovered this issue while using powershell 7.2 in NixOS: ``` Test-Connection -TargetName localhost -IPv4 Test-Connection: Testing connection to computer 'localhost' failed: An exception occurred during a Ping request. Test-Connection: Testing connection to computer 'localhost' failed: An exception occurred during a Ping request. Test-Connection: Testing connection to computer 'localhost' failed: An exception occurred during a Ping request. Test-Connection: Testing connection to computer 'localhost' failed: An exception occurred during a Ping request. ``` Checking the error: ``` Get-Error Exception : Type : System.Net.NetworkInformation.PingException Message : Testing connection to computer 'localhost' failed: An exception occurred during a Ping request. InnerException : Type : System.PlatformNotSupportedException TargetSite : Name : GetPingProcess DeclaringType : System.Net.NetworkInformation.Ping MemberType : Method Module : System.Net.Ping.dll Message : The system's ping utility could not be found. Source : System.Net.Ping HResult : -2146233031 StackTrace : at System.Net.NetworkInformation.Ping.GetPingProcess(IPAddress address, Byte[] buffer, Int32 timeout, PingOptions options) at System.Net.NetworkInformation.Ping.SendWithPingUtilityAsync(IPAddress address, Byte[] buffer, Int32 timeout, PingOptions options) at System.Net.NetworkInformation.Ping.SendPingAsyncCore(IPAddress address, Byte[] buffer, Int32 timeout, PingOptions options) at System.Net.NetworkInformation.Ping.SendPingAsyncInternal(IPAddress address, Int32 timeout, Byte[] buffer, PingOptions options) HResult : -2146233079 TargetObject : localhost CategoryInfo : ResourceUnavailable: (localhost:String) [Test-Connection], PingException FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand InvocationInfo : MyCommand : Test-Connection ScriptLineNumber : 1 OffsetInLine : 1 HistoryId : 20 Line : Test-Connection -TargetName localhost -IPv4 PositionMessage : At line:1 char:1 + Test-Connection -TargetName localhost -IPv4 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ InvocationName : Test-Connection CommandOrigin : Internal ScriptStackTrace : at , : line 1 PipelineIterationInfo : ``` However, running `ping localhost` in powershell directly works just fine. ### Expected behavior .NET should find "ping" without issues, no matter where it is. It seems to have special places only where it will look for stuff: https://github.com/dotnet/runtime/blob/6407eae2c9cda49c725e744f9628bca65b6e71d2/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs#L13 But on NixOS, it's not there: ```sh which ping /run/wrappers/bin/ping ``` But this is a special case only for some commands. In general, NixOS links commands in `/run/current-system/sw/bin` (`ping` is there as expected): ```sh stat /run/current-system/sw/bin/ping File: /run/current-system/sw/bin/ping -> /nix/store/gib6m18i3w1k5h619jww1dpvn93mavz5-iputils-20211215/bin/ping Size: 69 Blocks: 1 IO Block: 512 symbolic link Device: 0,28 Inode: 1195624 Links: 1 Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2023-03-16 10:54:36.985177879 +0100 Modify: 1970-01-01 01:00:01.000000000 +0100 Change: 2023-03-16 10:54:36.968177896 +0100 Birth: 2023-03-16 10:54:35.968178887 +0100 ``` ## Solutions - either dot net just should respect the PATH and find the command there - OR it should look for them in `/run/current-system/sw/bin` for NixOS. ### Actual behavior ping is not found, and Test-Connection fails. ### Regression? Unknown ### Known Workarounds _No response_ ### Configuration - .NET version: the one used by powershell 7.2.2 (but the code in master shows it's an issue even in latest) - NixOS 22.11 - x64 - Specific to NixOS - N/A ### Other information _No response_
Author: Jiehong
Assignees: -
Labels: `area-System.Net`, `untriaged`
Milestone: -
wfurt commented 1 year ago

That its unfortunate. I think the code does not follow PATH on purpose to avoid executing something unintentional. I think we may be able to add /run/current-system/sw/bin but I'm not sure we want to fiddle with unusual behavior of nix-shell. Workaround may be running app in a way that has access to raw sockets or execute the ping directly.

Jiehong commented 1 year ago

@wfurt : I think that you're right, just adding /run/current-system/sw/bin should be sufficient most of the time for NixOS