From 3274c227f8bbe01337691144e6dc18a57651836e Mon Sep 17 00:00:00 2001 From: Phillip Hoff Date: Fri, 1 Oct 2021 09:56:50 -0700 Subject: [PATCH 1/5] Try inverting default placement service behavior. --- .../Dapr/DaprExtension.cs | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs index 1d0be276c..dc3105d3d 100644 --- a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs +++ b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs @@ -18,43 +18,35 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati // If we're getting called then the user configured dapr in their tye.yaml. // We don't have any of our own config. + int? daprPlacementPort = null; + if (context.Operation == ExtensionContext.OperationKind.LocalRun) { - // default placement port number - var daprPlacementImage = "daprio/dapr"; - var daprPlacementContainerPort = 50005; - var daprPlacementPort = NextPortFinder.GetNextPort(); - var isCustomPlacementPortDefined = false; - // see if a placement port number has been defined if (config.Data.TryGetValue("placement-port", out var obj) && obj?.ToString() is string && int.TryParse(obj.ToString(), out var customPlacementPort)) { context.Output.WriteDebugLine($"Using Dapr placement service host port {customPlacementPort} from 'placement-port'"); daprPlacementPort = customPlacementPort; - isCustomPlacementPortDefined = true; } - // see if a placement image has been defined - if (config.Data.TryGetValue("placement-image", out obj) && obj?.ToString() is string customPlacementImage) + if (config.Data.TryGetValue("include-placement-container", out obj) && obj?.ToString() is string includePlacementContainer && includePlacementContainer == "true") { - context.Output.WriteDebugLine($"Using Dapr placement service image {customPlacementImage} from 'placement-image'"); - daprPlacementImage = customPlacementImage; - } + var daprPlacementImage = "daprio/dapr"; + var daprPlacementContainerPort = 50005; + daprPlacementPort = NextPortFinder.GetNextPort(); - // see if a placement container port has been defined - if (config.Data.TryGetValue("placement-container-port", out obj) && obj?.ToString() is string && int.TryParse(obj.ToString(), out var customPlacementContainerPort)) - { - context.Output.WriteDebugLine($"Using Dapr placement service container port {customPlacementContainerPort} from 'placement-container-port'"); - daprPlacementContainerPort = customPlacementContainerPort; - } + // see if a placement image has been defined + if (config.Data.TryGetValue("placement-image", out obj) && obj?.ToString() is string customPlacementImage) + { + context.Output.WriteDebugLine($"Using Dapr placement service image {customPlacementImage} from 'placement-image'"); + daprPlacementImage = customPlacementImage; + } - // We can only skip injecting a Dapr placement container if a 'placement-port' has been defined and 'exclude-placement-container=true' - if (!(isCustomPlacementPortDefined && config.Data.TryGetValue("exclude-placement-container", out obj) && - obj?.ToString() is string excludePlacementContainer && excludePlacementContainer == "true")) - { - if (!isCustomPlacementPortDefined) + // see if a placement container port has been defined + if (config.Data.TryGetValue("placement-container-port", out obj) && obj?.ToString() is string && int.TryParse(obj.ToString(), out var customPlacementContainerPort)) { - context.Output.WriteDebugLine("A 'placement-port' has not been defined. So the 'exclude-placement-container' will default to 'false'."); + context.Output.WriteDebugLine($"Using Dapr placement service container port {customPlacementContainerPort} from 'placement-container-port'"); + daprPlacementContainerPort = customPlacementContainerPort; } context.Output.WriteDebugLine("Injecting Dapr placement service..."); @@ -73,7 +65,7 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati } else { - context.Output.WriteDebugLine("Skipping injecting Dapr placement service because 'exclude-placement-container=true'."); + context.Output.WriteDebugLine("Skipping injecting Dapr placement service because 'include-placement-container=false'."); } // For local run, enumerate all projects, and add services for each dapr proxy. @@ -110,9 +102,14 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati // These environment variables are replaced with environment variables // defined for this service. - Args = $"run --app-id {project.Name} --app-port %APP_PORT% --dapr-grpc-port %DAPR_GRPC_PORT% --dapr-http-port %DAPR_HTTP_PORT% --metrics-port %METRICS_PORT% --placement-host-address localhost:{daprPlacementPort}", + Args = $"run --app-id {project.Name} --app-port %APP_PORT% --dapr-grpc-port %DAPR_GRPC_PORT% --dapr-http-port %DAPR_HTTP_PORT% --metrics-port %METRICS_PORT%", }; + if (daprPlacementPort.HasValue) + { + proxy.Args += $" --placement-host-address localhost:{daprPlacementPort.Value}"; + } + // When running locally `-config` specifies a filename, not a configuration name. By convention // we'll assume the filename and config name are the same. if (config.Data.TryGetValue("config", out obj) && obj?.ToString() is string daprConfig) From b18bf7f8e5aa610fab5e41b7277f2e0a73d5649e Mon Sep 17 00:00:00 2001 From: Phillip Hoff Date: Fri, 1 Oct 2021 11:15:31 -0700 Subject: [PATCH 2/5] Eliminate placement service management. --- samples/dapr/pub-sub/tye.yaml | 8 ++-- .../Dapr/DaprExtension.cs | 43 +------------------ 2 files changed, 6 insertions(+), 45 deletions(-) diff --git a/samples/dapr/pub-sub/tye.yaml b/samples/dapr/pub-sub/tye.yaml index 77d0683db..ec650d4c6 100644 --- a/samples/dapr/pub-sub/tye.yaml +++ b/samples/dapr/pub-sub/tye.yaml @@ -42,7 +42,7 @@ services: # # Doing a `docker ps` can show if its already running. If that's the case # then comment out out when running locally. -- name: redis - image: redis - bindings: - - port: 6379 +# - name: redis +# image: redis +# bindings: +# - port: 6379 diff --git a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs index dc3105d3d..ed7dbd44e 100644 --- a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs +++ b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs @@ -18,10 +18,10 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati // If we're getting called then the user configured dapr in their tye.yaml. // We don't have any of our own config. - int? daprPlacementPort = null; - if (context.Operation == ExtensionContext.OperationKind.LocalRun) { + int? daprPlacementPort = null; + // see if a placement port number has been defined if (config.Data.TryGetValue("placement-port", out var obj) && obj?.ToString() is string && int.TryParse(obj.ToString(), out var customPlacementPort)) { @@ -29,45 +29,6 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati daprPlacementPort = customPlacementPort; } - if (config.Data.TryGetValue("include-placement-container", out obj) && obj?.ToString() is string includePlacementContainer && includePlacementContainer == "true") - { - var daprPlacementImage = "daprio/dapr"; - var daprPlacementContainerPort = 50005; - daprPlacementPort = NextPortFinder.GetNextPort(); - - // see if a placement image has been defined - if (config.Data.TryGetValue("placement-image", out obj) && obj?.ToString() is string customPlacementImage) - { - context.Output.WriteDebugLine($"Using Dapr placement service image {customPlacementImage} from 'placement-image'"); - daprPlacementImage = customPlacementImage; - } - - // see if a placement container port has been defined - if (config.Data.TryGetValue("placement-container-port", out obj) && obj?.ToString() is string && int.TryParse(obj.ToString(), out var customPlacementContainerPort)) - { - context.Output.WriteDebugLine($"Using Dapr placement service container port {customPlacementContainerPort} from 'placement-container-port'"); - daprPlacementContainerPort = customPlacementContainerPort; - } - - context.Output.WriteDebugLine("Injecting Dapr placement service..."); - var daprPlacement = new ContainerServiceBuilder("placement", daprPlacementImage, ServiceSource.Extension) - { - Args = "./placement", - Bindings = { - new BindingBuilder() { - Port = daprPlacementPort, - ContainerPort = daprPlacementContainerPort, - Protocol = "http" - } - } - }; - context.Application.Services.Add(daprPlacement); - } - else - { - context.Output.WriteDebugLine("Skipping injecting Dapr placement service because 'include-placement-container=false'."); - } - // For local run, enumerate all projects, and add services for each dapr proxy. var projects = context.Application.Services.OfType().Cast(); var executables = context.Application.Services.OfType().Cast(); From 8cb204b6edc6d58a4271703b3586402cfb9bb027 Mon Sep 17 00:00:00 2001 From: Phillip Hoff Date: Fri, 1 Oct 2021 11:27:43 -0700 Subject: [PATCH 3/5] Remove references to placement service options. --- samples/dapr/pub-sub/tye.yaml | 11 ++--------- samples/dapr/service-invocation/tye.yaml | 11 ++--------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/samples/dapr/pub-sub/tye.yaml b/samples/dapr/pub-sub/tye.yaml index ec650d4c6..c9cacd02a 100644 --- a/samples/dapr/pub-sub/tye.yaml +++ b/samples/dapr/pub-sub/tye.yaml @@ -8,10 +8,6 @@ name: dapr extensions: - name: dapr - # If you want to use a different tag or container port - # placement-image: daprio/dapr - # placement-container-port: 50005 - # log-level configures the log level of the dapr sidecar log-level: debug @@ -24,11 +20,8 @@ extensions: # components-path configures the components path of the dapr sidecar components-path: "./components/" - # You can instruct Tye to not create the Dapr placement container on your behalf. This is required if you have Dapr running and want to use that container. - # Doing a `docker ps` can show if its already running. If it's running then you can set 'exclude-placement-container: true' with `placement-port: xxxx` set to the host port of that container. - # (i.e. In Windows + WSL2, Dapr uses 6050 as the host port) - - # exclude-placement-container: true + # If not using the default Dapr placement service or otherwise using a placement service on a nonstandard port, + # you can configure the Dapr sidecar to use an explicit port. # placement-port: 6050 services: - name: orders diff --git a/samples/dapr/service-invocation/tye.yaml b/samples/dapr/service-invocation/tye.yaml index ee4c88f8f..d2b42a1b3 100644 --- a/samples/dapr/service-invocation/tye.yaml +++ b/samples/dapr/service-invocation/tye.yaml @@ -8,10 +8,6 @@ name: distributedtyedemo extensions: - name: dapr - # If you want to use a different tag or container port - # placement-image: daprio/dapr - # placement-container-port: 50005 - # log-level configures the log level of the dapr sidecar log-level: debug @@ -24,11 +20,8 @@ extensions: # components-path configures the components path of the dapr sidecard # components-path: "./components/" - # You can instruct Tye to not create the Dapr placement container on your behalf. This is required if you have Dapr running and want to use that container. - # Doing a `docker ps` can show if its already running. If it's running then you can set 'exclude-placement-container: true' with `placement-port: xxxx` set to the host port of that container. - # (i.e. In Windows + WSL2, Dapr uses 6050 as the host port) - - # exclude-placement-container: true + # If not using the default Dapr placement service or otherwise using a placement service on a nonstandard port, + # you can configure the Dapr sidecar to use an explicit port. # placement-port: 6050 services: # uppercase service is a node app and is run via a dockerfile From 4212dedbdc78ea536b518ceac21b4da563159bc0 Mon Sep 17 00:00:00 2001 From: Phillip Hoff Date: Fri, 1 Oct 2021 12:24:41 -0700 Subject: [PATCH 4/5] Try to determine Dapr status. --- src/Microsoft.Tye.Core/ProcessExtensions.cs | 4 +- .../Dapr/DaprExtension.cs | 42 ++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Tye.Core/ProcessExtensions.cs b/src/Microsoft.Tye.Core/ProcessExtensions.cs index c1c328a8b..cd7826a67 100644 --- a/src/Microsoft.Tye.Core/ProcessExtensions.cs +++ b/src/Microsoft.Tye.Core/ProcessExtensions.cs @@ -11,7 +11,7 @@ namespace Microsoft.Tye { - internal static class ProcessExtensions + public static class ProcessExtensions { private static readonly bool _isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); private static readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(30); @@ -97,7 +97,7 @@ private static void KillProcessUnix(int processId, TimeSpan timeout) } } - private static void RunProcessAndWaitForExit(string fileName, string arguments, TimeSpan timeout, out string? stdout) + public static void RunProcessAndWaitForExit(string fileName, string arguments, TimeSpan timeout, out string? stdout) { var startInfo = new ProcessStartInfo { diff --git a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs index ed7dbd44e..9309518dd 100644 --- a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs +++ b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs @@ -7,19 +7,22 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Microsoft.Tye.Extensions.Dapr { internal sealed class DaprExtension : Extension { - public override Task ProcessAsync(ExtensionContext context, ExtensionConfiguration config) + public override async Task ProcessAsync(ExtensionContext context, ExtensionConfiguration config) { // If we're getting called then the user configured dapr in their tye.yaml. // We don't have any of our own config. if (context.Operation == ExtensionContext.OperationKind.LocalRun) { + await VerifyDaprInitialized(context); + int? daprPlacementPort = null; // see if a placement port number has been defined @@ -223,8 +226,43 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati } } } + } + + private static Task VerifyDaprInitialized(ExtensionContext context) + { + return Task.Run( + () => + { + string? stdout = null; + + try + { + ProcessExtensions.RunProcessAndWaitForExit("dapr", "--version", TimeSpan.FromSeconds(10), out stdout); + } + catch + { + } + + if (stdout != null) + { + var match = Regex.Match(stdout, "^Runtime version: (?.+)$", RegexOptions.Multiline); + + if (match.Success) + { + if (match.Groups["version"].Value == "n/a") + { + throw new CommandException("Dapr has not been initialized (e.g. via `dapr init`)."); + } + else + { + // Some version of Dapr has been initialized... + return; + } + } + } - return Task.CompletedTask; + context.Output.WriteAlwaysLine($"Unable to determine whether Dapr has been installed and initialized (e.g. via `dapr init`)."); + }); } private string GetDaprExecutablePath() From b8066de8d1536f8ccdf007b43f59f5fc1fdf89da Mon Sep 17 00:00:00 2001 From: Phillip Hoff Date: Fri, 1 Oct 2021 12:46:40 -0700 Subject: [PATCH 5/5] Update formatting. --- src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs index 9309518dd..6a00dd3be 100644 --- a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs +++ b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs @@ -251,7 +251,7 @@ private static Task VerifyDaprInitialized(ExtensionContext context) { if (match.Groups["version"].Value == "n/a") { - throw new CommandException("Dapr has not been initialized (e.g. via `dapr init`)."); + throw new CommandException("Dapr has not been initialized (e.g. via `dapr init`)."); } else {