feat: espace offline pour partitions non montées
tune2fs pour ext4, ntfsresize pour NTFS, btrfs partiel. Utile pour dual-boot et partitions de données non montées. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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]:
|
||||
|
||||
Reference in New Issue
Block a user