Merge pull request #1552 from william-richard/ecs-memory-hard-limit-cpu-host-port-are-optional

ECS CPU, memory hard limits and host ports are all optional.
This commit is contained in:
Steve Pulec 2018-04-12 18:42:51 -04:00 committed by GitHub
commit e3b377d9fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 4 deletions

View File

@ -502,10 +502,27 @@ class EC2ContainerServiceBackend(BaseBackend):
def _calculate_task_resource_requirements(task_definition):
resource_requirements = {"CPU": 0, "MEMORY": 0, "PORTS": [], "PORTS_UDP": []}
for container_definition in task_definition.container_definitions:
resource_requirements["CPU"] += container_definition.get('cpu')
resource_requirements["MEMORY"] += container_definition.get("memory")
for port_mapping in container_definition.get("portMappings", []):
resource_requirements["PORTS"].append(port_mapping.get('hostPort'))
# cloudformation uses capitalized properties, while boto uses all lower case
# CPU is optional
resource_requirements["CPU"] += container_definition.get('cpu',
container_definition.get('Cpu', 0))
# either memory or memory reservation must be provided
if 'Memory' in container_definition or 'MemoryReservation' in container_definition:
resource_requirements["MEMORY"] += container_definition.get(
"Memory", container_definition.get('MemoryReservation'))
else:
resource_requirements["MEMORY"] += container_definition.get(
"memory", container_definition.get('memoryReservation'))
port_mapping_key = 'PortMappings' if 'PortMappings' in container_definition else 'portMappings'
for port_mapping in container_definition.get(port_mapping_key, []):
if 'hostPort' in port_mapping:
resource_requirements["PORTS"].append(port_mapping.get('hostPort'))
elif 'HostPort' in port_mapping:
resource_requirements["PORTS"].append(port_mapping.get('HostPort'))
return resource_requirements
@staticmethod

View File

@ -1229,6 +1229,87 @@ def test_resource_reservation_and_release():
remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
container_instance_description['runningTasksCount'].should.equal(0)
@mock_ec2
@mock_ecs
def test_resource_reservation_and_release_memory_reservation():
client = boto3.client('ecs', region_name='us-east-1')
ec2 = boto3.resource('ec2', region_name='us-east-1')
test_cluster_name = 'test_ecs_cluster'
_ = client.create_cluster(
clusterName=test_cluster_name
)
test_instance = ec2.create_instances(
ImageId="ami-1234abcd",
MinCount=1,
MaxCount=1,
)[0]
instance_id_document = json.dumps(
ec2_utils.generate_instance_identity_document(test_instance)
)
_ = client.register_container_instance(
cluster=test_cluster_name,
instanceIdentityDocument=instance_id_document
)
_ = client.register_task_definition(
family='test_ecs_task',
containerDefinitions=[
{
'name': 'hello_world',
'image': 'docker/hello-world:latest',
'memoryReservation': 400,
'essential': True,
'environment': [{
'name': 'AWS_ACCESS_KEY_ID',
'value': 'SOME_ACCESS_KEY'
}],
'logConfiguration': {'logDriver': 'json-file'},
'portMappings': [
{
'containerPort': 8080
}
]
}
]
)
run_response = client.run_task(
cluster='test_ecs_cluster',
overrides={},
taskDefinition='test_ecs_task',
count=1,
startedBy='moto'
)
container_instance_arn = run_response['tasks'][0].get('containerInstanceArn')
container_instance_description = client.describe_container_instances(
cluster='test_ecs_cluster',
containerInstances=[container_instance_arn]
)['containerInstances'][0]
remaining_resources, registered_resources = _fetch_container_instance_resources(container_instance_description)
remaining_resources['CPU'].should.equal(registered_resources['CPU'])
remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'] - 400)
remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
container_instance_description['runningTasksCount'].should.equal(1)
client.stop_task(
cluster='test_ecs_cluster',
task=run_response['tasks'][0].get('taskArn'),
reason='moto testing'
)
container_instance_description = client.describe_container_instances(
cluster='test_ecs_cluster',
containerInstances=[container_instance_arn]
)['containerInstances'][0]
remaining_resources, registered_resources = _fetch_container_instance_resources(container_instance_description)
remaining_resources['CPU'].should.equal(registered_resources['CPU'])
remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'])
remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
container_instance_description['runningTasksCount'].should.equal(0)
@mock_ecs
@mock_cloudformation