feat: espace LVM — thin pool data_percent + ext4 offline via tune2fs
- lvs query enrichi : lv_dm_path, data_percent, lv_attr - thin_pool_used_percent sur les thin pools (ex: Proxmox pve/data) - LV ext4 non montés lus via tune2fs sur /dev/mapper path - _format_lv() centralise la construction des entrées LV Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+38
-8
@@ -314,7 +314,7 @@ def get_lvm_map():
|
||||
return {}
|
||||
lvs_by_vg = {}
|
||||
lvs_out = run(["lvs", "--noheadings", "--reportformat", "json",
|
||||
"-o", "lv_name,vg_name,lv_size,lv_path"])
|
||||
"-o", "lv_name,vg_name,lv_size,lv_path,lv_dm_path,data_percent,lv_attr"])
|
||||
if lvs_out:
|
||||
try:
|
||||
for lv in json.loads(lvs_out)["report"][0]["lv"]:
|
||||
@@ -328,17 +328,47 @@ def get_lvm_map():
|
||||
if pv_name and vg_name:
|
||||
result[pv_name] = {
|
||||
"vg_name": vg_name,
|
||||
"logical_volumes": [
|
||||
{"lv_name": lv.get("lv_name", ""),
|
||||
"size_human": _lv_size_human(lv.get("lv_size", "")),
|
||||
"used_human": None, "free_human": None,
|
||||
"used_percent": None, "fstype": None, "mountpoint": None}
|
||||
for lv in lvs_by_vg.get(vg_name, [])
|
||||
],
|
||||
"logical_volumes": [_format_lv(lv)
|
||||
for lv in lvs_by_vg.get(vg_name, [])],
|
||||
}
|
||||
dprint(f"LVM : {len(result)} volume(s) physique(s)")
|
||||
return result
|
||||
|
||||
def _format_lv(lv):
|
||||
name = lv.get("lv_name", "")
|
||||
dm_path = lv.get("lv_dm_path", "") or lv.get("lv_path", "") or ""
|
||||
attr = lv.get("lv_attr", "")
|
||||
|
||||
entry = {
|
||||
"lv_name": name,
|
||||
"size_human": _lv_size_human(lv.get("lv_size", "")),
|
||||
"used_human": None, "free_human": None, "used_percent": None,
|
||||
"fstype": None, "mountpoint": None,
|
||||
"thin_pool_used_percent": None,
|
||||
}
|
||||
|
||||
# Thin pool : data_percent indique le remplissage du pool
|
||||
dp = lv.get("data_percent", "")
|
||||
if dp and dp.strip() not in ("", "0.00"):
|
||||
try:
|
||||
entry["thin_pool_used_percent"] = round(float(dp), 1)
|
||||
dprint(f" LV {name} thin pool : {entry['thin_pool_used_percent']}% utilise")
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# LV ext4 non monté → lecture offline via tune2fs
|
||||
# (attr[0] 'V'/'v' = thin vol, 't'/'T' = thin pool; les deux ont data_percent)
|
||||
is_pool = attr[:1].lower() in ("t",)
|
||||
if not is_pool and dm_path:
|
||||
space = _ext4_space(dm_path)
|
||||
if space:
|
||||
entry["used_human"] = bytes_human(space["used_bytes"])
|
||||
entry["free_human"] = bytes_human(space["free_bytes"])
|
||||
entry["used_percent"] = space["used_percent"]
|
||||
dprint(f" LV {name} offline : {entry['used_human']} utilise ({entry['used_percent']}%)")
|
||||
|
||||
return entry
|
||||
|
||||
|
||||
# -- /home users --------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user