Add environment variables for Launcher path and args in ANCM (#19797)

This commit is contained in:
Brennan 2020-03-13 16:07:16 -07:00 committed by GitHub
parent 361dd0cc54
commit 25b4f8069d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 13 deletions

View File

@ -54,6 +54,11 @@ ShimOptions::ShimOptions(const ConfigurationSource &configurationSource) :
.value_or(environmentVariables[CS_ASPNETCORE_ENVIRONMENT]); .value_or(environmentVariables[CS_ASPNETCORE_ENVIRONMENT]);
const auto dotnetEnvironment = Environment::GetEnvironmentVariableValue(CS_DOTNET_ENVIRONMENT) const auto dotnetEnvironment = Environment::GetEnvironmentVariableValue(CS_DOTNET_ENVIRONMENT)
.value_or(environmentVariables[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 detailedErrorsEnabled = equals_ignore_case(L"1", detailedErrors) || equals_ignore_case(L"true", detailedErrors);
auto aspnetCoreEnvironmentEnabled = equals_ignore_case(L"Development", aspnetCoreEnvironment); auto aspnetCoreEnvironmentEnabled = equals_ignore_case(L"Development", aspnetCoreEnvironment);

View File

@ -33,6 +33,8 @@
#define CS_ASPNETCORE_DETAILEDERRORS L"ASPNETCORE_DETAILEDERRORS" #define CS_ASPNETCORE_DETAILEDERRORS L"ASPNETCORE_DETAILEDERRORS"
#define CS_ASPNETCORE_ENVIRONMENT L"ASPNETCORE_ENVIRONMENT" #define CS_ASPNETCORE_ENVIRONMENT L"ASPNETCORE_ENVIRONMENT"
#define CS_DOTNET_ENVIRONMENT L"DOTNET_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 class ConfigurationSection: NonCopyable
{ {

View File

@ -4,6 +4,7 @@
#include "InProcessOptions.h" #include "InProcessOptions.h"
#include "InvalidOperationException.h" #include "InvalidOperationException.h"
#include "EventLog.h" #include "EventLog.h"
#include "Environment.h"
HRESULT InProcessOptions::Create( HRESULT InProcessOptions::Create(
IHttpServer& pServer, IHttpServer& pServer,
@ -51,6 +52,11 @@ InProcessOptions::InProcessOptions(const ConfigurationSource &configurationSourc
auto const aspNetCoreSection = configurationSource.GetRequiredSection(CS_ASPNETCORE_SECTION); auto const aspNetCoreSection = configurationSource.GetRequiredSection(CS_ASPNETCORE_SECTION);
m_strArguments = aspNetCoreSection->GetString(CS_ASPNETCORE_PROCESS_ARGUMENTS).value_or(CS_ASPNETCORE_PROCESS_ARGUMENTS_DEFAULT); m_strArguments = aspNetCoreSection->GetString(CS_ASPNETCORE_PROCESS_ARGUMENTS).value_or(CS_ASPNETCORE_PROCESS_ARGUMENTS_DEFAULT);
m_strProcessPath = aspNetCoreSection->GetRequiredString(CS_ASPNETCORE_PROCESS_EXE_PATH); 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_fStdoutLogEnabled = aspNetCoreSection->GetRequiredBool(CS_ASPNETCORE_STDOUT_LOG_ENABLED);
m_struStdoutLogFile = aspNetCoreSection->GetRequiredString(CS_ASPNETCORE_STDOUT_LOG_FILE); m_struStdoutLogFile = aspNetCoreSection->GetRequiredString(CS_ASPNETCORE_STDOUT_LOG_FILE);
m_fDisableStartUpErrorPage = aspNetCoreSection->GetRequiredBool(CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE); m_fDisableStartUpErrorPage = aspNetCoreSection->GetRequiredBool(CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE);

View File

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

View File

@ -880,6 +880,39 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess
Assert.True(result.IsSuccessStatusCode); 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) private static void VerifyDotnetRuntimeEventLog(IISDeploymentResult deploymentResult)
{ {
var entries = GetEventLogsFromDotnetRuntime(deploymentResult); var entries = GetEventLogsFromDotnetRuntime(deploymentResult);