Skip to content

Commit 6a804ac

Browse files
committed
Merge pull request #483 from docker/read_only_rootfs
read_only parameter
2 parents d051202 + e379e8a commit 6a804ac

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

docker/client.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ def start(self, container, binds=None, port_bindings=None, lxc_conf=None,
936936
publish_all_ports=False, links=None, privileged=False,
937937
dns=None, dns_search=None, volumes_from=None, network_mode=None,
938938
restart_policy=None, cap_add=None, cap_drop=None, devices=None,
939-
extra_hosts=None):
939+
extra_hosts=None, read_only=None):
940940

941941
if utils.compare_version('1.10', self._version) < 0:
942942
if dns is not None:
@@ -948,13 +948,19 @@ def start(self, container, binds=None, port_bindings=None, lxc_conf=None,
948948
'volumes_from is only supported for API version >= 1.10'
949949
)
950950

951+
if utils.compare_version('1.17', self._version) < 0 and \
952+
read_only is not None:
953+
raise errors.InvalidVersion(
954+
'read_only is only supported for API version >= 1.17'
955+
)
956+
951957
start_config = utils.create_host_config(
952958
binds=binds, port_bindings=port_bindings, lxc_conf=lxc_conf,
953959
publish_all_ports=publish_all_ports, links=links, dns=dns,
954960
privileged=privileged, dns_search=dns_search, cap_add=cap_add,
955961
cap_drop=cap_drop, volumes_from=volumes_from, devices=devices,
956962
network_mode=network_mode, restart_policy=restart_policy,
957-
extra_hosts=extra_hosts
963+
extra_hosts=extra_hosts, read_only=read_only
958964
)
959965

960966
if isinstance(container, dict):

docker/utils/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def create_host_config(
301301
publish_all_ports=False, links=None, privileged=False,
302302
dns=None, dns_search=None, volumes_from=None, network_mode=None,
303303
restart_policy=None, cap_add=None, cap_drop=None, devices=None,
304-
extra_hosts=None
304+
extra_hosts=None, read_only=None
305305
):
306306
host_config = {}
307307

@@ -311,6 +311,9 @@ def create_host_config(
311311
if publish_all_ports:
312312
host_config['PublishAllPorts'] = publish_all_ports
313313

314+
if read_only is not None:
315+
host_config['ReadOnlyRootFs'] = read_only
316+
314317
if dns_search:
315318
host_config['DnsSearch'] = dns_search
316319

docs/hostconfig.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ for example:
8282
* cap_add (list of str): Add kernel capabilities
8383
* cap_drop (list of str): Drop kernel capabilities
8484
* extra_hosts (dict): custom host-to-IP mappings (host:ip)
85+
* read_only (bool): mount the container's root filesystem as read only
8586

8687
**Returns** (dict) HostConfig dictionary
8788

tests/integration_test.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,33 @@ def runTest(self):
312312
self.assertFalse(inspect_data['VolumesRW'][mount_dest])
313313

314314

315+
class TestCreateContainerReadOnlyFs(BaseTestCase):
316+
def runTest(self):
317+
ctnr = self.client.create_container(
318+
'busybox', ['mkdir', '/shrine'],
319+
host_config=create_host_config(read_only=True)
320+
)
321+
self.assertIn('Id', ctnr)
322+
self.tmp_containers.append(ctnr['Id'])
323+
self.client.start(ctnr)
324+
res = self.client.wait(ctnr)
325+
self.assertNotEqual(res, 0)
326+
327+
328+
class TestStartContainerReadOnlyFs(BaseTestCase):
329+
def runTest(self):
330+
# Presumably a bug in 1.5.0
331+
# https://github.com/docker/docker/issues/10695
332+
ctnr = self.client.create_container(
333+
'busybox', ['mkdir', '/shrine'],
334+
)
335+
self.assertIn('Id', ctnr)
336+
self.tmp_containers.append(ctnr['Id'])
337+
self.client.start(ctnr, read_only=True)
338+
# res = self.client.wait(ctnr)
339+
# self.assertNotEqual(res, 0)
340+
341+
315342
class TestCreateContainerWithName(BaseTestCase):
316343
def runTest(self):
317344
res = self.client.create_container('busybox', 'true', name='foobar')

0 commit comments

Comments
 (0)