Backport ANCM environment variable additions (#20006)

This commit is contained in:
Brennan 2020-03-27 10:56:49 -07:00 committed by GitHub
parent 1040be3588
commit 654cf06615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 131 additions and 14 deletions

View File

@ -54,6 +54,11 @@ ShimOptions::ShimOptions(const ConfigurationSource &configurationSource) :
.value_or(environmentVariables[CS_ASPNETCORE_ENVIRONMENT]);
const auto dotnetEnvironment = Environment::GetEnvironmentVariableValue(CS_DOTNET_ENVIRONMENT)
.value_or(environmentVariables[CS_DOTNET_ENVIRONMENT]);
// We prefer the environment variables for LAUNCHER_PATH and LAUNCHER_ARGS
m_strProcessPath = Environment::GetEnvironmentVariableValue(CS_ANCM_LAUNCHER_PATH)
.value_or(m_strProcessPath);
m_strArguments = Environment::GetEnvironmentVariableValue(CS_ANCM_LAUNCHER_ARGS)
.value_or(m_strArguments);
auto detailedErrorsEnabled = equals_ignore_case(L"1", detailedErrors) || equals_ignore_case(L"true", detailedErrors);
auto aspnetCoreEnvironmentEnabled = equals_ignore_case(L"Development", aspnetCoreEnvironment);

View File

@ -33,6 +33,8 @@
#define CS_ASPNETCORE_DETAILEDERRORS L"ASPNETCORE_DETAILEDERRORS"
#define CS_ASPNETCORE_ENVIRONMENT L"ASPNETCORE_ENVIRONMENT"
#define CS_DOTNET_ENVIRONMENT L"DOTNET_ENVIRONMENT"
#define CS_ANCM_LAUNCHER_PATH L"ANCM_LAUNCHER_PATH"
#define CS_ANCM_LAUNCHER_ARGS L"ANCM_LAUNCHER_ARGS"
class ConfigurationSection: NonCopyable
{

View File

@ -4,6 +4,7 @@
#include "InProcessOptions.h"
#include "InvalidOperationException.h"
#include "EventLog.h"
#include "Environment.h"
HRESULT InProcessOptions::Create(
IHttpServer& pServer,
@ -51,6 +52,11 @@ InProcessOptions::InProcessOptions(const ConfigurationSource &configurationSourc
auto const aspNetCoreSection = configurationSource.GetRequiredSection(CS_ASPNETCORE_SECTION);
m_strArguments = aspNetCoreSection->GetString(CS_ASPNETCORE_PROCESS_ARGUMENTS).value_or(CS_ASPNETCORE_PROCESS_ARGUMENTS_DEFAULT);
m_strProcessPath = aspNetCoreSection->GetRequiredString(CS_ASPNETCORE_PROCESS_EXE_PATH);
// We prefer the environment variables for LAUNCHER_PATH and LAUNCHER_ARGS
m_strProcessPath = Environment::GetEnvironmentVariableValue(CS_ANCM_LAUNCHER_PATH)
.value_or(m_strProcessPath);
m_strArguments = Environment::GetEnvironmentVariableValue(CS_ANCM_LAUNCHER_ARGS)
.value_or(m_strArguments);
m_fStdoutLogEnabled = aspNetCoreSection->GetRequiredBool(CS_ASPNETCORE_STDOUT_LOG_ENABLED);
m_struStdoutLogFile = aspNetCoreSection->GetRequiredString(CS_ASPNETCORE_STDOUT_LOG_FILE);
m_fDisableStartUpErrorPage = aspNetCoreSection->GetRequiredBool(CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE);

View File

@ -13,6 +13,7 @@
#define ASPNETCORE_IIS_AUTH_BASIC L"basic;"
#define ASPNETCORE_IIS_AUTH_ANONYMOUS L"anonymous;"
#define ASPNETCORE_IIS_AUTH_NONE L"none"
#define ANCM_PREFER_ENVIRONMENT_VARIABLES_ENV_STR L"ANCM_PREFER_ENVIRONMENT_VARIABLES"
//
// The key used for hash-table lookups, consists of the port on which the http process is created.

View File

@ -78,9 +78,27 @@ public:
environmentVariables.insert_or_assign(HOSTING_STARTUP_ASSEMBLIES_ENV_STR, hostingStartupValues);
}
auto preferEnvironmentVariablesSetting = Environment::GetEnvironmentVariableValue(ANCM_PREFER_ENVIRONMENT_VARIABLES_ENV_STR).value_or(L"false");
auto preferEnvironmentVariables = equals_ignore_case(L"1", preferEnvironmentVariablesSetting) || equals_ignore_case(L"true", preferEnvironmentVariablesSetting);
for (auto& environmentVariable : environmentVariables)
{
environmentVariable.second = Environment::ExpandEnvironmentVariables(environmentVariable.second);
if (preferEnvironmentVariables)
{
auto env = Environment::GetEnvironmentVariableValue(environmentVariable.first);
if (env.has_value())
{
environmentVariable.second = env.value();
}
else
{
environmentVariable.second = Environment::ExpandEnvironmentVariables(environmentVariable.second);
}
}
else
{
environmentVariable.second = Environment::ExpandEnvironmentVariables(environmentVariable.second);
}
}
return environmentVariables;

View File

@ -7,6 +7,7 @@
#include "environmentvariablehash.h"
#include "exceptions.h"
#include "config_utility.h"
#include "Environment.h"
REQUESTHANDLER_CONFIG::~REQUESTHANDLER_CONFIG()
{
@ -101,6 +102,8 @@ REQUESTHANDLER_CONFIG::Populate(
BSTR bstrBasicAuthSection = NULL;
BSTR bstrAnonymousAuthSection = NULL;
BSTR bstrAspNetCoreSection = NULL;
std::optional<std::wstring> launcherPathEnv;
std::optional<std::wstring> launcherArgsEnv;
pAdminManager = pHttpServer->GetAdminManager();
try
@ -248,12 +251,47 @@ REQUESTHANDLER_CONFIG::Populate(
goto Finished;
}
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_EXE_PATH,
&m_struProcessPath);
if (FAILED(hr))
// We prefer the environment variables for LAUNCHER_PATH and LAUNCHER_ARGS
try
{
goto Finished;
launcherPathEnv = Environment::GetEnvironmentVariableValue(CS_ANCM_LAUNCHER_PATH);
launcherArgsEnv = Environment::GetEnvironmentVariableValue(CS_ANCM_LAUNCHER_ARGS);
}
catch(...)
{
FINISHED_IF_FAILED(E_FAIL);
}
if (launcherPathEnv.has_value())
{
hr = m_struProcessPath.Copy(launcherPathEnv.value().c_str());
FINISHED_IF_FAILED(hr);
}
else
{
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_EXE_PATH,
&m_struProcessPath);
if (FAILED(hr))
{
goto Finished;
}
}
if (launcherArgsEnv.has_value())
{
hr = m_struArguments.Copy(launcherArgsEnv.value().c_str());
FINISHED_IF_FAILED(hr);
}
else
{
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_ARGUMENTS,
&m_struArguments);
if (FAILED(hr))
{
goto Finished;
}
}
hr = GetElementStringProperty(pAspNetCoreElement,
@ -281,14 +319,6 @@ REQUESTHANDLER_CONFIG::Populate(
goto Finished;
}
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_ARGUMENTS,
&m_struArguments);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementDWORDProperty(pAspNetCoreElement,
CS_ASPNETCORE_RAPID_FAILS_PER_MINUTE,
&m_dwRapidFailsPerMinute);

View File

@ -126,5 +126,22 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess
deploymentParameters.WebConfigBasedEnvironmentVariables["OtherVariable"] = "%TestVariable%;Hello";
Assert.Equal("World;Hello", await GetStringAsync(deploymentParameters, "/GetEnvironmentVariable?name=OtherVariable"));
}
[ConditionalTheory]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
[RequiresNewHandler]
[RequiresNewShim]
[InlineData(HostingModel.InProcess)]
[InlineData(HostingModel.OutOfProcess)]
public async Task PreferEnvironmentVariablesOverWebConfigWhenConfigured(HostingModel hostingModel)
{
var deploymentParameters = Fixture.GetBaseDeploymentParameters(hostingModel);
var environment = "Development";
deploymentParameters.EnvironmentVariables["ANCM_PREFER_ENVIRONMENT_VARIABLES"] = "true";
deploymentParameters.EnvironmentVariables["ASPNETCORE_ENVIRONMENT"] = environment;
deploymentParameters.WebConfigBasedEnvironmentVariables.Add("ASPNETCORE_ENVIRONMENT", "Debug");
Assert.Equal(environment, await GetStringAsync(deploymentParameters, "/GetEnvironmentVariable?name=ASPNETCORE_ENVIRONMENT"));
}
}
}

View File

@ -875,6 +875,39 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess
Assert.True(result.IsSuccessStatusCode);
}
[ConditionalTheory]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
[RequiresNewShim]
[RequiresNewHandler]
[InlineData(HostingModel.InProcess)]
[InlineData(HostingModel.OutOfProcess)]
public async Task EnvironmentVariableForLauncherPathIsPreferred(HostingModel hostingModel)
{
var deploymentParameters = Fixture.GetBaseDeploymentParameters(hostingModel);
deploymentParameters.EnvironmentVariables["ANCM_LAUNCHER_PATH"] = _dotnetLocation;
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "nope"));
await StartAsync(deploymentParameters);
}
[ConditionalTheory]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
[RequiresNewShim]
[RequiresNewHandler]
[InlineData(HostingModel.InProcess)]
[InlineData(HostingModel.OutOfProcess)]
public async Task EnvironmentVariableForLauncherArgsIsPreferred(HostingModel hostingModel)
{
var deploymentParameters = Fixture.GetBaseDeploymentParameters(hostingModel);
using var publishedApp = await deploymentParameters.ApplicationPublisher.Publish(deploymentParameters, LoggerFactory.CreateLogger("test"));
deploymentParameters.EnvironmentVariables["ANCM_LAUNCHER_ARGS"] = Path.ChangeExtension(Path.Combine(publishedApp.Path, deploymentParameters.ApplicationPublisher.ApplicationPath), ".dll");
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("arguments", "nope"));
await StartAsync(deploymentParameters);
}
private static void VerifyDotnetRuntimeEventLog(IISDeploymentResult deploymentResult)
{
var entries = GetEventLogsFromDotnetRuntime(deploymentResult);

View File

@ -61,6 +61,11 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
var ancmConfigPath = Path.Combine(Environment.SystemDirectory, "inetsrv", "config", "schema", "aspnetcore_schema.xml");
if (!File.Exists(ancmConfigPath))
{
ancmConfigPath = Path.Combine(Environment.SystemDirectory, "inetsrv", "config", "schema", "aspnetcore_schema_v2.xml");
}
if (!File.Exists(ancmConfigPath) && !SkipInVSTSAttribute.RunningInVSTS)
{
_skipReasonStatic = "IIS Schema is not installed.";