Browse Source

Make user secrets work in docker scenarios. (#152)

* Make user secrets work in docker scenarios.
- Make build errors show up in the output

* Small nits
davidfowl/dependencies
David Fowler 7 years ago
committed by GitHub
parent
commit
8b81b3d470
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/Microsoft.Tye.Core/ProcessUtil.cs
  2. 42
      src/Microsoft.Tye.Hosting/DockerRunner.cs
  3. 8
      src/Microsoft.Tye.Hosting/ProcessRunner.cs
  4. 13
      src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs

4
src/Microsoft.Tye.Core/ProcessUtil.cs

@ -81,10 +81,6 @@ namespace Microsoft.Tye
{ {
errorDataReceived.Invoke(e.Data); errorDataReceived.Invoke(e.Data);
} }
else if (outputDataReceived != null)
{
outputDataReceived.Invoke(e.Data);
}
else else
{ {
errorBuilder.AppendLine(e.Data); errorBuilder.AppendLine(e.Data);

42
src/Microsoft.Tye.Hosting/DockerRunner.cs

@ -4,11 +4,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Tye.Hosting.Model;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Tye.Hosting.Model;
namespace Microsoft.Tye.Hosting namespace Microsoft.Tye.Hosting
{ {
@ -71,6 +72,15 @@ namespace Microsoft.Tye.Hosting
var volumes = ""; var volumes = "";
var workingDirectory = docker.WorkingDirectory != null ? $"-w {docker.WorkingDirectory}" : ""; var workingDirectory = docker.WorkingDirectory != null ? $"-w {docker.WorkingDirectory}" : "";
// This is .NET specific
var userSecretStore = GetUserSecretsPathFromSecrets();
if (!string.IsNullOrEmpty(userSecretStore))
{
// Map the user secrets on this drive to user secrets
docker.VolumeMappings[userSecretStore] = "/root/.microsoft/usersecrets:ro";
}
var dockerInfo = new DockerInformation(new Task[service.Description.Replicas]); var dockerInfo = new DockerInformation(new Task[service.Description.Replicas]);
async Task RunDockerContainer(IEnumerable<(int Port, int? InternalPort, int BindingPort, string? Protocol)> ports) async Task RunDockerContainer(IEnumerable<(int Port, int? InternalPort, int BindingPort, string? Protocol)> ports)
@ -260,21 +270,29 @@ namespace Microsoft.Tye.Hosting
} }
} }
private static async Task<bool> DetectDockerInstalled() private static string? GetUserSecretsPathFromSecrets()
{ {
// Detect Docker installation // This is the logic used to determine the user secrets path
try // See https://github.com/dotnet/extensions/blob/64140f90157fec1bfd8aeafdffe8f30308ccdf41/src/Configuration/Config.UserSecrets/src/PathHelper.cs#L27
{ const string userSecretsFallbackDir = "DOTNET_USER_SECRETS_FALLBACK_DIR";
await ProcessUtil.RunAsync("docker", "version", throwOnError: false);
return true; // For backwards compat, this checks env vars first before using Env.GetFolderPath
} var appData = Environment.GetEnvironmentVariable("APPDATA");
catch (Exception) var root = appData // On Windows it goes to %APPDATA%\Microsoft\UserSecrets\
?? Environment.GetEnvironmentVariable("HOME") // On Mac/Linux it goes to ~/.microsoft/usersecrets/
?? Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
?? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
?? Environment.GetEnvironmentVariable(userSecretsFallbackDir); // this fallback is an escape hatch if everything else fails
if (string.IsNullOrEmpty(root))
{ {
// Unfortunately, process throws return null;
return false;
} }
}
return !string.IsNullOrEmpty(appData)
? Path.Combine(root, "Microsoft", "UserSecrets")
: Path.Combine(root, ".microsoft", "usersecrets");
}
private class DockerInformation private class DockerInformation
{ {

8
src/Microsoft.Tye.Hosting/ProcessRunner.cs

@ -108,13 +108,13 @@ namespace Microsoft.Tye.Hosting
service.Logs.OnNext($"dotnet build \"{service.Status.ProjectFilePath}\" /nologo"); service.Logs.OnNext($"dotnet build \"{service.Status.ProjectFilePath}\" /nologo");
var buildResult = await ProcessUtil.RunAsync("dotnet", $"build \"{service.Status.ProjectFilePath}\" /nologo", var buildResult = await ProcessUtil.RunAsync("dotnet", $"build \"{service.Status.ProjectFilePath}\" /nologo", throwOnError: false);
outputDataReceived: data => service.Logs.OnNext(data),
throwOnError: false); service.Logs.OnNext(buildResult.StandardOutput);
if (buildResult.ExitCode != 0) if (buildResult.ExitCode != 0)
{ {
_logger.LogInformation("Building {ProjectFile} failed with exit code {ExitCode}: " + buildResult.StandardOutput + buildResult.StandardError, service.Status.ProjectFilePath, buildResult.ExitCode); _logger.LogInformation("Building {ProjectFile} failed with exit code {ExitCode}: \r\n" + buildResult.StandardOutput, service.Status.ProjectFilePath, buildResult.ExitCode);
return; return;
} }
} }

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

@ -50,13 +50,16 @@ namespace Microsoft.Tye.Hosting
service.Logs.OnNext($"dotnet publish \"{service.Status.ProjectFilePath}\" /nologo"); service.Logs.OnNext($"dotnet publish \"{service.Status.ProjectFilePath}\" /nologo");
var buildResult = await ProcessUtil.RunAsync("dotnet", $"publish \"{service.Status.ProjectFilePath}\" /nologo", var buildResult = await ProcessUtil.RunAsync("dotnet", $"publish \"{service.Status.ProjectFilePath}\" /nologo", throwOnError: false);
outputDataReceived: data => service.Logs.OnNext(data),
throwOnError: false); service.Logs.OnNext(buildResult.StandardOutput);
if (buildResult.ExitCode != 0) if (buildResult.ExitCode != 0)
{ {
_logger.LogInformation("Publishing {ProjectFile} failed with exit code {ExitCode}: " + buildResult.StandardOutput + buildResult.StandardError, service.Status.ProjectFilePath, buildResult.ExitCode); _logger.LogInformation("Publishing {ProjectFile} failed with exit code {ExitCode}: \r\n" + buildResult.StandardOutput, service.Status.ProjectFilePath, buildResult.ExitCode);
// Null out the RunInfo so that
serviceDescription.RunInfo = null;
return; return;
} }
@ -78,7 +81,7 @@ namespace Microsoft.Tye.Hosting
private static string DetermineContainerImage(string targetFramework) private static string DetermineContainerImage(string targetFramework)
{ {
// TODO: Determine the base iamge from the tfm // TODO: Determine the base image from the tfm
return "mcr.microsoft.com/dotnet/core/sdk:3.1-buster"; return "mcr.microsoft.com/dotnet/core/sdk:3.1-buster";
} }

Loading…
Cancel
Save