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

RFC: Add linux-musl-x64 Runtime Support #496

Open
botondbotos opened this issue Apr 22, 2024 · 3 comments · May be fixed by #502
Open

RFC: Add linux-musl-x64 Runtime Support #496

botondbotos opened this issue Apr 22, 2024 · 3 comments · May be fixed by #502
Labels
triage This issue is yet to be triaged by a maintainer

Comments

@botondbotos
Copy link

Previous issues
Add linux-musl-x64 Runtime Support

Is your feature request related to a problem? Please describe.
According to Compatibility / Operating System page Linux (musl) is not supported, however starting with Pact FFI Library 0.4.17 the libpact_ffi-linux-aarch64-musl.so and libpact_ffi-linux-x86_64-musl.so shared libraries are part of releases.

Describe the solution you'd like
Update pact-net to use latest Pact FFI Library 0.4.19 which has the libpact_ffi shared libraries and extend the NuGet package with additional runtime targets.

Breaking Changes
No

Potential Downsides/Caveats
n/a

Describe alternatives you've considered
n/a

Additional context
After replacing the runtimes/linux-x64/native/libpact_ffi.so file added by PactNet 5.0.0-beta.2 package with libpact_ffi-linux-x86_64-musl.so I was able to successfully run pact-net tests inside Docker using mcr.microsoft.com/dotnet/sdk:6.0.421-alpine3.19-amd64

@botondbotos botondbotos added the triage This issue is yet to be triaged by a maintainer label Apr 22, 2024
@adamrodger
Copy link
Contributor

Currently there is no reliable way to detect libc vs musl during a .Net restore operation and therefore no reliable way to ensure the correct libpact binary is restored. That makes this issue currently infeasible until a reliable way of doing that detection is found.

@botondbotos
Copy link
Author

botondbotos commented May 27, 2024

Could you please help me understand why it is preferred to restore the correct pact_ffi package over picking the correct one at runtime?
I have a PoC implemented, which is addressing the issue of musl support: #497 (comment)
One of the drawbacks is that all native packages need to be deployed, but the runtime can pick the correct one.

@adamrodger
Copy link
Contributor

That's the design of the FFI packaging, so that the correct binary is restored to the bin folder when the NuGet is installed. That means we're leaning on existing features provided in MSBuild instead of rolling our own detection code, which is bound to be worse.

I'm not sure how runtime vs restore time is a distinction here anyway? Either way there's no reliable way to detect libc vs musl, because if there was you could use it with either style. Both call in to .Net APIs to determine the OS/arch currently, but there's no API to determine libc vs musl.

I can understand why that is also - .Net itself doesn't need to worry about that because your code is all IL and it's the installed runtime that matters. Given we're doing native interop though then it does matter to us, so the missing API matters.

YOU54F added a commit to YOU54F/pact-net that referenced this issue May 29, 2024
## Rationale

pact-reference has introduced musl and arm64 based ffi libraries for linux

- pact-foundation/pact-reference#416

Tracking Issue

- pact-foundation/roadmap#30

## Issues Resolved

fixes pact-foundation#498
fixes pact-foundation#496
fixes pact-foundation#500
fixes pact-foundation#374
fixes pact-foundation#387

## Backwards Compatibility

Linux glibc based hosts take precedence, so if any error occurs during musl
detection. I do not anticipate breaking changes for users

## Implementation notes

### .NET notes

- Docs
  - [Uses MSBuild Exec task](https://learn.microsoft.com/en-us/visualstudio/msbuild/exec-task?view=vs-2022)
- MSBuild Blog Posts
  - [Cross-Platform Build Events in .NET Core using MSBuild](https://jeremybytes.blogspot.com/2020/05/cross-platform-build-events-in-net-core.html)
  - [MSBuild 101: Using the exit code from a command](https://www.creepingcoder.com/2020/06/01/msbuild-101-using-the-exit-code-from-a-command/)
- Stack OverFlow
  - [Set PropertyGroup property to Exec output](https://stackoverflow.com/questions/76583824/set-propertygroup-property-to-exec-output)
- .NET runtime musl detection code
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/mono/llvm/llvm-init.proj\#L7
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs\#L78t

### Conditions for execution

musl detection will run if

- if linux
- if /lib/ld-musl-(x86_64|aarch64).so.1 exists
- if ldd bin/sh | grep musl is true (musl lib is loaded, rather than glibc)

will continue on error, reverting back to glibc based libaries.

### Supported musl targets

should work for multiple musl based distroes if

- /lib/ld-musl-(x86_64|aarch64).so.1 exists
- ldd is available (available by default in alpine images)

Tested on Alpine ARM64 / AMD64.

## Caveats

- [.NET does not run under QEMU](https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md#qemu) affecting the ability to test multi-arch from a single system
- .NET restore can take a long time when running under containers.
  - [Workaround](NuGet/Home#13062 (comment)): Set `DOTNET_NUGET_SIGNATURE_VERIFICATION` to `false`

## Compatibility

### Operating System

Due to using a shared native library instead of C# for the main Pact logic only certain OSs are supported:

| OS           | Arch        | Support                                                            |
| ------------ | ----------- | -------------------------------------------------------------------|
| Windows      | x86         | ❌ No                                                              |
| Windows      | x64         | ✔️ Yes                                                              |
| Linux (libc) | x86         | ❌ No                                                              |
| Linux (libc) | x64         | ✔️ Yes                                                              |
| Linux (musl) | x64         | ✔️ Yes (Tier 2)*                                                    |
| Linux (libc) | ARM         | ✔️ Yes (Tier 3)*                                                    |
| Linux (musl) | ARM         | ✔️ Yes (Tier 3)*                                                    |
| OSX          | x64         | ✔️ Yes                                                              |
| OSX          | ARM (M1/M2) | ✔️ Yes                                                              |

#### Support

- Tier 1
  - Established
  - Full CI/CD support.
  - Users should not encounter issues
  - Full reproducible examples running in CI, should be provided by users raising issues
  - If using musl targets, users should attempt the same test on a libc target (such as debian)
- Tier 2
  - Recently introduced
  - Full CI/CD support.
  - Users may encounter issues
  - Full reproducible examples running in CI, should be provided by users raising issues
  - If using musl targets, users should attempt the same test on a libc target (such as debian)
- Tier 3
  - Recently introduced, No/limited CI/CD support.
  - Users may encounter issues
  - Full reproducible examples which can be run by maintainers locally, should be provided by users raising issues
@YOU54F YOU54F linked a pull request May 29, 2024 that will close this issue
YOU54F added a commit to YOU54F/pact-net that referenced this issue Sep 24, 2024
## Rationale

pact-reference has introduced musl and arm64 based ffi libraries for linux

- pact-foundation/pact-reference#416

Tracking Issue

- pact-foundation/roadmap#30

## Issues Resolved

fixes pact-foundation#498
fixes pact-foundation#496
fixes pact-foundation#500
fixes pact-foundation#374
fixes pact-foundation#387

## Backwards Compatibility

Linux glibc based hosts take precedence, so if any error occurs during musl
detection. I do not anticipate breaking changes for users

## Implementation notes

### .NET notes

- Docs
  - [Uses MSBuild Exec task](https://learn.microsoft.com/en-us/visualstudio/msbuild/exec-task?view=vs-2022)
- MSBuild Blog Posts
  - [Cross-Platform Build Events in .NET Core using MSBuild](https://jeremybytes.blogspot.com/2020/05/cross-platform-build-events-in-net-core.html)
  - [MSBuild 101: Using the exit code from a command](https://www.creepingcoder.com/2020/06/01/msbuild-101-using-the-exit-code-from-a-command/)
- Stack OverFlow
  - [Set PropertyGroup property to Exec output](https://stackoverflow.com/questions/76583824/set-propertygroup-property-to-exec-output)
- .NET runtime musl detection code
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/mono/llvm/llvm-init.proj\#L7
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs\#L78t

### Conditions for execution

musl detection will run if

- if linux
- if /lib/ld-musl-(x86_64|aarch64).so.1 exists
- if ldd bin/sh | grep musl is true (musl lib is loaded, rather than glibc)

will continue on error, reverting back to glibc based libaries.

### Supported musl targets

should work for multiple musl based distroes if

- /lib/ld-musl-(x86_64|aarch64).so.1 exists
- ldd is available (available by default in alpine images)

Tested on Alpine ARM64 / AMD64.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage This issue is yet to be triaged by a maintainer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants