Repository: ansible-collections/community.general

Issue:
lvol - lvcreate snapshot "**%ORIGIN" fails
##### SUMMARY
When i want to create a lvm snapshot with the module `lvol` and the option `size : 20%ORIGIN` for example,
it fails : 
> "Snapshot Volumes are not supported"
> 
This option is valid according to lvcreate(8).

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
lvol

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```
ansible --version
ansible 2.9.14
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/var/lib/awx/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Apr 16 2020, 01:36:27) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```paste below

```

##### OS / ENVIRONMENT
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->
OS : Linux REDHAT 7


##### STEPS TO REPRODUCE
<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->

<!--- Paste example playbooks or commands between quotes below -->
```
- name: "[BACKUP] create snapshots" 
  lvol:
    vg: "{{ item.value.vg }}"
    lv: "{{ item.key }}"
    snapshot: "{{ item.key }}_{{ snap_suffix }}"
    size: 20%ORIGIN
  with_dict: "{{ ansible_lvm.lvs }}" 
```

<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- Describe what you expected to happen when running the steps above -->
Creation of lvm snapshot.  
On redhat 7 :  
`lvcreate -s -l 20%ORIGIN --name lv_***_snap_suffix /dev/vg***/lv_***`    
`  Logical volume "lv_***_snap_suffix" created.`

##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes -->
```
{
    "msg": "Snapshot Volumes are not supported",
    "invocation": {
        "module_args": {
            "pvs": null,
            "force": false,
            "vg": "vg01",
            "lv": "lv_***",
            "resizefs": false,
            "state": "present",
            "thinpool": null,
            "snapshot": "lv_***_snap_suffix",
            "active": true,
            "shrink": true,
            "opts": null,
            "size": "20%ORIGIN"
        }
    },
    "_ansible_no_log": false,
    "changed": false,
    "item": {
        "key": "lv_***",
        "value": {
            "size_g": "***",
            "vg": "vg***"
        }
    },
    "ansible_loop_var": "item",
    "_ansible_item_label": {
        "key": "lv_***",
        "value": {
            "size_g": "***",
            "vg": "vg***"
        }
    }
}

```



Discussion:
Files identified in the description:
None

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
Files identified in the description:
* [`plugins/modules/system/lvol.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/system/lvol.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @abulimov @jhoekx
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
cc @unkaputtbar112 @zigaSRC
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Files identified in the description:
* [`plugins/modules/lvol.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/lvol.py)

If these files are incorrect, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->

Resolving patch:
diff --git a/plugins/modules/lvol.py b/plugins/modules/lvol.py
--- a/plugins/modules/lvol.py
+++ b/plugins/modules/lvol.py
@@ -41,13 +41,13 @@
     description:
     - The size of the logical volume, according to lvcreate(8) --size, by
       default in megabytes or optionally with one of [bBsSkKmMgGtTpPeE] units; or
-      according to lvcreate(8) --extents as a percentage of [VG|PVS|FREE];
+      according to lvcreate(8) --extents as a percentage of [VG|PVS|FREE|ORIGIN];
       Float values must begin with a digit.
     - When resizing, apart from specifying an absolute size you may, according to
       lvextend(8)|lvreduce(8) C(--size), specify the amount to extend the logical volume with
       the prefix V(+) or the amount to reduce the logical volume by with prefix V(-).
     - Resizing using V(+) or V(-) was not supported prior to community.general 3.0.0.
-    - Please note that when using V(+) or V(-), the module is B(not idempotent).
+    - Please note that when using V(+), V(-), or percentage of FREE, the module is B(not idempotent).
   state:
     type: str
     description:
@@ -73,7 +73,7 @@
   snapshot:
     type: str
     description:
-    - The name of the snapshot volume
+    - The name of a snapshot volume to be configured. When creating a snapshot volume, the O(lv) parameter specifies the origin volume.
   pvs:
     type: str
     description:
@@ -368,10 +368,10 @@ def main():
             if size_percent > 100:
                 module.fail_json(msg="Size percentage cannot be larger than 100%")
             size_whole = size_parts[1]
-            if size_whole == 'ORIGIN':
-                module.fail_json(msg="Snapshot Volumes are not supported")
-            elif size_whole not in ['VG', 'PVS', 'FREE']:
-                module.fail_json(msg="Specify extents as a percentage of VG|PVS|FREE")
+            if size_whole == 'ORIGIN' and snapshot is None:
+                module.fail_json(msg="Percentage of ORIGIN supported only for snapshot volumes")
+            elif size_whole not in ['VG', 'PVS', 'FREE', 'ORIGIN']:
+                module.fail_json(msg="Specify extents as a percentage of VG|PVS|FREE|ORIGIN")
             size_opt = 'l'
             size_unit = ''
 


Test patch:
diff --git a/tests/integration/targets/lvg/tasks/setup.yml b/tests/integration/targets/lvg/tasks/setup.yml
--- a/tests/integration/targets/lvg/tasks/setup.yml
+++ b/tests/integration/targets/lvg/tasks/setup.yml
@@ -4,7 +4,7 @@
 # SPDX-License-Identifier: GPL-3.0-or-later
 
 - name: "Create files to use as a disk devices"
-  command: "dd if=/dev/zero of={{ remote_tmp_dir }}/img{{ item }} bs=1M count=10"
+  command: "dd if=/dev/zero of={{ remote_tmp_dir }}/img{{ item }} bs=1M count=36"
   with_sequence: 'count=4'
 
 - name: "Show next free loop device"
diff --git a/tests/integration/targets/lvg/tasks/test_active_change.yml b/tests/integration/targets/lvg/tasks/test_active_change.yml
--- a/tests/integration/targets/lvg/tasks/test_active_change.yml
+++ b/tests/integration/targets/lvg/tasks/test_active_change.yml
@@ -17,6 +17,16 @@
     lv: "{{ item }}"
     size: 2m
 
+- name: Create snapshot volumes of origin logical volumes
+  loop:
+    - lv1
+    - lv2
+  lvol:
+    vg: testvg
+    lv: "{{ item }}"
+    snapshot: "{{ item }}_snap"
+    size: 50%ORIGIN
+
 - name: Collect all lv active status in testvg
   shell: vgs -olv_active --noheadings testvg | xargs -n1
   register: initial_lv_status_result
diff --git a/tests/integration/targets/lvg/tasks/test_pvresize.yml b/tests/integration/targets/lvg/tasks/test_pvresize.yml
--- a/tests/integration/targets/lvg/tasks/test_pvresize.yml
+++ b/tests/integration/targets/lvg/tasks/test_pvresize.yml
@@ -12,10 +12,10 @@
   shell: vgs -v testvg -o pv_size --noheading --units b | xargs
   register: cmd_result
 
-- name: Assert the testvg size is 8388608B
+- name: Assert the testvg size is 33554432B
   assert:
    that:
-    - "'8388608B' == cmd_result.stdout"
+    - "'33554432B' == cmd_result.stdout"
 
 - name: Increases size in file
   command: "dd if=/dev/zero bs=8MiB count=1 of={{ remote_tmp_dir }}/img1 conv=notrunc oflag=append"
@@ -38,10 +38,10 @@
   shell: vgs -v testvg -o pv_size --noheading --units b | xargs
   register: cmd_result
 
-- name: Assert the testvg size is still 8388608B
+- name: Assert the testvg size is still 33554432B
   assert:
    that:
-    - "'8388608B' == cmd_result.stdout"
+    - "'33554432B' == cmd_result.stdout"
 
 - name: "Reruns lvg with pvresize:yes and check_mode:yes"
   lvg:
@@ -60,10 +60,10 @@
   shell: vgs -v testvg -o pv_size --noheading --units b | xargs
   register: cmd_result
  
-- name: Assert the testvg size is still 8388608B
+- name: Assert the testvg size is still 33554432B
   assert:
    that:
-    - "'8388608B' == cmd_result.stdout"
+    - "'33554432B' == cmd_result.stdout"
 
 - name: "Reruns lvg with pvresize:yes"
   lvg:
@@ -75,7 +75,7 @@
   shell: vgs -v testvg -o pv_size --noheading --units b | xargs
   register: cmd_result
 
-- name: Assert the testvg size is now 16777216B
+- name: Assert the testvg size is now 41943040B
   assert:
    that:
-    - "'16777216B' == cmd_result.stdout"
+    - "'41943040B' == cmd_result.stdout"