Skip to content

Commit

Permalink
Add HostConfig properties (Azure#4080)
Browse files Browse the repository at this point in the history
* Add HostConfig properties
  • Loading branch information
ancaantochi committed Dec 18, 2020
1 parent ef9215e commit e34cff7
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Agent.Docker.Models
{
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class DeviceMapping
{
[JsonProperty("PathOnHost", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string PathOnHost { get; set; }

[JsonProperty("PathInContainer", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string PathInContainer { get; set; }

[JsonProperty("CgroupPermissions", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string CgroupPermissions { get; set; }

[JsonExtensionData]
public IDictionary<string, JToken> OtherProperties { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,183 @@ public class HostConfig
[JsonProperty("Privileged", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public bool Privileged { get; set; }

[JsonProperty("CpuRealtimePeriod", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long CPURealtimePeriod { get; set; }

[JsonProperty("CpuQuota", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long CPUQuota { get; set; }

[JsonProperty("CpuPeriod", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long CPUPeriod { get; set; }

[JsonProperty("BlkioDeviceWriteIOps", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<ThrottleDevice> BlkioDeviceWriteIOps { get; set; }

[JsonProperty("BlkioDeviceReadIOps", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<ThrottleDevice> BlkioDeviceReadIOps { get; set; }

[JsonProperty("BlkioDeviceWriteBps", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<ThrottleDevice> BlkioDeviceWriteBps { get; set; }

[JsonProperty("BlkioDeviceReadBps", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<ThrottleDevice> BlkioDeviceReadBps { get; set; }

[JsonProperty("BlkioWeightDevice", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<WeightDevice> BlkioWeightDevice { get; set; }

[JsonProperty("BlkioWeight", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public ushort BlkioWeight { get; set; }

[JsonProperty("CgroupParent", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string CgroupParent { get; set; }

[JsonProperty("NanoCpus", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long NanoCPUs { get; set; }

[JsonProperty("Memory", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long Memory { get; set; }

[JsonProperty("CpuShares", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long CPUShares { get; set; }

[JsonProperty("CpuRealtimeRuntime", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long CPURealtimeRuntime { get; set; }

[JsonProperty("CpusetCpus", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string CpusetCpus { get; set; }

[JsonProperty("CpusetMems", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string CpusetMems { get; set; }

[JsonProperty("Devices", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<DeviceMapping> Devices { get; set; }

[JsonProperty("DiskQuota", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long DiskQuota { get; set; }

[JsonProperty("KernelMemory", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long KernelMemory { get; set; }

[JsonProperty("MemoryReservation", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long MemoryReservation { get; set; }

[JsonProperty("MemorySwap", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long MemorySwap { get; set; }

[JsonProperty("MemorySwappiness", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long? MemorySwappiness { get; set; }

[JsonProperty("OomKillDisable", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public bool? OomKillDisable { get; set; }

[JsonProperty("PidsLimit", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long? PidsLimit { get; set; }

[JsonProperty("Ulimits", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<Ulimit> Ulimits { get; set; }

[JsonProperty("CpuCount", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long CPUCount { get; set; }

[JsonProperty("CpuPercent", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long CPUPercent { get; set; }

[JsonProperty("IOMaximumIOps", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public ulong IOMaximumIOps { get; set; }

[JsonProperty("IOMaximumBandwidth", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public ulong IOMaximumBandwidth { get; set; }

[JsonProperty("Isolation", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string Isolation { get; set; }

[JsonProperty("ConsoleSize", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public ulong[] ConsoleSize { get; set; }

[JsonProperty("Runtime", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string Runtime { get; set; }

[JsonProperty("Sysctls", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IDictionary<string, string> Sysctls { get; set; }

[JsonProperty("ContainerIDFile", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string ContainerIDFile { get; set; }

[JsonProperty("RestartPolicy", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public RestartPolicy RestartPolicy { get; set; }

[JsonProperty("AutoRemove", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public bool AutoRemove { get; set; }

[JsonProperty("VolumeDriver", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string VolumeDriver { get; set; }

[JsonProperty("VolumesFrom", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> VolumesFrom { get; set; }

[JsonProperty("CapAdd", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> CapAdd { get; set; }

[JsonProperty("CapDrop", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> CapDrop { get; set; }

[JsonProperty("Dns", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> DNS { get; set; }

[JsonProperty("DnsOptions", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> DNSOptions { get; set; }

[JsonProperty("DnsSearch", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> DNSSearch { get; set; }

[JsonProperty("Init", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public bool? Init { get; set; }

[JsonProperty("ExtraHosts", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> ExtraHosts { get; set; }

[JsonProperty("Cgroup", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string Cgroup { get; set; }

[JsonProperty("Links", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> Links { get; set; }

[JsonProperty("OomScoreAdj", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long OomScoreAdj { get; set; }

[JsonProperty("PidMode", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string PidMode { get; set; }

[JsonProperty("PublishAllPorts", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public bool PublishAllPorts { get; set; }

[JsonProperty("ReadonlyRootfs", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public bool ReadonlyRootfs { get; set; }

[JsonProperty("SecurityOpt", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> SecurityOpt { get; set; }

[JsonProperty("StorageOpt", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IDictionary<string, string> StorageOpt { get; set; }

[JsonProperty("Tmpfs", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IDictionary<string, string> Tmpfs { get; set; }

[JsonProperty("UTSMode", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string UTSMode { get; set; }

[JsonProperty("UsernsMode", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string UsernsMode { get; set; }

[JsonProperty("ShmSize", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long ShmSize { get; set; }

[JsonProperty("GroupAdd", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public IList<string> GroupAdd { get; set; }

[JsonProperty("InitPath", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string InitPath { get; set; }

[JsonExtensionData]
public IDictionary<string, JToken> OtherProperties { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Agent.Docker.Models
{
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class RestartPolicy
{
[JsonProperty("Name", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public RestartPolicyKind Name { get; set; }

[JsonProperty("MaximumRetryCount", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long MaximumRetryCount { get; set; }

[JsonExtensionData]
public IDictionary<string, JToken> OtherProperties { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Agent.Docker.Models
{
using Newtonsoft.Json;

public enum RestartPolicyKind
{
[JsonProperty("")]
Undefined,

[JsonProperty("no")]
No,

[JsonProperty("always")]
Always,

[JsonProperty("on-failure")]
OnFailure,

[JsonProperty("unless-stopped")]
UnlessStopped
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Agent.Docker.Models
{
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class ThrottleDevice
{
[JsonProperty("Path", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string Path { get; set; }

[JsonProperty("Rate", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public ulong Rate { get; set; }

[JsonExtensionData]
public IDictionary<string, JToken> OtherProperties { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Agent.Docker.Models
{
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class Ulimit
{
[JsonProperty("Name", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string Name { get; set; }

[JsonProperty("Hard", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long Hard { get; set; }

[JsonProperty("Soft", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public long Soft { get; set; }

[JsonExtensionData]
public IDictionary<string, JToken> OtherProperties { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Agent.Docker.Models
{
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class WeightDevice
{
[JsonProperty("Path", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public string Path { get; set; }

[JsonProperty("Weight", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public ushort Weight { get; set; }

[JsonExtensionData]
public IDictionary<string, JToken> OtherProperties { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public KubernetesModule(
string version,
string type,
ModuleStatus status,
RestartPolicy restartPolicy,
Core.RestartPolicy restartPolicy,
ConfigurationInfo configurationInfo,
IDictionary<string, EnvVal> env,
KubernetesConfig settings,
Expand Down Expand Up @@ -69,7 +69,7 @@ public KubernetesModule(
public ModuleStatus DesiredStatus { get; }

[JsonProperty(PropertyName = "restartPolicy")]
public RestartPolicy RestartPolicy { get; }
public Core.RestartPolicy RestartPolicy { get; }

[JsonProperty(PropertyName = "imagePullPolicy")]
public ImagePullPolicy ImagePullPolicy { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,57 @@ public void ExtensionDataFields()
}
}

[Fact]
public void ExtensionDataFields_BackwardCompatibility_LowercaseToUppercase()
{
// Arrange
var runtimeInfo = new Mock<IRuntimeInfo<DockerRuntimeConfig>>();
runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

// capabilities will remain lowercase because there is no backward compatibility issue for those properties supported after 1.0.9
string createOptions = "{\"HostConfig\":{\"portBindings\":{\"8883/tcp\":[{\"hostPort\":\"8883\"}]},\"Devices\":[],\"runtime\":\"nvidia\",\"DeviceRequests\":[{\"Driver\":\"\",\"Count\":-1,\"DeviceIDs\":null,\"capabilities\":[[\"gpu\"]],\"Options\":{}}]}}";
var module = new Mock<IModule<DockerConfig>>();
module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", createOptions, Option.None<string>()));
module.SetupGet(m => m.Name).Returns("mod1");

IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
new Dictionary<string, string>
{
{ Constants.EdgeletWorkloadUriVariableName, "unix:///var/run/iotedgedworkload.sock" },
{ Constants.EdgeletManagementUriVariableName, "unix:///var/run/iotedgedmgmt.sock" },
{ Constants.NetworkIdKey, "testnetwork1" },
{ Constants.EdgeDeviceHostNameKey, "edhk1" }
}).Build();
var configSource = Mock.Of<IConfigSource>(s => s.Configuration == configRoot);

ICombinedConfigProvider<CombinedDockerConfig> provider = new CombinedEdgeletConfigProvider(new[] { new AuthConfig() }, configSource);

// Act
CombinedDockerConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

// Assert
Assert.NotNull(config.CreateOptions);
Assert.NotNull(config.CreateOptions.HostConfig);

var otherProperties = config.CreateOptions.HostConfig.OtherProperties;
Assert.NotNull(otherProperties);

var reserializedHostConfig = Newtonsoft.Json.JsonConvert.SerializeObject(config.CreateOptions.HostConfig);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Equal(
"{\"Binds\":[\"\\\\var\\\\run:\\\\var\\\\run\"],\"PortBindings\":{\"8883/tcp\":[{\"HostPort\":\"8883\"}]},\"Devices\":[],\"Runtime\":\"nvidia\",\"DeviceRequests\":[{\"Driver\":\"\",\"Count\":-1,\"DeviceIDs\":null,\"capabilities\":[[\"gpu\"]],\"Options\":{}}]}",
reserializedHostConfig);
}
else
{
Assert.Equal(
"{\"Binds\":[\"/var/run/iotedgedworkload.sock:/var/run/iotedgedworkload.sock\"],\"PortBindings\":{\"8883/tcp\":[{\"HostPort\":\"8883\"}]},\"Devices\":[],\"Runtime\":\"nvidia\",\"DeviceRequests\":[{\"Driver\":\"\",\"Count\":-1,\"DeviceIDs\":null,\"capabilities\":[[\"gpu\"]],\"Options\":{}}]}",
reserializedHostConfig);
}
}


static (IDictionary<string, EnvVal>, string) CreateEnv(params (string key, string value)[] pairs)
{
var dict = new Dictionary<string, EnvVal>();
Expand Down
Loading

0 comments on commit e34cff7

Please sign in to comment.