diff --git a/compose/config/config.py b/compose/config/config.py index 71364316b..dbf64bae2 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -76,7 +76,8 @@ DOCKER_CONFIG_KEYS = [ 'labels', 'links', 'mac_address', - 'mem_limit', + 'mem_limit' + 'mem_reservation', 'memswap_limit', 'mem_swappiness', 'net', diff --git a/compose/config/config_schema_v2.0.json b/compose/config/config_schema_v2.0.json index d20a0d89a..54e9b3314 100644 --- a/compose/config/config_schema_v2.0.json +++ b/compose/config/config_schema_v2.0.json @@ -145,8 +145,9 @@ "mac_address": {"type": "string"}, "mem_limit": {"type": ["number", "string"]}, - "memswap_limit": {"type": ["number", "string"]}, + "mem_reservation": {"type": ["string", "integer"]}, "mem_swappiness": {"type": "integer"}, + "memswap_limit": {"type": ["number", "string"]}, "network_mode": {"type": "string"}, "networks": { diff --git a/compose/config/config_schema_v2.1.json b/compose/config/config_schema_v2.1.json index 7247f9a90..0f87be24e 100644 --- a/compose/config/config_schema_v2.1.json +++ b/compose/config/config_schema_v2.1.json @@ -168,8 +168,9 @@ "mac_address": {"type": "string"}, "mem_limit": {"type": ["number", "string"]}, - "memswap_limit": {"type": ["number", "string"]}, + "mem_reservation": {"type": ["string", "integer"]}, "mem_swappiness": {"type": "integer"}, + "memswap_limit": {"type": ["number", "string"]}, "network_mode": {"type": "string"}, "networks": { diff --git a/compose/service.py b/compose/service.py index 5e2ae3640..712d5ac15 100644 --- a/compose/service.py +++ b/compose/service.py @@ -64,9 +64,10 @@ DOCKER_START_KEYS = [ 'log_driver', 'log_opt', 'mem_limit', + 'mem_reservation', 'memswap_limit', - 'oom_score_adj', 'mem_swappiness', + 'oom_score_adj', 'pid', 'pids_limit', 'privileged', @@ -766,6 +767,7 @@ class Service(object): cap_add=options.get('cap_add'), cap_drop=options.get('cap_drop'), mem_limit=options.get('mem_limit'), + mem_reservation=options.get('mem_reservation'), memswap_limit=options.get('memswap_limit'), ulimits=build_ulimits(options.get('ulimits')), log_config=log_config, diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py index 8104163bb..ddc2f3bae 100644 --- a/tests/integration/service_test.py +++ b/tests/integration/service_test.py @@ -880,6 +880,11 @@ class ServiceTest(DockerClientTestCase): container = create_and_start_container(service) self.assertEqual(container.get('HostConfig.MemorySwappiness'), 11) + def test_mem_reservation(self): + service = self.create_service('web', mem_reservation='20m') + container = create_and_start_container(service) + assert container.get('HostConfig.MemoryReservation') == 20 * 1024 * 1024 + def test_restart_always_value(self): service = self.create_service('web', restart={'Name': 'always'}) container = create_and_start_container(service) diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py index 4d81623ba..5dc5265e6 100644 --- a/tests/unit/service_test.py +++ b/tests/unit/service_test.py @@ -170,6 +170,20 @@ class ServiceTest(unittest.TestCase): 2000000000 ) + def test_mem_reservation(self): + self.mock_client.create_host_config.return_value = {} + + service = Service( + name='foo', + image='foo', + hostname='name', + client=self.mock_client, + mem_reservation='512m' + ) + service._get_container_create_options({'some': 'overrides'}, 1) + assert self.mock_client.create_host_config.called is True + assert self.mock_client.create_host_config.call_args[1]['mem_reservation'] == '512m' + def test_cgroup_parent(self): self.mock_client.create_host_config.return_value = {}