Add cpu_count, cpu_percent, cpus parameters to container HostConfig.

Signed-off-by: Alexey Rokhin <arokhin@mail.ru>
This commit is contained in:
Alexey Rokhin 2017-04-19 15:06:48 +03:00
parent f127a9ffdc
commit 3f7d622143
4 changed files with 95 additions and 1 deletions

View File

@ -456,10 +456,13 @@ class ContainerCollection(Collection):
cap_add (list of str): Add kernel capabilities. For example,
``["SYS_ADMIN", "MKNOD"]``.
cap_drop (list of str): Drop kernel capabilities.
cpu_count (int): CPU count (Windows only).
cpu_percent (int): CPU percent (Windows only).
cpu_period (int): The length of a CPU period in microseconds.
cpu_quota (int): Microseconds of CPU time that the container can
get in a CPU period.
cpu_shares (int): CPU shares (relative weight).
cpus (float): Number of CPUs.
cpuset_cpus (str): CPUs in which to allow execution (``0-3``,
``0,1``).
detach (bool): Run container in the background and return a
@ -801,9 +804,12 @@ RUN_HOST_CONFIG_KWARGS = [
'cap_add',
'cap_drop',
'cgroup_parent',
'cpu_count',
'cpu_percent',
'cpu_period',
'cpu_quota',
'cpu_shares',
'cpus',
'cpuset_cpus',
'device_read_bps',
'device_read_iops',

View File

@ -118,7 +118,8 @@ class HostConfig(dict):
tmpfs=None, oom_score_adj=None, dns_opt=None, cpu_shares=None,
cpuset_cpus=None, userns_mode=None, pids_limit=None,
isolation=None, auto_remove=False, storage_opt=None,
init=None, init_path=None, volume_driver=None):
init=None, init_path=None, volume_driver=None,
cpu_count=None, cpu_percent=None, cpus=None):
if mem_limit is not None:
self['Memory'] = parse_bytes(mem_limit)
@ -433,6 +434,30 @@ class HostConfig(dict):
raise host_config_version_error('volume_driver', '1.21')
self['VolumeDriver'] = volume_driver
if cpu_count:
if not isinstance(cpu_count, int):
raise host_config_type_error('cpu_count', cpu_count, 'int')
if version_lt(version, '1.25'):
raise host_config_version_error('cpu_count', '1.25')
self['CpuCount'] = cpu_count
if cpu_percent:
if not isinstance(cpu_percent, int):
raise host_config_type_error('cpu_percent', cpu_percent, 'int')
if version_lt(version, '1.25'):
raise host_config_version_error('cpu_percent', '1.25')
self['CpuPercent'] = cpu_percent
if cpus:
if not isinstance(cpus, (float, int)):
raise host_config_type_error('cpus', cpus, 'float')
if version_lt(version, '1.25'):
raise host_config_version_error('cpus', '1.25')
self['NanoCpus'] = int(1000000000 * cpus)
def host_config_type_error(param, param_value, expected):
error_msg = 'Invalid type for {0} param: expected {1} but found {2}'

View File

@ -1152,6 +1152,36 @@ class CreateContainerTest(BaseAPIClientTest):
self.assertEqual(args[0][1], url_prefix + 'containers/create')
self.assertEqual(json.loads(args[1]['data'])['Env'], expected)
@requires_api_version('1.25')
def test_create_container_with_host_config_cpus(self):
self.client.create_container(
'busybox', 'ls', host_config=self.client.create_host_config(
cpu_count=1,
cpu_percent=20,
cpus=10
)
)
args = fake_request.call_args
self.assertEqual(args[0][1],
url_prefix + 'containers/create')
self.assertEqual(json.loads(args[1]['data']),
json.loads('''
{"Tty": false, "Image": "busybox",
"Cmd": ["ls"], "AttachStdin": false,
"AttachStderr": true,
"AttachStdout": true, "OpenStdin": false,
"StdinOnce": false,
"NetworkDisabled": false,
"HostConfig": {
"CpuCount": 1,
"CpuPercent": 20,
"NanoCpus": 10000000000,
"NetworkMode": "default"
}}'''))
self.assertEqual(args[1]['headers'], {'Content-Type': 'application/json'})
class ContainerTest(BaseAPIClientTest):
def test_list_containers(self):

View File

@ -172,6 +172,39 @@ class HostConfigTest(unittest.TestCase):
config = create_host_config(version='1.21', volume_driver='local')
assert config.get('VolumeDriver') == 'local'
def test_create_host_config_invalid_cpu_count_types(self):
with pytest.raises(TypeError):
create_host_config(version='1.25', cpu_count='1')
def test_create_host_config_with_cpu_count(self):
config = create_host_config(version='1.25', cpu_count=2)
self.assertEqual(config.get('CpuCount'), 2)
self.assertRaises(
InvalidVersion, lambda: create_host_config(
version='1.24', cpu_count=1))
def test_create_host_config_invalid_cpu_percent_types(self):
with pytest.raises(TypeError):
create_host_config(version='1.25', cpu_percent='1')
def test_create_host_config_with_cpu_percent(self):
config = create_host_config(version='1.25', cpu_percent=15)
self.assertEqual(config.get('CpuPercent'), 15)
self.assertRaises(
InvalidVersion, lambda: create_host_config(
version='1.24', cpu_percent=10))
def test_create_host_config_invalid_cpus_types(self):
with pytest.raises(TypeError):
create_host_config(version='1.25', cpus='0')
def test_create_host_config_with_cpus(self):
config = create_host_config(version='1.25', cpus=100)
self.assertEqual(config.get('NanoCpus'), 100000000000)
self.assertRaises(
InvalidVersion, lambda: create_host_config(
version='1.24', cpus=1))
class ContainerConfigTest(unittest.TestCase):