summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/utils/fs.py61
1 files changed, 52 insertions, 9 deletions
diff --git a/src/utils/fs.py b/src/utils/fs.py
index a7058a7..bffdb8c 100644
--- a/src/utils/fs.py
+++ b/src/utils/fs.py
@@ -82,15 +82,21 @@ def get_usedperc(mountpoint):
def ogReduceFs(disk, part):
"""
- Bash function 'ogReduceFs' wrapper
- """
- proc = subprocess.run(f'ogReduceFs {disk} {part}',
- shell=True, stdout=PIPE,
- encoding='utf-8')
- if proc.returncode != 0:
- logging.warn(f'ogReduceFS exited with non zero code: {proc.returncode}')
- subprocess.run(f'ogUnmount {disk} {part}',
- shell=True)
+ Shrink filesystem of a partition. Supports ext4 and ntfs partitions.
+ Unsupported filesystem or invalid paths don't raise an exception,
+ instead this method logs a warning message and does nothing.
+ """
+ partdev = get_partition_device(disk, part)
+ fstype = get_filesystem_type(partdev)
+
+ umount(partdev)
+ if fstype == 'ext4':
+ _reduce_resize2fs(partdev)
+ elif fstype == 'ntfs':
+ _reduce_ntfsresize(partdev)
+ else:
+ logging.warn(f'Unable to shrink filesystem at {partdev}. '
+ f'Unsupported filesystem "{fstype}".')
def ogExtendFs(disk, part):
@@ -177,3 +183,40 @@ def get_filesystem_type(partdev):
if proc.returncode != 0:
raise RuntimeError(f'Error getting filesystem from {partdev}')
return proc.stdout.strip()
+
+
+def _reduce_resize2fs(partdev):
+ cmd = shlex.split(f'resize2fs -fpM {partdev}')
+ with open('/tmp/command.log', 'ab', 0) as logfile:
+ subprocess.run(cmd, stdout=logfile, stderr=STDOUT)
+
+
+def _reduce_ntfsresize(partdev):
+ cmd_info = shlex.split(f'ntfsresize -Pfi {partdev}')
+ proc_info = subprocess.run(cmd_info, stdout=subprocess.PIPE, encoding='utf-8')
+ out_info = proc_info.stdout.strip()
+
+ # Process ntfsresize output directly.
+ # The first split operation leaves the wanted data at the second element of
+ # the split ([1]). Finally do a second split with ' ' to get the data but
+ # nothing else following it.
+ #
+ # In addition, increase by 10%+1K the reported shrink location on which the
+ # filesystem can be resized according to ntfsresize.
+ size = int(out_info.split('device size: ')[1].split(' ')[0])
+ new_size = int(int(out_info.split('resize at ')[1].split(' ')[0])*1.1+1024)
+
+ # Dry-run loop to test if resizing is actually possible. This is required by ntfsresize.
+ returncode = 1
+ while new_size < size and returncode != 0:
+ cmd_resize_dryrun = shlex.split(f'ntfsresize -Pfns {new_size:.0f} {partdev}')
+ proc_resize_dryrun = subprocess.run(cmd_resize_dryrun, stdout=subprocess.PIPE, encoding='utf-8')
+ returncode = proc_resize_dryrun.returncode
+ out_resize_dryrun = proc_resize_dryrun.stdout.strip()
+ extra_size = int(out_resize_dryrun.split('Needed relocations : ')[1].split(' ')[0])*1.1+1024
+ new_size += int(extra_size)
+
+ if new_size < size:
+ cmd_resize = shlex.split(f'ntfsresize -fs {new_size:.0f} {partdev}')
+ with open('/tmp/command.log', 'ab', 0) as logfile:
+ subprocess.run(cmd_resize, input='y', stderr=STDOUT, encoding='utf-8')