Skip to content

Commit 7dd7625

Browse files
committed
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 <[email protected]>
1 parent be73aaf commit 7dd7625

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

docker/utils/utils.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,21 @@ def convert_volume_binds(binds):
177177
result = []
178178
for k, v in binds.items():
179179
if isinstance(v, dict):
180+
if 'ro' in v and 'mode' in v:
181+
raise ValueError(
182+
'Binding cannot contain both "ro" and "mode": {}'
183+
.format(repr(v))
184+
)
185+
186+
if 'ro' in v:
187+
mode = 'ro' if v['ro'] else 'rw'
188+
elif 'mode' in v:
189+
mode = v['mode']
190+
else:
191+
mode = 'rw'
192+
180193
result.append('{0}:{1}:{2}'.format(
181-
k, v['bind'], 'ro' if v.get('ro', False) else 'rw'
194+
k, v['bind'], mode
182195
))
183196
else:
184197
result.append('{0}:{1}:rw'.format(k, v))

docs/volumes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ container_id = c.create_container(
1010
host_config=docker.utils.create_host_config(binds={
1111
'/home/user1/': {
1212
'bind': '/mnt/vol2',
13-
'ro': False
13+
'mode': 'rw',
1414
},
1515
'/var/www': {
1616
'bind': '/mnt/vol1',
17-
'ro': True
17+
'mode': 'ro',
1818
}
1919
})
2020
)

tests/test.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,53 @@ def test_create_container_with_binds_rw(self):
808808
DEFAULT_TIMEOUT_SECONDS
809809
)
810810

811+
def test_create_container_with_binds_mode(self):
812+
try:
813+
mount_dest = '/mnt'
814+
mount_origin = '/tmp'
815+
self.client.create_container(
816+
'busybox', 'true', host_config=create_host_config(
817+
binds={mount_origin: {
818+
"bind": mount_dest,
819+
"mode": "z",
820+
}}
821+
)
822+
)
823+
except Exception as e:
824+
self.fail('Command should not raise exception: {0}'.format(e))
825+
826+
args = fake_request.call_args
827+
self.assertEqual(args[0][0], url_prefix +
828+
'containers/create')
829+
expected_payload = self.base_create_payload()
830+
expected_payload['HostConfig'] = create_host_config()
831+
expected_payload['HostConfig']['Binds'] = ["/tmp:/mnt:z"]
832+
self.assertEqual(json.loads(args[1]['data']), expected_payload)
833+
self.assertEqual(args[1]['headers'],
834+
{'Content-Type': 'application/json'})
835+
self.assertEqual(
836+
args[1]['timeout'],
837+
DEFAULT_TIMEOUT_SECONDS
838+
)
839+
840+
def test_create_container_with_binds_mode_and_ro_error(self):
841+
try:
842+
mount_dest = '/mnt'
843+
mount_origin = '/tmp'
844+
self.client.create_container(
845+
'busybox', 'true', host_config=create_host_config(
846+
binds={mount_origin: {
847+
"bind": mount_dest,
848+
"mode": "z",
849+
"ro": True,
850+
}}
851+
)
852+
)
853+
except ValueError:
854+
return
855+
856+
self.fail('Command should raise ValueError')
857+
811858
def test_create_container_with_port_binds(self):
812859
self.maxDiff = None
813860
try:

0 commit comments

Comments
 (0)