mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Add ability to resize existing partition (#773)
* Add ability to resize existing partition * Add 'resize' flag to support backwards compatability, and allow partition reduction * Add changelog fragment for #773 * Update changelogs/fragments/773-resize-partition.yml Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/modules/system/parted.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update resize flag with PR review comments Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru> * Update plugins/modules/system/parted.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update default on resize flag in parted.py * Apply suggestions from code review Co-authored-by: Felix Fontein <felix@fontein.de> Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
This commit is contained in:
parent
0a28a0c8b0
commit
8f99f9cb1c
3 changed files with 65 additions and 0 deletions
2
changelogs/fragments/773-resize-partition.yml
Normal file
2
changelogs/fragments/773-resize-partition.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- parted - add ``resize`` option to resize existing partitions (https://github.com/ansible-collections/community.general/pull/773).
|
|
@ -103,6 +103,13 @@ options:
|
|||
- Parameter optional, but see notes below about negative negative C(part_start) values.
|
||||
type: str
|
||||
version_added: '0.2.0'
|
||||
resize:
|
||||
description:
|
||||
- Call C(resizepart) on existing partitions to match the size specified by I(part_end).
|
||||
type: bool
|
||||
default: false
|
||||
version_added: '1.3.0'
|
||||
|
||||
notes:
|
||||
- When fetching information about a new disk and when the version of parted
|
||||
installed on the system is before version 3.1, the module queries the kernel
|
||||
|
@ -207,6 +214,13 @@ EXAMPLES = r'''
|
|||
number: '{{ item.num }}'
|
||||
state: absent
|
||||
loop: '{{ sdb_info.partitions }}'
|
||||
|
||||
- name: Extend an existing partition to fill all available space
|
||||
community.general.parted:
|
||||
decice: /dev/sdb
|
||||
number: "{{ sdb_info.partitions | length }}"
|
||||
part_end: "100%"
|
||||
resize: true
|
||||
'''
|
||||
|
||||
|
||||
|
@ -392,6 +406,21 @@ def format_disk_size(size_bytes, unit):
|
|||
return round(output, precision), unit
|
||||
|
||||
|
||||
def convert_to_bytes(size_str, unit):
|
||||
size = float(size_str)
|
||||
multiplier = 1.0
|
||||
if unit in units_si:
|
||||
multiplier = 1000.0 ** units_si.index(unit)
|
||||
elif unit in units_iec:
|
||||
multiplier = 1024.0 ** (units_iec.index(unit) + 1)
|
||||
elif unit in ['', 'compact', 'cyl', 'chs']:
|
||||
# As per format_disk_size, default to compact, which defaults to megabytes
|
||||
multiplier = 1000.0 ** units_si.index("MB")
|
||||
|
||||
output = size * multiplier
|
||||
return int(output)
|
||||
|
||||
|
||||
def get_unlabeled_device_info(device, unit):
|
||||
"""
|
||||
Fetches device information directly from the kernel and it is used when
|
||||
|
@ -586,6 +615,9 @@ def main():
|
|||
|
||||
# rm/mkpart command
|
||||
state=dict(type='str', default='info', choices=['absent', 'info', 'present']),
|
||||
|
||||
# resize part
|
||||
resize=dict(type='bool', default=False),
|
||||
),
|
||||
required_if=[
|
||||
['state', 'present', ['number']],
|
||||
|
@ -608,6 +640,7 @@ def main():
|
|||
state = module.params['state']
|
||||
flags = module.params['flags']
|
||||
fs_type = module.params['fs_type']
|
||||
resize = module.params['resize']
|
||||
|
||||
# Parted executable
|
||||
parted_exec = module.get_bin_path('parted', True)
|
||||
|
@ -652,6 +685,25 @@ def main():
|
|||
if unit and script:
|
||||
script = "unit %s %s" % (unit, script)
|
||||
|
||||
# If partition exists, try to resize
|
||||
if resize and part_exists(current_parts, 'num', number):
|
||||
# Ensure new end is different to current
|
||||
partition = [p for p in current_parts if p['num'] == number][0]
|
||||
current_part_end = convert_to_bytes(partition['end'], unit)
|
||||
|
||||
size, parsed_unit = parse_unit(part_end, unit)
|
||||
if parsed_unit == "%":
|
||||
size = int((int(current_device['generic']['size']) * size) / 100)
|
||||
parsed_unit = unit
|
||||
|
||||
desired_part_end = convert_to_bytes(size, parsed_unit)
|
||||
|
||||
if current_part_end != desired_part_end:
|
||||
script += "resizepart %s %s " % (
|
||||
number,
|
||||
part_end
|
||||
)
|
||||
|
||||
# Execute the script and update the data structure.
|
||||
# This will create the partition for the next steps
|
||||
if script:
|
||||
|
|
|
@ -206,6 +206,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='rm 1')
|
||||
|
||||
def test_resize_partition(self):
|
||||
set_module_args({
|
||||
'device': '/dev/sdb',
|
||||
'number': 3,
|
||||
'state': 'present',
|
||||
'part_end': '100%',
|
||||
'resize': True
|
||||
})
|
||||
with patch('ansible_collections.community.general.plugins.modules.system.parted.get_device_info', return_value=parted_dict1):
|
||||
self.execute_module(changed=True, script='resizepart 3 100%')
|
||||
|
||||
def test_change_flag(self):
|
||||
# Flags are set in a second run of parted().
|
||||
# Between the two runs, the partition dict is updated.
|
||||
|
|
Loading…
Reference in a new issue