diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Helpers/ConfigHelperTest.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Helpers/ConfigHelperTest.cs index b2e7041cd..c19c7592b 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Helpers/ConfigHelperTest.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Helpers/ConfigHelperTest.cs @@ -88,13 +88,16 @@ public void CreateGatewayModuleShouldReturnValue() // Arrange var config = new Configuration("config_test"); + var expectedContainerCreateOptions = /*lang=json,strict*/ "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"; + var jPropModule = new Dictionary() { { "status", "running" }, { "version", "1.0" }, { "settings", new Dictionary() { - { "image", "image_test" } + { "image", "image_test" }, + { "createOptions", expectedContainerCreateOptions } } }, { "env", new Dictionary() @@ -118,6 +121,7 @@ public void CreateGatewayModuleShouldReturnValue() Assert.IsNotNull(result); Assert.AreEqual("running", result.Status); Assert.AreEqual("image_test", result.ImageURI); + Assert.AreEqual(expectedContainerCreateOptions, result.ContainerCreateOptions); Assert.AreEqual(1, result.EnvironmentVariables.Count); } @@ -151,6 +155,10 @@ public void CreateGatewayModuleWithNullModuleShouldThrowException() public void GenerateModulesContentShouldReturnValue() { // Arrange + var expectedModuleName = "ModuleTest"; + var expectedContainerCreateOptions = /*lang=json,strict*/ + "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"; + var edgeModel = new IoTEdgeModel() { ModelId = Guid.NewGuid().ToString(), @@ -158,14 +166,15 @@ public void GenerateModulesContentShouldReturnValue() Description = "Description Test", EdgeModules = new List() { - new IoTEdgeModule() + new() { - ModuleName = "ModuleTest", + ModuleName = expectedModuleName, Status = "running", ImageURI = "image", + ContainerCreateOptions = expectedContainerCreateOptions, EnvironmentVariables = new List() { - new IoTEdgeModuleEnvironmentVariable(){ Name = "envTest01", Value = "test" } + new() { Name = "envTest01", Value = "test" } }, ModuleIdentityTwinSettings = new List() } @@ -179,6 +188,9 @@ public void GenerateModulesContentShouldReturnValue() Assert.IsNotNull(result); Assert.IsAssignableFrom>>(result); Assert.AreEqual(2, result.Count); + var edgeHubPropertiesDesired = (EdgeAgentPropertiesDesired)result["$edgeAgent"]["properties.desired"]; + _ = edgeHubPropertiesDesired.Modules[expectedModuleName].Settings.CreateOptions.Should() + .Be(expectedContainerCreateOptions); } [Test] diff --git a/src/AzureIoTHub.Portal/Client/Pages/EdgeModels/EdgeModule/ModuleDialog.razor b/src/AzureIoTHub.Portal/Client/Pages/EdgeModels/EdgeModule/ModuleDialog.razor index 3c1675669..418c68431 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/EdgeModels/EdgeModule/ModuleDialog.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/EdgeModels/EdgeModule/ModuleDialog.razor @@ -1,8 +1,5 @@ @using AzureIoTHub.Portal.Models.v10 @using AzureIoTHub.Portal.Shared.Models.v10 -@inject HttpClient Http -@inject IJSRuntime JS -@inject ISnackbar Snackbar @@ -23,6 +20,16 @@ For="@(()=> Module.ImageURI)" Required="true" /> + + + + + How to configure container create options for IoT Edge modules + @@ -55,6 +62,7 @@ private string currentModuleName; private string currentImageUri; + private string currentContainerCreateOptions; private List currentEnvironmentVariables = new(); private List currentModuleIdentityTwinSettings = new(); @@ -69,6 +77,7 @@ currentModuleName = Module.ModuleName; currentImageUri = Module.ImageURI; + currentContainerCreateOptions = Module.ContainerCreateOptions; currentEnvironmentVariables = new List(Module.EnvironmentVariables.ToArray()); currentModuleIdentityTwinSettings = new List(Module.ModuleIdentityTwinSettings.ToArray()); currentCommands = new List(Module.Commands.ToArray()); @@ -80,6 +89,7 @@ { Module.ModuleName = currentModuleName; Module.ImageURI = currentImageUri; + Module.ContainerCreateOptions = currentContainerCreateOptions; Module.EnvironmentVariables = new List(currentEnvironmentVariables.ToArray()); Module.ModuleIdentityTwinSettings = new List(currentModuleIdentityTwinSettings.ToArray()); Module.Commands = new List(currentCommands.ToArray()); diff --git a/src/AzureIoTHub.Portal/Server/Helpers/ConfigHelper.cs b/src/AzureIoTHub.Portal/Server/Helpers/ConfigHelper.cs index c0f4d40ea..fe505509f 100644 --- a/src/AzureIoTHub.Portal/Server/Helpers/ConfigHelper.cs +++ b/src/AzureIoTHub.Portal/Server/Helpers/ConfigHelper.cs @@ -149,6 +149,7 @@ public static IoTEdgeModule CreateGatewayModule(Configuration config, JProperty { ModuleName = module.Name, ImageURI = module.Value["settings"]["image"]?.Value(), + ContainerCreateOptions = module.Value["settings"]["createOptions"]?.Value(), Status = module.Value["status"]?.Value(), }; @@ -248,7 +249,8 @@ public static Dictionary> GenerateModulesCon Status = "running", Settings = new ModuleSettings() { - Image = module.ImageURI + Image = module.ImageURI, + CreateOptions = module.ContainerCreateOptions }, RestartPolicy = "always", EnvironmentVariables = new Dictionary() diff --git a/src/AzureIoTHub.Portal/Shared/Models/v1.0/IoTEdgeModule.cs b/src/AzureIoTHub.Portal/Shared/Models/v1.0/IoTEdgeModule.cs index 084779f93..feb6ffe30 100644 --- a/src/AzureIoTHub.Portal/Shared/Models/v1.0/IoTEdgeModule.cs +++ b/src/AzureIoTHub.Portal/Shared/Models/v1.0/IoTEdgeModule.cs @@ -24,6 +24,8 @@ public class IoTEdgeModule [Required(ErrorMessage = "The device image uri is required.")] public string ImageURI { get; set; } + public string ContainerCreateOptions { get; set; } + /// /// The module status. ///