mirror of https://github.com/docker/docker-py.git
Merge pull request #889 from docker/725-devices-format
Improve host devices support
This commit is contained in:
commit
57b79cb1e7
|
@ -4,7 +4,7 @@ from .utils import (
|
|||
kwargs_from_env, convert_filters, datetime_to_timestamp, create_host_config,
|
||||
create_container_config, parse_bytes, ping_registry, parse_env_file,
|
||||
version_lt, version_gte, decode_json_header, split_command,
|
||||
create_ipam_config, create_ipam_pool,
|
||||
create_ipam_config, create_ipam_pool, parse_devices
|
||||
) # flake8: noqa
|
||||
|
||||
from .types import Ulimit, LogConfig # flake8: noqa
|
||||
|
|
|
@ -400,7 +400,7 @@ def parse_host(addr, platform=None):
|
|||
port = int(port)
|
||||
except Exception:
|
||||
raise errors.DockerException(
|
||||
"Invalid port: %s", addr
|
||||
"Invalid port: {0}".format(addr)
|
||||
)
|
||||
|
||||
elif proto in ("http", "https") and ':' not in addr:
|
||||
|
@ -417,7 +417,14 @@ def parse_host(addr, platform=None):
|
|||
def parse_devices(devices):
|
||||
device_list = []
|
||||
for device in devices:
|
||||
device_mapping = device.split(":")
|
||||
if isinstance(device, dict):
|
||||
device_list.append(device)
|
||||
continue
|
||||
if not isinstance(device, six.string_types):
|
||||
raise errors.DockerException(
|
||||
'Invalid device type {0}'.format(type(device))
|
||||
)
|
||||
device_mapping = device.split(':')
|
||||
if device_mapping:
|
||||
path_on_host = device_mapping[0]
|
||||
if len(device_mapping) > 1:
|
||||
|
@ -428,9 +435,11 @@ def parse_devices(devices):
|
|||
permissions = device_mapping[2]
|
||||
else:
|
||||
permissions = 'rwm'
|
||||
device_list.append({"PathOnHost": path_on_host,
|
||||
"PathInContainer": path_in_container,
|
||||
"CgroupPermissions": permissions})
|
||||
device_list.append({
|
||||
'PathOnHost': path_on_host,
|
||||
'PathInContainer': path_in_container,
|
||||
'CgroupPermissions': permissions
|
||||
})
|
||||
return device_list
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,18 @@ cli.create_container(
|
|||
)
|
||||
```
|
||||
|
||||
Each string is a single mapping using the colon (':') as the separator. So the
|
||||
above example essentially allow the container to have read write permissions to
|
||||
access the host's /dev/sda via a node named /dev/xvda in the container. The
|
||||
devices parameter is a list to allow multiple devices to be mapped.
|
||||
Each string is a single mapping using the following format:
|
||||
`<path_on_host>:<path_in_container>:<cgroup_permissions>`
|
||||
The above example allows the container to have read-write access to
|
||||
the host's `/dev/sda` via a node named `/dev/xvda` inside the container.
|
||||
|
||||
As a more verbose alternative, each host device definition can be specified as
|
||||
a dictionary with the following keys:
|
||||
|
||||
```python
|
||||
{
|
||||
'PathOnHost': '/dev/sda1',
|
||||
'PathInContainer': '/dev/xvda',
|
||||
'CgroupPermissions': 'rwm'
|
||||
}
|
||||
```
|
||||
|
|
|
@ -104,17 +104,12 @@ for example:
|
|||
* mem_swappiness (int): Tune a container's memory swappiness behavior.
|
||||
Accepts number between 0 and 100.
|
||||
* cpu_group (int): The length of a CPU period in microseconds.
|
||||
* cpu_period (int): Microseconds of CPU time that the container can get in a CPU period.
|
||||
* cpu_period (int): Microseconds of CPU time that the container can get in a
|
||||
CPU period.
|
||||
* group_add (list): List of additional group names and/or IDs that the
|
||||
container process will run as.
|
||||
* devices (list): A list of devices to add to the container specified as dicts
|
||||
in the form:
|
||||
```
|
||||
{ "PathOnHost": "/dev/deviceName",
|
||||
"PathInContainer": "/dev/deviceName",
|
||||
"CgroupPermissions": "mrw"
|
||||
}
|
||||
```
|
||||
* devices (list): Host device bindings. See [host devices](host-devices.md)
|
||||
for more information.
|
||||
|
||||
**Returns** (dict) HostConfig dictionary
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ from docker.utils import (
|
|||
parse_repository_tag, parse_host, convert_filters, kwargs_from_env,
|
||||
create_host_config, Ulimit, LogConfig, parse_bytes, parse_env_file,
|
||||
exclude_paths, convert_volume_binds, decode_json_header, tar,
|
||||
split_command, create_ipam_config, create_ipam_pool,
|
||||
split_command, create_ipam_config, create_ipam_pool, parse_devices,
|
||||
)
|
||||
from docker.utils.utils import create_endpoint_config
|
||||
from docker.utils.ports import build_port_bindings, split_port
|
||||
|
@ -406,6 +406,65 @@ class ParseRepositoryTagTest(base.BaseTestCase):
|
|||
)
|
||||
|
||||
|
||||
class ParseDeviceTest(base.BaseTestCase):
|
||||
def test_dict(self):
|
||||
devices = parse_devices([{
|
||||
'PathOnHost': '/dev/sda1',
|
||||
'PathInContainer': '/dev/mnt1',
|
||||
'CgroupPermissions': 'r'
|
||||
}])
|
||||
self.assertEqual(devices[0], {
|
||||
'PathOnHost': '/dev/sda1',
|
||||
'PathInContainer': '/dev/mnt1',
|
||||
'CgroupPermissions': 'r'
|
||||
})
|
||||
|
||||
def test_partial_string_definition(self):
|
||||
devices = parse_devices(['/dev/sda1'])
|
||||
self.assertEqual(devices[0], {
|
||||
'PathOnHost': '/dev/sda1',
|
||||
'PathInContainer': '/dev/sda1',
|
||||
'CgroupPermissions': 'rwm'
|
||||
})
|
||||
|
||||
def test_permissionless_string_definition(self):
|
||||
devices = parse_devices(['/dev/sda1:/dev/mnt1'])
|
||||
self.assertEqual(devices[0], {
|
||||
'PathOnHost': '/dev/sda1',
|
||||
'PathInContainer': '/dev/mnt1',
|
||||
'CgroupPermissions': 'rwm'
|
||||
})
|
||||
|
||||
def test_full_string_definition(self):
|
||||
devices = parse_devices(['/dev/sda1:/dev/mnt1:r'])
|
||||
self.assertEqual(devices[0], {
|
||||
'PathOnHost': '/dev/sda1',
|
||||
'PathInContainer': '/dev/mnt1',
|
||||
'CgroupPermissions': 'r'
|
||||
})
|
||||
|
||||
def test_hybrid_list(self):
|
||||
devices = parse_devices([
|
||||
'/dev/sda1:/dev/mnt1:rw',
|
||||
{
|
||||
'PathOnHost': '/dev/sda2',
|
||||
'PathInContainer': '/dev/mnt2',
|
||||
'CgroupPermissions': 'r'
|
||||
}
|
||||
])
|
||||
|
||||
self.assertEqual(devices[0], {
|
||||
'PathOnHost': '/dev/sda1',
|
||||
'PathInContainer': '/dev/mnt1',
|
||||
'CgroupPermissions': 'rw'
|
||||
})
|
||||
self.assertEqual(devices[1], {
|
||||
'PathOnHost': '/dev/sda2',
|
||||
'PathInContainer': '/dev/mnt2',
|
||||
'CgroupPermissions': 'r'
|
||||
})
|
||||
|
||||
|
||||
class UtilsTest(base.BaseTestCase):
|
||||
longMessage = True
|
||||
|
||||
|
|
Loading…
Reference in New Issue