diff --git a/client/lib/engine/bin/FileSystemLib.py b/client/lib/engine/bin/FileSystemLib.py index 8eb19e1..250efcb 100755 --- a/client/lib/engine/bin/FileSystemLib.py +++ b/client/lib/engine/bin/FileSystemLib.py @@ -253,9 +253,9 @@ def ogFormatFs (disk, par, fs=None, label=None): subprocess.run (['umount', PART]) try: if input: - errcode = subprocess.run ([prog] + params.split (' ') + [PART]) + errcode = subprocess.run ([prog] + params.split (' ') + [PART]).returncode else: - errcode = subprocess.run ([prog] + params.split (' ') + [PART], input=input, text=True) + errcode = subprocess.run ([prog] + params.split (' ') + [PART], input=input, text=True).returncode except FileNotFoundError: SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog) errcode = ogGlobals.OG_ERR_NOTEXEC @@ -681,71 +681,82 @@ def ogMountCdrom(): #@warning El sistema de archivos se amplía al mínimo + 10%. #@note Requisitos: *resize* #*/ ## -def ogReduceFs(int_ndisk, int_nfilesys): - - # Error si no se reciben 2 parámetros. - if len(sys.argv) != 3: - SystemLib.ogRaiseError ( - [], - ogGlobals.OG_ERR_FORMAT, - "Not enough arguments" - ) - return - - # Obtener partición. - PART = DiskLib.ogDiskToDev(int_ndisk, int_nfilesys) - if not PART: - return +def ogReduceFs (disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return # Redimensionar según el tipo de partición. - TYPE = ogGetFsType(int_ndisk, int_nfilesys) - if TYPE == "EXT4": - ogUnmount(int_ndisk, int_nfilesys) - subprocess.run(["resize2fs", "-fpM", PART], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - elif TYPE == "BTRFS": - MNTDIR = ogMount(int_ndisk, int_nfilesys) - SIZE = subprocess.run(["btrfs", "filesystem", "show", MNTDIR], capture_output=True, text=True) - SIZE = SIZE.stdout.strip().split(" ")[6] - SIZE = int(float(SIZE) * 1.1 + 1) - subprocess.run(["btrfs", "filesystem", "resize", str(SIZE), MNTDIR], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - elif TYPE in ["REISERFS", "REISER4"]: - MNTDIR = ogMount(int_ndisk, int_nfilesys) - SIZE = int(subprocess.run(["df", "-k", MNTDIR], capture_output=True, text=True).stdout.strip().split("\n")[1].split()[2]) - SIZE = SIZE * 110 // 100 - ogUnmount(int_ndisk, int_nfilesys) - subprocess.run(["resize_reiserfs", "-s" + str(SIZE) + "K", PART], input="y\n", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - elif TYPE == "NTFS": - ogUnmount(int_ndisk, int_nfilesys) - MAXSIZE, SIZE = subprocess.run(["ntfsresize", "-fi", PART], capture_output=True, text=True) - MAXSIZE = MAXSIZE.strip().split(" ")[3] - SIZE = SIZE.strip().split(" ")[4] - SIZE = int(float(SIZE) * 1.1 / 1024 + 1) * 1024 - RETVAL = 1 - while RETVAL != 0 and SIZE + EXTRASIZE < MAXSIZE: - EXTRASIZE = subprocess.run(["ntfsresize", "-fns", str(SIZE), PART], capture_output=True, text=True) - EXTRASIZE = int(EXTRASIZE.stdout.strip()) if EXTRASIZE.stdout.strip() else 0 - RETVAL = EXTRASIZE != 0 - SIZE += EXTRASIZE - if SIZE < MAXSIZE: - subprocess.run(["ntfsresize", "-fs", str(SIZE), PART], input="y\n", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - elif TYPE in ["FAT32", "FAT16"]: - # No se reduce (por el momento). - pass - elif TYPE == "HFS" or TYPE == "HFSPLUS": - # No se reduce (por el momento). - pass - elif TYPE == "UFS": - # No se reduce (por el momento). + type = ogGetFsType (disk, par) + if type in ['EXT2', 'EXT3', 'EXT4']: + ogUnmount (disk, par) + rc = subprocess.run (['resize2fs', '-fpM', PART], capture_output=True, text=True).returncode + if rc: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}") + return None + elif 'BTRFS' == type: + mntdir = ogMount (disk, par) + # Calcular tamaño ocupado + 10%, redondeado + 1 (incluyendo letra de unidad). + btrfs_lines = subprocess.run (['btrfs', 'filesystem', 'show', mntdir], capture_output=True, text=True).stdout.splitlines() + for l in btrfs_lines: + if 'devid' not in l: continue + ## 'devid 2 size 8.89GiB used 1.00GiB path /dev/sda4' + devid_str, devid, size_str, size, used_str, used, path_str, path = l.split() + if PART != os.path.realpath (path): continue + (sz, unit) = re.search ('^([^A-Z]+)([A-Z])', used).groups() + sz = float (sz) * 1.1 + 1 + size = f'{str(sz)}{unit}' + subprocess.run (['btrfs', 'filesystem', 'resize', size, mntdir], capture_output=True, text=True) + break + elif type in ['REISERFS', 'REISER4']: + mntdir = ogMount (disk, par) + df_lines = subprocess.run (['df', '-k', mntdir], capture_output=True, text=True).stdout.splitlines() + for l in df_lines: + if 'Filesystem' in l: continue + fs, blocks, used, avail, use_pct, mntpt = l.split() + size = str (int (used) * 1.1) + ogUnmount (disk, par) + subprocess.run (['resize_reiserfs', f'-s{size}K', PART], input='y\n', capture_output=True, text=True) + break + elif type == 'NTFS': + ogUnmount (disk, par) + nr_lines = subprocess.run (['ntfsresize', '-fi', PART], capture_output=True, text=True).stdout.splitlines() + maxsize = None + size = None + for l in nr_lines: + if 'device size' in l: + maxsize = float (l.split()[3]) + if 'resize at' in l: + size = l.split()[4] + size = int ((int (size) * 1.1 / 1024 + 1) * 1024) + + if not maxsize and not size: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{par}') + return None + + import time + + extrasize = 0 + retval = 1 + while retval != 0 and size+extrasize < maxsize: + nr = subprocess.run (['ntfsresize', '-fns', str(size), PART], capture_output=True, text=True) + for l in nr.stdout.splitlines(): + if 'Needed relocations' not in l: continue + extrasize = int ((int (l.split()[3])*1.1/1024+1)*1024) + break + retval = nr.returncode + size += extrasize + if size < maxsize: + rc = subprocess.run (['ntfsresize', '-fs', str(size), PART], input='y\n', capture_output=True, text=True).returncode + if rc: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}") + return None + elif type in ['FAT32', 'FAT16', 'F2FS', 'JFS', 'NILFS2', 'XFS', 'EXFAT', 'HFS', 'HFSPLUS', 'UFS']: pass else: - SystemLib.ogRaiseError ( - [], - ogGlobals.OG_ERR_PARTITION, - f"{int_ndisk}, {int_nfilesys}" - ) + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}") + return None - # Devuelve tamaño del sistema de ficheros. - return ogGetFsSize(int_ndisk, int_nfilesys) + return ogGetFsSize (disk, par) #/** diff --git a/client/shared/functions/ogReduceFs b/client/shared/functions/ogReduceFs new file mode 100755 index 0000000..999aa90 --- /dev/null +++ b/client/shared/functions/ogReduceFs @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogReduceFs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogReduceFs', 'ogReduceFs int_ndisk int_nfilesys', ['ogReduceFs 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogReduceFs (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret)