From 15c89d44cca58111250281fc3df1745f3915b217 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Thu, 20 Jun 2024 16:04:00 -0700 Subject: [PATCH 1/8] Add doc for embedding install location options in apphost --- proposed/apphost-embed-install-location.md | 158 +++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 proposed/apphost-embed-install-location.md diff --git a/proposed/apphost-embed-install-location.md b/proposed/apphost-embed-install-location.md new file mode 100644 index 000000000..ed3d7b226 --- /dev/null +++ b/proposed/apphost-embed-install-location.md @@ -0,0 +1,158 @@ +# Add ability to embed install location options in apphost + +There have been numerous requests around being able to customize how/where the +.NET root path will be determined for a an application. This document describes +a proposed mechanism for basic configuration of how `apphost` will search for +the .NET install location. + +Goals: + +- Enable developers to build an app and configure it such that it can: + - Only consider global .NET installs + - Always look at a relative path for a .NET install +- Create a building block for a fuller, SDK-supported experience that should fit +in regardless of where we land for the full experience + +Non-goals: + +- SDK support for layout and deployment of the app with a runtime files in a +corresponding relative path +- SDK and project system experience for building a set of applications using the +same custom runtime install location + +Related: + +- [dotnet/runtime#2572](https://github.com/dotnet/runtime/issues/2572) +- [dotnet/runtime#3453](https://github.com/dotnet/runtime/issues/3453) +- [dotnet/runtime#53834](https://github.com/dotnet/runtime/issues/53834) +- [dotnet/runtime#64430](https://github.com/dotnet/runtime/issues/64430) +- [dotnet/runtime#70975](https://github.com/dotnet/runtime/issues/70975) +- [dotnet/runtime#86801](https://github.com/dotnet/runtime/issues/86801) + +## State in .NET 8 + +The current state is described in detail in +[install-locations](https://github.com/dotnet/designs/blob/main/accepted/2020/install-locations.md) +and [install-locations-per-architecture](https://github.com/dotnet/designs/blob/main/accepted/2021/install-locations-per-architecture.md) + +At a high level, the process and priority for `apphost` determining the install +location is: + + 1. App-local + - Look for the runtime in the app's folder (self-contained apps) + 2. Environment variables + - Read the `DOTNET_ROOT_` and `DOTNET_ROOT` environment variables + 3. Global install (registered) + - Check for a registered install - registry key on Windows or a install + location file on non-Windows + 4. Global install (default) + - Fall back to a well-known default install location based on the platform + +## Embedded install location options for `apphost` + +Every `apphost` already has a placeholder that gets rewritten to contain the app +binary path during build (that is, `dotnet build`). This proposal adds another +placeholder which would represent the optional configuration of search locations +and embedded relative path to an install location. Like the existing placeholder +placeholder, it would conditionally be rewritten during build based on the app's +settings. This is similar to the proposal in [dotnet/runtime#64430](https://github.com/dotnet/runtime/issues/64430), +but with additional configuration of which search locations to use. + +### Configuration of search locations + +Some applications do not want to use all the default search locations when they +are deployed - for example, [dotnet/runtime#86801](https://github.com/dotnet/runtime/issues/86801). + +We can allow selection of which search locations the `apphost` will use. When +search locations are configured, only the specified locations will be searched. + +```c++ +enum search_location +{ + default = 0, + app_local = 1 << 0, + embedded = 1 << 1, + environment_variables = 1 << 2, + global = 1 << 3, +}; +``` + +The behaviour corresponding to the `default` value is defined by the `apphost`. +It is currently `app_local | environment_variables | global`. + +The search location could be specified via a property in the project: + +```xml +Global +``` + +where the valid values are `AppLocal`, `Embedded`, `EnvironmentVariables`, or +`Global`. Multiple values can be specified, delimited by semi-colons. + +When a value is specified, only those locations will be used. For example, if +`Global` is specified, `apphost` will only look at global install locations, not +app-local, at any embedded path, or at environment variables. + +### Embedded relative path to install location + +When a relative path is embedded and the `apphost` is [configured to look at it](#configuration-of-search-locations), +that path will be used as the .NET install root when running the application. + +The install location could be specified via a property in the project: + +```xml +./path/to/runtime, +``` + +Setting this implies `AppHostDotNetSearch=Embedded`. If `AppHostDotNetSearch` is +explicitly set to a value that does not include `Embedded`, `AppHostDotNetRoot` +is meaningless - the SDK will not write the relative path into the `apphost` +nd the `apphost` will not check for an embedded relative path. + +## Updated behaviour + +At a high level, the updated process and priority for `apphost` determining the +install location would be: + + 1. App-local, if search location not configured + - Look for the runtime in the app's folder (self-contained apps) + 2. Embedded, if specified as a search location + - Use the path embedded into `apphost`, relative to the app location + 3. Environment variables, if search location not configured or if set as a + search location + - Read the `DOTNET_ROOT_` and `DOTNET_ROOT` environment variables + 4. Global install (registered), if search location not configured or if set as + a search location + - Check for a registered install - registry key on Windows or a install + location file on non-Windows + 5. Global install(default), if search location not configured or if set as a + search location + - Fall back to a well-known default install location based on the platform + +Be default - that is, without any embedded install location options - the +effective behaviour remains as in the [current state](#state-in-net-8). + +## Considerations + +### Writing embedded options on build + +This proposal writes the install location options in the `apphost` on `build`. +Without SDK support for constructing the layout, this means that if a developer +specifies an embedded relative install location path, it is up to them to create +a layout with the runtime in the expected location relative to the app output as +part of their build. Otherwise, running the app immediately after build would +not work. Another possible option is to only rewrite on `publish`, but that may +introduce another confusing difference between `build` and `publish`. Currently, +the `apphost` is the same between `build` and `publish` (with the exception of +single-file, which is only a `publish` scenario). + +### Other hosts + +This proposal is only for `apphost`. It is not relevant for `singlefilehost`, as +that has the runtime itself statically linked. Other hosts (`comhost`,`ijwhost`) +are also not included. In theory, other hosts could be given the same treatment, +but we do not have feedback for scenarios using them. They also do not have the +app-local search or the existing requirment of being partially re-written via a +known placeholder. Changing them would add significant complexity without a +compelling scenario. If we see confusion here, we could add an SDK warning if +`AppHostDotNetRoot` or `AppHostDotNetSearch` is set for those projects. From ce02251cd05a8477f88d845f75283c774c246d9d Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Fri, 21 Jun 2024 10:32:53 -0700 Subject: [PATCH 2/8] Update index.md --- INDEX.md | 1 + 1 file changed, 1 insertion(+) diff --git a/INDEX.md b/INDEX.md index 07e68ea65..9aa18f133 100644 --- a/INDEX.md +++ b/INDEX.md @@ -98,6 +98,7 @@ Use update-index to regenerate it: |Year|Title|Owners| |----|-----|------| +| | [Add ability to embed install location options in apphost](proposed/apphost-embed-install-location.md) | | | | [Provide SDK hint paths in global.json](proposed/local-sdk-global-json.md) | | | | [Rate limits](proposed/rate-limit.md) | [John Luo](https://github.com/juntaoluo), [Sourabh Shirhatti](https://github.com/shirhatti) | | | [Readonly references in C# and IL verification.](proposed/verifiable-ref-readonly.md) | | From 261a89dbbb39bbc4382675706d2dfb0eee1fa260 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Fri, 21 Jun 2024 11:59:56 -0700 Subject: [PATCH 3/8] Add prefix to enum, fix typos --- proposed/apphost-embed-install-location.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/proposed/apphost-embed-install-location.md b/proposed/apphost-embed-install-location.md index ed3d7b226..e37f47cce 100644 --- a/proposed/apphost-embed-install-location.md +++ b/proposed/apphost-embed-install-location.md @@ -53,9 +53,9 @@ location is: Every `apphost` already has a placeholder that gets rewritten to contain the app binary path during build (that is, `dotnet build`). This proposal adds another placeholder which would represent the optional configuration of search locations -and embedded relative path to an install location. Like the existing placeholder -placeholder, it would conditionally be rewritten during build based on the app's -settings. This is similar to the proposal in [dotnet/runtime#64430](https://github.com/dotnet/runtime/issues/64430), +and embedded relative path to an install location. Same as existing placeholder, +it would conditionally be rewritten during build based on the app's settings. +This is similar to the proposal in [dotnet/runtime#64430](https://github.com/dotnet/runtime/issues/64430), but with additional configuration of which search locations to use. ### Configuration of search locations @@ -66,14 +66,14 @@ are deployed - for example, [dotnet/runtime#86801](https://github.com/dotnet/run We can allow selection of which search locations the `apphost` will use. When search locations are configured, only the specified locations will be searched. -```c++ +```c enum search_location { - default = 0, - app_local = 1 << 0, - embedded = 1 << 1, - environment_variables = 1 << 2, - global = 1 << 3, + sl_default = 0, + sl_app_local = 1 << 0, + sl_embedded = 1 << 1, + sl_environment_variables = 1 << 2, + sl_global = 1 << 3, }; ``` @@ -107,7 +107,7 @@ The install location could be specified via a property in the project: Setting this implies `AppHostDotNetSearch=Embedded`. If `AppHostDotNetSearch` is explicitly set to a value that does not include `Embedded`, `AppHostDotNetRoot` is meaningless - the SDK will not write the relative path into the `apphost` -nd the `apphost` will not check for an embedded relative path. +and the `apphost` will not check for an embedded relative path. ## Updated behaviour From 77a1ff4220fe0e9551d8f05fab356ee453d4a1e9 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 24 Jun 2024 08:30:19 -0700 Subject: [PATCH 4/8] Write options on `publish` only --- proposed/apphost-embed-install-location.md | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/proposed/apphost-embed-install-location.md b/proposed/apphost-embed-install-location.md index e37f47cce..0eb47d264 100644 --- a/proposed/apphost-embed-install-location.md +++ b/proposed/apphost-embed-install-location.md @@ -54,7 +54,8 @@ Every `apphost` already has a placeholder that gets rewritten to contain the app binary path during build (that is, `dotnet build`). This proposal adds another placeholder which would represent the optional configuration of search locations and embedded relative path to an install location. Same as existing placeholder, -it would conditionally be rewritten during build based on the app's settings. +it would conditionally be rewritten based on the app's settings. For this case, +it would [only be done on `publilsh`](#writing-options-on-publish) currently. This is similar to the proposal in [dotnet/runtime#64430](https://github.com/dotnet/runtime/issues/64430), but with additional configuration of which search locations to use. @@ -134,17 +135,16 @@ effective behaviour remains as in the [current state](#state-in-net-8). ## Considerations -### Writing embedded options on build - -This proposal writes the install location options in the `apphost` on `build`. -Without SDK support for constructing the layout, this means that if a developer -specifies an embedded relative install location path, it is up to them to create -a layout with the runtime in the expected location relative to the app output as -part of their build. Otherwise, running the app immediately after build would -not work. Another possible option is to only rewrite on `publish`, but that may -introduce another confusing difference between `build` and `publish`. Currently, -the `apphost` is the same between `build` and `publish` (with the exception of -single-file, which is only a `publish` scenario). +### Writing options on publish + +This proposal writes the install location options in the `apphost` on `publish`. +Without SDK support for constructing the layout, updating on `build` would cause +the app to stop working in inner dev loop scenarios (running from output folder, +`dotnet run`, F5) unless they create a layout with the runtime in the expected +location relative to the app output as part of their build. This introduces a +difference between `build` and `publish` for `apphost` (currently, it is the +same between `build` and `publish` - with the exception of single-file, which is +nly a `publish` scenario), but once SDK support is added it can be reconciled. ### Other hosts From 7f421cc3a5e3f0deaff72a6236b0cf4c19898d89 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 24 Jun 2024 08:40:19 -0700 Subject: [PATCH 5/8] Embedded -> AppRelative --- proposed/apphost-embed-install-location.md | 49 ++++++++-------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/proposed/apphost-embed-install-location.md b/proposed/apphost-embed-install-location.md index 0eb47d264..ee9bc2a81 100644 --- a/proposed/apphost-embed-install-location.md +++ b/proposed/apphost-embed-install-location.md @@ -53,9 +53,9 @@ location is: Every `apphost` already has a placeholder that gets rewritten to contain the app binary path during build (that is, `dotnet build`). This proposal adds another placeholder which would represent the optional configuration of search locations -and embedded relative path to an install location. Same as existing placeholder, -it would conditionally be rewritten based on the app's settings. For this case, -it would [only be done on `publilsh`](#writing-options-on-publish) currently. +and app-relative path to an install location. Same as existing placeholder, it +would conditionally be rewritten based on the app's settings. This rewrite would +[only be done on `publish`](#writing-options-on-publish) of the app currently. This is similar to the proposal in [dotnet/runtime#64430](https://github.com/dotnet/runtime/issues/64430), but with additional configuration of which search locations to use. @@ -67,48 +67,35 @@ are deployed - for example, [dotnet/runtime#86801](https://github.com/dotnet/run We can allow selection of which search locations the `apphost` will use. When search locations are configured, only the specified locations will be searched. -```c -enum search_location -{ - sl_default = 0, - sl_app_local = 1 << 0, - sl_embedded = 1 << 1, - sl_environment_variables = 1 << 2, - sl_global = 1 << 3, -}; -``` - -The behaviour corresponding to the `default` value is defined by the `apphost`. -It is currently `app_local | environment_variables | global`. - The search location could be specified via a property in the project: ```xml Global ``` -where the valid values are `AppLocal`, `Embedded`, `EnvironmentVariables`, or +where the valid values are `AppLocal`, `AppRelative`, `EnvironmentVariables`, or `Global`. Multiple values can be specified, delimited by semi-colons. When a value is specified, only those locations will be used. For example, if `Global` is specified, `apphost` will only look at global install locations, not -app-local, at any embedded path, or at environment variables. +app-local, at any app-relative path, or at environment variables. -### Embedded relative path to install location +### App-relative path to install location -When a relative path is embedded and the `apphost` is [configured to look at it](#configuration-of-search-locations), -that path will be used as the .NET install root when running the application. +When a relative path is written into an `apphost` which is [configured to look +at it](#configuration-of-search-locations), that path will be used as the .NET +install root when running the application. The install location could be specified via a property in the project: ```xml -./path/to/runtime, +./relative/path/to/runtime, ``` -Setting this implies `AppHostDotNetSearch=Embedded`. If `AppHostDotNetSearch` is -explicitly set to a value that does not include `Embedded`, `AppHostDotNetRoot` -is meaningless - the SDK will not write the relative path into the `apphost` -and the `apphost` will not check for an embedded relative path. +Setting this implies `AppHostDotNetSearch=AppRelative`. If `AppHostDotNetSearch` +is explicitly set to a value that does not include `AppRelative`, then setting +`AppHostRelativeDotNet` is meaningless - the SDK will not write the relative +path into the `apphost` and the `apphost` will not check for a relative path. ## Updated behaviour @@ -117,8 +104,8 @@ install location would be: 1. App-local, if search location not configured - Look for the runtime in the app's folder (self-contained apps) - 2. Embedded, if specified as a search location - - Use the path embedded into `apphost`, relative to the app location + 2. App-relative, if specified as a search location + - Use the path written into `apphost`, relative to the app location 3. Environment variables, if search location not configured or if set as a search location - Read the `DOTNET_ROOT_` and `DOTNET_ROOT` environment variables @@ -130,7 +117,7 @@ install location would be: search location - Fall back to a well-known default install location based on the platform -Be default - that is, without any embedded install location options - the +Be default - that is, without any configured install location options - the effective behaviour remains as in the [current state](#state-in-net-8). ## Considerations @@ -155,4 +142,4 @@ but we do not have feedback for scenarios using them. They also do not have the app-local search or the existing requirment of being partially re-written via a known placeholder. Changing them would add significant complexity without a compelling scenario. If we see confusion here, we could add an SDK warning if -`AppHostDotNetRoot` or `AppHostDotNetSearch` is set for those projects. +`AppHostRelativeDotNet` or `AppHostDotNetSearch` is set for those projects. From 1bf90a7a2ec32e63ce6494a8b4f5bbf47b049422 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 1 Jul 2024 10:55:58 -0700 Subject: [PATCH 6/8] Clarify setting AppHostRelativeDotNet implies AppHostDotNetSearch=AppRelative --- proposed/apphost-embed-install-location.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/proposed/apphost-embed-install-location.md b/proposed/apphost-embed-install-location.md index ee9bc2a81..0f46171d0 100644 --- a/proposed/apphost-embed-install-location.md +++ b/proposed/apphost-embed-install-location.md @@ -92,8 +92,15 @@ The install location could be specified via a property in the project: ./relative/path/to/runtime, ``` -Setting this implies `AppHostDotNetSearch=AppRelative`. If `AppHostDotNetSearch` -is explicitly set to a value that does not include `AppRelative`, then setting +Setting this implies `AppHostDotNetSearch=AppRelative`. This means that only the +relative path will be considered. If a .NET install is not found at the relative +path, other locations - environment variables, global install locations - will +not be considered and the app will fail to run. + +`AppHostDotNetSearch` could also be explicitly set to include a fallback - for +example, `AppHostDotNetSearch=AppRelative;Global` would look at the relative +path and, if it is not found, the global locations. If `AppHostDotNetSearch` is +explicitly set to a value that does not include `AppRelative`, then setting `AppHostRelativeDotNet` is meaningless - the SDK will not write the relative path into the `apphost` and the `apphost` will not check for a relative path. From 134b7f64eca02b684895fdf05d0b6969db14642f Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 2 Jul 2024 08:32:40 -0700 Subject: [PATCH 7/8] Apply suggestions from code review Co-authored-by: Jan Jones --- proposed/apphost-embed-install-location.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposed/apphost-embed-install-location.md b/proposed/apphost-embed-install-location.md index 0f46171d0..c21e9a9f9 100644 --- a/proposed/apphost-embed-install-location.md +++ b/proposed/apphost-embed-install-location.md @@ -1,7 +1,7 @@ # Add ability to embed install location options in apphost There have been numerous requests around being able to customize how/where the -.NET root path will be determined for a an application. This document describes +.NET root path will be determined for an application. This document describes a proposed mechanism for basic configuration of how `apphost` will search for the .NET install location. @@ -43,7 +43,7 @@ location is: 2. Environment variables - Read the `DOTNET_ROOT_` and `DOTNET_ROOT` environment variables 3. Global install (registered) - - Check for a registered install - registry key on Windows or a install + - Check for a registered install - registry key on Windows or an install location file on non-Windows 4. Global install (default) - Fall back to a well-known default install location based on the platform @@ -89,7 +89,7 @@ install root when running the application. The install location could be specified via a property in the project: ```xml -./relative/path/to/runtime, +./relative/path/to/runtime ``` Setting this implies `AppHostDotNetSearch=AppRelative`. This means that only the @@ -120,11 +120,11 @@ install location would be: a search location - Check for a registered install - registry key on Windows or a install location file on non-Windows - 5. Global install(default), if search location not configured or if set as a + 5. Global install (default), if search location not configured or if set as a search location - Fall back to a well-known default install location based on the platform -Be default - that is, without any configured install location options - the +By default - that is, without any configured install location options - the effective behaviour remains as in the [current state](#state-in-net-8). ## Considerations @@ -138,12 +138,12 @@ the app to stop working in inner dev loop scenarios (running from output folder, location relative to the app output as part of their build. This introduces a difference between `build` and `publish` for `apphost` (currently, it is the same between `build` and `publish` - with the exception of single-file, which is -nly a `publish` scenario), but once SDK support is added it can be reconciled. +only a `publish` scenario), but once SDK support is added it can be reconciled. ### Other hosts This proposal is only for `apphost`. It is not relevant for `singlefilehost`, as -that has the runtime itself statically linked. Other hosts (`comhost`,`ijwhost`) +that has the runtime itself statically linked. Other hosts (`comhost`, `ijwhost`) are also not included. In theory, other hosts could be given the same treatment, but we do not have feedback for scenarios using them. They also do not have the app-local search or the existing requirment of being partially re-written via a From 475caf66b84eb51af93c8d4b71925105d6618931 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 2 Jul 2024 14:06:26 -0700 Subject: [PATCH 8/8] Update proposed/apphost-embed-install-location.md Co-authored-by: Aaron Robinson --- proposed/apphost-embed-install-location.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposed/apphost-embed-install-location.md b/proposed/apphost-embed-install-location.md index c21e9a9f9..7ed141aaa 100644 --- a/proposed/apphost-embed-install-location.md +++ b/proposed/apphost-embed-install-location.md @@ -146,7 +146,7 @@ This proposal is only for `apphost`. It is not relevant for `singlefilehost`, as that has the runtime itself statically linked. Other hosts (`comhost`, `ijwhost`) are also not included. In theory, other hosts could be given the same treatment, but we do not have feedback for scenarios using them. They also do not have the -app-local search or the existing requirment of being partially re-written via a +app-local search or the existing requirement of being partially re-written via a known placeholder. Changing them would add significant complexity without a compelling scenario. If we see confusion here, we could add an SDK warning if `AppHostRelativeDotNet` or `AppHostDotNetSearch` is set for those projects.