Ver código fonte

Add cpu_count, cpu_percent, cpus parameters.

Signed-off-by: Alexey Rokhin <[email protected]>
Alexey Rokhin 8 anos atrás
pai
commit
93d1ce5a55

+ 3 - 0
compose/config/config.py

@@ -52,8 +52,11 @@ DOCKER_CONFIG_KEYS = [
     'cap_drop',
     'cgroup_parent',
     'command',
+    'cpu_count',
+    'cpu_percent',
     'cpu_quota',
     'cpu_shares',
+    'cpus',
     'cpuset',
     'detach',
     'devices',

+ 3 - 0
compose/config/config_schema_v2.2.json

@@ -74,8 +74,11 @@
           ]
         },
         "container_name": {"type": "string"},
+        "cpu_count": {"type": "integer", "minimum": 0},
+        "cpu_percent": {"type": "integer", "minimum": 0, "maximum": 100},
         "cpu_shares": {"type": ["number", "string"]},
         "cpu_quota": {"type": ["number", "string"]},
+        "cpus": {"type": ["number", "string"], "minimum": 0},
         "cpuset": {"type": "string"},
         "depends_on": {
           "oneOf": [

+ 10 - 0
compose/service.py

@@ -52,7 +52,10 @@ HOST_CONFIG_KEYS = [
     'cap_add',
     'cap_drop',
     'cgroup_parent',
+    'cpu_count',
+    'cpu_percent',
     'cpu_quota',
+    'cpus',
     'devices',
     'dns',
     'dns_search',
@@ -798,6 +801,10 @@ class Service(object):
             init_path = options.get('init')
             options['init'] = True
 
+        nano_cpus = None
+        if options.has_key('cpus'):
+            nano_cpus = int(options.get('cpus') * 1000000000)
+
         return self.client.create_host_config(
             links=self._get_links(link_to_self=one_off),
             port_bindings=build_port_bindings(
@@ -837,6 +844,9 @@ class Service(object):
             init=options.get('init', None),
             init_path=init_path,
             isolation=options.get('isolation'),
+            cpu_count=options.get('cpu_count'),
+            cpu_percent=options.get('cpu_percent'),
+            nano_cpus=nano_cpus,
         )
 
     def get_secret_volumes(self):

+ 1 - 1
setup.py

@@ -37,7 +37,7 @@ install_requires = [
     'requests >= 2.6.1, != 2.11.0, < 2.12',
     'texttable >= 0.8.1, < 0.9',
     'websocket-client >= 0.32.0, < 1.0',
-    'docker >= 2.2.1, < 3.0',
+    'docker >= 2.3.0, < 3.0',
     'dockerpty >= 0.4.1, < 0.5',
     'six >= 1.3.0, < 2',
     'jsonschema >= 2.5.1, < 3',

+ 25 - 0
tests/integration/service_test.py

@@ -33,6 +33,7 @@ from compose.service import ConvergenceStrategy
 from compose.service import NetworkMode
 from compose.service import Service
 from tests.integration.testcases import v2_1_only
+from tests.integration.testcases import v2_2_only
 from tests.integration.testcases import v2_only
 from tests.integration.testcases import v3_only
 
@@ -110,6 +111,30 @@ class ServiceTest(DockerClientTestCase):
         container.start()
         self.assertEqual(container.get('HostConfig.CpuQuota'), 40000)
 
+    @v2_2_only()
+    def test_create_container_with_cpu_count(self):
+        self.require_api_version('1.25')
+        service = self.create_service('db', cpu_count=2)
+        container = service.create_container()
+        service.start_container(container)
+        self.assertEqual(container.get('HostConfig.CpuCount'), 2)
+
+    @v2_2_only()
+    def test_create_container_with_cpu_percent(self):
+        self.require_api_version('1.25')
+        service = self.create_service('db', cpu_percent=12)
+        container = service.create_container()
+        service.start_container(container)
+        self.assertEqual(container.get('HostConfig.CpuPercent'), 12)
+
+    @v2_2_only()
+    def test_create_container_with_cpus(self):
+        self.require_api_version('1.25')
+        service = self.create_service('db', cpus=1)
+        container = service.create_container()
+        service.start_container(container)
+        self.assertEqual(container.get('HostConfig.NanoCpus'), 1000000000)
+
     def test_create_container_with_shm_size(self):
         self.require_api_version('1.22')
         service = self.create_service('db', shm_size=67108864)

+ 4 - 1
tests/integration/testcases.py

@@ -15,6 +15,7 @@ from compose.const import API_VERSIONS
 from compose.const import COMPOSEFILE_V1 as V1
 from compose.const import COMPOSEFILE_V2_0 as V2_0
 from compose.const import COMPOSEFILE_V2_0 as V2_1
+from compose.const import COMPOSEFILE_V2_2 as V2_2
 from compose.const import COMPOSEFILE_V3_2 as V3_2
 from compose.const import LABEL_PROJECT
 from compose.progress_stream import stream_output
@@ -69,9 +70,11 @@ def v2_only():
 def v2_1_only():
     return build_version_required_decorator((V1, V2_0))
 
+def v2_2_only():
+    return build_version_required_decorator((V1, V2_0, V2_1))
 
 def v3_only():
-    return build_version_required_decorator((V1, V2_0, V2_1))
+    return build_version_required_decorator((V1, V2_0, V2_1, V2_2))
 
 
 class DockerClientTestCase(unittest.TestCase):

+ 4 - 0
tests/unit/config/config_test.py

@@ -27,6 +27,7 @@ from compose.config.types import VolumeSpec
 from compose.const import COMPOSEFILE_V1 as V1
 from compose.const import COMPOSEFILE_V2_0 as V2_0
 from compose.const import COMPOSEFILE_V2_1 as V2_1
+from compose.const import COMPOSEFILE_V2_2 as V2_2
 from compose.const import COMPOSEFILE_V3_0 as V3_0
 from compose.const import COMPOSEFILE_V3_1 as V3_1
 from compose.const import COMPOSEFILE_V3_2 as V3_2
@@ -174,6 +175,9 @@ class ConfigTest(unittest.TestCase):
         cfg = config.load(build_config_details({'version': '2.1'}))
         assert cfg.version == V2_1
 
+        cfg = config.load(build_config_details({'version': '2.2'}))
+        assert cfg.version == V2_2
+
         for version in ['3', '3.0']:
             cfg = config.load(build_config_details({'version': version}))
             assert cfg.version == V3_0