diff --git a/compose/config/config.py b/compose/config/config.py index 0b5c7df0a..3b8490a0b 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -67,6 +67,7 @@ DOCKER_CONFIG_KEYS = [ 'command', 'cpu_count', 'cpu_percent', + 'cpu_period', 'cpu_quota', 'cpu_shares', 'cpus', diff --git a/compose/config/config_schema_v2.1.json b/compose/config/config_schema_v2.1.json index 984c46c53..87a730dd8 100644 --- a/compose/config/config_schema_v2.1.json +++ b/compose/config/config_schema_v2.1.json @@ -106,6 +106,7 @@ "container_name": {"type": "string"}, "cpu_shares": {"type": ["number", "string"]}, "cpu_quota": {"type": ["number", "string"]}, + "cpu_period": {"type": ["number", "string"]}, "cpuset": {"type": "string"}, "depends_on": { "oneOf": [ diff --git a/compose/config/config_schema_v2.2.json b/compose/config/config_schema_v2.2.json index 8e3927e1d..e15223fc3 100644 --- a/compose/config/config_schema_v2.2.json +++ b/compose/config/config_schema_v2.2.json @@ -110,6 +110,7 @@ "cpu_percent": {"type": "integer", "minimum": 0, "maximum": 100}, "cpu_shares": {"type": ["number", "string"]}, "cpu_quota": {"type": ["number", "string"]}, + "cpu_period": {"type": ["number", "string"]}, "cpus": {"type": "number", "minimum": 0}, "cpuset": {"type": "string"}, "depends_on": { diff --git a/compose/config/config_schema_v2.3.json b/compose/config/config_schema_v2.3.json index 33840dba5..c2e860be2 100644 --- a/compose/config/config_schema_v2.3.json +++ b/compose/config/config_schema_v2.3.json @@ -113,6 +113,7 @@ "cpu_percent": {"type": "integer", "minimum": 0, "maximum": 100}, "cpu_shares": {"type": ["number", "string"]}, "cpu_quota": {"type": ["number", "string"]}, + "cpu_period": {"type": ["number", "string"]}, "cpus": {"type": "number", "minimum": 0}, "cpuset": {"type": "string"}, "depends_on": { diff --git a/compose/config/interpolation.py b/compose/config/interpolation.py index b1143d66c..7e50f9892 100644 --- a/compose/config/interpolation.py +++ b/compose/config/interpolation.py @@ -10,6 +10,7 @@ import six from .errors import ConfigurationError from compose.const import COMPOSEFILE_V2_0 as V2_0 from compose.utils import parse_bytes +from compose.utils import parse_nanoseconds_int log = logging.getLogger(__name__) @@ -223,6 +224,12 @@ def bytes_to_int(s): return v +def to_microseconds(v): + if not isinstance(v, six.string_types): + return v + return int(parse_nanoseconds_int(v) / 1000) + + class ConversionMap(object): map = { service_path('blkio_config', 'weight'): to_int, @@ -230,6 +237,8 @@ class ConversionMap(object): service_path('build', 'labels', FULL_JOKER): to_str, service_path('cpus'): to_float, service_path('cpu_count'): to_int, + service_path('cpu_quota'): to_microseconds, + service_path('cpu_period'): to_microseconds, service_path('configs', 'mode'): to_int, service_path('secrets', 'mode'): to_int, service_path('healthcheck', 'retries'): to_int, diff --git a/compose/service.py b/compose/service.py index b9f9af2cd..501664c7c 100644 --- a/compose/service.py +++ b/compose/service.py @@ -62,6 +62,7 @@ HOST_CONFIG_KEYS = [ 'cgroup_parent', 'cpu_count', 'cpu_percent', + 'cpu_period', 'cpu_quota', 'cpu_shares', 'cpus', @@ -948,6 +949,7 @@ class Service(object): device_write_iops=blkio_config.get('device_write_iops'), mounts=options.get('mounts'), device_cgroup_rules=options.get('device_cgroup_rules'), + cpu_period=options.get('cpu_period'), ) def get_secret_volumes(self): diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py index 2b6b7711e..6752364b2 100644 --- a/tests/integration/service_test.py +++ b/tests/integration/service_test.py @@ -121,10 +121,11 @@ class ServiceTest(DockerClientTestCase): assert container.get('HostConfig.CpuShares') == 73 def test_create_container_with_cpu_quota(self): - service = self.create_service('db', cpu_quota=40000) + service = self.create_service('db', cpu_quota=40000, cpu_period=150000) container = service.create_container() container.start() assert container.get('HostConfig.CpuQuota') == 40000 + assert container.get('HostConfig.CpuPeriod') == 150000 @v2_2_only() def test_create_container_with_cpu_count(self):