Skip to content

Commit 7d68914

Browse files
committed
Merge ecs-params service resources with task def values
1 parent 16d7aa7 commit 7d68914

File tree

2 files changed

+192
-6
lines changed

2 files changed

+192
-6
lines changed

ecs-cli/modules/utils/compose/convert_task_definition.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,6 @@ func convertToContainerDef(inputCfg *adapter.ContainerConfig, ecsContainerDef *C
248248
return nil, errors.New("mem_limit must be greater than mem_reservation")
249249
}
250250

251-
// One or both of memory and memoryReservation is required to register a task definition with ECS
252-
// NOTE: Docker does not set a memory limit for containers
253-
if mem == 0 && memoryReservation == 0 {
254-
mem = defaultMemLimit
255-
}
256-
257251
// Populate ECS container definition, offloading the validation to aws-sdk
258252
outputContDef.SetCpu(inputCfg.CPU)
259253
outputContDef.SetCommand(aws.StringSlice(inputCfg.Command))
@@ -317,6 +311,44 @@ func convertToContainerDef(inputCfg *adapter.ContainerConfig, ecsContainerDef *C
317311
// Set fields from ecs-params file
318312
if ecsContainerDef != nil {
319313
outputContDef.Essential = aws.Bool(ecsContainerDef.Essential)
314+
315+
overrideMsg := "Using ecs-params value as override (was %v but is now %v)"
316+
if ecsContainerDef.Cpu > 0 {
317+
if outputContDef.Cpu != nil && *outputContDef.Cpu > 0 {
318+
log.WithFields(log.Fields{
319+
"option name": "Cpu",
320+
"service name": inputCfg.Name,
321+
}).Infof(overrideMsg, *outputContDef.Cpu, ecsContainerDef.Cpu)
322+
}
323+
outputContDef.Cpu = aws.Int64(ecsContainerDef.Cpu)
324+
}
325+
memInMB := adapter.ConvertToMemoryInMB(int64(ecsContainerDef.Memory))
326+
if memInMB > 0 {
327+
if outputContDef.Memory != nil {
328+
log.WithFields(log.Fields{
329+
"option name": "Memory",
330+
"service name": inputCfg.Name,
331+
}).Infof(overrideMsg, *outputContDef.Memory, memInMB)
332+
}
333+
outputContDef.Memory = aws.Int64(memInMB)
334+
}
335+
memResInMB := adapter.ConvertToMemoryInMB(int64(ecsContainerDef.MemoryReservation))
336+
if memResInMB > 0 {
337+
if outputContDef.MemoryReservation != nil {
338+
log.WithFields(log.Fields{
339+
"option name": "MemoryReservation",
340+
"service name": inputCfg.Name,
341+
}).Infof(overrideMsg, *outputContDef.MemoryReservation, memResInMB)
342+
}
343+
outputContDef.MemoryReservation = aws.Int64(memResInMB)
344+
}
345+
}
346+
347+
// One or both of memory and memoryReservation is required to register a task definition with ECS
348+
// If neither is provided by 1) compose file or 2) ecs-params, set default
349+
// NOTE: Docker does not set a memory limit for containers
350+
if outputContDef.Memory == nil && outputContDef.MemoryReservation == nil {
351+
outputContDef.SetMemory(defaultMemLimit)
320352
}
321353

322354
return outputContDef, nil

ecs-cli/modules/utils/compose/convert_task_definition_test.go

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,160 @@ task_definition:
731731
}
732732
}
733733

734+
func TestConvertToTaskDefinitionWithECSParams_ContainerResourcesPresent(t *testing.T) {
735+
containerConfigs := testContainerConfigs([]string{"mysql", "wordpress"})
736+
737+
mysqlCPU := int64(100)
738+
mysqlMem := int64(15)
739+
mysqlMemRes := int64(10)
740+
741+
wordpressCPU := int64(4)
742+
wordpressMem := int64(8)
743+
wordpressMemRes := int64(5)
744+
745+
ecsParamsString := `version: 1
746+
task_definition:
747+
services:
748+
mysql:
749+
cpu_shares: 100
750+
mem_limit: 15m
751+
mem_reservation: 10m
752+
wordpress:
753+
cpu_shares: 4
754+
mem_limit: 8m
755+
mem_reservation: 5m`
756+
757+
content := []byte(ecsParamsString)
758+
759+
tmpfile, err := ioutil.TempFile("", "ecs-params")
760+
assert.NoError(t, err, "Could not create ecs fields tempfile")
761+
762+
defer os.Remove(tmpfile.Name())
763+
764+
_, err = tmpfile.Write(content)
765+
assert.NoError(t, err, "Could not write data to ecs fields tempfile")
766+
767+
err = tmpfile.Close()
768+
assert.NoError(t, err, "Could not close tempfile")
769+
770+
ecsParamsFileName := tmpfile.Name()
771+
ecsParams, err := ReadECSParams(ecsParamsFileName)
772+
assert.NoError(t, err, "Could not read ECS Params file")
773+
774+
taskDefinition, err := convertToTaskDefWithEcsParamsInTest(t, containerConfigs, "", ecsParams)
775+
776+
containerDefs := taskDefinition.ContainerDefinitions
777+
mysql := findContainerByName("mysql", containerDefs)
778+
wordpress := findContainerByName("wordpress", containerDefs)
779+
780+
if assert.NoError(t, err) {
781+
assert.Equal(t, mysqlCPU, aws.Int64Value(mysql.Cpu), "Expected CPU to match")
782+
assert.Equal(t, mysqlMem, aws.Int64Value(mysql.Memory), "Expected Memory to match")
783+
assert.Equal(t, mysqlMemRes, aws.Int64Value(mysql.MemoryReservation), "Expected MemoryReservation to match")
784+
785+
assert.Equal(t, wordpressCPU, aws.Int64Value(wordpress.Cpu), "Expected CPU to match")
786+
assert.Equal(t, wordpressMem, aws.Int64Value(wordpress.Memory), "Expected Memory to match")
787+
assert.Equal(t, wordpressMemRes, aws.Int64Value(wordpress.MemoryReservation), "Expected MemoryReservation to match")
788+
}
789+
}
790+
791+
func TestConvertToTaskDefinitionWithECSParams_ContainerResourcesOverrideProvidedVals(t *testing.T) {
792+
containerConfig := &adapter.ContainerConfig{
793+
Name: "web",
794+
Image: "httpd",
795+
CPU: int64(2),
796+
Memory: int64(3),
797+
MemoryReservation: int64(3),
798+
}
799+
800+
// define ecs-params values we expect to override containerConfig vals
801+
webCPU := int64(5)
802+
webMem := int64(15)
803+
webMemRes := int64(10)
804+
805+
ecsParamsString := `version: 1
806+
task_definition:
807+
services:
808+
web:
809+
cpu_shares: 5
810+
mem_limit: 15m
811+
mem_reservation: 10m`
812+
813+
content := []byte(ecsParamsString)
814+
815+
tmpfile, err := ioutil.TempFile("", "ecs-params")
816+
assert.NoError(t, err, "Could not create ecs fields tempfile")
817+
818+
defer os.Remove(tmpfile.Name())
819+
820+
_, err = tmpfile.Write(content)
821+
assert.NoError(t, err, "Could not write data to ecs fields tempfile")
822+
823+
err = tmpfile.Close()
824+
assert.NoError(t, err, "Could not close tempfile")
825+
826+
ecsParamsFileName := tmpfile.Name()
827+
ecsParams, err := ReadECSParams(ecsParamsFileName)
828+
assert.NoError(t, err, "Could not read ECS Params file")
829+
830+
containerConfigs := []adapter.ContainerConfig{*containerConfig}
831+
taskDefinition, err := convertToTaskDefWithEcsParamsInTest(t, containerConfigs, "", ecsParams)
832+
833+
containerDefs := taskDefinition.ContainerDefinitions
834+
web := findContainerByName("web", containerDefs)
835+
836+
if assert.NoError(t, err) {
837+
assert.Equal(t, webCPU, aws.Int64Value(web.Cpu), "Expected CPU to match")
838+
assert.Equal(t, webMem, aws.Int64Value(web.Memory), "Expected Memory to match")
839+
assert.Equal(t, webMemRes, aws.Int64Value(web.MemoryReservation), "Expected MemoryReservation to match")
840+
}
841+
}
842+
843+
func TestConvertToTaskDefinitionWithECSParams_NoMemoryProvided(t *testing.T) {
844+
containerConfig := &adapter.ContainerConfig{
845+
Name: "web",
846+
Image: "httpd",
847+
}
848+
849+
// define ecs-params values we expect to override containerConfig vals
850+
webCPU := int64(5)
851+
852+
ecsParamsString := `version: 1
853+
task_definition:
854+
services:
855+
web:
856+
cpu_shares: 5`
857+
858+
content := []byte(ecsParamsString)
859+
860+
tmpfile, err := ioutil.TempFile("", "ecs-params")
861+
assert.NoError(t, err, "Could not create ecs fields tempfile")
862+
863+
defer os.Remove(tmpfile.Name())
864+
865+
_, err = tmpfile.Write(content)
866+
assert.NoError(t, err, "Could not write data to ecs fields tempfile")
867+
868+
err = tmpfile.Close()
869+
assert.NoError(t, err, "Could not close tempfile")
870+
871+
ecsParamsFileName := tmpfile.Name()
872+
ecsParams, err := ReadECSParams(ecsParamsFileName)
873+
assert.NoError(t, err, "Could not read ECS Params file")
874+
875+
containerConfigs := []adapter.ContainerConfig{*containerConfig}
876+
taskDefinition, err := convertToTaskDefWithEcsParamsInTest(t, containerConfigs, "", ecsParams)
877+
878+
containerDefs := taskDefinition.ContainerDefinitions
879+
web := findContainerByName("web", containerDefs)
880+
881+
if assert.NoError(t, err) {
882+
assert.Equal(t, webCPU, aws.Int64Value(web.Cpu), "Expected CPU to match")
883+
assert.Equal(t, int64(defaultMemLimit), aws.Int64Value(web.Memory), "Expected Memory to match default")
884+
assert.Empty(t, aws.Int64Value(web.MemoryReservation), "Expected MemoryReservation to be empty")
885+
}
886+
}
887+
734888
func TestConvertToTaskDefinition_WithTaskSize(t *testing.T) {
735889
containerConfigs := testContainerConfigs([]string{"mysql", "wordpress"})
736890
ecsParamsString := `version: 1

0 commit comments

Comments
 (0)