Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docker/api/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ def create_host_config(self, *args, **kwargs):
``0,1``).
cpuset_mems (str): Memory nodes (MEMs) in which to allow execution
(``0-3``, ``0,1``). Only effective on NUMA systems.
device_cgroup_rules (:py:class:`list`): A list of cgroup rules to
apply to the container.
device_read_bps: Limit read rate (bytes per second) from a device
in the form of: `[{"Path": "device_path", "Rate": rate}]`
device_read_iops: Limit read rate (IO per second) from a device.
Expand Down
3 changes: 3 additions & 0 deletions docker/models/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ def run(self, image, command=None, stdout=True, stderr=False,
(``0-3``, ``0,1``). Only effective on NUMA systems.
detach (bool): Run container in the background and return a
:py:class:`Container` object.
device_cgroup_rules (:py:class:`list`): A list of cgroup rules to
apply to the container.
device_read_bps: Limit read rate (bytes per second) from a device
in the form of: `[{"Path": "device_path", "Rate": rate}]`
device_read_iops: Limit read rate (IO per second) from a device.
Expand Down Expand Up @@ -912,6 +914,7 @@ def prune(self, filters=None):
'cpuset_mems',
'cpu_rt_period',
'cpu_rt_runtime',
'device_cgroup_rules',
'device_read_bps',
'device_read_iops',
'device_write_bps',
Expand Down
12 changes: 11 additions & 1 deletion docker/types/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ def __init__(self, version, binds=None, port_bindings=None,
init=None, init_path=None, volume_driver=None,
cpu_count=None, cpu_percent=None, nano_cpus=None,
cpuset_mems=None, runtime=None, mounts=None,
cpu_rt_period=None, cpu_rt_runtime=None):
cpu_rt_period=None, cpu_rt_runtime=None,
device_cgroup_rules=None):

if mem_limit is not None:
self['Memory'] = parse_bytes(mem_limit)
Expand Down Expand Up @@ -466,6 +467,15 @@ def __init__(self, version, binds=None, port_bindings=None,
raise host_config_version_error('mounts', '1.30')
self['Mounts'] = mounts

if device_cgroup_rules is not None:
if version_lt(version, '1.28'):
raise host_config_version_error('device_cgroup_rules', '1.28')
if not isinstance(device_cgroup_rules, list):
raise host_config_type_error(
'device_cgroup_rules', device_cgroup_rules, 'list'
)
self['DeviceCgroupRules'] = device_cgroup_rules


def host_config_type_error(param, param_value, expected):
error_msg = 'Invalid type for {0} param: expected {1} but found {2}'
Expand Down
15 changes: 15 additions & 0 deletions tests/integration/api_container_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,21 @@ def test_create_with_cpu_rt_options(self):
assert config['HostConfig']['CpuRealtimeRuntime'] == 500
assert config['HostConfig']['CpuRealtimePeriod'] == 1000

@requires_api_version('1.28')
def test_create_with_device_cgroup_rules(self):
rule = 'c 7:128 rwm'
ctnr = self.client.create_container(
BUSYBOX, 'cat /sys/fs/cgroup/devices/devices.list',
host_config=self.client.create_host_config(
device_cgroup_rules=[rule]
)
)
self.tmp_containers.append(ctnr)
config = self.client.inspect_container(ctnr)
assert config['HostConfig']['DeviceCgroupRules'] == [rule]
self.client.start(ctnr)
assert rule in self.client.logs(ctnr).decode('utf-8')


class VolumeBindTest(BaseAPIIntegrationTest):
def setUp(self):
Expand Down