diff --git a/inventaire.py b/inventaire.py index bfa950e..f7a6372 100644 --- a/inventaire.py +++ b/inventaire.py @@ -394,6 +394,71 @@ def get_proxmox_role(dev_name): return None +# -- Espace offline (partitions non montées) ---------------------------------- + +def get_offline_space(dev, fstype): + """Lit l'espace d'une partition non montée selon son type de filesystem.""" + if fstype in ("ext2", "ext3", "ext4"): + return _ext4_space(dev) + if fstype == "ntfs": + return _ntfs_space(dev) + if fstype == "btrfs": + return _btrfs_space(dev) + return None + +def _ext4_space(dev): + out = run(["tune2fs", "-l", dev]) + if not out: + return None + vals = {} + for line in out.splitlines(): + for key in ("Block count", "Free blocks", "Block size"): + if line.startswith(key + ":"): + try: + vals[key] = int(line.split(":", 1)[1].strip().replace(",", "")) + except ValueError: + pass + try: + total = vals["Block count"] * vals["Block size"] + free = vals["Free blocks"] * vals["Block size"] + used = total - free + return {"size_bytes": total, "used_bytes": used, "free_bytes": free, + "used_percent": int(used / total * 100) if total else 0} + except KeyError: + return None + +def _ntfs_space(dev): + # ntfsresize -i indique la taille minimale ≈ espace utilisé + out = run(["ntfsresize", "--info", "--force", dev]) + if not out: + return None + total = used = None + for line in out.splitlines(): + if "Current volume size:" in line: + m = re.search(r"(\d+)\s+bytes", line) + if m: + total = int(m.group(1)) + if "You might resize at" in line: + m = re.search(r"(\d+)\s+bytes", line) + if m: + used = int(m.group(1)) + if total and used: + return {"size_bytes": total, "used_bytes": used, "free_bytes": total - used, + "used_percent": int(used / total * 100) if total else 0} + return None + +def _btrfs_space(dev): + out = run(["btrfs", "filesystem", "show", dev]) + if not out: + return None + # "Total devices 1 FS bytes used 10.00GiB" + m = re.search(r"FS bytes used\s+([\d.]+)(\w+)", out) + if m: + # approximation seulement, pas de total fiable sans montage + dprint(f"btrfs {dev} : espace utilisé approximatif") + return None # trop imprecis sans montage + + # -- Construction des partitions ---------------------------------------------- def build_partitions(children, df_map, lvm_map, home_done): @@ -436,6 +501,16 @@ def build_partitions(children, df_map, lvm_map, home_done): f"{part['used_human']} / {part['size_human']} ({part['used_percent']}%)") else: dprint(f" partition {name} : fstype={fstype}, non montee") + if fstype in ("ext2", "ext3", "ext4", "ntfs", "btrfs"): + space = get_offline_space(f"/dev/{name}", fstype) + if space: + part["used_bytes"] = space["used_bytes"] + part["used_human"] = bytes_human(space["used_bytes"]) + part["free_bytes"] = space["free_bytes"] + part["free_human"] = bytes_human(space["free_bytes"]) + part["used_percent"] = space["used_percent"] + dprint(f" partition {name} offline : " + f"{part['used_human']} / {part['size_human']} ({part['used_percent']}%)") # /home users sur cette partition if mountpoint == "/home" and not home_done[0]: