From 70614e7b5f8e0ae303524939c0400c3e20329518 Mon Sep 17 00:00:00 2001 From: Shayne Boyer Date: Mon, 11 May 2020 19:16:40 -0400 Subject: [PATCH] Add baseimage and tag (#447) --- src/Microsoft.Tye.Core/ApplicationFactory.cs | 4 ++-- src/Microsoft.Tye.Core/DockerfileGenerator.cs | 8 +++---- src/Microsoft.Tye.Core/ProjectReader.cs | 7 ++++++ .../Model/ProjectRunInfo.cs | 5 ++++ .../TransformProjectsIntoContainers.cs | 14 +++++++++-- test/E2ETest/TyeRunTests.cs | 24 +++++++++++++++++++ .../backend/backend-baseimage.csproj | 17 +++++++++++++ 7 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 test/E2ETest/testassets/projects/frontend-backend/backend/backend-baseimage.csproj diff --git a/src/Microsoft.Tye.Core/ApplicationFactory.cs b/src/Microsoft.Tye.Core/ApplicationFactory.cs index 53a5b17d..dfaaf289 100644 --- a/src/Microsoft.Tye.Core/ApplicationFactory.cs +++ b/src/Microsoft.Tye.Core/ApplicationFactory.cs @@ -96,12 +96,12 @@ namespace Microsoft.Tye } project.Replicas = configService.Replicas ?? 1; - await ProjectReader.ReadProjectDetailsAsync(output, project); - // We don't apply more container defaults here because we might need // to prompt for the registry name. project.ContainerInfo = new ContainerInfo() { UseMultiphaseDockerfile = false, }; + await ProjectReader.ReadProjectDetailsAsync(output, project); + // Do k8s by default. project.ManifestInfo = new KubernetesManifestInfo(); } diff --git a/src/Microsoft.Tye.Core/DockerfileGenerator.cs b/src/Microsoft.Tye.Core/DockerfileGenerator.cs index 786ae597..e08eac3b 100644 --- a/src/Microsoft.Tye.Core/DockerfileGenerator.cs +++ b/src/Microsoft.Tye.Core/DockerfileGenerator.cs @@ -92,21 +92,21 @@ namespace Microsoft.Tye throw new ArgumentNullException(nameof(container)); } - if (container.BaseImageName == null && project.IsAspNet) + if (string.IsNullOrEmpty(container.BaseImageName) && project.IsAspNet) { container.BaseImageName = "mcr.microsoft.com/dotnet/core/aspnet"; } - else if (container.BaseImageName == null) + else if (string.IsNullOrEmpty(container.BaseImageName)) { container.BaseImageName = "mcr.microsoft.com/dotnet/core/runtime"; } - if (container.BaseImageTag == null && project.TargetFrameworkName == "netcoreapp") + if (string.IsNullOrEmpty(container.BaseImageTag) && project.TargetFrameworkName == "netcoreapp") { container.BaseImageTag = project.TargetFrameworkVersion; } - if (container.BaseImageTag == null) + if (string.IsNullOrEmpty(container.BaseImageTag)) { throw new CommandException($"Unsupported TFM {project.TargetFramework}."); } diff --git a/src/Microsoft.Tye.Core/ProjectReader.cs b/src/Microsoft.Tye.Core/ProjectReader.cs index 49ccbbec..7fd0b94d 100644 --- a/src/Microsoft.Tye.Core/ProjectReader.cs +++ b/src/Microsoft.Tye.Core/ProjectReader.cs @@ -268,6 +268,13 @@ namespace Microsoft.Tye project.Frameworks.AddRange(sharedFrameworks.Select(s => new Framework(s))); output.WriteDebugLine($"Found shared frameworks: {string.Join(", ", sharedFrameworks)}"); + // determine container base image + if (project.ContainerInfo != null) + { + project.ContainerInfo.BaseImageName = projectInstance.GetPropertyValue("ContainerBaseImage"); + project.ContainerInfo.BaseImageTag = projectInstance.GetPropertyValue("ContainerBaseTag"); + } + bool PropertyIsTrue(string property) { return projectInstance.GetPropertyValue(property) is string s && !string.IsNullOrEmpty(s) && bool.Parse(s); diff --git a/src/Microsoft.Tye.Hosting/Model/ProjectRunInfo.cs b/src/Microsoft.Tye.Hosting/Model/ProjectRunInfo.cs index 59d054ab..c7ce4c97 100644 --- a/src/Microsoft.Tye.Hosting/Model/ProjectRunInfo.cs +++ b/src/Microsoft.Tye.Hosting/Model/ProjectRunInfo.cs @@ -24,6 +24,8 @@ namespace Microsoft.Tye.Hosting.Model RunCommand = project.RunCommand; RunArguments = project.RunArguments; PublishOutputPath = project.PublishDir; + ContainerBaseImage = project.ContainerInfo?.BaseImageName; + ContainerBaseTag = project.ContainerInfo?.BaseImageTag; IsAspNet = project.IsAspNet; } @@ -47,6 +49,9 @@ namespace Microsoft.Tye.Hosting.Model public string RunCommand { get; } public string RunArguments { get; } + public string? ContainerBaseTag { get; } + public string? ContainerBaseImage { get; } + // This exists for running projects as containers public List VolumeMappings { get; } = new List(); } diff --git a/src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs b/src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs index c4ccc9b1..ad0772c5 100644 --- a/src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs +++ b/src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs @@ -125,9 +125,19 @@ namespace Microsoft.Tye.Hosting private static string DetermineContainerImage(ProjectRunInfo project) { - var baseImage = project.IsAspNet ? "mcr.microsoft.com/dotnet/core/aspnet" : "mcr.microsoft.com/dotnet/core/runtime"; + string baseImage; + if (!string.IsNullOrEmpty(project.ContainerBaseImage)) + { + baseImage = project.ContainerBaseImage; + } + else + { + baseImage = project.IsAspNet ? "mcr.microsoft.com/dotnet/core/aspnet" : "mcr.microsoft.com/dotnet/core/runtime"; + } + + var baseImageTag = !string.IsNullOrEmpty(project.ContainerBaseTag) ? project.ContainerBaseTag : project.TargetFrameworkVersion; - return $"{baseImage}:{project.TargetFrameworkVersion}"; + return $"{baseImage}:{baseImageTag}"; } public Task StopAsync(Application application) diff --git a/test/E2ETest/TyeRunTests.cs b/test/E2ETest/TyeRunTests.cs index 60bd1e51..f0a4ced2 100644 --- a/test/E2ETest/TyeRunTests.cs +++ b/test/E2ETest/TyeRunTests.cs @@ -246,6 +246,30 @@ namespace E2ETest }); } + [Fact] + public async Task DockerBaseImageAndTagTest() + { + using var projectDirectory = CopyTestProjectDirectory(Path.Combine("frontend-backend", "backend")); + + var projectFile = new FileInfo(Path.Combine(projectDirectory.DirectoryPath, "backend-baseimage.csproj")); + + var outputContext = new OutputContext(_sink, Verbosity.Debug); + var application = await ApplicationFactory.CreateAsync(outputContext, projectFile); + + // Transform the backend into a docker image for testing + var project = (ProjectServiceBuilder)application.Services.First(s => s.Name == "backend-baseimage"); + + // check ContainerInfo values + Assert.True(string.Equals(project.ContainerInfo!.BaseImageName, "mcr.microsoft.com/dotnet/core/sdk")); + Assert.True(string.Equals(project.ContainerInfo!.BaseImageTag, "3.1-buster")); + + // check projectInfo values + var projectRunInfo = new ProjectRunInfo(project); + + Assert.True(string.Equals(projectRunInfo!.ContainerBaseImage, project.ContainerInfo.BaseImageName)); + Assert.True(string.Equals(projectRunInfo!.ContainerBaseTag, project.ContainerInfo.BaseImageTag)); + } + [ConditionalFact] [SkipIfDockerNotRunning] public async Task DockerNamedVolumeTest() diff --git a/test/E2ETest/testassets/projects/frontend-backend/backend/backend-baseimage.csproj b/test/E2ETest/testassets/projects/frontend-backend/backend/backend-baseimage.csproj new file mode 100644 index 00000000..c99f0dea --- /dev/null +++ b/test/E2ETest/testassets/projects/frontend-backend/backend/backend-baseimage.csproj @@ -0,0 +1,17 @@ + + + + netcoreapp3.1 + Backend + + + + mcr.microsoft.com/dotnet/core/sdk + 3.1-buster + + + + + + +