-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Make host look for RID-specific assets via a known list by default #84100
Conversation
Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov Issue DetailsHost probing algorithm portion of #83246 - looks for computed RID followed by known non-distro/version-specific RIDs based on the host's build. If an app targets net8.0 or above, using the probing algorithm is enabled by default. Below net7.0 keeps reading the RID fallback graph - this is in hostpolicy, so we could also say that regardless of what you target, if you are running on 8.0 (for example via roll forward), the algorithm is the default regardless, but I think the target pivot is clearer. As a backwards compat fallback, the runtime config property For example:
There's still one test case for multiple packages with/without RID assets (
|
a462360
to
7be2573
Compare
7be2573
to
e2c826b
Compare
d0d0c90
to
c78e438
Compare
c78e438
to
ca68832
Compare
Added When you commit this breaking change:
Tagging @dotnet/compat for awareness of the breaking change. |
cc @richlander |
Works for me. I don't have anything better to offer. |
Just a dump of thoughts on this change (and related topics): The automatic backward compatibility for < 8.0 means that we can never remove the RID graph from the framework itself, unless in the future we say that it's not valid to run really old apps on newest runtimes anymore. The host property also has the added complexity that if the app needs to do some of the special magic as defined in the spec, it would need to do two things - inject the RID graph into the app and set the host property, so that it's actually looked at. Should we maybe always read the RID graph if it's in the app itself? And only avoid reading it if it comes from the framework (with the explicit opt-in for rare cases). The proposal says that we will add the RID graph customizations into a new section in the There's another question about SCD apps - as designed, in theory the host property should work there as well, but that means the SDK will have to include the RID graph in the app. So we will need the SDK to be aware of the host property and react accordingly - assuming we don't want to include the RID graph by default (it would be really nice to be able to drop the RID graph in SCD by default). |
src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs
Show resolved
Hide resolved
Excellent point/insight. I was thinking about this yesterday when I read the PR description. I knew there was something more to discuss but I couldn't see around that corner. Help me understand ... Is the code in question in the actual apphost or in hostfxr (or similar binaries) in the runtime layout? That's clearly an important point for any plan. I didn't realize this. The first is from an FDD build and the second SCD. % cat dotnetapp.deps.json | wc -l
22
% cat dotnetapp.deps.json | wc -l
2911 Is there a functional reason why that is needed? The whole design point of SCD is that RID selection has already occurred. |
Indeed, great point. I do think it is reasonable to just say running on 8.0 means we don't read the RID graph by default. It just becomes a slightly broader breaking change.
In my mind, we would keep the distro compat as specified by the app separate from the 'read RID graph' setting. And with putting the distro compat in a new section, we would always read it if it exists.
I had thoughts kicking about around this that I hadn't put into words yet. The proposal currently mentions using the distro compat in combination with reading the existing RID graph, which would require merging. I see an end desire of this as not using/having the RID graph, but providing the new distro-compat mechanism to achieve the required behaviour instead. Given that, maybe the two options should be prioritized rather than combined. For example, if you say set the property to fall back to old behaviour, that is what we do, period. Otherwise (default behaviour), if the distro compat section exists, we will use that in combination with the algorithmic probing and if the distro compat section doesn't exist, we will just do the algorithmic probing. And then, eventually, we get rid of the runtimes section entirely. Thoughts?
To me, part of having the compat property is that it can be changed post-build/deployment. Perhaps something more incremental - this release: we don't read by default, next: don't include the RID graph by default for SCD, later (or rather optimistically, next): delete the RID graph entirely |
It is in
It allows the self-contained app to load portable components (for example, plugins using |
We could adopt the approach that any app that runs on net8+ global runtime gets the new behavior. That would cover the roll-forward case. Do we need to update |
Latest commit has it not checking the TFM - so algorithmic if using .NET 8 runtime. |
RID_CURRENT_ARCH_LIST("linux") | ||
RID_CURRENT_ARCH_LIST("unix") | ||
#else | ||
RID_CURRENT_ARCH_LIST(FALLBACK_HOST_OS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Microsoft's portable build, FALLBACK_HOST_OS
is linux
.
For a source-built .NET, FALLBACK_HOST_OS
matches the rid that is built for, like fedora.37
.
In the source-build case, we still want there to be a fallback to linux
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good catch. Adding a TARGET_LINUX
case should cover that, right?
#elif defined(TARGET_LINUX)
RID_CURRENT_ARCH_LIST("linux")
RID_CURRENT_ARCH_LIST("unix")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should.
No, both are TARGET_LINUX
we need something like:
RID_CURRENT_ARCH_LIST(FALLBACK_HOST_OS)
RID_CURRENT_ARCH_LIST("linux")
RID_CURRENT_ARCH_LIST("unix")
#elif defined(TARGET_OSX) | ||
RID_CURRENT_ARCH_LIST("osx") | ||
RID_CURRENT_ARCH_LIST("unix") | ||
#elif defined(TARGET_LINUX_MUSL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a non-portable build on a musl-based Linux, we also need to add the target rid for probing.
Co-authored-by: Adeel Mujahid <[email protected]>
ad24e7c
to
e48c8e7
Compare
This is now using the fixed list based on how the host/runtime is built (description updated). |
Working on the review, but general comment about the PR. Could you please update the PR's description to match the implemented behavior? For example the description still says that <8.0 apps would read the fallback graph, but the code will never read it by default (regardless of TFM). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good - thanks a lot!
src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs
Outdated
Show resolved
Hide resolved
// When not using the RID graph, the host uses the target OS for which it was built to determine applicable | ||
// RIDs that apply, so it can find both the arch-specific and the OS-only assets. | ||
// When using the RID graph, the host uses it to resolve any RID-specific assets that don't exactly match | ||
// the current RID, so the OS-only asset remains excluded if there are no fallbacks. | ||
string includedPath = null; | ||
string excludedPath = $"{CurrentOSAsset};{DifferentArchAsset}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe not for this change, but this test misses an interesting case.
If there's an asset for the current RID as determined by the host (so on windows it would be win10-x64) and there's no RID graph but it's instructed to read the RID graph, the asset should still resolve.
Currently the test never exercises this case, since the CurrentRid
will be the current build target RID (so on windows it would be win-x64), which is currently always portable RID, and thus never the one the host determines on its own.
It might be that on source-built runtime, where the build target is non-portable, it could happen that the host determined RID and the build target RID matches, in which case the test would fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at doing this, but it was a bit more complicated than I thought. We'd need to match the fallback RID, since the non-fallback computed RID is ignored if it doesn't exist in the RID graph. But I don't think the tests have a way of knowing the fallback RID right now.
I'll try to do this in a separate change - opened #86250
I had tried to update for that a bit ago, but apparently just made it kind of vague. Hopefully did a better job this time. |
This is not the best name. We try to match the API naming for names of config switches. We would not ever create A better name would be something like |
Ah, good point. Put up #86598 to rename |
Host probing algorithm portion of #83246 - looks for a list of RIDs based on how the host is built:
As long as an app is running on .NET 8.0 (or above), using the probing algorithm is enabled by default - regardless of its TFM. For example, if an app/component targets net7.0 (
TargetFrameworkMoniker=net7.0
), enables roll-forward on major version, and ends up running on .NET 8.0, the probing algorithm is still enabled by default.As a backwards compat fallback, the runtime config property
System.Host.Resolution.ReadRidGraph
(or another name suggestion) can be set totrue
, which will go back to the existing method of reading the RID fallback graph.Example of algorithmic probing:
or on a non-portable build of the host/runtmie on rhel.9: