mirror of https://github.com/docker/docker-py.git
Allow any mode string to be passed into a volume bind
Volume binds now take a "mode" key, whose value can be any string. "ro" is still supported. It is an error to specify both "ro" and "mode". Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
parent
be73aaf540
commit
7dd7625391
|
@ -177,8 +177,21 @@ def convert_volume_binds(binds):
|
||||||
result = []
|
result = []
|
||||||
for k, v in binds.items():
|
for k, v in binds.items():
|
||||||
if isinstance(v, dict):
|
if isinstance(v, dict):
|
||||||
|
if 'ro' in v and 'mode' in v:
|
||||||
|
raise ValueError(
|
||||||
|
'Binding cannot contain both "ro" and "mode": {}'
|
||||||
|
.format(repr(v))
|
||||||
|
)
|
||||||
|
|
||||||
|
if 'ro' in v:
|
||||||
|
mode = 'ro' if v['ro'] else 'rw'
|
||||||
|
elif 'mode' in v:
|
||||||
|
mode = v['mode']
|
||||||
|
else:
|
||||||
|
mode = 'rw'
|
||||||
|
|
||||||
result.append('{0}:{1}:{2}'.format(
|
result.append('{0}:{1}:{2}'.format(
|
||||||
k, v['bind'], 'ro' if v.get('ro', False) else 'rw'
|
k, v['bind'], mode
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
result.append('{0}:{1}:rw'.format(k, v))
|
result.append('{0}:{1}:rw'.format(k, v))
|
||||||
|
|
|
@ -10,11 +10,11 @@ container_id = c.create_container(
|
||||||
host_config=docker.utils.create_host_config(binds={
|
host_config=docker.utils.create_host_config(binds={
|
||||||
'/home/user1/': {
|
'/home/user1/': {
|
||||||
'bind': '/mnt/vol2',
|
'bind': '/mnt/vol2',
|
||||||
'ro': False
|
'mode': 'rw',
|
||||||
},
|
},
|
||||||
'/var/www': {
|
'/var/www': {
|
||||||
'bind': '/mnt/vol1',
|
'bind': '/mnt/vol1',
|
||||||
'ro': True
|
'mode': 'ro',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
|
@ -808,6 +808,53 @@ class DockerClientTest(Cleanup, base.BaseTestCase):
|
||||||
DEFAULT_TIMEOUT_SECONDS
|
DEFAULT_TIMEOUT_SECONDS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_create_container_with_binds_mode(self):
|
||||||
|
try:
|
||||||
|
mount_dest = '/mnt'
|
||||||
|
mount_origin = '/tmp'
|
||||||
|
self.client.create_container(
|
||||||
|
'busybox', 'true', host_config=create_host_config(
|
||||||
|
binds={mount_origin: {
|
||||||
|
"bind": mount_dest,
|
||||||
|
"mode": "z",
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.fail('Command should not raise exception: {0}'.format(e))
|
||||||
|
|
||||||
|
args = fake_request.call_args
|
||||||
|
self.assertEqual(args[0][0], url_prefix +
|
||||||
|
'containers/create')
|
||||||
|
expected_payload = self.base_create_payload()
|
||||||
|
expected_payload['HostConfig'] = create_host_config()
|
||||||
|
expected_payload['HostConfig']['Binds'] = ["/tmp:/mnt:z"]
|
||||||
|
self.assertEqual(json.loads(args[1]['data']), expected_payload)
|
||||||
|
self.assertEqual(args[1]['headers'],
|
||||||
|
{'Content-Type': 'application/json'})
|
||||||
|
self.assertEqual(
|
||||||
|
args[1]['timeout'],
|
||||||
|
DEFAULT_TIMEOUT_SECONDS
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_create_container_with_binds_mode_and_ro_error(self):
|
||||||
|
try:
|
||||||
|
mount_dest = '/mnt'
|
||||||
|
mount_origin = '/tmp'
|
||||||
|
self.client.create_container(
|
||||||
|
'busybox', 'true', host_config=create_host_config(
|
||||||
|
binds={mount_origin: {
|
||||||
|
"bind": mount_dest,
|
||||||
|
"mode": "z",
|
||||||
|
"ro": True,
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.fail('Command should raise ValueError')
|
||||||
|
|
||||||
def test_create_container_with_port_binds(self):
|
def test_create_container_with_port_binds(self):
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue