Distinguish limits for Fargate and EC2

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2020-09-22 12:15:55 +02:00
parent 109ba96743
commit 2cfaf69546
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
6 changed files with 73 additions and 36 deletions

View File

@ -277,7 +277,7 @@ func (b *ecsAPIService) convert(project *types.Project) (*cloudformation.Templat
LoadBalancers: serviceLB,
NetworkConfiguration: &ecs.Service_NetworkConfiguration{
AwsvpcConfiguration: &ecs.Service_AwsVpcConfiguration{
AssignPublicIp: ecsapi.AssignPublicIpDisabled,
AssignPublicIp: ecsapi.AssignPublicIpEnabled,
SecurityGroups: serviceSecurityGroups,
Subnets: []string{
cloudformation.Ref(parameterSubnet1Id),

View File

@ -245,6 +245,15 @@ services:
func TestTaskSizeConvert(t *testing.T) {
template := convertYaml(t, `
services:
test:
image: nginx
`)
def := template.Resources["TestTaskDefinition"].(*ecs.TaskDefinition)
assert.Equal(t, def.Cpu, "256")
assert.Equal(t, def.Memory, "512")
template = convertYaml(t, `
services:
test:
image: nginx
@ -253,11 +262,8 @@ services:
limits:
cpus: '0.5'
memory: 2048M
reservations:
cpus: '0.5'
memory: 2048M
`)
def := template.Resources["TestTaskDefinition"].(*ecs.TaskDefinition)
def = template.Resources["TestTaskDefinition"].(*ecs.TaskDefinition)
assert.Equal(t, def.Cpu, "512")
assert.Equal(t, def.Memory, "2048")
@ -270,13 +276,29 @@ services:
limits:
cpus: '4'
memory: 8192M
reservations:
cpus: '4'
memory: 8192M
`)
def = template.Resources["TestTaskDefinition"].(*ecs.TaskDefinition)
assert.Equal(t, def.Cpu, "4096")
assert.Equal(t, def.Memory, "8192")
template = convertYaml(t, `
services:
test:
image: nginx
deploy:
resources:
limits:
cpus: '4'
memory: 792Mb
reservations:
generic_resources:
- discrete_resource_spec:
kind: gpus
value: 2
`)
def = template.Resources["TestTaskDefinition"].(*ecs.TaskDefinition)
assert.Equal(t, def.Cpu, "4000")
assert.Equal(t, def.Memory, "792")
}
func TestTaskSizeConvertFailure(t *testing.T) {
model := loadConfig(t, `

View File

@ -323,8 +323,17 @@ func toSystemControls(sysctls types.Mapping) []ecs.TaskDefinition_SystemControl
const miB = 1024 * 1024
func toLimits(service types.ServiceConfig) (string, string, error) {
// All possible CPU/mem values for Fargate
cpuToMem := map[int64][]types.UnitBytes{
mem, cpu, err := getConfiguredLimits(service)
if err != nil {
return "", "", err
}
if requireEC2(service) {
// just return configured limits expressed in Mb and CPU units
return fmt.Sprint(cpu), fmt.Sprint(mem / miB), nil
}
// All possible cpu/mem values for Fargate
fargateCPUToMem := map[int64][]types.UnitBytes{
256: {512, 1024, 2048},
512: {1024, 2048, 3072, 4096},
1024: {2048, 3072, 4096, 5120, 6144, 7168, 8192},
@ -333,37 +342,22 @@ func toLimits(service types.ServiceConfig) (string, string, error) {
}
cpuLimit := "256"
memLimit := "512"
if service.Deploy == nil {
if mem == 0 && cpu == 0 {
return cpuLimit, memLimit, nil
}
limits := service.Deploy.Resources.Limits
if limits == nil {
return cpuLimit, memLimit, nil
}
if limits.NanoCPUs == "" {
return cpuLimit, memLimit, nil
}
v, err := opts.ParseCPUs(limits.NanoCPUs)
if err != nil {
return "", "", err
}
var cpus []int64
for k := range cpuToMem {
for k := range fargateCPUToMem {
cpus = append(cpus, k)
}
sort.Slice(cpus, func(i, j int) bool { return cpus[i] < cpus[j] })
for _, cpu := range cpus {
mem := cpuToMem[cpu]
if v <= cpu*miB {
for _, m := range mem {
if limits.MemoryBytes <= m*miB {
cpuLimit = strconv.FormatInt(cpu, 10)
for _, fargateCPU := range cpus {
options := fargateCPUToMem[fargateCPU]
if cpu <= fargateCPU {
for _, m := range options {
if mem <= m*miB {
cpuLimit = strconv.FormatInt(fargateCPU, 10)
memLimit = strconv.FormatInt(int64(m), 10)
return cpuLimit, memLimit, nil
}
@ -373,6 +367,27 @@ func toLimits(service types.ServiceConfig) (string, string, error) {
return "", "", fmt.Errorf("the resources requested are not supported by ECS/Fargate")
}
func getConfiguredLimits(service types.ServiceConfig) (types.UnitBytes, int64, error) {
if service.Deploy == nil {
return 0, 0, nil
}
limits := service.Deploy.Resources.Limits
if limits == nil {
return 0, 0, nil
}
if limits.NanoCPUs == "" {
return limits.MemoryBytes, 0, nil
}
v, err := opts.ParseCPUs(limits.NanoCPUs)
if err != nil {
return 0, 0, err
}
return limits.MemoryBytes, v / 1e6, nil
}
func toContainerReservation(service types.ServiceConfig) (string, int) {
cpuReservation := ".0"
memReservation := 0

View File

@ -92,7 +92,7 @@ func (s sdk) CheckRequirements(ctx context.Context, region string) error {
if *serviceLongArnFormat != "enabled" {
return fmt.Errorf("this tool requires the \"new ARN resource ID format\".\n"+
"Check https://%s.console.aws.amazon.com/ecs/home#/settings\n"+
"Learn more: https://aws.amazon.com/blogs/compute/migrating-your-amazon-ecs-deployment-to-the-new-arn-and-resource-ID-format-2", region)
"Learn more: https://aws.amazon.com/blogs/compute/migrating-your-amazon-ecs-deployment-to-the-new-arn-and-resource-id-format-2", region)
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2020 Docker, Inc.
Copyright 2020 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -107,7 +107,7 @@
],
"NetworkConfiguration": {
"AwsvpcConfiguration": {
"AssignPublicIp": "DISABLED",
"AssignPublicIp": "ENABLED",
"SecurityGroups": [
{
"Ref": "TestSimpleConvertDefaultNetwork"