From c9ee88e09abbac8dbde434d4c76ccad55e936083 Mon Sep 17 00:00:00 2001 From: Oleg Karasik Date: Fri, 11 Jun 2021 17:52:59 +0300 Subject: [PATCH 1/5] Fixed an issue when path to Dockerfile isn't correctly expanded when referencing service as repository. --- src/Microsoft.Tye.Core/ApplicationFactory.cs | 38 +++++++++++++++++-- .../ConfigModel/ConfigService.cs | 1 + 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Tye.Core/ApplicationFactory.cs b/src/Microsoft.Tye.Core/ApplicationFactory.cs index b65b3aaaf..d5732572f 100644 --- a/src/Microsoft.Tye.Core/ApplicationFactory.cs +++ b/src/Microsoft.Tye.Core/ApplicationFactory.cs @@ -78,6 +78,13 @@ public static async Task CreateAsync(OutputContext output, F config.Services; var sw = Stopwatch.StartNew(); + + // This will correctly expand full paths to all service files and projects + EvaluatePaths( + configServices: services, + configRoot: config.Source.DirectoryName!, + output: output); + // Project services will be restored and evaluated before resolving all other services. // This batching will mitigate the performance cost of running MSBuild out of process. var projectServices = services.Where(s => !string.IsNullOrEmpty(s.Project)); @@ -120,6 +127,11 @@ public static async Task CreateAsync(OutputContext output, F { output.WriteDebugLine("Re-evaluating multi-targeted projects"); + EvaluatePaths( + configServices: multiTFMProjects, + configRoot: config.Source.DirectoryName!, + output: output); + var multiTFMEvaluationResult = await EvaluateProjectsAsync( projects: multiTFMProjects, configRoot: config.Source.DirectoryName!, @@ -212,7 +224,7 @@ public static async Task CreateAsync(OutputContext output, F Args = configService.Args, Build = configService.Build ?? true, Replicas = configService.Replicas ?? 1, - DockerFile = Path.Combine(source.DirectoryName!, configService.DockerFile), + DockerFile = Path.Combine(source.DirectoryName!, configService.DockerFileFullPath!), // Supplying an absolute path with trailing slashes fails for DockerFileContext when calling docker build, so trim trailing slash. DockerFileContext = GetDockerFileContext(source, configService), BuildArgs = configService.DockerFileArgs @@ -476,6 +488,27 @@ service is ProjectServiceBuilder project2 && return root; } + private static void EvaluatePaths(IEnumerable configServices, string configRoot, OutputContext output) + { + output.WriteDebugLine("Evaluating configuration paths"); + + foreach (var configService in configServices) + { + if (!string.IsNullOrEmpty(configService.Project)) + { + configService.ProjectFullPath = Path.Combine( + configRoot, + Environment.ExpandEnvironmentVariables(configService.Project!)); + } + if (!string.IsNullOrEmpty(configService.DockerFile)) + { + configService.DockerFileFullPath = Path.Combine( + configRoot, + Environment.ExpandEnvironmentVariables(configService.DockerFile!)); + } + } + } + private static async Task EvaluateProjectsAsync(IEnumerable projects, string configRoot, OutputContext output) { using var directory = TempDirectory.Create(); @@ -487,9 +520,6 @@ private static async Task EvaluateProjectsAsync(IEnumerable DockerFileArgs { get; set; } = new Dictionary(); public string? DockerFileContext { get; set; } public string? Project { get; set; } From 459e537f8d8a69261f824e5b926dbf17733b437e Mon Sep 17 00:00:00 2001 From: Oleg Karasik Date: Mon, 14 Jun 2021 12:24:56 +0300 Subject: [PATCH 2/5] Fixed spacing issues --- src/Microsoft.Tye.Core/ApplicationFactory.cs | 40 ++++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Microsoft.Tye.Core/ApplicationFactory.cs b/src/Microsoft.Tye.Core/ApplicationFactory.cs index d5732572f..996a1f472 100644 --- a/src/Microsoft.Tye.Core/ApplicationFactory.cs +++ b/src/Microsoft.Tye.Core/ApplicationFactory.cs @@ -81,9 +81,9 @@ public static async Task CreateAsync(OutputContext output, F // This will correctly expand full paths to all service files and projects EvaluatePaths( - configServices: services, - configRoot: config.Source.DirectoryName!, - output: output); + configServices: services, + configRoot: config.Source.DirectoryName!, + output: output); // Project services will be restored and evaluated before resolving all other services. // This batching will mitigate the performance cost of running MSBuild out of process. @@ -128,9 +128,9 @@ public static async Task CreateAsync(OutputContext output, F output.WriteDebugLine("Re-evaluating multi-targeted projects"); EvaluatePaths( - configServices: multiTFMProjects, - configRoot: config.Source.DirectoryName!, - output: output); + configServices: multiTFMProjects, + configRoot: config.Source.DirectoryName!, + output: output); var multiTFMEvaluationResult = await EvaluateProjectsAsync( projects: multiTFMProjects, @@ -490,23 +490,23 @@ service is ProjectServiceBuilder project2 && private static void EvaluatePaths(IEnumerable configServices, string configRoot, OutputContext output) { - output.WriteDebugLine("Evaluating configuration paths"); + output.WriteDebugLine("Evaluating configuration paths"); - foreach (var configService in configServices) - { - if (!string.IsNullOrEmpty(configService.Project)) - { - configService.ProjectFullPath = Path.Combine( - configRoot, - Environment.ExpandEnvironmentVariables(configService.Project!)); - } - if (!string.IsNullOrEmpty(configService.DockerFile)) + foreach (var configService in configServices) { - configService.DockerFileFullPath = Path.Combine( - configRoot, - Environment.ExpandEnvironmentVariables(configService.DockerFile!)); + if (!string.IsNullOrEmpty(configService.Project)) + { + configService.ProjectFullPath = Path.Combine( + configRoot, + Environment.ExpandEnvironmentVariables(configService.Project!)); + } + if (!string.IsNullOrEmpty(configService.DockerFile)) + { + configService.DockerFileFullPath = Path.Combine( + configRoot, + Environment.ExpandEnvironmentVariables(configService.DockerFile!)); + } } - } } private static async Task EvaluateProjectsAsync(IEnumerable projects, string configRoot, OutputContext output) From fac57a29377e30cbd29be0e482235dc06e6f05f7 Mon Sep 17 00:00:00 2001 From: Oleg Karasik Date: Tue, 15 Jun 2021 12:57:55 +0300 Subject: [PATCH 3/5] Removed trailing whitespaces as required by formatter tool --- src/Microsoft.Tye.Core/ApplicationFactory.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.Tye.Core/ApplicationFactory.cs b/src/Microsoft.Tye.Core/ApplicationFactory.cs index 996a1f472..d53d4d309 100644 --- a/src/Microsoft.Tye.Core/ApplicationFactory.cs +++ b/src/Microsoft.Tye.Core/ApplicationFactory.cs @@ -81,8 +81,8 @@ public static async Task CreateAsync(OutputContext output, F // This will correctly expand full paths to all service files and projects EvaluatePaths( - configServices: services, - configRoot: config.Source.DirectoryName!, + configServices: services, + configRoot: config.Source.DirectoryName!, output: output); // Project services will be restored and evaluated before resolving all other services. @@ -128,8 +128,8 @@ public static async Task CreateAsync(OutputContext output, F output.WriteDebugLine("Re-evaluating multi-targeted projects"); EvaluatePaths( - configServices: multiTFMProjects, - configRoot: config.Source.DirectoryName!, + configServices: multiTFMProjects, + configRoot: config.Source.DirectoryName!, output: output); var multiTFMEvaluationResult = await EvaluateProjectsAsync( @@ -492,18 +492,18 @@ private static void EvaluatePaths(IEnumerable configServices, str { output.WriteDebugLine("Evaluating configuration paths"); - foreach (var configService in configServices) + foreach (var configService in configServices) { if (!string.IsNullOrEmpty(configService.Project)) { configService.ProjectFullPath = Path.Combine( - configRoot, + configRoot, Environment.ExpandEnvironmentVariables(configService.Project!)); } if (!string.IsNullOrEmpty(configService.DockerFile)) { configService.DockerFileFullPath = Path.Combine( - configRoot, + configRoot, Environment.ExpandEnvironmentVariables(configService.DockerFile!)); } } From 3a5064a00d1ac458136174952ee65ed0abb838c8 Mon Sep 17 00:00:00 2001 From: Oleg Karasik Date: Sat, 16 Apr 2022 23:57:07 +0300 Subject: [PATCH 4/5] Implemented a demo test (need to update with much simplier test project). --- test/E2ETest/TyeRunTests.cs | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/E2ETest/TyeRunTests.cs b/test/E2ETest/TyeRunTests.cs index 0f37c4120..41c7b6a51 100644 --- a/test/E2ETest/TyeRunTests.cs +++ b/test/E2ETest/TyeRunTests.cs @@ -1011,6 +1011,44 @@ public async Task MultiRepo_WorksWithCloning() }); } + [ConditionalFact] + [SkipIfDockerNotRunning] + public async Task MultiRepo_WorksWithCloningAndDockerfile() + { + using var projectDirectory = TempDirectory.Create(preferUserDirectoryOnMacOS: true); + + var content = @" +name: companion-solution +services: +- name: companion-source-api + repository: https://github.com/coherentsolutionsinc/dotnet-fwdays-2021-project-tye-to-tie-dotnet-microservices-companion"; + + var yamlFile = Path.Combine(projectDirectory.DirectoryPath, "tye.yaml"); + var projectFile = new FileInfo(yamlFile); + await File.WriteAllTextAsync(yamlFile, content); + + // Debug targets can be null if not specified, so make sure calling host.Start does not throw. + 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(), async (app, uri) => + { + var votingUri = await GetServiceUrl(client, uri, "companion-source-api"); + + var votingResponse = await client.GetAsync($"{votingUri}/weatherforecast"); + + Assert.True(votingResponse.IsSuccessStatusCode); + }); + } + [ConditionalFact] [SkipIfDockerNotRunning] public async Task DockerFileTest() From 785bbfb5f5703f8e6731ef2b9341c72c73484156 Mon Sep 17 00:00:00 2001 From: Oleg Karasik Date: Sun, 17 Apr 2022 00:40:07 +0300 Subject: [PATCH 5/5] Updated test to use simple docker image --- test/E2ETest/TyeRunTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/E2ETest/TyeRunTests.cs b/test/E2ETest/TyeRunTests.cs index 41c7b6a51..465d23ed0 100644 --- a/test/E2ETest/TyeRunTests.cs +++ b/test/E2ETest/TyeRunTests.cs @@ -1018,10 +1018,10 @@ public async Task MultiRepo_WorksWithCloningAndDockerfile() using var projectDirectory = TempDirectory.Create(preferUserDirectoryOnMacOS: true); var content = @" -name: companion-solution +name: tye-docker-sample services: -- name: companion-source-api - repository: https://github.com/coherentsolutionsinc/dotnet-fwdays-2021-project-tye-to-tie-dotnet-microservices-companion"; +- name: minapp + repository: https://github.com/OlegKarasik/tye-docker-sample"; var yamlFile = Path.Combine(projectDirectory.DirectoryPath, "tye.yaml"); var projectFile = new FileInfo(yamlFile); @@ -1041,11 +1041,11 @@ public async Task MultiRepo_WorksWithCloningAndDockerfile() await RunHostingApplication(application, new HostOptions(), async (app, uri) => { - var votingUri = await GetServiceUrl(client, uri, "companion-source-api"); + var appUri = await GetServiceUrl(client, uri, "minapp"); - var votingResponse = await client.GetAsync($"{votingUri}/weatherforecast"); + var appResponse = await client.GetAsync(appUri); - Assert.True(votingResponse.IsSuccessStatusCode); + Assert.True(appResponse.IsSuccessStatusCode); }); }