1
0
Fork 0
mirror of https://github.com/containers/ansible-podman-collections.git synced 2026-02-04 07:11:49 +00:00

Add mount and unmount for volumes (#764)

Fix #603
Signed-off-by: Sagi Shnaidman <sshnaidm@redhat.com>
Signed-off-by: Derek <derek@frisbeeworld.com>
This commit is contained in:
Sergey 2024-05-29 18:28:44 +03:00 committed by Derek
parent 989dfaec67
commit e182fd3e9d
2 changed files with 123 additions and 4 deletions

View file

@ -24,6 +24,8 @@ options:
choices:
- present
- absent
- mounted
- unmounted
- quadlet
recreate:
description:
@ -131,6 +133,7 @@ EXAMPLES = '''
'''
# noqa: F402
import json # noqa: F402
import os # noqa: F402
from ansible.module_utils.basic import AnsibleModule # noqa: F402
from ansible.module_utils._text import to_bytes, to_native # noqa: F402
@ -160,7 +163,7 @@ class PodmanVolumeModuleParams:
Returns:
list -- list of byte strings for Popen command
"""
if self.action in ['delete']:
if self.action in ['delete', 'mount', 'unmount']:
return self._simple_action()
if self.action in ['create']:
return self._create_action()
@ -169,6 +172,12 @@ class PodmanVolumeModuleParams:
if self.action == 'delete':
cmd = ['rm', '-f', self.params['name']]
return [to_bytes(i, errors='surrogate_or_strict') for i in cmd]
if self.action == 'mount':
cmd = ['mount', self.params['name']]
return [to_bytes(i, errors='surrogate_or_strict') for i in cmd]
if self.action == 'unmount':
cmd = ['unmount', self.params['name']]
return [to_bytes(i, errors='surrogate_or_strict') for i in cmd]
def _create_action(self):
cmd = [self.action, self.params['name']]
@ -326,6 +335,7 @@ class PodmanVolume:
self.module = module
self.name = name
self.stdout, self.stderr = '', ''
self.mount_point = None
self.info = self.get_info()
self.version = self._get_podman_version()
self.diff = {}
@ -380,7 +390,7 @@ class PodmanVolume:
"""Perform action with volume.
Arguments:
action {str} -- action to perform - create, stop, delete
action {str} -- action to perform - create, delete, mount, unmout
"""
b_command = PodmanVolumeModuleParams(action,
self.module.params,
@ -389,11 +399,14 @@ class PodmanVolume:
).construct_command_from_params()
full_cmd = " ".join([self.module.params['executable'], 'volume']
+ [to_native(i) for i in b_command])
# check if running not from root
if os.getuid() != 0 and action == 'mount':
full_cmd = f"{self.module.params['executable']} unshare {full_cmd}"
self.module.log("PODMAN-VOLUME-DEBUG: %s" % full_cmd)
self.actions.append(full_cmd)
if not self.module.check_mode:
rc, out, err = self.module.run_command(
[self.module.params['executable'], b'volume'] + b_command,
full_cmd,
expand_user_and_vars=False)
self.stdout = out
self.stderr = err
@ -401,6 +414,9 @@ class PodmanVolume:
self.module.fail_json(
msg="Can't %s volume %s" % (action, self.name),
stdout=out, stderr=err)
# in case of mount/unmount, return path to the volume from stdout
if action in ['mount']:
self.mount_point = out.strip()
def delete(self):
"""Delete the volume."""
@ -410,6 +426,14 @@ class PodmanVolume:
"""Create the volume."""
self._perform_action('create')
def mount(self):
"""Delete the volume."""
self._perform_action('mount')
def unmount(self):
"""Create the volume."""
self._perform_action('unmount')
def recreate(self):
"""Recreate the volume."""
self.delete()
@ -468,6 +492,8 @@ class PodmanVolumeManager:
states_map = {
'present': self.make_present,
'absent': self.make_absent,
'mounted': self.make_mount,
'unmounted': self.make_unmount,
'quadlet': self.make_quadlet,
}
process_action = states_map[self.state]
@ -501,6 +527,26 @@ class PodmanVolumeManager:
'podman_actions': self.volume.actions})
self.module.exit_json(**self.results)
def make_mount(self):
"""Run actions if desired state is 'mounted'."""
if not self.volume.exists:
self.volume.create()
self.results['actions'].append('created %s' % self.volume.name)
self.volume.mount()
self.results['actions'].append('mounted %s' % self.volume.name)
if self.volume.mount_point:
self.results.update({'mount_point': self.volume.mount_point})
self.update_volume_result()
def make_unmount(self):
"""Run actions if desired state is 'unmounted'."""
if self.volume.exists:
self.volume.unmount()
self.results['actions'].append('unmounted %s' % self.volume.name)
self.update_volume_result()
else:
self.module.fail_json(msg="Volume %s does not exist!" % self.name)
def make_quadlet(self):
results_update = create_quadlet_state(self.module, "volume")
self.results.update(results_update)
@ -511,7 +557,7 @@ def main():
module = AnsibleModule(
argument_spec=dict(
state=dict(type='str', default="present",
choices=['present', 'absent', 'quadlet']),
choices=['present', 'absent', 'mounted', 'unmounted', 'quadlet']),
name=dict(type='str', required=True),
label=dict(type='dict', required=False),
driver=dict(type='str', required=False),

View file

@ -161,6 +161,79 @@
- info10 is failed
- delete.volume == {}
- name: Mount non existing volume
containers.podman.podman_volume:
executable: "{{ test_executable | default('podman') }}"
name: nonexistent
state: mounted
register: mount1
- name: Check results
assert:
that:
- mount1 is success
- "'mount_point' in mount1"
- name: Create volume for mount
containers.podman.podman_volume:
executable: "{{ test_executable | default('podman') }}"
name: mountme
state: present
- name: Mount existing volume
containers.podman.podman_volume:
executable: "{{ test_executable | default('podman') }}"
name: mountme
state: mounted
register: mount2
- name: Check results
assert:
that:
- mount2 is success
- "'mount_point' in mount2"
- name: Unmount volume
containers.podman.podman_volume:
executable: "{{ test_executable | default('podman') }}"
name: mountme
state: unmounted
register: unmount
- name: Check results
assert:
that:
- unmount is success
- "'mount_point' not in unmount"
- name: Mount as root
become: true
containers.podman.podman_volume:
executable: "{{ test_executable | default('podman') }}"
name: rootmount
state: mounted
register: mount3
- name: Check results
assert:
that:
- mount3 is success
- "'mount_point' in mount3"
- name: Unmount as root
become: true
containers.podman.podman_volume:
executable: "{{ test_executable | default('podman') }}"
name: rootmount
state: unmounted
register: unmount2
- name: Check results
assert:
that:
- unmount2 is success
- "'mount_point' not in unmount2"
- name: Create a Quadlet for volume with filename
containers.podman.podman_volume:
executable: "{{ test_executable | default('podman') }}"