Integrate claude, improve selenium and support qemu #1

Open
mathben wants to merge 224 commits from develop into master
Showing only changes of commit c9ec5b98b9 - Show all commits

View file

@ -1838,7 +1838,9 @@ class TODO:
if rc != 0: if rc != 0:
print(t("Partition rewrite failed; reverting.")) print(t("Partition rewrite failed; reverting."))
return self._qemu_shrink_revert(bak, disk, changed=True) return self._qemu_shrink_revert(bak, disk, changed=True)
subprocess.run(["sudo", "partprobe", dev], check=False) subprocess.run(
["sudo", "partprobe", dev], check=False, capture_output=True
)
# Détache puis tronque le conteneur qcow2. # Détache puis tronque le conteneur qcow2.
self._qemu_nbd_disconnect(dev) self._qemu_nbd_disconnect(dev)
dev = None dev = None
@ -1853,7 +1855,9 @@ class TODO:
dev = self._qemu_nbd_connect(disk) dev = self._qemu_nbd_connect(disk)
if dev: if dev:
subprocess.run(["sudo", "sgdisk", "-e", dev], check=False) subprocess.run(["sudo", "sgdisk", "-e", dev], check=False)
subprocess.run(["sudo", "partprobe", dev], check=False) subprocess.run(
["sudo", "partprobe", dev], check=False, capture_output=True
)
p2 = self._qemu_root_part(dev)[0] p2 = self._qemu_root_part(dev)[0]
if p2: if p2:
subprocess.run( subprocess.run(
@ -1880,7 +1884,9 @@ class TODO:
@staticmethod @staticmethod
def _qemu_nbd_connect(disk): def _qemu_nbd_connect(disk):
"""Attache `disk` à un /dev/nbdN libre et renvoie le chemin, ou None.""" """Attache `disk` à un /dev/nbdN libre et renvoie le chemin, ou None.
Attend que les sous-périphériques de partition (nbdNpM) APPARAISSENT
(sinon lsblk/resize2fs ne voient rien juste après le connect)."""
for i in range(16): for i in range(16):
dev = f"/dev/nbd{i}" dev = f"/dev/nbd{i}"
# /sys/block/nbdN/pid absent => device libre. # /sys/block/nbdN/pid absent => device libre.
@ -1890,10 +1896,19 @@ class TODO:
["sudo", "qemu-nbd", "-c", dev, disk], ["sudo", "qemu-nbd", "-c", dev, disk],
capture_output=True, text=True, capture_output=True, text=True,
).returncode ).returncode
if rc == 0: if rc != 0:
time.sleep(1) continue
subprocess.run(["sudo", "partprobe", dev], check=False) base = f"nbd{i}"
for _ in range(15):
subprocess.run(
["sudo", "partprobe", dev], check=False, capture_output=True
)
time.sleep(1) time.sleep(1)
if any(
os.path.exists(f"/sys/class/block/{base}p{n}")
for n in range(1, 32)
):
break
return dev return dev
return None return None
@ -1905,25 +1920,29 @@ class TODO:
@staticmethod @staticmethod
def _qemu_root_part(dev): def _qemu_root_part(dev):
"""(partition la plus grosse, secteur de début, type FS) du disque nbd. """(partition la plus grosse, secteur de début, type FS) du disque nbd.
(None, 0, '') si introuvable.""" (None, 0, '') si introuvable. Format lsblk -P (paires) : robuste aux
colonnes VIDES — juste après le connect, FSTYPE peut être vide, et un
parsing positionnel décalait/ignorait alors toutes les partitions."""
import re
try: try:
res = subprocess.run( res = subprocess.run(
["lsblk", "-bnro", "NAME,SIZE,FSTYPE,TYPE", dev], ["lsblk", "-Pbno", "NAME,SIZE,TYPE,FSTYPE", dev],
capture_output=True, text=True, timeout=30, capture_output=True, text=True, timeout=30,
) )
except (OSError, subprocess.SubprocessError): except (OSError, subprocess.SubprocessError):
return None, 0, "" return None, 0, ""
best, best_sz, best_fs = None, -1, "" best, best_sz, best_fs = None, -1, ""
for line in res.stdout.splitlines(): for line in res.stdout.splitlines():
cols = line.split() d = dict(re.findall(r'(\w+)="([^"]*)"', line))
if len(cols) < 4 or cols[-1] != "part": if d.get("TYPE") != "part":
continue continue
name, size = cols[0], int(cols[1]) try:
fstype = cols[2] if len(cols) >= 4 and cols[2] != "part" else "" size = int(d.get("SIZE") or 0)
if len(cols) == 3: # pas de FSTYPE -> décalage except ValueError:
fstype = "" size = 0
if size > best_sz: if size > best_sz:
best, best_sz, best_fs = name, size, fstype best, best_sz, best_fs = d.get("NAME"), size, d.get("FSTYPE", "")
if not best: if not best:
return None, 0, "" return None, 0, ""
part = f"/dev/{best}" part = f"/dev/{best}"
@ -1934,6 +1953,7 @@ class TODO:
except OSError: except OSError:
start = 0 start = 0
if not best_fs: if not best_fs:
# FSTYPE pas encore en cache : sonder directement avec blkid.
best_fs = subprocess.run( best_fs = subprocess.run(
["sudo", "blkid", "-o", "value", "-s", "TYPE", part], ["sudo", "blkid", "-o", "value", "-s", "TYPE", part],
capture_output=True, text=True, capture_output=True, text=True,