|
|
@@ -175,10 +175,6 @@ func getDNSSidecar(containers []containerinstance.Container) containerinstance.C
|
|
|
Image: to.StringPtr(dnsSidecarImage),
|
|
|
Command: &alpineCmd,
|
|
|
Resources: &containerinstance.ResourceRequirements{
|
|
|
- Limits: &containerinstance.ResourceLimits{
|
|
|
- MemoryInGB: to.Float64Ptr(0.1), // "The memory requirement should be in incrememts of 0.1 GB."
|
|
|
- CPU: to.Float64Ptr(0.01), // "The CPU requirement should be in incrememts of 0.01."
|
|
|
- },
|
|
|
Requests: &containerinstance.ResourceRequests{
|
|
|
MemoryInGB: to.Float64Ptr(0.1),
|
|
|
CPU: to.Float64Ptr(0.01),
|
|
|
@@ -357,38 +353,73 @@ func (s serviceConfigAciHelper) getAciContainer(volumesCache map[string]bool) (c
|
|
|
volumes = &allVolumes
|
|
|
}
|
|
|
|
|
|
- memLimit := 1. // Default 1 Gb
|
|
|
- var cpuLimit float64 = 1
|
|
|
+ resource, err := s.getResourceRequestsLimits()
|
|
|
+ if err != nil {
|
|
|
+ return containerinstance.Container{}, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return containerinstance.Container{
|
|
|
+ Name: to.StringPtr(s.Name),
|
|
|
+ ContainerProperties: &containerinstance.ContainerProperties{
|
|
|
+ Image: to.StringPtr(s.Image),
|
|
|
+ Command: to.StringSlicePtr(s.Command),
|
|
|
+ EnvironmentVariables: getEnvVariables(s.Environment),
|
|
|
+ Resources: resource,
|
|
|
+ VolumeMounts: volumes,
|
|
|
+ },
|
|
|
+ }, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (s serviceConfigAciHelper) getResourceRequestsLimits() (*containerinstance.ResourceRequirements, error) {
|
|
|
+ memRequest := 1. // Default 1 Gb
|
|
|
+ var cpuRequest float64 = 1
|
|
|
+ var err error
|
|
|
+ hasMemoryRequest := func() bool {
|
|
|
+ return s.Deploy != nil && s.Deploy.Resources.Reservations != nil && s.Deploy.Resources.Reservations.MemoryBytes != 0
|
|
|
+ }
|
|
|
+ hasCPURequest := func() bool {
|
|
|
+ return s.Deploy != nil && s.Deploy.Resources.Reservations != nil && s.Deploy.Resources.Reservations.NanoCPUs != ""
|
|
|
+ }
|
|
|
+ if hasMemoryRequest() {
|
|
|
+ memRequest = bytesToGb(s.Deploy.Resources.Reservations.MemoryBytes)
|
|
|
+ }
|
|
|
+
|
|
|
+ if hasCPURequest() {
|
|
|
+ cpuRequest, err = strconv.ParseFloat(s.Deploy.Resources.Reservations.NanoCPUs, 0)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ memLimit := memRequest
|
|
|
+ cpuLimit := cpuRequest
|
|
|
if s.Deploy != nil && s.Deploy.Resources.Limits != nil {
|
|
|
if s.Deploy.Resources.Limits.MemoryBytes != 0 {
|
|
|
memLimit = bytesToGb(s.Deploy.Resources.Limits.MemoryBytes)
|
|
|
+ if !hasMemoryRequest() {
|
|
|
+ memRequest = memLimit
|
|
|
+ }
|
|
|
}
|
|
|
if s.Deploy.Resources.Limits.NanoCPUs != "" {
|
|
|
cpuLimit, err = strconv.ParseFloat(s.Deploy.Resources.Limits.NanoCPUs, 0)
|
|
|
if err != nil {
|
|
|
- return containerinstance.Container{}, err
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if !hasCPURequest() {
|
|
|
+ cpuRequest = cpuLimit
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return containerinstance.Container{
|
|
|
- Name: to.StringPtr(s.Name),
|
|
|
- ContainerProperties: &containerinstance.ContainerProperties{
|
|
|
- Image: to.StringPtr(s.Image),
|
|
|
- Command: to.StringSlicePtr(s.Command),
|
|
|
- EnvironmentVariables: getEnvVariables(s.Environment),
|
|
|
- Resources: &containerinstance.ResourceRequirements{
|
|
|
- Limits: &containerinstance.ResourceLimits{
|
|
|
- MemoryInGB: to.Float64Ptr(memLimit),
|
|
|
- CPU: to.Float64Ptr(cpuLimit),
|
|
|
- },
|
|
|
- Requests: &containerinstance.ResourceRequests{
|
|
|
- MemoryInGB: to.Float64Ptr(memLimit), // TODO: use the memory requests here and not limits
|
|
|
- CPU: to.Float64Ptr(cpuLimit), // TODO: use the cpu requests here and not limits
|
|
|
- },
|
|
|
- },
|
|
|
- VolumeMounts: volumes,
|
|
|
+ resources := containerinstance.ResourceRequirements{
|
|
|
+ Requests: &containerinstance.ResourceRequests{
|
|
|
+ MemoryInGB: to.Float64Ptr(memRequest),
|
|
|
+ CPU: to.Float64Ptr(cpuRequest),
|
|
|
},
|
|
|
- }, nil
|
|
|
+ Limits: &containerinstance.ResourceLimits{
|
|
|
+ MemoryInGB: to.Float64Ptr(memLimit),
|
|
|
+ CPU: to.Float64Ptr(cpuLimit),
|
|
|
+ },
|
|
|
+ }
|
|
|
+ return &resources, nil
|
|
|
}
|
|
|
|
|
|
func getEnvVariables(composeEnv types.MappingWithEquals) *[]containerinstance.EnvironmentVariable {
|
|
|
@@ -413,6 +444,10 @@ func bytesToGb(b types.UnitBytes) float64 {
|
|
|
return math.Round(f*100) / 100
|
|
|
}
|
|
|
|
|
|
+func gbToBytes(memInBytes float64) uint64 {
|
|
|
+ return uint64(memInBytes * 1024 * 1024 * 1024)
|
|
|
+}
|
|
|
+
|
|
|
// ContainerGroupToServiceStatus convert from an ACI container definition to service status
|
|
|
func ContainerGroupToServiceStatus(containerID string, group containerinstance.ContainerGroup, container containerinstance.Container, region string) compose.ServiceStatus {
|
|
|
var replicas = 1
|
|
|
@@ -438,18 +473,27 @@ func fqdn(group containerinstance.ContainerGroup, region string) string {
|
|
|
|
|
|
// ContainerGroupToContainer composes a Container from an ACI container definition
|
|
|
func ContainerGroupToContainer(containerID string, cg containerinstance.ContainerGroup, cc containerinstance.Container, region string) containers.Container {
|
|
|
- memLimits := 0.
|
|
|
- if cc.Resources != nil &&
|
|
|
- cc.Resources.Limits != nil &&
|
|
|
- cc.Resources.Limits.MemoryInGB != nil {
|
|
|
- memLimits = *cc.Resources.Limits.MemoryInGB * 1024 * 1024 * 1024
|
|
|
- }
|
|
|
-
|
|
|
+ memLimits := uint64(0)
|
|
|
+ memRequest := uint64(0)
|
|
|
cpuLimit := 0.
|
|
|
- if cc.Resources != nil &&
|
|
|
- cc.Resources.Limits != nil &&
|
|
|
- cc.Resources.Limits.CPU != nil {
|
|
|
- cpuLimit = *cc.Resources.Limits.CPU
|
|
|
+ cpuReservation := 0.
|
|
|
+ if cc.Resources != nil {
|
|
|
+ if cc.Resources.Limits != nil {
|
|
|
+ if cc.Resources.Limits.MemoryInGB != nil {
|
|
|
+ memLimits = gbToBytes(*cc.Resources.Limits.MemoryInGB)
|
|
|
+ }
|
|
|
+ if cc.Resources.Limits.CPU != nil {
|
|
|
+ cpuLimit = *cc.Resources.Limits.CPU
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if cc.Resources.Requests != nil {
|
|
|
+ if cc.Resources.Requests.MemoryInGB != nil {
|
|
|
+ memRequest = gbToBytes(*cc.Resources.Requests.MemoryInGB)
|
|
|
+ }
|
|
|
+ if cc.Resources.Requests.CPU != nil {
|
|
|
+ cpuReservation = *cc.Resources.Requests.CPU
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
command := ""
|
|
|
@@ -468,26 +512,30 @@ func ContainerGroupToContainer(containerID string, cg containerinstance.Containe
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- var config *containers.RuntimeConfig = &containers.RuntimeConfig{FQDN: fqdn(cg, region)}
|
|
|
- if envVars != nil {
|
|
|
- config.Env = envVars
|
|
|
+ config := &containers.RuntimeConfig{
|
|
|
+ FQDN: fqdn(cg, region),
|
|
|
+ Env: envVars,
|
|
|
+ }
|
|
|
+ hostConfig := &containers.HostConfig{
|
|
|
+ CPULimit: cpuLimit,
|
|
|
+ CPUReservation: cpuReservation,
|
|
|
+ MemoryLimit: memLimits,
|
|
|
+ MemoryReservation: memRequest,
|
|
|
+ RestartPolicy: toContainerRestartPolicy(cg.RestartPolicy),
|
|
|
}
|
|
|
c := containers.Container{
|
|
|
- ID: containerID,
|
|
|
- Status: status,
|
|
|
- Image: to.String(cc.Image),
|
|
|
- Command: command,
|
|
|
- CPUTime: 0,
|
|
|
- CPULimit: cpuLimit,
|
|
|
- MemoryUsage: 0,
|
|
|
- MemoryLimit: uint64(memLimits),
|
|
|
- PidsCurrent: 0,
|
|
|
- PidsLimit: 0,
|
|
|
- Labels: nil,
|
|
|
- Ports: ToPorts(cg.IPAddress, *cc.Ports),
|
|
|
- Platform: platform,
|
|
|
- RestartPolicyCondition: toContainerRestartPolicy(cg.RestartPolicy),
|
|
|
- Config: config,
|
|
|
+ ID: containerID,
|
|
|
+ Status: status,
|
|
|
+ Image: to.String(cc.Image),
|
|
|
+ Command: command,
|
|
|
+ CPUTime: 0,
|
|
|
+ MemoryUsage: 0,
|
|
|
+ PidsCurrent: 0,
|
|
|
+ PidsLimit: 0,
|
|
|
+ Ports: ToPorts(cg.IPAddress, *cc.Ports),
|
|
|
+ Platform: platform,
|
|
|
+ Config: config,
|
|
|
+ HostConfig: hostConfig,
|
|
|
}
|
|
|
|
|
|
return c
|