From ced14746a8bc35550199b8dd30eb5c1c06458bd1 Mon Sep 17 00:00:00 2001 From: Robert Osowiecki Date: Tue, 23 Jun 2020 14:02:35 +0200 Subject: [PATCH] parted: Allow passing negative numbers to specify partition boundary relative to disk end (#129) * Allow passing negative numbers to specify partition boundary relative to disk end Fixes: https://github.com/ansible/ansible/issues/43369 * parted: unit test case, create partition with part_start: -1GiB * fs_type parameter is not really optional for negative part_start parameter * Revert "fs_type parameter is not really optional for negative part_start parameter" This reverts commit 800b1cb00b37c32e95d664df34f3fd76747b41d4. Instead: added notes and documentation about netagive part_start and fs_type. * include fs_type in negative part_start example --- .../fragments/parted_negative_numbers.yml | 2 ++ plugins/modules/system/parted.py | 25 +++++++++++++++---- .../plugins/modules/system/test_parted.py | 11 ++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/parted_negative_numbers.yml diff --git a/changelogs/fragments/parted_negative_numbers.yml b/changelogs/fragments/parted_negative_numbers.yml new file mode 100644 index 0000000000..9a54a2c173 --- /dev/null +++ b/changelogs/fragments/parted_negative_numbers.yml @@ -0,0 +1,2 @@ +minor_changes: + - "parted - accept negative numbers in ``part_start`` and ``part_end``" diff --git a/plugins/modules/system/parted.py b/plugins/modules/system/parted.py index c2f1005d7c..a962ee1963 100644 --- a/plugins/modules/system/parted.py +++ b/plugins/modules/system/parted.py @@ -66,15 +66,18 @@ options: part_start: description: - Where the partition will start as offset from the beginning of the disk, - that is, the "distance" from the start of the disk. + that is, the "distance" from the start of the disk. Negative numbers + specify distance from the end of the disk. - The distance can be specified with all the units supported by parted (except compat) and it is case sensitive, e.g. C(10GiB), C(15%). + - Using negative values may require setting of C(fs_type) (see notes). type: str default: 0% - part_end : + part_end: description: - Where the partition will end as offset from the beginning of the disk, - that is, the "distance" from the start of the disk. + that is, the "distance" from the start of the disk. Negative numbers + specify distance from the end of the disk. - The distance can be specified with all the units supported by parted (except compat) and it is case sensitive, e.g. C(10GiB), C(15%). type: str @@ -96,6 +99,7 @@ options: fs_type: description: - If specified and the partition does not exist, will set filesystem type to given partition. + - Parameter optional, but see notes below about negative negative C(part_start) values. type: str version_added: '0.2.0' notes: @@ -103,6 +107,9 @@ notes: installed on the system is before version 3.1, the module queries the kernel through C(/sys/) to obtain disk information. In this case the units CHS and CYL are not supported. + - Negative C(part_start) start values were rejected if C(fs_type) was not given. + This bug was fixed in parted 3.2.153. If you want to use negative C(part_start), + specify C(fs_type) as well or make sure your system contains newer parted. ''' RETURN = r''' @@ -180,6 +187,14 @@ EXAMPLES = r''' state: present part_start: 1GiB +- name: Create a new primary partition with a size of 1GiB at disk's end + parted: + device: /dev/sdb + number: 3 + state: present + fs_type: ext3 + part_start: -1GiB + # Example on how to read info and reuse it in subsequent task - name: Read device information (always use unit when probing) parted: device=/dev/sdb unit=MiB @@ -208,9 +223,9 @@ parted_units = units_si + units_iec + ['s', '%', 'cyl', 'chs', 'compact'] def parse_unit(size_str, unit=''): """ - Parses a string containing a size of information + Parses a string containing a size or boundary information """ - matches = re.search(r'^([\d.]+)([\w%]+)?$', size_str) + matches = re.search(r'^(-?[\d.]+)([\w%]+)?$', size_str) if matches is None: # ",," format matches = re.search(r'^(\d+),(\d+),(\d+)$', size_str) diff --git a/tests/unit/plugins/modules/system/test_parted.py b/tests/unit/plugins/modules/system/test_parted.py index 2846d70dd7..c709938d6d 100644 --- a/tests/unit/plugins/modules/system/test_parted.py +++ b/tests/unit/plugins/modules/system/test_parted.py @@ -198,6 +198,17 @@ class TestParted(ModuleTestCase): with patch('ansible_collections.community.general.plugins.modules.system.parted.get_device_info', return_value=parted_dict1): self.execute_module(changed=True, script='unit KiB mkpart primary 0% 1GiB') + def test_create_new_partition_minus_1G(self): + set_module_args({ + 'device': '/dev/sdb', + 'number': 4, + 'state': 'present', + 'fs_type': 'ext2', + 'part_start': '-1GiB', + }) + with patch('ansible_collections.community.general.plugins.modules.system.parted.get_device_info', return_value=parted_dict1): + self.execute_module(changed=True, script='unit KiB mkpart primary ext2 -1GiB 100%') + def test_remove_partition_number_1(self): set_module_args({ 'device': '/dev/sdb',