Skip to content

Commit

Permalink
Merge pull request #143 from msisj/minor/allow-passing-multiple-optio…
Browse files Browse the repository at this point in the history
…ns-to-volume-bind

Allow passing all available options to volume mount
  • Loading branch information
rhatdan committed Jun 28, 2022
2 parents 6d09aed + 18c7269 commit 21a48cb
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 9 deletions.
34 changes: 25 additions & 9 deletions podman/domain/containers_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,17 +215,26 @@ def create(
version (str): The version of the API to use. Set to auto to automatically detect
the server's version. Default: 3.0.0
volume_driver (str): The name of a volume driver/plugin.
volumes (Dict[str, Dict[str, str]]): A dictionary to configure volumes mounted inside
the container. The key is either the host path or a volume name, and the value is
volumes (Dict[str, Dict[str, Union[str, list]]]): A dictionary to configure
volumes mounted inside the container.
The key is either the host path or a volume name, and the value is
a dictionary with the keys:
- bind: The path to mount the volume inside the container
- mode: Either rw to mount the volume read/write, or ro to mount it read-only.
Kept for docker-py compatibility
- extended_mode: List of options passed to volume mount.
For example:
{'/home/user1/': {'bind': '/mnt/vol2', 'mode': 'rw'},
'/var/www': {'bind': '/mnt/vol1', 'mode': 'ro'}}
{
'test_bind_1':
{'bind': '/mnt/vol1', 'mode': 'rw'},
'test_bind_2':
{'bind': '/mnt/vol2', 'extended_mode': ['ro', 'noexec']},
'test_bind_3':
{'bind': '/mnt/vol3', 'extended_mode': ['noexec'], 'mode': 'rw'}
}
volumes_from (List[str]): List of container names or IDs to get volumes from.
working_dir (str): Path to the working directory.
Expand Down Expand Up @@ -548,11 +557,18 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]:

for item in args.pop("volumes", {}).items():
key, value = item
volume = {
"Name": key,
"Dest": value["bind"],
"Options": [value["mode"]] if "mode" in value else [],
}
extended_mode = value.get('extended_mode', [])
if not isinstance(extended_mode, list):
raise ValueError("'extended_mode' value should be a list")

options = extended_mode
mode = value.get('mode')
if mode is not None:
if not isinstance(mode, str):
raise ValueError("'mode' value should be a str")
options.append(mode)

volume = {"Name": key, "Dest": value["bind"], "Options": options}
params["volumes"].append(volume)

if "cgroupns" in args:
Expand Down
28 changes: 28 additions & 0 deletions podman/tests/integration/test_container_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,34 @@ def tearUp(self):
for container in self.containers:
container.remove(force=True)

def test_container_volume_mount(self):
with self.subTest("Check volume mount"):
volumes = {
'test_bind_1': {'bind': '/mnt/vol1', 'mode': 'rw'},
'test_bind_2': {'bind': '/mnt/vol2', 'extended_mode': ['ro', 'noexec']},
'test_bind_3': {'bind': '/mnt/vol3', 'extended_mode': ['noexec'], 'mode': 'rw'},
}
container = self.client.containers.create(self.alpine_image, volumes=volumes)
container_mounts = container.attrs.get('Mounts', {})
self.assertEqual(len(container_mounts), len(volumes))

for mount in container_mounts:
name = mount.get('Name')
self.assertIn(name, volumes)
test_mount = volumes.get(name)
test_mode = test_mount.get('mode', '')
test_extended_mode = test_mount.get('extended_mode', [])
# check RO/RW
if 'ro' in test_mode or 'ro' in test_extended_mode:
self.assertEqual(mount.get('RW'), False)

if 'rw' in test_mode or 'rw' in test_extended_mode:
self.assertEqual(mount.get('RW'), True)

other_options = [o for o in test_extended_mode if o not in ['ro', 'rw']]
for o in other_options:
self.assertIn(o, mount.get('Options'))

def test_container_extra_hosts(self):
"""Test Container Extra hosts"""
extra_hosts = {"host1 host3": "127.0.0.2", "host2": "127.0.0.3"}
Expand Down

0 comments on commit 21a48cb

Please sign in to comment.