From aa31cbab69119aa31c5bfc41b0a51a703efae75d Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Thu, 20 Sep 2018 03:00:08 -0700 Subject: [PATCH] Add separate document describing host probing logic Describes in detail how the host does probing for assets. Replace the existing short description of this in the shared store document. Fix some related comments in the code. Commit migrated from https://github.com/dotnet/core-setup/commit/399a130743ae420c453ae47cb57c6bf01241a7dd --- .../design-docs/DotNetCore-SharedPackageStore.md | 17 +----- docs/installer/design-docs/host-probing.md | 61 ++++++++++++++++++++++ src/installer/corehost/cli/deps_resolver.cpp | 5 +- 3 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 docs/installer/design-docs/host-probing.md diff --git a/docs/installer/design-docs/DotNetCore-SharedPackageStore.md b/docs/installer/design-docs/DotNetCore-SharedPackageStore.md index 2d8eda0..45b7aaa 100644 --- a/docs/installer/design-docs/DotNetCore-SharedPackageStore.md +++ b/docs/installer/design-docs/DotNetCore-SharedPackageStore.md @@ -102,21 +102,8 @@ Note that this is different from current behavior of `dotnet run` for an applica ## Host probe precedence -The host will probe in the following order of precedence for `dotnet run` and application activations post `dotnet publish`: - -+ `$CORE_SERVICING` on Unix or `%ProgramFiles(x86)%\coreservicing` on Windows. -+ Application Bin and Shared FX directory -+ `DOTNET_SHARED_STORE` in the chained order -+ Store locations - - The dotnet.exe relative shared package store - - The global shared package store - - ~~`DOTNET_HOSTING_OPTIMIZATION_CACHE` deprecated in favor of `DOTNET_SHARED_STORE`~~ -+ Additional Probing Paths - - `--additionalprobingpaths` specified in the command line - - `runtimeOptions.additionalProbingPaths` (includes NuGet cache probe specified by the CLI for `dotnet run`) - -**NOTE:** `--additionalprobingpaths` can be passed template paths like below and the host will interpret `|arch|/|tfm|` appropriately to look for assets: - `%USERPROFILE%\user\cache\|arch|\|tfm|` or `$HOME/user/cache/|arch|/|tfm|` +The host will probe in the order described in [host-probing](host-probing.md) for `dotnet run` and application activations post `dotnet publish`. + ## dotnet publish Publish will be enhanced to support a filter profile file specified as xml. This file explicitly lists all asset packages that need to be trimmed out of the publish output. The following are examples of how various application types can be published. diff --git a/docs/installer/design-docs/host-probing.md b/docs/installer/design-docs/host-probing.md new file mode 100644 index 0000000..db83a6a --- /dev/null +++ b/docs/installer/design-docs/host-probing.md @@ -0,0 +1,61 @@ +# .NET Core host probing + +The dotnet host uses probing when it searches for actual file on disk for a given asset. This happens for example when it tries to resolve assembly specified in `.deps.json` to a file on disk. The `.deps.json` specifies relative path of the asset in its library and also the relative path to the library (typically package name and version). Consider this small portion of `.deps.json` for example (only relevant parts, everything else omitted): +```json +{ + "targets": { + ".NETCoreApp,Version=v2.1": { + "Newtonsoft.Json/11.0.2": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + } + } + } + }, + "libraries": { + "Newtonsoft.Json/11.0.2": { + "type": "package", + "serviceable": true, + "path": "newtonsoft.json/11.0.2", + } + } +} +``` + +The library relative path in this case is `newtonsoft.json/11.0.2` and the asset relative path is `lib/netstandard2.0/Newtonsoft.Json.dll`. So the goal of the probing logic is to find the `Newtonsoft.Json.dll` file using the above relative paths. + +## Probing +The probing itself is done by going over a list of probing paths, which are ordered according to their priority. For each path, the host will append the relative parts of the path as per above and see if the file actually exists on the disk. +If the file is found, the probing is done, and the full path just resolved is stored. +If the file is not found, the probing continues with the next path on the list. +If all paths are tried and the asset is still not found this is reported as an error (with the exception of app's `.deps.json` asset, in which case it's ignored). + +## Probing paths +The list of probing paths ordered according to their priority. First path in the list below is tried first and so on. +* Servicing paths + Servicing paths are only used for serviceable assets, that is the corresponding library record must specify `serviceable: true`. + The base servicing path is + * On Windows x64 `%ProgramFiles(x86)%\coreservicing` + * On Windows x86 `%ProgramFiles%\coreservicing` + * Otherwise (Linux/Mac) `$CORE_SERVICING` + + Given the base servicing path, the probing paths are + * Servicing NI probe path `/|arch|` - this is used only for `runtime` assets + * Servicing normal probe path `/pkgs` - this is used for all assets + +* The application (or framework if we're resolving framework assets) directory +* Framework directories + If the app (or framework) has dependencies on frameworks, these frameworks are used as probing paths. + The order is from the higher level framework to lower level framework. The app is considered the highest level, it direct dependencies are next and so on. + For assets from frameworks, only that framework and lower level frameworks are considered. +* Shared store paths + * `$DOTNET_SHARED_STORE/|arch|/|tfm|` - The environment variable `DOTNET_SHARED_STORE` can contain multiple paths, in which case each is appended with `|arch|/|tfm|` and used as a probing path. + * If the app is executed through `dotnet.exe` then path relative to the directory with the `dotnet.exe` is used + * `/store/|arch|/|tfm|` + * On Windows, the global shared store is used + * If running in WOW64 mode - `%ProgramFiles(x86)%\dotnet\store\|arch|\|tfm|` + * Otherwise - `%ProgramFiles%\dotnet\store\|arch|\|tfm|` +* Additional probing paths + In these paths the `|arch|/|tfm|` string can be used and will be replaced with the actual values before using the path. + * `--additionalprobingpath` command line arguments + * `additionalProbingPaths` specified in `.runtimeconfig.json` for the app and each framework (highest to lowest) \ No newline at end of file diff --git a/src/installer/corehost/cli/deps_resolver.cpp b/src/installer/corehost/cli/deps_resolver.cpp index c2e0669..e83736c 100644 --- a/src/installer/corehost/cli/deps_resolver.cpp +++ b/src/installer/corehost/cli/deps_resolver.cpp @@ -178,13 +178,14 @@ void deps_resolver_t::setup_shared_store_probes( { if (pal::directory_exists(shared)) { - // Shared Store probe: DOTNET_SHARED_STORE + // Shared Store probe: DOTNET_SHARED_STORE environment variable m_probes.push_back(probe_config_t::lookup(shared)); } } if (pal::directory_exists(args.dotnet_shared_store)) { + // Path relative to the location of "dotnet.exe" if it's being used to run the app m_probes.push_back(probe_config_t::lookup(args.dotnet_shared_store)); } @@ -192,7 +193,7 @@ void deps_resolver_t::setup_shared_store_probes( { if (global_shared != args.dotnet_shared_store && pal::directory_exists(global_shared)) { - // Shared Store probe: DOTNET_SHARED_STORE + // Global store probe: the global location m_probes.push_back(probe_config_t::lookup(global_shared)); } } -- 2.7.4