Browse Source

Dont overwrite dotnet env vars when transforming projects into containers (#1480)

* Don't overwrite dotnet env when transforming projects into containers

* use System.Text.Json instead of Newtonsoft

* escaping the whitespace police!

* Apply suggestions from code review

Co-authored-by: David Fowler <davidfowl@gmail.com>
main
josdeweger 4 years ago
committed by GitHub
parent
commit
3f3442df9f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 49
      src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs
  2. 34
      test/E2ETest/TyeRunTests.cs
  3. 34
      test/E2ETest/testassets/projects/dotnet-env-vars/single-project.sln
  4. 30
      test/E2ETest/testassets/projects/dotnet-env-vars/test-project/Program.cs
  5. 27
      test/E2ETest/testassets/projects/dotnet-env-vars/test-project/Properties/launchSettings.json
  6. 46
      test/E2ETest/testassets/projects/dotnet-env-vars/test-project/Startup.cs
  7. 8
      test/E2ETest/testassets/projects/dotnet-env-vars/test-project/test-project.csproj
  8. 12
      test/E2ETest/testassets/projects/dotnet-env-vars/tye.yaml

49
src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs

@ -17,6 +17,18 @@ namespace Microsoft.Tye.Hosting
private readonly ILogger _logger;
private Lazy<TempDirectory> _certificateDirectory;
private static readonly Dictionary<string, string> _defaultDotnetEnvVars = new Dictionary<string, string>
{
{ "DOTNET_ENVIRONMENT", "Development" },
{ "DOTNET_LOGGING__CONSOLE__DISABLECOLORS", "true" }
};
private static readonly Dictionary<string, string> _defaultAspnetEnvVars = new Dictionary<string, string>
{
{ "ASPNETCORE_ENVIRONMENT", "Development" },
{ "ASPNETCORE_LOGGING__CONSOLE__DISABLECOLORS", "true" }
};
public TransformProjectsIntoContainers(ILogger logger)
{
_logger = logger;
@ -41,7 +53,6 @@ namespace Microsoft.Tye.Hosting
private async Task TransformProjectToContainer(Service service, ProjectRunInfo project)
{
var serviceDescription = service.Description;
var serviceName = serviceDescription.Name;
service.Status.ProjectFilePath = project.ProjectFile.FullName;
var targetFramework = project.TargetFramework;
@ -95,17 +106,7 @@ namespace Microsoft.Tye.Hosting
dockerRunInfo.VolumeMappings.Add(new DockerVolume(source: userSecretStore, name: null, target: "/root/.microsoft/usersecrets", readOnly: true));
}
// Default to development environment
serviceDescription.Configuration.Add(new EnvironmentVariable("DOTNET_ENVIRONMENT", "Development"));
// Remove the color codes from the console output
serviceDescription.Configuration.Add(new EnvironmentVariable("DOTNET_LOGGING__CONSOLE__DISABLECOLORS", "true"));
if (project.IsAspNet)
{
serviceDescription.Configuration.Add(new EnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"));
serviceDescription.Configuration.Add(new EnvironmentVariable("ASPNETCORE_LOGGING__CONSOLE__DISABLECOLORS", "true"));
}
SetDefaultEnvVars(project, serviceDescription);
// If we have an https binding then export the dev cert and mount the volume into the container
if (serviceDescription.Bindings.Any(b => string.Equals(b.Protocol, "https", StringComparison.OrdinalIgnoreCase)))
@ -125,6 +126,30 @@ namespace Microsoft.Tye.Hosting
serviceDescription.RunInfo = dockerRunInfo;
}
private void SetDefaultEnvVars(ProjectRunInfo project, ServiceDescription serviceDescription)
{
foreach (var dotnetEnvVar in _defaultDotnetEnvVars)
{
if (!serviceDescription.Configuration.Exists(x => x.Name.Equals(dotnetEnvVar.Key)))
{
serviceDescription.Configuration.Add(new EnvironmentVariable(dotnetEnvVar.Key, dotnetEnvVar.Value));
}
}
if (!project.IsAspNet)
{
return;
}
foreach (var aspnetEnvVar in _defaultAspnetEnvVars)
{
if (!serviceDescription.Configuration.Exists(x => x.Name.Equals(aspnetEnvVar.Key)))
{
serviceDescription.Configuration.Add(new EnvironmentVariable(aspnetEnvVar.Key, aspnetEnvVar.Value));
}
}
}
private static string DetermineContainerImage(ProjectRunInfo project)
{
var baseImageTag = !string.IsNullOrEmpty(project.ContainerBaseTag) ? project.ContainerBaseTag : project.TargetFrameworkVersion;

34
test/E2ETest/TyeRunTests.cs

@ -19,7 +19,6 @@ using Microsoft.Tye;
using Microsoft.Tye.Hosting;
using Microsoft.Tye.Hosting.Model;
using Microsoft.Tye.Hosting.Model.V1;
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel;
using Test.Infrastructure;
using Xunit;
using Xunit.Abstractions;
@ -1279,6 +1278,39 @@ services:
});
}
[ConditionalFact]
[SkipIfDockerNotRunning]
public async Task RunWithDotnetEnvVarsDoesNotGetOverriddenByDefaultDotnetEnvVars()
{
using var projectDirectory = CopyTestProjectDirectory("dotnet-env-vars");
var projectFile = new FileInfo(Path.Combine(projectDirectory.DirectoryPath, "tye.yaml"));
var outputContext = new OutputContext(_sink, Verbosity.Debug);
var application = await ApplicationFactory.CreateAsync(outputContext, projectFile);
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (a, b, c, d) => true,
AllowAutoRedirect = false
};
var client = new HttpClient(new RetryHandler(handler));
await RunHostingApplication(application, new HostOptions { Docker = true }, async (app, uri) =>
{
var backendUri = await GetServiceUrl(client, uri, "test-project");
var backendResponse = await client.GetAsync(backendUri);
Assert.True(backendResponse.IsSuccessStatusCode);
var response = await backendResponse.Content.ReadAsStringAsync();
var dict = JsonSerializer.Deserialize<Dictionary<string, string>>(response);
Assert.Contains(new KeyValuePair<string, string>("DOTNET_ENVIRONMENT", "dev"), dict);
Assert.Contains(new KeyValuePair<string, string>("ASPNETCORE_ENVIRONMENT", "dev"), dict);
});
}
private async Task<string> GetServiceUrl(HttpClient client, Uri uri, string serviceName)
{
var serviceResult = await client.GetStringAsync($"{uri}api/v1/services/{serviceName}");

34
test/E2ETest/testassets/projects/dotnet-env-vars/single-project.sln

@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test-project", "test-project\test-project.csproj", "{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x64.ActiveCfg = Debug|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x64.Build.0 = Debug|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x86.ActiveCfg = Debug|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x86.Build.0 = Debug|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|Any CPU.Build.0 = Release|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x64.ActiveCfg = Release|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x64.Build.0 = Release|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x86.ActiveCfg = Release|Any CPU
{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

30
test/E2ETest/testassets/projects/dotnet-env-vars/test-project/Program.cs

@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace test_project
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

27
test/E2ETest/testassets/projects/dotnet-env-vars/test-project/Properties/launchSettings.json

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:18482",
"sslPort": 44344
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"test_project": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

46
test/E2ETest/testassets/projects/dotnet-env-vars/test-project/Startup.cs

@ -0,0 +1,46 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace test_project
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/",
() => Results.Json(new Dictionary<string, string>
{
{ "DOTNET_ENVIRONMENT", Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") },
{ "ASPNETCORE_ENVIRONMENT", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") }
}));
});
}
}
}

8
test/E2ETest/testassets/projects/dotnet-env-vars/test-project/test-project.csproj

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>test_project</RootNamespace>
</PropertyGroup>
</Project>

12
test/E2ETest/testassets/projects/dotnet-env-vars/tye.yaml

@ -0,0 +1,12 @@
# tye application configuration file
# read all about it at https://github.com/dotnet/tye
name: dotnet-env-vars
dashboardPort: 8005
services:
- name: test-project
project: test-project/test-project.csproj
env:
- name: DOTNET_ENVIRONMENT
value: "dev"
- name: ASPNETCORE_ENVIRONMENT
value: "dev"
Loading…
Cancel
Save